mirror of
https://github.com/achlipala/frap.git
synced 2024-11-10 00:07:51 +00:00
82 lines
2.8 KiB
Coq
82 lines
2.8 KiB
Coq
Require Import Relations.
|
|
|
|
Set Implicit Arguments.
|
|
|
|
|
|
Record trsys state := {
|
|
Initial : state -> Prop;
|
|
Step : state -> state -> Prop
|
|
}.
|
|
|
|
Definition invariantFor {state} (sys : trsys state) (invariant : state -> Prop) :=
|
|
forall s, sys.(Initial) s
|
|
-> forall s', sys.(Step)^* s s'
|
|
-> invariant s'.
|
|
|
|
Theorem use_invariant : forall {state} (sys : trsys state) (invariant : state -> Prop) s s',
|
|
invariantFor sys invariant
|
|
-> sys.(Step)^* s s'
|
|
-> sys.(Initial) s
|
|
-> invariant s'.
|
|
Proof.
|
|
firstorder.
|
|
Qed.
|
|
|
|
Theorem invariant_weaken : forall {state} (sys : trsys state)
|
|
(invariant1 invariant2 : state -> Prop),
|
|
invariantFor sys invariant1
|
|
-> (forall s, invariant1 s -> invariant2 s)
|
|
-> invariantFor sys invariant2.
|
|
Proof.
|
|
unfold invariantFor; intuition eauto.
|
|
Qed.
|
|
|
|
Theorem invariant_induction : forall {state} (sys : trsys state)
|
|
(invariant : state -> Prop),
|
|
(forall s, sys.(Initial) s -> invariant s)
|
|
-> (forall s, invariant s -> forall s', sys.(Step) s s' -> invariant s')
|
|
-> invariantFor sys invariant.
|
|
Proof.
|
|
unfold invariantFor; intros.
|
|
assert (invariant s) by eauto.
|
|
clear H1.
|
|
induction H2; eauto.
|
|
Qed.
|
|
|
|
|
|
(** * General parallel composition *)
|
|
|
|
Record threaded_state shared private := {
|
|
Shared : shared;
|
|
Private : private
|
|
}.
|
|
|
|
Inductive parallel1 shared private1 private2
|
|
(init1 : threaded_state shared private1 -> Prop)
|
|
(init2 : threaded_state shared private2 -> Prop)
|
|
: threaded_state shared (private1 * private2) -> Prop :=
|
|
| Pinit : forall sh pr1 pr2,
|
|
init1 {| Shared := sh; Private := pr1 |}
|
|
-> init2 {| Shared := sh; Private := pr2 |}
|
|
-> parallel1 init1 init2 {| Shared := sh; Private := (pr1, pr2) |}.
|
|
|
|
Inductive parallel2 shared private1 private2
|
|
(step1 : threaded_state shared private1 -> threaded_state shared private1 -> Prop)
|
|
(step2 : threaded_state shared private2 -> threaded_state shared private2 -> Prop)
|
|
: threaded_state shared (private1 * private2)
|
|
-> threaded_state shared (private1 * private2) -> Prop :=
|
|
| Pstep1 : forall sh pr1 pr2 sh' pr1',
|
|
step1 {| Shared := sh; Private := pr1 |} {| Shared := sh'; Private := pr1' |}
|
|
-> parallel2 step1 step2 {| Shared := sh; Private := (pr1, pr2) |}
|
|
{| Shared := sh'; Private := (pr1', pr2) |}
|
|
| Pstep2 : forall sh pr1 pr2 sh' pr2',
|
|
step2 {| Shared := sh; Private := pr2 |} {| Shared := sh'; Private := pr2' |}
|
|
-> parallel2 step1 step2 {| Shared := sh; Private := (pr1, pr2) |}
|
|
{| Shared := sh'; Private := (pr1, pr2') |}.
|
|
|
|
Definition parallel shared private1 private2
|
|
(sys1 : trsys (threaded_state shared private1))
|
|
(sys2 : trsys (threaded_state shared private2)) := {|
|
|
Initial := parallel1 sys1.(Initial) sys2.(Initial);
|
|
Step := parallel2 sys1.(Step) sys2.(Step)
|
|
|}.
|