Admitted.
End LIST2.
Hint Rewrite @lseg_nil_eq : norm.
Hint Rewrite @lseg_eq using reflexivity: norm.
Hint Resolve @lseg_local_facts : saturate_local.
End LsegGeneral.
Module LsegSpecial.
Section LIST.
Context {cs: compspecs}.
Context  {list_structid: ident} {list_link: ident} {list_token: share -> val -> mpred}.
Definition lseg (ls: listspec list_structid list_link list_token) (sh: share)
(contents: list (elemtype ls)) (x y: val) : mpred :=
EX al:list (val*elemtype ls),
!! (contents = map snd al) &&
LsegGeneral.lseg ls sh sh al x y.

(* Specifications: *)
Lemma lseg_unfold (ls: listspec list_structid list_link list_token): forall sh contents v1 v2,
lseg ls sh contents v1 v2 =
match contents with
| h::t => !! (~ ptr_eq v1 v2) && EX tail: val,
!! is_pointer_or_null tail &&
list_token sh v1 * list_cell ls sh h v1
* field_at sh list_struct (StructField list_link :: nil)
(valinject (nested_field_type list_struct (StructField list_link :: nil)) tail) v1
*  lseg ls sh t tail v2
| nil => !! (ptr_eq v1 v2) && emp
end.
Lemma lseg_eq (ls: listspec list_structid list_link list_token):
forall sh l v ,
is_pointer_or_null v ->
lseg ls sh l v v = !!(l=nil) && emp.