Skip to content

Commit b6ab7a9

Browse files
authored
HOTFIX re-introduce indeterminate result for checkPredicates instead of exceptions (#3908)
* Re-introduces the 'indeterminate' result for checkPredicates, and returns that on inconsistent ground truth. * In the rewrite, aborts on `SMTSolverUnknown` when checking requires clauses, but throws actual exceptions (terminating the request) on other SMT errors (translation error, general error). Follow-up to #3907
1 parent 22409b1 commit b6ab7a9

File tree

2 files changed

+40
-32
lines changed

2 files changed

+40
-32
lines changed

booster/library/Booster/Pattern/Rewrite.hs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module Booster.Pattern.Rewrite (
1818
) where
1919

2020
import Control.Applicative ((<|>))
21+
import Control.Exception qualified as Exception (throw)
2122
import Control.Monad
2223
import Control.Monad.Extra (whenJust)
2324
import Control.Monad.IO.Class (MonadIO (..))
@@ -354,29 +355,30 @@ applyRule pat@Pattern{ceilConditions} rule = withRuleContext rule $ runRewriteRu
354355
-- check unclear requires-clauses in the context of known constraints (prior)
355356
mbSolver <- lift $ RewriteT $ (.smtSolver) <$> ask
356357

358+
let smtUnclear = do
359+
withContext "abort" . logMessage . renderOneLineText $
360+
"Uncertain about condition(s) in a rule:" <+> pretty unclearRequires
361+
failRewrite $
362+
RuleConditionUnclear rule . coerce . foldl1 AndTerm $
363+
map coerce unclearRequires
357364
case mbSolver of
358365
Just solver -> do
359-
checkAllRequires <- SMT.checkPredicates solver prior mempty (Set.fromList unclearRequires)
366+
checkAllRequires <-
367+
SMT.checkPredicates solver prior mempty (Set.fromList unclearRequires)
360368

361369
case checkAllRequires of
362-
Left _ -> do
363-
-- TODO: we could process SMTError here
364-
-- unclear even with the prior
365-
withContext "abort" $
366-
logMessage $
367-
renderOneLineText $
368-
"Uncertain about a condition(s) in rule:" <+> pretty unclearRequires
369-
failRewrite $
370-
RuleConditionUnclear rule . coerce $
371-
foldl1 AndTerm $
372-
map coerce unclearRequires
373-
Right False -> do
370+
Left SMT.SMTSolverUnknown{} ->
371+
smtUnclear -- abort rewrite if a solver result was Unknown
372+
Left other ->
373+
liftIO $ Exception.throw other -- fail hard on other SMT errors
374+
Right (Just False) -> do
374375
-- requires is actually false given the prior
375376
withContext "failure" $ logMessage ("Required clauses evaluated to #Bottom." :: Text)
376377
RewriteRuleAppT $ pure NotApplied
377-
Right True ->
378-
-- can proceed
379-
pure ()
378+
Right (Just True) ->
379+
pure () -- can proceed
380+
Right Nothing ->
381+
smtUnclear -- no implication could be determined
380382
Nothing ->
381383
unless (null unclearRequires) $ do
382384
withContext "abort" $
@@ -398,10 +400,15 @@ applyRule pat@Pattern{ceilConditions} rule = withRuleContext rule $ runRewriteRu
398400
-- check all new constraints together with the known side constraints
399401
whenJust mbSolver $ \solver ->
400402
(lift $ SMT.checkPredicates solver prior mempty (Set.fromList newConstraints)) >>= \case
401-
Right False -> do
403+
Right (Just False) -> do
402404
withContext "success" $ logMessage ("New constraints evaluated to #Bottom." :: Text)
403405
RewriteRuleAppT $ pure Trivial
404-
_other -> pure ()
406+
Right _other ->
407+
pure ()
408+
Left SMT.SMTSolverUnknown{} ->
409+
pure ()
410+
Left other ->
411+
liftIO $ Exception.throw other
405412

406413
-- existential variables may be present in rule.rhs and rule.ensures,
407414
-- need to strip prefixes and freshen their names with respect to variables already

booster/library/Booster/SMT/Interface.hs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,9 @@ checkPredicates ::
263263
Set Predicate ->
264264
Map Variable Term ->
265265
Set Predicate ->
266-
io (Either SMTError Bool)
266+
io (Either SMTError (Maybe Bool))
267267
checkPredicates ctxt givenPs givenSubst psToCheck
268-
| null psToCheck = pure $ Right True
268+
| null psToCheck = pure . Right $ Just True
269269
| Left errMsg <- translated = Log.withContext "smt" $ do
270270
Log.logErrorNS "booster" $ "SMT translation error: " <> errMsg
271271
Log.logMessage $ "SMT translation error: " <> errMsg
@@ -297,34 +297,35 @@ checkPredicates ctxt givenPs givenSubst psToCheck
297297
mapM_ smtRun smtGiven
298298

299299
consistent <- smtRun CheckSat
300-
when (consistent /= Sat) $ do
301-
void $ smtRun Pop
300+
unless (consistent == Sat) $ do
302301
let errMsg = ("Inconsistent ground truth, check returns Nothing" :: Text)
303302
Log.logMessage errMsg
304-
throwE $ GeneralSMTError errMsg
303+
let ifConsistent check = if (consistent == Sat) then check else pure Unsat
305304

306305
-- save ground truth for 2nd check
307306
smtRun_ Push
308307

309308
-- run check for K ∧ P and then for K ∧ !P
310309
let allToCheck = SMT.List (Atom "and" : sexprsToCheck)
311310

312-
smtRun_ $ Assert "P" allToCheck
313-
positive <- smtRun CheckSat
311+
positive <- ifConsistent $ do
312+
smtRun_ $ Assert "P" allToCheck
313+
smtRun CheckSat
314+
smtRun_ Pop
315+
negative <- ifConsistent $ do
316+
smtRun_ $ Assert "not P" (SMT.smtnot allToCheck)
317+
smtRun CheckSat
314318
smtRun_ Pop
315-
smtRun_ $ Assert "not P" (SMT.smtnot allToCheck)
316-
negative <- smtRun CheckSat
317-
void $ smtRun Pop
318319

319320
Log.logMessage $
320321
"Check of Given ∧ P and Given ∧ !P produced "
321322
<> pack (show (positive, negative))
322323

323324
case (positive, negative) of
324-
(Unsat, Unsat) -> throwSMT "Inconsistent ground truth: should have been caught above"
325-
(Sat, Sat) -> throwE $ GeneralSMTError "Implication not determined"
326-
(Sat, Unsat) -> pure True
327-
(Unsat, Sat) -> pure False
325+
(Unsat, Unsat) -> pure Nothing -- defensive choice for inconsistent ground truth
326+
(Sat, Sat) -> pure Nothing -- implication not determined
327+
(Sat, Unsat) -> pure $ Just True
328+
(Unsat, Sat) -> pure $ Just False
328329
(Unknown, _) -> do
329330
smtRun GetReasonUnknown >>= \case
330331
ReasonUnknown reason -> throwE $ SMTSolverUnknown reason givenPs psToCheck

0 commit comments

Comments
 (0)