mirror of
https://github.com/pingcap/tla-plus.git
synced 2024-12-28 13:30:10 +08:00
294 lines
8.8 KiB
Coq
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.
|