intros.
rewrite Space_denote_cons in SD1, SD2.
destruct SD1 as [s1 [s1' [J1 [K1 K1']]]].
destruct SD2 as [s2 [s2' [J2 [K2 K2']]]].
simpl in K1, K2.
repeat rewrite <- (expr_denote_join _ _ _ _ J1) in K1.
repeat rewrite <- (expr_denote_join _ _ _ _ J2) in K2.
assert (s2 = s1 /\ s2' = s1').
assert (hp s2 = hp s1 /\ hp s2' = hp s1').
eapply (lseg_unique _ _ _ K1 _ K2 (hp s1') (hp s)). apply J1. apply J2.
destruct H as [HP1 HP2]. destruct s2. destruct s2'. destruct s1. destruct s1'.
destruct (join_stacks_eq _ _ _ J1).
destruct (join_stacks_eq _ _ _ J2).
simpl in *. subst. subst. split; trivial.
destruct H; subst. clear J2 K2.
rewrite Space_denote_cons in K1', K2'.
destruct K1' as [t1 [t1' [I1 [G1 G1']]]].
destruct K2' as [t2 [t2' [I2 [G2 G2']]]].
simpl in G1.
repeat rewrite <- (expr_denote_join _ _ _ _ I1) in G1.
repeat rewrite <- (expr_denote_join _ _ _ _ (join_comm J1)) in G1.
simpl in G2. remember (val2loc (expr_denote z t2)) as b; destruct b; subst.
destruct (join_assoc (join_comm I1) (join_comm J1)) as [u [JJ KK]].
exists u. exists t1'. split. apply (join_comm KK).
split; try assumption.
eapply lseg_lseg_app. rewrite <- (expr_denote_join _ _ _ _ (join_comm KK)). apply K1.
rewrite <- (expr_denote_join _ _ _ _ (join_comm KK)). apply G1.
apply JJ.
rewrite <- (expr_denote_join _ _ _ _ I2) in Heqb.
rewrite <- (expr_denote_join _ _ _ _ (join_comm J1)) in Heqb.
rewrite <- (expr_denote_join _ _ _ _ (join_comm KK)). rewrite <- Heqb. reflexivity.
assert (emp_at l0 (hp s1)).
destruct G2. apply rawnext2rawnext' in H.
destruct (@rawnext_at1 _ _ _ (hp t2') (hp s1') H). apply I2.
destruct (@rawnext_at1 _ _ _ (hp s1) (hp s) H2). apply join_comm. apply J1. assumption.
eapply (@emp_at_join (hp t1) (hp s1) (hp u)). apply JJ.
split; trivial.
destruct (lseg_end _ _ _ G1).
destruct H0. apply heap_gempty. apply H1.
destruct H0. rewrite <- (expr_denote_join _ _ _ _ I2) in Heqb.
rewrite <- (expr_denote_join _ _ _ _ (join_comm J1)) in Heqb.
rewrite H0 in Heqb. rewrite nil_not_loc in Heqb. inversion Heqb.
destruct H0 as [lc [vlc elc]]. rewrite <- (expr_denote_join _ _ _ _ I2) in Heqb.
rewrite <- (expr_denote_join _ _ _ _ (join_comm J1)) in Heqb.
rewrite vlc in Heqb. inversion Heqb. subst. assumption.
contradiction.
Qed.

(* Specifications: *)
Lemma unfolding4_sound' : forall  sigma2 sigma0 sigma1 sig2' s,
In sig2' (unfolding4NPR' sigma0 sigma1 sigma2) ->
space_denote sigma1 s -> space_denote sig2' s ->
space_denote (sigma0++ sigma2) s.
Lemma unfolding4_sound: forall sc1 sc2 s
(SC1: clause_denote sc1 s) (SC2: clause_denote sc2 s),
listd clause_denote inter TT (unfolding4 sc1 sc2) s.
Lemma U5_axiom: forall x y z w sigma' sigma h
(K: (sepcon (lseg x y) (sepcon (lseg z w) sigma')) h)
(K': (sepcon (lseg x y) (sepcon (lseg y z) sigma)) h),
(z=w \/ (sepcon (lseg x z) sigma)  h).
Lemma U5: forall x y z w sigma1 sigma s
(K: space_denote (Lseg x y :: Lseg z w :: sigma1) s)
(K': space_denote (Lseg x y:: Lseg y z :: sigma) s),
pure_atom_denote (Eqv z w) s \/ space_denote (Lseg x z :: sigma) s.
Lemma unfolding6NPR'_sound: forall  sigma2 sigma0 sigma1 sig2' p s,
In (p,sig2') (unfolding6NPR' sigma0 sigma1 sigma2) ->
space_denote sigma1 s -> space_denote sig2' s ->
pure_atom_denote p s \/ (space_denote (sigma0++ sigma2)) s.
Lemma unfolding6_sound: forall sc1 sc2 s
(SC1: clause_denote sc1 s) (SC2: clause_denote sc2 s),
listd clause_denote inter TT (unfolding6 sc1 sc2) s.
(*an axiom schema for an additional (but apparently superfluous) rule eliminating loops in lsegs*)
Lemma U7_axiomSchema: forall x y z u Sigma s,
space_denote (Lseg y z::Lseg z y::Lseg x y::Lseg u z::Sigma) s ->
space_denote (Lseg x z::Lseg u y::Sigma) s.
Lemma clause_setd_listd l s :
listd clause_denote inter TT l s ->
setd clause_denote inter TT (clause_list2set l) s.