9
9
from pyk .cli_utils import dir_path , file_path
10
10
from pyk .cterm import CTerm
11
11
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
13
13
from pyk .kast .outer import KDefinition , KFlatModule , KImport , KRequire , KRule
14
14
from pyk .kcfg import KCFG
15
15
from pyk .ktool .kit import KIT
16
16
from pyk .ktool .krun import KRunOutput , _krun
17
- from pyk .prelude .ml import mlTop
17
+ from pyk .prelude .ml import mlAnd , mlTop
18
18
from pyk .utils import shorten_hashes
19
19
20
20
from .gst_to_kore import gst_to_kore
@@ -380,7 +380,7 @@ def prove_it(id_and_cfg: Tuple[str, Tuple[KCFG, Path]]) -> bool:
380
380
_LOGGER .info (f'Advancing proof from node { cfgid } : { shorten_hashes (curr_node .id )} ' )
381
381
edge = KCFG .Edge (curr_node , target_node , mlTop (), - 1 )
382
382
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 } '
384
384
depth , branching , result = foundry .get_claim_basic_block (
385
385
claim_id , claim , lemmas = lemma_rules , max_depth = max_depth
386
386
)
@@ -395,31 +395,49 @@ def prove_it(id_and_cfg: Tuple[str, Tuple[KCFG, Path]]) -> bool:
395
395
next_state = CTerm (sanitize_config (foundry .definition , result ))
396
396
next_node = cfg .get_or_create_node (next_state )
397
397
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
+ )
399
401
cfg .create_edge (curr_node .id , next_node .id , mlTop (), depth )
400
402
401
403
if KEVM .is_terminal (next_node .cterm ):
402
404
cfg .add_expanded (next_node .id )
403
405
_LOGGER .info (f'Terminal node { cfgid } : { shorten_hashes ((curr_node .id ))} .' )
404
406
405
407
elif branching :
408
+ cfg .add_expanded (next_node .id )
406
409
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 ] } '
410
413
)
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 )
423
441
424
442
_write_cfg (cfg , cfgpath )
425
443
0 commit comments