Skip to content

Commit be6592d

Browse files
Return vacuous in kore-rpc when state goes to #bottom (#3637)
Another attempt at addressing runtimeverification/evm-semantics#1944. Addresses #3630 (needs a follow-up in booster) This change mimicks what kore-exe in prover mode returns(as introduced by #2451), namely the configuration goes to bottom
1 parent a47444b commit be6592d

File tree

14 files changed

+3819
-30
lines changed

14 files changed

+3819
-30
lines changed

kore-rpc-types/src/Kore/JsonRpc/Types.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ data ExecuteState = ExecuteState
115115
data HaltReason
116116
= Branching
117117
| Stuck
118+
| Vacuous
118119
| DepthBound
119120
| CutPointRule
120121
| TerminalRule

kore/src/Kore/Exec.hs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ import Kore.Equation qualified as Equation (
7979
argument,
8080
requires,
8181
)
82+
import Kore.Exec.GraphTraversal (extractStuckTraversalResult)
8283
import Kore.Exec.GraphTraversal qualified as GraphTraversal
8384
import Kore.IndexedModule.IndexedModule (
8485
IndexedModule (..),
@@ -323,7 +324,7 @@ exec
323324
GraphTraversal.Ended results ->
324325
pure results
325326
GraphTraversal.GotStuck _ results ->
326-
pure results
327+
pure $ map extractStuckTraversalResult results
327328
GraphTraversal.Stopped results nexts -> do
328329
when (null nexts) $
329330
forM_ depthLimit warnDepthLimitExceeded
@@ -535,7 +536,8 @@ rpcExec
535536
toTransitionResult prior@RpcExecState{rpcProgState = priorPState} [] =
536537
case priorPState of
537538
Remaining _ -> GraphTraversal.Stuck prior
538-
Kore.Rewrite.Bottom -> GraphTraversal.Stuck prior
539+
-- this should not be reachable unless we received bottom as initial configuration?
540+
Kore.Rewrite.Bottom -> GraphTraversal.Vacuous prior
539541
-- returns `Final` to signal that no instructions were left.
540542
Start _ -> GraphTraversal.Final prior
541543
Rewritten _ -> GraphTraversal.Final prior
@@ -548,13 +550,13 @@ rpcExec
548550
GraphTraversal.Stop
549551
(setTraces rules priorRules next)
550552
[]
551-
toTransitionResult RpcExecState{rpcRules = priorRules} [(next@RpcExecState{rpcProgState = nextPState}, rules)] =
553+
toTransitionResult prior@RpcExecState{rpcRules = priorRules} [(next@RpcExecState{rpcProgState = nextPState}, rules)] =
552554
let next' = setTraces rules priorRules next
553555
in case nextPState of
554556
Start _ -> GraphTraversal.Continuing next'
555557
Rewritten _ -> GraphTraversal.Continuing next'
556558
Remaining _ -> GraphTraversal.Stuck next'
557-
Kore.Rewrite.Bottom -> GraphTraversal.Stuck next'
559+
Kore.Rewrite.Bottom -> GraphTraversal.Vacuous prior
558560
toTransitionResult prior (s : ss) =
559561
GraphTraversal.Branch prior $ fmap fst (s :| ss)
560562

kore/src/Kore/Exec/GraphTraversal.hs

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ module Kore.Exec.GraphTraversal (
1313
TraversalResult (..),
1414
transitionWithRule,
1515
GraphTraversalTimeoutMode (..),
16+
StuckTraversalResult (..),
17+
extractStuckTraversalResult,
1618
) where
1719

1820
import Control.Concurrent (
@@ -78,6 +80,8 @@ data TransitionResult a
7880
| -- | no next state but not final (e.g., not goal state, or side
7981
-- conditions do not hold)
8082
Stuck a
83+
| -- | the current configuration was simplified to bottom
84+
Vacuous a
8185
| -- | final state (e.g., goal state reached, side conditions hold)
8286
Final a
8387
| -- | not stuck, but also not final (maximum depth reached before
@@ -90,6 +94,7 @@ instance Functor TransitionResult where
9094
Continuing a -> Continuing $ f a
9195
Branch a as -> Branch (f a) $ NE.map f as
9296
Stuck a -> Stuck $ f a
97+
Vacuous a -> Vacuous $ f a
9398
Final a -> Final $ f a
9499
Stop a as -> Stop (f a) (map f as)
95100

@@ -98,6 +103,7 @@ instance Pretty a => Pretty (TransitionResult a) where
98103
Continuing a -> single "Continuing" a
99104
Branch a as -> multi "Branch" "node" a "successors" (NE.toList as)
100105
Stuck a -> single "Stuck" a
106+
Vacuous a -> single "Vacuous" a
101107
Final a -> single "Final" a
102108
Stop a as -> multi "Stop" "node" a "successors" as
103109
where
@@ -115,9 +121,10 @@ instance Pretty a => Pretty (TransitionResult a) where
115121
]
116122
<> map (Pretty.indent 4 . Pretty.pretty) as
117123

118-
isStuck, isFinal, isStop, isBranch :: TransitionResult a -> Bool
119-
isStuck (Stuck _) = True
120-
isStuck _ = False
124+
isStuckOrVacuous, isFinal, isStop, isBranch :: TransitionResult a -> Bool
125+
isStuckOrVacuous (Stuck _) = True
126+
isStuckOrVacuous (Vacuous _) = True
127+
isStuckOrVacuous _ = False
121128
isFinal (Final _) = True
122129
isFinal _ = False
123130
isStop (Stop _ _) = True
@@ -130,6 +137,7 @@ extractNext = \case
130137
Continuing a -> [a]
131138
Branch _ as -> NE.toList as
132139
Stuck _ -> []
140+
Vacuous _ -> []
133141
Final _ -> []
134142
Stop _ as -> as
135143

@@ -138,9 +146,16 @@ extractState = \case
138146
Continuing _ -> Nothing
139147
Branch a _ -> Just a
140148
Stuck a -> Just a
149+
Vacuous a -> Just a
141150
Final a -> Just a
142151
Stop a _ -> Just a
143152

153+
extractStuckOrVacuous :: TransitionResult a -> Maybe (StuckTraversalResult a)
154+
extractStuckOrVacuous = \case
155+
Stuck a -> Just $ IsStuck a
156+
Vacuous a -> Just $ IsVacuous a
157+
_ -> Nothing
158+
144159
{- | The traversal state, including subsequent steps to take in the
145160
traversal.
146161
-}
@@ -239,7 +254,7 @@ graphTraversal
239254
ma <- liftIO newEmptyMVar
240255
enqueue [TState steps start] Seq.empty
241256
>>= either
242-
(pure . const (GotStuck 0 [start]))
257+
(pure . const (GotStuck 0 [IsStuck start]))
243258
(\q -> evalStateT (worker ma q >>= checkLeftUnproven) [])
244259
where
245260
enqueue' = unfoldSearchOrder direction
@@ -287,14 +302,14 @@ graphTraversal
287302
Continue nextQ -> worker ma nextQ
288303
Output oneResult nextQ -> do
289304
modify (oneResult :)
290-
if not (isStuck oneResult)
305+
if not (isStuckOrVacuous oneResult)
291306
then worker ma nextQ
292307
else do
293-
stuck <- gets (filter isStuck)
308+
stuck <- gets (filter isStuckOrVacuous)
294309
if maxCounterExamples <= Limit (fromIntegral (length stuck))
295310
then
296311
pure $
297-
GotStuck (Seq.length nextQ) (mapMaybe extractState stuck)
312+
GotStuck (Seq.length nextQ) (mapMaybe extractStuckOrVacuous stuck)
298313
else worker ma nextQ
299314
Abort _lastState queue -> do
300315
pure $ Aborted $ toList queue
@@ -337,7 +352,7 @@ graphTraversal
337352
Simplifier (StepResult (TState instr config))
338353
step a q = do
339354
next <- branchStop <$> transit a
340-
if (isStuck next || isFinal next || isStop next)
355+
if (isStuckOrVacuous next || isFinal next || isStop next)
341356
then pure (Output next q)
342357
else
343358
let abort (LimitExceeded queue) = Abort next queue
@@ -353,7 +368,7 @@ graphTraversal
353368
result@(Ended{}) -> do
354369
collected <- gets reverse
355370
-- we collect a maximum of 'maxCounterExamples' Stuck states
356-
let stuck = map (fmap currentState) $ filter isStuck collected
371+
let stuck = map (fmap currentState) $ filter isStuckOrVacuous collected
357372
-- Other states may be unfinished but not stuck (Stop)
358373
-- Only provide the requested amount of states (maxCounterExamples)
359374
let unproven =
@@ -362,7 +377,7 @@ graphTraversal
362377
pure $
363378
if
364379
| (not $ null stuck) ->
365-
GotStuck 0 (mapMaybe extractState stuck)
380+
GotStuck 0 (mapMaybe extractStuckOrVacuous stuck)
366381
| not $ null unproven ->
367382
Stopped
368383
(mapMaybe extractState unproven)
@@ -394,10 +409,28 @@ data StepResult a
394409
Timeout a (Seq a)
395410
deriving stock (Eq, Show)
396411

412+
data StuckTraversalResult a = IsStuck a | IsVacuous a
413+
deriving stock (Eq, Show)
414+
deriving stock (GHC.Generics.Generic, Functor)
415+
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
416+
417+
instance Debug a => Debug (StuckTraversalResult a)
418+
instance (Debug a, Diff a) => Diff (StuckTraversalResult a)
419+
420+
instance Pretty a => Pretty (StuckTraversalResult a) where
421+
pretty = \case
422+
IsStuck a -> pretty a
423+
IsVacuous a -> "(vacuous)" <+> pretty a
424+
425+
extractStuckTraversalResult :: StuckTraversalResult a -> a
426+
extractStuckTraversalResult = \case
427+
IsStuck a -> a
428+
IsVacuous a -> a
429+
397430
data TraversalResult a
398431
= -- | remaining queue length and stuck results (always at most
399432
-- maxCounterExamples many).
400-
GotStuck Int [a]
433+
GotStuck Int [StuckTraversalResult a]
401434
| -- | queue (length exceeding the limit), including result(s) of
402435
-- the last step that led to stopping.
403436
Aborted [a]
@@ -438,7 +471,7 @@ instance Pretty a => Pretty (TraversalResult a) where
438471
: ("Queue" : map Pretty.pretty qu)
439472
instance Functor TraversalResult where
440473
fmap f = \case
441-
GotStuck n rs -> GotStuck n (map f rs)
474+
GotStuck n rs -> GotStuck n (map (fmap f) rs)
442475
Aborted rs -> Aborted (map f rs)
443476
Ended rs -> Ended (map f rs)
444477
Stopped rs qu -> Stopped (map f rs) (map f qu)

kore/src/Kore/JsonRpc.hs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,9 @@ respond serverState moduleName runSMT =
211211
}
212212
GraphTraversal.GotStuck
213213
_n
214-
[Exec.RpcExecState{rpcDepth = ExecDepth depth, rpcProgState = result, rpcRules = rules}] ->
214+
[ GraphTraversal.IsStuck
215+
Exec.RpcExecState{rpcDepth = ExecDepth depth, rpcProgState = result, rpcRules = rules}
216+
] ->
215217
Right $
216218
Execute $
217219
ExecuteResult
@@ -222,6 +224,21 @@ respond serverState moduleName runSMT =
222224
, nextStates = Nothing
223225
, logs = mkLogs rules
224226
}
227+
GraphTraversal.GotStuck
228+
_n
229+
[ GraphTraversal.IsVacuous
230+
Exec.RpcExecState{rpcDepth = ExecDepth depth, rpcProgState = result, rpcRules = rules}
231+
] ->
232+
Right $
233+
Execute $
234+
ExecuteResult
235+
{ state = patternToExecState sort result
236+
, depth = Depth depth
237+
, reason = Vacuous
238+
, rule = Nothing
239+
, nextStates = Nothing
240+
, logs = mkLogs rules
241+
}
225242
GraphTraversal.Stopped
226243
[Exec.RpcExecState{rpcDepth = ExecDepth depth, rpcProgState, rpcRules = rules}]
227244
nexts

kore/src/Kore/Reachability/Prove.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import GHC.Generics qualified as GHC
5555
import Generics.SOP qualified as SOP
5656
import Kore.Attribute.Axiom qualified as Attribute.Axiom
5757
import Kore.Debug
58+
import Kore.Exec.GraphTraversal (extractStuckTraversalResult)
5859
import Kore.Exec.GraphTraversal qualified as GraphTraversal
5960
import Kore.Internal.Conditional (
6061
Conditional (..),
@@ -399,7 +400,7 @@ proveClaim
399400

400401
case traversalResult of
401402
GraphTraversal.GotStuck n rs ->
402-
returnUnprovenClaims n rs
403+
returnUnprovenClaims n $ map extractStuckTraversalResult rs
403404
GraphTraversal.Stopped rs nexts ->
404405
returnUnprovenClaims (length nexts) rs
405406
GraphTraversal.Aborted rs ->

kore/src/Kore/Rewrite.hs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,26 +176,23 @@ transitionRule ::
176176
(ProgramState (Pattern RewritingVariableName))
177177
transitionRule rewriteGroups = transitionRuleWorker
178178
where
179+
transitionRuleWorker _ Simplify Bottom = pure Bottom
180+
transitionRuleWorker _ _ Bottom = empty
179181
transitionRuleWorker _ Begin (Rewritten a) = pure $ Start a
180182
transitionRuleWorker _ Begin (Remaining _) = empty
181183
transitionRuleWorker _ Begin state@(Start _) = pure state
182-
transitionRuleWorker _ Begin Bottom = empty
183184
transitionRuleWorker _ Simplify (Rewritten patt) =
184185
transitionSimplify Rewritten patt
185186
transitionRuleWorker _ Simplify (Remaining patt) =
186187
transitionSimplify Remaining patt
187188
transitionRuleWorker _ Simplify (Start patt) =
188189
transitionSimplify Start patt
189-
transitionRuleWorker _ Simplify Bottom =
190-
empty
191190
transitionRuleWorker mode Rewrite (Remaining patt) =
192191
transitionRewrite mode patt
193192
transitionRuleWorker mode Rewrite (Start patt) =
194193
transitionRewrite mode patt
195194
transitionRuleWorker _ Rewrite state@(Rewritten _) =
196195
pure state
197-
transitionRuleWorker _ Rewrite Bottom =
198-
empty
199196

200197
transitionSimplify prim config = do
201198
configs <- lift $ Pattern.simplifyTopConfiguration config
@@ -230,7 +227,7 @@ deriveResults ::
230227
Result.Results (w (RulePattern variable)) a ->
231228
TransitionT (RewriteRule variable, Seq SimplifierTrace) Simplifier (ProgramState a)
232229
deriveResults Result.Results{results, remainders} =
233-
if null results && null remainders
230+
if (null results || all (\Result.Result{result} -> null result) results) && null remainders
234231
then pure Bottom
235232
else addResults results <|> addRemainders remainders
236233
where

kore/test/Test/Kore/Exec.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import Kore.Equation.Equation (
4747
)
4848
import Kore.Error qualified
4949
import Kore.Exec
50-
import Kore.Exec.GraphTraversal (TraversalResult (..))
50+
import Kore.Exec.GraphTraversal (StuckTraversalResult (..), TraversalResult (..))
5151
import Kore.IndexedModule.IndexedModule
5252
import Kore.Internal.ApplicationSorts
5353
import Kore.Internal.Pattern (
@@ -201,15 +201,15 @@ test_rpcExecDepth =
201201
[ testCase "without depth limit" $ do
202202
result <-
203203
runDepth $ rpcExecTest [] [] Unlimited verifiedModule (state "c")
204-
assertEqual "depth" (stuckAt 2) result
204+
assertEqual "depth" (stuckAt $ IsStuck 2) result
205205
, testCase "with depth limit limiting execution" $ do
206206
result <-
207207
runDepth $ rpcExecTest [] [] (Limit 1) verifiedModule (state "c")
208208
assertEqual "depth" (endsAt 1) result
209209
, testCase "with depth limit above execution limit" $ do
210210
result <-
211211
runDepth $ rpcExecTest [] [] (Limit 3) verifiedModule (state "c")
212-
assertEqual "depth" (stuckAt 2) result
212+
assertEqual "depth" (stuckAt $ IsStuck 2) result
213213
, testCase "when branching" $ do
214214
result <-
215215
runDepth $ rpcExecTest [] [] Unlimited verifiedModule (state "a")

test/kevm-optimism-invariant/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ DEF_KORE =
22
include $(CURDIR)/../include.mk
33

44
test-%.sh.out: $(TEST_DIR)/test-%-*
5-
KORE_EXEC_OPTS += --smt-timeout 100
5+
KORE_EXEC_OPTS += --smt-timeout 125

test/kevm-optimism-invariant/test-optimism-invariant.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ exec kore-exec \
55
--module FOUNDRY-MAIN \
66
--strategy all \
77
--max-counterexamples 1 \
8-
--smt-retry-limit 1 \
8+
--smt-retry-limit 4 \
99
--smt-reset-interval 100 \
1010
--smt z3 \
1111
--log-level \

test/regression-wasm/test-wrc20.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
#!/bin/sh
2-
${KORE_EXEC:?} test-wrc20-vdefinition.kore --module WRC20-LEMMAS --prove test-wrc20-spec.kore --spec-module WRC20-SPEC "$@"
2+
${KORE_EXEC:?} test-wrc20-vdefinition.kore --module WRC20-LEMMAS --prove test-wrc20-spec.kore --spec-module WRC20-SPEC --smt-timeout 40 --smt-retry-limit 1 --smt-reset-interval 100 "$@"

0 commit comments

Comments
 (0)