Skip to content

Commit 7ecea69

Browse files
Retry SMT query once if it fails (#2224)
* Retry SMT query once if it fails * checkPredicate: only run SMT.check * decidePredicate: Restart query after first failure * Clean-up: remove empty * Clean-up: use MaybeT instance of MonadSMT * Update kore/src/Kore/Log/ErrorDecidePredicateUnknown.hs Co-authored-by: Thomas Tuegel <[email protected]> * Update WarnRetrySolverQuery.hs Co-authored-by: Thomas Tuegel <[email protected]>
1 parent 11e10fb commit 7ecea69

File tree

4 files changed

+109
-15
lines changed

4 files changed

+109
-15
lines changed

kore/src/Kore/Log/ErrorDecidePredicateUnknown.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ instance Entry ErrorDecidePredicateUnknown where
5858
errorDecidePredicateUnknown
5959
:: InternalVariable variable
6060
=> NonEmpty (Predicate variable)
61-
-> log ()
61+
-> log a
6262
errorDecidePredicateUnknown predicates' =
6363
throw ErrorDecidePredicateUnknown { predicates }
6464
where

kore/src/Kore/Log/Registry.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ import Kore.Log.WarnFunctionWithoutEvaluators
101101
import Kore.Log.WarnIfLowProductivity
102102
( WarnIfLowProductivity
103103
)
104+
import Kore.Log.WarnRetrySolverQuery
105+
( WarnRetrySolverQuery
106+
)
104107
import Kore.Log.WarnStuckClaimState
105108
( WarnStuckClaimState
106109
)
@@ -160,6 +163,7 @@ entryHelpDocs :: [Pretty.Doc ()]
160163
, mk $ Proxy @WarnStuckClaimState
161164
, mk $ Proxy @WarnIfLowProductivity
162165
, mk $ Proxy @WarnTrivialClaim
166+
, mk $ Proxy @WarnRetrySolverQuery
163167
, mk $ Proxy @DebugEvaluateCondition
164168
, mk $ Proxy @ErrorException
165169
, mk $ Proxy @ErrorRewriteLoop
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{- |
2+
Copyright : (c) Runtime Verification, 2020
3+
License : NCSA
4+
5+
-}
6+
7+
module Kore.Log.WarnRetrySolverQuery
8+
( WarnRetrySolverQuery
9+
, warnRetrySolverQuery
10+
) where
11+
12+
import Prelude.Kore
13+
14+
import Kore.Internal.Predicate
15+
( Predicate
16+
)
17+
import qualified Kore.Internal.Predicate as Predicate
18+
import Kore.Internal.Variable
19+
( InternalVariable
20+
, VariableName
21+
, toVariableName
22+
)
23+
import Kore.Unparser
24+
( unparse
25+
)
26+
import Log
27+
import Pretty
28+
( Pretty (..)
29+
)
30+
import qualified Pretty
31+
32+
newtype WarnRetrySolverQuery =
33+
WarnRetrySolverQuery
34+
{ predicates :: NonEmpty (Predicate VariableName) }
35+
deriving (Show)
36+
37+
instance Pretty WarnRetrySolverQuery where
38+
pretty WarnRetrySolverQuery { predicates } =
39+
Pretty.vsep $
40+
[ "The SMT solver initially failed to solve the following query:"
41+
, Pretty.indent 2 "Decide predicate:"
42+
, Pretty.indent 4 (unparse predicate)
43+
, Pretty.indent 2 "with side conditions:"
44+
]
45+
<> fmap (Pretty.indent 4 . unparse) sideConditions
46+
<> ["The SMT solver was reset and the query\
47+
\ was tried one more time."
48+
]
49+
where
50+
predicate :| sideConditions = predicates
51+
52+
instance Entry WarnRetrySolverQuery where
53+
entrySeverity _ = Warning
54+
helpDoc _ =
55+
"warning raised when the solver failed to decide\
56+
\ the satisfiability of a formula, indicating that\
57+
\ the solver was reset and the formula retried"
58+
59+
warnRetrySolverQuery
60+
:: InternalVariable variable
61+
=> MonadLog log
62+
=> NonEmpty (Predicate variable)
63+
-> log ()
64+
warnRetrySolverQuery predicates' =
65+
logEntry WarnRetrySolverQuery { predicates }
66+
where
67+
predicates =
68+
Predicate.mapVariables (pure toVariableName) <$> predicates'

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

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ module Kore.Step.SMT.Evaluator
1818
import Prelude.Kore
1919

2020
import Control.Error
21-
( hoistMaybe
21+
( MaybeT
22+
, hoistMaybe
2223
, runMaybeT
2324
)
2425
import qualified Control.Lens as Lens
@@ -65,6 +66,9 @@ import Kore.Log.DebugEvaluateCondition
6566
import Kore.Log.ErrorDecidePredicateUnknown
6667
( errorDecidePredicateUnknown
6768
)
69+
import Kore.Log.WarnRetrySolverQuery
70+
( warnRetrySolverQuery
71+
)
6872
import Kore.Step.Simplification.Simplify as Simplifier
6973
import Kore.Step.SMT.Translate
7074
import Kore.TopBottom
@@ -172,19 +176,37 @@ decidePredicate
172176
=> NonEmpty (Predicate variable)
173177
-> simplifier (Maybe Bool)
174178
decidePredicate predicates =
175-
whileDebugEvaluateCondition predicates
176-
$ SMT.withSolver $ runMaybeT $ evalTranslator $ do
177-
tools <- Simplifier.askMetadataTools
178-
predicates' <- traverse (translatePredicate tools) predicates
179-
Foldable.traverse_ SMT.assert predicates'
180-
result <- SMT.check
181-
debugEvaluateConditionResult result
182-
case result of
183-
Unsat -> return False
184-
Sat -> empty
185-
Unknown -> do
186-
errorDecidePredicateUnknown predicates
187-
empty
179+
whileDebugEvaluateCondition predicates go
180+
where
181+
go =
182+
do
183+
result <- query >>= whenUnknown retry
184+
debugEvaluateConditionResult result
185+
case result of
186+
Unsat -> return False
187+
Sat -> empty
188+
Unknown ->
189+
errorDecidePredicateUnknown predicates
190+
& runMaybeT
191+
192+
whenUnknown f Unknown = f
193+
whenUnknown _ result = return result
194+
195+
-- | Run the SMT query once.
196+
query :: MaybeT simplifier Result
197+
query =
198+
SMT.withSolver $ evalTranslator $ do
199+
tools <- Simplifier.askMetadataTools
200+
predicates' <- traverse (translatePredicate tools) predicates
201+
Foldable.traverse_ SMT.assert predicates'
202+
SMT.check
203+
204+
-- | Re-run the SMT query.
205+
retry = do
206+
SMT.reinit
207+
result <- query
208+
warnRetrySolverQuery predicates
209+
return result
188210

189211
translatePredicate
190212
:: forall variable m.

0 commit comments

Comments
 (0)