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.

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.