@@ -234,6 +234,9 @@ popRecursion = do
234
234
throw $ InternalError " Trying to pop an empty recursion stack"
235
235
else eqState $ put s{recursionStack = tail s. recursionStack}
236
236
237
+ getRecusionDepth :: LoggerMIO io => EquationT io Int
238
+ getRecusionDepth = (length . (. recursionStack)) <$> getState
239
+
237
240
toCache :: Monad io => CacheTag -> Term -> Term -> EquationT io ()
238
241
toCache tag orig result = eqState . modify $ \ s -> s{cache = updateCache tag s. cache}
239
242
where
@@ -331,6 +334,9 @@ iterateEquations direction preference startTerm = do
331
334
config <- getConfig
332
335
currentCount <- countSteps
333
336
when (coerce currentCount > config. maxIterations) $ do
337
+ -- FIXME if this exception is caught in evaluatePattern',
338
+ -- then CtxAbort is a wrong context for it.
339
+ -- We should emit this log entry somewhere else.
334
340
withContext CtxAbort $ do
335
341
logWarn $
336
342
renderOneLineText $
@@ -409,7 +415,8 @@ evaluateTerm' ::
409
415
Direction ->
410
416
Term ->
411
417
EquationT io Term
412
- evaluateTerm' direction = iterateEquations direction PreferFunctions
418
+ evaluateTerm' direction =
419
+ iterateEquations direction PreferFunctions
413
420
414
421
{- | Simplify a Pattern, processing its constraints independently.
415
422
Returns either the first failure or the new pattern if no failure was encountered
@@ -431,13 +438,24 @@ evaluatePattern' ::
431
438
Pattern ->
432
439
EquationT io Pattern
433
440
evaluatePattern' pat@ Pattern {term, ceilConditions} = withPatternContext pat $ do
434
- newTerm <- withTermContext term $ evaluateTerm' BottomUp term
441
+ newTerm <- withTermContext term $ evaluateTerm' BottomUp term `catch_` keepTopLevelResults
435
442
-- after evaluating the term, evaluate all (existing and
436
443
-- newly-acquired) constraints, once
437
444
traverse_ simplifyAssumedPredicate . predicates =<< getState
438
445
-- this may yield additional new constraints, left unevaluated
439
446
evaluatedConstraints <- predicates <$> getState
440
447
pure Pattern {constraints = evaluatedConstraints, term = newTerm, ceilConditions}
448
+ where
449
+ -- when TooManyIterations exception occurs while evaluating the top-level term (not a side-condition),
450
+ -- it is safe to keep the partial result and ignore the exception. Otherwise we
451
+ -- would be throwing away useful work.
452
+ keepTopLevelResults :: LoggerMIO io => EquationFailure -> EquationT io Term
453
+ keepTopLevelResults = \ case
454
+ err@ (TooManyIterations _ _ partialResult) ->
455
+ getRecusionDepth >>= \ case
456
+ 0 -> pure partialResult
457
+ _ -> throw err
458
+ err -> throw err
441
459
442
460
-- evaluate the given predicate assuming all others
443
461
simplifyAssumedPredicate :: LoggerMIO io => Predicate -> EquationT io ()
0 commit comments