{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
module Data.SBV.Client
( sbvCheckSolverInstallation
, defaultSolverConfig
, sbvAvailableSolvers
, mkSymbolicEnumeration
) where
import Control.Monad (filterM)
import Data.Generics
import qualified Control.Exception as C
import qualified Language.Haskell.TH as TH
import Data.SBV.Core.Data
import Data.SBV.Core.Model
import Data.SBV.Control.Utils
import Data.SBV.Provers.Prover
sbvCheckSolverInstallation :: SMTConfig -> IO Bool
sbvCheckSolverInstallation cfg = check `C.catch` (\(_ :: C.SomeException) -> return False)
where check = do ThmResult r <- proveWith cfg $ \x -> (x+x) .== ((x*2) :: SWord8)
case r of
Unsatisfiable{} -> return True
_ -> return False
defaultSolverConfig :: Solver -> SMTConfig
defaultSolverConfig Z3 = z3
defaultSolverConfig Yices = yices
defaultSolverConfig Boolector = boolector
defaultSolverConfig CVC4 = cvc4
defaultSolverConfig MathSAT = mathSAT
defaultSolverConfig ABC = abc
sbvAvailableSolvers :: IO [SMTConfig]
sbvAvailableSolvers = filterM sbvCheckSolverInstallation (map defaultSolverConfig [minBound .. maxBound])
mkSymbolicEnumeration :: TH.Name -> TH.Q [TH.Dec]
mkSymbolicEnumeration typeName = do
let typeCon = TH.conT typeName
[d| deriving instance Eq $(typeCon)
deriving instance Show $(typeCon)
deriving instance Ord $(typeCon)
deriving instance Read $(typeCon)
deriving instance Data $(typeCon)
deriving instance SymVal $(typeCon)
deriving instance HasKind $(typeCon)
deriving instance SMTValue $(typeCon)
deriving instance SatModel $(typeCon)
|]