{-# OPTIONS_GHC -Wall -Werror #-}
module Documentation.SBV.Examples.Queries.Concurrency where
import Data.SBV
import Data.SBV.Control
import Control.Concurrent
import Control.Monad.IO.Class (liftIO)
shared :: MVar (SInteger, SInteger) -> Symbolic ()
shared :: MVar (SInteger, SInteger) -> Symbolic ()
shared MVar (SInteger, SInteger)
v = do
SInteger
x <- String -> Symbolic SInteger
sInteger String
"x"
SInteger
y <- String -> Symbolic SInteger
sInteger String
"y"
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ SInteger
y forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
10
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ SInteger
x forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
10
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ SInteger
x forall a. Num a => a -> a -> a
+ SInteger
y forall a. EqSymbolic a => a -> a -> SBool
.== SInteger
10
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> a -> IO ()
putMVar MVar (SInteger, SInteger)
v (SInteger
x,SInteger
y)
queryOne :: MVar (SInteger, SInteger) -> Query (Maybe Integer)
queryOne :: MVar (SInteger, SInteger) -> Query (Maybe Integer)
queryOne MVar (SInteger, SInteger)
v = do
forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn String
"[One]: Waiting"
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Int -> IO ()
threadDelay Int
5000000
forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn String
"[One]: Done"
(SInteger
x,SInteger
y) <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> IO a
takeMVar MVar (SInteger, SInteger)
v
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ SInteger
x forall a. OrdSymbolic a => a -> a -> SBool
.< SInteger
y
CheckSatResult
cs <- Query CheckSatResult
checkSat
case CheckSatResult
cs of
CheckSatResult
Unk -> forall a. HasCallStack => String -> a
error String
"Too bad, solver said unknown.."
DSat{} -> forall a. HasCallStack => String -> a
error String
"Unexpected dsat result.."
CheckSatResult
Unsat -> do forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn String
"No other solution!"
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
CheckSatResult
Sat -> do Integer
xv <- forall a. SymVal a => SBV a -> Query a
getValue SInteger
x
Integer
yv <- forall a. SymVal a => SBV a -> Query a
getValue SInteger
y
forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String
"[One]: Current solution is: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Integer
xv, Integer
yv)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (Integer
xv forall a. Num a => a -> a -> a
+ Integer
yv)
queryTwo :: MVar (SInteger, SInteger) -> Query (Maybe Integer)
queryTwo :: MVar (SInteger, SInteger) -> Query (Maybe Integer)
queryTwo MVar (SInteger, SInteger)
v = do
(SInteger
x,SInteger
y) <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> IO a
takeMVar MVar (SInteger, SInteger)
v
forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String
"[Two]: got values" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (SInteger
x,SInteger
y)
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ SInteger
y forall a. OrdSymbolic a => a -> a -> SBool
.< SInteger
x
CheckSatResult
cs <- Query CheckSatResult
checkSat
case CheckSatResult
cs of
CheckSatResult
Unk -> forall a. HasCallStack => String -> a
error String
"Too bad, solver said unknown.."
DSat{} -> forall a. HasCallStack => String -> a
error String
"Unexpected dsat result.."
CheckSatResult
Unsat -> do forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn String
"No other solution!"
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
CheckSatResult
Sat -> do Integer
yv <- forall a. SymVal a => SBV a -> Query a
getValue SInteger
y
Integer
xv <- forall a. SymVal a => SBV a -> Query a
getValue SInteger
x
forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String
"[Two]: Current solution is: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Integer
xv, Integer
yv)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (Integer
xv forall a. Num a => a -> a -> a
* Integer
yv)
demo :: IO ()
demo :: IO ()
demo = do
MVar (SInteger, SInteger)
v <- forall a. IO (MVar a)
newEmptyMVar
String -> IO ()
putStrLn String
"[Main]: Hello from main, kicking off children: "
[(Solver, NominalDiffTime, SatResult)]
results <- forall a b.
Provable a =>
SMTConfig
-> [Query b] -> a -> IO [(Solver, NominalDiffTime, SatResult)]
satConcurrentWithAll SMTConfig
z3 [MVar (SInteger, SInteger) -> Query (Maybe Integer)
queryOne MVar (SInteger, SInteger)
v, MVar (SInteger, SInteger) -> Query (Maybe Integer)
queryTwo MVar (SInteger, SInteger)
v] (MVar (SInteger, SInteger) -> Symbolic ()
shared MVar (SInteger, SInteger)
v)
String -> IO ()
putStrLn String
"[Main]: Children spawned, waiting for results"
String -> IO ()
putStrLn String
"[Main]: Here they are: "
forall a. Show a => a -> IO ()
print [(Solver, NominalDiffTime, SatResult)]
results
sharedDependent :: MVar (SInteger, SInteger) -> Symbolic ()
sharedDependent :: MVar (SInteger, SInteger) -> Symbolic ()
sharedDependent MVar (SInteger, SInteger)
v = do
SInteger
x <- String -> Symbolic SInteger
sInteger String
"x"
SInteger
y <- String -> Symbolic SInteger
sInteger String
"y"
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ SInteger
y forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
10
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ SInteger
x forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
10
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ SInteger
x forall a. Num a => a -> a -> a
+ SInteger
y forall a. EqSymbolic a => a -> a -> SBool
.== SInteger
10
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> a -> IO ()
putMVar MVar (SInteger, SInteger)
v (SInteger
x,SInteger
y)
firstQuery :: MVar (SInteger, SInteger) -> MVar (SInteger , SInteger) -> Query (Maybe Integer)
firstQuery :: MVar (SInteger, SInteger)
-> MVar (SInteger, SInteger) -> Query (Maybe Integer)
firstQuery MVar (SInteger, SInteger)
v1 MVar (SInteger, SInteger)
v2 = do
(SInteger
x,SInteger
y) <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> IO a
takeMVar MVar (SInteger, SInteger)
v1
forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn String
"[One]: got vars...working..."
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ SInteger
x forall a. OrdSymbolic a => a -> a -> SBool
.< SInteger
y
CheckSatResult
cs <- Query CheckSatResult
checkSat
case CheckSatResult
cs of
CheckSatResult
Unk -> forall a. HasCallStack => String -> a
error String
"Too bad, solver said unknown.."
DSat{} -> forall a. HasCallStack => String -> a
error String
"Unexpected dsat result.."
CheckSatResult
Unsat -> do forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn String
"No other solution!"
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
CheckSatResult
Sat -> do Integer
xv <- forall a. SymVal a => SBV a -> Query a
getValue SInteger
x
Integer
yv <- forall a. SymVal a => SBV a -> Query a
getValue SInteger
y
forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String
"[One]: Current solution is: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Integer
xv, Integer
yv)
forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn String
"[One]: Place vars for [Two]"
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> a -> IO ()
putMVar MVar (SInteger, SInteger)
v2 (forall a. SymVal a => a -> SBV a
literal (Integer
xv forall a. Num a => a -> a -> a
+ Integer
yv), forall a. SymVal a => a -> SBV a
literal (Integer
xv forall a. Num a => a -> a -> a
* Integer
yv))
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (Integer
xv forall a. Num a => a -> a -> a
+ Integer
yv)
secondQuery :: MVar (SInteger, SInteger) -> Query (Maybe Integer)
secondQuery :: MVar (SInteger, SInteger) -> Query (Maybe Integer)
secondQuery MVar (SInteger, SInteger)
v2 = do
(SInteger
x,SInteger
y) <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> IO a
takeMVar MVar (SInteger, SInteger)
v2
forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String
"[Two]: got values" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (SInteger
x,SInteger
y)
SInteger
z <- forall a. SymVal a => String -> Query (SBV a)
freshVar String
"z"
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ SInteger
z forall a. OrdSymbolic a => a -> a -> SBool
.> SInteger
x forall a. Num a => a -> a -> a
+ SInteger
y
CheckSatResult
cs <- Query CheckSatResult
checkSat
case CheckSatResult
cs of
CheckSatResult
Unk -> forall a. HasCallStack => String -> a
error String
"Too bad, solver said unknown.."
DSat{} -> forall a. HasCallStack => String -> a
error String
"Unexpected dsat result.."
CheckSatResult
Unsat -> do forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn String
"No other solution!"
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
CheckSatResult
Sat -> do Integer
yv <- forall a. SymVal a => SBV a -> Query a
getValue SInteger
y
Integer
xv <- forall a. SymVal a => SBV a -> Query a
getValue SInteger
x
Integer
zv <- forall a. SymVal a => SBV a -> Query a
getValue SInteger
z
forall a. IO a -> Query a
io forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String
"[Two]: My solution is: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Integer
zv forall a. Num a => a -> a -> a
+ Integer
xv, Integer
zv forall a. Num a => a -> a -> a
+ Integer
yv)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (Integer
zv forall a. Num a => a -> a -> a
* Integer
xv forall a. Num a => a -> a -> a
* Integer
yv)
demoDependent :: IO ()
demoDependent :: IO ()
demoDependent = do
MVar (SInteger, SInteger)
v1 <- forall a. IO (MVar a)
newEmptyMVar
MVar (SInteger, SInteger)
v2 <- forall a. IO (MVar a)
newEmptyMVar
[(Solver, NominalDiffTime, SatResult)]
results <- forall a b.
Provable a =>
SMTConfig
-> [Query b] -> a -> IO [(Solver, NominalDiffTime, SatResult)]
satConcurrentWithAll SMTConfig
z3 [MVar (SInteger, SInteger)
-> MVar (SInteger, SInteger) -> Query (Maybe Integer)
firstQuery MVar (SInteger, SInteger)
v1 MVar (SInteger, SInteger)
v2, MVar (SInteger, SInteger) -> Query (Maybe Integer)
secondQuery MVar (SInteger, SInteger)
v2] (MVar (SInteger, SInteger) -> Symbolic ()
sharedDependent MVar (SInteger, SInteger)
v1)
forall a. Show a => a -> IO ()
print [(Solver, NominalDiffTime, SatResult)]
results
{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}