sbv-13.1: SMT Based Verification: Symbolic Haskell theorem prover using SMT solving.
Copyright(c) Levent Erkok
LicenseBSD3
Maintainererkokl@gmail.com
Stabilityexperimental
Safe HaskellNone
LanguageHaskell2010

Documentation.SBV.Examples.Lists.BoundedMutex

Description

Proves a simple mutex algorithm correct up to a given bound.

Synopsis

Documentation

data State Source #

Each agent can be in one of the three states

Constructors

Idle

Regular work

Ready

Intention to enter critical state

Critical

In the critical state

Instances

Instances details
Arbitrary State Source # 
Instance details

Defined in Documentation.SBV.Examples.Lists.BoundedMutex

Methods

arbitrary :: Gen State #

shrink :: State -> [State] #

Show State Source # 
Instance details

Defined in Documentation.SBV.Examples.Lists.BoundedMutex

Methods

showsPrec :: Int -> State -> ShowS #

show :: State -> String #

showList :: [State] -> ShowS #

SymVal State Source # 
Instance details

Defined in Documentation.SBV.Examples.Lists.BoundedMutex

HasKind State Source # 
Instance details

Defined in Documentation.SBV.Examples.Lists.BoundedMutex

EnumSymbolic State Source # 
Instance details

Defined in Documentation.SBV.Examples.Lists.BoundedMutex

SatModel State Source # 
Instance details

Defined in Documentation.SBV.Examples.Lists.BoundedMutex

Methods

parseCVs :: [CV] -> Maybe (State, [CV]) Source #

cvtModel :: (State -> Maybe b) -> Maybe (State, [CV]) -> Maybe (b, [CV]) Source #

OrdSymbolic (SBV State) Source # 
Instance details

Defined in Documentation.SBV.Examples.Lists.BoundedMutex

HasInductionSchema (Forall ta State -> SBool) Source # 
Instance details

Defined in Documentation.SBV.Examples.Lists.BoundedMutex

Methods

inductionSchema :: (Forall ta State -> SBool) -> ProofObj Source #

SymVal extraT => HasInductionSchema (Forall ta State -> Forall extraS extraT -> SBool) Source # 
Instance details

Defined in Documentation.SBV.Examples.Lists.BoundedMutex

Methods

inductionSchema :: (Forall ta State -> Forall extraS extraT -> SBool) -> ProofObj Source #

(SymVal extraT1, SymVal extraT2) => HasInductionSchema (Forall ta State -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> SBool) Source # 
Instance details

Defined in Documentation.SBV.Examples.Lists.BoundedMutex

Methods

inductionSchema :: (Forall ta State -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> SBool) -> ProofObj Source #

(SymVal extraT1, SymVal extraT2, SymVal extraT3) => HasInductionSchema (Forall ta State -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> Forall extraS3 extraT3 -> SBool) Source # 
Instance details

Defined in Documentation.SBV.Examples.Lists.BoundedMutex

Methods

inductionSchema :: (Forall ta State -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> Forall extraS3 extraT3 -> SBool) -> ProofObj Source #

(SymVal extraT1, SymVal extraT2, SymVal extraT3, SymVal extraT4) => HasInductionSchema (Forall ta State -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> Forall extraS3 extraT3 -> Forall extraS4 extraT4 -> SBool) Source # 
Instance details

Defined in Documentation.SBV.Examples.Lists.BoundedMutex

Methods

inductionSchema :: (Forall ta State -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> Forall extraS3 extraT3 -> Forall extraS4 extraT4 -> SBool) -> ProofObj Source #

(SymVal extraT1, SymVal extraT2, SymVal extraT3, SymVal extraT4, SymVal extraT5) => HasInductionSchema (Forall ta State -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> Forall extraS3 extraT3 -> Forall extraS4 extraT4 -> Forall extraS5 extraT5 -> SBool) Source # 
Instance details

Defined in Documentation.SBV.Examples.Lists.BoundedMutex

Methods

inductionSchema :: (Forall ta State -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> Forall extraS3 extraT3 -> Forall extraS4 extraT4 -> Forall extraS5 extraT5 -> SBool) -> ProofObj Source #

cv2State :: String -> [CV] -> State Source #

Conversion from SMT values to State values.

_undefiner_State :: a Source #

Autogenerated definition to avoid unused-variable warnings from GHC.

type SState = SBV State Source #

Symbolic version of the type State.

sIdle :: SBV State Source #

Symbolic version of the constructor Idle.

sReady :: SBV State Source #

Symbolic version of the constructor Ready.

sCritical :: SBV State Source #

Symbolic version of the constructor Critical.

isIdle :: SBV State -> SBool Source #

Field recognizer predicate.

isReady :: SBV State -> SBool Source #

Field recognizer predicate.

isCritical :: SBV State -> SBool Source #

Field recognizer predicate.

sCaseState :: Mergeable result => SBV State -> result -> result -> result -> result Source #

Case analyzer for the type State.

mutex :: [SState] -> [SState] -> SBool Source #

The mutex property holds for two sequences of state transitions, if they are not in their critical section at the same time.

validSequence :: Integer -> [SInteger] -> [SState] -> SBool Source #

A sequence is valid upto a bound if it starts at Idle, and follows the mutex rules. That is:

The variable me identifies the agent id.

validTurns :: [SInteger] -> [SState] -> [SState] -> SBool Source #

The mutex algorithm, coded implicitly as an assignment to turns. Turns start at 1, and at each stage is either 1 or 2; giving preference to that process. The only condition is that if either process is in its critical section, then the turn value stays the same. Note that this is sufficient to satisfy safety (i.e., mutual exclusion), though it does not guarantee liveness.

checkMutex :: Int -> IO () Source #

Check that we have the mutex property so long as validSequence and validTurns holds; i.e., so long as both the agents and the arbiter act according to the rules. The check is bounded up-to-the given concrete bound; so this is an example of a bounded-model-checking style proof. We have:

>>> checkMutex 20
All is good!

notFair :: Int -> IO () Source #

Our algorithm is correct, but it is not fair. It does not guarantee that a process that wants to enter its critical-section will always do so eventually. Demonstrate this by trying to show a bounded trace of length 10, such that the second process is ready but never transitions to critical. We have:

>>> notFair 10
Fairness is violated at bound: 10
P1: [Idle,Idle,Ready,Critical,Idle,Ready,Critical,Critical,Idle,Ready]
P2: [Idle,Ready,Ready,Ready,Ready,Ready,Ready,Ready,Ready,Ready]
Ts: [1,1,1,1,1,1,1,1,1,1]

As expected, P2 gets ready but never goes critical since the arbiter keeps picking P1 unfairly. (You might get a different trace depending on what z3 happens to produce!)

Exercise for the reader: Change the validTurns function so that it alternates the turns from the previous value if neither process is in critical. Show that this makes the notFair function below no longer exhibits the issue. Is this sufficient? Concurrent programming is tricky!