PySMT 0.9.7.dev414__tar.gz → 0.9.7.dev426__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.dev414/PySMT.egg-info → pysmt-0.9.7.dev426}/PKG-INFO +1 -1
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426/PySMT.egg-info}/PKG-INFO +1 -1
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/__init__.py +1 -1
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/rewritings.py +168 -6
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/z3.py +8 -5
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_back.py +29 -3
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_cnf.py +21 -22
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_regressions.py +1 -1
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/LICENSE +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/MANIFEST.in +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/NOTICE +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/PySMT.egg-info/SOURCES.txt +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/PySMT.egg-info/dependency_links.txt +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/PySMT.egg-info/entry_points.txt +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/PySMT.egg-info/top_level.txt +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/README.rst +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/CHANGES.rst +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/api_ref.rst +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/development.rst +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/getting_started.rst +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/index.rst +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/tutorials/boolean_logic.rst +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/tutorials.rst +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/__main__.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/__init__.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/check_version.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/install.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/__init__.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/base.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/bdd.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/btor.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/cvcfive.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/cvcfour.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/msat.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/optimsat.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/pico.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/yices.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/z3.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/shell.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/configuration.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/constants.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/decorators.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/environment.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/exceptions.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/factory.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/fnode.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/formula.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/logics.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/operators.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/__init__.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/goal.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/msat.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/optimizer.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/optimsat.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/yices.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/z3.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/oracles.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/parsing.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/printers.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/shortcuts.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/simplifier.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/__init__.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/annotations.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/commands.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/parser/__init__.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/parser/parser.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/printers.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/script.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/solver.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/utils.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/__init__.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/bdd.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/btor.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/cvcfive.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/cvcfour.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/dynmsat.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/eager.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/interpolation.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/msat.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/options.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/pico.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/portfolio.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/qelim.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/smtlib.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/solver.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/yices.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/substituter.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/__init__.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/configs/config1.ini +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/configs/config_bad.ini +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/examples.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/omt_examples.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/optimization_utils.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/__init__.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/parser_utils.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_annotations.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_fuzzed.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_generic_wrapper.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_griggio.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_model_validation.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_omt_lib_solver.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_examples.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_extensibility.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_lra.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_omt.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_arrays.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_lia.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_lira.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_lra.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_nia.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_nra.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_uf.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_ufbv.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_type_error.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_smtlibscript.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_array.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_bdd.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_bv.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_bv_simplification.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_configuration.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_constants.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_cvc_quantifiers.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_dwf.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_eager_model.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_env.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_euf.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_formula.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_hr_parsing.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_imports.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_int.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_interpolation.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_lira.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_logics.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_models.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_native_qe.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_nia.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_nlira.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_optimization.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_optimizing.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_oracles.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_portfolio.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_printing.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_qe.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_rewritings.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_shannon_expansion.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_simplify.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_size.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_solving.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_sorts.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_string.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_typechecker.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_unsat_cores.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_walker_ext.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_walkers.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/type_checker.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/typing.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/utils.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/walkers/__init__.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/walkers/dag.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/walkers/generic.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/walkers/identitydag.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/walkers/tree.py +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/setup.cfg +0 -0
- {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/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", 426)
|
|
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
|
|
|
@@ -340,12 +340,12 @@ class Z3Converter(Converter, DagWalker):
|
|
|
340
340
|
z3.Z3_OP_IMPLIES: lambda args, expr: self.mgr.Implies(args[0], args[1]),
|
|
341
341
|
z3.Z3_OP_ITE: lambda args, expr: self.mgr.Ite(args[0], args[1], args[2]),
|
|
342
342
|
z3.Z3_OP_TO_REAL: lambda args, expr: self.mgr.ToReal(args[0]),
|
|
343
|
-
z3.Z3_OP_BAND : lambda args, expr: self.mgr.BVAnd(args
|
|
344
|
-
z3.Z3_OP_BOR : lambda args, expr: self.mgr.BVOr(args
|
|
343
|
+
z3.Z3_OP_BAND : lambda args, expr: self.mgr.BVAnd(args),
|
|
344
|
+
z3.Z3_OP_BOR : lambda args, expr: self.mgr.BVOr(args),
|
|
345
345
|
z3.Z3_OP_BXOR : lambda args, expr: self.mgr.BVXor(args[0], args[1]),
|
|
346
346
|
z3.Z3_OP_BNOT : lambda args, expr: self.mgr.BVNot(args[0]),
|
|
347
347
|
z3.Z3_OP_BNEG : lambda args, expr: self.mgr.BVNeg(args[0]),
|
|
348
|
-
z3.Z3_OP_CONCAT : lambda args, expr: self.mgr.BVConcat(args
|
|
348
|
+
z3.Z3_OP_CONCAT : lambda args, expr: self.mgr.BVConcat(args),
|
|
349
349
|
z3.Z3_OP_ULT : lambda args, expr: self.mgr.BVULT(args[0], args[1]),
|
|
350
350
|
z3.Z3_OP_ULEQ : lambda args, expr: self.mgr.BVULE(args[0], args[1]),
|
|
351
351
|
z3.Z3_OP_SLT : lambda args, expr: self.mgr.BVSLT(args[0], args[1]),
|
|
@@ -354,8 +354,8 @@ class Z3Converter(Converter, DagWalker):
|
|
|
354
354
|
z3.Z3_OP_UGEQ : lambda args, expr: self.mgr.BVUGE(args[0], args[1]),
|
|
355
355
|
z3.Z3_OP_SGT : lambda args, expr: self.mgr.BVSGT(args[0], args[1]),
|
|
356
356
|
z3.Z3_OP_SGEQ : lambda args, expr: self.mgr.BVSGE(args[0], args[1]),
|
|
357
|
-
z3.Z3_OP_BADD : lambda args, expr: self.mgr.BVAdd(args
|
|
358
|
-
z3.Z3_OP_BMUL : lambda args, expr: self.mgr.BVMul(args
|
|
357
|
+
z3.Z3_OP_BADD : lambda args, expr: self.mgr.BVAdd(args),
|
|
358
|
+
z3.Z3_OP_BMUL : lambda args, expr: self.mgr.BVMul(args),
|
|
359
359
|
z3.Z3_OP_BUDIV : lambda args, expr: self.mgr.BVUDiv(args[0], args[1]),
|
|
360
360
|
z3.Z3_OP_BSDIV : lambda args, expr: self.mgr.BVSDiv(args[0], args[1]),
|
|
361
361
|
z3.Z3_OP_BUREM : lambda args, expr: self.mgr.BVURem(args[0], args[1]),
|
|
@@ -513,6 +513,9 @@ class Z3Converter(Converter, DagWalker):
|
|
|
513
513
|
assert not len(args) > 2 or \
|
|
514
514
|
(z3.is_and(expr) or z3.is_or(expr) or
|
|
515
515
|
z3.is_add(expr) or z3.is_mul(expr) or
|
|
516
|
+
z3.is_app_of(expr, z3.Z3_OP_BAND) or z3.is_app_of(expr, z3.Z3_OP_BOR) or
|
|
517
|
+
z3.is_app_of(expr, z3.Z3_OP_BADD) or z3.is_app_of(expr, z3.Z3_OP_BMUL) or
|
|
518
|
+
z3.is_app_of(expr, z3.Z3_OP_CONCAT) or
|
|
516
519
|
(len(args) == 3 and (z3.is_ite(expr) or z3.is_array_store(expr)))),\
|
|
517
520
|
"Unexpected n-ary term: %s" % expr
|
|
518
521
|
|
|
@@ -16,11 +16,12 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
#
|
|
18
18
|
from pysmt.shortcuts import FreshSymbol, GT, And, Plus, Real, Int, LE, Iff
|
|
19
|
-
from pysmt.shortcuts import Solver
|
|
20
|
-
from pysmt.
|
|
19
|
+
from pysmt.shortcuts import Solver, Symbol, EqualsOrIff
|
|
20
|
+
from pysmt.shortcuts import BVAdd, BVMul, BVAnd, BVOr, BVConcat
|
|
21
|
+
from pysmt.typing import REAL, INT, BVType
|
|
21
22
|
from pysmt.test import TestCase, skipIfSolverNotAvailable, main
|
|
22
23
|
from pysmt.test.examples import get_example_formulae
|
|
23
|
-
from pysmt.logics import QF_UFLIRA
|
|
24
|
+
from pysmt.logics import QF_UFLIRA, QF_BV
|
|
24
25
|
from pysmt.exceptions import NoSolverAvailableError
|
|
25
26
|
|
|
26
27
|
|
|
@@ -87,6 +88,31 @@ class TestBasic(TestCase):
|
|
|
87
88
|
self.do_back("z3", via_smtlib=True)
|
|
88
89
|
self.do_back("z3", via_smtlib=False)
|
|
89
90
|
|
|
91
|
+
@skipIfSolverNotAvailable("z3")
|
|
92
|
+
def test_z3_back_nary_bv(self):
|
|
93
|
+
# Z3 simplification can produce n-ary (more than two arguments)
|
|
94
|
+
# bit-vector operations. Back-converting them used to fail because
|
|
95
|
+
# only the binary case was handled (unlike the integer operations).
|
|
96
|
+
import z3 # type: ignore[import]
|
|
97
|
+
|
|
98
|
+
s = Solver(name="z3", logic=QF_BV)
|
|
99
|
+
conv = s.converter
|
|
100
|
+
a = Symbol("a", BVType(8))
|
|
101
|
+
b = Symbol("b", BVType(8))
|
|
102
|
+
c = Symbol("c", BVType(8))
|
|
103
|
+
|
|
104
|
+
for f in (BVAdd(BVAdd(a, b), c),
|
|
105
|
+
BVMul(BVMul(a, b), c),
|
|
106
|
+
BVAnd(BVAnd(a, b), c),
|
|
107
|
+
BVOr(BVOr(a, b), c),
|
|
108
|
+
BVConcat(BVConcat(a, b), c)):
|
|
109
|
+
# Simplify in Z3 to flatten the associative operators into a
|
|
110
|
+
# single n-ary application before converting back.
|
|
111
|
+
simplified = z3.simplify(conv.convert(f))
|
|
112
|
+
res = conv.back(simplified)
|
|
113
|
+
self.assertValid(EqualsOrIff(f, res), logic=QF_BV,
|
|
114
|
+
solver_name="z3")
|
|
115
|
+
|
|
90
116
|
|
|
91
117
|
if __name__ == '__main__':
|
|
92
118
|
main()
|
|
@@ -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):
|
|
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
|