PySMT 0.9.7.dev446__tar.gz → 0.9.7.dev457__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.
Files changed (164) hide show
  1. {pysmt-0.9.7.dev446/PySMT.egg-info → pysmt-0.9.7.dev457}/PKG-INFO +1 -1
  2. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457/PySMT.egg-info}/PKG-INFO +1 -1
  3. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/README.rst +19 -19
  4. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/__init__.py +1 -1
  5. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/factory.py +13 -2
  6. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/msat.py +57 -10
  7. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/portfolio.py +8 -2
  8. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/examples.py +4 -4
  9. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_env.py +12 -0
  10. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_nlira.py +28 -32
  11. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_portfolio.py +16 -1
  12. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_solving.py +0 -1
  13. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/LICENSE +0 -0
  14. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/MANIFEST.in +0 -0
  15. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/NOTICE +0 -0
  16. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/PySMT.egg-info/SOURCES.txt +0 -0
  17. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/PySMT.egg-info/dependency_links.txt +0 -0
  18. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/PySMT.egg-info/entry_points.txt +0 -0
  19. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/PySMT.egg-info/top_level.txt +0 -0
  20. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/docs/CHANGES.rst +0 -0
  21. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/docs/api_ref.rst +0 -0
  22. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/docs/development.rst +0 -0
  23. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/docs/getting_started.rst +0 -0
  24. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/docs/index.rst +0 -0
  25. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/docs/tutorials/boolean_logic.rst +0 -0
  26. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/docs/tutorials.rst +0 -0
  27. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/__main__.py +0 -0
  28. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/__init__.py +0 -0
  29. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/check_version.py +0 -0
  30. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/install.py +0 -0
  31. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/installers/__init__.py +0 -0
  32. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/installers/base.py +0 -0
  33. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/installers/bdd.py +0 -0
  34. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/installers/btor.py +0 -0
  35. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/installers/cvcfive.py +0 -0
  36. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/installers/cvcfour.py +0 -0
  37. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/installers/msat.py +0 -0
  38. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/installers/optimsat.py +0 -0
  39. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/installers/pico.py +0 -0
  40. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/installers/yices.py +0 -0
  41. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/installers/z3.py +0 -0
  42. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/cmd/shell.py +0 -0
  43. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/configuration.py +0 -0
  44. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/constants.py +0 -0
  45. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/decorators.py +0 -0
  46. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/environment.py +0 -0
  47. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/exceptions.py +0 -0
  48. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/fnode.py +0 -0
  49. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/formula.py +0 -0
  50. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/logics.py +0 -0
  51. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/operators.py +0 -0
  52. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/optimization/__init__.py +0 -0
  53. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/optimization/goal.py +0 -0
  54. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/optimization/msat.py +0 -0
  55. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/optimization/optimizer.py +0 -0
  56. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/optimization/optimsat.py +0 -0
  57. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/optimization/yices.py +0 -0
  58. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/optimization/z3.py +0 -0
  59. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/oracles.py +0 -0
  60. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/parsing.py +0 -0
  61. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/printers.py +0 -0
  62. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/rewritings.py +0 -0
  63. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/shortcuts.py +0 -0
  64. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/simplifier.py +0 -0
  65. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/smtlib/__init__.py +0 -0
  66. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/smtlib/annotations.py +0 -0
  67. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/smtlib/commands.py +0 -0
  68. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/smtlib/parser/__init__.py +0 -0
  69. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/smtlib/parser/parser.py +0 -0
  70. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/smtlib/printers.py +0 -0
  71. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/smtlib/script.py +0 -0
  72. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/smtlib/solver.py +0 -0
  73. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/smtlib/utils.py +0 -0
  74. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/__init__.py +0 -0
  75. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/bdd.py +0 -0
  76. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/btor.py +0 -0
  77. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/cvcfive.py +0 -0
  78. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/cvcfour.py +0 -0
  79. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/dynmsat.py +0 -0
  80. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/eager.py +0 -0
  81. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/interpolation.py +0 -0
  82. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/options.py +0 -0
  83. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/pico.py +0 -0
  84. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/qelim.py +0 -0
  85. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/smtlib.py +0 -0
  86. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/solver.py +0 -0
  87. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/yices.py +0 -0
  88. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/solvers/z3.py +0 -0
  89. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/substituter.py +0 -0
  90. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/__init__.py +0 -0
  91. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/configs/config1.ini +0 -0
  92. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/configs/config_bad.ini +0 -0
  93. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/omt_examples.py +0 -0
  94. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/optimization_utils.py +0 -0
  95. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/__init__.py +0 -0
  96. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/parser_utils.py +0 -0
  97. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_annotations.py +0 -0
  98. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_fuzzed.py +0 -0
  99. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_generic_wrapper.py +0 -0
  100. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_griggio.py +0 -0
  101. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_model_validation.py +0 -0
  102. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_omt_lib_solver.py +0 -0
  103. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_parser_examples.py +0 -0
  104. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_parser_extensibility.py +0 -0
  105. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_parser_lra.py +0 -0
  106. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_parser_omt.py +0 -0
  107. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_parser_qf_arrays.py +0 -0
  108. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_parser_qf_lia.py +0 -0
  109. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_parser_qf_lira.py +0 -0
  110. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_parser_qf_lra.py +0 -0
  111. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_parser_qf_nia.py +0 -0
  112. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_parser_qf_nra.py +0 -0
  113. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_parser_qf_uf.py +0 -0
  114. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_parser_qf_ufbv.py +0 -0
  115. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_parser_type_error.py +0 -0
  116. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/smtlib/test_smtlibscript.py +0 -0
  117. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_array.py +0 -0
  118. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_back.py +0 -0
  119. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_bdd.py +0 -0
  120. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_bv.py +0 -0
  121. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_bv_simplification.py +0 -0
  122. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_cnf.py +0 -0
  123. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_configuration.py +0 -0
  124. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_constants.py +0 -0
  125. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_cvc_quantifiers.py +0 -0
  126. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_dwf.py +0 -0
  127. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_eager_model.py +0 -0
  128. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_euf.py +0 -0
  129. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_formula.py +0 -0
  130. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_hr_parsing.py +0 -0
  131. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_imports.py +0 -0
  132. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_int.py +0 -0
  133. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_interpolation.py +0 -0
  134. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_lira.py +0 -0
  135. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_logics.py +0 -0
  136. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_models.py +0 -0
  137. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_native_qe.py +0 -0
  138. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_nia.py +0 -0
  139. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_optimization.py +0 -0
  140. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_optimizing.py +0 -0
  141. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_oracles.py +0 -0
  142. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_printing.py +0 -0
  143. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_qe.py +0 -0
  144. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_regressions.py +0 -0
  145. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_rewritings.py +0 -0
  146. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_shannon_expansion.py +0 -0
  147. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_simplify.py +0 -0
  148. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_size.py +0 -0
  149. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_sorts.py +0 -0
  150. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_string.py +0 -0
  151. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_typechecker.py +0 -0
  152. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_unsat_cores.py +0 -0
  153. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_walker_ext.py +0 -0
  154. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/test/test_walkers.py +0 -0
  155. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/type_checker.py +0 -0
  156. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/typing.py +0 -0
  157. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/utils.py +0 -0
  158. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/walkers/__init__.py +0 -0
  159. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/walkers/dag.py +0 -0
  160. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/walkers/generic.py +0 -0
  161. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/walkers/identitydag.py +0 -0
  162. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/pysmt/walkers/tree.py +0 -0
  163. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/setup.cfg +0 -0
  164. {pysmt-0.9.7.dev446 → pysmt-0.9.7.dev457}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PySMT
3
- Version: 0.9.7.dev446
3
+ Version: 0.9.7.dev457
4
4
  Summary: A solver-agnostic library for SMT Formulae manipulation and solving
5
5
  Home-page: http://www.pysmt.org
6
6
  Author: PySMT Team
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PySMT
3
- Version: 0.9.7.dev446
3
+ Version: 0.9.7.dev457
4
4
  Summary: A solver-agnostic library for SMT Formulae manipulation and solving
5
5
  Home-page: http://www.pysmt.org
6
6
  Author: PySMT Team
@@ -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 | Quantifiers | Quantifier Elimination | Unsat Core | Interpolation|
237
- +==================+===========+================================+=============+========================+============+==============+
238
- | MathSAT | msat | UF, LIA, LRA, BV, AX | 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 | 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
- +------------------+-----------+--------------------------------+-------------+------------------------+------------+--------------+
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", 446)
22
+ VERSION: Union[Tuple[int, int, int], Tuple[int, int, int, str, int]] = (0, 9, 7, "dev", 457)
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
@@ -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, solvers)
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], solvers: Dict[str, Any]) -> Type[Solver]:
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]
@@ -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
- NonLinearError, PysmtValueError, PysmtTypeError,
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,
@@ -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
- if not self._msat_lib.msat_term_is_number(self.msat_env(), x):
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:
@@ -232,7 +232,13 @@ def _run_solver(idx, solver, logic, options, formula, signaling_queue, ctrl_pipe
232
232
  """
233
233
  from pysmt.environment import get_env
234
234
 
235
- Solver = get_env().factory.Solver
235
+ env = get_env()
236
+ # The formula is pickled across the process boundary, so its FNodes
237
+ # belong to no FormulaManager here (this is always the case with the
238
+ # 'spawn'/'forkserver' start methods). Contextualize it in our own env.
239
+ formula = env.formula_manager.normalize(formula)
240
+
241
+ Solver = env.factory.Solver
236
242
  with Solver(name=solver, logic=logic, **options) as s:
237
243
  s.add_assertion(formula)
238
244
  try:
@@ -258,7 +264,7 @@ def _run_solver(idx, solver, logic, options, formula, signaling_queue, ctrl_pipe
258
264
  model = list(s.get_model())
259
265
  ctrl_pipe.send(model)
260
266
  elif cmd == "get_value":
261
- args = get_env().formula_manager.normalize(args)
267
+ args = env.formula_manager.normalize(args)
262
268
  ctrl_pipe.send(s.get_value(args))
263
269
  else:
264
270
  raise ValueError("Unknown command '%s'" % cmd)
@@ -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="(2.0 = (r * r))",
929
- expr=Equals(Real(2), Times(r,r)),
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) = 25.0)",
950
- expr=Equals(Times(r, r, r), Real(25)),
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, InternalSolverError,
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
- with Solver(name="z3") as s:
40
- self.assertTrue(s.is_sat(f))
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
- with Solver(name="z3") as s:
47
- self.assertTrue(s.is_sat(f))
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
- f = Equals(Times(x, x), Real(2))
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
- with Solver(name=sname) as s:
79
- if sname in ["bdd", "picosat", "btor"]:
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
- elif sname in ["yices", "cvc4", "msat", "optimsat"]:
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
- elif sname in ["cvc5"]:
86
- with self.assertRaises(InternalSolverError):
87
- s.is_sat(f)
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
- f = Equals(Times(x, x), Int(2))
97
- with Solver(name="z3") as s:
98
- self.assertFalse(s.is_sat(f))
99
-
100
- # f = Equals(Times(Int(4), Pow(x, Int(-1))), Int(2))
101
- # self.assertTrue(is_sat(f, solver_name="z3"))
102
-
103
- # f = Equals(Div(Int(4), x), Int(2))
104
- # self.assertTrue(is_sat(f, solver_name="z3"))
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):
@@ -25,11 +25,26 @@ from pysmt.solvers.portfolio import Portfolio
25
25
  from pysmt.smtlib.parser import get_formula_fname
26
26
  from pysmt.shortcuts import TRUE, Implies, Equals, Symbol, FALSE
27
27
  from pysmt.shortcuts import reset_env, is_sat
28
- from pysmt.typing import REAL
28
+ from pysmt.typing import REAL, BOOL
29
29
 
30
30
 
31
31
  class PortfolioTestCase(TestCase):
32
32
 
33
+ @skipIfSolverNotAvailable("z3")
34
+ def test_basic_z3(self):
35
+ mgr = self.env.formula_manager
36
+ x = mgr.Symbol('x', BOOL)
37
+ y = mgr.Symbol('y', BOOL)
38
+ formula = mgr.And(x, y)
39
+ with Portfolio(["z3"],
40
+ environment=self.env,
41
+ logic=QF_LRA) as solver:
42
+ res = solver.is_sat(formula)
43
+ self.assertTrue(res)
44
+ model = solver.get_model()
45
+ formula_val_term = model.get_value(formula)
46
+ self.assertTrue(formula_val_term.is_true())
47
+
33
48
  @skipIfSolverNotAvailable("z3")
34
49
  @skipIfSolverNotAvailable("msat")
35
50
  @skipIfSolverNotAvailable("cvc5")
@@ -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