Skip to content

Commit e4085f5

Browse files
ehildenbrv-auditorjberthold
authored
Improvements to printing using new infrastructure (#593)
These are some improvements to printing that we can implement now that we have merged changes upstream runtimeverification/k#4808. - Improves the printing of spans in the TUI viewer to actually print the file name and line that it's referring to. - Passes the entire `DisplayOpts` to the `KMIRAPRNodePrinter`, because why not? - Omits printing the `<currentBody>` cell by default in TUI and shower, but enables turning it back on with `--no-omit-current-body` option to both. - Saves off the `SMIRInfo` in the `proof_dir` when we have it available in `prove-rs`, so that it can be used for printing sourcemap information in the show/view commands (like current function name and span). --------- Co-authored-by: devops <[email protected]> Co-authored-by: Jost Berthold <[email protected]>
1 parent 5288896 commit e4085f5

File tree

9 files changed

+69
-31
lines changed

9 files changed

+69
-31
lines changed

kmir/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "kmir"
7-
version = "0.3.170"
7+
version = "0.3.171"
88
description = ""
99
requires-python = "~=3.10"
1010
dependencies = [

kmir/src/kmir/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
from typing import Final
22

3-
VERSION: Final = '0.3.170'
3+
VERSION: Final = '0.3.171'

kmir/src/kmir/__main__.py

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -114,25 +114,22 @@ def _kmir_prove_raw(opts: ProveRawOpts) -> None:
114114
def _kmir_view(opts: ViewOpts) -> None:
115115
kmir = KMIR(HASKELL_DEF_DIR, LLVM_LIB_DIR)
116116
proof = APRProof.read_proof_data(opts.proof_dir, opts.id)
117-
smir_info = None
118-
if opts.smir_info is not None:
119-
smir_info = SMIRInfo.from_file(opts.smir_info)
120117
printer = PrettyPrinter(kmir.definition)
121-
cterm_show = CTermShow(printer.print)
122-
node_printer = KMIRAPRNodePrinter(cterm_show, proof, smir_info=smir_info, full_printer=False)
123-
viewer = APRProofViewer(proof, kmir, node_printer=node_printer)
118+
omit_labels = ('<currentBody>',) if opts.omit_current_body else ()
119+
cterm_show = CTermShow(printer.print, omit_labels=omit_labels)
120+
opts.full_printer = False
121+
node_printer = KMIRAPRNodePrinter(cterm_show, proof, opts)
122+
viewer = APRProofViewer(proof, kmir, node_printer=node_printer, cterm_show=cterm_show)
124123
viewer.run()
125124

126125

127126
def _kmir_show(opts: ShowOpts) -> None:
128127
kmir = KMIR(HASKELL_DEF_DIR, LLVM_LIB_DIR)
129128
proof = APRProof.read_proof_data(opts.proof_dir, opts.id)
130-
smir_info = None
131-
if opts.smir_info is not None:
132-
smir_info = SMIRInfo.from_file(opts.smir_info)
133129
printer = PrettyPrinter(kmir.definition)
134-
cterm_show = CTermShow(printer.print)
135-
node_printer = KMIRAPRNodePrinter(cterm_show, proof, smir_info=smir_info, full_printer=opts.full_printer)
130+
omit_labels = ('<currentBody>',) if opts.omit_current_body else ()
131+
cterm_show = CTermShow(printer.print, omit_labels=omit_labels)
132+
node_printer = KMIRAPRNodePrinter(cterm_show, proof, opts)
136133
shower = APRProofShow(kmir.definition, node_printer=node_printer)
137134
lines = shower.show(proof)
138135
print('\n'.join(lines))
@@ -232,6 +229,13 @@ def _arg_parser() -> ArgumentParser:
232229
default=None,
233230
help='Path to SMIR JSON file to improve debug messaging.',
234231
)
232+
display_args.add_argument(
233+
'--no-omit-current-body',
234+
dest='omit_current_body',
235+
default=True,
236+
action='store_false',
237+
help='Display the <currentBody> cell completely.',
238+
)
235239

236240
command_parser.add_parser(
237241
'show', help='Show a saved proof', parents=[kcli_args.logging_args, proof_args, display_args]
@@ -291,13 +295,25 @@ def _parse_args(ns: Namespace) -> KMirOpts:
291295
)
292296
case 'view':
293297
proof_dir = Path(ns.proof_dir).resolve()
294-
return ViewOpts(proof_dir, ns.id, full_printer=ns.full_printer, smir_info=ns.smir_info)
298+
return ViewOpts(
299+
proof_dir,
300+
ns.id,
301+
full_printer=ns.full_printer,
302+
smir_info=ns.smir_info,
303+
omit_current_body=ns.omit_current_body,
304+
)
295305
case 'prune':
296306
proof_dir = Path(ns.proof_dir).resolve()
297307
return PruneOpts(proof_dir, ns.id, ns.node_id)
298308
case 'show':
299309
proof_dir = Path(ns.proof_dir).resolve()
300-
return ShowOpts(proof_dir, ns.id, full_printer=ns.full_printer, smir_info=ns.smir_info)
310+
return ShowOpts(
311+
proof_dir,
312+
ns.id,
313+
full_printer=ns.full_printer,
314+
smir_info=ns.smir_info,
315+
omit_current_body=ns.omit_current_body,
316+
)
301317
case 'prove-rs':
302318
return ProveRSOpts(
303319
rs_file=Path(ns.rs_file).resolve(),

kmir/src/kmir/kmir.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
from pyk.kore.syntax import Pattern
3636
from pyk.utils import BugReport
3737

38-
from .options import ProveRSOpts
38+
from .options import DisplayOpts, ProveRSOpts
3939

4040
_LOGGER: Final = logging.getLogger(__name__)
4141

@@ -166,6 +166,8 @@ def prove_rs(self, opts: ProveRSOpts) -> APRProof:
166166
apr_proof = self.apr_proof_from_kast(
167167
label, kmir_kast, SMIRInfo(smir_json), start_symbol=opts.start_symbol, proof_dir=opts.proof_dir
168168
)
169+
if apr_proof.proof_dir is not None and (apr_proof.proof_dir / apr_proof.id).is_dir():
170+
(apr_proof.proof_dir / apr_proof.id / 'smir.json').write_text(json.dumps(smir_json))
169171
if apr_proof.passed:
170172
return apr_proof
171173
with self.kcfg_explore(label) as kcfg_explore:
@@ -195,14 +197,20 @@ def __init__(self, cterm_show: CTermShow, full_printer: bool = False) -> None:
195197
class KMIRAPRNodePrinter(KMIRNodePrinter, APRProofNodePrinter):
196198
smir_info: SMIRInfo | None
197199

198-
def __init__(
199-
self, cterm_show: CTermShow, proof: APRProof, smir_info: SMIRInfo | None = None, full_printer: bool = False
200-
) -> None:
201-
KMIRNodePrinter.__init__(self, cterm_show, full_printer=full_printer)
202-
APRProofNodePrinter.__init__(self, proof, cterm_show, full_printer=full_printer)
203-
self.smir_info = smir_info
200+
def __init__(self, cterm_show: CTermShow, proof: APRProof, opts: DisplayOpts) -> None:
201+
KMIRNodePrinter.__init__(self, cterm_show, full_printer=opts.full_printer)
202+
APRProofNodePrinter.__init__(self, proof, cterm_show, full_printer=opts.full_printer)
203+
self.smir_info = None
204+
if opts.smir_info:
205+
self.smir_info = SMIRInfo.from_file(opts.smir_info)
206+
elif (
207+
proof.proof_dir is not None
208+
and (proof.proof_dir / proof.id).is_dir()
209+
and (proof.proof_dir / proof.id / 'smir.json').is_file()
210+
):
211+
self.smir_info = SMIRInfo.from_file(proof.proof_dir / proof.id / 'smir.json')
204212

205-
def _span(self, node: KCFG.Node) -> int | None:
213+
def _span(self, node: KCFG.Node) -> str | None:
206214
curr_span: int | None = None
207215
span_worklist: list[KInner] = [node.cterm.cell('K_CELL')]
208216
while span_worklist:
@@ -218,7 +226,12 @@ def _span(self, node: KCFG.Node) -> int | None:
218226
span_worklist = list(next_item.args) + span_worklist
219227
if type(next_item) is KSequence:
220228
span_worklist = list(next_item.items) + span_worklist
221-
return curr_span
229+
if self.smir_info is not None and curr_span is not None and curr_span in self.smir_info.spans:
230+
path, start_row, _start_column, _end_row, _end_column = self.smir_info.spans[curr_span]
231+
return f'{str(path)[-30:]}:{start_row}'
232+
if curr_span is not None:
233+
return f'{curr_span}'
234+
return None
222235

223236
def _function_name(self, node: KCFG.Node) -> str | None:
224237
curr_func_ty_kast = node.cterm.cell('CURRENTFUNC_CELL')

kmir/src/kmir/options.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,18 +132,21 @@ def __init__(
132132
class DisplayOpts(ProofOpts):
133133
full_printer: bool
134134
smir_info: Path | None
135+
omit_current_body: bool
135136

136137
def __init__(
137138
self,
138139
proof_dir: Path | str,
139140
id: str,
140141
full_printer: bool = True,
141142
smir_info: Path | None = None,
143+
omit_current_body: bool = True,
142144
) -> None:
143145
self.proof_dir = Path(proof_dir).resolve() if proof_dir is not None else None
144146
self.id = id
145147
self.full_printer = full_printer
146148
self.smir_info = smir_info
149+
self.omit_current_body = omit_current_body
147150

148151

149152
@dataclass

kmir/src/kmir/smir.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ def function_tys(self) -> dict[str, int]:
8484
res[name] = fun_syms[sym]
8585
return res
8686

87+
@cached_property
88+
def spans(self) -> dict[int, tuple[Path, int, int, int, int]]:
89+
return {id: (p, sr, sc, er, ec) for id, [p, sr, sc, er, ec] in self._smir['spans']}
90+
8791
@staticmethod
8892
def _is_func(item: dict[str, dict]) -> bool:
8993
return 'MonoItemFn' in item['mono_item_kind']

kmir/src/tests/integration/test_integration.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from kmir.__main__ import _kmir_gen_spec, _kmir_prove_raw
1616
from kmir.build import HASKELL_DEF_DIR, LLVM_DEF_DIR
1717
from kmir.kmir import KMIR, KMIRAPRNodePrinter
18-
from kmir.options import GenSpecOpts, ProveRawOpts, ProveRSOpts
18+
from kmir.options import GenSpecOpts, ProveRawOpts, ProveRSOpts, ShowOpts
1919
from kmir.parse.parser import Parser
2020
from kmir.testing.fixtures import assert_or_update_show_output
2121

@@ -479,9 +479,10 @@ def test_prove_rs(rs_file: Path, kmir: KMIR, update_expected_output: bool) -> No
479479
else:
480480
assert apr_proof.failed
481481

482-
shower = APRProofShow(
483-
kmir.definition, node_printer=KMIRAPRNodePrinter(cterm_show, apr_proof, full_printer=False)
482+
display_opts = ShowOpts(
483+
rs_file.parent, apr_proof.id, full_printer=False, smir_info=None, omit_current_body=False
484484
)
485+
shower = APRProofShow(kmir.definition, node_printer=KMIRAPRNodePrinter(cterm_show, apr_proof, display_opts))
485486
show_res = '\n'.join(shower.show(apr_proof))
486487
assert_or_update_show_output(
487488
show_res, PROVING_DIR / f'show/{rs_file.stem}.expected', update=update_expected_output
@@ -511,9 +512,10 @@ def test_prove_pinocchio(kmir: KMIR, update_expected_output: bool) -> None:
511512
for start_symbol in start_symbols:
512513
prove_rs_opts.start_symbol = start_symbol
513514
apr_proof = kmir.prove_rs(prove_rs_opts)
514-
shower = APRProofShow(
515-
kmir.definition, node_printer=KMIRAPRNodePrinter(cterm_show, apr_proof, full_printer=True)
515+
display_opts = ShowOpts(
516+
pinocchio_token_program.parent, apr_proof.id, full_printer=True, smir_info=None, omit_current_body=False
516517
)
518+
shower = APRProofShow(kmir.definition, node_printer=KMIRAPRNodePrinter(cterm_show, apr_proof, display_opts))
517519
show_res = '\n'.join(shower.show(apr_proof))
518520
assert_or_update_show_output(
519521
show_res,

kmir/uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.3.170
1+
0.3.171

0 commit comments

Comments
 (0)