Module CL := CL_Sound VSM. Import CL.
(* rule w2 *)
Ltac dsepcon :=
match goal with
[ H : sepcon _ _ _ |- _ ] =>
let s1 := fresh "s" in
let s2 := fresh "s" in
let JOIN := fresh "JOIN" in
let H1 := fresh "H" in
let H2 := fresh "H" in
destruct H as [s1 [s2 [JOIN [H1 H2]]]]
end.
Hint Resolve nil_or_loc_full.
Proof with auto; try congruence; try solve [
destruct B as [x' [y' [C [D E]]]]; destruct (IHsigma A y' E) as [s0 [z [F G]]];
subst; exists s0; exists z; split; simpl; auto;
apply join_sub_trans with (b := y'); simpl; auto;
eapply join_join_sub'; eauto].
intros A B; revert s B; induction sigma; intros s B. simpl in A...
simpl in A. remember a as b; destruct b... remember e as b'; destruct b'...
destruct (Ident.eq_dec x v)... destruct B as [x' [y' [C [D E]]]].
subst; exists x'; exists e0; split... solve [eapply join_join_sub'; eauto].
Qed.
Proof with try congruence.
intros A B C D; destruct (next_in_dom_rawnext _ _ _ A B) as [s' [z' [F G]]].
simpl in F, C. cut (stk s2 = stk s'). intro Heq; rewrite Heq in *; clear Heq.
destruct (val2loc (env_get (stk s') x))...
destruct F as [H I]; destruct C as [J K].
assert (L : join_sub (hp s') (hp s1)).
destruct G as [x0 [G1 G2]]; exists (hp x0)...
assert (M : joins (hp s1) (hp s2)).
destruct D as [x0 [D1 D2]]; exists (hp x0)...
generalize (next_next_join_False _ _ (hp s2) _ _ _ _ H L J)... intro N.
apply N... apply join_sub_refl.
destruct G as [? [[G0 G1] G']]; destruct D as [? [[D0 D1] D']].
solve [rewrite G0, G1, D0; auto].
Qed.

Lemma join_stacks_eq : forall s0 s1 s : state,
join s0 s1 s -> stk s0=stk s1 /\ stk s0=stk s.