Skip to content

Recover from TooManyIterations when simplifying during rewriting #3989

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 23, 2024

Conversation

geo2a
Copy link
Contributor

@geo2a geo2a commented Jul 22, 2024

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.

@geo2a
Copy link
Contributor Author

geo2a commented Jul 22, 2024

No difference in KEVM performance as of commit 49516fc

@geo2a
Copy link
Contributor Author

geo2a commented Jul 22, 2024

No significant difference in Kontrol performance either.

@geo2a geo2a marked this pull request as ready for review July 22, 2024 18:29
@geo2a geo2a requested review from jberthold and goodlyrottenapple and removed request for jberthold July 22, 2024 18:29
Copy link
Member

@jberthold jberthold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test code not adapted yet.

Comment on lines 450 to 461
where
-- when TooManyIterations exception occurred while evaluating the top-level term,
-- i.e. not in a recursive evaluation of a side-condition,
-- it is safe to keep the partial result and ignore the exception.
-- Otherwise we would be throwing away useful work.
keepTopLevelResults :: LoggerMIO io => EquationFailure -> EquationT io Term
keepTopLevelResults = \case
err@(TooManyIterations recursionDepth _ _ partialResult) ->
case recursionDepth of
0 -> pure partialResult
_ -> throw err
err -> throw err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After checking the code where we recurse into the evaluation,

checkConstraint whenBottom (Predicate p) = withContext CtxConstraint $ do
let fallBackToUnsimplifiedOrBottom :: EquationFailure -> EquationT io Term
fallBackToUnsimplifiedOrBottom = \case
UndefinedTerm{} -> pure FalseBool
_ -> pure p
-- exceptions need to be handled differently in the recursion,
-- falling back to the unsimplified constraint instead of aborting.
simplified <-
lift $ simplifyConstraint' True p `catch_` fallBackToUnsimplifiedOrBottom

I think it is probably fine without this additional catch_. Of course it is safer the way you propose it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need the catch_ to get the simplified term, but I do agree that the recursion depth check is redundant. I've removed it.

Comment on lines 238 to 239
getRecusionDepth :: LoggerMIO io => EquationT io Int
getRecusionDepth = (length . (.recursionStack)) <$> getState
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
getRecusionDepth :: LoggerMIO io => EquationT io Int
getRecusionDepth = (length . (.recursionStack)) <$> getState
getRecursionDepth :: LoggerMIO io => EquationT io Int
getRecursionDepth = (length . (.recursionStack)) <$> getState

@@ -331,6 +335,10 @@ iterateEquations direction preference startTerm = do
config <- getConfig
currentCount <- countSteps
when (coerce currentCount > config.maxIterations) $ do
currentRecursionDepth <- getRecusionDepth
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
currentRecursionDepth <- getRecusionDepth
currentRecursionDepth <- getRecursionDepth

Comment on lines 339 to 344
-- FIXME if this exception is caught in evaluatePattern',
-- then CtxAbort is a wrong context for it.
-- We should emit this log entry somewhere else.
withContext CtxAbort $ do
logWarn $
renderOneLineText $
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could probably log this in evaluatePattern' where we decide whether or not to use the final term.
The warning will still show up for recursive evaluations where we catch the exception, too. Maybe not useless to notify the user about it, though? (so we could just use CtxWarn).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed CtxAbort, so these will show up as warnings now.

@geo2a geo2a force-pushed the georgy/keep-simplifications branch from b0c52a7 to a3cc6a7 Compare July 23, 2024 06:01
Copy link
Member

@jberthold jberthold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@rv-jenkins rv-jenkins merged commit 10ef196 into master Jul 23, 2024
6 checks passed
@rv-jenkins rv-jenkins deleted the georgy/keep-simplifications branch July 23, 2024 11:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants