Module VeriStarSound := VSS.
(********duplicate temporarily a lemma from wellformed_sound. Maybe some of the lemmas there Repair import-structire later****** ********)
(************end of duplicated lemma ********)
(* Definition agree_except (x: var) (s s': state) : Prop := (forall x', x' <> x -> stack_get (stk s) (Some x') = stack_get (stk s') (Some x')) /\ hp s = hp s'.  Lemma agree_except_refl: forall x s, agree_except x s s. Hint Resolve agree_except_refl.  Definition existsv (nextv: var) (P: spred) : spred := fun s => exists s', agree_except nextv s s' /\ P s'. *)
Definition existsv (nextv: var) (P: spred) : spred :=
fun s => exists y,  P (State (env_set nextv y (stk s)) (hp s)).
Definition fresh {A} (f: A -> var) (a: A) (x: var) : Prop :=  Ident.lt (f a) x.
Ltac do_fresh1 :=
repeat match goal with H: Ile _ _ |- _ => revert H
| H: Ident.lt _ _ |- _ => revert H
| H: fresh _ _ _ |- _ => revert H end;
clear;
unfold fresh; simpl;
repeat ((rewrite freshmax_list_app || rewrite freshmax_list_rev
|| rewrite varmax_minid || rewrite varmax_minid'); simpl).
Ltac do_fresh :=
do_fresh1; intros;
repeat match goal with
|  H: Ident.lt (var_max _ _) _ |- _ => apply var_max_split in H; destruct H
end;
repeat apply var_max_intro; auto;
try solve [etransitivity; eauto].
(*  repeat rewrite Zpos_succ_morphism in *; solve [auto | omega]. *)
Definition set_in_state nextv z s := State (env_set nextv z (stk s)) (hp s).
(* Lemma agree_except_sym: forall x s s', agree_except x s s' -> agree_except x s' s. *)
intros.
unfold space_denote.
apply (listd_perm space_atom_denote _ emp (sepconS _ _) (@sepconA state _ _) l l' H) .
Qed.
intros.
simpl.
rewrite (space_denote_permute _ _ H).
trivial.
Qed.

Lemma exorcize_sound_Lseg:
forall (e : expr) (pnatoms : list pn_atom) (e0 e1 : expr)
(sigma : list space_atom) (nextv : var) (nextv2 : var)
(sigma0 : list space_atom) (l : list assertion),
fresh freshmax_expr e nextv ->
Ident.lt nextv nextv2 ->
fresh freshmax_assertion
(Assertion pnatoms (rev (Lseg e0 e1 :: sigma0) ++ sigma)) nextv ->
entailment_denote
(Entailment (Assertion pnatoms (rev (Lseg e0 e1 :: sigma0) ++ sigma))
(Assertion [Equ e e0] (rev (Lseg e0 e1 :: sigma0) ++ sigma))) ->
(assertion_denote
(Assertion (Equ e0 e1 :: pnatoms) (rev (Lseg e0 e1 :: sigma0) ++ sigma))
|-- fold_right
(fun P => orp (existsv nextv (assertion_denote P))) FF l) /\
(forall (Q : assertion),
In Q l ->
match Q with
|Assertion _ (Next e0 _ :: _) => e=e0
| _ => False
end /\
fresh freshmax_assertion Q nextv2) ->
(assertion_denote (Assertion pnatoms (rev (Lseg e0 e1 :: sigma0) ++ sigma))
|-- fold_right
(fun P => orp (existsv nextv (assertion_denote P))) FF
(Assertion pnatoms (Next e (Var nextv) :: Lseg (Var nextv) e1 :: rev sigma0 ++ sigma) :: l)) /\
(forall Q,
In Q (Assertion pnatoms (Next e (Var nextv) :: Lseg (Var nextv) e1 :: rev sigma0 ++ sigma) :: l) ->
match Q with
|Assertion _ (Next e0 _ :: _) => e=e0
| _ => False
end /\
fresh freshmax_assertion Q nextv2).