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.

Lemma list_append_null (cs : compspecs)
(list_structid list_link : ident) (sh : share)
(ls : listspec list_structid list_link list_token) (hd mid : val)
(ct1 ct2 : list (elemtype ls)) :
lseg ls sh ct1 hd mid * lseg ls sh ct2 mid nullval
|-- lseg ls sh (ct1 ++ ct2) hd nullval.