@@ -144,7 +144,7 @@ instance Pretty (PrettyWithModifiers mods EquationFailure) where
144
144
data EquationConfig = EquationConfig
145
145
{ definition :: KoreDefinition
146
146
, llvmApi :: Maybe LLVM. API
147
- , smtSolver :: Maybe SMT. SMTContext
147
+ , smtSolver :: SMT. SMTContext
148
148
, maxRecursion :: Bound " Recursion"
149
149
, maxIterations :: Bound " Iterations"
150
150
, logger :: Logger LogMessage
@@ -281,7 +281,7 @@ runEquationT ::
281
281
LoggerMIO io =>
282
282
KoreDefinition ->
283
283
Maybe LLVM. API ->
284
- Maybe SMT. SMTContext ->
284
+ SMT. SMTContext ->
285
285
SimplifierCache ->
286
286
Set Predicate ->
287
287
EquationT io a ->
@@ -331,15 +331,14 @@ iterateEquations direction preference startTerm = do
331
331
config <- getConfig
332
332
currentCount <- countSteps
333
333
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
343
342
throw $
344
343
TooManyIterations currentCount startTerm currentTerm
345
344
pushTerm currentTerm
@@ -395,7 +394,7 @@ evaluateTerm ::
395
394
Direction ->
396
395
KoreDefinition ->
397
396
Maybe LLVM. API ->
398
- Maybe SMT. SMTContext ->
397
+ SMT. SMTContext ->
399
398
Set Predicate ->
400
399
Term ->
401
400
io (Either EquationFailure Term , SimplifierCache )
@@ -418,7 +417,7 @@ evaluatePattern ::
418
417
LoggerMIO io =>
419
418
KoreDefinition ->
420
419
Maybe LLVM. API ->
421
- Maybe SMT. SMTContext ->
420
+ SMT. SMTContext ->
422
421
SimplifierCache ->
423
422
Pattern ->
424
423
io (Either EquationFailure Pattern , SimplifierCache )
@@ -431,13 +430,24 @@ evaluatePattern' ::
431
430
Pattern ->
432
431
EquationT io Pattern
433
432
evaluatePattern' pat@ Pattern {term, ceilConditions} = withPatternContext pat $ do
434
- newTerm <- withTermContext term $ evaluateTerm' BottomUp term
433
+ newTerm <- withTermContext term $ evaluateTerm' BottomUp term `catch_` keepTopLevelResults
435
434
-- after evaluating the term, evaluate all (existing and
436
435
-- newly-acquired) constraints, once
437
436
traverse_ simplifyAssumedPredicate . predicates =<< getState
438
437
-- this may yield additional new constraints, left unevaluated
439
438
evaluatedConstraints <- predicates <$> getState
440
439
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
441
451
442
452
-- evaluate the given predicate assuming all others
443
453
simplifyAssumedPredicate :: LoggerMIO io => Predicate -> EquationT io ()
@@ -452,7 +462,7 @@ evaluateConstraints ::
452
462
LoggerMIO io =>
453
463
KoreDefinition ->
454
464
Maybe LLVM. API ->
455
- Maybe SMT. SMTContext ->
465
+ SMT. SMTContext ->
456
466
SimplifierCache ->
457
467
Set Predicate ->
458
468
io (Either EquationFailure (Set Predicate ), SimplifierCache )
@@ -818,7 +828,7 @@ applyEquation term rule =
818
828
-- could now be syntactically present in the path constraints, filter again
819
829
stillUnclear <- lift $ filterOutKnownConstraints knownPredicates unclearConditions
820
830
821
- mbSolver :: Maybe SMT. SMTContext <- (. smtSolver) <$> lift getConfig
831
+ solver :: SMT. SMTContext <- (. smtSolver) <$> lift getConfig
822
832
823
833
-- check any conditions that are still unclear with the SMT solver
824
834
-- (or abort if no solver is being used), abort if still unclear after
@@ -832,7 +842,7 @@ applyEquation term rule =
832
842
liftIO $ Exception. throw other
833
843
Right result ->
834
844
pure result
835
- in maybe ( pure Nothing ) ( lift . checkWithSmt) mbSolver >>= \ case
845
+ in lift ( checkWithSmt solver) >>= \ case
836
846
Nothing -> do
837
847
-- no solver or still unclear: abort
838
848
throwE
@@ -872,23 +882,22 @@ applyEquation term rule =
872
882
)
873
883
ensured
874
884
-- check all ensured conditions together with the path condition
875
- whenJust mbSolver $ \ solver -> do
876
- lift (SMT. checkPredicates solver knownPredicates mempty $ Set. fromList ensuredConditions) >>= \ case
877
- Right (Just False ) -> do
878
- let falseEnsures = Predicate $ foldl1' AndTerm $ map coerce ensuredConditions
879
- throwE
880
- ( \ ctx ->
881
- ctx . logMessage $
882
- WithJsonMessage (object [" conditions" .= map (externaliseTerm . coerce) ensuredConditions]) $
883
- renderOneLineText (" Ensured conditions found to be false: " <> pretty' @ mods falseEnsures)
884
- , EnsuresFalse falseEnsures
885
- )
886
- Right _other ->
887
- pure ()
888
- Left SMT. SMTSolverUnknown {} ->
889
- pure ()
890
- Left other ->
891
- liftIO $ Exception. throw other
885
+ lift (SMT. checkPredicates solver knownPredicates mempty $ Set. fromList ensuredConditions) >>= \ case
886
+ Right (Just False ) -> do
887
+ let falseEnsures = Predicate $ foldl1' AndTerm $ map coerce ensuredConditions
888
+ throwE
889
+ ( \ ctx ->
890
+ ctx . logMessage $
891
+ WithJsonMessage (object [" conditions" .= map (externaliseTerm . coerce) ensuredConditions]) $
892
+ renderOneLineText (" Ensured conditions found to be false: " <> pretty' @ mods falseEnsures)
893
+ , EnsuresFalse falseEnsures
894
+ )
895
+ Right _other ->
896
+ pure ()
897
+ Left SMT. SMTSolverUnknown {} ->
898
+ pure ()
899
+ Left other ->
900
+ liftIO $ Exception. throw other
892
901
lift $ pushConstraints $ Set. fromList ensuredConditions
893
902
pure $ substituteInTerm subst rule. rhs
894
903
where
@@ -994,19 +1003,19 @@ simplifyConstraint ::
994
1003
LoggerMIO io =>
995
1004
KoreDefinition ->
996
1005
Maybe LLVM. API ->
997
- Maybe SMT. SMTContext ->
1006
+ SMT. SMTContext ->
998
1007
SimplifierCache ->
999
1008
Set Predicate ->
1000
1009
Predicate ->
1001
1010
io (Either EquationFailure Predicate , SimplifierCache )
1002
- simplifyConstraint def mbApi mbSMT cache knownPredicates (Predicate p) = do
1003
- runEquationT def mbApi mbSMT cache knownPredicates $ (coerce <$> ) . simplifyConstraint' True $ p
1011
+ simplifyConstraint def mbApi smt cache knownPredicates (Predicate p) = do
1012
+ runEquationT def mbApi smt cache knownPredicates $ (coerce <$> ) . simplifyConstraint' True $ p
1004
1013
1005
1014
simplifyConstraints ::
1006
1015
LoggerMIO io =>
1007
1016
KoreDefinition ->
1008
1017
Maybe LLVM. API ->
1009
- Maybe SMT. SMTContext ->
1018
+ SMT. SMTContext ->
1010
1019
SimplifierCache ->
1011
1020
[Predicate ] ->
1012
1021
io (Either EquationFailure [Predicate ], SimplifierCache )
0 commit comments