Checkpoint simplifying SharedMemory

This commit is contained in:
Adam Chlipala 2017-04-30 20:05:19 -04:00
parent db0f87d654
commit 824d4bc524

View file

@ -276,7 +276,7 @@ Proof.
equality. equality.
Qed. Qed.
(* The key correctnss property: when an original step takes place, either it (* The key correctness property: when an original step takes place, either it
* has no effect or can be duplicated when we apply [runLocal] both *before* and * has no effect or can be duplicated when we apply [runLocal] both *before* and
* *after* the step. *) * *after* the step. *)
Lemma step_runLocal : forall h l c h' l' c', Lemma step_runLocal : forall h l c h' l' c',
@ -456,7 +456,7 @@ Record summary := {
Locks : set nat Locks : set nat
}. }.
(* Here is a relation to check the accuracy of a summary for a single thread. *) (* Here is a relation to check the accuracy of a summary. *)
Inductive summarize : cmd -> summary -> Prop := Inductive summarize : cmd -> summary -> Prop :=
| SumReturn : forall r s, | SumReturn : forall r s,
summarize (Return r) s summarize (Return r) s
@ -465,6 +465,8 @@ Inductive summarize : cmd -> summary -> Prop :=
| SumBind : forall c1 c2 s, | SumBind : forall c1 c2 s,
summarize c1 s summarize c1 s
-> (forall r, summarize (c2 r) s) -> (forall r, summarize (c2 r) s)
(* Note the approximation here: we consider all [r] values, even if some
* are semantically impossible. *)
-> summarize (Bind c1 c2) s -> summarize (Bind c1 c2) s
| SumRead : forall a s, | SumRead : forall a s,
a \in s.(Reads) a \in s.(Reads)
@ -477,22 +479,15 @@ Inductive summarize : cmd -> summary -> Prop :=
-> summarize (Lock a) s -> summarize (Lock a) s
| SumUnlock : forall a s, | SumUnlock : forall a s,
a \in s.(Locks) a \in s.(Locks)
-> summarize (Unlock a) s. -> summarize (Unlock a) s
| SumPar : forall c1 c2 s,
(* And here's one to check the accuracy of a summary for a list of threads. summarize c1 s
* Each thread is packaged with its verified summary in the list. *) -> summarize c2 s
Inductive summarizeThreads : cmd -> list (cmd * summary) -> Prop := -> summarize (Par c1 c2) s.
| StPar : forall c1 c2 ss1 ss2,
summarizeThreads c1 ss1
-> summarizeThreads c2 ss2
-> summarizeThreads (Par c1 c2) (ss1 ++ ss2)
| StAtomic : forall c s,
summarize c s
-> summarizeThreads c [(c, s)].
(* We will use these expanded lists as the command type in the new semantics. *)
(* To check commutativity, it is helpful to know which atomic command a thread (* To check commutativity, it is helpful to know which atomic command a thread
* could run next. *) * could run next. We skip coverage of parallel compositions to make things
* simple. *)
Inductive nextAction : cmd -> cmd -> Prop := Inductive nextAction : cmd -> cmd -> Prop :=
| NaReturn : forall r, | NaReturn : forall r,
nextAction (Return r) (Return r) nextAction (Return r) (Return r)
@ -526,41 +521,42 @@ Definition commutes (c : cmd) (s : summary) : Prop :=
end. end.
(* Now the new semantics: *) (* Now the new semantics: *)
Inductive stepC : heap * locks * list (cmd * summary) -> heap * locks * list (cmd * summary) -> Prop := Inductive stepC (s : summary) : heap * locks * cmd -> heap * locks * cmd -> Prop :=
(* It is always OK to let the first thread run. *) (* It is always OK to let the first thread run. *)
| StepFirst : forall h l c h' l' c' s cs, | StepFirst : forall h l c1 h' l' c1' c2,
step (h, l, c) (h', l', c') step (h, l, c1) (h', l', c1')
-> stepC (h, l, (c, s) :: cs) (h', l', (c', s) :: cs) -> stepC s (h, l, c1 || c2) (h', l', c1' || c2)
(* However, you may only pick another thread to run if it would be unsound to (* However, you may only pick another thread to run if it would be unsound to
* consider just the first thread. The negation of the soundness condition is * consider just the first thread. The negation of the soundness condition is
* expressed in the first premise below. *) * expressed in the first premise below. *)
| StepAny : forall h l c h' l' s cs1 c1 s1 cs2 c1', | StepAny : forall h l c2 h' l' c2' c1,
(forall c0 h'' l'' c'', nextAction c c0 (forall c0 h'' l'' c1'', nextAction c1 c0
(* The first thread [c] has some atomic action [c0] (* The first thread [c] has some atomic action [c0]
* ready to run. *) * ready to run. *)
-> List.Forall (fun c_s => commutes c0 (snd c_s)) (cs1 ++ (c1, s1) :: cs2) -> commutes c0 s
(* All other threads only contain actiosn that commute (* All other threads only contain actions that commute
* with [c0]. *) * with [c0]. *)
-> step (h, l, c) (h'', l'', c'') -> step (h, l, c1) (h'', l'', c1'')
(* Finaly, [c] is actually enabled to run, which might (* Finaly, [c] is actually enabled to run, which
* not be the case if [c0] is a locking command. *) * might not be the case if [c0] is a locking
* command. *)
-> False) -> False)
(* If we passed that check, then we can step a single thread as expected! *) (* If we passed that check, then we can step a single thread as expected! *)
-> step (h, l, c1) (h', l', c1') -> step (h, l, c2) (h', l', c2')
-> stepC (h, l, (c, s) :: cs1 ++ (c1, s1) :: cs2) (h', l', (c, s) :: cs1 ++ (c1', s1) :: cs2). -> stepC s (h, l, c1 || c2) (h', l', c1 || c2').
(* Notice how this definition turns the partial-order-reduction optimization (* Notice how this definition turns the partial-order-reduction optimization
* "off and on" during state-space exploration. We only restrict our attention * "off and on" during state-space exploration. We only restrict our attention
* to the first thread so long as the soundness condition above is true. *) * to the first thread so long as the soundness condition above is true. *)
Definition trsys_ofC (h : heap) (l : locks) (cs : list (cmd * summary)) := {| Definition trsys_ofC (s : summary) (h : heap) (l : locks) (c : cmd) := {|
Initial := {(h, l, cs)}; Initial := {(h, l, c)};
Step := stepC Step := stepC s
|}. |}.