Skip to content

Commit f8980df

Browse files
authored
Updates from master (#916)
* build dependency updates * moving a simplification lemma to master * transmute cast rule for `MaybeUninit` cases (element updates within arrays) * stable-mir-json upgrade
2 parents 5a1667f + ba67f50 commit f8980df

30 files changed

Lines changed: 1749 additions & 317 deletions

.github/workflows/update-dependencies.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ jobs:
4949
git fetch --all
5050
git checkout "${VERSION}"
5151
cd ../..
52-
git add deps/stable-mir-json
52+
sed -i 's!__smir_version__: Final = '"'[0-9a-f]*'"'!__smir_version__: Final = '"'${VERSION}'"'!' kmir/src/kmir/__init__.py
53+
git add deps/stable-mir-json kmir/src/kmir/__init__.py
5354
git commit -m "deps/stable-mir-json: sync submodule ${VERSION}" || true
5455
- name: 'Update Nix flake inputs'
5556
run: |

deps/stable-mir-json_release

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
626e8fed0470078c4d980b6b5b503a3aceb355ec
1+
a5b714d89d0c12c7f4b00602a95ad2d3a34530f0

deps/uv2nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4cca323a547a1aaa9b94929c4901bed5343eafe8
1+
9d357f0d2ce6f5f35ec7959d7e704452352eb4da

deps/uv_release

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.9.14
1+
0.9.22

flake.lock

Lines changed: 11 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
flake-utils.url = "github:numtide/flake-utils";
88

9-
stable-mir-json-flake.url = "github:runtimeverification/stable-mir-json/626e8fed0470078c4d980b6b5b503a3aceb355ec";
9+
stable-mir-json-flake.url = "github:runtimeverification/stable-mir-json/a5b714d89d0c12c7f4b00602a95ad2d3a34530f0";
1010
stable-mir-json-flake = {
1111
inputs.nixpkgs.follows = "nixpkgs";
1212
inputs.flake-utils.follows = "flake-utils";
@@ -18,7 +18,7 @@
1818
inputs.nixpkgs.follows = "nixpkgs";
1919
};
2020

21-
uv2nix.url = "github:pyproject-nix/uv2nix/4cca323a547a1aaa9b94929c4901bed5343eafe8";
21+
uv2nix.url = "github:pyproject-nix/uv2nix/9d357f0d2ce6f5f35ec7959d7e704452352eb4da";
2222
# uv2nix requires a newer version of nixpkgs
2323
# therefore, we pin uv2nix specifically to a newer version of nixpkgs
2424
# until we replaced our stale version of nixpkgs with an upstream one as well

kmir/src/kmir/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from importlib.metadata import version
12
from typing import Final
23

3-
VERSION: Final = '0.3.181'
4+
__version__: Final = version('kmir')
5+
__smir_version__: Final = 'a5b714d89d0c12c7f4b00602a95ad2d3a34530f0'

kmir/src/kmir/__main__.py

Lines changed: 109 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
from pyk.cli.args import KCLIArgs
1111
from pyk.cterm.show import CTermShow
1212
from pyk.kast.pretty import PrettyPrinter
13+
from pyk.kdist import kdist
1314
from pyk.proof.reachability import APRProof
1415
from pyk.proof.show import APRProofShow
1516
from pyk.proof.tui import APRProofViewer
1617

17-
from .build import HASKELL_DEF_DIR, LLVM_LIB_DIR
1818
from .cargo import CargoProject
1919
from .kmir import KMIR, KMIRAPRNodePrinter
2020
from .linker import link
@@ -54,7 +54,14 @@ def _kmir_run(opts: RunOpts) -> None:
5454
smir_info = cargo.smir_for_project(clean=False)
5555

5656
def run(target_dir: Path):
57-
kmir = KMIR.from_kompiled_kore(smir_info, symbolic=opts.haskell_backend, target_dir=target_dir)
57+
kmir = KMIR.from_kompiled_kore(
58+
smir_info,
59+
target_dir=target_dir,
60+
symbolic=opts.symbolic,
61+
haskell_target=opts.haskell_target,
62+
llvm_lib_target=opts.llvm_lib_target,
63+
llvm_target=opts.llvm_target,
64+
)
5865
result = kmir.run_smir(smir_info, start_symbol=opts.start_symbol, depth=opts.depth)
5966
print(kmir.kore_to_pretty(result))
6067

@@ -73,7 +80,10 @@ def _kmir_prove_rs(opts: ProveRSOpts) -> None:
7380

7481

7582
def _kmir_view(opts: ViewOpts) -> None:
76-
kmir = KMIR(HASKELL_DEF_DIR, LLVM_LIB_DIR)
83+
kmir = KMIR(
84+
definition_dir=kdist.which(opts.haskell_target or 'mir-semantics.haskell'),
85+
llvm_library_dir=kdist.which(opts.llvm_lib_target or 'mir-semantics.llvm-library'),
86+
)
7787
proof = APRProof.read_proof_data(opts.proof_dir, opts.id)
7888
printer = PrettyPrinter(kmir.definition)
7989
omit_labels = ('<currentBody>',) if opts.omit_current_body else ()
@@ -84,14 +94,53 @@ def _kmir_view(opts: ViewOpts) -> None:
8494
viewer.run()
8595

8696

97+
def _write_to_module(kmir: KMIR, proof: APRProof, to_module_path: Path) -> None:
98+
"""Write proof KCFG as a K module to the specified path."""
99+
import json
100+
101+
from pyk.kast.manip import remove_generated_cells
102+
from pyk.kast.outer import KRule
103+
104+
# Generate K module using KCFG.to_module with defunc_with for proper function inlining
105+
module_name = proof.id.upper().replace('.', '-').replace('_', '-') + '-SUMMARY'
106+
k_module = proof.kcfg.to_module(module_name=module_name, defunc_with=kmir.definition)
107+
108+
if to_module_path.suffix == '.json':
109+
# JSON format for --add-module: keep <generatedTop> for Kore conversion
110+
# Note: We don't use minimize_rule_like here because it creates partial configs
111+
# with dots that cannot be converted back to Kore
112+
to_module_path.write_text(json.dumps(k_module.to_dict(), indent=2))
113+
else:
114+
# K text format for human readability: remove <generatedTop> and <generatedCounter>
115+
def _process_sentence(sent): # type: ignore[no-untyped-def]
116+
if isinstance(sent, KRule):
117+
sent = sent.let(body=remove_generated_cells(sent.body))
118+
return sent
119+
120+
k_module_readable = k_module.let(sentences=[_process_sentence(sent) for sent in k_module.sentences])
121+
k_module_text = kmir.pretty_print(k_module_readable)
122+
to_module_path.write_text(k_module_text)
123+
_LOGGER.info(f'Module written to: {to_module_path}')
124+
125+
87126
def _kmir_show(opts: ShowOpts) -> None:
88127
from pyk.kast.pretty import PrettyPrinter
89128

90129
from .kprint import KMIRPrettyPrinter
91130

92-
kmir = KMIR(HASKELL_DEF_DIR, LLVM_LIB_DIR)
131+
kmir = KMIR(
132+
definition_dir=kdist.which(opts.haskell_target or 'mir-semantics.haskell'),
133+
llvm_library_dir=kdist.which(opts.llvm_lib_target or 'mir-semantics.llvm-library'),
134+
)
93135
proof = APRProof.read_proof_data(opts.proof_dir, opts.id)
94136

137+
# Minimize proof KCFG if requested
138+
if opts.minimize_proof:
139+
_LOGGER.info('Minimizing proof KCFG...')
140+
proof.minimize_kcfg()
141+
proof.write_proof_data()
142+
_LOGGER.info('Proof KCFG minimized and saved')
143+
95144
# Use custom KMIR printer by default, switch to standard printer if requested
96145
if opts.use_default_printer:
97146
printer = PrettyPrinter(kmir.definition)
@@ -119,6 +168,7 @@ def _kmir_show(opts: ShowOpts) -> None:
119168
nodes=opts.nodes or (),
120169
node_deltas=effective_node_deltas,
121170
omit_cells=tuple(all_omit_cells),
171+
to_module=opts.to_module is not None,
122172
)
123173
if opts.statistics:
124174
if lines and lines[-1] != '':
@@ -132,7 +182,12 @@ def _kmir_show(opts: ShowOpts) -> None:
132182
lines.append('')
133183
lines.extend(render_leaf_k_cells(proof, node_printer.cterm_show))
134184

135-
print('\n'.join(lines))
185+
# Handle --to-module output
186+
if opts.to_module:
187+
_write_to_module(kmir, proof, opts.to_module)
188+
print(f'Module written to: {opts.to_module}')
189+
else:
190+
print('\n'.join(lines))
136191

137192

138193
def _kmir_prune(opts: PruneOpts) -> None:
@@ -156,7 +211,14 @@ def _kmir_section_edge(opts: SectionEdgeOpts) -> None:
156211

157212
smir_info = SMIRInfo.from_file(target_path / 'smir.json')
158213

159-
kmir = KMIR.from_kompiled_kore(smir_info, symbolic=True, bug_report=opts.bug_report, target_dir=target_path)
214+
kmir = KMIR.from_kompiled_kore(
215+
smir_info,
216+
target_dir=target_path,
217+
bug_report=opts.bug_report,
218+
symbolic=True,
219+
haskell_target=opts.haskell_target,
220+
llvm_lib_target=opts.llvm_lib_target,
221+
)
160222

161223
source_id, target_id = opts.edge
162224
_LOGGER.info(f'Attempting to add {opts.sections} sections from node {source_id} to node {target_id}')
@@ -229,7 +291,10 @@ def _arg_parser() -> ArgumentParser:
229291
run_parser.add_argument(
230292
'--start-symbol', type=str, metavar='SYMBOL', default='main', help='Symbol name to begin execution from'
231293
)
232-
run_parser.add_argument('--haskell-backend', action='store_true', help='Run with the haskell backend')
294+
run_parser.add_argument('--symbolic', action='store_true', help='Run with the symbolic backend')
295+
run_parser.add_argument('--haskell-target', metavar='TARGET', help='Haskell target to use')
296+
run_parser.add_argument('--llvm-lib-target', metavar='TARGET', help='LLVM lib target to use')
297+
run_parser.add_argument('--llvm-target', metavar='TARGET', help='LLVM target to use')
233298

234299
info_parser = command_parser.add_parser(
235300
'info', help='Show information about a SMIR JSON file', parents=[kcli_args.logging_args]
@@ -239,6 +304,8 @@ def _arg_parser() -> ArgumentParser:
239304

240305
prove_args = ArgumentParser(add_help=False)
241306
prove_args.add_argument('--proof-dir', metavar='DIR', help='Proof directory')
307+
prove_args.add_argument('--haskell-target', metavar='TARGET', help='Haskell target to use')
308+
prove_args.add_argument('--llvm-lib-target', metavar='TARGET', help='LLVM lib target to use')
242309
prove_args.add_argument('--bug-report', metavar='PATH', help='path to optional bug report')
243310
prove_args.add_argument('--max-depth', metavar='DEPTH', type=int, help='max steps to take between nodes in kcfg')
244311
prove_args.add_argument(
@@ -370,6 +437,8 @@ def _arg_parser() -> ArgumentParser:
370437
action='store_false',
371438
help='Display the <currentBody> cell completely.',
372439
)
440+
display_args.add_argument('--haskell-target', metavar='TARGET', help='Haskell target to use')
441+
display_args.add_argument('--llvm-lib-target', metavar='TARGET', help='LLVM lib target to use')
373442

374443
show_parser = command_parser.add_parser(
375444
'show', help='Show proof information', parents=[kcli_args.logging_args, proof_args, display_args]
@@ -410,6 +479,17 @@ def _arg_parser() -> ArgumentParser:
410479
)
411480

412481
show_parser.add_argument('--rules', metavar='EDGES', help='Comma separated list of edges in format "source:target"')
482+
show_parser.add_argument(
483+
'--to-module',
484+
type=Path,
485+
metavar='FILE',
486+
help='Output path for K module file (.k for readable, .json for --add-module)',
487+
)
488+
show_parser.add_argument(
489+
'--minimize-proof',
490+
action='store_true',
491+
help='Minimize the proof KCFG before exporting to module',
492+
)
413493

414494
command_parser.add_parser(
415495
'view', help='View proof information', parents=[kcli_args.logging_args, proof_args, display_args]
@@ -429,6 +509,8 @@ def _arg_parser() -> ArgumentParser:
429509
section_edge_parser.add_argument(
430510
'--sections', type=int, default=2, help='Number of sections to make from edge (>= 2, default: 2)'
431511
)
512+
section_edge_parser.add_argument('--haskell-target', metavar='TARGET', help='Haskell target to use')
513+
section_edge_parser.add_argument('--llvm-lib-target', metavar='TARGET', help='LLVM lib target to use')
432514

433515
prove_rs_parser = command_parser.add_parser(
434516
'prove-rs', help='Prove a rust program', parents=[kcli_args.logging_args, prove_args]
@@ -443,6 +525,12 @@ def _arg_parser() -> ArgumentParser:
443525
prove_rs_parser.add_argument(
444526
'--start-symbol', type=str, metavar='SYMBOL', default='main', help='Symbol name to begin execution from'
445527
)
528+
prove_rs_parser.add_argument(
529+
'--add-module',
530+
type=Path,
531+
metavar='FILE',
532+
help='K module file to include (.json format from --to-module)',
533+
)
446534

447535
link_parser = command_parser.add_parser(
448536
'link', help='Link together 2 or more SMIR JSON files', parents=[kcli_args.logging_args]
@@ -464,7 +552,7 @@ def _parse_args(ns: Namespace) -> KMirOpts:
464552
target_dir=ns.target_dir,
465553
depth=ns.depth,
466554
start_symbol=ns.start_symbol,
467-
haskell_backend=ns.haskell_backend,
555+
symbolic=ns.symbolic,
468556
)
469557
case 'info':
470558
return InfoOpts(smir_file=Path(ns.smir_file), types=ns.types)
@@ -474,6 +562,8 @@ def _parse_args(ns: Namespace) -> KMirOpts:
474562
id=ns.id,
475563
full_printer=ns.full_printer,
476564
smir_info=Path(ns.smir_info) if ns.smir_info else None,
565+
haskell_target=ns.haskell_target,
566+
llvm_lib_target=ns.llvm_lib_target,
477567
omit_current_body=ns.omit_current_body,
478568
nodes=ns.nodes,
479569
node_deltas=ns.node_deltas,
@@ -492,6 +582,8 @@ def _parse_args(ns: Namespace) -> KMirOpts:
492582
ns.id,
493583
full_printer=ns.full_printer,
494584
smir_info=ns.smir_info,
585+
haskell_target=ns.haskell_target,
586+
llvm_lib_target=ns.llvm_lib_target,
495587
omit_current_body=ns.omit_current_body,
496588
)
497589
case 'prune':
@@ -501,7 +593,14 @@ def _parse_args(ns: Namespace) -> KMirOpts:
501593
if ns.proof_dir is None:
502594
raise ValueError('Must pass --proof-dir to section-edge command')
503595
proof_dir = Path(ns.proof_dir)
504-
return SectionEdgeOpts(proof_dir, ns.id, ns.edge, ns.sections)
596+
return SectionEdgeOpts(
597+
proof_dir,
598+
ns.id,
599+
ns.edge,
600+
sections=ns.sections,
601+
haskell_target=ns.haskell_target,
602+
llvm_lib_target=ns.llvm_lib_target,
603+
)
505604
case 'prove-rs':
506605
return ProveRSOpts(
507606
rs_file=Path(ns.rs_file),
@@ -530,6 +629,7 @@ def _parse_args(ns: Namespace) -> KMirOpts:
530629
break_every_terminator=ns.break_every_terminator,
531630
break_every_step=ns.break_every_step,
532631
terminate_on_thunk=ns.terminate_on_thunk,
632+
add_module=ns.add_module,
533633
)
534634
case 'link':
535635
return LinkOpts(

0 commit comments

Comments
 (0)