@@ -26,6 +26,7 @@ module Booster.Pattern.ApplyEquations (
26
26
evaluateConstraints ,
27
27
) where
28
28
29
+ import Control.Exception qualified as Exception (throw )
29
30
import Control.Monad
30
31
import Control.Monad.Extra (fromMaybeM , whenJust )
31
32
import Control.Monad.IO.Class (MonadIO (.. ))
@@ -39,7 +40,7 @@ import Data.ByteString.Char8 qualified as BS
39
40
import Data.Coerce (coerce )
40
41
import Data.Data (Data , Proxy )
41
42
import Data.Foldable (toList , traverse_ )
42
- import Data.List (intersperse , partition )
43
+ import Data.List (foldl1' , intersperse , partition )
43
44
import Data.List.NonEmpty qualified as NonEmpty
44
45
import Data.Map (Map )
45
46
import Data.Map qualified as Map
@@ -817,17 +818,45 @@ applyEquation term rule =
817
818
-- could now be syntactically present in the path constraints, filter again
818
819
stillUnclear <- lift $ filterOutKnownConstraints knownPredicates unclearConditions
819
820
820
- -- abort if any of the conditions is still unclear at that point
821
+ mbSolver :: Maybe SMT. SMTContext <- (. smtSolver) <$> lift getConfig
822
+
823
+ -- check any conditions that are still unclear with the SMT solver
824
+ -- (or abort if no solver is being used), abort if still unclear after
821
825
unless (null stillUnclear) $
822
- throwE
823
- ( \ ctxt ->
824
- ctxt $
825
- logMessage $
826
- renderOneLineText $
827
- " Uncertain about a condition(s) in rule:"
828
- <+> hsep (intersperse " ," $ map (pretty' @ mods ) unclearConditions)
829
- , IndeterminateCondition unclearConditions
830
- )
826
+ let checkWithSmt :: SMT. SMTContext -> EquationT io (Maybe Bool )
827
+ checkWithSmt smt =
828
+ SMT. checkPredicates smt knownPredicates mempty (Set. fromList stillUnclear) >>= \ case
829
+ Left SMT. SMTSolverUnknown {} -> do
830
+ pure Nothing
831
+ Left other ->
832
+ liftIO $ Exception. throw other
833
+ Right result ->
834
+ pure result
835
+ in maybe (pure Nothing ) (lift . checkWithSmt) mbSolver >>= \ case
836
+ Nothing -> do
837
+ -- no solver or still unclear: abort
838
+ throwE
839
+ ( \ ctx ->
840
+ ctx . logMessage $
841
+ WithJsonMessage (object [" conditions" .= map (externaliseTerm . coerce) stillUnclear]) $
842
+ renderOneLineText
843
+ ( " Uncertain about conditions in rule: " <+> hsep (intersperse " ," $ map (pretty' @ mods ) stillUnclear)
844
+ )
845
+ , IndeterminateCondition stillUnclear
846
+ )
847
+ Just False -> do
848
+ -- actually false given path condition: fail
849
+ let failedP = Predicate $ foldl1' AndTerm $ map coerce stillUnclear
850
+ throwE
851
+ ( \ ctx ->
852
+ ctx . logMessage $
853
+ WithJsonMessage (object [" conditions" .= map (externaliseTerm . coerce) stillUnclear]) $
854
+ renderOneLineText (" Required condition found to be false: " <> pretty' @ mods failedP)
855
+ , ConditionFalse failedP
856
+ )
857
+ Just True -> do
858
+ -- can proceed
859
+ pure ()
831
860
832
861
-- check ensured conditions, filter any
833
862
-- true ones, prune if any is false
@@ -842,6 +871,24 @@ applyEquation term rule =
842
871
( checkConstraint $ \ p -> (\ ctxt -> ctxt $ logMessage (" Ensures clause simplified to #Bottom." :: Text ), EnsuresFalse p)
843
872
)
844
873
ensured
874
+ -- check all ensured conditions together with the path condition
875
+ whenJust mbSolver $ \ solver -> do
876
+ lift (SMT. checkPredicates solver knownPredicates mempty $ Set. fromList ensuredConditions) >>= \ case
877
+ Right (Just False ) -> do
878
+ let falseEnsures = Predicate $ foldl1' AndTerm $ map coerce ensuredConditions
879
+ throwE
880
+ ( \ ctx ->
881
+ ctx . logMessage $
882
+ WithJsonMessage (object [" conditions" .= map (externaliseTerm . coerce) ensuredConditions]) $
883
+ renderOneLineText (" Ensured conditions found to be false: " <> pretty' @ mods falseEnsures)
884
+ , EnsuresFalse falseEnsures
885
+ )
886
+ Right _other ->
887
+ pure ()
888
+ Left SMT. SMTSolverUnknown {} ->
889
+ pure ()
890
+ Left other ->
891
+ liftIO $ Exception. throw other
845
892
lift $ pushConstraints $ Set. fromList ensuredConditions
846
893
pure $ substituteInTerm subst rule. rhs
847
894
where
0 commit comments