End ListHead.
Module LsegRecursiveLoopFree.
Fixpoint lseg (sh: share) (contents: list int) (x z: val) : mpred :=
match contents with
| h::hs => !! (x<>z) &&
EX y:val,
field_at sh t_struct_list [StructField _head] (Vint h) x *
field_at sh t_struct_list [StructField _tail] y x *
lseg sh hs y z
| nil => !! (x = z) && emp
end.
Arguments lseg sh contents x z : simpl never.

(* Specifications: *)
Lemma singleton_lseg: forall sh (contents: list int) (a: int) (x y: val),
readable_share sh ->
field_at sh t_struct_list [StructField _head] (Vint a) x *
field_at sh t_struct_list [StructField _tail] y x *
listrep sh contents y |--
lseg sh [a] x y *
listrep sh contents y.
Lemma singleton_lseg': forall sh (a b: int) (x y: val),
readable_share sh ->
field_at sh t_struct_list [StructField _head] (Vint a) x *
field_at sh t_struct_list [StructField _tail] y x *
field_at sh t_struct_list [StructField _head] (Vint b) y |--
lseg sh [a] x y *
field_at sh t_struct_list [StructField _head] (Vint b) y.
Lemma lseg_lseg: forall sh (s1 s2: list int) (a: int) (x y z: val),
readable_share sh ->
lseg sh s2 y z * lseg sh s1 x y * field_at sh t_struct_list [StructField _head] (Vint a) z |--
lseg sh (s1 ++ s2) x z * field_at sh t_struct_list [StructField _head] (Vint a) z.
(* TODO: swap the order of * *)
Lemma list_lseg: forall sh (s1 s2: list int) (x y: val),
listrep sh s2 y * lseg sh s1 x y |-- listrep sh (s1 ++ s2) x.