intros.
simpl.
rewrite (space_denote_permute _ _ H).
trivial.
Qed.

(* Specifications: *)
Lemma Lseg_unfold_neq:
forall e nextv pi sigma0 e0 e1 sigma s,
fresh freshmax_expr e nextv ->
fresh freshmax_assertion (Assertion pi (sigma0 ++ Lseg e0 e1 :: sigma)) nextv ->
(e === e0) s ->
list_denote pn_atom_denote (@andp _)
(space_denote (sigma0 ++ Lseg e0 e1 :: sigma)) pi s ->
~ (e0 === e1) s ->
existsv nextv
(assertion_denote (Assertion pi (Next e (Var nextv) :: Lseg (Var nextv) e1 :: sigma0 ++ sigma))) s.
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).
Lemma incon_e: forall P, incon P = true -> assertion_denote P |-- FF.
Lemma exorcize_sound_nil:
forall e pnatoms nextv nextv2 sigma0 cl,
Ident.lt nextv nextv2 ->
exorcize e pnatoms sigma0 [ ] nextv = Some cl ->
(assertion_denote (Assertion pnatoms (rev sigma0 ++ [ ]))
|-- fold_right
(fun P => orp (existsv nextv (assertion_denote P))) FF cl) /\
(forall (Q : assertion),
In Q cl ->
(match Q with
|Assertion  _ (Next e0 _ :: _) => e=e0
| _ => False
end /\
fresh freshmax_assertion Q nextv2)).
(* need this bogus "exorcize_e" lemma, because doing it in-line, in the obvious way using case_eq or (remember; destruct) makes the Qed take forever. *)
Lemma exorcize_e:
forall e pnatoms sigma0 e0 e1 sigma nextv cl,
exorcize e pnatoms sigma0 (Lseg e0 e1 :: sigma) nextv = Some cl ->
(entailment_denote
(Entailment (Assertion pnatoms (rev (Lseg e0 e1 :: sigma0) ++ sigma))
(Assertion [Equ e e0] (rev (Lseg e0 e1 :: sigma0) ++ sigma)))
/\ (exists cl',
exorcize e (Equ e0 e1 :: pnatoms) (Lseg e0 e1 :: sigma0) sigma nextv = Some cl' /\
cl = (Assertion pnatoms
(Next e (Var nextv) :: Lseg (Var nextv) e1 :: rev sigma0 ++ sigma)) :: cl'))
\/ exorcize e pnatoms (Lseg e0 e1 :: sigma0) sigma nextv = Some cl.
Lemma exorcize_sound:
forall e pnatoms sigma nextv nextv2
(FRESHe: fresh freshmax_expr e nextv)
(LT: Ident.lt nextv nextv2),
(fresh freshmax_assertion (Assertion pnatoms sigma) nextv) ->
forall cl,
(exorcize e pnatoms nil sigma nextv) = Some cl ->
(assertion_denote (Assertion pnatoms sigma)
|-- fold_right (fun P => orp (existsv nextv (assertion_denote P))) FF cl) /\
(forall Q,
In Q cl ->
match Q with
|Assertion _ (Next e0 _ :: _) => e=e0
| _ => False
end /\
fresh freshmax_assertion Q nextv2).
(* need this bogus "isolate_e" lemma, because doing it in-line, in the obvious way using case_eq or (remember; destruct) makes the Qed take forever. *)
Lemma isolate_e:
forall e pnatoms sigma0 e0 e1 sigma nextv N results,
isolate' e pnatoms sigma0 (Lseg e0 e1 :: sigma) nextv N = Some results ->
(entailment_denote
(Entailment (Assertion pnatoms (rev sigma0 ++ Lseg e0 e1 :: sigma))
(Assertion [Equ e e0, Nequ e0 e1] (rev sigma0 ++ Lseg e0 e1 :: sigma)))
/\ results = [Assertion pnatoms (Next e (Var nextv) :: Lseg (Var nextv) e1 :: rev sigma0 ++ sigma)]
\/ (entailment_denote
(Entailment (Assertion pnatoms (rev sigma0 ++ Lseg e0 e1 :: sigma))
(Assertion [Equ e e0] (rev sigma0 ++ Lseg e0 e1 :: sigma)))
/\ isolate' e pnatoms (Lseg e0 e1 :: sigma0) sigma nextv (S N) =Some results)
\/ isolate' e pnatoms (Lseg e0 e1 :: sigma0) sigma nextv N = Some results).
Lemma if_bool_e:
forall {A: Type} (b: bool) (c d e: A),
(if b then c else d) = e ->
b=true /\ c=e \/ b=false /\ d=e.
Lemma isolate_Next1:
forall e e1 sigma nextv nextv2 pnatoms sigma0
(LT: Ident.lt nextv nextv2),
fresh freshmax_assertion
(Assertion pnatoms (rev sigma0 ++ Next e e1 :: sigma)) nextv ->
(assertion_denote (Assertion pnatoms (rev sigma0 ++ Next e e1 :: sigma))
|-- fold_right (fun P : assertion => orp (existsv nextv (assertion_denote P))) FF
[Assertion pnatoms (Next e e1 :: rev sigma0 ++ sigma)]) /\
(forall Q : assertion,
In Q [(Assertion pnatoms (Next e e1 :: rev sigma0 ++ sigma))] ->
match Q with
|Assertion _ (Next e0 _ :: _) => e=e0
| _ => False
end  /\
fresh freshmax_assertion Q nextv2).
Lemma isolate_Next2:
forall e e0 e1 sigma nextv nextv2 pnatoms sigma0
(FRESHe:  fresh freshmax_expr e nextv)
(LT: Ident.lt nextv nextv2),
entailment_denote
(Entailment (Assertion pnatoms (rev sigma0 ++ Next e0 e1 :: sigma))
(Assertion [Equ e e0] (rev sigma0 ++ Next e0 e1 :: sigma))) ->
fresh freshmax_assertion
(Assertion pnatoms (rev sigma0 ++ Next e0 e1 :: sigma)) nextv ->
(assertion_denote (Assertion pnatoms (rev sigma0 ++ Next e0 e1 :: sigma))
|-- fold_right (fun P : assertion => orp (existsv nextv (assertion_denote P))) FF
[Assertion pnatoms (Next e e1 :: rev sigma0 ++ sigma)]) /\
(forall (Q : assertion),
In Q [Assertion pnatoms (Next e e1 :: rev sigma0 ++ sigma)] ->
match Q with
|Assertion _ (Next e0 _ :: _) => e=e0
| _ => False
end/\
fresh freshmax_assertion Q nextv2).
Lemma isolate_Lseg1: forall e e0 e1 sigma nextv nextv2 pnatoms sigma0
(FRESHe : fresh freshmax_expr e nextv)
(LT: Ident.lt nextv nextv2),
entailment_denote
(Entailment (Assertion pnatoms (rev sigma0 ++ Lseg e0 e1 :: sigma))
(Assertion [Equ e e0, Nequ e0 e1] (rev sigma0 ++ Lseg e0 e1 :: sigma))) ->
fresh freshmax_assertion
(Assertion pnatoms (rev sigma0 ++ Lseg e0 e1 :: sigma)) nextv ->
(assertion_denote (Assertion pnatoms (rev sigma0 ++ Lseg e0 e1 :: 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)]) /\
(forall Q : assertion,
In Q
[Assertion pnatoms (Next e (Var nextv) :: Lseg (Var nextv) e1 :: rev sigma0 ++ sigma)] ->
match Q with
|Assertion _ (Next e0 _ :: _) => e=e0
| _ => False
end /\
fresh freshmax_assertion Q nextv2).
Lemma isolate'_sound:
forall e pnatoms sigma nextv nextv2 results
(LT: Ident.lt nextv nextv2),
isolate' e pnatoms nil sigma nextv 0 = Some results ->
fresh freshmax_expr e nextv ->
fresh freshmax_assertion (Assertion pnatoms sigma) nextv ->
assertion_denote (Assertion pnatoms sigma) |--
fold_right (fun P => orp (existsv nextv (assertion_denote P))) FF results /\
(forall Q, In Q results ->
match Q with
|Assertion _ (Next e0 _ :: _) => e=e0
| _ => False
end /\
fresh freshmax_assertion Q nextv2).
Lemma isolate_sound:
forall e P nextv nextv2 results
(LT: Ident.lt nextv nextv2),
isolate e P nextv = Some results ->
fresh freshmax_expr e nextv ->
fresh freshmax_assertion P nextv ->
assertion_denote P |--
fold_right (fun P => orp (existsv nextv (assertion_denote P))) FF results /\
forall Q, In Q results ->
match Q with
|Assertion _ (Next e0 _ :: _) => e=e0
| _ => False
end /\
fresh freshmax_assertion Q nextv2.