Skip to content

Commit 45976d2

Browse files
ehildenbrv-auditor
andauthored
Implement APRProofViewer as an APRProof specific TUI (#507)
Following runtimeverification/pyk#489, it turns out that KEVM's TUI is broken because it relies on the old way of doing Node printing. This makes a new `APRProofViewer` class, which largely inherits from `KCFGViewer`, but adjusts it to handle the more spceific node viewers. I have tested this with both KEVM+Foundry and raw KEVM specs, and it seems to work. --------- Co-authored-by: devops <devops@runtimeverification.com>
1 parent 98f873c commit 45976d2

5 files changed

Lines changed: 147 additions & 8 deletions

File tree

pyk/package/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.1.342
1+
0.1.343

pyk/pyproject.toml

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

55
[tool.poetry]
66
name = "pyk"
7-
version = "0.1.342"
7+
version = "0.1.343"
88
description = ""
99
authors = [
1010
"Runtime Verification, Inc. <contact@runtimeverification.com>",

pyk/src/pyk/kcfg/tui.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111
from ..cterm import CTerm
1212
from ..kast.inner import KApply, KRewrite
1313
from ..kast.manip import flatten_label, minimize_term, push_down_rewrites
14-
from ..kcfg import KCFG, KCFGShow
1514
from ..prelude.kbool import TRUE
1615
from ..utils import shorten_hashes, single
16+
from .kcfg import KCFG
17+
from .show import KCFGShow
1718

1819
if TYPE_CHECKING:
1920
from collections.abc import Callable, Iterable
@@ -23,6 +24,7 @@
2324

2425
from ..kast import KInner
2526
from ..ktool.kprint import KPrint
27+
from .show import NodePrinter
2628

2729

2830
KCFGElem = Union[KCFG.Node, KCFG.Successor]
@@ -57,15 +59,15 @@ class BehaviorView(Widget):
5759
_kcfg: KCFG
5860
_kprint: KPrint
5961
_minimize: bool
60-
_node_printer: Callable[[CTerm], Iterable[str]] | None
62+
_node_printer: NodePrinter | None
6163
_kcfg_nodes: Iterable[GraphChunk]
6264

6365
def __init__(
6466
self,
6567
kcfg: KCFG,
6668
kprint: KPrint,
6769
minimize: bool = True,
68-
node_printer: Callable[[CTerm], Iterable[str]] | None = None,
70+
node_printer: NodePrinter | None = None,
6971
id: str = '',
7072
):
7173
super().__init__(id=id)
@@ -74,7 +76,7 @@ def __init__(
7476
self._minimize = minimize
7577
self._node_printer = node_printer
7678
self._kcfg_nodes = []
77-
kcfg_show = KCFGShow(kprint)
79+
kcfg_show = KCFGShow(kprint, node_printer=node_printer)
7880
for lseg_id, node_lines in kcfg_show.pretty_segments(self._kcfg, minimize=self._minimize):
7981
self._kcfg_nodes.append(GraphChunk(lseg_id, node_lines))
8082

@@ -236,7 +238,7 @@ class KCFGViewer(App):
236238
_kcfg: KCFG
237239
_kprint: KPrint
238240

239-
_node_printer: Callable[[CTerm], Iterable[str]] | None
241+
_node_printer: NodePrinter | None
240242
_custom_view: Callable[[KCFGElem], Iterable[str]] | None
241243

242244
_minimize: bool
@@ -248,7 +250,7 @@ def __init__(
248250
self,
249251
kcfg: KCFG,
250252
kprint: KPrint,
251-
node_printer: Callable[[CTerm], Iterable[str]] | None = None,
253+
node_printer: NodePrinter | None = None,
252254
custom_view: Callable[[KCFGElem], Iterable[str]] | None = None,
253255
minimize: bool = True,
254256
) -> None:

pyk/src/pyk/proof/style.css

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#navigation {
2+
dock: left;
3+
width: 35%;
4+
height: 100%;
5+
layout: vertical;
6+
}
7+
#behavior {
8+
height: 1fr;
9+
border: solid;
10+
overflow-x: auto;
11+
overflow-y: auto;
12+
}
13+
14+
.cfg-node {
15+
height: auto;
16+
width: auto;
17+
}
18+
19+
.hidden {
20+
display: none;
21+
}
22+
23+
#display {
24+
layout: vertical;
25+
}
26+
#info-view {
27+
height: 2fr;
28+
border: solid;
29+
overflow: auto scroll;
30+
}
31+
#term-view {
32+
height: 15fr;
33+
border: solid;
34+
overflow: auto scroll;
35+
}
36+
#constraint-view {
37+
height: 5fr;
38+
border: solid;
39+
overflow: auto scroll;
40+
}
41+
#custom-view {
42+
height: 15fr;
43+
border: solid;
44+
overflow: auto scroll;
45+
}
46+
#info {
47+
width: auto;
48+
height: auto;
49+
}
50+
#term {
51+
width: auto;
52+
height: auto;
53+
}
54+
#constraint {
55+
width: auto;
56+
height: auto;
57+
}
58+
#custom {
59+
width: auto;
60+
height: auto;
61+
}

pyk/src/pyk/proof/tui.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING
4+
5+
from textual.containers import Horizontal, Vertical
6+
from textual.widget import Widget
7+
from textual.widgets import Footer
8+
9+
from ..kcfg.tui import GraphChunk, KCFGViewer, NodeView
10+
from .show import APRProofShow
11+
12+
if TYPE_CHECKING:
13+
from collections.abc import Callable, Iterable
14+
15+
from textual.app import ComposeResult
16+
17+
from ..kcfg.show import NodePrinter
18+
from ..kcfg.tui import KCFGElem
19+
from ..ktool.kprint import KPrint
20+
from .reachability import APRProof
21+
22+
23+
class APRProofBehaviorView(Widget):
24+
_proof: APRProof
25+
_kprint: KPrint
26+
_minimize: bool
27+
_node_printer: NodePrinter | None
28+
_proof_nodes: Iterable[GraphChunk]
29+
30+
def __init__(
31+
self,
32+
proof: APRProof,
33+
kprint: KPrint,
34+
minimize: bool = True,
35+
node_printer: NodePrinter | None = None,
36+
id: str = '',
37+
):
38+
super().__init__(id=id)
39+
self._proof = proof
40+
self._kprint = kprint
41+
self._minimize = minimize
42+
self._node_printer = node_printer
43+
self._proof_nodes = []
44+
proof_show = APRProofShow(kprint, node_printer=node_printer)
45+
for lseg_id, node_lines in proof_show.pretty_segments(self._proof, minimize=self._minimize):
46+
self._proof_nodes.append(GraphChunk(lseg_id, node_lines))
47+
48+
def compose(self) -> ComposeResult:
49+
return self._proof_nodes
50+
51+
52+
class APRProofViewer(KCFGViewer):
53+
CSS_PATH = 'style.css'
54+
55+
_proof: APRProof
56+
57+
def __init__(
58+
self,
59+
proof: APRProof,
60+
kprint: KPrint,
61+
node_printer: NodePrinter | None = None,
62+
custom_view: Callable[[KCFGElem], Iterable[str]] | None = None,
63+
minimize: bool = True,
64+
) -> None:
65+
super().__init__(proof.kcfg, kprint, node_printer=node_printer, custom_view=custom_view, minimize=minimize)
66+
self._proof = proof
67+
68+
def compose(self) -> ComposeResult:
69+
yield Horizontal(
70+
Vertical(
71+
APRProofBehaviorView(self._proof, self._kprint, node_printer=self._node_printer, id='behavior'),
72+
id='navigation',
73+
),
74+
Vertical(NodeView(self._kprint, custom_view=self._custom_view, id='node-view'), id='display'),
75+
)
76+
yield Footer()

0 commit comments

Comments
 (0)