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

Commit b06ecb4

Browse files
committed
Merge master into branch
2 parents 71095a6 + ca97bb1 commit b06ecb4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+731
-359
lines changed

deps/k_release

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6.0.69
1+
6.0.87

package/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.1.432
1+
0.1.448

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

src/pyk/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
from typing import Final
77

88

9-
K_VERSION: Final = '6.0.69'
9+
K_VERSION: Final = '6.0.87'

src/pyk/cli/args.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ def smt_args(self) -> ArgumentParser:
101101
type=int,
102102
help='Number of times to retry SMT queries with scaling timeouts.',
103103
)
104+
args.add_argument(
105+
'--smt-tactic',
106+
dest='smt_tactic',
107+
type=str,
108+
help='Z3 tactic to use when checking satisfiability. Example: (check-sat-using smt)',
109+
)
104110
return args
105111

106112
@cached_property

src/pyk/cterm.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
)
2424
from .kast.outer import KClaim, KRule
2525
from .prelude.k import GENERATED_TOP_CELL
26-
from .prelude.kbool import orBool
26+
from .prelude.kbool import andBool, orBool
2727
from .prelude.ml import is_bottom, is_top, mlAnd, mlBottom, mlEqualsTrue, mlImplies, mlTop
2828
from .utils import single, unique
2929

@@ -118,7 +118,11 @@ def _is_bottom(kast: KInner) -> bool:
118118
flat = flatten_label('#And', kast)
119119
if len(flat) == 1:
120120
return is_bottom(single(flat))
121-
return all(CTerm._is_bottom(term) for term in flat)
121+
return any(CTerm._is_bottom(term) for term in flat)
122+
123+
@property
124+
def is_bottom(self) -> bool:
125+
return CTerm._is_bottom(self.config) or any(CTerm._is_bottom(cterm) for cterm in self.constraints)
122126

123127
@staticmethod
124128
def _constraint_sort_key(term: KInner) -> tuple[int, str]:
@@ -190,17 +194,21 @@ def add_constraint(self, new_constraint: KInner) -> CTerm:
190194
def anti_unify(
191195
self, other: CTerm, keep_values: bool = False, kdef: KDefinition | None = None
192196
) -> tuple[CTerm, CSubst, CSubst]:
193-
def disjunction_from_substs(subst1: Subst, subst2: Subst) -> KInner:
194-
if KToken('true', 'Bool') in [subst1.pred, subst2.pred]:
195-
return mlTop()
196-
return mlEqualsTrue(orBool([subst1.pred, subst2.pred]))
197-
198197
new_config, self_subst, other_subst = anti_unify(self.config, other.config, kdef=kdef)
199198
common_constraints = [constraint for constraint in self.constraints if constraint in other.constraints]
200-
201-
new_cterm = CTerm(
202-
config=new_config, constraints=([disjunction_from_substs(self_subst, other_subst)] if keep_values else [])
203-
)
199+
self_unique_constraints = [
200+
ml_pred_to_bool(constraint) for constraint in self.constraints if constraint not in other.constraints
201+
]
202+
other_unique_constraints = [
203+
ml_pred_to_bool(constraint) for constraint in other.constraints if constraint not in self.constraints
204+
]
205+
206+
new_cterm = CTerm(config=new_config, constraints=())
207+
if keep_values:
208+
disjunct_lhs = andBool([self_subst.pred] + self_unique_constraints)
209+
disjunct_rhs = andBool([other_subst.pred] + other_unique_constraints)
210+
if KToken('true', 'Bool') not in [disjunct_lhs, disjunct_rhs]:
211+
new_cterm = new_cterm.add_constraint(mlEqualsTrue(orBool([disjunct_lhs, disjunct_rhs])))
204212

205213
new_constraints = []
206214
fvs = free_vars(new_cterm.kast)

src/pyk/kast/inner.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,10 +577,10 @@ def __init__(self, *args: Any, **kwargs: Any):
577577
else:
578578
items = args
579579

580-
_items = []
580+
_items: list[KInner] = []
581581
for i in items:
582582
if type(i) is KSequence:
583-
_items.extend(list(i.items))
583+
_items.extend(i.items)
584584
else:
585585
_items.append(i)
586586
items = tuple(_items)

src/pyk/kast/outer.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,14 +1154,21 @@ def greatest_common_subsort(self, sort1: KSort, sort2: KSort) -> KSort | None:
11541154
return None
11551155

11561156
# Sorts like Int cannot be injected directly into sort K so they are embedded in a KSequence.
1157-
def add_ksequence_under_kequal(self, kast: KInner) -> KInner:
1158-
def _add_ksequence_under_kequal(kast: KInner) -> KInner:
1159-
if type(kast) is KApply and kast.label.name == '_==K_':
1160-
return KApply('_==K_', [KSequence(arg) for arg in kast.args])
1161-
else:
1157+
def add_ksequence_under_k_productions(self, kast: KInner) -> KInner:
1158+
def _add_ksequence_under_k_productions(kast: KInner) -> KInner:
1159+
if type(kast) is not KApply:
11621160
return kast
11631161

1164-
return top_down(_add_ksequence_under_kequal, kast)
1162+
prod = self.production_for_klabel(kast.label)
1163+
return KApply(
1164+
kast.label,
1165+
[
1166+
KSequence(arg) if sort.name == 'K' and not self.sort(arg) == KSort('K') else arg
1167+
for arg, sort in zip(kast.args, prod.argument_sorts, strict=True)
1168+
],
1169+
)
1170+
1171+
return top_down(_add_ksequence_under_k_productions, kast)
11651172

11661173
def sort_vars(self, kast: KInner, sort: KSort | None = None) -> KInner:
11671174
if type(kast) is KVariable and kast.sort is None and sort is not None:

src/pyk/kbuild/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
from .kbuild import KBuild
2-
from .package import Package
32
from .project import Project

src/pyk/kbuild/__main__.py

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
1-
import shutil
21
import sys
32
from argparse import ArgumentParser
43
from pathlib import Path
54
from typing import Any
65

76
from ..cli.utils import check_dir_path, dir_path
8-
from .config import KBUILD_DIR, PROJECT_FILE_NAME
7+
from .config import DIST_DIR_NAME, PROJECT_FILE_NAME
98
from .kbuild import KBuild
10-
from .package import Package
9+
from .project import Project
1110
from .utils import find_file_upwards
1211

1312

1413
def main() -> None:
1514
args = vars(_argument_parser().parse_args())
1615
command = args['command']
1716

18-
if command == 'clean':
19-
return do_clean(**args)
20-
2117
if command == 'kompile':
2218
return do_kompile(**args)
2319

@@ -35,38 +31,52 @@ def _argument_parser() -> ArgumentParser:
3531

3632
command_parser = parser.add_subparsers(dest='command', metavar='COMMAND', required=True)
3733

38-
command_parser.add_parser('clean', help='clean build cache')
39-
4034
kompile_parser = command_parser.add_parser('kompile', help='kompile target')
4135
kompile_parser.add_argument('target_name', metavar='TARGET', help='target to build')
36+
kompile_parser.add_argument(
37+
'-o',
38+
'--output',
39+
dest='output_dir',
40+
metavar='OUTPUT',
41+
type=Path,
42+
help='output directory',
43+
)
4244

4345
which_parser = command_parser.add_parser('which', help='print definition directory for target')
4446
which_parser.add_argument('target_name', metavar='TARGET', help='target to print definition directory for')
47+
which_parser.add_argument(
48+
'-o',
49+
'--output',
50+
dest='output_dir',
51+
metavar='OUTPUT',
52+
type=Path,
53+
help='output directory',
54+
)
4555

4656
return parser
4757

4858

49-
def _package(start_dir: Path) -> Package:
50-
project_file = find_file_upwards(PROJECT_FILE_NAME, start_dir)
51-
return Package.create(project_file)
52-
59+
def _project_file(start_dir: Path) -> Path:
60+
return find_file_upwards(PROJECT_FILE_NAME, start_dir)
5361

54-
def do_clean(**kwargs: Any) -> None:
55-
shutil.rmtree(KBUILD_DIR, ignore_errors=True)
5662

63+
def do_kompile(start_dir: Path, target_name: str, output_dir: Path | None, **kwargs: Any) -> None:
64+
project_file = _project_file(start_dir)
65+
project = Project.load(project_file)
66+
kdist_dir = output_dir or project_file.parent / DIST_DIR_NAME
67+
kbuild = KBuild(kdist_dir)
5768

58-
def do_kompile(start_dir: Path, target_name: str, **kwargs: Any) -> None:
59-
package = _package(start_dir)
60-
kbuild = KBuild()
61-
definition_dir = kbuild.kompile(package, target_name)
69+
definition_dir = kbuild.kompile(project, target_name)
6270
print(definition_dir)
6371

6472

65-
def do_which(start_dir: Path, target_name: str, **kwargs: Any) -> None:
66-
package = _package(start_dir)
67-
kbuild = KBuild()
68-
definition_dir = kbuild.definition_dir(package, target_name)
73+
def do_which(start_dir: Path, target_name: str, output_dir: Path | None, **kwargs: Any) -> None:
74+
project_file = _project_file(start_dir)
75+
project = Project.load(project_file)
76+
kdist_dir = output_dir or project_file.parent / DIST_DIR_NAME
77+
kbuild = KBuild(kdist_dir)
6978

79+
definition_dir = kbuild.definition_dir(project, target_name)
7080
try:
7181
check_dir_path(definition_dir)
7282
except ValueError as e:

0 commit comments

Comments
 (0)