9
9
from pyk .cli_utils import dir_path , file_path
10
10
from pyk .cterm import CTerm
11
11
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
13
13
from pyk .kcfg import KCFG
14
14
from pyk .ktool .kit import KIT
15
15
from pyk .ktool .krun import _krun
16
- from pyk .prelude .ml import mlTop
16
+ from pyk .prelude .ml import mlAnd , mlTop
17
17
from pyk .utils import shorten_hashes
18
18
19
19
from .gst_to_kore import gst_to_kore
@@ -374,7 +374,7 @@ def prove_it(id_and_cfg: Tuple[str, Tuple[KCFG, Path]]) -> bool:
374
374
_LOGGER .info (f'Advancing proof from node { cfgid } : { shorten_hashes (curr_node .id )} ' )
375
375
edge = KCFG .Edge (curr_node , target_node , mlTop (), - 1 )
376
376
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 } '
378
378
depth , branching , result = foundry .get_claim_basic_block (
379
379
claim_id , claim , lemmas = lemma_rules , max_depth = max_depth
380
380
)
@@ -389,31 +389,49 @@ def prove_it(id_and_cfg: Tuple[str, Tuple[KCFG, Path]]) -> bool:
389
389
next_state = CTerm (sanitize_config (foundry .definition , result ))
390
390
next_node = cfg .get_or_create_node (next_state )
391
391
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
+ )
393
395
cfg .create_edge (curr_node .id , next_node .id , mlTop (), depth )
394
396
395
397
if KEVM .is_terminal (next_node .cterm ):
396
398
cfg .add_expanded (next_node .id )
397
399
_LOGGER .info (f'Terminal node { cfgid } : { shorten_hashes ((curr_node .id ))} .' )
398
400
399
401
elif branching :
402
+ cfg .add_expanded (next_node .id )
400
403
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 ] } '
404
407
)
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 )
417
435
418
436
_write_cfg (cfg , cfgpath )
419
437
0 commit comments