tla-plus/TwoPC/Coq/TwoPC.v
2018-01-21 20:45:05 +08:00

294 lines
8.8 KiB
Coq

Require Import List Bool Arith.
Require Import TwoPC.Crush TwoPC.Learn.
(** The collection of resource managers (RM). *)
Axiom RM : Type.
(** Assumes two RMs are distinguishable. *)
Axiom RMDecidable :
forall x y : RM, { x = y } + { x <> y }.
Inductive RMState : Set :=
RMWorking | RMPrepared | RMCommitted | RMAborted.
Inductive TMState : Set :=
| TMInit | TMCommitted | TMAborted.
Inductive Message : Type :=
MsgPrepared : RM -> Message
| MsgCommit | MsgAbort.
Record State := {
rmState : RM -> RMState;
tmState : TMState;
tmPrepared : RM -> bool;
msgs : list Message
}.
Inductive StateInit : State -> Prop :=
| InitIntro :
forall (rmInit : RM -> RMState) (tmPreparedInit : RM -> bool),
(forall rm, rmInit rm = RMWorking /\ tmPreparedInit rm = false) ->
StateInit {| rmState := rmInit;
tmState := TMInit;
tmPrepared := tmPreparedInit;
msgs := nil |}.
Inductive StateStep : State -> State -> Prop :=
| TMRcvPrepared :
forall rm rmState tmState msgs tmPrepared tmPrepared',
tmState = TMInit ->
In (MsgPrepared rm) msgs ->
(forall rm0, rm0 <> rm -> tmPrepared rm0 = tmPrepared' rm0) ->
tmPrepared' rm = true ->
StateStep {| rmState := rmState;
tmState := tmState;
tmPrepared := tmPrepared;
msgs := msgs |}
{| rmState := rmState;
tmState := tmState;
tmPrepared := tmPrepared';
msgs := msgs |}
| TMCommit :
forall rmState tmState tmState' tmPrepared msgs msgs',
tmState = TMInit ->
(forall rm, tmPrepared rm = true) ->
tmState' = TMCommitted ->
msgs' = cons MsgCommit msgs ->
StateStep {| rmState := rmState;
tmState := tmState;
tmPrepared := tmPrepared;
msgs := msgs |}
{| rmState := rmState;
tmState := tmState';
tmPrepared := tmPrepared;
msgs := msgs' |}
| TMAbort :
forall rmState tmState tmState' tmPrepared msgs msgs',
tmState = TMInit ->
tmState' = TMAborted ->
msgs' = cons MsgAbort msgs ->
StateStep {| rmState := rmState;
tmState := tmState;
tmPrepared := tmPrepared;
msgs := msgs |}
{| rmState := rmState;
tmState := tmState';
tmPrepared := tmPrepared;
msgs := msgs' |}
| RMPrepare :
forall rm rmState rmState' tmState tmPrepared msgs msgs',
rmState rm = RMWorking ->
(forall rm0, rm0 <> rm -> rmState rm0 = rmState' rm0) ->
rmState' rm = RMPrepared ->
msgs' = cons (MsgPrepared rm) msgs ->
StateStep {| rmState := rmState;
tmState := tmState;
tmPrepared := tmPrepared;
msgs := msgs |}
{| rmState := rmState';
tmState := tmState;
tmPrepared := tmPrepared;
msgs := msgs' |}
| RMChooseToAbort :
forall rm rmState rmState' tmState tmPrepared msgs,
rmState rm = RMWorking ->
(forall rm0, rm0 <> rm -> rmState rm0 = rmState' rm0) ->
rmState' rm = RMAborted ->
StateStep {| rmState := rmState;
tmState := tmState;
tmPrepared := tmPrepared;
msgs := msgs |}
{| rmState := rmState';
tmState := tmState;
tmPrepared := tmPrepared;
msgs := msgs |}
| RMRcvCommitMsg :
forall rm rmState rmState' tmState tmPrepared msgs,
In MsgCommit msgs ->
(forall rm0, rm0 <> rm -> rmState rm0 = rmState' rm0) ->
rmState' rm = RMCommitted ->
StateStep {| rmState := rmState;
tmState := tmState;
tmPrepared := tmPrepared;
msgs := msgs |}
{| rmState := rmState';
tmState := tmState;
tmPrepared := tmPrepared;
msgs := msgs |}
| RMRcvAbortMsg :
forall rm rmState rmState' tmState tmPrepared msgs,
In MsgAbort msgs ->
(forall rm0, rm0 <> rm -> rmState rm0 = rmState' rm0) ->
rmState' rm = RMAborted ->
StateStep {| rmState := rmState;
tmState := tmState;
tmPrepared := tmPrepared;
msgs := msgs |}
{| rmState := rmState';
tmState := tmState;
tmPrepared := tmPrepared;
msgs := msgs |}.
Inductive StateMultiStep : State -> State -> Prop :=
| StateMultiStep0 :
forall state,
StateMultiStep state state
| StateMultiStep1 :
forall state state1 state2,
StateStep state1 state2 ->
StateMultiStep state state1 ->
StateMultiStep state state2.
Inductive Consistency : State -> Prop :=
| ConsistencyIntro :
forall rmState tmState tmPrepared msgs,
( (* if one RM is committed, other RMs cannot be aborted. *)
(exists rm, rmState rm = RMCommitted) ->
(forall rm, rmState rm <> RMAborted)
) ->
( (* if one RM is aborted, other RMs cannot be committed. *)
(exists rm, rmState rm = RMAborted) ->
(forall rm, rmState rm <> RMCommitted)
) ->
Consistency {| rmState := rmState;
tmState := tmState;
tmPrepared := tmPrepared;
msgs := msgs |}.
Inductive Invariant : State -> Prop :=
| InvariantIntro :
forall rmState tmState tmPrepared msgs,
(
tmState = TMInit -> (* 1PC *)
(
(forall rm, rmState rm <> RMCommitted) /\
(forall rm, (In (MsgPrepared rm) msgs <-> rmState rm = RMPrepared)) /\
(forall rm, tmPrepared rm = true -> rmState rm = RMPrepared)
)
) ->
( (* 2PC: Commit *)
tmState = TMCommitted ->
(
forall rm, rmState rm = RMCommitted \/ rmState rm = RMPrepared
)
) ->
( (* 2PC: Abort *)
tmState = TMAborted ->
(
forall rm, rmState rm <> RMCommitted
)
) ->
( (* Abort message in message list <==> TM is aborted *)
In MsgAbort msgs <-> tmState = TMAborted
) ->
( (* Committed message in message list <==> TM is committed *)
In MsgCommit msgs <-> tmState = TMCommitted
) ->
Invariant {| rmState := rmState;
tmState := tmState;
tmPrepared := tmPrepared;
msgs := msgs |}.
Ltac inst_rm x :=
repeat
( match goal with
| [ H: forall rm, _ |- _ ] => learn (H x)
end
);
repeat
( match goal with
| [ H : Learnt |- _ ] => clear H
end
).
Ltac invert H := inversion H; subst; clear H.
Lemma InvariantImpliesConsistency :
forall state, Invariant state -> Consistency state.
Proof.
intros.
invert H. constructor; crush.
+ destruct tmState0; crush;
try (inst_rm x; crush);
try (inst_rm rm; crush).
+ destruct tmState0; crush;
try (inst_rm x; crush);
try (inst_rm rm; crush).
Qed.
Lemma InitStateSatisfiesInvariant :
forall state, StateInit state -> Invariant state.
Proof.
intros.
invert H; constructor; crush;
try (inst_rm x); try (inst_rm rm); crush.
Qed.
Lemma StateStepKeepsInvariant :
forall state state',
StateStep state state' ->
Invariant state ->
Invariant state'.
Proof.
intros.
invert H0; invert H.
+ constructor; crush.
destruct (RMDecidable rm0 rm).
- inst_rm rm; crush.
- inst_rm rm0; eauto.
+ constructor; crush.
+ constructor; crush.
+ destruct tmState0.
- constructor; crush;
destruct (RMDecidable rm0 rm); crush; inst_rm rm; inst_rm rm0; crush.
- crush. inst_rm rm; crush.
- constructor; crush;
destruct (RMDecidable rm0 rm); crush; inst_rm rm; inst_rm rm0; crush.
+ destruct tmState0.
- constructor; crush;
destruct (RMDecidable rm0 rm); crush; inst_rm rm; inst_rm rm0; crush.
- crush. inst_rm rm; crush.
- constructor; crush;
destruct (RMDecidable rm0 rm); crush; inst_rm rm; inst_rm rm0; crush.
+ constructor; crush.
destruct (RMDecidable rm0 rm).
- crush.
- inst_rm rm0; crush.
left; crush.
right; crush.
+ constructor; crush.
destruct (RMDecidable rm0 rm).
- crush.
- inst_rm rm0; crush.
Qed.
Lemma Safety' :
forall state state',
StateMultiStep state state' ->
Invariant state ->
Invariant state'.
Proof.
induction 1; intros.
+ auto.
+ eapply StateStepKeepsInvariant; eauto.
Qed.
Theorem Safety :
forall state state',
StateMultiStep state state' ->
StateInit state ->
Consistency state'.
Proof.
intros.
apply InvariantImpliesConsistency.
apply InitStateSatisfiesInvariant in H0.
eapply Safety'; eauto.
Qed.