Skip to content

Commit 2af5206

Browse files
committed
kevm-pyk/__main__: fall back to manual branch extraction using haskell backend
1 parent 54882e7 commit 2af5206

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,11 +9,11 @@
99
from pyk.cli_utils import dir_path, file_path
1010
from pyk.cterm import CTerm
1111
from pyk.kast import KApply, KAtt, KDefinition, KFlatModule, KImport, KInner, KRequire, KRewrite, KRule, KToken
12-
from pyk.kastManip import minimize_term, push_down_rewrites
12+
from pyk.kastManip import flatten_label, minimize_term, push_down_rewrites
1313
from pyk.kcfg import KCFG
1414
from pyk.ktool.kit import KIT
1515
from pyk.ktool.krun import _krun
16-
from pyk.prelude.ml import mlTop
16+
from pyk.prelude.ml import mlAnd, mlTop
1717
from pyk.utils import shorten_hashes
1818

1919
from .gst_to_kore import gst_to_kore
@@ -374,7 +374,7 @@ def prove_it(id_and_cfg: Tuple[str, Tuple[KCFG, Path]]) -> bool:
374374
_LOGGER.info(f'Advancing proof from node {cfgid}: {shorten_hashes(curr_node.id)}')
375375
edge = KCFG.Edge(curr_node, target_node, mlTop(), -1)
376376
claim = edge.to_claim()
377-
claim_id = f'gen-{curr_node.id}-to-{target_node.id}'
377+
claim_id = f'gen-block-{curr_node.id}-to-{target_node.id}'
378378
depth, branching, result = foundry.get_claim_basic_block(
379379
claim_id, claim, lemmas=lemma_rules, max_depth=max_depth
380380
)
@@ -389,31 +389,49 @@ def prove_it(id_and_cfg: Tuple[str, Tuple[KCFG, Path]]) -> bool:
389389
next_state = CTerm(sanitize_config(foundry.definition, result))
390390
next_node = cfg.get_or_create_node(next_state)
391391
if next_node != curr_node:
392-
_LOGGER.info(f'Found basic block at depth {depth} for {cfgid}: {shorten_hashes((curr_node.id, next_node.id))}.')
392+
_LOGGER.info(
393+
f'Found basic block at depth {depth} for {cfgid}: {shorten_hashes((curr_node.id, next_node.id))}.'
394+
)
393395
cfg.create_edge(curr_node.id, next_node.id, mlTop(), depth)
394396

395397
if KEVM.is_terminal(next_node.cterm):
396398
cfg.add_expanded(next_node.id)
397399
_LOGGER.info(f'Terminal node {cfgid}: {shorten_hashes((curr_node.id))}.')
398400

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

418436
_write_cfg(cfg, cfgpath)
419437

0 commit comments

Comments
 (0)