PySMT 0.9.7.dev408__tar.gz → 0.9.7.dev423__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pysmt-0.9.7.dev408/PySMT.egg-info → pysmt-0.9.7.dev423}/PKG-INFO +1 -1
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423/PySMT.egg-info}/PKG-INFO +1 -1
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/__init__.py +1 -1
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/rewritings.py +168 -6
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/substituter.py +5 -3
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_cnf.py +21 -22
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_regressions.py +1 -1
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_walkers.py +16 -1
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/LICENSE +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/MANIFEST.in +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/NOTICE +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/PySMT.egg-info/SOURCES.txt +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/PySMT.egg-info/dependency_links.txt +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/PySMT.egg-info/entry_points.txt +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/PySMT.egg-info/top_level.txt +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/README.rst +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/CHANGES.rst +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/api_ref.rst +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/development.rst +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/getting_started.rst +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/index.rst +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/tutorials/boolean_logic.rst +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/tutorials.rst +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/__main__.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/__init__.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/check_version.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/install.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/__init__.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/base.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/bdd.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/btor.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/cvcfive.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/cvcfour.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/msat.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/optimsat.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/pico.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/yices.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/z3.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/shell.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/configuration.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/constants.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/decorators.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/environment.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/exceptions.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/factory.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/fnode.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/formula.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/logics.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/operators.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/__init__.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/goal.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/msat.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/optimizer.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/optimsat.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/yices.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/z3.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/oracles.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/parsing.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/printers.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/shortcuts.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/simplifier.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/__init__.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/annotations.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/commands.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/parser/__init__.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/parser/parser.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/printers.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/script.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/solver.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/utils.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/__init__.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/bdd.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/btor.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/cvcfive.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/cvcfour.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/dynmsat.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/eager.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/interpolation.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/msat.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/options.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/pico.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/portfolio.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/qelim.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/smtlib.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/solver.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/yices.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/z3.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/__init__.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/configs/config1.ini +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/configs/config_bad.ini +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/examples.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/omt_examples.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/optimization_utils.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/__init__.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/parser_utils.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_annotations.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_fuzzed.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_generic_wrapper.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_griggio.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_model_validation.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_omt_lib_solver.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_examples.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_extensibility.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_lra.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_omt.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_arrays.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_lia.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_lira.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_lra.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_nia.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_nra.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_uf.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_ufbv.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_type_error.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_smtlibscript.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_array.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_back.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_bdd.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_bv.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_bv_simplification.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_configuration.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_constants.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_cvc_quantifiers.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_dwf.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_eager_model.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_env.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_euf.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_formula.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_hr_parsing.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_imports.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_int.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_interpolation.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_lira.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_logics.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_models.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_native_qe.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_nia.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_nlira.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_optimization.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_optimizing.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_oracles.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_portfolio.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_printing.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_qe.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_rewritings.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_shannon_expansion.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_simplify.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_size.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_solving.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_sorts.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_string.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_typechecker.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_unsat_cores.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_walker_ext.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/type_checker.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/typing.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/utils.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/walkers/__init__.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/walkers/dag.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/walkers/generic.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/walkers/identitydag.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/walkers/tree.py +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/setup.cfg +0 -0
- {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/setup.py +0 -0
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
from typing import Tuple, Union
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
VERSION: Union[Tuple[int, int, int], Tuple[int, int, int, str, int]] = (0, 9, 7, "dev",
|
|
22
|
+
VERSION: Union[Tuple[int, int, int], Tuple[int, int, int, str, int]] = (0, 9, 7, "dev", 423)
|
|
23
23
|
|
|
24
24
|
# Try to provide human-readable version of latest commit for dev versions
|
|
25
25
|
# E.g. v0.5.1-4-g49a49f2-wip
|
|
@@ -53,10 +53,12 @@ class CNFizer(DagWalker):
|
|
|
53
53
|
def convert(self, formula):
|
|
54
54
|
"""Convert formula into an Equisatisfiable CNF.
|
|
55
55
|
|
|
56
|
-
Returns a set of clauses: a set of
|
|
56
|
+
Returns a set of clauses: a set of sets of literals.
|
|
57
57
|
"""
|
|
58
58
|
tl, _cnf = self.walk(formula)
|
|
59
|
-
|
|
59
|
+
if len(_cnf) == 0:
|
|
60
|
+
return frozenset([frozenset([tl])])
|
|
61
|
+
res = []
|
|
60
62
|
for clause in _cnf:
|
|
61
63
|
if len(clause) == 0:
|
|
62
64
|
return CNFizer.FALSE_CNF
|
|
@@ -66,6 +68,14 @@ class CNFizer(DagWalker):
|
|
|
66
68
|
# Prune clauses that are trivially TRUE
|
|
67
69
|
simp = None
|
|
68
70
|
break
|
|
71
|
+
elif lit == tl:
|
|
72
|
+
# Prune clauses as ~tl -> l1 v ... v lk
|
|
73
|
+
simp = None
|
|
74
|
+
break
|
|
75
|
+
elif lit == self.mgr.Not(tl).simplify():
|
|
76
|
+
# Simplify tl -> l1 v ... v lk
|
|
77
|
+
# into l1 v ... v lk
|
|
78
|
+
continue
|
|
69
79
|
elif not lit.is_false():
|
|
70
80
|
# Prune FALSE literals
|
|
71
81
|
simp.append(lit)
|
|
@@ -126,10 +136,7 @@ class CNFizer(DagWalker):
|
|
|
126
136
|
elif a.is_false():
|
|
127
137
|
return self.mgr.TRUE(), CNFizer.TRUE_CNF
|
|
128
138
|
else:
|
|
129
|
-
|
|
130
|
-
return k, _cnf | frozenset([frozenset([self.mgr.Not(k),
|
|
131
|
-
self.mgr.Not(a).simplify()]),
|
|
132
|
-
frozenset([k, a])])
|
|
139
|
+
return self.mgr.Not(a).simplify(), _cnf
|
|
133
140
|
|
|
134
141
|
def walk_implies(self, formula, args, **kwargs):
|
|
135
142
|
a, cnf_a = args[0]
|
|
@@ -214,6 +221,161 @@ class CNFizer(DagWalker):
|
|
|
214
221
|
# EOC CNFizer
|
|
215
222
|
|
|
216
223
|
|
|
224
|
+
class PolarityCNFizer(CNFizer):
|
|
225
|
+
"""
|
|
226
|
+
Convert formula into an Equisatisfiable CNF using the polarity-based transformation.
|
|
227
|
+
"""
|
|
228
|
+
|
|
229
|
+
def _get_children(self, formula, pol=None):
|
|
230
|
+
if formula.is_not():
|
|
231
|
+
return [(formula.arg(0), not pol)]
|
|
232
|
+
|
|
233
|
+
elif formula.is_implies():
|
|
234
|
+
return [(formula.arg(0), not pol), (formula.arg(1), pol)]
|
|
235
|
+
|
|
236
|
+
elif formula.is_iff():
|
|
237
|
+
return [(formula.arg(0), pol), (formula.arg(1), pol),
|
|
238
|
+
(formula.arg(0), not pol), (formula.arg(1), not pol)]
|
|
239
|
+
|
|
240
|
+
elif formula.is_and() or formula.is_or() or formula.is_quantifier():
|
|
241
|
+
return [(a, pol) for a in formula.args()]
|
|
242
|
+
|
|
243
|
+
elif formula.is_ite():
|
|
244
|
+
# This must be a boolean ITE as we do not recur within
|
|
245
|
+
# theory atoms
|
|
246
|
+
assert self.env.stc.get_type(formula).is_bool_type()
|
|
247
|
+
i, t, e = formula.args()
|
|
248
|
+
return [(i, pol), (i, not pol), (t, pol), (e, pol)]
|
|
249
|
+
|
|
250
|
+
else:
|
|
251
|
+
assert formula.is_str_op() or \
|
|
252
|
+
formula.is_symbol() or \
|
|
253
|
+
formula.is_function_application() or \
|
|
254
|
+
formula.is_bool_constant() or \
|
|
255
|
+
formula.is_theory_relation(), str(formula)
|
|
256
|
+
return []
|
|
257
|
+
|
|
258
|
+
def _push_with_children_to_stack(self, formula, pol=None, **kwargs):
|
|
259
|
+
self.stack.append((True, formula, pol))
|
|
260
|
+
|
|
261
|
+
for s, p in self._get_children(formula, pol):
|
|
262
|
+
# Add only if not memoized already
|
|
263
|
+
key = self._get_key(s, p, **kwargs)
|
|
264
|
+
if key not in self.memoization:
|
|
265
|
+
self.stack.append((False, s, p))
|
|
266
|
+
|
|
267
|
+
def _compute_node_result(self, formula, pol=None, **kwargs):
|
|
268
|
+
key = self._get_key(formula, pol, **kwargs)
|
|
269
|
+
if key not in self.memoization:
|
|
270
|
+
try:
|
|
271
|
+
f = self.functions[formula.node_type()]
|
|
272
|
+
except KeyError:
|
|
273
|
+
f = self.walk_error
|
|
274
|
+
|
|
275
|
+
args = [self.memoization[self._get_key(s, p, **kwargs)] \
|
|
276
|
+
for s, p in self._get_children(formula, pol)]
|
|
277
|
+
|
|
278
|
+
self.memoization[key] = f(formula, args=args, pol=pol, **kwargs)
|
|
279
|
+
else:
|
|
280
|
+
pass
|
|
281
|
+
|
|
282
|
+
def _process_stack(self, **kwargs):
|
|
283
|
+
while self.stack:
|
|
284
|
+
(was_expanded, formula, pol) = self.stack.pop()
|
|
285
|
+
if was_expanded:
|
|
286
|
+
self._compute_node_result(formula, pol, **kwargs)
|
|
287
|
+
else:
|
|
288
|
+
self._push_with_children_to_stack(formula, pol, **kwargs)
|
|
289
|
+
|
|
290
|
+
def iter_walk(self, formula, **kwargs):
|
|
291
|
+
self.stack.append((False, formula, True))
|
|
292
|
+
self._process_stack(**kwargs)
|
|
293
|
+
res_key = self._get_key(formula, pol=True, **kwargs)
|
|
294
|
+
return self.memoization[res_key]
|
|
295
|
+
|
|
296
|
+
def _get_key(self, formula, pol=None, **kwargs):
|
|
297
|
+
return formula, pol
|
|
298
|
+
|
|
299
|
+
def walk_and(self, formula, args, pol=None, **kwargs):
|
|
300
|
+
if len(args) == 1:
|
|
301
|
+
return args[0]
|
|
302
|
+
|
|
303
|
+
k = self._key_var(formula)
|
|
304
|
+
_cnf = [clause for a, c in args for clause in c]
|
|
305
|
+
if pol:
|
|
306
|
+
_cnf.extend(frozenset([a, self.mgr.Not(k)]) for a, _ in args)
|
|
307
|
+
else:
|
|
308
|
+
_cnf.extend([frozenset([k] + [self.mgr.Not(a).simplify() for a, _ in args])])
|
|
309
|
+
|
|
310
|
+
return k, frozenset(_cnf)
|
|
311
|
+
|
|
312
|
+
def walk_or(self, formula, args, pol=None, **kwargs):
|
|
313
|
+
if len(args) == 1:
|
|
314
|
+
return args[0]
|
|
315
|
+
|
|
316
|
+
k = self._key_var(formula)
|
|
317
|
+
_cnf = [clause for a, c in args for clause in c]
|
|
318
|
+
if pol:
|
|
319
|
+
_cnf.extend([frozenset([self.mgr.Not(k)] + [a for a, _ in args])])
|
|
320
|
+
else:
|
|
321
|
+
_cnf.extend(frozenset([k, self.mgr.Not(a).simplify()]) for a, c in args)
|
|
322
|
+
|
|
323
|
+
return k, frozenset(_cnf)
|
|
324
|
+
|
|
325
|
+
def walk_implies(self, formula, args, pol=None, **kwargs):
|
|
326
|
+
a, cnf_a = args[0]
|
|
327
|
+
b, cnf_b = args[1]
|
|
328
|
+
|
|
329
|
+
k = self._key_var(formula)
|
|
330
|
+
not_a = self.mgr.Not(a).simplify()
|
|
331
|
+
not_b = self.mgr.Not(b).simplify()
|
|
332
|
+
not_k = self.mgr.Not(k)
|
|
333
|
+
_cnf = []
|
|
334
|
+
if pol:
|
|
335
|
+
_cnf.extend([frozenset([not_a, b, not_k])])
|
|
336
|
+
else:
|
|
337
|
+
_cnf.extend([frozenset([a, k]), frozenset([not_b, k])])
|
|
338
|
+
|
|
339
|
+
return k, (cnf_a | cnf_b | frozenset(_cnf))
|
|
340
|
+
|
|
341
|
+
def walk_iff(self, formula, args, pol=None, **kwargs):
|
|
342
|
+
a, cnf_ap = args[0]
|
|
343
|
+
b, cnf_bp = args[1]
|
|
344
|
+
_, cnf_an = args[2]
|
|
345
|
+
_, cnf_bn = args[3]
|
|
346
|
+
|
|
347
|
+
k = self._key_var(formula)
|
|
348
|
+
not_a = self.mgr.Not(a).simplify()
|
|
349
|
+
not_b = self.mgr.Not(b).simplify()
|
|
350
|
+
not_k = self.mgr.Not(k)
|
|
351
|
+
|
|
352
|
+
return k, (cnf_ap | cnf_an | cnf_bp | cnf_bn
|
|
353
|
+
| frozenset([frozenset([not_a, not_b, k]),
|
|
354
|
+
frozenset([not_a, b, not_k]),
|
|
355
|
+
frozenset([a, not_b, not_k]),
|
|
356
|
+
frozenset([a, b, k])]))
|
|
357
|
+
|
|
358
|
+
def walk_ite(self, formula, args, pol=None, **kwargs):
|
|
359
|
+
if any(a == CNFizer.THEORY_PLACEHOLDER for a in args):
|
|
360
|
+
return CNFizer.THEORY_PLACEHOLDER
|
|
361
|
+
(i, cnf_ip), (_, cnf_in), (t, cnf_t), (e, cnf_e) = args
|
|
362
|
+
k = self._key_var(formula)
|
|
363
|
+
not_i = self.mgr.Not(i).simplify()
|
|
364
|
+
not_t = self.mgr.Not(t).simplify()
|
|
365
|
+
not_e = self.mgr.Not(e).simplify()
|
|
366
|
+
not_k = self.mgr.Not(k)
|
|
367
|
+
|
|
368
|
+
_cnf = []
|
|
369
|
+
if pol:
|
|
370
|
+
_cnf.extend([frozenset([not_i, t, not_k]), frozenset([i, e, not_k])])
|
|
371
|
+
else:
|
|
372
|
+
_cnf.extend([frozenset([not_i, not_t, k]), frozenset([i, not_e, k])])
|
|
373
|
+
|
|
374
|
+
return k, (cnf_ip | cnf_in | cnf_t | cnf_e | frozenset(_cnf))
|
|
375
|
+
|
|
376
|
+
# EOC PolarityCNFizer
|
|
377
|
+
|
|
378
|
+
|
|
217
379
|
class NNFizer(DagWalker):
|
|
218
380
|
"""Converts a formula into Negation Normal Form.
|
|
219
381
|
|
|
@@ -151,7 +151,8 @@ class Substituter(pysmt.walkers.IdentityDagWalker):
|
|
|
151
151
|
# 2. We apply the substitution on the quantifier body with
|
|
152
152
|
# the new 'reduced' map
|
|
153
153
|
sub = self.__class__(self.env)
|
|
154
|
-
res_formula = sub.substitute(formula.arg(0), new_subs
|
|
154
|
+
res_formula = sub.substitute(formula.arg(0), subs=new_subs,
|
|
155
|
+
interpretations=kwargs.get('interpretations', None))
|
|
155
156
|
|
|
156
157
|
# 3. We invoke the relevant function (walk_exists or
|
|
157
158
|
# walk_forall) to compute the substitution
|
|
@@ -304,8 +305,9 @@ class MSSubstituter(Substituter):
|
|
|
304
305
|
def __init__(self, env):
|
|
305
306
|
Substituter.__init__(self, env=env)
|
|
306
307
|
|
|
307
|
-
def substitute(self, formula, subs):
|
|
308
|
-
return Substituter.substitute(self, formula, subs
|
|
308
|
+
def substitute(self, formula, subs=None, interpretations=None):
|
|
309
|
+
return Substituter.substitute(self, formula, subs,
|
|
310
|
+
interpretations=interpretations)
|
|
309
311
|
|
|
310
312
|
def _substitute(self, formula, substitutions):
|
|
311
313
|
"""Returns the substitution for formula, if one is defined, otherwise
|
|
@@ -19,7 +19,7 @@ import os
|
|
|
19
19
|
import pytest
|
|
20
20
|
|
|
21
21
|
from pysmt.shortcuts import Implies, is_sat, is_valid, reset_env, Symbol, Iff, Select, ArrayType, INT, BOOL, And, get_env
|
|
22
|
-
from pysmt.rewritings import CNFizer
|
|
22
|
+
from pysmt.rewritings import CNFizer, PolarityCNFizer
|
|
23
23
|
from pysmt.logics import QF_BOOL, QF_LRA, QF_LIA, QF_UFLIRA, QF_UFLRA, QF_ALIA
|
|
24
24
|
from pysmt.test import TestCase, skipIfNoSolverForLogic, main
|
|
25
25
|
from pysmt.test.examples import get_example_formulae
|
|
@@ -29,16 +29,16 @@ from pysmt.smtlib.parser import get_formula_fname
|
|
|
29
29
|
class TestCnf(TestCase):
|
|
30
30
|
|
|
31
31
|
def do_examples(self, logic):
|
|
32
|
-
conv
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
for conv in (CNFizer(), PolarityCNFizer()):
|
|
33
|
+
for example in get_example_formulae():
|
|
34
|
+
if example.logic != logic:
|
|
35
|
+
continue
|
|
36
|
+
cnf = conv.convert_as_formula(example.expr)
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
self.assertValid(Implies(cnf, example.expr), logic=logic)
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
res = is_sat(cnf, logic=logic)
|
|
41
|
+
self.assertEqual(res, example.is_sat)
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
@skipIfNoSolverForLogic(QF_BOOL)
|
|
@@ -80,31 +80,30 @@ class TestCnf(TestCase):
|
|
|
80
80
|
|
|
81
81
|
def _smtlib_cnf(self, filename, logic, res_is_sat):
|
|
82
82
|
reset_env()
|
|
83
|
-
conv = CNFizer()
|
|
84
83
|
smtfile = os.path.join(SMTLIB_DIR, filename)
|
|
85
84
|
assert os.path.exists(smtfile)
|
|
86
85
|
|
|
87
86
|
expr = get_formula_fname(smtfile)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
87
|
+
for conv in (CNFizer(), PolarityCNFizer()):
|
|
88
|
+
if not logic.quantifier_free:
|
|
89
|
+
with self.assertRaises(NotImplementedError):
|
|
90
|
+
conv.convert_as_formula(expr)
|
|
91
|
+
return
|
|
92
|
+
cnf = conv.convert_as_formula(expr)
|
|
93
|
+
self.assertTrue(is_valid(Implies(cnf, expr), logic=logic))
|
|
92
94
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
res = is_sat(cnf, logic=logic)
|
|
97
|
-
self.assertEqual(res, res_is_sat)
|
|
95
|
+
res = is_sat(cnf, logic=logic)
|
|
96
|
+
self.assertEqual(res, res_is_sat)
|
|
98
97
|
|
|
99
98
|
@skipIfNoSolverForLogic(QF_BOOL)
|
|
100
99
|
def test_implies(self):
|
|
101
100
|
a,b,c,d = (Symbol(x) for x in "abcd")
|
|
102
101
|
f = Implies(Iff(a, b), Iff(c, d))
|
|
103
102
|
|
|
104
|
-
conv
|
|
105
|
-
|
|
103
|
+
for conv in [CNFizer(), PolarityCNFizer()]:
|
|
104
|
+
cnf = conv.convert_as_formula(f)
|
|
106
105
|
|
|
107
|
-
|
|
106
|
+
self.assertValid(Implies(cnf, f), logic=QF_BOOL)
|
|
108
107
|
|
|
109
108
|
@skipIfNoSolverForLogic(QF_ALIA)
|
|
110
109
|
def test_CNFizer_bool_theory(self):
|
|
@@ -26,7 +26,7 @@ from pysmt.test import TestCase, main
|
|
|
26
26
|
from pysmt.formula import FormulaManager
|
|
27
27
|
from pysmt.test.examples import get_example_formulae
|
|
28
28
|
from pysmt.exceptions import UnsupportedOperatorError, PysmtTypeError
|
|
29
|
-
from pysmt.substituter import MSSubstituter, MGSubstituter
|
|
29
|
+
from pysmt.substituter import FunctionInterpretation, MSSubstituter, MGSubstituter
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class TestWalkers(TestCase):
|
|
@@ -78,6 +78,21 @@ class TestWalkers(TestCase):
|
|
|
78
78
|
with self.assertRaisesRegex(PysmtTypeError, "substitute()"):
|
|
79
79
|
substitute(f, {x:x})
|
|
80
80
|
|
|
81
|
+
def test_substituter_interpretations_in_quantifiers(self):
|
|
82
|
+
x = Symbol("x", INT)
|
|
83
|
+
UF_XOR = Symbol('uf_xor', FunctionType(INT, [INT, INT]))
|
|
84
|
+
f = ForAll([x], Equals(Function(UF_XOR, [x, x]), Int(0)))
|
|
85
|
+
|
|
86
|
+
class XORInterpreter(FunctionInterpretation):
|
|
87
|
+
def __init__(self): pass
|
|
88
|
+
def interpret(self, env, args):
|
|
89
|
+
if args[0] == args[1]: return Int(0)
|
|
90
|
+
return Function(UF_XOR, args)
|
|
91
|
+
|
|
92
|
+
subs = f.substitute({}, interpretations={UF_XOR: XORInterpreter()})
|
|
93
|
+
|
|
94
|
+
self.assertEqual(subs, ForAll([x], Equals(Int(0), Int(0))))
|
|
95
|
+
|
|
81
96
|
def test_undefined_node(self):
|
|
82
97
|
varA = Symbol("At", INT)
|
|
83
98
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|