@@ -70,6 +70,7 @@ import Booster.Pattern.Pretty
70
70
import Booster.Pattern.Util
71
71
import Booster.Prettyprinter
72
72
import Booster.SMT.Interface qualified as SMT
73
+ import Booster.SMT.Runner qualified as SMT
73
74
import Booster.Syntax.Json.Externalise (externalisePredicate , externaliseSort , externaliseTerm )
74
75
import Booster.Util (Flag (.. ))
75
76
@@ -198,7 +199,18 @@ rewriteStep cutLabels terminalLabels pat = do
198
199
RewriteStuck {} -> pure $ RewriteTrivial pat
199
200
other -> pure other
200
201
AppliedRules ([] , _remainder) -> processGroups rest
201
- AppliedRules ([(rule, newPat, _subst)], _remainder)
202
+ AppliedRules ([(rule, newPat, _subst)], remainder)
203
+ | not (Set. null remainder) && not (any isFalse remainder) -> do
204
+ -- a non-trivial remainder with a single applicable rule is
205
+ -- an indication if semantics incompleteness: abort
206
+ -- TODO refactor remainder check into a function and reuse below
207
+ solver <- getSolver
208
+ logMessage (show (SMT. options solver))
209
+ satRes <- SMT. isSat solver (Set. toList $ pat. constraints <> remainder)
210
+ throw $
211
+ RewriteRemainderPredicate [rule] satRes . coerce . foldl1 AndTerm $
212
+ map coerce . Set. toList $
213
+ remainder
202
214
-- a single rule applies, see if it's special and return an appropriate result
203
215
| labelOf rule `elem` cutLabels ->
204
216
pure $ RewriteCutPoint (labelOf rule) (uniqueId rule) pat newPat
@@ -209,7 +221,6 @@ rewriteStep cutLabels terminalLabels pat = do
209
221
AppliedRules (xs, remainder)
210
222
-- multiple rules apply, analyse brunching and remainders
211
223
| any isFalse remainder -> do
212
- withContext CtxRemainder $ logMessage (" remainder is UNSAT" :: Text )
213
224
-- the remainder predicate is trivially false, return the branching result
214
225
pure $
215
226
RewriteBranch pat $
@@ -222,7 +233,6 @@ rewriteStep cutLabels terminalLabels pat = do
222
233
SMT. isSat solver (Set. toList $ pat. constraints <> remainder) >>= \ case
223
234
SMT. IsUnsat -> do
224
235
-- the remainder condition is unsatisfiable: no need to consider the remainder branch.
225
- withContext CtxRemainder $ logMessage (" remainder is UNSAT" :: Text )
226
236
-- pure resultsWithoutRemainders
227
237
pure $
228
238
RewriteBranch pat $
@@ -438,6 +448,10 @@ applyRule pat@Pattern{ceilConditions} rule =
438
448
case unclearRequiresAfterSmt of
439
449
[] -> withPatternContext rewritten $ pure (rewritten, Predicate FalseBool , subst)
440
450
_ -> do
451
+ -- the requires clause was unclear:
452
+ -- - add it as an assumption to the pattern
453
+ -- - return it's negation as a rule remainder to construct
454
+ --- the remainder pattern in @rewriteStep@
441
455
let rewritten' = rewritten{constraints = rewritten. constraints <> Set. fromList unclearRequiresAfterSmt}
442
456
in withPatternContext rewritten' $
443
457
pure
@@ -502,8 +516,13 @@ applyRule pat@Pattern{ceilConditions} rule =
502
516
solver <- lift $ RewriteT $ (. smtSolver) <$> ask
503
517
SMT. checkPredicates solver pat. constraints mempty (Set. fromList stillUnclear) >>= \ case
504
518
SMT. IsUnknown reason -> do
505
- -- abort rewrite if a solver result was Unknown
506
519
withContext CtxAbort $ logMessage reason
520
+ -- return unclear rewrite rule condition if the condition is indeterminate
521
+ withContext CtxConstraint . withContext CtxWarn . logMessage $
522
+ WithJsonMessage (object [" conditions" .= (externaliseTerm . coerce <$> stillUnclear)]) $
523
+ renderOneLineText $
524
+ " Uncertain about condition(s) in a rule:"
525
+ <+> (hsep . punctuate comma . map (pretty' @ mods ) $ stillUnclear)
507
526
pure unclearRequires
508
527
SMT. IsInvalid -> do
509
528
-- requires is actually false given the prior
0 commit comments