|
6 | 6 | from typing import TYPE_CHECKING |
7 | 7 |
|
8 | 8 | from ..kast import KInner |
9 | | -from ..kast.inner import KApply, KRewrite, KToken, Subst, bottom_up |
| 9 | +from ..kast.inner import KApply, KRewrite, KToken, KVariable, Subst, bottom_up |
10 | 10 | from ..kast.manip import ( |
11 | 11 | abstract_term_safely, |
12 | 12 | build_claim, |
13 | 13 | build_rule, |
| 14 | + extract_subst, |
14 | 15 | flatten_label, |
15 | 16 | free_vars, |
16 | 17 | ml_pred_to_bool, |
|
20 | 21 | split_config_and_constraints, |
21 | 22 | split_config_from, |
22 | 23 | ) |
23 | | -from ..prelude.k import GENERATED_TOP_CELL |
| 24 | +from ..prelude.k import GENERATED_TOP_CELL, K |
24 | 25 | from ..prelude.kbool import andBool, orBool |
25 | | -from ..prelude.ml import is_bottom, is_top, mlAnd, mlBottom, mlEqualsTrue, mlImplies, mlTop |
| 26 | +from ..prelude.ml import is_bottom, is_top, mlAnd, mlBottom, mlEquals, mlEqualsTrue, mlImplies, mlTop |
26 | 27 | from ..utils import unique |
27 | 28 |
|
28 | 29 | if TYPE_CHECKING: |
@@ -217,17 +218,7 @@ def anti_unify( |
217 | 218 | if KToken('true', 'Bool') not in [disjunct_lhs, disjunct_rhs]: |
218 | 219 | new_cterm = new_cterm.add_constraint(mlEqualsTrue(orBool([disjunct_lhs, disjunct_rhs]))) |
219 | 220 |
|
220 | | - new_constraints = [] |
221 | | - fvs = new_cterm.free_vars |
222 | | - len_fvs = 0 |
223 | | - while len_fvs < len(fvs): |
224 | | - len_fvs = len(fvs) |
225 | | - for constraint in common_constraints: |
226 | | - if constraint not in new_constraints: |
227 | | - constraint_fvs = free_vars(constraint) |
228 | | - if any(fv in fvs for fv in constraint_fvs): |
229 | | - new_constraints.append(constraint) |
230 | | - fvs = fvs | constraint_fvs |
| 221 | + new_constraints = remove_useless_constraints(common_constraints, new_cterm.free_vars) |
231 | 222 |
|
232 | 223 | for constraint in new_constraints: |
233 | 224 | new_cterm = new_cterm.add_constraint(constraint) |
@@ -341,6 +332,26 @@ def from_dict(dct: dict[str, Any]) -> CSubst: |
341 | 332 | constraints = (KInner.from_dict(c) for c in dct['constraints']) |
342 | 333 | return CSubst(subst=subst, constraints=constraints) |
343 | 334 |
|
| 335 | + @staticmethod |
| 336 | + def from_pred(pred: KInner) -> CSubst: |
| 337 | + """Extract from a boolean predicate a CSubst.""" |
| 338 | + subst, pred = extract_subst(pred) |
| 339 | + return CSubst(subst=subst, constraints=flatten_label('#And', pred)) |
| 340 | + |
| 341 | + def pred(self, sort_with: KDefinition | None = None, subst: bool = True, constraints: bool = True) -> KInner: |
| 342 | + """Return an ML predicate representing this substitution.""" |
| 343 | + _preds: list[KInner] = [] |
| 344 | + if subst: |
| 345 | + for k, v in self.subst.minimize().items(): |
| 346 | + sort = K |
| 347 | + if sort_with is not None: |
| 348 | + _sort = sort_with.sort(v) |
| 349 | + sort = _sort if _sort is not None else sort |
| 350 | + _preds.append(mlEquals(KVariable(k, sort=sort), v, arg_sort=sort)) |
| 351 | + if constraints: |
| 352 | + _preds.extend(self.constraints) |
| 353 | + return mlAnd(_preds) |
| 354 | + |
344 | 355 | @property |
345 | 356 | def constraint(self) -> KInner: |
346 | 357 | """Return the set of constraints as a single flattened constraint using `mlAnd`.""" |
|
0 commit comments