Definition lseg_cell  (ls: listspec list_structid list_link list_token)
(dsh psh : share)
(v: elemtype ls) (x y: val) :=
!!is_pointer_or_null y && list_token dsh x * list_cell ls dsh v x * field_at psh 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) (dsh psh : share) (h : elemtype ls)
(r : list (val * elemtype ls))
(x x' z : val), lseg ls dsh psh ((x',h) :: r) x z =
!!(x=x' /\ ~ ptr_eq x z) && (EX  y : val, lseg_cell ls dsh psh h x y * lseg ls dsh psh r y z).
Lemma list_append: forall {dsh psh: share}
{ls : listspec list_structid list_link list_token} (hd mid tl:val) ct1 ct2 P,
(forall x tl', lseg_cell ls dsh psh x tl tl' * P tl |-- FF) ->
(lseg ls dsh psh ct1 hd mid) * lseg ls dsh psh ct2 mid tl * P tl|--
(lseg ls dsh psh (ct1 ++ ct2) hd tl) * P tl.
Lemma list_append_null:
forall
(ls: listspec list_structid list_link list_token)
(dsh psh: share)
(hd mid: val) ct1 ct2,
lseg ls dsh psh ct1 hd mid * lseg ls dsh psh ct2 mid nullval |--
lseg ls dsh psh (ct1++ct2) hd nullval.
Lemma sizeof_list_struct_pos (LS: listspec list_structid list_link list_token) :
sizeof list_struct > 0.
Lemma lseg_cons_eq2: forall
(ls : listspec list_structid list_link list_token) (dsh psh : share) (h : elemtype ls)
(r : list val )  (x z : val),
~ (readable_share dsh) ->
lseg ls dsh psh (x :: r) x z =
!!(~ ptr_eq x z) && (EX  y : val, lseg_cell ls dsh psh h x y * lseg ls dsh psh r y z).
Lemma list_append: forall {dsh psh: share}
{ls : listspec list_structid list_link list_token} (hd mid tl:val) ct1 ct2 P,
(forall tl', lseg_cell ls dsh psh (vund ls) tl tl' * P tl |-- FF) ->
(lseg ls dsh psh ct1 hd mid) * lseg ls dsh psh ct2 mid tl * P tl|--
(lseg ls dsh psh (ct1 ++ ct2) hd tl) * P tl.
Lemma list_append_null:
forall
(ls: listspec list_structid list_link list_token)
(dsh psh: share)
(hd mid: val) ct1 ct2,
lseg ls dsh psh ct1 hd mid * lseg ls dsh psh ct2 mid nullval |--
lseg ls dsh psh (ct1++ct2) hd nullval.
Lemma list_cell_valid_pointer:
forall (LS: listspec list_structid list_link list_token) (dsh psh: Share.t) v p,
sepalg.nonidentity dsh ->
sepalg.join_sub dsh psh ->
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 dsh v p * field_at_ psh list_struct (StructField list_link::nil) p
|-- valid_pointer p.
Lemma list_cell_valid_pointerx:
forall (ls : listspec list_structid list_link list_token)  sh v p,
sh <> Share.bot ->
list_cell ls sh v p |-- valid_pointer p.