Skip to content

Commit 650a620

Browse files
authored
Refactors to simplify import structure (#1019)
* src/kontrol/{utils,solc_to_k,state_record,prove}: move hex_string_to_int from solc_to_k to utils * kontrol/cli: direct imports instead of through prove * kontrol/{options,cli,__main__}: remove kontrol compile command * kontrol/solc_to_k: remove now unused method * kontrol/{cli,options,foundry,__main__}: remove kontrol to-dot command * kontrol/{foundry,__main__}: factor out foundry_view command similar to foundry_show * kontrol/{foundry,__main__}: demote hevm import to foundry instead of __main__ with refactor * kontrol/{hevm,foundry}: inline Hevm.help_info into Foundry.help_info * kontrol/{hevm,prove,foundry}: inline Hevm.{success,fail} directly into Foundry class * kontrol/foundry: use Foundry directly for parsing instead of buliding foundry_node_printer
1 parent 043339b commit 650a620

File tree

9 files changed

+61
-214
lines changed

9 files changed

+61
-214
lines changed

src/kontrol/__main__.py

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import annotations
22

3-
import json
43
import logging
54
import sys
65
from collections.abc import Iterable
@@ -9,7 +8,6 @@
98
from pyk.cli.pyk import parse_toml_args
109
from pyk.cterm.symbolic import CTermSMTError
1110
from pyk.proof.reachability import APRFailureInfo, APRProof
12-
from pyk.proof.tui import APRProofViewer
1311

1412
from . import VERSION
1513
from .cli import _create_argument_parser, generate_options, get_argument_type_setter, get_option_string_destination
@@ -20,7 +18,6 @@
2018
foundry_list,
2119
foundry_merge_nodes,
2220
foundry_minimize_proof,
23-
foundry_node_printer,
2421
foundry_refute_node,
2522
foundry_remove_node,
2623
foundry_section_edge,
@@ -29,30 +26,25 @@
2926
foundry_split_node,
3027
foundry_state_load,
3128
foundry_step_node,
32-
foundry_to_dot,
3329
foundry_unrefute_node,
30+
foundry_view,
3431
init_project,
3532
read_recorded_state_diff,
3633
read_recorded_state_dump,
3734
)
38-
from .hevm import Hevm
3935
from .kompile import foundry_kompile
4036
from .prove import foundry_prove
41-
from .solc import CompilationUnit
42-
from .solc_to_k import solc_compile
4337
from .utils import _LOG_FORMAT, _rv_blue, _rv_yellow, check_k_version, config_file_path, console, loglevel
4438

4539
if TYPE_CHECKING:
4640
from pathlib import Path
4741
from typing import Final, TypeVar
4842

49-
from pyk.kcfg.tui import KCFGElem
5043
from pyk.utils import BugReport
5144

5245
from .options import (
5346
BuildOptions,
5447
CleanOptions,
55-
CompileOptions,
5648
GetModelOptions,
5749
InitOptions,
5850
ListOptions,
@@ -67,7 +59,6 @@
6759
SimplifyNodeOptions,
6860
SplitNodeOptions,
6961
StepNodeOptions,
70-
ToDotOptions,
7162
UnrefuteNodeOptions,
7263
VersionOptions,
7364
ViewKcfgOptions,
@@ -142,11 +133,6 @@ def exec_version(options: VersionOptions) -> None:
142133
print(f'Kontrol version: {VERSION}')
143134

144135

145-
def exec_compile(options: CompileOptions) -> None:
146-
res = solc_compile(options.contract_file)
147-
print(json.dumps(res))
148-
149-
150136
def exec_build(options: BuildOptions) -> None:
151137
_LOGGER.debug(options)
152138

@@ -228,7 +214,7 @@ def exec_prove(options: ProveOptions) -> None:
228214
if isinstance(proof, APRProof) and isinstance(proof.failure_info, APRFailureInfo):
229215
failure_log = proof.failure_info
230216
if options.failure_info and failure_log is not None:
231-
log = failure_log.print() + (Foundry.help_info() if not options.hevm else Hevm.help_info(proof.id))
217+
log = failure_log.print() + Foundry.help_info(proof.id, options.hevm)
232218
for line in log:
233219
print(line)
234220
refuted_nodes = list(proof.node_refutations.keys())
@@ -281,13 +267,6 @@ def exec_split_node(options: SplitNodeOptions) -> None:
281267
print(f'Node {options.node} has been split into {node_ids} on condition {options.branch_condition}.')
282268

283269

284-
def exec_to_dot(options: ToDotOptions) -> None:
285-
foundry_to_dot(
286-
foundry=_load_foundry(options.foundry_root, add_enum_constraints=options.enum_constraints),
287-
options=options,
288-
)
289-
290-
291270
def exec_list(options: ListOptions) -> None:
292271
stats = foundry_list(foundry=_load_foundry(options.foundry_root, add_enum_constraints=options.enum_constraints))
293272
print('\n'.join(stats))
@@ -297,18 +276,7 @@ def exec_view_kcfg(options: ViewKcfgOptions) -> None:
297276
foundry = _load_foundry(
298277
options.foundry_root, use_hex_encoding=options.use_hex_encoding, add_enum_constraints=options.enum_constraints
299278
)
300-
test_id = foundry.get_test_id(options.test, options.version)
301-
contract_name, _ = test_id.split('.')
302-
proof = foundry.get_apr_proof(test_id)
303-
304-
compilation_unit = CompilationUnit.load_build_info(foundry.build_info)
305-
306-
def _custom_view(elem: KCFGElem) -> Iterable[str]:
307-
return foundry.custom_view(contract_name, elem, compilation_unit)
308-
309-
node_printer = foundry_node_printer(foundry, contract_name, proof)
310-
viewer = APRProofViewer(proof, foundry.kevm, node_printer=node_printer, custom_view=_custom_view)
311-
viewer.run()
279+
foundry_view(foundry, options)
312280

313281

314282
def exec_minimize_proof(options: MinimizeProofOptions) -> None:

src/kontrol/cli.py

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from .options import (
1414
BuildOptions,
1515
CleanOptions,
16-
CompileOptions,
16+
ConfigType,
1717
GetModelOptions,
1818
InitOptions,
1919
ListOptions,
@@ -28,12 +28,11 @@
2828
SimplifyNodeOptions,
2929
SplitNodeOptions,
3030
StepNodeOptions,
31-
ToDotOptions,
3231
UnrefuteNodeOptions,
3332
VersionOptions,
3433
ViewKcfgOptions,
3534
)
36-
from .prove import ConfigType, parse_test_version_tuple
35+
from .utils import parse_test_version_tuple
3736

3837
if TYPE_CHECKING:
3938
from collections.abc import Callable
@@ -49,14 +48,12 @@ def generate_options(args: dict[str, Any]) -> LoggingOptions:
4948
options = {
5049
'load-state': LoadStateOptions(args),
5150
'version': VersionOptions(args),
52-
'compile': CompileOptions(args),
5351
'build': BuildOptions(args),
5452
'prove': ProveOptions(args),
5553
'show': ShowOptions(args),
5654
'refute-node': RefuteNodeOptions(args),
5755
'unrefute-node': UnrefuteNodeOptions(args),
5856
'split-node': SplitNodeOptions(args),
59-
'to-dot': ToDotOptions(args),
6057
'list': ListOptions(args),
6158
'view-kcfg': ViewKcfgOptions(args),
6259
'remove-node': RemoveNodeOptions(args),
@@ -80,14 +77,12 @@ def get_option_string_destination(command: str, option_string: str) -> str:
8077
options = {
8178
'load-state': LoadStateOptions.from_option_string(),
8279
'version': VersionOptions.from_option_string(),
83-
'compile': CompileOptions.from_option_string(),
8480
'build': BuildOptions.from_option_string(),
8581
'prove': ProveOptions.from_option_string(),
8682
'show': ShowOptions.from_option_string(),
8783
'refute-node': RefuteNodeOptions.from_option_string(),
8884
'unrefute-node': UnrefuteNodeOptions.from_option_string(),
8985
'split-node': SplitNodeOptions.from_option_string(),
90-
'to-dot': ToDotOptions.from_option_string(),
9186
'list': ListOptions.from_option_string(),
9287
'view-kcfg': ViewKcfgOptions.from_option_string(),
9388
'remove-node': RemoveNodeOptions.from_option_string(),
@@ -109,14 +104,12 @@ def get_argument_type_setter(command: str, option_string: str) -> Callable[[str]
109104
options = {
110105
'load-state': LoadStateOptions.get_argument_type(),
111106
'version': VersionOptions.get_argument_type(),
112-
'compile': CompileOptions.get_argument_type(),
113107
'build': BuildOptions.get_argument_type(),
114108
'prove': ProveOptions.get_argument_type(),
115109
'show': ShowOptions.get_argument_type(),
116110
'refute-node': RefuteNodeOptions.get_argument_type(),
117111
'unrefute-node': UnrefuteNodeOptions.get_argument_type(),
118112
'split-node': SplitNodeOptions.get_argument_type(),
119-
'to-dot': ToDotOptions.get_argument_type(),
120113
'list': ListOptions.get_argument_type(),
121114
'view-kcfg': ViewKcfgOptions.get_argument_type(),
122115
'remove-node': RemoveNodeOptions.get_argument_type(),
@@ -249,9 +242,6 @@ def parse(s: str) -> list[T]:
249242

250243
command_parser.add_parser('version', help='Print out version of Kontrol command.')
251244

252-
solc_args = command_parser.add_parser('compile', help='Generate combined JSON with solc compilation results.')
253-
solc_args.add_argument('contract_file', type=file_path, help='Path to contract file.')
254-
255245
build = command_parser.add_parser(
256246
'build',
257247
help='Kompile K definition corresponding to given output directory.',
@@ -644,17 +634,6 @@ def parse(s: str) -> list[T]:
644634
help='Run KCFG minimization routine before displaying it.',
645635
)
646636

647-
command_parser.add_parser(
648-
'to-dot',
649-
help='Dump the given CFG for the test as DOT for visualization.',
650-
parents=[
651-
kontrol_cli_args.foundry_test_args,
652-
kontrol_cli_args.logging_args,
653-
kontrol_cli_args.foundry_args,
654-
config_args.config_args,
655-
],
656-
)
657-
658637
command_parser.add_parser(
659638
'list',
660639
help='List information about CFGs on disk',

src/kontrol/foundry.py

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
from pyk.proof.proof import Proof
4545
from pyk.proof.reachability import APRFailureInfo, APRProof
4646
from pyk.proof.show import APRProofNodePrinter, APRProofShow
47+
from pyk.proof.tui import APRProofViewer
4748
from pyk.utils import ensure_dir_path, hash_str, run_process_2, single, unique
4849

4950
from . import VERSION
@@ -86,8 +87,8 @@
8687
SimplifyNodeOptions,
8788
SplitNodeOptions,
8889
StepNodeOptions,
89-
ToDotOptions,
9090
UnrefuteNodeOptions,
91+
ViewKcfgOptions,
9192
)
9293

9394
_LOGGER: Final = logging.getLogger(__name__)
@@ -670,6 +671,14 @@ def success(s: KInner, dst: KInner, r: KInner, c: KInner, e1: KInner, e2: KInner
670671
def fail(s: KInner, dst: KInner, r: KInner, c: KInner, e1: KInner, e2: KInner) -> KApply:
671672
return notBool(Foundry.success(s, dst, r, c, e1, e2))
672673

674+
@staticmethod
675+
def hevm_success(s: KInner, dst: KInner, out: KInner) -> KApply:
676+
return KApply('hevm_success', [s, dst, out])
677+
678+
@staticmethod
679+
def hevm_fail(s: KInner, dst: KInner) -> KApply:
680+
return KApply('hevm_fail', [s, dst])
681+
673682
# address(uint160(uint256(keccak256("foundry default caller"))))
674683

675684
@staticmethod
@@ -735,13 +744,28 @@ def symbolic_account(prefix: str, program: KInner, storage: KInner | None = None
735744
)
736745

737746
@staticmethod
738-
def help_info() -> list[str]:
747+
def help_info(proof_id: str, hevm: bool) -> list[str]:
739748
res_lines: list[str] = []
740-
res_lines.append('')
741-
res_lines.append('See `foundry_success` predicate for more information:')
742-
res_lines.append(
743-
'https://github.com/runtimeverification/kontrol/blob/master/src/kontrol/kdist/foundry.md#foundry-success-predicate'
744-
)
749+
if hevm:
750+
_, test = proof_id.split('.')
751+
if not any(test.startswith(prefix) for prefix in ['testFail', 'checkFail', 'proveFail']):
752+
res_lines.append('')
753+
res_lines.append('See `hevm_success` predicate for more information:')
754+
res_lines.append(
755+
'https://github.com/runtimeverification/kontrol/blob/master/src/kontrol/kdist/hevm.md#hevm-success-predicate'
756+
)
757+
else:
758+
res_lines.append('')
759+
res_lines.append('See `hevm_fail` predicate for more information:')
760+
res_lines.append(
761+
'https://github.com/runtimeverification/kontrol/blob/master/src/kontrol/kdist/hevm.md#hevm-fail-predicate'
762+
)
763+
else:
764+
res_lines.append('')
765+
res_lines.append('See `foundry_success` predicate for more information:')
766+
res_lines.append(
767+
'https://github.com/runtimeverification/kontrol/blob/master/src/kontrol/kdist/foundry.md#foundry-success-predicate'
768+
)
745769
res_lines.append('')
746770
res_lines.append('Access documentation for Kontrol at https://docs.runtimeverification.com/kontrol')
747771
return res_lines
@@ -990,7 +1014,7 @@ def foundry_show(
9901014
extra_module=foundry.load_lemmas(options.lemmas),
9911015
) as kcfg_explore:
9921016
res_lines += print_failure_info(proof, kcfg_explore, options.counterexample_info)
993-
res_lines += Foundry.help_info()
1017+
res_lines += Foundry.help_info(proof.id, False)
9941018

9951019
if options.to_kevm_claims or options.to_kevm_rules:
9961020
_foundry_labels = [
@@ -1070,16 +1094,19 @@ def _collect_klabel(_k: KInner) -> None:
10701094
return '\n'.join([line.rstrip() for line in res_lines])
10711095

10721096

1073-
def foundry_to_dot(foundry: Foundry, options: ToDotOptions) -> None:
1074-
dump_dir = foundry.proofs_dir / 'dump'
1097+
def foundry_view(foundry: Foundry, options: ViewKcfgOptions) -> None:
10751098
test_id = foundry.get_test_id(options.test, options.version)
1076-
contract_name, _ = single(foundry.matching_tests([options.test])).split('.')
1099+
contract_name, _ = test_id.split('.')
10771100
proof = foundry.get_apr_proof(test_id)
10781101

1079-
node_printer = foundry_node_printer(foundry, contract_name, proof)
1080-
proof_show = APRProofShow(foundry.kevm, node_printer=node_printer)
1102+
compilation_unit = CompilationUnit.load_build_info(foundry.build_info)
1103+
1104+
def _custom_view(elem: KCFGElem) -> Iterable[str]:
1105+
return foundry.custom_view(contract_name, elem, compilation_unit)
10811106

1082-
proof_show.dump(proof, dump_dir, dot=True)
1107+
node_printer = foundry_node_printer(foundry, contract_name, proof)
1108+
viewer = APRProofViewer(proof, foundry.kevm, node_printer=node_printer, custom_view=_custom_view)
1109+
viewer.run()
10831110

10841111

10851112
def foundry_list(foundry: Foundry) -> list[str]:
@@ -1212,8 +1239,7 @@ def foundry_split_node(
12121239
proof = foundry.get_apr_proof(test_id)
12131240

12141241
token = KToken(options.branch_condition, 'Bool')
1215-
node_printer = foundry_node_printer(foundry, contract_name, proof)
1216-
parsed_condition = node_printer.kprint.parse_token(token, as_rule=True)
1242+
parsed_condition = foundry.kevm.parse_token(token, as_rule=True)
12171243

12181244
split_nodes = proof.kcfg.split_on_constraints(
12191245
options.node, [mlEqualsTrue(parsed_condition), mlEqualsFalse(parsed_condition)]

src/kontrol/hevm.py

Lines changed: 0 additions & 38 deletions
This file was deleted.

0 commit comments

Comments
 (0)