Skip to content

Commit 10ef196

Browse files
authored
Recover from TooManyIterations when simplifying during rewriting (#3989)
Booster's rewriting algorithm, upon getting stuck (or aborting due to `RuleApplicationUnclear`), will try so simplify the configuration once and retry applying rules. When we cannot not finish simplifying the term due to a `TooManyIterations`, we throw the partial result away and fail. This PR handles the `TooManyIterations` exception and attempts applying rewrite rules to the partially simplified term.
1 parent 1103673 commit 10ef196

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

booster/library/Booster/Pattern/ApplyEquations.hs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -331,15 +331,14 @@ iterateEquations direction preference startTerm = do
331331
config <- getConfig
332332
currentCount <- countSteps
333333
when (coerce currentCount > config.maxIterations) $ do
334-
withContext CtxAbort $ do
335-
logWarn $
336-
renderOneLineText $
337-
"Unable to finish evaluation in" <+> pretty currentCount <+> "iterations."
338-
withContext CtxDetail $
339-
getPrettyModifiers >>= \case
340-
ModifiersRep (_ :: FromModifiersT mods => Proxy mods) ->
341-
logMessage . renderOneLineText $
342-
"Final term:" <+> pretty' @mods currentTerm
334+
logWarn $
335+
renderOneLineText $
336+
"Unable to finish evaluation in" <+> pretty currentCount <+> "iterations."
337+
withContext CtxDetail $
338+
getPrettyModifiers >>= \case
339+
ModifiersRep (_ :: FromModifiersT mods => Proxy mods) ->
340+
logMessage . renderOneLineText $
341+
"Final term:" <+> pretty' @mods currentTerm
343342
throw $
344343
TooManyIterations currentCount startTerm currentTerm
345344
pushTerm currentTerm
@@ -431,13 +430,24 @@ evaluatePattern' ::
431430
Pattern ->
432431
EquationT io Pattern
433432
evaluatePattern' pat@Pattern{term, ceilConditions} = withPatternContext pat $ do
434-
newTerm <- withTermContext term $ evaluateTerm' BottomUp term
433+
newTerm <- withTermContext term $ evaluateTerm' BottomUp term `catch_` keepTopLevelResults
435434
-- after evaluating the term, evaluate all (existing and
436435
-- newly-acquired) constraints, once
437436
traverse_ simplifyAssumedPredicate . predicates =<< getState
438437
-- this may yield additional new constraints, left unevaluated
439438
evaluatedConstraints <- predicates <$> getState
440439
pure Pattern{constraints = evaluatedConstraints, term = newTerm, ceilConditions}
440+
where
441+
-- when TooManyIterations exception occurred while evaluating the top-level term,
442+
-- i.e. not in a recursive evaluation of a side-condition,
443+
-- it is safe to keep the partial result and ignore the exception.
444+
-- Otherwise we would be throwing away useful work.
445+
-- The exceptions thrown in recursion is caught in applyEquation.checkConstraint
446+
keepTopLevelResults :: LoggerMIO io => EquationFailure -> EquationT io Term
447+
keepTopLevelResults = \case
448+
TooManyIterations _ _ partialResult ->
449+
pure partialResult
450+
err -> throw err
441451

442452
-- evaluate the given predicate assuming all others
443453
simplifyAssumedPredicate :: LoggerMIO io => Predicate -> EquationT io ()

0 commit comments

Comments
 (0)