Definition lseg_cell (ls: listspec list_structid list_link list_token)
(sh : share)
(v: elemtype ls) (x y: val) :=
!!is_pointer_or_null y && list_token sh x * list_cell ls sh v x * field_at sh list_struct (StructField list_link :: nil) (valinject (nested_field_type list_struct (StructField list_link :: nil)) y) x.

(* Specifications: *)
Lemma lseg_cons_eq2: forall
(ls : listspec list_structid list_link list_token) (sh : share) (h : elemtype ls)
(r : list (elemtype ls))
(x z : val), lseg ls sh (h :: r) x z =
!!(~ ptr_eq x z) && (EX  y : val, lseg_cell ls sh h x y * lseg ls sh r y z).
Lemma list_append: forall {sh: share}
{ls : listspec list_structid list_link list_token} (hd mid tl:val) ct1 ct2 P,
(forall x tl', lseg_cell ls sh x tl tl' * P tl |-- FF) ->
(lseg ls sh ct1 hd mid) * lseg ls sh ct2 mid tl * P tl|--
(lseg ls sh (ct1 ++ ct2) hd tl) * P tl.
Lemma list_append_null:
forall
(ls: listspec list_structid list_link list_token)
(sh: share)
(hd mid: val) ct1 ct2,
lseg ls sh ct1 hd mid * lseg ls sh ct2 mid nullval |--
lseg ls sh (ct1++ct2) hd nullval.
Lemma list_cell_valid_pointer:
forall (LS: listspec list_structid list_link list_token) (sh: Share.t) v p,
sepalg.nonidentity sh ->
field_offset cenv_cs list_link list_fields + sizeof (field_type list_link list_fields)
= field_offset_next cenv_cs list_link list_fields  (co_sizeof (get_co list_structid)) ->
list_cell LS sh v p * field_at_ sh list_struct (StructField list_link::nil) p
|-- valid_pointer p.
Lemma lseg_valid_pointer:
forall (ls : listspec list_structid list_link list_token) sh contents p q R,
sepalg.nonidentity sh ->
field_offset cenv_cs list_link list_fields + sizeof (field_type list_link list_fields)
= field_offset_next cenv_cs list_link list_fields  (co_sizeof (get_co list_structid)) ->
R |-- valid_pointer q ->
R * lseg ls sh contents p q |-- valid_pointer p.