PySMT 0.9.7.dev452__tar.gz → 0.9.7.dev461__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.dev452/PySMT.egg-info → pysmt-0.9.7.dev461}/PKG-INFO +1 -1
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461/PySMT.egg-info}/PKG-INFO +1 -1
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/README.rst +19 -19
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/__init__.py +1 -1
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/exceptions.py +10 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/factory.py +13 -2
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/formula.py +3 -2
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/parsing.py +5 -1
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/msat.py +60 -13
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/solver.py +23 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/z3.py +9 -4
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/examples.py +4 -4
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_env.py +12 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_nlira.py +28 -32
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_regressions.py +61 -1
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_solving.py +0 -1
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/LICENSE +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/MANIFEST.in +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/NOTICE +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/PySMT.egg-info/SOURCES.txt +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/PySMT.egg-info/dependency_links.txt +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/PySMT.egg-info/entry_points.txt +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/PySMT.egg-info/top_level.txt +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/docs/CHANGES.rst +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/docs/api_ref.rst +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/docs/development.rst +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/docs/getting_started.rst +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/docs/index.rst +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/docs/tutorials/boolean_logic.rst +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/docs/tutorials.rst +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/__main__.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/__init__.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/check_version.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/install.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/installers/__init__.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/installers/base.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/installers/bdd.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/installers/btor.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/installers/cvcfive.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/installers/cvcfour.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/installers/msat.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/installers/optimsat.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/installers/pico.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/installers/yices.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/installers/z3.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/cmd/shell.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/configuration.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/constants.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/decorators.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/environment.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/fnode.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/logics.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/operators.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/optimization/__init__.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/optimization/goal.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/optimization/msat.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/optimization/optimizer.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/optimization/optimsat.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/optimization/yices.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/optimization/z3.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/oracles.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/printers.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/rewritings.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/shortcuts.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/simplifier.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/smtlib/__init__.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/smtlib/annotations.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/smtlib/commands.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/smtlib/parser/__init__.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/smtlib/parser/parser.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/smtlib/printers.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/smtlib/script.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/smtlib/solver.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/smtlib/utils.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/__init__.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/bdd.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/btor.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/cvcfive.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/cvcfour.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/dynmsat.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/eager.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/interpolation.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/options.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/pico.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/portfolio.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/qelim.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/smtlib.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/solvers/yices.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/substituter.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/__init__.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/configs/config1.ini +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/configs/config_bad.ini +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/omt_examples.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/optimization_utils.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/__init__.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/parser_utils.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_annotations.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_fuzzed.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_generic_wrapper.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_griggio.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_model_validation.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_omt_lib_solver.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_parser_examples.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_parser_extensibility.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_parser_lra.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_parser_omt.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_parser_qf_arrays.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_parser_qf_lia.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_parser_qf_lira.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_parser_qf_lra.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_parser_qf_nia.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_parser_qf_nra.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_parser_qf_uf.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_parser_qf_ufbv.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_parser_type_error.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/smtlib/test_smtlibscript.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_array.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_back.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_bdd.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_bv.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_bv_simplification.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_cnf.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_configuration.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_constants.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_cvc_quantifiers.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_dwf.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_eager_model.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_euf.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_formula.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_hr_parsing.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_imports.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_int.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_interpolation.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_lira.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_logics.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_models.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_native_qe.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_nia.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_optimization.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_optimizing.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_oracles.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_portfolio.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_printing.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_qe.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_rewritings.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_shannon_expansion.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_simplify.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_size.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_sorts.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_string.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_typechecker.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_unsat_cores.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_walker_ext.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/test/test_walkers.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/type_checker.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/typing.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/utils.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/walkers/__init__.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/walkers/dag.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/walkers/generic.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/walkers/identitydag.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/pysmt/walkers/tree.py +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/setup.cfg +0 -0
- {pysmt-0.9.7.dev452 → pysmt-0.9.7.dev461}/setup.py +0 -0
|
@@ -232,25 +232,25 @@ Solvers Support
|
|
|
232
232
|
The following table summarizes the features supported via pySMT for
|
|
233
233
|
each of the available solvers.
|
|
234
234
|
|
|
235
|
-
|
|
236
|
-
| Solver | pySMT name| Supported Theories
|
|
237
|
-
|
|
238
|
-
| MathSAT | msat | UF, LIA, LRA, BV, AX
|
|
239
|
-
|
|
240
|
-
| Z3 | z3 | UF, LIA, LRA, BV, AX, NRA, NIA
|
|
241
|
-
|
|
242
|
-
| cvc5 | cvc5 | UF, LIA, LRA, BV, AX, S
|
|
243
|
-
|
|
244
|
-
| Yices | yices | UF, LIA, LRA, BV
|
|
245
|
-
|
|
246
|
-
| Boolector | btor | UF, BV, AX
|
|
247
|
-
|
|
248
|
-
| SMT-Lib Interface| <custom> | UF, LIA, LRA, BV, AX
|
|
249
|
-
|
|
250
|
-
| PicoSAT | picosat | [None]
|
|
251
|
-
|
|
252
|
-
| BDD (CUDD) | bdd | [None]
|
|
253
|
-
|
|
235
|
+
+------------------+-----------+-----------------------------------+-------------+------------------------+------------+--------------+
|
|
236
|
+
| Solver | pySMT name| Supported Theories | Quantifiers | Quantifier Elimination | Unsat Core | Interpolation|
|
|
237
|
+
+==================+===========+===================================+=============+========================+============+==============+
|
|
238
|
+
| MathSAT | msat | UF, LIA, LRA, BV, AX, NRA, NIA | No | msat-fm, msat-lw | Yes | Yes |
|
|
239
|
+
+------------------+-----------+-----------------------------------+-------------+------------------------+------------+--------------+
|
|
240
|
+
| Z3 | z3 | UF, LIA, LRA, BV, AX, NRA, NIA | Yes | z3 | Yes | No |
|
|
241
|
+
+------------------+-----------+-----------------------------------+-------------+------------------------+------------+--------------+
|
|
242
|
+
| cvc5 | cvc5 | UF, LIA, LRA, BV, AX, S, NRA, NIA | Yes | No | No | No |
|
|
243
|
+
+------------------+-----------+-----------------------------------+-------------+------------------------+------------+--------------+
|
|
244
|
+
| Yices | yices | UF, LIA, LRA, BV | No | No | No | No |
|
|
245
|
+
+------------------+-----------+-----------------------------------+-------------+------------------------+------------+--------------+
|
|
246
|
+
| Boolector | btor | UF, BV, AX | No | No | No | No |
|
|
247
|
+
+------------------+-----------+-----------------------------------+-------------+------------------------+------------+--------------+
|
|
248
|
+
| SMT-Lib Interface| <custom> | UF, LIA, LRA, BV, AX | Yes | No | No | No |
|
|
249
|
+
+------------------+-----------+-----------------------------------+-------------+------------------------+------------+--------------+
|
|
250
|
+
| PicoSAT | picosat | [None] | No | [No] | No | No |
|
|
251
|
+
+------------------+-----------+-----------------------------------+-------------+------------------------+------------+--------------+
|
|
252
|
+
| BDD (CUDD) | bdd | [None] | Yes | bdd | No | No |
|
|
253
|
+
+------------------+-----------+-----------------------------------+-------------+------------------------+------------+--------------+
|
|
254
254
|
|
|
255
255
|
|
|
256
256
|
|
|
@@ -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", 461)
|
|
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
|
|
@@ -131,6 +131,16 @@ class PysmtImportError(PysmtException, ImportError):
|
|
|
131
131
|
class PysmtValueError(PysmtException, ValueError):
|
|
132
132
|
pass
|
|
133
133
|
|
|
134
|
+
class PysmtEmptySymbolNameError(PysmtValueError):
|
|
135
|
+
"""A symbol with the empty name was built, but they are not enabled."""
|
|
136
|
+
|
|
137
|
+
def __init__(self):
|
|
138
|
+
PysmtValueError.__init__(
|
|
139
|
+
self,
|
|
140
|
+
"The empty string is not a valid symbol name. SMT-LIB allows it "
|
|
141
|
+
"(as `||`), but not every solver does, so pySMT requires it to be "
|
|
142
|
+
"enabled explicitly by setting `env.allow_empty_var_names = True`.")
|
|
143
|
+
|
|
134
144
|
class PysmtTypeError(PysmtException, TypeError):
|
|
135
145
|
pass
|
|
136
146
|
|
|
@@ -190,13 +190,15 @@ class Factory(object):
|
|
|
190
190
|
|
|
191
191
|
if logic is None:
|
|
192
192
|
logic = default_logic
|
|
193
|
+
assert isinstance(logic, Logic)
|
|
193
194
|
|
|
194
195
|
solvers = self._filter_solvers(solver_list, logic=logic)
|
|
195
196
|
|
|
196
197
|
if solvers is not None and len(solvers) > 0:
|
|
197
198
|
# Pick the first solver based on preference list
|
|
198
199
|
preference_list = self.preferences[solver_type]
|
|
199
|
-
SolverClass = self._pick_favorite(preference_list, solver_list,
|
|
200
|
+
SolverClass = self._pick_favorite(preference_list, solver_list,
|
|
201
|
+
solvers, logic)
|
|
200
202
|
closer_logic = get_closer_logic(SolverClass.LOGICS, logic)
|
|
201
203
|
return SolverClass, closer_logic
|
|
202
204
|
|
|
@@ -205,7 +207,16 @@ class Factory(object):
|
|
|
205
207
|
(solver_type, logic))
|
|
206
208
|
|
|
207
209
|
|
|
208
|
-
def _pick_favorite(self, preference_list: List[str], solver_list: Dict[str, Any],
|
|
210
|
+
def _pick_favorite(self, preference_list: List[str], solver_list: Dict[str, Any],
|
|
211
|
+
solvers: Dict[str, Any], logic: Logic) -> Type[Solver]:
|
|
212
|
+
if not logic.theory.linear:
|
|
213
|
+
# The MathSAT family solves nonlinear problems by incremental
|
|
214
|
+
# linearization, which may not terminate on satisfiable instances
|
|
215
|
+
# whose solutions are all irrational (see the note on
|
|
216
|
+
# MathSAT5Solver.LOGICS). Prefer any other capable solver, but keep
|
|
217
|
+
# them as a fallback when nothing else supports the logic.
|
|
218
|
+
preference_list = sorted(preference_list,
|
|
219
|
+
key=lambda n: n.startswith(("msat", "optimsat")))
|
|
209
220
|
for candidate in preference_list:
|
|
210
221
|
if candidate in solvers:
|
|
211
222
|
return solver_list[candidate]
|
|
@@ -45,7 +45,8 @@ import pysmt.operators as op
|
|
|
45
45
|
from pysmt.fnode import FNode
|
|
46
46
|
from pysmt.typing import PySMTType
|
|
47
47
|
from pysmt.fnode import FNode, FNodeContent
|
|
48
|
-
from pysmt.exceptions import UndefinedSymbolError, PysmtValueError,
|
|
48
|
+
from pysmt.exceptions import (UndefinedSymbolError, PysmtValueError,
|
|
49
|
+
PysmtTypeError, PysmtEmptySymbolNameError)
|
|
49
50
|
from pysmt.walkers.identitydag import IdentityDagWalker
|
|
50
51
|
from pysmt.constants import Fraction, Numeral
|
|
51
52
|
from pysmt.constants import (is_pysmt_fraction,
|
|
@@ -107,7 +108,7 @@ class FormulaManager(object):
|
|
|
107
108
|
|
|
108
109
|
def _create_symbol(self, name: str, typename: PySMTType=types.BOOL) -> FNode:
|
|
109
110
|
if len(name) == 0 and not self.env.allow_empty_var_names:
|
|
110
|
-
raise
|
|
111
|
+
raise PysmtEmptySymbolNameError()
|
|
111
112
|
if not isinstance(typename, types.PySMTType):
|
|
112
113
|
raise PysmtValueError("typename must be a PySMTType.")
|
|
113
114
|
n = self.create_node(node_type=op.SYMBOL,
|
|
@@ -22,7 +22,8 @@ from typing import List, Optional
|
|
|
22
22
|
import pysmt
|
|
23
23
|
import pysmt.typing as types
|
|
24
24
|
from pysmt.environment import get_env
|
|
25
|
-
from pysmt.exceptions import PysmtSyntaxError, UndefinedSymbolError
|
|
25
|
+
from pysmt.exceptions import (PysmtSyntaxError, UndefinedSymbolError,
|
|
26
|
+
PysmtEmptySymbolNameError)
|
|
26
27
|
from pysmt.constants import Fraction
|
|
27
28
|
|
|
28
29
|
|
|
@@ -332,6 +333,9 @@ class Constant(GrammarSymbol):
|
|
|
332
333
|
class Identifier(GrammarSymbol):
|
|
333
334
|
def __init__(self, name, env):
|
|
334
335
|
GrammarSymbol.__init__(self)
|
|
336
|
+
if name == "" and not env.allow_empty_var_names:
|
|
337
|
+
# Otherwise this would be reported as an undefined symbol
|
|
338
|
+
raise PysmtEmptySymbolNameError()
|
|
335
339
|
self.value = env.formula_manager.get_symbol(name)
|
|
336
340
|
if self.value is None:
|
|
337
341
|
raise UndefinedSymbolError(name)
|
|
@@ -35,7 +35,7 @@ from pysmt.utils import assert_not_none
|
|
|
35
35
|
from pysmt.walkers import DagWalker
|
|
36
36
|
from pysmt.exceptions import (SolverReturnedUnknownResultError,
|
|
37
37
|
InternalSolverError,
|
|
38
|
-
|
|
38
|
+
PysmtValueError, PysmtTypeError,
|
|
39
39
|
ConvertExpressionError)
|
|
40
40
|
from pysmt.decorators import clear_pending_pop, catch_conversion_error
|
|
41
41
|
from pysmt.solvers.qelim import QuantifierEliminator
|
|
@@ -180,9 +180,37 @@ class MathSAT5Solver(IncrementalTrackingSolver, UnsatCoreSolver, SmtLibBasicSolv
|
|
|
180
180
|
|
|
181
181
|
__lib_name__ = "mathsat"
|
|
182
182
|
|
|
183
|
+
# NOTE on nonlinear arithmetic (QF_NRA/QF_NIA, and OptiMathSAT, which
|
|
184
|
+
# inherits this LOGICS set).
|
|
185
|
+
#
|
|
186
|
+
# MathSAT solves nonlinear problems by incremental linearization: the
|
|
187
|
+
# nonlinear terms are abstracted away as free symbols and then
|
|
188
|
+
# progressively constrained with linear lemmas, until either the
|
|
189
|
+
# abstraction is refuted (UNSAT) or a model of the abstraction happens to
|
|
190
|
+
# be a model of the original formula (SAT). Every model MathSAT can build
|
|
191
|
+
# therefore assigns *rational* values only; irrational (algebraic) values
|
|
192
|
+
# are not representable.
|
|
193
|
+
#
|
|
194
|
+
# This is fine for UNSAT instances and for SAT instances that admit a
|
|
195
|
+
# rational solution, but not for SAT instances whose solutions are all
|
|
196
|
+
# irrational: on e.g. `x * x = 2` no finite set of linear lemmas refutes
|
|
197
|
+
# the abstraction, and no model of the abstraction ever satisfies the
|
|
198
|
+
# original constraint, so the refinement loop does not terminate. MathSAT
|
|
199
|
+
# diverges rather than returning `unknown`, and there is currently no
|
|
200
|
+
# option to bound the number of refinement rounds. The only available
|
|
201
|
+
# mitigation is a soft timeout installed with `msat_set_termination_test`,
|
|
202
|
+
# which pySMT does not expose, and which could only be wall-clock based
|
|
203
|
+
# (hence non-reproducible), since the internal statistics that would give a
|
|
204
|
+
# deterministic budget cannot be retrieved through the API.
|
|
205
|
+
# See the discussion in https://github.com/pysmt/pysmt/pull/844.
|
|
206
|
+
#
|
|
207
|
+
# Practical consequences:
|
|
208
|
+
# - formulas that need algebraic witnesses must be sent to a solver with a
|
|
209
|
+
# complete NRA decision procedure (z3, cvc5);
|
|
210
|
+
# - the nonlinear examples and tests run against MathSAT are kept
|
|
211
|
+
# rational on purpose (e.g. `r * r = 4.0` instead of `r * r = 2.0`).
|
|
183
212
|
LOGICS: Iterable[Logic] = PYSMT_QF_LOGICS -\
|
|
184
|
-
set(l for l in PYSMT_QF_LOGICS
|
|
185
|
-
if not l.theory.linear or l.theory.strings)
|
|
213
|
+
set(l for l in PYSMT_QF_LOGICS if l.theory.strings)
|
|
186
214
|
|
|
187
215
|
OptionsClass = MathSATOptions
|
|
188
216
|
|
|
@@ -407,6 +435,7 @@ class MSatConverter(Converter, DagWalker):
|
|
|
407
435
|
self._msat_lib.MSAT_TAG_LEQ: self._back_adapter(self.mgr.LE),
|
|
408
436
|
self._msat_lib.MSAT_TAG_PLUS: self._back_adapter(self.mgr.Plus),
|
|
409
437
|
self._msat_lib.MSAT_TAG_TIMES: self._back_adapter(self.mgr.Times),
|
|
438
|
+
self._msat_lib.MSAT_TAG_DIVIDE: self._back_adapter(self.mgr.Div),
|
|
410
439
|
self._msat_lib.MSAT_TAG_BV_MUL: self._back_adapter(self.mgr.BVMul),
|
|
411
440
|
self._msat_lib.MSAT_TAG_BV_ADD: self._back_adapter(self.mgr.BVAdd),
|
|
412
441
|
self._msat_lib.MSAT_TAG_BV_UDIV: self._back_adapter(self.mgr.BVUDiv),
|
|
@@ -463,6 +492,7 @@ class MSatConverter(Converter, DagWalker):
|
|
|
463
492
|
self._msat_lib.MSAT_TAG_LEQ: self._sig_most_generic_bool_binary,
|
|
464
493
|
self._msat_lib.MSAT_TAG_PLUS: self._sig_most_generic_bool_binary,
|
|
465
494
|
self._msat_lib.MSAT_TAG_TIMES: self._sig_most_generic_bool_binary,
|
|
495
|
+
self._msat_lib.MSAT_TAG_DIVIDE: self._sig_most_generic_bool_binary,
|
|
466
496
|
self._msat_lib.MSAT_TAG_FLOOR: lambda term, args:\
|
|
467
497
|
self.tm.FunctionType(types.INT, [types.REAL]),
|
|
468
498
|
self._msat_lib.MSAT_TAG_BV_MUL: self._sig_binary,
|
|
@@ -700,7 +730,7 @@ class MSatConverter(Converter, DagWalker):
|
|
|
700
730
|
val, width = map(int, str(term).split("_"))
|
|
701
731
|
res = self.mgr.BV(val, width)
|
|
702
732
|
elif self._msat_lib.msat_term_is_constant(self.msat_env(), term):
|
|
703
|
-
rep = self._msat_lib.msat_term_repr(term)
|
|
733
|
+
rep = self._restore_empty(self._msat_lib.msat_term_repr(term))
|
|
704
734
|
ty = self._msat_lib.msat_term_get_type(term)
|
|
705
735
|
if self._msat_lib.msat_term_is_boolean_constant(self.msat_env(), term):
|
|
706
736
|
res = self.mgr.Symbol(rep, types.BOOL)
|
|
@@ -987,16 +1017,33 @@ class MSatConverter(Converter, DagWalker):
|
|
|
987
1017
|
|
|
988
1018
|
def walk_times(self, formula: FNode, args: List[Any], **kwargs) -> Any:
|
|
989
1019
|
res = args[0]
|
|
990
|
-
nl_count = 0 if self._msat_lib.msat_term_is_number(self.msat_env(), res) else 1
|
|
991
1020
|
for x in args[1:]:
|
|
992
|
-
|
|
993
|
-
nl_count += 1
|
|
994
|
-
if nl_count >= 2:
|
|
995
|
-
raise NonLinearError(formula)
|
|
996
|
-
else:
|
|
997
|
-
res = self._msat_lib.msat_make_times(self.msat_env(), res, x)
|
|
1021
|
+
res = self._msat_lib.msat_make_times(self.msat_env(), res, x)
|
|
998
1022
|
return res
|
|
999
1023
|
|
|
1024
|
+
def walk_pow(self, formula: FNode, args: List[Any], **kwargs) -> Any:
|
|
1025
|
+
# MathSAT rejects exponents it cannot handle by returning an error
|
|
1026
|
+
# term, which convert() turns into an InternalSolverError.
|
|
1027
|
+
return self._msat_lib.msat_make_pow(self.msat_env(), args[0], args[1])
|
|
1028
|
+
|
|
1029
|
+
def walk_div(self, formula: FNode, args: List[Any], **kwargs) -> Any:
|
|
1030
|
+
num, den = args
|
|
1031
|
+
if self.env.stc.get_type(formula).is_real_type():
|
|
1032
|
+
return self._msat_lib.msat_make_divide(self.msat_env(), num, den)
|
|
1033
|
+
# msat_make_divide is real division, while pySMT follows the SMT-LIB
|
|
1034
|
+
# semantics for integers: den >= 0 ? floor(num/den) : ceil(num/den).
|
|
1035
|
+
# ceil(a) is rewritten as -floor(-a).
|
|
1036
|
+
zero = self._msat_lib.msat_make_number(self.msat_env(), "0")
|
|
1037
|
+
neg = self._msat_lib.msat_make_number(self.msat_env(), "-1")
|
|
1038
|
+
cond = self._msat_lib.msat_make_leq(self.msat_env(), zero, den)
|
|
1039
|
+
div = self._msat_lib.msat_make_floor(self.msat_env(),
|
|
1040
|
+
self._msat_lib.msat_make_divide(self.msat_env(), num, den))
|
|
1041
|
+
n_den = self._msat_lib.msat_make_times(self.msat_env(), neg, den)
|
|
1042
|
+
n_div = self._msat_lib.msat_make_times(self.msat_env(), neg,
|
|
1043
|
+
self._msat_lib.msat_make_floor(self.msat_env(),
|
|
1044
|
+
self._msat_lib.msat_make_divide(self.msat_env(), num, n_den)))
|
|
1045
|
+
return self._msat_lib.msat_make_term_ite(self.msat_env(), cond, div, n_div)
|
|
1046
|
+
|
|
1000
1047
|
def walk_function(self, formula: FNode, args: List[Any], **kwargs) -> Any:
|
|
1001
1048
|
name = formula.function_name()
|
|
1002
1049
|
if name not in self.symbol_to_decl:
|
|
@@ -1094,10 +1141,10 @@ class MSatConverter(Converter, DagWalker):
|
|
|
1094
1141
|
if not var.is_symbol():
|
|
1095
1142
|
raise PysmtTypeError("Trying to declare as a variable something "
|
|
1096
1143
|
"that is not a symbol: %s" % var)
|
|
1097
|
-
if var
|
|
1144
|
+
if var not in self.symbol_to_decl:
|
|
1098
1145
|
tp = self._type_to_msat(var.symbol_type())
|
|
1099
1146
|
decl = self._msat_lib.msat_declare_function(self.msat_env(),
|
|
1100
|
-
var.symbol_name(),
|
|
1147
|
+
self._rename_empty(var.symbol_name()),
|
|
1101
1148
|
tp)
|
|
1102
1149
|
if self._msat_lib.MSAT_ERROR_DECL(decl):
|
|
1103
1150
|
msat_msg = self._msat_lib.msat_last_error_message(self.msat_env())
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
#
|
|
18
18
|
from fractions import Fraction
|
|
19
|
+
import pysmt.formula
|
|
19
20
|
from pysmt.typing import BOOL
|
|
20
21
|
from pysmt.solvers.options import SolverOptions
|
|
21
22
|
from pysmt.decorators import clear_pending_pop
|
|
@@ -566,3 +567,25 @@ class Converter(object):
|
|
|
566
567
|
def back(self, expr: Any, *args: Any, **kwargs: Any) -> FNode:
|
|
567
568
|
"""Convert an expression of the Solver into a PySMT term."""
|
|
568
569
|
raise NotImplementedError
|
|
570
|
+
|
|
571
|
+
# SMT-LIB allows a symbol with the empty name (`||`), but some
|
|
572
|
+
# solvers refuse to declare it (MathSAT) or cannot print it back
|
|
573
|
+
# (Z3). Those converters rename it to a fresh, unused name on the
|
|
574
|
+
# way in and undo the renaming on the way out.
|
|
575
|
+
_empty_name_subst: Optional[str] = None
|
|
576
|
+
mgr: 'pysmt.formula.FormulaManager'
|
|
577
|
+
|
|
578
|
+
def _rename_empty(self, name: str) -> str:
|
|
579
|
+
"""Map a pySMT symbol name to the name used by the solver."""
|
|
580
|
+
if name != "":
|
|
581
|
+
return name
|
|
582
|
+
if self._empty_name_subst is None:
|
|
583
|
+
i = 0
|
|
584
|
+
while ("__pysmt_empty_name_%d" % i) in self.mgr.symbols:
|
|
585
|
+
i += 1
|
|
586
|
+
self._empty_name_subst = "__pysmt_empty_name_%d" % i
|
|
587
|
+
return self._empty_name_subst
|
|
588
|
+
|
|
589
|
+
def _restore_empty(self, name: str) -> str:
|
|
590
|
+
"""Inverse of _rename_empty()."""
|
|
591
|
+
return "" if name == self._empty_name_subst else name
|
|
@@ -573,7 +573,7 @@ class Z3Converter(Converter, DagWalker):
|
|
|
573
573
|
else:
|
|
574
574
|
# it must be a symbol
|
|
575
575
|
try:
|
|
576
|
-
return self.mgr.get_symbol(str(expr))
|
|
576
|
+
return self.mgr.get_symbol(self._restore_empty(str(expr)))
|
|
577
577
|
except UndefinedSymbolError:
|
|
578
578
|
import warnings
|
|
579
579
|
symb_type = self._z3_to_type(expr.sort())
|
|
@@ -582,7 +582,7 @@ class Z3Converter(Converter, DagWalker):
|
|
|
582
582
|
template="__z3_%d")
|
|
583
583
|
elif z3.is_function(expr):
|
|
584
584
|
# This needs to be after we try to convert regular Symbols
|
|
585
|
-
fsymbol = self.mgr.get_symbol(expr.decl().name())
|
|
585
|
+
fsymbol = self.mgr.get_symbol(self._restore_empty(expr.decl().name()))
|
|
586
586
|
return self.mgr.Function(fsymbol, args)
|
|
587
587
|
|
|
588
588
|
# If we reach this point, we did not manage to translate the expression
|
|
@@ -622,6 +622,11 @@ class Z3Converter(Converter, DagWalker):
|
|
|
622
622
|
expr.ast)
|
|
623
623
|
stream_in = StringIO(s)
|
|
624
624
|
r = parser.get_script(stream_in).get_last_formula(self.mgr)
|
|
625
|
+
if self._empty_name_subst is not None:
|
|
626
|
+
# Undo the renaming of the empty symbol name (see Converter)
|
|
627
|
+
src = self.mgr.get_symbol(self._empty_name_subst)
|
|
628
|
+
r = self.env.substituter.substitute(
|
|
629
|
+
r, {src: self.mgr.Symbol("", src.symbol_type())})
|
|
625
630
|
key = (askey(expr), None)
|
|
626
631
|
self._back_memoization[key] = r
|
|
627
632
|
return r
|
|
@@ -642,7 +647,7 @@ class Z3Converter(Converter, DagWalker):
|
|
|
642
647
|
|
|
643
648
|
def walk_symbol(self, formula: FNode, **kwargs) -> z3.Ast:
|
|
644
649
|
symbol_type = formula.symbol_type()
|
|
645
|
-
sname = formula.symbol_name()
|
|
650
|
+
sname = self._rename_empty(formula.symbol_name())
|
|
646
651
|
z3_sname = z3.Z3_mk_string_symbol(self.ctx.ref(), sname)
|
|
647
652
|
if symbol_type.is_bool_type():
|
|
648
653
|
sort_ast = self.z3BoolSort.ast
|
|
@@ -756,7 +761,7 @@ class Z3Converter(Converter, DagWalker):
|
|
|
756
761
|
z3dom[i] = self._type_to_z3(t).ast
|
|
757
762
|
z3ret = self._type_to_z3(tp.return_type).ast
|
|
758
763
|
z3name = z3.Z3_mk_string_symbol(self.ctx.ref(),
|
|
759
|
-
func_name.symbol_name())
|
|
764
|
+
self._rename_empty(func_name.symbol_name()))
|
|
760
765
|
z3func = z3.Z3_mk_func_decl(self.ctx.ref(), z3name,
|
|
761
766
|
arity, z3dom, z3ret)
|
|
762
767
|
self._z3_func_decl_cache[func_name] = z3func
|
|
@@ -925,8 +925,8 @@ def get_full_example_formulae(environment: Optional[Environment]=None) -> List[E
|
|
|
925
925
|
logic=pysmt.logics.QF_NRA
|
|
926
926
|
),
|
|
927
927
|
|
|
928
|
-
Example(hr="(
|
|
929
|
-
expr=Equals(Real(
|
|
928
|
+
Example(hr="(4.0 = (r * r))",
|
|
929
|
+
expr=Equals(Real(4), Times(r,r)),
|
|
930
930
|
is_valid=False,
|
|
931
931
|
is_sat=True,
|
|
932
932
|
logic=pysmt.logics.QF_NRA
|
|
@@ -946,8 +946,8 @@ def get_full_example_formulae(environment: Optional[Environment]=None) -> List[E
|
|
|
946
946
|
logic=pysmt.logics.QF_NRA
|
|
947
947
|
),
|
|
948
948
|
|
|
949
|
-
Example(hr="((r * r * r) =
|
|
950
|
-
expr=Equals(Times(r, r, r), Real(
|
|
949
|
+
Example(hr="((r * r * r) = 27.0)",
|
|
950
|
+
expr=Equals(Times(r, r, r), Real(27)),
|
|
951
951
|
is_valid=False,
|
|
952
952
|
is_sat=True,
|
|
953
953
|
logic=pysmt.logics.QF_NRA
|
|
@@ -203,5 +203,17 @@ class TestEnvironment(TestCase):
|
|
|
203
203
|
factory.get_quantifier_eliminator()
|
|
204
204
|
|
|
205
205
|
|
|
206
|
+
def test_nonlinear_demotes_mathsat(self):
|
|
207
|
+
# The MathSAT family is the last resort on nonlinear logics, but still
|
|
208
|
+
# picked when it is the only capable solver.
|
|
209
|
+
pick = get_env().factory._pick_favorite
|
|
210
|
+
available = {'msat': 'MSAT', 'z3': 'Z3'}
|
|
211
|
+
prefs = ['msat', 'z3']
|
|
212
|
+
self.assertEqual(pick(prefs, available, available, logics.QF_NRA), 'Z3')
|
|
213
|
+
self.assertEqual(pick(prefs, available, available, logics.QF_LRA), 'MSAT')
|
|
214
|
+
only_msat = {'msat': 'MSAT'}
|
|
215
|
+
self.assertEqual(pick(prefs, only_msat, only_msat, logics.QF_NRA), 'MSAT')
|
|
216
|
+
|
|
217
|
+
|
|
206
218
|
if __name__ == '__main__':
|
|
207
219
|
main()
|
|
@@ -24,33 +24,33 @@ from pysmt.shortcuts import FreshSymbol, Times, Equals, Div, Real, Int, Pow
|
|
|
24
24
|
from pysmt.shortcuts import Solver, Symbol, And, Not, is_sat
|
|
25
25
|
from pysmt.typing import REAL, INT
|
|
26
26
|
from pysmt.exceptions import (ConvertExpressionError,
|
|
27
|
-
NonLinearError,
|
|
27
|
+
NonLinearError,
|
|
28
28
|
SolverReturnedUnknownResultError)
|
|
29
|
-
from pysmt.logics import QF_NRA
|
|
29
|
+
from pysmt.logics import QF_NRA, QF_NIA
|
|
30
30
|
from pysmt.constants import Fraction
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class TestNonLinear(TestCase):
|
|
34
34
|
|
|
35
|
-
@skipIfSolverNotAvailable("z3")
|
|
36
35
|
def test_times(self):
|
|
37
36
|
x = FreshSymbol(REAL)
|
|
38
37
|
f = Equals(Times(x, x), x)
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
for sname in self.env.factory.all_solvers(logic=QF_NRA):
|
|
39
|
+
with Solver(name=sname, logic=QF_NRA) as s:
|
|
40
|
+
self.assertTrue(s.is_sat(f), sname)
|
|
41
41
|
|
|
42
|
-
@skipIfSolverNotAvailable("z3")
|
|
43
42
|
def test_div(self):
|
|
44
43
|
x = FreshSymbol(REAL)
|
|
45
44
|
f = Equals(Div(x, x), x)
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
for sname in self.env.factory.all_solvers(logic=QF_NRA):
|
|
46
|
+
with Solver(name=sname, logic=QF_NRA) as s:
|
|
47
|
+
self.assertTrue(s.is_sat(f), sname)
|
|
48
48
|
|
|
49
49
|
@skipIfSolverNotAvailable("z3")
|
|
50
50
|
def test_irrational(self):
|
|
51
51
|
x = FreshSymbol(REAL)
|
|
52
52
|
f = Equals(Times(x, x), Real(2))
|
|
53
|
-
with Solver(name="z3") as s:
|
|
53
|
+
with Solver(name="z3", logic=QF_NRA) as s:
|
|
54
54
|
self.assertTrue(s.is_sat(f))
|
|
55
55
|
model = s.get_model()
|
|
56
56
|
xval = model[x]
|
|
@@ -73,38 +73,34 @@ class TestNonLinear(TestCase):
|
|
|
73
73
|
|
|
74
74
|
def test_unknownresult(self):
|
|
75
75
|
x = FreshSymbol(REAL)
|
|
76
|
-
|
|
76
|
+
# 4.0 rather than 2.0: the point here is which solvers reject
|
|
77
|
+
# nonlinear arithmetic, not who can represent an algebraic number.
|
|
78
|
+
f = Equals(Times(x, x), Real(4))
|
|
77
79
|
for sname in self.env.factory.all_solvers():
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
if sname in ["bdd", "picosat", "btor"]:
|
|
81
|
+
with Solver(name=sname) as s:
|
|
80
82
|
with self.assertRaises(ConvertExpressionError):
|
|
81
83
|
s.is_sat(f)
|
|
82
|
-
|
|
84
|
+
elif sname in ["yices", "cvc4"]:
|
|
85
|
+
with Solver(name=sname) as s:
|
|
83
86
|
with self.assertRaises(NonLinearError):
|
|
84
87
|
s.is_sat(f)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
else:
|
|
89
|
-
res = s.is_sat(f)
|
|
90
|
-
self.assertTrue(res, sname)
|
|
88
|
+
else:
|
|
89
|
+
with Solver(name=sname, logic=QF_NRA) as s:
|
|
90
|
+
self.assertTrue(s.is_sat(f), sname)
|
|
91
91
|
self.assertIn(QF_NRA, s.LOGICS, sname)
|
|
92
92
|
|
|
93
|
-
@skipIfSolverNotAvailable("z3")
|
|
94
93
|
def test_integer(self):
|
|
95
94
|
x = FreshSymbol(INT)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
f = Equals(Times(x, x), Int(16))
|
|
107
|
-
self.assertTrue(is_sat(f, solver_name="z3"))
|
|
95
|
+
f1 = Equals(Times(x, x), Int(2))
|
|
96
|
+
f2 = Equals(Times(x, x), Int(16))
|
|
97
|
+
for sname in self.env.factory.all_solvers(logic=QF_NIA):
|
|
98
|
+
for f, expected in ((f1, False), (f2, True)):
|
|
99
|
+
with Solver(name=sname, logic=QF_NIA) as s:
|
|
100
|
+
try:
|
|
101
|
+
self.assertEqual(expected, s.is_sat(f), (sname, f))
|
|
102
|
+
except SolverReturnedUnknownResultError:
|
|
103
|
+
pass
|
|
108
104
|
|
|
109
105
|
@skipIfSolverNotAvailable("z3")
|
|
110
106
|
def test_div_pow(self):
|
|
@@ -29,11 +29,13 @@ from pysmt.test import (TestCase, skipIfSolverNotAvailable, skipIfNoSolverForLog
|
|
|
29
29
|
skipIfNoQEForLogic)
|
|
30
30
|
from pysmt.test import main
|
|
31
31
|
from pysmt.exceptions import (ConvertExpressionError, PysmtValueError,
|
|
32
|
-
PysmtTypeError, InternalSolverError
|
|
32
|
+
PysmtTypeError, InternalSolverError,
|
|
33
|
+
PysmtEmptySymbolNameError, UndefinedSymbolError)
|
|
33
34
|
from pysmt.test.examples import get_example_formulae
|
|
34
35
|
from pysmt.environment import Environment
|
|
35
36
|
from pysmt.rewritings import cnf_as_set
|
|
36
37
|
from pysmt.smtlib.parser import SmtLibParser
|
|
38
|
+
from pysmt.parsing import parse as hr_parse
|
|
37
39
|
from pysmt.smtlib.commands import DECLARE_FUN
|
|
38
40
|
from pysmt.smtlib.script import SmtLibCommand
|
|
39
41
|
from pysmt.logics import get_closer_smtlib_logic
|
|
@@ -270,6 +272,64 @@ class TestRegressions(TestCase):
|
|
|
270
272
|
def test_empty_string_symbol(self):
|
|
271
273
|
with self.assertRaises(PysmtValueError):
|
|
272
274
|
Symbol("")
|
|
275
|
+
# SMT-LIB allows `||` as a symbol name (see #587), but pySMT
|
|
276
|
+
# requires the user to opt-in explicitly.
|
|
277
|
+
self.env.allow_empty_var_names = True
|
|
278
|
+
self.assertNotEqual(Symbol(""), Symbol(" "))
|
|
279
|
+
|
|
280
|
+
def test_empty_string_symbol_error_message(self):
|
|
281
|
+
# Parsing a symbol with the empty name must point at the option
|
|
282
|
+
# to enable, not fail with an unrelated message.
|
|
283
|
+
smtlib = """(set-logic QF_BV)
|
|
284
|
+
(declare-fun || () (_ BitVec 4))
|
|
285
|
+
(assert (= || || ))
|
|
286
|
+
(check-sat)"""
|
|
287
|
+
with self.assertRaises(PysmtEmptySymbolNameError) as ctx:
|
|
288
|
+
SmtLibParser().get_script(StringIO(smtlib))
|
|
289
|
+
self.assertIn("allow_empty_var_names", str(ctx.exception))
|
|
290
|
+
with self.assertRaises(PysmtEmptySymbolNameError):
|
|
291
|
+
hr_parse("'' & x")
|
|
292
|
+
# Once enabled, the empty name is just an undeclared symbol
|
|
293
|
+
self.env.allow_empty_var_names = True
|
|
294
|
+
with self.assertRaises(UndefinedSymbolError):
|
|
295
|
+
hr_parse("'' & x")
|
|
296
|
+
Symbol("")
|
|
297
|
+
self.assertEqual(hr_parse("''"), Symbol(""))
|
|
298
|
+
|
|
299
|
+
@skipIfNoSolverForLogic(logics.QF_BV)
|
|
300
|
+
def test_empty_string_symbol_in_solvers(self):
|
|
301
|
+
self.env.allow_empty_var_names = True
|
|
302
|
+
empty = Symbol("", BVType(8))
|
|
303
|
+
other = Symbol("other", BVType(8))
|
|
304
|
+
f = Not(Equals(empty, other))
|
|
305
|
+
for sname in self.env.factory.all_solvers(logic=logics.QF_BV):
|
|
306
|
+
with Solver(name=sname, logic=logics.QF_BV) as s:
|
|
307
|
+
s.add_assertion(f)
|
|
308
|
+
self.assertTrue(s.solve(), sname)
|
|
309
|
+
self.assertTrue(s.get_value(empty).is_bv_constant(), sname)
|
|
310
|
+
# Round-trip, but only for converters that can back-convert
|
|
311
|
+
# a regular symbol in the first place.
|
|
312
|
+
try:
|
|
313
|
+
can_back = s.converter.back(s.converter.convert(other)) == other
|
|
314
|
+
except Exception:
|
|
315
|
+
can_back = False
|
|
316
|
+
if can_back:
|
|
317
|
+
self.assertEqual(s.converter.back(s.converter.convert(empty)),
|
|
318
|
+
empty, sname)
|
|
319
|
+
|
|
320
|
+
@skipIfNoSolverForLogic(logics.QF_BV)
|
|
321
|
+
def test_empty_string_symbol_smtlib(self):
|
|
322
|
+
# The benchmark reported in #587 declares `||` and `| |`.
|
|
323
|
+
self.env.allow_empty_var_names = True
|
|
324
|
+
txt = """(set-logic QF_BV)
|
|
325
|
+
(declare-fun || () (_ BitVec 4))
|
|
326
|
+
(declare-fun | | () (_ BitVec 4))
|
|
327
|
+
(assert (not (= || | |)))
|
|
328
|
+
(check-sat)"""
|
|
329
|
+
script = SmtLibParser().get_script(StringIO(txt))
|
|
330
|
+
self.assertEqual({s.symbol_name() for s in script.get_declared_symbols()},
|
|
331
|
+
{"", " "})
|
|
332
|
+
self.assertSat(script.get_last_formula())
|
|
273
333
|
|
|
274
334
|
def test_smtlib_info_quoting(self):
|
|
275
335
|
cmd = SmtLibCommand(smtcmd.SET_INFO, [":source", "This\nis\nmultiline!"])
|
|
@@ -198,7 +198,6 @@ class TestBasic(TestCase):
|
|
|
198
198
|
def test_examples_msat(self):
|
|
199
199
|
for (f, validity, satisfiability, logic) in get_example_formulae():
|
|
200
200
|
if not logic.quantifier_free: continue
|
|
201
|
-
if not logic.theory.linear: continue
|
|
202
201
|
if logic.theory.strings: continue
|
|
203
202
|
|
|
204
203
|
v = is_valid(f, solver_name='msat', logic=logic)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|