Open Scope logic.
Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs. mk_varspecs prog. Defined.
Instance LS: listspec _list _tail (fun _ _ => emp).
Definition merge_invariant _cond sh init_a init_b v_ret :=
(EX cond: int, EX a: list int, EX b: list int, EX merged: list int,
EX a_: val, EX b_: val, EX c_: val, EX begin: val,
PROP (merge init_a init_b = merged ++ merge a b;
cond = Int.zero <-> (a_ = nullval \/ b_ = nullval)
)
LOCAL (temp _a a_;
temp _b b_;
temp _x (if merged then v_ret else field_address (Tstruct _list noattr) [StructField _tail] c_);
lvar _ret tlist v_ret;
temp _cond (Vint cond)
)
SEP (lseg LS sh (map Vint a) a_ nullval;
lseg LS sh (map Vint b) b_ nullval;
data_at Tsh tlist (if merged then Vundef else begin) v_ret;
lseg LS sh (map Vint (butlast merged)) begin c_;
if merged then emp else data_at sh t_struct_list (Vint (last merged), Vundef) c_
))%assert.

(* TODO-LTAC - is this a missing lemma of the theory of [list_cell]?*)
Lemma list_cell_field_at sh (v : val) p :
list_cell LS sh v p = field_at sh list_struct [StructField _head] v p.