Skip to content

Commit 4de886e

Browse files
committed
kevm-pyk/__main__: fall back to manual branch extraction using haskell backend
1 parent 25ae6e2 commit 4de886e

File tree

1 file changed

+37
-19
lines changed

1 file changed

+37
-19
lines changed

kevm-pyk/src/kevm_pyk/__main__.py

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
from pyk.cli_utils import dir_path, file_path
1010
from pyk.cterm import CTerm
1111
from pyk.kast.inner import KApply, KAtt, KInner, KRewrite, KToken
12-
from pyk.kast.manip import minimize_term, push_down_rewrites
12+
from pyk.kast.manip import flatten_label, minimize_term, push_down_rewrites
1313
from pyk.kast.outer import KDefinition, KFlatModule, KImport, KRequire, KRule
1414
from pyk.kcfg import KCFG
1515
from pyk.ktool.kit import KIT
1616
from pyk.ktool.krun import KRunOutput, _krun
17-
from pyk.prelude.ml import mlTop
17+
from pyk.prelude.ml import mlAnd, mlTop
1818
from pyk.utils import shorten_hashes
1919

2020
from .gst_to_kore import gst_to_kore
@@ -380,7 +380,7 @@ def prove_it(id_and_cfg: Tuple[str, Tuple[KCFG, Path]]) -> bool:
380380
_LOGGER.info(f'Advancing proof from node {cfgid}: {shorten_hashes(curr_node.id)}')
381381
edge = KCFG.Edge(curr_node, target_node, mlTop(), -1)
382382
claim = edge.to_claim()
383-
claim_id = f'gen-{curr_node.id}-to-{target_node.id}'
383+
claim_id = f'gen-block-{curr_node.id}-to-{target_node.id}'
384384
depth, branching, result = foundry.get_claim_basic_block(
385385
claim_id, claim, lemmas=lemma_rules, max_depth=max_depth
386386
)
@@ -395,31 +395,49 @@ def prove_it(id_and_cfg: Tuple[str, Tuple[KCFG, Path]]) -> bool:
395395
next_state = CTerm(sanitize_config(foundry.definition, result))
396396
next_node = cfg.get_or_create_node(next_state)
397397
if next_node != curr_node:
398-
_LOGGER.info(f'Found basic block at depth {depth} for {cfgid}: {shorten_hashes((curr_node.id, next_node.id))}.')
398+
_LOGGER.info(
399+
f'Found basic block at depth {depth} for {cfgid}: {shorten_hashes((curr_node.id, next_node.id))}.'
400+
)
399401
cfg.create_edge(curr_node.id, next_node.id, mlTop(), depth)
400402

401403
if KEVM.is_terminal(next_node.cterm):
402404
cfg.add_expanded(next_node.id)
403405
_LOGGER.info(f'Terminal node {cfgid}: {shorten_hashes((curr_node.id))}.')
404406

405407
elif branching:
408+
cfg.add_expanded(next_node.id)
406409
branches = KEVM.extract_branches(next_state)
407-
if not branches:
408-
raise ValueError(
409-
f'Could not extract branch condition {cfgid}:\n{foundry.pretty_print(minimize_term(result))}'
410+
if len(list(branches)) > 0:
411+
_LOGGER.info(
412+
f'Found {len(list(branches))} branches at depth {depth} for {cfgid}: {[foundry.pretty_print(b) for b in branches]}'
410413
)
411-
cfg.add_expanded(next_node.id)
412-
_LOGGER.info(
413-
f'Found {len(list(branches))} branches at depth {depth} for {cfgid}: {[foundry.pretty_print(b) for b in branches]}'
414-
)
415-
for branch in branches:
416-
branch_cterm = next_state.add_constraint(branch)
417-
branch_node = cfg.get_or_create_node(branch_cterm)
418-
cfg.create_edge(next_node.id, branch_node.id, branch, 0)
419-
_LOGGER.info(f'Made split for {cfgid}: {shorten_hashes((next_node.id, branch_node.id))}')
420-
# TODO: have to store case splits as rewrites because of how frontier is handled for covers
421-
# cfg.create_cover(branch_node.id, next_node.id)
422-
# _LOGGER.info(f'Made cover: {shorten_hashes((branch_node.id, next_node.id))}')
414+
for branch in branches:
415+
branch_cterm = next_state.add_constraint(branch)
416+
branch_node = cfg.get_or_create_node(branch_cterm)
417+
cfg.create_edge(next_node.id, branch_node.id, branch, 0)
418+
_LOGGER.info(f'Made split for {cfgid}: {shorten_hashes((next_node.id, branch_node.id))}')
419+
# TODO: have to store case splits as rewrites because of how frontier is handled for covers
420+
# cfg.create_cover(branch_node.id, next_node.id)
421+
# _LOGGER.info(f'Made cover: {shorten_hashes((branch_node.id, next_node.id))}')
422+
else:
423+
_LOGGER.warning(
424+
f'Falling back to running backend for branch extraction {cfgid}:\n{foundry.pretty_print(minimize_term(result))}'
425+
)
426+
edge = KCFG.Edge(next_node, target_node, mlTop(), -1)
427+
claim = edge.to_claim()
428+
claim_id = f'gen-branch-{curr_node.id}-to-{target_node.id}'
429+
result = foundry.prove_claim(claim, claim_id, lemmas=lemma_rules, args=['--depth', '1'])
430+
branch_cterms = [CTerm(r) for r in flatten_label('#Or', result)]
431+
old_constraints = next_state.constraints
432+
new_constraints = [
433+
[c for c in s.constraints if c not in old_constraints] for s in branch_cterms
434+
]
435+
_LOGGER.info(
436+
f'Found {len(list(branch_cterms))} branches manually ad depth 1 for {cfgid}: {[foundry.pretty_print(mlAnd(nc)) for nc in new_constraints]}'
437+
)
438+
for ns, nc in zip(branch_cterms, new_constraints):
439+
branch_node = cfg.get_or_create_node(ns)
440+
cfg.create_edge(next_node.id, branch_node.id, mlAnd(nc), 1)
423441

424442
_write_cfg(cfg, cfgpath)
425443

0 commit comments

Comments
 (0)