mirror of
https://github.com/achlipala/frap.git
synced 2024-11-09 16:07:49 +00:00
Tweak files for ModelChecking in class
This commit is contained in:
parent
1e7c33f0a9
commit
1c88de0f7d
2 changed files with 272 additions and 0 deletions
82
ModelChecking_sol.v
Normal file
82
ModelChecking_sol.v
Normal file
|
@ -0,0 +1,82 @@
|
|||
Theorem factorial_ok_2 :
|
||||
invariantFor (factorial_sys 2) (fact_correct 2).
|
||||
Proof.
|
||||
simplify.
|
||||
eapply invariant_weaken.
|
||||
(* We begin like in last chapter, by strengthening to an inductive
|
||||
* invariant. *)
|
||||
|
||||
apply multiStepClosure_ok.
|
||||
(* The difference is that we will use multi-step closure to find the invariant
|
||||
* automatically. Note that the invariant appears as an existential variable,
|
||||
* whose name begins with a question mark. *)
|
||||
simplify.
|
||||
rewrite fact_init_is.
|
||||
(* It's important to phrase the current candidate invariant explicitly as a
|
||||
* finite set, before continuing. Otherwise, it won't be obvious how to take
|
||||
* the one-step closure. *)
|
||||
|
||||
(* Compute which states are reachable after one step. *)
|
||||
eapply MscStep.
|
||||
apply oneStepClosure_split; simplify.
|
||||
invert H; simplify.
|
||||
apply singleton_in.
|
||||
apply oneStepClosure_empty.
|
||||
simplify.
|
||||
|
||||
(* Compute which states are reachable after two steps. *)
|
||||
eapply MscStep.
|
||||
apply oneStepClosure_split; simplify.
|
||||
invert H; simplify.
|
||||
apply singleton_in.
|
||||
apply oneStepClosure_split; simplify.
|
||||
invert H; simplify.
|
||||
apply singleton_in.
|
||||
apply oneStepClosure_empty.
|
||||
simplify.
|
||||
|
||||
(* Compute which states are reachable after three steps. *)
|
||||
eapply MscStep.
|
||||
apply oneStepClosure_split; simplify.
|
||||
invert H; simplify.
|
||||
apply singleton_in.
|
||||
apply oneStepClosure_split; simplify.
|
||||
invert H; simplify.
|
||||
apply singleton_in.
|
||||
apply oneStepClosure_split; simplify.
|
||||
invert H; simplify.
|
||||
apply singleton_in.
|
||||
apply oneStepClosure_empty.
|
||||
simplify.
|
||||
|
||||
(* Now the candidate invariatn is closed under single steps. Let's prove
|
||||
* it. *)
|
||||
apply MscDone.
|
||||
apply prove_oneStepClosure; simplify.
|
||||
propositional.
|
||||
propositional; invert H0; try equality.
|
||||
invert H; equality.
|
||||
invert H1; equality.
|
||||
|
||||
(* Finally, we prove that our new invariant implies the simpler, noninductive
|
||||
* one that we started with. *)
|
||||
simplify.
|
||||
propositional; subst; simplify; propositional.
|
||||
(* [subst]: remove all hypotheses like [x = e] for variables [x], simply
|
||||
* replacing all uses of [x] by [e]. *)
|
||||
Qed.
|
||||
|
||||
Theorem twoadd2_ok :
|
||||
invariantFor (parallel twoadd_sys twoadd_sys) (twoadd_correct (private := _)).
|
||||
Proof.
|
||||
eapply invariant_weaken.
|
||||
eapply invariant_simulates.
|
||||
apply withInterference_abstracts.
|
||||
apply withInterference_parallel.
|
||||
apply twoadd_ok.
|
||||
apply twoadd_ok.
|
||||
|
||||
unfold twoadd_correct.
|
||||
invert 1.
|
||||
assumption.
|
||||
Qed.
|
|
@ -410,6 +410,196 @@ Proof.
|
|||
Admitted.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Inductive add2_bthread :=
|
||||
| BRead
|
||||
| BWrite (local : bool).
|
||||
|
||||
Inductive add2_binit : threaded_state bool add2_bthread -> Prop :=
|
||||
| Add2BInit : add2_binit {| Shared := true; Private := BRead |}.
|
||||
|
||||
Inductive add2_bstep : threaded_state bool add2_bthread -> threaded_state bool add2_bthread -> Prop :=
|
||||
| StepBRead : forall global,
|
||||
add2_bstep {| Shared := global; Private := BRead |}
|
||||
{| Shared := global; Private := BWrite global |}
|
||||
| StepBWrite : forall global local,
|
||||
add2_bstep {| Shared := global; Private := BWrite local |}
|
||||
{| Shared := local; Private := BRead |}.
|
||||
|
||||
Definition add2_bsys1 := {|
|
||||
Initial := add2_binit;
|
||||
Step := add2_bstep
|
||||
|}.
|
||||
|
||||
Definition add2_bsys := parallel add2_bsys1 add2_bsys1.
|
||||
|
||||
(* This invariant formalizes the connection between local states of threads, in
|
||||
* the original and abstracted systems. *)
|
||||
Inductive R_private1 : add2_thread -> add2_bthread -> Prop :=
|
||||
| RpRead : R_private1 Read BRead
|
||||
| RpWrite : forall n b, (b = true <-> isEven n)
|
||||
-> R_private1 (Write n) (BWrite b).
|
||||
|
||||
(* We lift [R_private1] to a relation over whole states. *)
|
||||
Inductive add2_R : threaded_state nat (add2_thread * add2_thread)
|
||||
-> threaded_state bool (add2_bthread * add2_bthread)
|
||||
-> Prop :=
|
||||
| Add2_R : forall n b th1 th2 th1' th2',
|
||||
(b = true <-> isEven n)
|
||||
-> R_private1 th1 th1'
|
||||
-> R_private1 th2 th2'
|
||||
-> add2_R {| Shared := n; Private := (th1, th2) |}
|
||||
{| Shared := b; Private := (th1', th2') |}.
|
||||
|
||||
(* Let's also recharacterize the initial states via a singleton set. *)
|
||||
Theorem add2_init_is :
|
||||
parallel1 add2_binit add2_binit = { {| Shared := true; Private := (BRead, BRead) |} }.
|
||||
Proof.
|
||||
simplify.
|
||||
apply sets_equal; simplify.
|
||||
propositional.
|
||||
|
||||
invert H.
|
||||
invert H2.
|
||||
invert H4.
|
||||
equality.
|
||||
|
||||
invert H0.
|
||||
constructor.
|
||||
constructor.
|
||||
constructor.
|
||||
Qed.
|
||||
|
||||
(* We ask Coq to remember this lemma as a hint, which will be used by the
|
||||
* model-checking tactics that we refrain from explaining in detail. *)
|
||||
Hint Rewrite add2_init_is.
|
||||
|
||||
(* Now, let's verify the original system. *)
|
||||
(*Theorem add2_ok :
|
||||
invariantFor add2_sys add2_correct.
|
||||
Proof.
|
||||
(* First step: strengthen the invariant. We leave an underscore for the
|
||||
* unknown invariant, to be found by model checking. *)
|
||||
eapply invariant_weaken with (invariant1 := invariantViaSimulation add2_R _).
|
||||
|
||||
(* One way to find an invariant-by-simulation is to find an invariant for the
|
||||
* abstracted system, as this step asks to do. *)
|
||||
apply invariant_simulates with (sys2 := add2_bsys).
|
||||
|
||||
(* Now we must prove that the simulation via [add2_R] is valid, which is
|
||||
* routine. *)
|
||||
constructor; simplify.
|
||||
|
||||
invert H.
|
||||
invert H0.
|
||||
invert H1.
|
||||
exists {| Shared := true; Private := (BRead, BRead) |}; simplify.
|
||||
propositional.
|
||||
constructor.
|
||||
propositional.
|
||||
constructor.
|
||||
constructor.
|
||||
constructor.
|
||||
|
||||
invert H.
|
||||
invert H0; simplify.
|
||||
|
||||
invert H7.
|
||||
|
||||
invert H2.
|
||||
exists {| Shared := b; Private := (BWrite b, th2') |}.
|
||||
propositional.
|
||||
constructor.
|
||||
propositional.
|
||||
constructor.
|
||||
propositional.
|
||||
assumption.
|
||||
constructor.
|
||||
constructor.
|
||||
|
||||
invert H2.
|
||||
exists {| Shared := b0; Private := (BRead, th2') |}.
|
||||
propositional.
|
||||
constructor.
|
||||
propositional.
|
||||
constructor.
|
||||
assumption.
|
||||
invert H0.
|
||||
propositional.
|
||||
constructor.
|
||||
assumption.
|
||||
constructor.
|
||||
constructor.
|
||||
|
||||
invert H7.
|
||||
|
||||
invert H3.
|
||||
exists {| Shared := b; Private := (th1', BWrite b) |}.
|
||||
propositional.
|
||||
constructor.
|
||||
propositional.
|
||||
assumption.
|
||||
constructor.
|
||||
propositional.
|
||||
constructor.
|
||||
constructor.
|
||||
|
||||
invert H3.
|
||||
exists {| Shared := b0; Private := (th1', BRead) |}.
|
||||
propositional.
|
||||
constructor.
|
||||
propositional.
|
||||
constructor.
|
||||
assumption.
|
||||
invert H0.
|
||||
propositional.
|
||||
assumption.
|
||||
constructor.
|
||||
constructor.
|
||||
constructor.
|
||||
|
||||
(* OK, we're glad to have that over with! Such a process could also be
|
||||
* automated, but we won't bother doing so here. However, we are now in a
|
||||
* good state, where our model checker can find the invariant
|
||||
* automatically. *)
|
||||
model_check_infer.
|
||||
(* It finds exactly four reachable states. We finish by showing that they all
|
||||
* obey the original invariant. *)
|
||||
|
||||
invert 1.
|
||||
invert H0.
|
||||
simplify.
|
||||
unfold add2_correct.
|
||||
simplify.
|
||||
propositional; subst.
|
||||
|
||||
invert H.
|
||||
propositional.
|
||||
|
||||
invert H1.
|
||||
propositional.
|
||||
|
||||
invert H.
|
||||
propositional.
|
||||
|
||||
invert H1.
|
||||
propositional.
|
||||
Qed.*)
|
||||
|
||||
|
||||
(** * Another abstraction example *)
|
||||
|
||||
Inductive pc :=
|
||||
|
|
Loading…
Reference in a new issue