{- | This module can be used if the simple 'Language.SMTLib2.withSMTSolver'-interface isn't sufficient, e.g. if you don't want to wrap your whole program into one big 'Language.SMTLib2.MonadSMT' or you want to run multiple solvers side by side. -} module Language.SMTLib2.Connection (SMTConnection() ,open ,close ,withConnection ,performSMT ,performSMTExitCleanly ) where import Language.SMTLib2.Internals import Control.Concurrent.MVar import Control.Monad.Trans (MonadIO,liftIO) import Control.Exception import Prelude (($),IO,return) -- | Represents a connection to an SMT solver. -- The SMT solver runs in a seperate thread and communication is handled via handles. data SMTConnection b = SMTConnection { backend :: MVar b } -- | Create a new connection to a SMT solver by spawning a shell command. -- The solver must be able to read from stdin and write to stdout. open :: (MonadIO m,SMTBackend b m) => b -- ^ The backend for the SMT solver. -> m (SMTConnection b) open solver = do st <- liftIO $ newMVar solver return (SMTConnection { backend = st }) -- | Closes an open SMT connection. Do not use the connection afterwards. close :: (MonadIO m,SMTBackend b m) => SMTConnection b -> m () close conn = do st <- liftIO $ takeMVar (backend conn) smtHandle st SMTExit return () withConnection :: MonadIO m => SMTConnection b -> (b -> m (a,b)) -> m a withConnection conn f = do b <- liftIO $ takeMVar (backend conn) (res,nb) <- f b liftIO $ putMVar (backend conn) nb return res -- | Perform an action in the SMT solver associated with this connection and return the result. performSMT :: (MonadIO m,SMTBackend b m) => SMTConnection b -- ^ The connection to the SMT solver to use -> SMT' m a -- ^ The action to perform -> m a performSMT conn act = withConnection conn (runSMT act) performSMTExitCleanly :: SMTBackend b IO => SMTConnection b -> SMT' IO a -> IO a performSMTExitCleanly conn act = do b <- takeMVar (backend conn) catch (do (res,nb) <- runSMT act b putMVar (backend conn) nb return res) (\e -> do smtHandle b SMTExit throw (e :: SomeException))