Definition Rule_U3 (nc pc : clause) :=
match nc , pc with
PosSpaceClause Gamma Delta ((Lseg x y)::Sigma) ,
NegSpaceClause Gamma' (Lseg x' Nil::Sigma') Delta' =>
match expr_cmp x x' with
Eq => Some (NegSpaceClause Gamma' (Lseg x y::Lseg y Nil::Sigma') Delta')
|_ => None
end
| _ , _ => None
end.

(* Specifications: *)
(*The axiom schema for U3 from Figure 2, used as an auxiliary lemma for the proof of U3*)
Lemma U3_axiomSchema: forall x y Sigma s,
space_denote (Lseg x y::Lseg y Nil::Sigma) s ->
space_denote (Lseg x Nil::Sigma) s.
Lemma U3_sound: forall nc pc c s,
clause_denote nc s -> clause_denote pc s ->
Rule_U3 nc pc = Some c ->
clause_denote c s.
Lemma U3_sound': forall nc pc c s,
clause_denote pc s ->
Rule_U3 nc pc = Some c ->
clause_denote c s.
Lemma unfolding3'_sound: forall  sigma2 sigma0 sigma1 sig2' s,
In sig2' (unfolding3' sigma0 sigma1 sigma2) ->
space_denote sig2' s -> space_denote (sigma0++sigma2) s.
Lemma unfolding3_sound: forall sc1 sc2,
forall s, clause_denote sc2 s
-> listd clause_denote inter TT (unfolding3 sc1 sc2) s.
Lemma lseg_prefix: forall x y z l h,
lseg x y h ->
val2loc z = Some l ->
~emp_at l h ->
exists h' : heap, lseg x z h' /\
join_sub h' h /\ emp_at l h'.
(*The axiom schema for U4 from Figure 2, used as an auxiliary lemma for the proof of U4*)
Lemma U4_axiomSchema: forall x y z w Sigma s,
space_denote (Lseg x y::Lseg y z::Next z w::Sigma) s ->
space_denote (Lseg x z::Next z w::Sigma) s.
Lemma next_in_dom_app: forall v sigma sigma',
true = next_in_dom v sigma -> true = next_in_dom v (sigma ++ sigma').
Lemma next_in_dom_true: forall v sigma s,
true = next_in_dom v sigma ->
space_denote sigma s ->
exists w, exists sig, space_denote (Next (Var v) w::sig) s /\
Permutation (Next (Var v) w::sig) sigma.
Lemma lseg_in_dom_app: forall sig p v sigma,
In p (lseg_in_dom_atoms v sigma) -> In p (lseg_in_dom_atoms v (sig ++ sigma)).
Lemma incl_nil: forall {A} (l:list A) , incl l [] -> l = [].
Lemma incl_consD: forall {A} (a:A) sigma sig, incl (a :: sigma) sig ->
In a sig /\ incl sigma sig.
Lemma lseg_in_dom_app2: forall sig p v sigma,
In p (lseg_in_dom_atoms v sigma) -> In p (lseg_in_dom_atoms v (sigma ++ sig)).
Lemma pure_atom_denote_join: forall p s1 s2 s,
join s1 s2 s ->
pure_atom_denote p s = pure_atom_denote p s1.
Lemma lseg_in_dom_atoms_Space_denotePerm:
forall sig p v s,
(space_denote sig) s -> In p (lseg_in_dom_atoms v sig) ->
pure_atom_denote p s \/ (exists sig1, exists y,
space_denote (Lseg (Var v) y::sig1) s /\
Permutation sig (Lseg (Var v) y :: sig1)).
Lemma lseg_in_dom_atoms_space_denote_perm_strong:
forall sig p v s,
(space_denote sig) s -> In p (lseg_in_dom_atoms v sig) ->
exists y, (p=Eqv (Var v) y \/ p=Eqv y (Var v)) /\
(pure_atom_denote p s \/
exists sig1,
space_denote (Lseg (Var v) y::sig1) s /\
Permutation sig (Lseg (Var v) y :: sig1)).
Lemma app_app: forall {A} (a:A) l ll l1 l2,
l ++ ll = l1 ++ a :: l2 ->
exists m, exists n,
(l = l1 ++ a :: n /\ l2 = n ++ ll) \/
(ll = m ++ a :: l2 /\ l1=l ++ m).
Lemma Perm_aux1: forall {A} (a:A) l0 l1 l2,
Permutation l0 (l1 ++ a :: l2) ->
exists l3 : list A,
exists l4 : list A, l0 = l3 ++ a :: l4.
Lemma Perm_aux: forall {A} (a a':A) l l',
Permutation (a::l) (a'::l') ->
(a=a' /\ Permutation l l') \/
exists l1, exists l2, l = l1 ++ a'::l2 /\ Permutation (a::l1++l2) l'.
Lemma lseg_in_dom2Lemma: forall x y z sigma,
Some y = lseg_in_dom2 x (Var z) sigma ->
exists sigma2, Permutation sigma (Lseg (Var x) y :: sigma2).
Lemma lseg_in_dom2Lemma_strong: forall x y z sigma,
Some y = lseg_in_dom2 x (Var z) sigma ->
exists sigma2, Permutation sigma (Lseg (Var x) y :: sigma2) /\
(expr_eq y (Var z) =false).
Lemma lseg_unique: forall x y s
(L:lseg x y s) s' (L': lseg x y s')
t r (J: join s t r) t' (J': join s' t' r),
s'=s /\ t'=t.
Lemma lseg_emp_at: forall h x y h1 (L:lseg x y h1) h2 (L2: lseg x y h2)
h1' (J1:join h1 h1' h) h2' (J2: join h2 h2' h) l (E: emp_at l h2), emp_at l h1.
Lemma U4: forall x y z w sigma l s
(SD1 : space_denote (Lseg x y :: Lseg y z :: sigma) s)
(SD2: space_denote (Lseg x y :: Next z w :: l) s),
space_denote (Lseg x z :: sigma) s.