sbv-8.7: SMT Based Verification: Symbolic Haskell theorem prover using SMT solving.

Documentation.SBV.Examples.Lists.BoundedMutex

Description

Demonstrates use of bounded list utilities, proving a simple mutex algorithm correct up to given bounds.

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
 Source # Instance details Methods(==) :: State -> State -> Bool #(/=) :: State -> State -> Bool # Source # Instance details Methodsgfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> State -> c State #gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c State #dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c State) #dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c State) #gmapT :: (forall b. Data b => b -> b) -> State -> State #gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> State -> r #gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> State -> r #gmapQ :: (forall d. Data d => d -> u) -> State -> [u] #gmapQi :: Int -> (forall d. Data d => d -> u) -> State -> u #gmapM :: Monad m => (forall d. Data d => d -> m d) -> State -> m State #gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> State -> m State #gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> State -> m State # Source # Instance details Methods(<) :: State -> State -> Bool #(<=) :: State -> State -> Bool #(>) :: State -> State -> Bool #(>=) :: State -> State -> Bool #max :: State -> State -> State #min :: State -> State -> State # Source # Instance details Methods Source # Instance details MethodsshowsPrec :: Int -> State -> ShowS #show :: State -> String #showList :: [State] -> ShowS # Source # Instance details Methods Source # Instance details MethodsisConcretely :: SBV State -> (State -> Bool) -> Bool Source #forall :: MonadSymbolic m => String -> m (SBV State) Source #forall_ :: MonadSymbolic m => m (SBV State) Source #mkForallVars :: MonadSymbolic m => Int -> m [SBV State] Source #exists :: MonadSymbolic m => String -> m (SBV State) Source #exists_ :: MonadSymbolic m => m (SBV State) Source #mkExistVars :: MonadSymbolic m => Int -> m [SBV State] Source #free :: MonadSymbolic m => String -> m (SBV State) Source #free_ :: MonadSymbolic m => m (SBV State) Source #mkFreeVars :: MonadSymbolic m => Int -> m [SBV State] Source #symbolic :: MonadSymbolic m => String -> m (SBV State) Source #symbolics :: MonadSymbolic m => [String] -> m [SBV State] Source # Source # Make State a symbolic enumeration Instance details MethodsparseCVs :: [CV] -> Maybe (State, [CV]) Source #cvtModel :: (State -> Maybe b) -> Maybe (State, [CV]) -> Maybe (b, [CV]) Source #

The type synonym SState is mnemonic for symbolic state.

Symbolic version of Idle

Symbolic version of Ready

Symbolic version of Critical

A bounded mutex property holds for two sequences of state transitions, if they are not in their critical section at the same time up to that given bound.

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

• From Idle it can switch to Ready or stay Idle
• From Ready it can switch to Critical if it's its turn
• From Critical it can either stay in Critical or go back to Idle

The variable me identifies the agent id.

The mutex algorithm, coded implicity 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:

ghci> notFair 10
Fairness is violated at bound: 10
Ts: [1,2,1,1,1,1,1,1,1,1]
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!