Skip to content

Commit f1d4ba6

Browse files
geo2arv-jenkins
andauthored
SMT retry logic changes in Kore (#3860)
Fixes #3859 * if a query returns unknown, do not retry with the same timeout, use double the timeout. Scale further timeouts quadratically, rather than linearly. * do not retry when applying simplifications * add context logs for unknown predicates --------- Co-authored-by: rv-jenkins <[email protected]>
1 parent b373660 commit f1d4ba6

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed

kore/src/Kore/Log/DecidePredicateUnknown.hs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import Kore.Internal.Predicate qualified as Predicate
3232
import Kore.Internal.TermLike qualified as TermLike
3333
import Kore.Internal.Variable
3434
import Kore.Syntax.Json qualified as PatternJson
35+
import Kore.Unparser (unparse)
3536
import Language.Haskell.TH.Syntax (Exp, Loc (..), Q, qLocation)
3637
import Log
3738
import Prelude.Kore
@@ -101,7 +102,23 @@ instance Entry DecidePredicateUnknown where
101102
where
102103
prettyHsLoc Loc{loc_module, loc_start = (row, col)} =
103104
Pretty.pretty loc_module <> ":" <> Pretty.pretty row <> ":" <> Pretty.pretty col
104-
oneLineDoc _ = "DecidePredicateUnknown"
105+
oneLineDoc (DecidePredicateUnknown{message, predicates}) =
106+
Pretty.hsep
107+
[ Pretty.brackets "smt"
108+
, Pretty.pretty description
109+
, unparse
110+
( Predicate.fromPredicate
111+
sortBool
112+
predicate
113+
)
114+
]
115+
where
116+
predicate = Predicate.makeMultipleAndPredicate . toList $ predicates
117+
description =
118+
"solver returned unknwon with reason "
119+
<> message
120+
<> " for predicate "
121+
105122
helpDoc _ =
106123
"error or a warning when the solver cannot decide the satisfiability of a formula"
107124

@@ -125,6 +142,10 @@ externaliseDecidePredicateUnknown :: DecidePredicateUnknown -> (Text, PatternJso
125142
externaliseDecidePredicateUnknown err@DecidePredicateUnknown{message} =
126143
( message
127144
, PatternJson.fromPredicate
128-
(TermLike.SortActualSort $ TermLike.SortActual (TermLike.Id "SortBool" TermLike.AstLocationNone) [])
145+
sortBool
129146
(Predicate.makeMultipleAndPredicate . toList $ predicates err)
130147
)
148+
149+
sortBool :: TermLike.Sort
150+
sortBool =
151+
(TermLike.SortActualSort $ TermLike.SortActual (TermLike.Id "SortBool" TermLike.AstLocationNone) [])

kore/src/Kore/Rewrite/SMT/Evaluator.hs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,11 @@ decidePredicate ::
169169
decidePredicate onUnknown sideCondition predicates =
170170
whileDebugEvaluateCondition predicates $
171171
do
172-
result <- query >>= whenUnknown retry
172+
result <- case onUnknown of
173+
-- do not retry the query on Unknown if the use-case is "soft", i.e. applying simplifications
174+
WarnDecidePredicateUnknown _ _ -> query
175+
-- if Unknown leads to a hard error, retry the query with scaled timeouts
176+
ErrorDecidePredicateUnknown _ _ -> query >>= whenUnknown retry
173177
debugEvaluateConditionResult result
174178
case result of
175179
Unsat -> return False
@@ -206,10 +210,8 @@ decidePredicate onUnknown sideCondition predicates =
206210
retryWithScaledTimeout :: MonadSMT m => m Result -> m Result
207211
retryWithScaledTimeout q = do
208212
SMT.RetryLimit limit <- SMT.askRetryLimit
209-
-- Use the same timeout for the first retry, since sometimes z3
210-
-- decides it doesn't want to work today and all we need is to
211-
-- retry it once.
212-
let timeoutScales = takeWithin limit [1 ..]
213+
-- the timeout is doubled for every retry
214+
let timeoutScales = takeWithin limit . map (2 ^) $ [1 :: Integer ..]
213215
retryActions = map (retryOnceWithScaledTimeout q) timeoutScales
214216
combineRetries [] = pure $ Unknown "retry limit is 0"
215217
combineRetries [r] = r

0 commit comments

Comments
 (0)