Definition listempty (lp: adr*adr) : mpred :=
!! (fst lp = snd lp) && emp.
Definition listrep' (R: adr*adr -> mpred) (lp: adr*adr) : mpred :=
listcons' R lp || listempty lp.
Definition listrep : adr*adr -> mpred := HORec listrep'.
Definition lseg (e1 e2: adr) : mpred := listrep (e1,e2).

(* Specifications: *)
Lemma lseg_unfold: forall e1 e2,
(lseg e1 e2 = (!! (e1<> e2)  && EX tail:adr, next e1 tail * |> lseg tail e2)
|| (!! (e1=e2) && emp)).
Lemma lseg_neq: forall p q: adr, p<>q ->
lseg p q = EX y:adr, next p y *  |> lseg y q.
Lemma lseg_eq: forall a, lseg a a = emp.
Lemma lseg_cons: (* U2 *)
forall x y z, x<>z -> next x y * lseg y z |-- lseg x z.
Lemma lseg_neq_0:  forall y, lseg 0 y |-- !! (y=0).  (* W2 *)
Lemma next_lseg:  (* U1 *)
forall x y, x<>y ->  next x y |-- lseg x y.
Lemma next_conflict:  (*  W3 *)
forall x y y', next x y * next x y' |-- FF.
Lemma next_conflict_list: (* W4 *)
forall x y z, next x y * lseg z 0 |-- !!(x<>z).
Lemma lseg_W5: forall x y z,   (* W5 *)
lseg x y * lseg x z |-- !!(x=y \/ x=z).
Lemma unfash_andp_distrib:
forall {A}{ND: NatDed A}{IA: Indir A}{RA: RecIndir A} (P: Triv) (Q R: A),
!P && (Q && R) = (!P && Q) && (!P && R).
Lemma lseg_cons_in_next_context:   (*  U4 *)
forall x y z v, lseg x y * next y z * next z v |-- lseg x z * next z v.
Lemma allp_andp1 {A}{NA: NatDed A}{B}: forall (any: B) (P: B -> A) Q,
allp P && Q = ALL x:B, P x && Q.
Lemma list_append:  (* U3 *)
forall x y, lseg x y * lseg y 0 |-- lseg x 0.
Lemma lseg_U5:
forall x y z w, z<>w -> lseg x y * next y z * lseg z w |-- lseg x z * lseg z w.
Lemma lseg_cons_in_list_context:
forall x y z, lseg x y * next y z * lseg z 0 |-- lseg x z * lseg z 0.