End SUBST_SOUND.
Module Subst_Sound (VSD: VERISTAR_DEFS) : SUBST_SOUND with Module VSD := VSD.
Module VSD := VSD.

(* Specifications: *)
(*Substitution Lemmas*)
Lemma subst_expr_sound : forall i e e' s,
(subst_expr i e e' ==
match e' with Nil => Nil | Var x  => if Var.eq_dec i x then e else e'
end) s.
Lemma subst_space_sound : forall i e a,
space_atom_denote (subst_space i e a) =
match a with
| Next x y => space_atom_denote (Next (subst_expr i e x) (subst_expr i e y))
| Lseg x y => space_atom_denote (Lseg (subst_expr i e x) (subst_expr i e y))
end.
Lemma subst_list_denote_sound :
forall A Q (l : list A) (denote: A -> spred) (subst: A -> A) B,
list_denote denote Q B (map subst l) =
match map subst l with
| nil => B
| _ :: _ => list_denote denote Q B (map subst l)
end.
Lemma subst_list_denote_sound_space : forall (l : list space_atom) i e,
list_denote space_atom_denote sepcon emp (map (subst_space i e) l) =
match map (subst_space i e) l with
| nil => emp
| _ :: _ => list_denote space_atom_denote sepcon emp (map (subst_space i e) l)
end.
Lemma subst_list_denote_sound_intersection : forall (l : list pure_atom) i e B,
list_denote pure_atom_denote (@andp state) B (map (subst_pure i e) l) =
match map (subst_pure i e) l with
| nil => B
| _ :: _ => list_denote pure_atom_denote (@andp state) B (map (subst_pure i e) l)
end.
Lemma subst_pures_denote_sound_intersection : forall (l : list pure_atom) i e B,
list_denote pure_atom_denote (@andp state) B (subst_pures i e l) =
match map (subst_pure i e) l with
| nil => B
| _ :: _ => list_denote pure_atom_denote (@andp state) B (subst_pures i e l)
end.
Lemma subst_list_denote_sound_union : forall (l : list pure_atom) i e B,
list_denote pure_atom_denote (@orp state) B (map (subst_pure i e) l) =
match map (subst_pure i e) l with
| nil => B
| _ :: _ => list_denote pure_atom_denote (@orp state) B (map (subst_pure i e) l)
end.
Lemma subst_pures_denote_sound_union : forall (l : list pure_atom) i e B,
list_denote pure_atom_denote (@orp state) B (subst_pures i e l) =
match map (subst_pure i e) l with
| nil => B
| _ :: _ => list_denote pure_atom_denote (@orp state) B (subst_pures i e l)
end.
Lemma subst_list_denote_sound0 : forall {A} (Q : spred -> spred -> spred) (l : list A)
(denote: A -> spred) (subst: A -> A) (B:spred),
list_denote denote Q B (map subst l) =
match l with
| nil => B
| x :: t => Q (denote (subst x)) (list_denote denote Q B (map subst t))
end.
Lemma subst_list_denote_sound_space0 : forall (l : list space_atom) i e,
list_denote space_atom_denote sepcon emp (map (subst_space i e) l) =
match l with
| nil => emp
| x :: t => sepcon (space_atom_denote (subst_space i e x))
(list_denote space_atom_denote sepcon emp (map (subst_space i e) t))
end.
Lemma subst_list_denote_sound_intersection0 : forall (l : list pure_atom) i e B,
list_denote pure_atom_denote (@andp state) B (map (subst_pure i e) l) =
match l with
| nil => B
| x :: t => (@andp state) (pure_atom_denote (subst_pure i e x))
(list_denote pure_atom_denote (@andp state) B (subst_pures i e t))
end.
Lemma subst_list_denote_sound_union0 : forall (l : list pure_atom) i e B,
list_denote pure_atom_denote (@orp state) B (map (subst_pure i e) l) =
match l with
| nil => B
| x :: t => (@orp state) (pure_atom_denote (subst_pure i e x))
(list_denote pure_atom_denote (@orp state) B (subst_pures i e t))
end.
Lemma subst_spaces_sound: forall AL i e,
space_denote (map (subst_space i e) AL)  =
list_denote (fun a => space_atom_denote (subst_space i e a)) sepcon emp AL.
Lemma subst_pure_sound: forall i e a,
pure_atom_denote (subst_pure i e a) =
match a with Eqv e1 e2 => pure_atom_denote (Eqv (subst_expr i e e1) (subst_expr i e e2))
end.
Lemma subst_pures_inter_sound: forall P i e B,
list_denote pure_atom_denote (@andp state) B (map (subst_pure i e)P) =
list_denote (fun a => pure_atom_denote (subst_pure i e a)) (@andp state) B P.
Lemma subst_pures_union_sound: forall P i e B,
list_denote pure_atom_denote (@orp state) B (map (subst_pure i e)P) =
list_denote (fun a => pure_atom_denote (subst_pure i e a)) (@orp state) B P.
Lemma subst_clause_sound: forall cl i e,
clause_denote (subst_clause i e cl) =
match cl with
| PureClause pa pa' _ _ =>
clause_denote (mkPureClause (subst_pures_delete i e pa) (subst_pures i e pa'))
| NegSpaceClause pa sa pa' =>
clause_denote (NegSpaceClause (subst_pures_delete i e pa) (subst_spaces i e sa) (subst_pures i e pa'))
| PosSpaceClause pa pa' sa' =>
clause_denote (PosSpaceClause (subst_pures_delete i e pa) (subst_pures i e pa') (subst_spaces i e sa'))
end.
Lemma expr_cmp_eq: forall e e',
expr_cmp e e' = Eq -> (e == e') = TT.
Lemma expr_cmp_eq': forall e e' s,
expr_cmp e e' = Eq -> (e == e') s.
Lemma remove_trivial_atoms_correct : forall pcs B,
list_denote pure_atom_denote (@andp state) B pcs =
list_denote pure_atom_denote (@andp state) B (remove_trivial_atoms pcs).
Lemma subst_pures_delete_same : forall i e pcs B,
list_denote pure_atom_denote (@andp state) B (subst_pures_delete i e pcs) =
list_denote pure_atom_denote (@andp state) B (subst_pures i e pcs).
Lemma clause_denote_PureClause_sound: forall i e Gamma Delta,
clause_denote (mkPureClause (subst_pures_delete i e Gamma) Delta) =
clause_denote (mkPureClause (subst_pures i e Gamma) Delta).
Lemma clause_denote_NegSpaceClause_sound: forall i e Gamma Sigma Delta,
clause_denote (NegSpaceClause (subst_pures_delete i e Gamma) Sigma Delta) =
clause_denote (NegSpaceClause (subst_pures i e Gamma) Sigma Delta).
Lemma clause_denote_PosSpaceClause_sound: forall i e Gamma Sigma Delta,
clause_denote (PosSpaceClause (subst_pures_delete i e Gamma) Sigma Delta) =
clause_denote (PosSpaceClause (subst_pures i e Gamma) Sigma Delta).