packages feed

hasmtlib 2.6.3 → 2.7.0

raw patch · 23 files changed

+764/−453 lines, 23 filesdep +lifted-basedep +monad-controlPVP ok

version bump matches the API change (PVP)

Dependencies added: lifted-base, monad-control

API changes (from Hackage documentation)

- Language.Hasmtlib.Internal.Render: class RenderSeq a
- Language.Hasmtlib.Internal.Render: renderBinary :: (Render a, Render b) => Builder -> a -> b -> Builder
- Language.Hasmtlib.Internal.Render: renderNary :: Render a => Builder -> [a] -> Builder
- Language.Hasmtlib.Internal.Render: renderSeq :: RenderSeq a => a -> Seq Builder
- Language.Hasmtlib.Internal.Render: renderTernary :: (Render a, Render b, Render c) => Builder -> a -> b -> c -> Builder
- Language.Hasmtlib.Internal.Render: renderUnary :: Render a => Builder -> a -> Builder
- Language.Hasmtlib.Solver.Common: Debugger :: (s -> IO ()) -> (Seq Builder -> IO ()) -> (ByteString -> IO ()) -> (ByteString -> IO ()) -> Debugger s
- Language.Hasmtlib.Solver.Common: [debugModelResponse] :: Debugger s -> ByteString -> IO ()
- Language.Hasmtlib.Solver.Common: [debugProblem] :: Debugger s -> Seq Builder -> IO ()
- Language.Hasmtlib.Solver.Common: [debugResultResponse] :: Debugger s -> ByteString -> IO ()
- Language.Hasmtlib.Solver.Common: [debugState] :: Debugger s -> s -> IO ()
- Language.Hasmtlib.Solver.Common: data Debugger s
- Language.Hasmtlib.Solver.Common: debug :: (RenderSeq s, MonadIO m) => Config -> Debugger s -> Solver s m
- Language.Hasmtlib.Solver.Common: def :: Default a => a
- Language.Hasmtlib.Solver.Common: instance Data.Default.Class.Default (Language.Hasmtlib.Solver.Common.Debugger Language.Hasmtlib.Type.OMT.OMT)
- Language.Hasmtlib.Solver.Common: instance Data.Default.Class.Default (Language.Hasmtlib.Solver.Common.Debugger Language.Hasmtlib.Type.SMT.SMT)
- Language.Hasmtlib.Solver.Common: interactiveSolver :: MonadIO m => Config -> m (Solver, Handle)
- Language.Hasmtlib.Solver.Common: processSolver :: (RenderSeq s, MonadIO m) => Config -> Maybe (Debugger s) -> Solver s m
- Language.Hasmtlib.Solver.Common: solver :: (RenderSeq s, MonadIO m) => Config -> Solver s m
- Language.Hasmtlib.Type.Bitvec: instance Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.Bitvec.Bitvec enc n)
- Language.Hasmtlib.Type.Expr: instance GHC.Show.Show (Language.Hasmtlib.Type.Value.Value t)
- Language.Hasmtlib.Type.Expr: instance Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.Expr.SMTVar t)
- Language.Hasmtlib.Type.Expr: instance Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.Value.Value t)
- Language.Hasmtlib.Type.Expr: instance Language.Hasmtlib.Type.SMTSort.KnownSMTSort t => GHC.Show.Show (Language.Hasmtlib.Type.Expr.Expr t)
- Language.Hasmtlib.Type.Expr: instance Language.Hasmtlib.Type.SMTSort.KnownSMTSort t => Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.Expr.Expr t)
- Language.Hasmtlib.Type.OMT: instance GHC.Show.Show Language.Hasmtlib.Type.OMT.SoftFormula
- Language.Hasmtlib.Type.OMT: instance Language.Hasmtlib.Internal.Render.Render Language.Hasmtlib.Type.OMT.SoftFormula
- Language.Hasmtlib.Type.OMT: instance Language.Hasmtlib.Internal.Render.RenderSeq Language.Hasmtlib.Type.OMT.OMT
- Language.Hasmtlib.Type.OMT: instance Language.Hasmtlib.Type.SMTSort.KnownSMTSort t => Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.OMT.Maximize t)
- Language.Hasmtlib.Type.OMT: instance Language.Hasmtlib.Type.SMTSort.KnownSMTSort t => Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.OMT.Minimize t)
- Language.Hasmtlib.Type.Option: instance Language.Hasmtlib.Internal.Render.Render Language.Hasmtlib.Type.Option.SMTOption
- Language.Hasmtlib.Type.Pipe: [_isDebugging] :: Pipe -> !Bool
- Language.Hasmtlib.Type.Pipe: isDebugging :: Lens' Pipe Bool
- Language.Hasmtlib.Type.Relation: instance (GHC.Ix.Ix a, GHC.Ix.Ix b, GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Language.Hasmtlib.Type.Relation.Relation a b)
- Language.Hasmtlib.Type.SMT: instance Language.Hasmtlib.Internal.Render.RenderSeq Language.Hasmtlib.Type.SMT.SMT
- Language.Hasmtlib.Type.SMT: renderAssert :: Expr BoolSort -> Builder
- Language.Hasmtlib.Type.SMT: renderDeclareVar :: forall t. KnownSMTSort t => SMTVar t -> Builder
- Language.Hasmtlib.Type.SMT: renderSetLogic :: Builder -> Builder
- Language.Hasmtlib.Type.SMT: renderVars :: Seq (SomeKnownSMTSort SMTVar) -> Seq Builder
- Language.Hasmtlib.Type.SMTSort: instance Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.SMTSort.SSMTSort t)
- Language.Hasmtlib.Type.Solution: instance GHC.Show.Show (Language.Hasmtlib.Type.Solution.IntValueMap t)
- Language.Hasmtlib.Type.Solution: instance GHC.Show.Show (Language.Hasmtlib.Type.Solution.SMTVarSol t)
- Language.Hasmtlib.Type.Solution: type Solver s m = s -> m (Result, Solution)
- Language.Hasmtlib.Type.Solver: class WithSolver a
- Language.Hasmtlib.Type.Solver: debugInteractiveWith :: (WithSolver s, MonadIO m) => (Solver, Handle) -> StateT s m () -> m ()
- Language.Hasmtlib.Type.Solver: instance Language.Hasmtlib.Type.Solver.WithSolver Language.Hasmtlib.Type.Pipe.Pipe
- Language.Hasmtlib.Type.Solver: withSolver :: WithSolver a => Solver -> Bool -> a
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Int.Int16
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Int.Int32
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Int.Int64
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Int.Int8
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Num.Integer.Integer
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Num.Natural.Natural
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Types.Bool
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Types.Char
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Types.Double
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Types.Float
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Types.Int
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Types.Ordering
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Types.Word
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Word.Word16
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Word.Word32
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Word.Word64
+ Language.Hasmtlib.Codec: instance Language.Hasmtlib.Codec.Codec GHC.Word.Word8
+ Language.Hasmtlib.Internal.Render: class RenderProblem s
+ Language.Hasmtlib.Internal.Render: instance GHC.Show.Show (Language.Hasmtlib.Type.Value.Value t)
+ Language.Hasmtlib.Internal.Render: instance Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.Bitvec.Bitvec enc n)
+ Language.Hasmtlib.Internal.Render: instance Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.Expr.SMTVar t)
+ Language.Hasmtlib.Internal.Render: instance Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.SMTSort.SSMTSort t)
+ Language.Hasmtlib.Internal.Render: instance Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.Value.Value t)
+ Language.Hasmtlib.Internal.Render: instance Language.Hasmtlib.Internal.Render.Render Language.Hasmtlib.Type.OMT.SoftFormula
+ Language.Hasmtlib.Internal.Render: instance Language.Hasmtlib.Internal.Render.Render Language.Hasmtlib.Type.Option.SMTOption
+ Language.Hasmtlib.Internal.Render: instance Language.Hasmtlib.Internal.Render.RenderProblem Language.Hasmtlib.Type.OMT.OMT
+ Language.Hasmtlib.Internal.Render: instance Language.Hasmtlib.Internal.Render.RenderProblem Language.Hasmtlib.Type.SMT.SMT
+ Language.Hasmtlib.Internal.Render: instance Language.Hasmtlib.Type.SMTSort.KnownSMTSort t => GHC.Show.Show (Language.Hasmtlib.Type.Expr.Expr t)
+ Language.Hasmtlib.Internal.Render: instance Language.Hasmtlib.Type.SMTSort.KnownSMTSort t => Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.Expr.Expr t)
+ Language.Hasmtlib.Internal.Render: instance Language.Hasmtlib.Type.SMTSort.KnownSMTSort t => Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.OMT.Maximize t)
+ Language.Hasmtlib.Internal.Render: instance Language.Hasmtlib.Type.SMTSort.KnownSMTSort t => Language.Hasmtlib.Internal.Render.Render (Language.Hasmtlib.Type.OMT.Minimize t)
+ Language.Hasmtlib.Internal.Render: render1 :: Render a => Builder -> a -> Builder
+ Language.Hasmtlib.Internal.Render: render2 :: (Render a, Render b) => Builder -> a -> b -> Builder
+ Language.Hasmtlib.Internal.Render: render3 :: (Render a, Render b, Render c) => Builder -> a -> b -> c -> Builder
+ Language.Hasmtlib.Internal.Render: renderAssert :: Expr BoolSort -> Builder
+ Language.Hasmtlib.Internal.Render: renderAssertions :: RenderProblem s => s -> Seq Builder
+ Language.Hasmtlib.Internal.Render: renderCheckSat :: Builder
+ Language.Hasmtlib.Internal.Render: renderDeclareVar :: forall t. KnownSMTSort t => SMTVar t -> Builder
+ Language.Hasmtlib.Internal.Render: renderDeclareVars :: RenderProblem s => s -> Seq Builder
+ Language.Hasmtlib.Internal.Render: renderGetModel :: Builder
+ Language.Hasmtlib.Internal.Render: renderGetValue :: SMTVar t -> Builder
+ Language.Hasmtlib.Internal.Render: renderLogic :: RenderProblem s => s -> Builder
+ Language.Hasmtlib.Internal.Render: renderMaximizations :: RenderProblem s => s -> Seq Builder
+ Language.Hasmtlib.Internal.Render: renderMinimizations :: RenderProblem s => s -> Seq Builder
+ Language.Hasmtlib.Internal.Render: renderN :: Render a => Builder -> [a] -> Builder
+ Language.Hasmtlib.Internal.Render: renderOptions :: RenderProblem s => s -> Seq Builder
+ Language.Hasmtlib.Internal.Render: renderPop :: Integer -> Builder
+ Language.Hasmtlib.Internal.Render: renderPush :: Integer -> Builder
+ Language.Hasmtlib.Internal.Render: renderQuantifier :: forall t. KnownSMTSort t => Builder -> Maybe (SMTVar t) -> (Expr t -> Expr BoolSort) -> Builder
+ Language.Hasmtlib.Internal.Render: renderSetLogic :: Builder -> Builder
+ Language.Hasmtlib.Internal.Render: renderSoftAssertions :: RenderProblem s => s -> Seq Builder
+ Language.Hasmtlib.Type.Debugger: Debugger :: (s -> IO ()) -> (Builder -> IO ()) -> (Builder -> IO ()) -> (Builder -> IO ()) -> (Builder -> IO ()) -> (Builder -> IO ()) -> (Builder -> IO ()) -> (Builder -> IO ()) -> (Builder -> IO ()) -> (Builder -> IO ()) -> (Builder -> IO ()) -> (Builder -> IO ()) -> (Builder -> IO ()) -> (ByteString -> IO ()) -> (ByteString -> IO ()) -> Debugger s
+ Language.Hasmtlib.Type.Debugger: [debugAssertSoft] :: Debugger s -> Builder -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugAssert] :: Debugger s -> Builder -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugCheckSat] :: Debugger s -> Builder -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugGetModel] :: Debugger s -> Builder -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugGetValue] :: Debugger s -> Builder -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugLogic] :: Debugger s -> Builder -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugMaximize] :: Debugger s -> Builder -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugMinimize] :: Debugger s -> Builder -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugModelResponse] :: Debugger s -> ByteString -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugOption] :: Debugger s -> Builder -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugPop] :: Debugger s -> Builder -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugPush] :: Debugger s -> Builder -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugResultResponse] :: Debugger s -> ByteString -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugState] :: Debugger s -> s -> IO ()
+ Language.Hasmtlib.Type.Debugger: [debugVar] :: Debugger s -> Builder -> IO ()
+ Language.Hasmtlib.Type.Debugger: assertionish :: Debugger s
+ Language.Hasmtlib.Type.Debugger: class StateDebugger s
+ Language.Hasmtlib.Type.Debugger: data Debugger s
+ Language.Hasmtlib.Type.Debugger: getValueish :: Debugger s
+ Language.Hasmtlib.Type.Debugger: incrementalStackish :: Debugger s
+ Language.Hasmtlib.Type.Debugger: instance Data.Default.Class.Default (Language.Hasmtlib.Type.Debugger.Debugger s)
+ Language.Hasmtlib.Type.Debugger: instance Language.Hasmtlib.Type.Debugger.StateDebugger Language.Hasmtlib.Type.OMT.OMT
+ Language.Hasmtlib.Type.Debugger: instance Language.Hasmtlib.Type.Debugger.StateDebugger Language.Hasmtlib.Type.SMT.SMT
+ Language.Hasmtlib.Type.Debugger: logicish :: Debugger s
+ Language.Hasmtlib.Type.Debugger: noisy :: Debugger s
+ Language.Hasmtlib.Type.Debugger: optionish :: Debugger s
+ Language.Hasmtlib.Type.Debugger: responseish :: Debugger s
+ Language.Hasmtlib.Type.Debugger: silently :: Debugger s
+ Language.Hasmtlib.Type.Debugger: statistically :: StateDebugger s => Debugger s
+ Language.Hasmtlib.Type.Debugger: varish :: Debugger s
+ Language.Hasmtlib.Type.Debugger: verbosely :: Debugger s
+ Language.Hasmtlib.Type.OMT: formula :: Lens' SoftFormula (Expr 'BoolSort)
+ Language.Hasmtlib.Type.OMT: mGroupId :: Lens' SoftFormula (Maybe String)
+ Language.Hasmtlib.Type.OMT: mWeight :: Lens' SoftFormula (Maybe Double)
+ Language.Hasmtlib.Type.Pipe: [_mPipeDebugger] :: Pipe -> Maybe (Debugger Pipe)
+ Language.Hasmtlib.Type.Solution: instance GHC.Show.Show (Language.Hasmtlib.Type.Value.Value t) => GHC.Show.Show (Language.Hasmtlib.Type.Solution.IntValueMap t)
+ Language.Hasmtlib.Type.Solution: instance GHC.Show.Show (Language.Hasmtlib.Type.Value.Value t) => GHC.Show.Show (Language.Hasmtlib.Type.Solution.SMTVarSol t)
+ Language.Hasmtlib.Type.Solver: SolverConfig :: Config -> Maybe Int -> Maybe (Debugger s) -> SolverConfig s
+ Language.Hasmtlib.Type.Solver: [_mDebugger] :: SolverConfig s -> Maybe (Debugger s)
+ Language.Hasmtlib.Type.Solver: [_mTimeout] :: SolverConfig s -> Maybe Int
+ Language.Hasmtlib.Type.Solver: [_processConfig] :: SolverConfig s -> Config
+ Language.Hasmtlib.Type.Solver: data SolverConfig s
+ Language.Hasmtlib.Type.Solver: debugging :: Debugger s -> SolverConfig s -> SolverConfig s
+ Language.Hasmtlib.Type.Solver: mDebugger :: forall s_a21ae s_a21bb. Lens (SolverConfig s_a21ae) (SolverConfig s_a21bb) (Maybe (Debugger s_a21ae)) (Maybe (Debugger s_a21bb))
+ Language.Hasmtlib.Type.Solver: mTimeout :: forall s_a21ae. Lens' (SolverConfig s_a21ae) (Maybe Int)
+ Language.Hasmtlib.Type.Solver: processConfig :: forall s_a21ae. Lens' (SolverConfig s_a21ae) Config
+ Language.Hasmtlib.Type.Solver: solver :: (RenderProblem s, MonadIO m) => SolverConfig s -> Solver s m
+ Language.Hasmtlib.Type.Solver: timingout :: Int -> SolverConfig s -> SolverConfig s
+ Language.Hasmtlib.Type.Solver: type Solver s m = s -> m (Result, Solution)
- Language.Hasmtlib.Solver.Bitwuzla: bitwuzla :: Config
+ Language.Hasmtlib.Solver.Bitwuzla: bitwuzla :: SolverConfig s
- Language.Hasmtlib.Solver.Bitwuzla: bitwuzlaKissat :: Config
+ Language.Hasmtlib.Solver.Bitwuzla: bitwuzlaKissat :: SolverConfig s
- Language.Hasmtlib.Solver.CVC5: cvc5 :: Config
+ Language.Hasmtlib.Solver.CVC5: cvc5 :: SolverConfig s
- Language.Hasmtlib.Solver.MathSAT: mathsat :: Config
+ Language.Hasmtlib.Solver.MathSAT: mathsat :: SolverConfig s
- Language.Hasmtlib.Solver.MathSAT: optimathsat :: Config
+ Language.Hasmtlib.Solver.MathSAT: optimathsat :: SolverConfig s
- Language.Hasmtlib.Solver.OpenSMT: opensmt :: Config
+ Language.Hasmtlib.Solver.OpenSMT: opensmt :: SolverConfig s
- Language.Hasmtlib.Solver.Yices: yices :: Config
+ Language.Hasmtlib.Solver.Yices: yices :: SolverConfig s
- Language.Hasmtlib.Solver.Z3: z3 :: Config
+ Language.Hasmtlib.Solver.Z3: z3 :: SolverConfig s
- Language.Hasmtlib.Type.ArrayMap: arrConst :: forall k_aeP4 v_aeP5. Lens' (ConstArray k_aeP4 v_aeP5) v_aeP5
+ Language.Hasmtlib.Type.ArrayMap: arrConst :: forall k_adEv v_adEw. Lens' (ConstArray k_adEv v_adEw) v_adEw
- Language.Hasmtlib.Type.ArrayMap: stored :: forall k_aeP4 v_aeP5 k_agnt. Lens (ConstArray k_aeP4 v_aeP5) (ConstArray k_agnt v_aeP5) (Map k_aeP4 v_aeP5) (Map k_agnt v_aeP5)
+ Language.Hasmtlib.Type.ArrayMap: stored :: forall k_adEv v_adEw k_afea. Lens (ConstArray k_adEv v_adEw) (ConstArray k_afea v_adEw) (Map k_adEv v_adEw) (Map k_afea v_adEw)
- Language.Hasmtlib.Type.Expr: varId :: forall t_awj3 t_axez. Iso (SMTVar t_awj3) (SMTVar t_axez) Int Int
+ Language.Hasmtlib.Type.Expr: varId :: forall t_auXq t_avSZ. Iso (SMTVar t_auXq) (SMTVar t_avSZ) Int Int
- Language.Hasmtlib.Type.Pipe: Pipe :: {-# UNPACK #-} !Int -> Maybe String -> !SharingMode -> !HashMap (StableName ()) (SomeKnownSMTSort Expr) -> !Seq (Seq (StableName ())) -> !Solver -> !Bool -> Pipe
+ Language.Hasmtlib.Type.Pipe: Pipe :: {-# UNPACK #-} !Int -> Maybe String -> !SharingMode -> !HashMap (StableName ()) (SomeKnownSMTSort Expr) -> !Seq (Seq (StableName ())) -> !Solver -> Maybe (Debugger Pipe) -> Pipe
- Language.Hasmtlib.Type.Solution: solVal :: forall t_a1dIb. Lens' (SMTVarSol t_a1dIb) (Value t_a1dIb)
+ Language.Hasmtlib.Type.Solution: solVal :: forall t_a18vp. Lens' (SMTVarSol t_a18vp) (Value t_a18vp)
- Language.Hasmtlib.Type.Solution: solVar :: forall t_a1dIb. Lens' (SMTVarSol t_a1dIb) (SMTVar t_a1dIb)
+ Language.Hasmtlib.Type.Solution: solVar :: forall t_a18vp. Lens' (SMTVarSol t_a18vp) (SMTVar t_a18vp)
- Language.Hasmtlib.Type.Solver: interactiveWith :: (WithSolver s, MonadIO m) => (Solver, Handle) -> StateT s m () -> m ()
+ Language.Hasmtlib.Type.Solver: interactiveWith :: (MonadIO m, MonadBaseControl IO m) => SolverConfig Pipe -> StateT Pipe m a -> m (Maybe a)

Files

CHANGELOG.md view
@@ -6,6 +6,29 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [PVP versioning](https://pvp.haskell.org/). +## v2.7.0 _(2024-09-12)_++### Added+- Added helpful instances for standard types for `Codec` to ease deriving.+- Added decorator `timingout` in `Language.Hasmtlib.Type.Solver` to set a time-out for solvers.+Unfortunately as of SMTLib standard v2.6 there is no SMT-Option for this. Although some solvers like `Z3` (unreliably) support it,+we instead do it by internally coordinating the kill of the solver process from Haskell using `System.Timeout.Lifted#timeout`. Works like a charme.+- Added `Language.Hasmtlib.Type.Debugger` for debugging problem construction and solver interaction.++### Changed+- *(breaking change)* Completely revised the way solver process-configurations are handled and debugged.+Solvers which previously had the type `Process.Config` from `smtlib-backends` now have the type `SolverConfig` from `Language.Hasmtlib.Type.Solver`.+This bundles information on the executable of the solver with additional information such as debugging and time-outs.+Actual solver creation still is done by funtion `solver`. Therefore this change is only breaking, if you created custom solvers or debugged solvers.+- Debugging solvers changed from `solveWith (debug z3 def) $ ...` to `solveWith (solver $ debugging z3 def) $ ...`.+Also note that there are plenty debugging configurations besides `def` existing in `Language.Hasmtlib.Type.Debugger` now.+- Interactive solving before was a two-stepper like `iZ3 <- interactiveSolver z3 ; interactiveWith iZ3 $ ...`.+Leveraging `SolverConfig` this has been changed to a more uniform way with `interactiveWith z3 $ do ...`.+Also note that `debugInteractiveWith z3 $ ...` now is replaced by `interactiveWith (debugging def z3) $ ...`.++### Removed+- Removed `Language.Hasmtlib.Solver.Common`. Contents are now in `Language.Hasmtlib.Type.Solver`.+ ## v2.6.3 _(2024-09-07)_  ### Added
hasmtlib.cabal view
@@ -1,7 +1,7 @@ cabal-version:         3.0  name:                  hasmtlib-version:               2.6.3+version:               2.7.0 synopsis:              A monad for interfacing with external SMT solvers description:           Hasmtlib is a library for generating SMTLib2-problems using a monad.   It takes care of encoding your problem, marshaling the data to an external solver and parsing and interpreting the result into Haskell types.@@ -37,7 +37,6 @@                      , Language.Hasmtlib.Internal.Sharing                      , Language.Hasmtlib.Internal.Uniplate1                      , Language.Hasmtlib.Internal.Constraint-                     , Language.Hasmtlib.Solver.Common                      , Language.Hasmtlib.Solver.Bitwuzla                      , Language.Hasmtlib.Solver.CVC5                      , Language.Hasmtlib.Solver.MathSAT@@ -57,10 +56,13 @@                      , Language.Hasmtlib.Type.ArrayMap                      , Language.Hasmtlib.Type.Bitvec                      , Language.Hasmtlib.Type.Relation+                     , Language.Hasmtlib.Type.Debugger    build-depends:       array                        >= 0.5    && < 1                      , attoparsec                   >= 0.14.4 && < 1                      , base                         >= 4.17.2 && < 5+                     , lifted-base                  >= 0.2 && < 0.5+                     , monad-control                >= 1.0 && < 1.2                      , bytestring                   >= 0.11.5 && < 1                      , containers                   >= 0.6.7  && < 1                      , unordered-containers         >= 0.2.20 && < 0.3
src/Language/Hasmtlib.hs view
@@ -32,7 +32,7 @@   -- ** Type   , module Language.Hasmtlib.Type.Solution   , module Language.Hasmtlib.Type.Solver-  , module Language.Hasmtlib.Solver.Common+  , module Language.Hasmtlib.Type.Debugger    -- ** Concrete solvers   , module Language.Hasmtlib.Solver.Z3@@ -61,11 +61,11 @@ import Language.Hasmtlib.Type.ArrayMap import Language.Hasmtlib.Type.Bitvec import Language.Hasmtlib.Type.Relation+import Language.Hasmtlib.Type.Debugger import Language.Hasmtlib.Boolean import Language.Hasmtlib.Codec import Language.Hasmtlib.Counting import Language.Hasmtlib.Variable-import Language.Hasmtlib.Solver.Common import Language.Hasmtlib.Solver.Bitwuzla import Language.Hasmtlib.Solver.CVC5 import Language.Hasmtlib.Solver.Z3@@ -73,3 +73,4 @@ import Language.Hasmtlib.Solver.OpenSMT import Language.Hasmtlib.Solver.MathSAT import Language.Hasmtlib.Internal.Sharing+import Language.Hasmtlib.Internal.Render ()
src/Language/Hasmtlib/Codec.hs view
@@ -48,6 +48,8 @@ import Data.Dependent.Map as DMap import Data.Tree (Tree) import Data.Array (Array, Ix)+import Data.Word+import Data.Int import qualified Data.Text as Text import Data.Monoid (Sum, Product, First, Last, Dual) import qualified Data.Vector.Sized as V@@ -223,6 +225,91 @@   type Decoded (Array i e) = Array i (Decoded e)   decode = traverse . decode   encode = fmap encode++instance Codec Int where+  type Decoded Int = Int+  decode _ = Just+  encode = id++instance Codec Integer where+  type Decoded Integer = Integer+  decode _ = Just+  encode = id++instance Codec Natural where+  type Decoded Natural = Natural+  decode _ = Just+  encode = id++instance Codec Word where+  type Decoded Word = Word+  decode _ = Just+  encode = id++instance Codec Word8 where+  type Decoded Word8 = Word8+  decode _ = Just+  encode = id++instance Codec Word16 where+  type Decoded Word16 = Word16+  decode _ = Just+  encode = id++instance Codec Word32 where+  type Decoded Word32 = Word32+  decode _ = Just+  encode = id++instance Codec Word64 where+  type Decoded Word64 = Word64+  decode _ = Just+  encode = id++instance Codec Int8 where+  type Decoded Int8 = Int8+  decode _ = Just+  encode = id++instance Codec Int16 where+  type Decoded Int16 = Int16+  decode _ = Just+  encode = id++instance Codec Int32 where+  type Decoded Int32 = Int32+  decode _ = Just+  encode = id++instance Codec Int64 where+  type Decoded Int64 = Int64+  decode _ = Just+  encode = id++instance Codec Char where+  type Decoded Char = Char+  decode _ = Just+  encode = id++instance Codec Float where+  type Decoded Float = Float+  decode _ = Just+  encode = id++instance Codec Double where+  type Decoded Double = Double+  decode _ = Just+  encode = id++instance Codec Ordering where+  type Decoded Ordering = Ordering+  decode _ = Just+  encode = id++instance Codec Bool where+  type Decoded Bool = Bool+  decode _ = Just+  encode = id  class GCodec f where   type GDecoded f :: Type -> Type
src/Language/Hasmtlib/Internal/Render.hs view
@@ -1,35 +1,68 @@+{-# LANGUAGE LambdaCase #-}+ module Language.Hasmtlib.Internal.Render where -import Data.ByteString.Builder-import Data.Foldable (foldl')+import Language.Hasmtlib.Type.OMT+import Language.Hasmtlib.Type.SMT+import Language.Hasmtlib.Type.Expr+import Language.Hasmtlib.Type.Value+import Language.Hasmtlib.Type.Option+import Language.Hasmtlib.Type.SMTSort+import Language.Hasmtlib.Type.Bitvec+import Language.Hasmtlib.Type.ArrayMap+import Data.Coerce import Data.Sequence+import Data.Foldable (foldl')+import Data.Map (size, minViewWithKey)+import Data.ByteString.Builder+import Data.ByteString.Lazy.UTF8 (toString) import qualified Data.Text as Text import qualified Data.Text.Encoding as Text.Enc+import qualified Data.Vector.Sized as V+import Control.Lens hiding (op) import GHC.TypeNats +render1 :: Render a => Builder -> a -> Builder+render1 op x = "(" <> op <> " " <> render x <> ")"+{-# INLINE render1 #-}++render2 :: (Render a, Render b) => Builder -> a -> b -> Builder+render2 op x y = "(" <> op <> " " <> render x <> " " <> render y <> ")"+{-# INLINE render2 #-}++render3 :: (Render a, Render b, Render c) => Builder -> a -> b -> c -> Builder+render3 op x y z = "(" <> op <> " " <> render x <> " " <> render y <> " " <> render z <> ")"+{-# INLINE render3 #-}++renderN :: Render a => Builder -> [a] -> Builder+renderN op xs = "(" <> op <> renderedXs <> ")"+  where+    renderedXs = foldl' (\s x -> s <> " " <> render x) mempty xs+{-# INLINE renderN #-}+ -- | Render values to their SMTLib2-Lisp form, represented as 'Builder'. class Render a where   render :: a -> Builder  instance Render Bool where   render b = if b then "true" else "false"-  {-# INLINEABLE render #-}+  {-# INLINE render #-}  instance Render Nat where   render = integerDec . fromIntegral-  {-# INLINEABLE render #-}+  {-# INLINE render #-}  instance Render Integer where   render x     | x < 0     = "(- " <> integerDec (abs x) <> ")"     | otherwise = integerDec x-  {-# INLINEABLE render #-}+  {-# INLINE render #-}  instance Render Double where   render x     | x < 0     = "(- " <> formatDouble standardDefaultPrecision (abs x) <> ")"     | otherwise = formatDouble standardDefaultPrecision x-  {-# INLINEABLE render #-}+  {-# INLINE render #-}  instance Render Char where   render = char8@@ -47,24 +80,229 @@   render = Text.Enc.encodeUtf8Builder   {-# INLINE render #-} -renderUnary :: Render a => Builder -> a -> Builder-renderUnary op x = "(" <> op <> " " <> render x <> ")"-{-# INLINEABLE renderUnary #-}+instance Render (Bitvec enc n) where+  render = stringUtf8 . show+  {-# INLINE render #-} -renderBinary :: (Render a, Render b) => Builder -> a -> b -> Builder-renderBinary op x y = "(" <> op <> " " <> render x <> " " <> render y <> ")"-{-# INLINEABLE renderBinary #-}+instance Render (SMTVar t) where+  render v = "var_" <> intDec (coerce @(SMTVar t) @Int v)+  {-# INLINE render #-} -renderTernary :: (Render a, Render b, Render c) => Builder -> a -> b -> c -> Builder-renderTernary op x y z = "(" <> op <> " " <> render x <> " " <> render y <> " " <> render z <> ")"-{-# INLINEABLE renderTernary #-}+instance Show (Value t) where+  show = toString . toLazyByteString . render -renderNary :: Render a => Builder -> [a] -> Builder-renderNary op xs = "(" <> op <> renderedXs <> ")"+instance Render (Value t) where+  render (IntValue x)   = render x+  render (RealValue x)  = render x+  render (BoolValue x)  = render x+  render (BvValue   v)  = "#b" <> render v+  render (ArrayValue arr) = case minViewWithKey (arr^.stored) of+    Nothing -> constRender $ arr^.arrConst+    Just ((k,v), stored')+      | size (arr^.stored) > 1 -> render $ ArrStore (Constant (wrapValue (arr & stored .~ stored'))) (Constant (wrapValue k)) (Constant (wrapValue v))+      | otherwise  -> constRender v+    where+      constRender v = "((as const " <> render (goSing arr) <> ") " <> render (wrapValue v) <> ")"+      goSing :: forall k v. (KnownSMTSort k, KnownSMTSort v, Ord (HaskellType k), Ord (HaskellType v)) => ConstArray (HaskellType k) (HaskellType v) -> SSMTSort (ArraySort k v)+      goSing _ = sortSing @(ArraySort k v)+  render (StringValue x) = "\"" <> render x <> "\""++instance KnownSMTSort t => Show (Expr t) where+  show = toString . toLazyByteString . render++instance KnownSMTSort t => Render (Expr t) where+  render (Var v)      = render v+  render (Constant c) = render c+  render (Plus x y)   = render2 (case sortSing' x of SBvSort _ _ -> "bvadd" ; _ -> "+") x y+  render (Minus x y)  = render2 (case sortSing' x of SBvSort _ _ -> "bvsub" ; _ -> "-") x y+  render (Neg x)      = render1  (case sortSing' x of SBvSort _ _ -> "bvneg" ; _ -> "-") x+  render (Mul x y)    = render2 (case sortSing' x of SBvSort _ _ -> "bvmul" ; _ -> "*") x y+  render (Abs x)      = render1  "abs" x+  render (Mod x y)    = render2 opStr x y+    where+      opStr = case sortSing' x of+        SBvSort enc _ -> case bvEncSing' enc of+          SUnsigned -> "bvurem"+          SSigned -> "bvsmod"+        _ -> "mod"+  render (Rem x y)    = render2 opStr x y+    where+      opStr = case sortSing' x of+        SBvSort enc _ -> case bvEncSing' enc of+          SUnsigned -> "bvurem"+          SSigned -> "bvsrem"+        _ -> "rem"+  render (IDiv x y)   = render2 opStr x y+    where+      opStr = case sortSing' x of+        SBvSort enc _ -> case bvEncSing' enc of+          SUnsigned -> "bvudiv"+          SSigned -> "bvsdiv"+        _ -> "div"+  render (Div x y)    = render2 "/" x y+  render (LTH x y)    = render2 opStr x y+    where+      opStr = case sortSing' x of+        SBvSort enc _ -> case bvEncSing' enc of+          SUnsigned -> "bvult"+          SSigned -> "bvslt"+        SStringSort -> "str.<"+        _ -> "<"+  render (LTHE x y)   = render2 opStr x y+    where+      opStr = case sortSing' x of+        SBvSort enc _ -> case bvEncSing' enc of+          SUnsigned -> "bvule"+          SSigned -> "bvsle"+        SStringSort -> "str.<="+        _ -> "<="+  render (EQU xs)     = renderN "=" $ V.toList xs+  render (Distinct xs)= renderN "distinct" $ V.toList xs+  render (GTHE x y)   = case sortSing' x of+    SBvSort enc _ -> case bvEncSing' enc of+      SUnsigned -> render2 "bvuge" x y+      SSigned   -> render2 "bvsge" x y+    SStringSort -> render2 "str.<=" y x+    _           -> render2 ">=" x y+  render (GTH x y)    = case sortSing' x of+    SBvSort enc _ -> case bvEncSing' enc of+      SUnsigned -> render2 "bvugt" x y+      SSigned   -> render2 "bvsgt" x y+    SStringSort -> render2 "str.<" y x+    _           -> render2 ">" x y+  render (Not x)      = render1  (case sortSing' x of SBvSort _ _ -> "bvnot" ; _ -> "not") x+  render (And x y)    = render2 (case sortSing' x of SBvSort _ _ -> "bvand" ; _ -> "and") x y+  render (Or x y)     = render2 (case sortSing' x of SBvSort _ _ -> "bvor" ; _ -> "or") x y+  render (Impl x y)   = render2 "=>" x y+  render (Xor x y)    = render2 (case sortSing' x of SBvSort _ _ -> "bvxor" ; _ -> "xor") x y+  render Pi           = "real.pi"+  render (Sqrt x)     = render1 "sqrt" x+  render (Exp x)      = render1 "exp" x+  render (Sin x)      = render1 "sin" x+  render (Cos x)      = render1 "cos" x+  render (Tan x)      = render1 "tan" x+  render (Asin x)     = render1 "arcsin" x+  render (Acos x)     = render1 "arccos" x+  render (Atan x)     = render1 "arctan" x+  render (ToReal x)   = render1 "to_real" x+  render (ToInt x)    = render1 "to_int" x+  render (IsInt x)    = render1 "is_int" x+  render (Ite p t f)  = render3 "ite" p t f+  render (BvNand x y)       = render2 "bvnand" (render x) (render y)+  render (BvNor x y)        = render2 "bvnor"  (render x) (render y)+  render (BvShL x y)        = render2 "bvshl"  (render x) (render y)+  render (BvLShR x y)       = render2 "bvlshr" (render x) (render y)+  render (BvAShR x y)       = render2 "bvashr" (render x) (render y)+  render (BvConcat x y)     = render2 "concat" (render x) (render y)+  render (BvRotL i x)       = render1 (render2 "_" ("rotate_left"  :: Builder) (render $ toInteger i)) (render x)+  render (BvRotR i x)       = render1 (render2 "_" ("rotate_right" :: Builder) (render $ toInteger i)) (render x)+  render (ArrSelect a i)    = render2  "select" (render a) (render i)+  render (ArrStore a i v)   = render3 "store"  (render a) (render i) (render v)+  render (StrConcat x y)        = render2 "str.++"  (render x) (render y)+  render (StrLength x)          = render1  "str.len" (render x)+  render (StrAt x i)            = render2 "str.at"  (render x) (render i)+  render (StrSubstring x i j)   = render3 "str.substr"  (render x) (render i) (render j)+  render (StrPrefixOf x y)      = render2 "str.prefixof" (render x) (render y)+  render (StrSuffixOf x y)      = render2 "str.suffixof" (render x) (render y)+  render (StrContains x y)      = render2 "str.contains" (render x) (render y)+  render (StrIndexOf x y i)     = render3 "str.indexof"     (render x) (render y) (render i)+  render (StrReplace x y y')    = render3 "str.replace"     (render x) (render y) (render y')+  render (StrReplaceAll x y y') = render3 "str.replace_all" (render x) (render y) (render y')+  render (ForAll mQvar f) = renderQuantifier "forall" mQvar f+  render (Exists mQvar f) = renderQuantifier "exists" mQvar f++renderQuantifier :: forall t. KnownSMTSort t => Builder -> Maybe (SMTVar t) -> (Expr t -> Expr BoolSort) -> Builder+renderQuantifier qname (Just qvar) f =+  render2+    qname+    ("(" <> render1 (render qvar) (sortSing @t) <> ")")+    expr   where-    renderedXs = foldl' (\s x -> s <> " " <> render x) mempty xs-{-# INLINEABLE renderNary #-}+    expr = render $ f $ Var qvar+renderQuantifier _ Nothing _ = mempty --- | Render values to their sequential SMTLib2-Lisp form, represented as a 'Seq' 'Builder'.-class RenderSeq a where-  renderSeq :: a -> Seq Builder+instance Render (SSMTSort t) where+  render SBoolSort   = "Bool"+  render SIntSort    = "Int"+  render SRealSort   = "Real"+  render (SBvSort _ p) = render2 "_" ("BitVec" :: Builder) (natVal p)+  render (SArraySort k v) = render2 "Array" (sortSing' k) (sortSing' v)+  render SStringSort   = "String"+  {-# INLINE render #-}++instance Render SMTOption where+  render (PrintSuccess  b) = render2 "set-option" (":print-success"  :: Builder) b+  render (ProduceModels b) = render2 "set-option" (":produce-models" :: Builder) b+  render (Incremental   b) = render2 "set-option" (":incremental"    :: Builder) b+  render (Custom k v)      = render2 "set-option" (":" <> render k) (render v)++instance Render SoftFormula where+  render sf = "(assert-soft " <> render (sf^.formula) <> " :weight " <> maybe "1" render (sf^.mWeight) <> renderGroupId (sf^.mGroupId) <> ")"+    where+      renderGroupId Nothing = mempty+      renderGroupId (Just groupId) = " :id " <> render groupId++instance KnownSMTSort t => Render (Minimize t) where+  render (Minimize expr) = "(minimize " <> render expr <> ")"++instance KnownSMTSort t => Render (Maximize t) where+  render (Maximize expr) = "(maximize " <> render expr <> ")"++renderSetLogic :: Builder -> Builder+renderSetLogic = render1 "set-logic"+{-# INLINE renderSetLogic #-}++renderDeclareVar :: forall t. KnownSMTSort t => SMTVar t -> Builder+renderDeclareVar v = render3 "declare-fun" v ("()" :: Builder) (sortSing @t)+{-# INLINE renderDeclareVar #-}++renderAssert :: Expr BoolSort -> Builder+renderAssert = render1 "assert"+{-# INLINE renderAssert #-}++renderGetValue :: SMTVar t -> Builder+renderGetValue x = render1 "get-value" $ "(" <> render x <> ")"+{-# INLINE renderGetValue #-}++renderPush :: Integer -> Builder+renderPush i = "(push "<> render i <>")"+{-# INLINE renderPush #-}++renderPop :: Integer -> Builder+renderPop i = "(pop "<> render i <>")"+{-# INLINE renderPop #-}++renderCheckSat :: Builder+renderCheckSat = "(check-sat)"+{-# INLINE renderCheckSat #-}++renderGetModel :: Builder+renderGetModel = "(get-model)"+{-# INLINE renderGetModel #-}++class RenderProblem s where+  renderOptions        :: s -> Seq Builder+  renderLogic          :: s -> Builder+  renderDeclareVars    :: s -> Seq Builder+  renderAssertions     :: s -> Seq Builder+  renderSoftAssertions :: s -> Seq Builder+  renderMinimizations  :: s -> Seq Builder+  renderMaximizations  :: s -> Seq Builder++instance RenderProblem SMT where+  renderOptions = fromList . fmap render . view options+  renderLogic = maybe mempty (renderSetLogic . stringUtf8) . view mlogic+  renderDeclareVars = fmap (\(SomeSMTSort v) -> renderDeclareVar v) . view vars+  renderAssertions = fmap renderAssert . view formulas+  renderSoftAssertions _ = mempty+  renderMinimizations _ = mempty+  renderMaximizations _ = mempty++instance RenderProblem OMT where+  renderOptions = renderOptions . view smt+  renderLogic = renderLogic . view smt+  renderDeclareVars = renderDeclareVars . view smt+  renderAssertions = renderAssertions . view smt+  renderSoftAssertions = fmap render . view softFormulas+  renderMinimizations = fmap (\case SomeSMTSort minExpr -> render minExpr) . view targetMinimize+  renderMaximizations = fmap (\case SomeSMTSort maxExpr -> render maxExpr) . view targetMaximize
src/Language/Hasmtlib/Solver/Bitwuzla.hs view
@@ -1,21 +1,28 @@ module Language.Hasmtlib.Solver.Bitwuzla where  import SMTLIB.Backends.Process+import Language.Hasmtlib.Type.Solver --- | A 'Config' for Bitwuzla.+-- | A 'SolverConfig' for Bitwuzla. --   Requires binary @bitwuzla@ to be in path. -- --   As of v0.5 Bitwuzla uses Cadical as SAT-Solver by default. --   Make sure it's default SAT-Solver binary - probably @cadical@ - is in path too.-bitwuzla :: Config-bitwuzla = defaultConfig { exe = "bitwuzla", args = [] }+bitwuzla :: SolverConfig s+bitwuzla = SolverConfig+  (defaultConfig { exe = "bitwuzla", args = [] })+  Nothing+  Nothing  --- | A 'Config' for Bitwuzla with Kissat as underlying sat-solver.+-- | A 'SolverConfig' for Bitwuzla with Kissat as underlying sat-solver. -- --   Requires binary @bitwuzla@ and to be in path. --   Will use the @kissat@ shipped with @bitwuzla@. -- --   It is recommended to build @bitwuzla@ from source for this to work as expected.-bitwuzlaKissat :: Config-bitwuzlaKissat = defaultConfig { exe = "bitwuzla", args = ["--sat-solver=kissat"] }+bitwuzlaKissat :: SolverConfig s+bitwuzlaKissat = SolverConfig+  (defaultConfig { exe = "bitwuzla", args = ["--sat-solver=kissat"] })+  Nothing+  Nothing
src/Language/Hasmtlib/Solver/CVC5.hs view
@@ -1,8 +1,11 @@ module Language.Hasmtlib.Solver.CVC5 where  import SMTLIB.Backends.Process+import Language.Hasmtlib.Type.Solver --- | A 'Config' for CVC5.+-- | A 'SolverConfig' for CVC5. --   Requires binary @cvc5@ to be in path.-cvc5 :: Config-cvc5 = defaultConfig { exe = "cvc5", args = [] }+cvc5 :: SolverConfig s+cvc5 = SolverConfig+  (defaultConfig { exe = "cvc5", args = [] })+  Nothing Nothing
− src/Language/Hasmtlib/Solver/Common.hs
@@ -1,121 +0,0 @@-{- |-This module handles common IO interaction with external SMT-Solvers via external processes.--It is built on top of Tweag's package @smtlib-backends@.--Although there already are several concrete solvers like @Z3@ in @Language.Hasmtlib.Solver.Z3@,-you may use this module to create your own solver bindings.--}-module Language.Hasmtlib.Solver.Common-(-  -- * Construction-  processSolver-, solver-, interactiveSolver--  -- * Debugging-, Debugger(..)-, debug-, def-)-where--import Language.Hasmtlib.Type.SMT-import Language.Hasmtlib.Type.OMT-import Language.Hasmtlib.Type.Solution-import Language.Hasmtlib.Internal.Render-import Language.Hasmtlib.Internal.Parser-import Data.Default-import Data.Sequence as Seq hiding ((|>), filter)-import Data.ByteString.Lazy hiding (singleton)-import Data.ByteString.Lazy.UTF8 (toString)-import Data.ByteString.Builder-import Data.Attoparsec.ByteString-import Control.Lens-import Control.Monad-import Control.Monad.IO.Class-import qualified SMTLIB.Backends.Process as Process-import qualified SMTLIB.Backends as Backend---- | Creates a 'Solver' from a 'Process.Config'.-solver :: (RenderSeq s, MonadIO m) => Process.Config -> Solver s m-solver cfg = processSolver cfg Nothing---- | Creates a debugging 'Solver' from a 'Process.Config'.-debug :: (RenderSeq s, MonadIO m) => Process.Config -> Debugger s -> Solver s m-debug cfg = processSolver cfg . Just---- | Creates an interactive session with a solver by creating and returning an alive process-handle 'Process.Handle'.---   Queues commands by default, see 'Backend.Queuing'.-interactiveSolver :: MonadIO m => Process.Config -> m (Backend.Solver, Process.Handle)-interactiveSolver cfg = liftIO $ do-  handle  <- Process.new cfg-  liftM2 (,) (Backend.initSolver Backend.Queuing $ Process.toBackend handle) (return handle)---- | A type holding actions for debugging states.-data Debugger s = Debugger-  { debugState          :: s -> IO ()               -- ^ Debug the entire state-  , debugProblem        :: Seq Builder -> IO ()     -- ^ Debug the linewise-rendered problem-  , debugResultResponse :: ByteString -> IO ()      -- ^ Debug the solvers raw response for @(check-sat)@-  , debugModelResponse  :: ByteString -> IO ()      -- ^ Debug the solvers raw response for @(get-model)@-  }--instance Default (Debugger SMT) where-  def = Debugger-    { debugState            = \s -> liftIO $ do-        putStrLn $ "Vars: "       ++ show (Seq.length (s^.vars))-        putStrLn $ "Assertions: " ++ show (Seq.length (s^.formulas))-    , debugProblem        = liftIO . mapM_ (putStrLn . toString . toLazyByteString)-    , debugResultResponse = liftIO . putStrLn . (\s -> "\n" ++ s ++ "\n") . toString-    , debugModelResponse  = liftIO . mapM_ (putStrLn . toString) . split 13-    }--instance Default (Debugger OMT) where-  def = Debugger-    { debugState          = \omt -> liftIO $ do-        putStrLn $ "Vars: "                 ++ show (Seq.length (omt^.smt.vars))-        putStrLn $ "Hard assertions: "      ++ show (Seq.length (omt^.smt.formulas))-        putStrLn $ "Soft assertions: "      ++ show (Seq.length (omt^.softFormulas))-        putStrLn $ "Optimization targets: " ++ show (Seq.length (omt^.targetMinimize) + Seq.length (omt^.targetMaximize))-    , debugProblem        = liftIO . mapM_ (putStrLn . toString . toLazyByteString)-    , debugResultResponse = liftIO . putStrLn . (\s -> "\n" ++ s ++ "\n") . toString-    , debugModelResponse  = liftIO . mapM_ (putStrLn . toString) . split 13-    }---- | A 'Solver' which holds an external process with a SMT-Solver.---   This will:------ 1. Encode the 'SMT'-problem,------ 2. start a new external process for the SMT-Solver,------ 3. send the problem to the SMT-Solver,------ 4. wait for an answer and parse it,------ 5. close the process and clean up all resources and------ 6. return the decoded solution.-processSolver :: (RenderSeq s, MonadIO m) => Process.Config -> Maybe (Debugger s) -> Solver s m-processSolver cfg debugger s = do-  liftIO $ Process.with cfg $ \handle -> do-    maybe mempty (`debugState` s) debugger-    pSolver <- Backend.initSolver Backend.Queuing $ Process.toBackend handle--    let problem = renderSeq s-    maybe mempty (`debugProblem` problem) debugger--    forM_ problem (Backend.command_ pSolver)-    resultResponse <- Backend.command pSolver "(check-sat)"-    maybe mempty (`debugResultResponse` resultResponse) debugger--    modelResponse  <- Backend.command pSolver "(get-model)"-    maybe mempty (`debugModelResponse` modelResponse) debugger--    case parseOnly resultParser (toStrict resultResponse) of-      Left e    -> fail e-      Right res -> case res of-        Unsat -> return (res, mempty)-        _     -> case parseOnly anyModelParser (toStrict modelResponse) of-          Left e    -> fail e-          Right sol -> return (res, sol)
src/Language/Hasmtlib/Solver/MathSAT.hs view
@@ -1,13 +1,20 @@ module Language.Hasmtlib.Solver.MathSAT where  import SMTLIB.Backends.Process+import Language.Hasmtlib.Type.Solver --- | A 'Config' for MathSAT.+-- | A 'SolverConfig' for MathSAT. --   Requires binary @mathsat@ to be in path.-mathsat :: Config-mathsat = defaultConfig { exe = "mathsat", args = [] }+mathsat :: SolverConfig s+mathsat = SolverConfig+  (defaultConfig { exe = "mathsat", args = [] })+  Nothing+  Nothing --- | A 'Config' for OptiMathSAT.+-- | A 'SolverConfig' for OptiMathSAT. --   Requires binary @optimathsat@ to be in path.-optimathsat :: Config-optimathsat = defaultConfig { exe = "optimathsat", args = ["-optimization=true"] }+optimathsat :: SolverConfig s+optimathsat = SolverConfig+  (defaultConfig { exe = "optimathsat", args = ["-optimization=true"] })+  Nothing+  Nothing
src/Language/Hasmtlib/Solver/OpenSMT.hs view
@@ -1,8 +1,11 @@ module Language.Hasmtlib.Solver.OpenSMT where  import SMTLIB.Backends.Process+import Language.Hasmtlib.Type.Solver --- | A 'Config' for OpenSMT.+-- | A 'SolverConfig' for OpenSMT. --   Requires binary @opensmt@ to be in path.-opensmt :: Config-opensmt = defaultConfig { exe = "opensmt", args = [] }+opensmt :: SolverConfig s+opensmt = SolverConfig+  (defaultConfig { exe = "opensmt", args = [] })+  Nothing Nothing
src/Language/Hasmtlib/Solver/Yices.hs view
@@ -1,8 +1,11 @@ module Language.Hasmtlib.Solver.Yices where  import SMTLIB.Backends.Process+import Language.Hasmtlib.Type.Solver --- | A 'Config' for Yices.+-- | A 'SolverConfig' for Yices. --   Requires binary @yices-smt2@ to be in path.-yices :: Config-yices = defaultConfig { exe = "yices-smt2", args = ["--smt2-model-format", "--incremental"] }+yices :: SolverConfig s+yices = SolverConfig+  (defaultConfig { exe = "yices-smt2", args = ["--smt2-model-format", "--incremental"] })+  Nothing Nothing
src/Language/Hasmtlib/Solver/Z3.hs view
@@ -1,8 +1,11 @@ module Language.Hasmtlib.Solver.Z3 where  import SMTLIB.Backends.Process+import Language.Hasmtlib.Type.Solver --- | A 'Config' for Z3.+-- | A 'SolverConfig' for Z3. --   Requires binary @z3@ to be in path.-z3 :: Config-z3 = defaultConfig+z3 :: SolverConfig s+z3 = SolverConfig+  defaultConfig+  Nothing Nothing
src/Language/Hasmtlib/Type/Bitvec.hs view
@@ -45,9 +45,7 @@  import Prelude hiding ((&&), (||), not) import Language.Hasmtlib.Boolean-import Language.Hasmtlib.Internal.Render import Data.GADT.Compare-import Data.ByteString.Builder import Data.Bit import Data.Bits import Data.Coerce@@ -117,10 +115,6 @@ instance Show (Bitvec enc n) where   show = V.toList . V.map (\b -> if coerce b then '1' else '0') . coerce @_ @(V.Vector n Bit)   {-# INLINEABLE show #-}--instance Render (Bitvec enc n) where-  render = stringUtf8 . show-  {-# INLINE render #-}  instance (KnownBvEnc enc, KnownNat n) => Bits (Bitvec enc n) where   (.&.) = (&&)
+ src/Language/Hasmtlib/Type/Debugger.hs view
@@ -0,0 +1,172 @@+{- |+This module provides debugging capabilites for the problem definition and communication with the external solver.+-}+module Language.Hasmtlib.Type.Debugger+  (+    -- * Type+    Debugger(..), StateDebugger(..)++    -- * Construction+    -- ** Volume+  , silently+  , noisy+  , verbosely++    -- ** Information+  , optionish+  , logicish+  , varish+  , assertionish+  , incrementalStackish, getValueish+  , responseish++  )+where++import Language.Hasmtlib.Type.SMT+import Language.Hasmtlib.Type.OMT+import Data.Sequence as Seq hiding ((|>), filter)+import Data.ByteString.Lazy hiding (singleton)+import Data.ByteString.Lazy.UTF8 (toString)+import Data.ByteString.Builder+import qualified Data.ByteString.Lazy.Char8 as ByteString.Char8+import Data.Default+import Control.Lens hiding (op)++-- | A type holding actions for debugging states holding SMT-Problems.+data Debugger s = Debugger+  { debugState          :: s -> IO ()               -- ^ Debug the entire state+  , debugOption         :: Builder -> IO ()+  , debugLogic          :: Builder -> IO ()+  , debugVar            :: Builder -> IO ()+  , debugAssert         :: Builder -> IO ()+  , debugPush           :: Builder -> IO ()+  , debugPop            :: Builder -> IO ()+  , debugCheckSat       :: Builder -> IO ()+  , debugGetModel       :: Builder -> IO ()+  , debugGetValue       :: Builder -> IO ()+  , debugMinimize       :: Builder -> IO ()+  , debugMaximize       :: Builder -> IO ()+  , debugAssertSoft     :: Builder -> IO ()+  , debugResultResponse :: ByteString -> IO ()      -- ^ Debug the solvers raw response for @(check-sat)@+  , debugModelResponse  :: ByteString -> IO ()      -- ^ Debug the solvers raw response for @(get-model)@+  }++instance Default (Debugger s) where+  def = verbosely++printer :: Builder -> IO ()+printer = ByteString.Char8.putStrLn . toLazyByteString++-- | The silent 'Debugger'. Does not debug at all.+silently :: Debugger s+silently = Debugger+  (const mempty)+  (const mempty)+  (const mempty)+  (const mempty)+  (const mempty)+  (const mempty)+  (const mempty)+  (const mempty)+  (const mempty)+  (const mempty)+  (const mempty)+  (const mempty)+  (const mempty)+  (const mempty)+  (const mempty)++-- | The noisy 'Debugger'.+--+--   Debugs the entire problem definition.+noisy :: Debugger s+noisy = Debugger+  (const mempty)+  printer+  printer+  printer+  printer+  printer+  printer+  printer+  printer+  printer+  printer+  printer+  printer+  (const mempty)+  (const mempty)++-- | The verbose 'Debugger'.+--+--   Debugs all communication between Haskell and the external solver.+verbosely :: Debugger s+verbosely = Debugger+  (const mempty)+  printer+  printer+  printer+  printer+  printer+  printer+  printer+  printer+  printer+  printer+  printer+  printer+  (ByteString.Char8.putStrLn . (\s -> "\n" <> s <> "\n"))+  (mapM_ (putStrLn . toString) . split 13)++-- | A 'Debugger' for debugging all rendered options that have been set.+optionish :: Debugger s+optionish = silently { debugOption = printer }++-- | A 'Debugger' for debugging the logic that has been set.+logicish :: Debugger s+logicish = silently { debugLogic = printer }++-- | A 'Debugger' for debugging all variable declarations.+varish :: Debugger s+varish = silently { debugVar = printer }++-- | A 'Debugger' for debugging all assertions.+assertionish :: Debugger s+assertionish = silently { debugAssert = printer, debugAssertSoft = printer }++-- | A 'Debugger' for debugging every push/pop-interaction with the solvers incremental stack.+incrementalStackish :: Debugger s+incrementalStackish = silently { debugPush = printer, debugPop = printer }++-- | A 'Debugger' for debugging every @(get-value)@ call to the solver.+getValueish :: Debugger s+getValueish = silently { debugGetValue = printer }++-- | A 'Debugger' for debugging the entire and raw responses of a solver for the commands @(check-sat)@ and @(get-model)@.+responseish :: Debugger s+responseish = silently+  { debugResultResponse = ByteString.Char8.putStrLn . (\s -> "\n" <> s <> "\n")+  , debugModelResponse = mapM_ (putStrLn . toString) . split 13+  }++-- | A class that allows debugging states.+class StateDebugger s where+  -- | Debugs information about the problem like the amount of variables and assertions.+  statistically :: Debugger s++instance StateDebugger SMT where+  statistically = silently+    { debugState = \s -> do+      putStrLn $ "Variables:  " ++ show (Seq.length (s^.vars))+      putStrLn $ "Assertions: " ++ show (Seq.length (s^.formulas))+    }++instance StateDebugger OMT where+  statistically = silently+    { debugState = \omt -> do+      putStrLn $ "Variables:       " ++ show (Seq.length (omt^.smt.vars))+      putStrLn $ "Hard assertions: " ++ show (Seq.length (omt^.smt.formulas))+      putStrLn $ "Soft assertions: " ++ show (Seq.length (omt^.softFormulas))+      putStrLn $ "Optimizations:   " ++ show (Seq.length (omt^.targetMinimize) + Seq.length (omt^.targetMaximize))+    }
src/Language/Hasmtlib/Type/Expr.hs view
@@ -77,15 +77,12 @@  import Prelude hiding (not, and, or, any, all, (&&), (||)) import Language.Hasmtlib.Internal.Uniplate1-import Language.Hasmtlib.Internal.Render-import Language.Hasmtlib.Type.Bitvec (BvEnc(..), KnownBvEnc(..), SBvEnc(..), bvEncSing')-import Language.Hasmtlib.Type.ArrayMap+import Language.Hasmtlib.Type.Bitvec (BvEnc(..), KnownBvEnc(..), SBvEnc(..)) import Language.Hasmtlib.Type.SMTSort import Language.Hasmtlib.Type.Value import Language.Hasmtlib.Boolean import Data.GADT.Compare import Data.GADT.DeepSeq-import Data.Map hiding (toList) import Data.Coerce import Data.Proxy import Data.Int@@ -99,8 +96,6 @@ import Data.Text (pack) import Data.List(genericLength) import Data.Foldable (toList)-import Data.ByteString.Builder-import Data.ByteString.Lazy.UTF8 (toString) import qualified Data.Vector.Sized as V import Control.Lens hiding (from, to) import GHC.TypeLits hiding (someNatVal)@@ -697,13 +692,13 @@ -- | This instance is __partial__ for 'toRational', this method is only intended for use with constants. instance (KnownSMTSort t, Real (HaskellType t)) => Real (Expr t) where   toRational (Constant x) = toRational $ unwrapValue x-  toRational x = error $ "Real#toRational[Expr " <> show (sortSing @t) <> "] only supported for constants. But given: " <> show x+  toRational _ = error $ "Real#toRational[Expr " <> show (sortSing @t) <> "] only supported for constants."   {-# INLINE toRational #-}  -- | This instance is __partial__ for 'fromEnum', this method is only intended for use with constants. instance (KnownSMTSort t, Enum (HaskellType t)) => Enum (Expr t) where   fromEnum (Constant x) = fromEnum $ unwrapValue x-  fromEnum x = error $ "Enum#fromEnum[Expr " <> show (sortSing @t) <> "] only supported for constants. But given: " <> show x+  fromEnum _ = error $ "Enum#fromEnum[Expr " <> show (sortSing @t) <> "] only supported for constants."   {-# INLINE fromEnum #-}   toEnum = Constant . wrapValue . toEnum   {-# INLINE toEnum #-}@@ -715,7 +710,7 @@   divMod x y  = (IDiv x y, Mod x y)   {-# INLINE divMod #-}   toInteger (Constant x) = toInteger $ unwrapValue x-  toInteger x = error $ "Integer#toInteger[Expr " <> show (sortSing @t) <> "] only supported for constants. But given: " <> show x+  toInteger _ = error $ "Integer#toInteger[Expr " <> show (sortSing @t) <> "] only supported for constants."   {-# INLINE toInteger #-}  instance Boolean (Expr BoolSort) where@@ -789,7 +784,7 @@   complementBit b _ = Not b   {-# INLINE complementBit #-}   testBit (Constant (BoolValue b)) _ = b-  testBit sb _ = error $ "Bits#testBit[Expr BoolSort] is only supported for constants. Given: " <> show sb+  testBit _ _ = error "Bits#testBit[Expr BoolSort] is only supported for constants."   {-# INLINE testBit #-}   bitSizeMaybe _ = Just 1   {-# INLINE bitSizeMaybe #-}@@ -808,7 +803,7 @@   rotateR b _ = b   {-# INLINE rotateR #-}   popCount (Constant (BoolValue b)) = if b then 1 else 0-  popCount sb = error $ "Bits#popCount[Expr BoolSort] is only supported for constants. Given: " <> show sb+  popCount _ = error "Bits#popCount[Expr BoolSort] is only supported for constants."   {-# INLINE popCount #-}  -- | This instance is __partial__ for 'testBit' and 'popCount', it's only intended for use with constants ('Constant').@@ -826,7 +821,7 @@   bit = Constant . BvValue . Bits.bit   {-# INLINE bit #-}   testBit (Constant (BvValue b)) i = Bits.testBit b i-  testBit sb _ = error $ "Bits#testBit[Expr BvSort] is only supported for constants. Given: " <> show sb+  testBit _ _ = error "Bits#testBit[Expr BvSort] is only supported for constants."   {-# INLINE testBit #-}   bitSizeMaybe _ = Just $ fromIntegral $ natVal $ Proxy @n   {-# INLINE bitSizeMaybe #-}@@ -847,7 +842,7 @@   rotateR b i = BvRotR i b   {-# INLINE rotateR #-}   popCount (Constant (BvValue b)) = Bits.popCount b-  popCount sb = error $ "Bits#popCount[Expr BvSort] is only supported for constants. Given: " <> show sb+  popCount _ = error $ "Bits#popCount[Expr BvSort] is only supported for constants."   {-# INLINE popCount #-}  instance Semigroup (Expr StringSort) where@@ -863,143 +858,6 @@ instance IsString (Expr StringSort) where   fromString = Constant . StringValue . pack   {-# INLINE fromString #-}--instance Render (SMTVar t) where-  render v = "var_" <> intDec (coerce @(SMTVar t) @Int v)-  {-# INLINE render #-}--instance Render (Value t) where-  render (IntValue x)   = render x-  render (RealValue x)  = render x-  render (BoolValue x)  = render x-  render (BvValue   v)  = "#b" <> render v-  render (ArrayValue arr) = case minViewWithKey (arr^.stored) of-    Nothing -> constRender $ arr^.arrConst-    Just ((k,v), stored')-      | size (arr^.stored) > 1 -> render $ ArrStore (Constant (wrapValue (arr & stored .~ stored'))) (Constant (wrapValue k)) (Constant (wrapValue v))-      | otherwise  -> constRender v-    where-      constRender v = "((as const " <> render (goSing arr) <> ") " <> render (wrapValue v) <> ")"-      goSing :: forall k v. (KnownSMTSort k, KnownSMTSort v, Ord (HaskellType k), Ord (HaskellType v)) => ConstArray (HaskellType k) (HaskellType v) -> SSMTSort (ArraySort k v)-      goSing _ = sortSing @(ArraySort k v)-  render (StringValue x) = "\"" <> render x <> "\""--instance KnownSMTSort t => Render (Expr t) where-  render (Var v)      = render v-  render (Constant c) = render c-  render (Plus x y)   = renderBinary (case sortSing' x of SBvSort _ _ -> "bvadd" ; _ -> "+") x y-  render (Minus x y)  = renderBinary (case sortSing' x of SBvSort _ _ -> "bvsub" ; _ -> "-") x y-  render (Neg x)      = renderUnary  (case sortSing' x of SBvSort _ _ -> "bvneg" ; _ -> "-") x-  render (Mul x y)    = renderBinary (case sortSing' x of SBvSort _ _ -> "bvmul" ; _ -> "*") x y-  render (Abs x)      = renderUnary  "abs" x-  render (Mod x y)    = renderBinary opStr x y-    where-      opStr = case sortSing' x of-        SBvSort enc _ -> case bvEncSing' enc of-          SUnsigned -> "bvurem"-          SSigned -> "bvsmod"-        _ -> "mod"-  render (Rem x y)    = renderBinary opStr x y-    where-      opStr = case sortSing' x of-        SBvSort enc _ -> case bvEncSing' enc of-          SUnsigned -> "bvurem"-          SSigned -> "bvsrem"-        _ -> "rem"-  render (IDiv x y)   = renderBinary opStr x y-    where-      opStr = case sortSing' x of-        SBvSort enc _ -> case bvEncSing' enc of-          SUnsigned -> "bvudiv"-          SSigned -> "bvsdiv"-        _ -> "div"-  render (Div x y)    = renderBinary "/" x y-  render (LTH x y)    = renderBinary opStr x y-    where-      opStr = case sortSing' x of-        SBvSort enc _ -> case bvEncSing' enc of-          SUnsigned -> "bvult"-          SSigned -> "bvslt"-        SStringSort -> "str.<"-        _ -> "<"-  render (LTHE x y)   = renderBinary opStr x y-    where-      opStr = case sortSing' x of-        SBvSort enc _ -> case bvEncSing' enc of-          SUnsigned -> "bvule"-          SSigned -> "bvsle"-        SStringSort -> "str.<="-        _ -> "<="-  render (EQU xs)     = renderNary "=" $ V.toList xs-  render (Distinct xs)= renderNary "distinct" $ V.toList xs-  render (GTHE x y)   = case sortSing' x of-    SBvSort enc _ -> case bvEncSing' enc of-      SUnsigned -> renderBinary "bvuge" x y-      SSigned   -> renderBinary "bvsge" x y-    SStringSort -> renderBinary "str.<=" y x-    _           -> renderBinary ">=" x y-  render (GTH x y)    = case sortSing' x of-    SBvSort enc _ -> case bvEncSing' enc of-      SUnsigned -> renderBinary "bvugt" x y-      SSigned   -> renderBinary "bvsgt" x y-    SStringSort -> renderBinary "str.<" y x-    _           -> renderBinary ">" x y-  render (Not x)      = renderUnary  (case sortSing' x of SBvSort _ _ -> "bvnot" ; _ -> "not") x-  render (And x y)    = renderBinary (case sortSing' x of SBvSort _ _ -> "bvand" ; _ -> "and") x y-  render (Or x y)     = renderBinary (case sortSing' x of SBvSort _ _ -> "bvor" ; _ -> "or") x y-  render (Impl x y)   = renderBinary "=>" x y-  render (Xor x y)    = renderBinary (case sortSing' x of SBvSort _ _ -> "bvxor" ; _ -> "xor") x y-  render Pi           = "real.pi"-  render (Sqrt x)     = renderUnary "sqrt" x-  render (Exp x)      = renderUnary "exp" x-  render (Sin x)      = renderUnary "sin" x-  render (Cos x)      = renderUnary "cos" x-  render (Tan x)      = renderUnary "tan" x-  render (Asin x)     = renderUnary "arcsin" x-  render (Acos x)     = renderUnary "arccos" x-  render (Atan x)     = renderUnary "arctan" x-  render (ToReal x)   = renderUnary "to_real" x-  render (ToInt x)    = renderUnary "to_int" x-  render (IsInt x)    = renderUnary "is_int" x-  render (Ite p t f)  = renderTernary "ite" p t f-  render (BvNand x y)       = renderBinary "bvnand" (render x) (render y)-  render (BvNor x y)        = renderBinary "bvnor"  (render x) (render y)-  render (BvShL x y)        = renderBinary "bvshl"  (render x) (render y)-  render (BvLShR x y)       = renderBinary "bvlshr" (render x) (render y)-  render (BvAShR x y)       = renderBinary "bvashr" (render x) (render y)-  render (BvConcat x y)     = renderBinary "concat" (render x) (render y)-  render (BvRotL i x)       = renderUnary (renderBinary "_" ("rotate_left"  :: Builder) (render $ toInteger i)) (render x)-  render (BvRotR i x)       = renderUnary (renderBinary "_" ("rotate_right" :: Builder) (render $ toInteger i)) (render x)-  render (ArrSelect a i)    = renderBinary  "select" (render a) (render i)-  render (ArrStore a i v)   = renderTernary "store"  (render a) (render i) (render v)-  render (StrConcat x y)        = renderBinary "str.++"  (render x) (render y)-  render (StrLength x)          = renderUnary  "str.len" (render x)-  render (StrAt x i)            = renderBinary "str.at"  (render x) (render i)-  render (StrSubstring x i j)   = renderTernary "str.substr"  (render x) (render i) (render j)-  render (StrPrefixOf x y)      = renderBinary "str.prefixof" (render x) (render y)-  render (StrSuffixOf x y)      = renderBinary "str.suffixof" (render x) (render y)-  render (StrContains x y)      = renderBinary "str.contains" (render x) (render y)-  render (StrIndexOf x y i)     = renderTernary "str.indexof"     (render x) (render y) (render i)-  render (StrReplace x y y')    = renderTernary "str.replace"     (render x) (render y) (render y')-  render (StrReplaceAll x y y') = renderTernary "str.replace_all" (render x) (render y) (render y')-  render (ForAll mQvar f) = renderQuantifier "forall" mQvar f-  render (Exists mQvar f) = renderQuantifier "exists" mQvar f--renderQuantifier :: forall t. KnownSMTSort t => Builder -> Maybe (SMTVar t) -> (Expr t -> Expr BoolSort) -> Builder-renderQuantifier qname (Just qvar) f =-  renderBinary-    qname-    ("(" <> renderUnary (render qvar) (sortSing @t) <> ")")-    expr-  where-    expr = render $ f $ Var qvar-renderQuantifier _ Nothing _ = mempty--instance Show (Value t) where-  show = toString . toLazyByteString . render--instance KnownSMTSort t => Show (Expr t) where-  show = toString . toLazyByteString . render  type instance Index   (Expr StringSort) = Expr IntSort type instance IxValue (Expr StringSort) = Expr StringSort
src/Language/Hasmtlib/Type/OMT.hs view
@@ -8,8 +8,12 @@ module Language.Hasmtlib.Type.OMT (   -- * SoftFormula+  -- ** Type   SoftFormula(..) +  -- ** Lens+, formula, mWeight, mGroupId+   -- * Optimization targets , Minimize(..), Maximize(..) @@ -23,7 +27,6 @@ where  import Language.Hasmtlib.Internal.Sharing-import Language.Hasmtlib.Internal.Render import Language.Hasmtlib.Type.MonadSMT import Language.Hasmtlib.Type.SMTSort import Language.Hasmtlib.Type.Option@@ -42,7 +45,7 @@   { _formula  :: Expr BoolSort    -- ^ The underlying soft formula   , _mWeight  :: Maybe Double     -- ^ Weight of the soft formula   , _mGroupId :: Maybe String     -- ^ Group-Id of the soft formula-  } deriving Show+  } $(makeLenses ''SoftFormula)  -- | A newtype for numerical expressions that are target of a minimization.@@ -108,22 +111,3 @@     sm <- use (smt.sharingMode)     sExpr <- runSharing sm expr     modifying softFormulas (|> SoftFormula sExpr w gid)--instance Render SoftFormula where-  render sf = "(assert-soft " <> render (sf^.formula) <> " :weight " <> maybe "1" render (sf^.mWeight) <> renderGroupId (sf^.mGroupId) <> ")"-    where-      renderGroupId Nothing = mempty-      renderGroupId (Just groupId) = " :id " <> render groupId--instance KnownSMTSort t => Render (Minimize t) where-  render (Minimize expr) = "(minimize " <> render expr <> ")"--instance KnownSMTSort t => Render (Maximize t) where-  render (Maximize expr) = "(maximize " <> render expr <> ")"--instance RenderSeq OMT where-  renderSeq omt =-       renderSeq (omt^.smt)-    <> fmap render (omt^.softFormulas)-    <> fmap (\case SomeSMTSort minExpr -> render minExpr) (omt^.targetMinimize)-    <> fmap (\case SomeSMTSort maxExpr -> render maxExpr) (omt^.targetMaximize)
src/Language/Hasmtlib/Type/Option.hs view
@@ -3,9 +3,7 @@ -} module Language.Hasmtlib.Type.Option where -import Language.Hasmtlib.Internal.Render import Data.Data (Data)-import Data.ByteString.Builder  -- | Options for SMT-Solvers. data SMTOption =@@ -14,9 +12,3 @@   | Incremental   Bool              -- ^ Incremental solving   | Custom String String            -- ^ Custom options. First String is the option, second its value.   deriving (Show, Eq, Ord, Data)--instance Render SMTOption where-  render (PrintSuccess  b) = renderBinary "set-option" (":print-success"  :: Builder) b-  render (ProduceModels b) = renderBinary "set-option" (":produce-models" :: Builder) b-  render (Incremental   b) = renderBinary "set-option" (":incremental"    :: Builder) b-  render (Custom k v)      = renderBinary "set-option" (":" <> render k) (render v)
src/Language/Hasmtlib/Type/Pipe.hs view
@@ -15,14 +15,14 @@   -- * Lens , lastPipeVarId, mPipeLogic , pipeSharingMode, pipeStableMap, incrSharedAuxs-, pipeSolver, isDebugging+, pipeSolver ) where  import Language.Hasmtlib.Internal.Sharing import Language.Hasmtlib.Internal.Render+import Language.Hasmtlib.Type.Debugger import Language.Hasmtlib.Type.Expr-import Language.Hasmtlib.Type.SMT import Language.Hasmtlib.Type.OMT (SoftFormula(..), Minimize(..), Maximize(..)) import Language.Hasmtlib.Type.MonadSMT import Language.Hasmtlib.Type.SMTSort@@ -36,12 +36,10 @@ import Data.IntMap as IntMap (singleton) import Data.Dependent.Map as DMap import Data.Coerce-import qualified Data.ByteString.Lazy.Char8 as ByteString.Char8 import Data.ByteString.Builder import Data.ByteString.Lazy hiding (filter, singleton, isPrefixOf) import Data.Attoparsec.ByteString hiding (Result) import Control.Monad.State-import Control.Monad import Control.Lens hiding (List) import System.Mem.StableName @@ -52,11 +50,11 @@ data Pipe = Pipe   { _lastPipeVarId     :: {-# UNPACK #-} !Int                                 -- ^ Last Id assigned to a new var   , _mPipeLogic        :: Maybe String                                        -- ^ Logic for the SMT-Solver-  , _pipeSharingMode   :: !SharingMode                                         -- ^ How to share common expressions+  , _pipeSharingMode   :: !SharingMode                                        -- ^ How to share common expressions   , _pipeStableMap     :: !(HashMap (StableName ()) (SomeKnownSMTSort Expr))  -- ^ Mapping between a 'StableName' and it's 'Expr' we may share   , _incrSharedAuxs    :: !(Seq (Seq (StableName ())))                        -- ^ Index of each 'Seq' ('StableName' ()) is incremental stack height where 'StableName' representing auxiliary var that has been shared   , _pipeSolver        :: !B.Solver                                           -- ^ Active pipe to the backend-  , _isDebugging       :: !Bool                                               -- ^ Flag if pipe shall debug+  , _mPipeDebugger      :: Maybe (Debugger Pipe)                                 -- ^ Debugger for communication with the external solver   } $(makeLenses ''Pipe) @@ -67,7 +65,7 @@     pipe <- get     modifying (incrSharedAuxs._last) (|> sn)     let cmd = renderAssert expr-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn $ toLazyByteString cmd+    liftIO $ maybe (return ()) (`debugAssert` cmd) (pipe^.mPipeDebugger)     liftIO $ B.command_ (pipe^.pipeSolver) cmd   setSharingMode sm = pipeSharingMode .= sm @@ -79,7 +77,7 @@     pipe <- get     newVar <- smtvar' p     let cmd = renderDeclareVar newVar-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn $ toLazyByteString cmd+    liftIO $ maybe (return ()) (`debugVar` cmd) (pipe^.mPipeDebugger)     liftIO $ B.command_ (pipe^.pipeSolver) cmd     return $ Var newVar   {-# INLINEABLE var' #-}@@ -91,45 +89,45 @@       Nothing    -> return sExpr       Just logic -> if "QF" `isPrefixOf` logic then return sExpr else quantify sExpr     let cmd = renderAssert qExpr-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn $ toLazyByteString cmd+    liftIO $ maybe (return ()) (`debugAssert` cmd) (pipe^.mPipeDebugger)     liftIO $ B.command_ (pipe^.pipeSolver) cmd   {-# INLINEABLE assert #-}    setOption opt = do     pipe <- get     let cmd = render opt-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn $ toLazyByteString cmd+    liftIO $ maybe (return ()) (`debugOption` cmd) (pipe^.mPipeDebugger)     liftIO $ B.command_ (pipe^.pipeSolver) cmd    setLogic l = do     mPipeLogic ?= l     pipe <- get     let cmd = renderSetLogic (stringUtf8 l)-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn $ toLazyByteString cmd+    liftIO $ maybe (return ()) (`debugLogic` cmd) (pipe^.mPipeDebugger)     liftIO $ B.command_ (pipe^.pipeSolver) cmd  instance (MonadState Pipe m, MonadIO m) => MonadIncrSMT Pipe m where   push = do     pipe <- get-    let cmd = "(push 1)"-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn $ toLazyByteString cmd+    let cmd = renderPush 1+    liftIO $ maybe (return ()) (`debugPush` cmd) (pipe^.mPipeDebugger)     liftIO $ B.command_ (pipe^.pipeSolver) cmd     incrSharedAuxs <>= mempty    pop = do     pipe <- get-    let cmd = "(pop 1)"-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn $ toLazyByteString cmd+    let cmd = renderPop 1+    liftIO $ maybe (return ()) (`debugPop` cmd) (pipe^.mPipeDebugger)     liftIO $ B.command_ (pipe^.pipeSolver) cmd     forMOf_ (incrSharedAuxs._last.folded) pipe (\sn -> pipeStableMap.at sn .= Nothing)     modifying incrSharedAuxs $ \case (auxs:>_) -> auxs ; auxs -> auxs    checkSat = do     pipe <- get-    let cmd = "(check-sat)"-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn $ toLazyByteString cmd+    let cmd = renderCheckSat+    liftIO $ maybe (return ()) (`debugCheckSat` cmd) (pipe^.mPipeDebugger)     result <- liftIO $ B.command (pipe^.pipeSolver) cmd-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn result+    liftIO $ maybe (return ()) (`debugResultResponse` result) (pipe^.mPipeDebugger)     case parseOnly resultParser (toStrict result) of       Left e    -> liftIO $ do         print result@@ -138,10 +136,10 @@    getModel = do     pipe   <- get-    let cmd = "(get-model)"-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn $ toLazyByteString cmd+    let cmd = renderGetModel+    liftIO $ maybe (return ()) (`debugGetModel` cmd) (pipe^.mPipeDebugger)     model <- liftIO $ B.command (pipe^.pipeSolver) cmd-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn model+    liftIO $ maybe (return ()) (`debugModelResponse` model) (pipe^.mPipeDebugger)     case parseOnly anyModelParser (toStrict model) of       Left e    -> liftIO $ do         print model@@ -151,10 +149,10 @@   getValue :: forall t. KnownSMTSort t => Expr t -> m (Maybe (Decoded (Expr t)))   getValue v@(Var x) = do     pipe   <- get-    let cmd = renderUnary "get-value" $ "(" <> render x <> ")"-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn $ toLazyByteString cmd+    let cmd = renderGetValue x+    liftIO $ maybe (return ()) (`debugGetValue` cmd) (pipe^.mPipeDebugger)     model <- liftIO $ B.command (pipe^.pipeSolver) cmd-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn model+    liftIO $ maybe (return ()) (`debugModelResponse` model) (pipe^.mPipeDebugger)     case parseOnly (getValueParser @t x) (toStrict model) of       Left e    -> liftIO $ do         print model@@ -175,7 +173,7 @@     pipe <- get     sExpr <- runSharing (pipe^.pipeSharingMode) expr     let cmd = render $ Minimize sExpr-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn $ toLazyByteString cmd+    liftIO $ maybe (return ()) (`debugMinimize` cmd) (pipe^.mPipeDebugger)     liftIO $ B.command_ (pipe^.pipeSolver) cmd   {-# INLINEABLE minimize #-} @@ -183,7 +181,7 @@     pipe <- get     sExpr <- runSharing (pipe^.pipeSharingMode) expr     let cmd = render $ Maximize sExpr-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn $ toLazyByteString cmd+    liftIO $ maybe (return ()) (`debugMaximize` cmd) (pipe^.mPipeDebugger)     liftIO $ B.command_ (pipe^.pipeSolver) cmd   {-# INLINEABLE maximize #-} @@ -191,6 +189,6 @@     pipe <- get     sExpr <- runSharing (pipe^.pipeSharingMode) expr     let cmd = render $ SoftFormula sExpr w gid-    when (pipe^.isDebugging) $ liftIO $ ByteString.Char8.putStrLn $ toLazyByteString cmd+    liftIO $ maybe (return ()) (`debugAssertSoft` cmd) (pipe^.mPipeDebugger)     liftIO $ B.command_ (pipe^.pipeSolver) cmd   {-# INLINEABLE assertSoft #-}
src/Language/Hasmtlib/Type/Relation.hs view
@@ -61,7 +61,6 @@ -- so @a@ and @b@ have to be instances of 'Ix', -- and both \(A\) and \(B\) are intervals. newtype Relation a b = Relation (Array (a, b) (Expr BoolSort))-  deriving stock Show  instance (Ix a, Ix b) => Codec (Relation a b) where   type Decoded (Relation a b) = Array (a, b) Bool
src/Language/Hasmtlib/Type/SMT.hs view
@@ -13,14 +13,10 @@ , lastVarId, vars, formulas , mlogic, options , sharingMode, Language.Hasmtlib.Type.SMT.stableMap--  -- * Rendering-, renderSetLogic, renderDeclareVar, renderAssert, renderVars ) where  import Language.Hasmtlib.Internal.Sharing-import Language.Hasmtlib.Internal.Render import Language.Hasmtlib.Type.MonadSMT import Language.Hasmtlib.Type.SMTSort import Language.Hasmtlib.Type.Option@@ -30,7 +26,6 @@ import Data.Coerce import Data.Sequence hiding ((|>), filter) import Data.Data (toConstr, showConstr)-import Data.ByteString.Builder import Data.HashMap.Lazy (HashMap) import Control.Monad.State import Control.Lens hiding (List)@@ -82,25 +77,3 @@       eqCon l r = showConstr (toConstr l) == showConstr (toConstr r)    setLogic l = mlogic ?= l--instance RenderSeq SMT where-  renderSeq smt =-       fromList (render <$> smt^.options)-       >< maybe mempty (singleton . renderSetLogic . stringUtf8) (smt^.mlogic)-       >< renderVars (smt^.vars)-       >< fmap renderAssert (smt^.formulas)--renderSetLogic :: Builder -> Builder-renderSetLogic = renderUnary "set-logic"--renderDeclareVar :: forall t. KnownSMTSort t => SMTVar t -> Builder-renderDeclareVar v = renderTernary "declare-fun" v ("()" :: Builder) (sortSing @t)-{-# INLINEABLE renderDeclareVar #-}--renderAssert :: Expr BoolSort -> Builder-renderAssert = renderUnary "assert"-{-# INLINEABLE renderAssert #-}--renderVars :: Seq (SomeKnownSMTSort SMTVar) -> Seq Builder-renderVars = fmap (\(SomeSMTSort v) -> renderDeclareVar v)-{-# INLINEABLE renderVars #-}
src/Language/Hasmtlib/Type/SMTSort.hs view
@@ -25,12 +25,10 @@  import Language.Hasmtlib.Internal.Constraint import Language.Hasmtlib.Type.Bitvec-import Language.Hasmtlib.Internal.Render import Language.Hasmtlib.Type.ArrayMap import Data.GADT.Compare import Data.Kind import Data.Proxy-import Data.ByteString.Builder import qualified Data.Text as Text import Control.Lens import GHC.TypeLits@@ -135,12 +133,3 @@  -- | An existential wrapper that hides some known 'SMTSort'. type SomeKnownSMTSort f = SomeSMTSort '[KnownSMTSort] f--instance Render (SSMTSort t) where-  render SBoolSort   = "Bool"-  render SIntSort    = "Int"-  render SRealSort   = "Real"-  render (SBvSort _ p) = renderBinary "_" ("BitVec" :: Builder) (natVal p)-  render (SArraySort k v) = renderBinary "Array" (sortSing' k) (sortSing' v)-  render SStringSort   = "String"-  {-# INLINEABLE render #-}
src/Language/Hasmtlib/Type/Solution.hs view
@@ -10,8 +10,8 @@ -} module Language.Hasmtlib.Type.Solution (-  -- * Solver-  Solver, Result(..)+  -- * Result+  Result(..)    -- * Solution , Solution@@ -40,9 +40,6 @@ import Data.Dependent.Map.Lens import Control.Lens --- | Function that turns a state into a result and a solution.-type Solver s m = s -> m (Result, Solution)- -- | Results of check-sat commands. data Result = Unsat | Unknown | Sat deriving (Show, Eq, Ord) @@ -50,15 +47,17 @@  -- | Newtype for 'IntMap' 'Value' so we can use it as right-hand-side of 'DMap'. newtype IntValueMap t = IntValueMap (IntMap (Value t))-  deriving stock Show   deriving newtype (Semigroup, Monoid) +deriving stock instance Show (Value t) => Show (IntValueMap t)+ -- | A solution for a single variable. data SMTVarSol (t :: SMTSort) = SMTVarSol   { _solVar :: SMTVar t                       -- ^ A variable in the SMT-Problem   , _solVal :: Value t                        -- ^ An assignment for this variable in a solution-  } deriving Show+  } $(makeLenses ''SMTVarSol)+deriving stock instance Show (Value t) => Show (SMTVarSol t)  -- | Alias class for constraint 'Ord' ('HaskellType' t) class Ord (HaskellType t) => OrdHaskellType t
src/Language/Hasmtlib/Type/Solver.hs view
@@ -1,16 +1,30 @@+{-# LANGUAGE TemplateHaskell #-}+ {- | This module provides functions for having SMT-Problems solved by external solvers.++The base type for every solver is the 'SolverConfig'. It describes where the solver executable is located and how it should behave.+You can provide a time-out using the decorator 'timingout'.+Another decorator - 'debugging' - allows you to debug all the information you want. The actual debuggers can be found in "Language.Hasmtlib.Type.Debugger". -} module Language.Hasmtlib.Type.Solver   (-  -- * WithSolver-  WithSolver(..)+  -- * Solver configuration +  -- ** Type+  SolverConfig(..)++  -- ** Decoration+  , debugging, timingout++  -- ** Lens+  , processConfig, mTimeout, mDebugger+   -- * Stateful solving-  , solveWith+  , Solver, solver, solveWith    -- * Interactive solving-  , interactiveWith, debugInteractiveWith+  , interactiveWith    -- ** Minimzation   , solveMinimized@@ -20,26 +34,111 @@   ) where +import Language.Hasmtlib.Internal.Render+import Language.Hasmtlib.Internal.Parser import Language.Hasmtlib.Type.MonadSMT+import Language.Hasmtlib.Type.Debugger import Language.Hasmtlib.Type.Expr import Language.Hasmtlib.Type.SMTSort import Language.Hasmtlib.Type.Solution import Language.Hasmtlib.Type.Pipe import Language.Hasmtlib.Codec+import Data.ByteString.Lazy hiding (singleton) import qualified SMTLIB.Backends as Backend import qualified SMTLIB.Backends.Process as Process import Data.Default import Data.Maybe+import Data.Attoparsec.ByteString (parseOnly)+import Control.Lens hiding (op)+import Control.Monad import Control.Monad.State+import Control.Monad.Trans.Control+import System.Timeout.Lifted --- | Data that can have a 'Backend.Solver' which may be debugged.-class WithSolver a where-  -- | Create a value with a 'Backend.Solver' and a 'Bool' for whether to debug the 'Backend.Solver'.-  withSolver :: Backend.Solver -> Bool -> a+-- | Function that turns a state into a 'Result' and a 'Solution'.+type Solver s m = s -> m (Result, Solution) -instance WithSolver Pipe where-  withSolver = Pipe 0 Nothing def mempty mempty+-- | Configuration for solver processes.+data SolverConfig s = SolverConfig+  { _processConfig  :: Process.Config         -- ^ The underlying config of the process+  , _mTimeout       :: Maybe Int              -- ^ Timeout in microseconds+  , _mDebugger      :: Maybe (Debugger s)     -- ^ Debugger for communication with external solver+  }+$(makeLenses ''SolverConfig) +-- | Creates a 'Solver' which holds an external process with a SMT-Solver.+--+--   This will:+--+-- 1. Encode the SMT-problem,+--+-- 2. start a new external process for the SMT-Solver,+--+-- 3. send the problem to the SMT-Solver,+--+-- 4. wait for an answer and parse it,+--+-- 5. close the process and clean up all resources and+--+-- 6. return the decoded solution.+solver :: (RenderProblem s, MonadIO m) => SolverConfig s -> Solver s m+solver (SolverConfig cfg mTO debugger) s = do+  liftIO $ Process.with cfg $ \handle -> do+    maybe mempty (`debugState` s) debugger+    pSolver <- Backend.initSolver Backend.Queuing $ Process.toBackend handle++    let os   = renderOptions s+        l    = renderLogic s+        vs   = renderDeclareVars s+        as   = renderAssertions s+        sas  = renderSoftAssertions s+        mins = renderMinimizations s+        maxs = renderMaximizations s+    maybe mempty (forM_ os . debugOption) debugger+    forM_ os (Backend.command_ pSolver)+    maybe mempty (`debugLogic` l) debugger+    Backend.command_ pSolver l+    maybe mempty (forM_ vs . debugVar) debugger+    forM_ vs (Backend.command_ pSolver)+    maybe mempty (forM_ as . debugAssert) debugger+    forM_ as (Backend.command_ pSolver)+    maybe mempty (forM_ sas . debugAssertSoft) debugger+    forM_ sas (Backend.command_ pSolver)+    maybe mempty (forM_ mins . debugMinimize) debugger+    forM_ mins (Backend.command_ pSolver)+    maybe mempty (forM_ maxs . debugMaximize) debugger+    forM_ maxs (Backend.command_ pSolver)++    let timingOut io = case mTO of+          Nothing -> io+          Just t -> fromMaybe "unknown" <$> timeout t io+    resultResponse <- timingOut $ Backend.command pSolver renderCheckSat+    maybe mempty (`debugResultResponse` resultResponse) debugger++    modelResponse <- Backend.command pSolver renderGetModel+    maybe mempty (`debugModelResponse` modelResponse) debugger++    case parseOnly resultParser (toStrict resultResponse) of+      Left e    -> fail e+      Right res -> case res of+        Unsat -> return (res, mempty)+        _     -> case parseOnly anyModelParser (toStrict modelResponse) of+          Left e    -> fail e+          Right sol -> return (res, sol)++-- | Decorates a 'SolverConfig' with a timeout. The timeout is given as an 'Int' which specifies+--   after how many __microseconds__ the external solver process shall time out on @(check-sat)@.+--+--   When timing out, the 'Result' will always be 'Unknown'.+--+--   This uses 'timeout' internally.+timingout :: Int -> SolverConfig s -> SolverConfig s+timingout t cfg = cfg & mTimeout ?~ t++-- | Decorates a 'SolverConfig' with a 'Debugger'.+debugging :: Debugger s -> SolverConfig s -> SolverConfig s+debugging debugger cfg = cfg & mDebugger ?~ debugger+ -- | @'solveWith' solver prob@ solves a SMT problem @prob@ with the given -- @solver@. It returns a pair consisting of: --@@ -72,9 +171,9 @@ -- -- The solver will probably answer with @x := 1@. solveWith :: (Default s, Monad m, Codec a) => Solver s m -> StateT s m a -> m (Result, Maybe (Decoded a))-solveWith solver m = do+solveWith solving m = do   (a, problem) <- runStateT m def-  (result, solution) <- solver problem+  (result, solution) <- solving problem    return (result, decode solution a) @@ -88,9 +187,7 @@ -- -- main :: IO () -- main = do---   cvc5Living <- interactiveSolver cvc5---   interactiveWith @Pipe cvc5Living $ do---     setOption $ Incremental True+--   interactiveWith z3 $ do --     setOption $ ProduceModels True --     setLogic \"QF_LRA\" --@@ -117,16 +214,16 @@ -- --   return () -- @-interactiveWith :: (WithSolver s, MonadIO m) => (Backend.Solver, Process.Handle) -> StateT s m () -> m ()-interactiveWith (solver, handle) m = do-  _ <- runStateT m $ withSolver solver False-  liftIO $ Process.close handle---- | Like 'interactiveWith' but it prints all communication with the solver to console.-debugInteractiveWith :: (WithSolver s, MonadIO m) => (Backend.Solver, Process.Handle) -> StateT s m () -> m ()-debugInteractiveWith (solver, handle) m = do-  _ <- runStateT m $ withSolver solver True+interactiveWith :: (MonadIO m, MonadBaseControl IO m) => SolverConfig Pipe -> StateT Pipe m a -> m (Maybe a)+interactiveWith cfg m = do+  handle <- liftIO $ Process.new $ cfg^.processConfig+  processSolver <- liftIO $ Backend.initSolver Backend.Queuing $ Process.toBackend handle+  let timingOut io = case cfg^.mTimeout of+        Nothing -> Just <$> io+        Just t -> timeout t io+  ma <- timingOut $ runStateT m $ Pipe 0 Nothing def mempty mempty processSolver (cfg^.mDebugger)   liftIO $ Process.close handle+  return $ fmap fst ma  -- | Solves the current problem with respect to a minimal solution for a given numerical expression. --