Module VSD := VSD.

(* Specifications: *)
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 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).