Library Soundness
Require Import Assertions.
Require Import HahnBase.
Require Import Heaps.
Require Import HeapSolver.
Require Import List.
Require Import Permissions.
Require Import PermSolver.
Require Import Permutation.
Require Import PermutationTactic.
Require Import Prelude.
Require Import Process.
Require Import ProcMap.
Require Import ProcMapSolver.
Require Import Programs.
Require Import QArith Qcanon.
Import ListNotations.
Set Implicit Arguments.
Require Import HahnBase.
Require Import Heaps.
Require Import HeapSolver.
Require Import List.
Require Import Permissions.
Require Import PermSolver.
Require Import Permutation.
Require Import PermutationTactic.
Require Import Prelude.
Require Import Process.
Require Import ProcMap.
Require Import ProcMapSolver.
Require Import Programs.
Require Import QArith Qcanon.
Import ListNotations.
Set Implicit Arguments.
Module Type Soundness
(domains : Domains)
(heaps : Heaps domains)
(hsolver : HeapSolver domains heaps)
(procs : Processes domains)
(procmaps : ProcMaps domains heaps procs)
(progs : Programs domains heaps procs procmaps)
(pmsolver : ProcMapSolver domains heaps procs procmaps)
(assns : Assertions domains heaps hsolver procs procmaps progs pmsolver).
Export domains heaps hsolver procs procmaps pmsolver progs assns.
Process environments
Parameter precondition : HProc -> HCond.
Moreover, the remaining theory requires that all defined processes
are safe (with respect to psafe).
Parameter precondition_safe :
forall P s ps,
pcond_eval (cDehybridise (precondition P) s) ps = true ->
psafe (pDehybridise P s) ps.
Adequacy of process maps
Definition pmeSafe (h : Heap)(c : ProcMapEntry) : Prop :=
match c with
| PEelem _ P xs f =>
forall ps,
(forall x, In x xs -> h (f x) = Some (ps x)) ->
psafe P ps
| PEfree => True
| PEinvalid => False
end.
Safety of process map entries is preserved by bisimilarity.
Lemma pmeSafe_bisim :
forall h c1 c2,
pmeBisim c1 c2 -> pmeSafe h c1 -> pmeSafe h c2.
Add Parametric Morphism : pmeSafe
with signature eq ==> pmeBisim ==> iff
as pmeSafe_bisim_mor.
Free entries are trivially safe.
Lemma pmeSafe_iden :
forall h, pmeSafe h PEfree.
Safety of process map entries c is stable under replacing
heaps that agree on all locations covered by c.
Lemma pmeSafe_heap_acc :
forall h1 h2 c,
(forall l, In l (pmeProj c) -> h1 l = h2 l) ->
pmeSafe h1 c ->
pmeSafe h2 c.
Safety of process map entries is stable
under extending (snapshot) heaps.
Lemma pmeSafe_subheap :
forall h1 h2 c,
(forall l v, h2 l = Some v -> h1 l = Some v) ->
pmeSafe h1 c ->
pmeSafe h2 c.
Lemma pmeSafe_weaken_snapshot_l :
forall ph1 ph2 c,
phDisj ph1 ph2 ->
pmeSafe (phSnapshot (phUnion ph1 ph2)) c ->
pmeSafe (phSnapshot ph1) c.
Lemma pmeSafe_weaken_snapshot_r :
forall ph1 ph2 c,
phDisj ph1 ph2 ->
pmeSafe (phSnapshot (phUnion ph1 ph2)) c ->
pmeSafe (phSnapshot ph2) c.
Removing entry information does not invalidate safety.
Lemma pmeSafe_weaken_l :
forall h c1 c2,
pmeSafe h (pmeUnion c1 c2) ->
pmeSafe h c1.
Lemma pmeSafe_weaken_r :
forall h c1 c2,
pmeSafe h (pmeUnion c1 c2) ->
pmeSafe h c2.
Any process map is defined to be safe (with respect to some heap)
if all its entries are safe with respect to pmeSafe.
Definition pmSafe (h : Heap)(pm : ProcMap) : Prop :=
forall pid, pmeSafe h (pm pid).
The identity process map is trivially safe.
Lemma pmSafe_iden :
forall h, pmSafe h pmIden.
Bisimilarity preserves safety.
Lemma pmSafe_bisim :
forall h pm1 pm2,
pmBisim pm1 pm2 -> pmSafe h pm1 -> pmSafe h pm2.
Add Parametric Morphism : pmSafe
with signature eq ==> pmBisim ==> iff
as pmSafe_bisim_mor.
Process map safety is stable under extensions
of the (snapshot) heap.
Lemma pmSafe_subheap :
forall h1 h2 pm,
(forall l v, h2 l = Some v -> h1 l = Some v) ->
pmSafe h1 pm ->
pmSafe h2 pm.
Lemma pmSafe_weaken_snapshot_l :
forall ph1 ph2 pm,
phDisj ph1 ph2 ->
pmSafe (phSnapshot (phUnion ph1 ph2)) pm ->
pmSafe (phSnapshot ph1) pm.
Lemma pmSafe_weaken_snapshot_r :
forall ph1 ph2 pm,
phDisj ph1 ph2 ->
pmSafe (phSnapshot (phUnion ph1 ph2)) pm ->
pmSafe (phSnapshot ph2) pm.
Removing process map information does not invalidate safety.
Lemma pmSafe_weaken_l :
forall h pm1 pm2,
pmSafe h (pmUnion pm1 pm2) ->
pmSafe h pm1.
Lemma pmSafe_weaken_r :
forall h pm1 pm2,
pmSafe h (pmUnion pm1 pm2) ->
pmSafe h pm2.
Well-structured process maps
Definition pmWs (pm : ProcMap) : Prop :=
forall p1 p2 l,
In l (pmeProj (pm p1)) -> In l (pmeProj (pm p2)) -> p1 = p2.
Bisimilarity preserves well-structuredness of process maps.
Lemma pmWs_bisim :
forall pm1 pm2,
pmBisim pm1 pm2 -> pmWs pm1 -> pmWs pm2.
Add Parametric Morphism : pmWs
with signature pmBisim ==> iff as pmWs_mor.
The identity process map is trivially well-structured.
Lemma pmWs_iden : pmWs pmIden.
Process map agreement preserves well-structuredness.
Lemma pmWs_agree :
forall pm1 pm2,
pmAgree pm1 pm2 -> pmWs pm1 -> pmWs pm2.
Add Parametric Morphism : pmWs
with signature pmAgree ==> iff as pmWs_agree_mor.
Below are several other useful properties
of well-structuredness.
Lemma pmWs_update :
forall pm p c,
(forall p' l, p <> p' -> In l (pmeProj c) -> ~ In l (pmeProj (pm p'))) ->
pmWs pm ->
pmWs (pmUpdate pm p c).
Adequacy
Definition invariant_sat (ph : PermHeap)(pm : ProcMap)(s g : Store)(C : GhostCmd)(J : Assn) : Prop :=
~ cmd_locked C -> sat ph pm s g J.
Fixpoint safe (n : nat)(basic : Prop)(C : GhostCmd)(ph : PermHeap)(pm : ProcMap)(s g : Store)(J A : Assn) : Prop :=
match n with
| O => True
| S m =>
(C = Cskip -> sat ph pm s g A) /\
(forall phF pmF,
phDisj ph phF ->
pmDisj pm pmF ->
let h := phConcr (phUnion ph phF) in
let pm' := pmUnion pm pmF in
hFinite h ->
pmFinite pm' ->
~ gfault h pm' s g C) /\
(forall l, cmd_acc C s l -> phcLt PHCfree (ph l)) /\
(forall l, cmd_writes C s l -> phcEntire (ph l)) /\
(forall phJ phF pmJ pmF pmC h' s' C',
phDisj ph phJ ->
phDisj (phUnion ph phJ) phF ->
pmDisj pm pmJ ->
pmDisj (pmUnion pm pmJ) pmF ->
pmBisim (pmUnion (pmUnion pm pmJ) pmF) pmC ->
pmFinite pmC ->
pmWs pmC ->
invariant_sat phJ pmJ s g C J ->
let h := phConcr (phUnion (phUnion ph phJ) phF) in
let hs := phSnapshot (phUnion (phUnion ph phJ) phF) in
hFinite h ->
pmCovers pmC hs ->
pmSafe hs pmC ->
step h s (plain C) h' s' C' ->
exists ph' phJ',
phDisj ph' phJ' /\
phDisj (phUnion ph' phJ') phF /\
phConcr (phUnion (phUnion ph' phJ') phF) = h' /\
hFinite h' /\
(basic -> phJ = phJ' /\ phSnapshot ph = phSnapshot ph') /\
exists pm' pmJ' pmC',
pmDisj pm' pmJ' /\
pmDisj (pmUnion pm' pmJ') pmF /\
pmBisim (pmUnion (pmUnion pm' pmJ') pmF) pmC' /\
pmFinite pmC' /\
pmWs pmC' /\
(basic -> pmBisim pm pm' /\ pmBisim pmJ pmJ') /\
let hs' := phSnapshot (phUnion (phUnion ph' phJ') phF) in
pmCovers pmC' hs' /\
pmSafe hs' pmC' /\
exists g' C'',
plain C'' = C' /\
gstep h pmC s g C h' pmC' s' g' C'' /\
invariant_sat phJ' pmJ' s' g' C'' J /\
safe m basic C'' ph' pm' s' g' J A)
end.
Safety is stable under replacing process maps by bisimilar ones.
Lemma safe_pmBisim :
forall n basic C ph pm1 pm2 s g J A,
pmBisim pm1 pm2 ->
safe n basic C ph pm1 s g J A ->
safe n basic C ph pm2 s g J A.
Safety is stable under replacing resource invariants
by equivalent ones.
Lemma safe_aEquiv_inv :
forall n basic C ph pm s g R1 R2 A,
aEquiv R1 R2 ->
safe n basic C ph pm s g R1 A ->
safe n basic C ph pm s g R2 A.
Safety is stable under replacing postconditions by equivalent ones.
Lemma safe_aEquiv_post :
forall n basic C ph pm s g R A1 A2,
phValid ph ->
pmValid pm ->
aEquiv A1 A2 ->
safe n basic C ph pm s g R A1 ->
safe n basic C ph pm s g R A2.
Add Parametric Morphism : safe
with signature eq ==> eq ==> eq ==> eq ==> pmBisim ==> eq ==> eq ==> aEquiv ==> eq ==> iff
as safe_bisim_mor.
Adequacy is monotonic in the number of computation steps.
That is, if any configuration is safe for n steps, it
must also be safe for less than n steps.
Open Scope nat_scope.
Lemma safe_mono :
forall m n basic C ph pm s g J A,
m <= n ->
safe n basic C ph pm s g J A ->
safe m basic C ph pm s g J A.
Close Scope nat_scope.
The Cskip program being safe in a certain state
means that the postcondition holds in that state.
Lemma safe_skip :
forall n basic ph pm s g J A,
safe (S n) basic Cskip ph pm s g J A ->
sat ph pm s g A.
Lemma safe_done :
forall n basic ph pm s g J A,
sat ph pm s g A ->
safe n basic Cskip ph pm s g J A.
Any (ghost) store can be replaced by one that agrees on
the values of all free variables in the program, resource invariant,
and the postcondition.
Lemma safe_agree :
forall n basic C ph pm s1 s2 g J A,
sAgree (assn_fv A) s1 s2 ->
sAgree (assn_fv J) s1 s2 ->
sAgree (cmd_fv C) s1 s2 ->
safe n basic C ph pm s1 g J A ->
safe n basic C ph pm s2 g J A.
Lemma safe_agree_ghost :
forall n basic C ph pm s g1 g2 J A,
sAgree (assn_fv A) g1 g2 ->
sAgree (assn_fv J) g1 g2 ->
sAgree (cmd_fv C) g1 g2 ->
safe n basic C ph pm s g1 J A ->
safe n basic C ph pm s g2 J A.
Disjuncts in postconditions can always be introduced.
Lemma safe_disj_weaken :
forall n basic C ph pm s g R A1 A2,
safe n basic C ph pm s g R A1 ->
safe n basic C ph pm s g R (Adisj A1 A2).
forall n basic C ph pm s g R A1 A2,
safe n basic C ph pm s g R A1 ->
safe n basic C ph pm s g R (Adisj A1 A2).
Soundness of the proof rules
Definition csl (basic : Prop)(J : Assn)(A1 : Assn)(C : GhostCmd)(A2 : Assn) : Prop :=
cmd_user C /\
forall n ph pm s g,
phValid ph ->
pmValid pm ->
pmSafe (phSnapshot ph) pm ->
cmd_wf C ->
sat ph pm s g A1 ->
safe n basic C ph pm s g J A2.
Any assertion (pre- or postcondition, or resource invariant)
can always be replaced by an equivalent one.
Add Parametric Morphism : csl
with signature eq ==> aEquiv ==> aEquiv ==> eq ==> aEquiv ==> iff
as csl_aEquiv_mor.
Any program judgement with an unsatisfiable precondition
trivially holds.
Lemma csl_trivial :
forall basic J C A,
cmd_user C -> csl basic J Afalse C A.
Theorem rule_skip :
forall basic J A,
csl basic J A Cskip A.
Open Scope nat_scope.
Lemma safe_seq :
forall n basic C1 C2 J A1 A2 ph pm s g,
phValid ph ->
pmValid pm ->
pmSafe (phSnapshot ph) pm ->
safe n basic C1 ph pm s g J A1 ->
(forall m ph' pm' s' g',
m <= n ->
phValid ph' ->
pmValid pm' ->
pmSafe (phSnapshot ph') pm' ->
sat ph' pm' s' g' A1 ->
safe m basic C2 ph' pm' s' g' J A2) ->
safe n basic (Cseq C1 C2) ph pm s g J A2.
Close Scope nat_scope.
Theorem rule_seq :
forall basic J A1 A2 A3 C1 C2,
csl basic J A1 C1 A2 ->
csl basic J A2 C2 A3 ->
csl basic J A1 (Cseq C1 C2) A3.
Lemma safe_ite :
forall n basic J A1 A2 B C1 C2 ph pm s g,
sat ph pm s g A1 ->
(sat ph pm s g (Astar A1 (Aplain B)) -> safe n basic C1 ph pm s g J A2) ->
(sat ph pm s g (Astar A1 (Aplain (Bnot B))) -> safe n basic C2 ph pm s g J A2) ->
safe n basic (Cite B C1 C2) ph pm s g J A2.
Theorem rule_ite :
forall basic J A1 A2 B C1 C2,
csl basic J (Astar A1 (Aplain B)) C1 A2 ->
csl basic J (Astar A1 (Aplain (Bnot B))) C2 A2 ->
csl basic J A1 (Cite B C1 C2) A2.
Lemma safe_while :
forall n basic B C ph pm s g J A,
csl basic J (Astar A (Aplain B)) C A ->
sat ph pm s g A ->
cmd_wf C ->
safe n basic (Cwhile B C) ph pm s g J (Astar A (Aplain (Bnot B))).
Theorem rule_while :
forall basic J A B C,
csl basic J (Astar A (Aplain B)) C A ->
csl basic J A (Cwhile B C) (Astar A (Aplain (Bnot B))).
Lemma safe_assign :
forall n basic J A x E ph pm s g,
~ assn_fv J x ->
sat ph pm s g (assn_subst x E A) ->
safe n basic (Cass x E) ph pm s g J A.
Theorem rule_assign :
forall basic J A x E,
~ assn_fv J x ->
csl basic J (assn_subst x E A) (Cass x E) A.
Lemma safe_conseq :
forall n basic C ph pm s g J A1 A2,
phValid ph ->
pmValid pm ->
pmSafe (phSnapshot ph) pm ->
aEntails A1 A2 ->
safe n basic C ph pm s g J A1 ->
safe n basic C ph pm s g J A2.
Theorem rule_conseq :
forall basic J A1 A2 A1' A2' C,
aEntails A1 A1' ->
aEntails A2' A2 ->
csl basic J A1' C A2' ->
csl basic J A1 C A2.
Theorem rule_disj :
forall basic J A1 A2 A1' A2' C,
csl basic J A1 C A1' ->
csl basic J A2 C A2' ->
csl basic J (Adisj A1 A2) C (Adisj A1' A2').
Corollary rule_disj_l :
forall basic J A1 A2 A3 C,
csl basic J A2 C A1 ->
csl basic J A3 C A1 ->
csl basic J (Adisj A2 A3) C A1.
Corollary rule_disj_r :
forall basic J A1 A2 A3 C,
csl basic J A1 C A2 ->
csl basic J A1 C A3 ->
csl basic J A1 C (Adisj A2 A3).
Lemma rule_disj_weaken :
forall basic J A1 A2 A3 C,
csl basic J A1 C A2 ->
csl basic J A1 C (Adisj A2 A3).
Lemma safe_frame :
forall n basic C ph1 ph2 pm1 pm2 s g J A1 A2,
phDisj ph1 ph2 ->
pmDisj pm1 pm2 ->
pmSafe (phSnapshot ph1) pm1 ->
disjoint (assn_fv A2) (cmd_mod C) ->
sat ph2 pm2 s g A2 ->
safe n basic C ph1 pm1 s g J A1 ->
safe n basic C (phUnion ph1 ph2) (pmUnion pm1 pm2) s g J (Astar A1 A2).
Theorem rule_frame :
forall basic J A1 A2 A3 C,
disjoint (assn_fv A3) (cmd_mod C) ->
csl basic J A1 C A2 ->
csl basic J (Astar A1 A3) C (Astar A2 A3).
Lemma rule_lookup_std :
forall basic x E1 q E2 J A,
~ In x (expr_fv E1) ->
~ In x (expr_fv E2) ->
~ assn_fv J x ->
csl basic J (Astar (assn_subst x E2 A) (Apointsto PTTstd q E1 E2)) (Cread x E1) (Astar A (Apointsto PTTstd q E1 E2)).
Lemma rule_lookup_proc :
forall basic x E1 q E2 J A,
~ In x (expr_fv E1) ->
~ In x (expr_fv E2) ->
~ assn_fv J x ->
csl basic J (Astar (assn_subst x E2 A) (Apointsto PTTproc q E1 E2)) (Cread x E1) (Astar A (Apointsto PTTproc q E1 E2)).
Lemma rule_lookup_act :
forall basic x E1 q E2 J A,
~ In x (expr_fv E1) ->
~ In x (expr_fv E2) ->
~ assn_fv J x ->
csl basic J (Astar (assn_subst x E2 A) (Apointsto PTTact q E1 E2)) (Cread x E1) (Astar A (Apointsto PTTact q E1 E2)).
Theorem rule_lookup :
forall basic x E1 q E2 J A t,
~ In x (expr_fv E1) ->
~ In x (expr_fv E2) ->
~ assn_fv J x ->
csl basic J (Astar (assn_subst x E2 A) (Apointsto t q E1 E2)) (Cread x E1) (Astar A (Apointsto t q E1 E2)).
Heap writing
Theorem rule_write_std :
forall basic J E1 E2 E3,
csl basic J (Apointsto PTTstd 1 E1 E3) (Cwrite E1 E2) (Apointsto PTTstd 1 E1 E2).
Theorem rule_write_act :
forall basic J E1 E2 E3,
csl basic J (Apointsto PTTact 1 E1 E3) (Cwrite E1 E2) (Apointsto PTTact 1 E1 E2).
Theorem rule_alloc :
forall basic x E J,
~ In x (expr_fv E) ->
~ assn_fv J x ->
csl basic J Atrue (Calloc x E) (Apointsto PTTstd perm_full (Evar x) E).
forall basic x E J,
~ In x (expr_fv E) ->
~ assn_fv J x ->
csl basic J Atrue (Calloc x E) (Apointsto PTTstd perm_full (Evar x) E).
Theorem rule_dispose :
forall basic E1 E2 J,
csl basic J (Apointsto PTTstd perm_full E1 E2) (Cdispose E1) Atrue.
forall basic E1 E2 J,
csl basic J (Apointsto PTTstd perm_full E1 E2) (Cdispose E1) Atrue.
Lemma safe_par :
forall n basic C1 C2 ph1 ph2 pm1 pm2 s g J A1 A2,
phDisj ph1 ph2 ->
pmDisj pm1 pm2 ->
pmSafe (phSnapshot ph1) pm1 ->
pmSafe (phSnapshot ph2) pm2 ->
cmd_wf (Cpar C1 C2) ->
disjoint (cmd_fv C1) (cmd_mod C2) ->
disjoint (assn_fv A1) (cmd_mod C2) ->
disjoint (assn_fv J) (cmd_mod C2) ->
disjoint (cmd_fv C2) (cmd_mod C1) ->
disjoint (assn_fv A2) (cmd_mod C1) ->
disjoint (assn_fv J) (cmd_mod C1) ->
safe n basic C1 ph1 pm1 s g J A1 ->
safe n basic C2 ph2 pm2 s g J A2 ->
safe n basic (Cpar C1 C2) (phUnion ph1 ph2) (pmUnion pm1 pm2) s g J (Astar A1 A2).
Theorem rule_par :
forall basic C1 C2 J A1 A2 A1' A2',
disjoint (cmd_fv C1) (cmd_mod C2) ->
disjoint (assn_fv A1') (cmd_mod C2) ->
disjoint (assn_fv J) (cmd_mod C2) ->
disjoint (cmd_fv C2) (cmd_mod C1) ->
disjoint (assn_fv A2') (cmd_mod C1) ->
disjoint (assn_fv J) (cmd_mod C1) ->
csl basic J A1 C1 A1' ->
csl basic J A2 C2 A2' ->
csl basic J (Astar A1 A2) (Cpar C1 C2) (Astar A1' A2').
Theorem rule_ex :
forall basic C J (A1 A2 : Val -> Assn),
(forall x, csl basic J (A1 x) C (A2 x)) ->
csl basic J (Aex A1) C (Aex A2).
Lemma safe_share :
forall n C ph1 ph2 pm1 pm2 s g J A1 A2,
phDisj ph1 ph2 ->
pmDisj pm1 pm2 ->
pmSafe (phSnapshot ph1) pm1 ->
pmSafe (phSnapshot ph2) pm2 ->
invariant_sat ph2 pm2 s g C A2 ->
safe n False C ph1 pm1 s g (Astar J A2) A1 ->
safe n False C (phUnion ph1 ph2) (pmUnion pm1 pm2) s g J (Astar A1 A2).
Theorem rule_share :
forall C J A1 A2 A3,
csl False (Astar J A3) A1 C A2 ->
csl False J (Astar A1 A3) C (Astar A2 A3).
Lemma safe_atom :
forall n C ph pm s g J A,
safe n False C ph pm s g Atrue (Astar A J) ->
safe n False (Cinatom C) ph pm s g J A.
Theorem rule_atom :
forall C J A1 A2,
csl False Atrue (Astar A1 J) C (Astar A2 J) ->
csl False J A1 (Catomic C) A2.
Theorem rule_proc_init :
forall Pf E J (x : Var)(xs : list ProcVar)(f1 f2 : ProcVar -> Expr),
let HP := Pf E in
let b := precondition HP in
let B := hcond_convert b f2 in
let fq := fun _ => perm_full in
(forall y, In y (hcond_fpv b) -> In y xs) ->
~ assn_fv J x ->
~ (exists y : ProcVar, In y xs /\ In x (expr_fv (f1 y))) ->
~ (exists y : ProcVar, In y xs /\ In x (expr_fv (f2 y))) ->
csl False J
(Astar (Aiter (ApointstoIter xs fq f1 f2 PTTstd)) (Aplain B))
(Cproc x Pf E xs f1)
(Astar (Astar (Aiter (ApointstoIter xs fq f1 f2 PTTproc)) (Aproc x perm_full HP xs f1)) (Aplain B)).
Theorem rule_proc_finish :
forall HP J (x : Var)(xs : list ProcVar)(f1 f2 : ProcVar -> Expr),
let fq := fun _ => perm_full in
csl False J
(Astar (Aiter (ApointstoIter xs fq f1 f2 PTTproc)) (Aproc x perm_full (HPalt HP HPepsilon) xs f1))
(Cendproc x)
(Aiter (ApointstoIter xs fq f1 f2 PTTstd)).
forall HP J (x : Var)(xs : list ProcVar)(f1 f2 : ProcVar -> Expr),
let fq := fun _ => perm_full in
csl False J
(Astar (Aiter (ApointstoIter xs fq f1 f2 PTTproc)) (Aproc x perm_full (HPalt HP HPepsilon) xs f1))
(Cendproc x)
(Aiter (ApointstoIter xs fq f1 f2 PTTstd)).
Action rule
Lemma phcConcr_snapshot_none :
forall pme, phcConcr pme = None -> phcSnapshot pme = None.
Definition metadata_agree (pid : Val)(a : Act)(v : Val)(xs : list ProcVar)(f : ProcVar -> Val)(h hs : Heap)(pm : ProcMap) : Prop :=
exists (q : Qc)(P : Proc),
pmeBisim (pm pid) (PEelem q P xs f) /\
(forall x : ProcVar, In x (act_fv a v) -> In x xs) /\
(forall x : ProcVar, In x xs -> h (f x) = hs (f x)) /\
exists ps : ProcStore,
(forall x : ProcVar, In x xs -> h (f x) = Some (ps x)) /\
pcond_eval (guard a v) ps = true.
Lemma metadata_agree_pmBisim :
forall pid a v xs f h hs pm1 pm2,
pmBisim pm1 pm2 ->
metadata_agree pid a v xs f h hs pm1 ->
metadata_agree pid a v xs f h hs pm2.
Add Parametric Morphism : metadata_agree
with signature eq ==> eq ==> eq ==> eq ==> eq ==> eq ==> eq ==> pmBisim ==> iff
as metadata_agree_pmBisim_mor.
Lemma metadata_agree_F :
forall pid a v xs F1 F2 h hs pm,
(forall x : ProcVar, In x xs -> F1 x = F2 x) ->
metadata_agree pid a v xs F1 h hs pm ->
metadata_agree pid a v xs F2 h hs pm.
Now to the actual soundness result, which can be proven
using the following (rather involved) key lemma:
Lemma safe_action :
forall n C ph pm pm' (s g : Store) x hs q E HP HQ (xs ys1 ys2 : list ProcVar) a (fq : ProcVar -> Qc)(f1 f2 : ProcVar -> Expr)(J A : Assn),
let B2 := hcond_convert (heffect a E) f2 in
let F1 := expr_eval_map f1 s : ProcVar -> Val in
let v := expr_eval E s in
metadata_agree (g x) a v xs F1 hs (phSnapshot ph) pm' ->
Permutation xs (ys1 ++ ys2) ->
(forall y : ProcVar, In y ys1 -> fq y <> perm_full) ->
(forall y : ProcVar, In y ys2 -> fq y = perm_full) ->
(forall y : ProcVar, In y xs -> perm_valid (fq y)) ->
(forall y : ProcVar, disjoint (expr_fv (f1 y)) (cmd_mod C)) ->
disjoint (expr_fv E) (cmd_mod C) ->
disjoint (hproc_fv HP) (cmd_mod C) ->
disjoint (hproc_fv HQ) (cmd_mod C) ->
~ cmd_mod C x ->
cmd_basic C ->
pmDisj pm pm' ->
sat phIden pm' s g (Aproc x q (HPalt (HPseq (HPact a E) HP) HQ) xs f1) ->
safe n True C ph pm s g J (Astar (Astar (Aiter (ApointstoIter_procact xs fq f1 f2)) (Aplain B2)) A) ->
safe n False (Cinact (GMdata (g x) a v hs) C) ph (pmUnion pm pm') s g J (Astar (Astar (Astar (Aiter (ApointstoIter xs fq f1 f2 PTTproc)) (Aproc x q HP xs f1)) (Aplain B2)) A).
Theorem rule_act :
forall x a E C xs J q HP HQ (f1 f2 f2' : ProcVar -> Expr)(fq : ProcVar -> Qc) A1 A2,
let B1 := hcond_convert (hguard a E) f2 in
let B2 := hcond_convert (heffect a E) f2' in
(forall y v, In y (act_fv a v) -> In y xs) ->
(forall y : ProcVar, In y xs -> perm_valid (fq y)) ->
(forall y : ProcVar, disjoint (expr_fv (f1 y)) (cmd_mod C)) ->
disjoint (expr_fv E) (cmd_mod C) ->
disjoint (hproc_fv HP) (cmd_mod C) ->
disjoint (hproc_fv HQ) (cmd_mod C) ->
~ cmd_mod C x ->
csl True J (Astar (Astar (Aiter (ApointstoIter_procact xs fq f1 f2)) (Aplain B1)) A1) C (Astar (Astar (Aiter (ApointstoIter_procact xs fq f1 f2')) (Aplain B2)) A2) ->
csl False J
(Astar (Astar (Astar (Aiter (ApointstoIter xs fq f1 f2 PTTproc)) (Aproc x q (HPalt (HPseq (HPact a E) HP) HQ) xs f1)) (Aplain B1)) A1)
(Cact x a E C)
(Astar (Astar (Astar (Aiter (ApointstoIter xs fq f1 f2' PTTproc)) (Aproc x q HP xs f1)) (Aplain B2)) A2).
Definition DisjWrapper (P Q : Prop) := P \/ Q.
Lemma wrap : forall P Q, P \/ Q -> DisjWrapper P Q.
Lemma unwrap : forall P Q, DisjWrapper P Q -> P \/ Q.
Lemma wrap : forall P Q, P \/ Q -> DisjWrapper P Q.
Lemma unwrap : forall P Q, DisjWrapper P Q -> P \/ Q.
And now the actual rule.
Theorem rule_query :
forall x HB HP HQ q (xs : list ProcVar)(f1 f2 : ProcVar -> Expr)(fq : ProcVar -> Qc) J A,
(forall y : ProcVar, In y (hcond_fpv HB) -> In y xs) ->
(forall y : ProcVar, In y xs -> perm_valid (fq y)) ->
let B := hcond_convert HB f2 in
csl False J
(Astar (Astar (Aiter (ApointstoIter xs fq f1 f2 PTTproc)) (Aproc x q (HPalt (HPseq (HPassert HB) HP) HQ) xs f1)) A)
(Cquery x)
(Astar (Astar (Astar (Aiter (ApointstoIter xs fq f1 f2 PTTproc)) (Aproc x q HP xs f1)) (Aplain B)) A).
End Soundness.