Skip to content
This repository was archived by the owner on Apr 25, 2024. It is now read-only.

Commit f9a2da5

Browse files
Refactor cterm_execute (#773)
* Extract class `CTermExecute` to represent the return value * Assert some properties on the RPC response and simplify logic --------- Co-authored-by: devops <[email protected]>
1 parent b5c15a2 commit f9a2da5

File tree

7 files changed

+63
-64
lines changed

7 files changed

+63
-64
lines changed

package/version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.1.542
1+
0.1.543

pyproject.toml

+1-1
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.542"
7+
version = "0.1.543"
88
description = ""
99
authors = [
1010
"Runtime Verification, Inc. <[email protected]>",

src/pyk/kcfg/explore.py

+39-33
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import logging
44
from abc import ABC
55
from dataclasses import dataclass, field
6-
from typing import TYPE_CHECKING, final
6+
from typing import TYPE_CHECKING, NamedTuple, final
77

88
from ..cterm import CSubst, CTerm
99
from ..kast.inner import KApply, KLabel, KRewrite, KVariable, Subst
@@ -47,6 +47,14 @@
4747
_LOGGER: Final = logging.getLogger(__name__)
4848

4949

50+
class CTermExecute(NamedTuple):
51+
state: CTerm
52+
next_states: tuple[CTerm, ...]
53+
depth: int
54+
vacuous: bool
55+
logs: tuple[LogEntry, ...]
56+
57+
5058
class KCFGExplore:
5159
kprint: KPrint
5260
_kore_client: KoreClient
@@ -77,39 +85,39 @@ def cterm_execute(
7785
cut_point_rules: Iterable[str] | None = None,
7886
terminal_rules: Iterable[str] | None = None,
7987
module_name: str | None = None,
80-
) -> tuple[bool, int, CTerm, list[CTerm], tuple[LogEntry, ...]]:
88+
) -> CTermExecute:
8189
_LOGGER.debug(f'Executing: {cterm}')
8290
kore = self.kprint.kast_to_kore(cterm.kast, GENERATED_TOP_CELL)
83-
er = self._kore_client.execute(
91+
response = self._kore_client.execute(
8492
kore,
8593
max_depth=depth,
8694
cut_point_rules=cut_point_rules,
8795
terminal_rules=terminal_rules,
8896
module_name=module_name,
89-
log_successful_rewrites=self._trace_rewrites if self._trace_rewrites else None,
90-
log_failed_rewrites=self._trace_rewrites if self._trace_rewrites else None,
91-
log_successful_simplifications=self._trace_rewrites if self._trace_rewrites else None,
92-
log_failed_simplifications=self._trace_rewrites if self._trace_rewrites else None,
97+
log_successful_rewrites=self._trace_rewrites,
98+
log_failed_rewrites=self._trace_rewrites,
99+
log_successful_simplifications=self._trace_rewrites,
100+
log_failed_simplifications=self._trace_rewrites,
93101
)
94102

95-
if isinstance(er, AbortedResult):
96-
unknown_predicate = er.unknown_predicate.text if er.unknown_predicate else None
103+
if isinstance(response, AbortedResult):
104+
unknown_predicate = response.unknown_predicate.text if response.unknown_predicate else None
97105
raise ValueError(f'Backend responded with aborted state. Unknown predicate: {unknown_predicate}')
98106

99-
_is_vacuous = er.reason is StopReason.VACUOUS
100-
depth = er.depth
101-
next_state = CTerm.from_kast(self.kprint.kore_to_kast(er.state.kore))
102-
_next_states = er.next_states if er.next_states is not None else []
103-
next_states = [CTerm.from_kast(self.kprint.kore_to_kast(ns.kore)) for ns in _next_states]
104-
next_states = [cterm for cterm in next_states if not cterm.is_bottom]
105-
if len(next_states) == 1 and len(next_states) < len(_next_states):
106-
return _is_vacuous, depth + 1, next_states[0], [], er.logs
107-
elif len(next_states) == 1:
108-
if er.reason == StopReason.CUT_POINT_RULE:
109-
return _is_vacuous, depth, next_state, next_states, er.logs
110-
else:
111-
next_states = []
112-
return _is_vacuous, depth, next_state, next_states, er.logs
107+
state = CTerm.from_kast(self.kprint.kore_to_kast(response.state.kore))
108+
resp_next_states = response.next_states or ()
109+
next_states = tuple(CTerm.from_kast(self.kprint.kore_to_kast(ns.kore)) for ns in resp_next_states)
110+
111+
assert all(not cterm.is_bottom for cterm in next_states)
112+
assert len(next_states) != 1 or response.reason is StopReason.CUT_POINT_RULE
113+
114+
return CTermExecute(
115+
state=state,
116+
next_states=next_states,
117+
depth=response.depth,
118+
vacuous=response.reason is StopReason.VACUOUS,
119+
logs=response.logs,
120+
)
113121

114122
def cterm_simplify(self, cterm: CTerm) -> tuple[CTerm, tuple[LogEntry, ...]]:
115123
_LOGGER.debug(f'Simplifying: {cterm}')
@@ -302,16 +310,14 @@ def step(
302310
if len(successors) != 0 and type(successors[0]) is KCFG.Split:
303311
raise ValueError(f'Cannot take step from split node {self.id}: {shorten_hashes(node.id)}')
304312
_LOGGER.info(f'Taking {depth} steps from node {self.id}: {shorten_hashes(node.id)}')
305-
_, actual_depth, cterm, next_cterms, next_node_logs = self.cterm_execute(
306-
node.cterm, depth=depth, module_name=module_name
307-
)
308-
if actual_depth != depth:
309-
raise ValueError(f'Unable to take {depth} steps from node, got {actual_depth} steps {self.id}: {node.id}')
310-
if len(next_cterms) > 0:
313+
exec_res = self.cterm_execute(node.cterm, depth=depth, module_name=module_name)
314+
if exec_res.depth != depth:
315+
raise ValueError(f'Unable to take {depth} steps from node, got {exec_res.depth} steps {self.id}: {node.id}')
316+
if len(exec_res.next_states) > 0:
311317
raise ValueError(f'Found branch within {depth} steps {self.id}: {node.id}')
312-
new_node = cfg.create_node(cterm)
318+
new_node = cfg.create_node(exec_res.state)
313319
_LOGGER.info(f'Found new node at depth {depth} {self.id}: {shorten_hashes((node.id, new_node.id))}')
314-
logs[new_node.id] = next_node_logs
320+
logs[new_node.id] = exec_res.logs
315321
out_edges = cfg.edges(source_id=node.id)
316322
if len(out_edges) == 0:
317323
cfg.create_edge(node.id, new_node.id, depth=depth)
@@ -405,7 +411,7 @@ def extend_cterm(
405411
if len(branches) > 1:
406412
return Branch(branches, heuristic=True)
407413

408-
_is_vacuous, depth, cterm, next_cterms, next_node_logs = self.cterm_execute(
414+
cterm, next_cterms, depth, vacuous, next_node_logs = self.cterm_execute(
409415
_cterm,
410416
depth=execute_depth,
411417
cut_point_rules=cut_point_rules,
@@ -419,7 +425,7 @@ def extend_cterm(
419425

420426
# Stuck or vacuous
421427
if not next_cterms:
422-
if _is_vacuous:
428+
if vacuous:
423429
return Vacuous()
424430
return Stuck()
425431

src/tests/integration/kcfg/test_multiple_definitions.py

+9-13
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,23 @@ def test_execute(
4444
kcfg_explore: KCFGExplore,
4545
test_id: str,
4646
) -> None:
47-
_, split_depth, split_post_term, split_next_terms, _logs = kcfg_explore.cterm_execute(self.config(), depth=1)
47+
exec_res = kcfg_explore.cterm_execute(self.config(), depth=1)
48+
split_next_terms = exec_res.next_states
49+
split_k = kcfg_explore.kprint.pretty_print(exec_res.state.cell('K_CELL'))
50+
split_next_k = [kcfg_explore.kprint.pretty_print(exec_res.state.cell('K_CELL')) for _ in split_next_terms]
4851

49-
split_k = kcfg_explore.kprint.pretty_print(split_post_term.cell('K_CELL'))
50-
split_next_k = [kcfg_explore.kprint.pretty_print(split_post_term.cell('K_CELL')) for term in split_next_terms]
51-
52-
assert split_depth == 0
52+
assert exec_res.depth == 0
5353
assert len(split_next_terms) == 2
5454
assert 'a ( X:KItem )' == split_k
5555
assert [
5656
'a ( X:KItem )',
5757
'a ( X:KItem )',
5858
] == split_next_k
5959

60-
_, step_1_depth, step_1_post_term, step_1_next_terms, _logs = kcfg_explore.cterm_execute(
61-
split_next_terms[0], depth=1
62-
)
63-
step_1_k = kcfg_explore.kprint.pretty_print(step_1_post_term.cell('K_CELL'))
60+
step_1_res = kcfg_explore.cterm_execute(split_next_terms[0], depth=1)
61+
step_1_k = kcfg_explore.kprint.pretty_print(step_1_res.state.cell('K_CELL'))
6462
assert 'c' == step_1_k
6563

66-
_, step_2_depth, step_2_post_term, step_2_next_terms, _logs = kcfg_explore.cterm_execute(
67-
split_next_terms[1], depth=1
68-
)
69-
step_2_k = kcfg_explore.kprint.pretty_print(step_1_post_term.cell('K_CELL'))
64+
step_2_res = kcfg_explore.cterm_execute(split_next_terms[1], depth=1)
65+
step_2_k = kcfg_explore.kprint.pretty_print(step_2_res.state.cell('K_CELL'))
7066
assert 'c' == step_2_k

src/tests/integration/kcfg/test_simple.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,16 @@ def test_execute(
7878
expected_k, expected_state, *_ = expected_post
7979

8080
# When
81-
_, actual_depth, actual_post_term, actual_next_terms, _logs = kcfg_explore.cterm_execute(
82-
self.config(kcfg_explore.kprint, *pre), depth=depth
83-
)
84-
actual_k = kcfg_explore.kprint.pretty_print(actual_post_term.cell('K_CELL'))
85-
actual_state = kcfg_explore.kprint.pretty_print(actual_post_term.cell('STATE_CELL'))
81+
exec_res = kcfg_explore.cterm_execute(self.config(kcfg_explore.kprint, *pre), depth=depth)
82+
actual_k = kcfg_explore.kprint.pretty_print(exec_res.state.cell('K_CELL'))
83+
actual_state = kcfg_explore.kprint.pretty_print(exec_res.state.cell('STATE_CELL'))
84+
actual_depth = exec_res.depth
8685
actual_next_states = [
8786
(
8887
kcfg_explore.kprint.pretty_print(s.cell('K_CELL')),
8988
kcfg_explore.kprint.pretty_print(s.cell('STATE_CELL')),
9089
)
91-
for s in actual_next_terms
90+
for s in exec_res.next_states
9291
]
9392

9493
# Then

src/tests/integration/proof/test_cell_map.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,9 @@ def test_execute(
104104
expected_k, _, _ = expected_post
105105

106106
# When
107-
_, actual_depth, actual_post_term, _, _logs = kcfg_explore.cterm_execute(
108-
self.config(kcfg_explore.kprint, k, aacounts, accounts), depth=depth
109-
)
110-
actual_k = kcfg_explore.kprint.pretty_print(actual_post_term.cell('K_CELL'))
107+
exec_res = kcfg_explore.cterm_execute(self.config(kcfg_explore.kprint, k, aacounts, accounts), depth=depth)
108+
actual_k = kcfg_explore.kprint.pretty_print(exec_res.state.cell('K_CELL'))
109+
actual_depth = exec_res.depth
111110

112111
# Then
113112
assert actual_depth == expected_depth

src/tests/integration/proof/test_imp.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -780,18 +780,17 @@ def test_execute(
780780
expected_k, expected_state = expected_post
781781

782782
# When
783-
_, actual_depth, actual_post_term, actual_next_terms, _logs = kcfg_explore.cterm_execute(
784-
self.config(kcfg_explore.kprint, k, state), depth=depth
785-
)
786-
actual_k = kcfg_explore.kprint.pretty_print(actual_post_term.cell('K_CELL'))
787-
actual_state = kcfg_explore.kprint.pretty_print(actual_post_term.cell('STATE_CELL'))
783+
exec_res = kcfg_explore.cterm_execute(self.config(kcfg_explore.kprint, k, state), depth=depth)
784+
actual_k = kcfg_explore.kprint.pretty_print(exec_res.state.cell('K_CELL'))
785+
actual_state = kcfg_explore.kprint.pretty_print(exec_res.state.cell('STATE_CELL'))
786+
actual_depth = exec_res.depth
788787

789788
actual_next_states = [
790789
(
791790
kcfg_explore.kprint.pretty_print(s.cell('K_CELL')),
792791
kcfg_explore.kprint.pretty_print(s.cell('STATE_CELL')),
793792
)
794-
for s in actual_next_terms
793+
for s in exec_res.next_states
795794
]
796795

797796
# Then

0 commit comments

Comments
 (0)