PySMT 0.9.7.dev470__tar.gz → 0.9.7.dev477__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.dev470/PySMT.egg-info → pysmt-0.9.7.dev477}/PKG-INFO +1 -1
  2. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477/PySMT.egg-info}/PKG-INFO +1 -1
  3. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/README.rst +1 -1
  4. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/docs/CHANGES.rst +23 -0
  5. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/__init__.py +1 -1
  6. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/shortcuts.py +5 -0
  7. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/smtlib/parser/parser.py +4 -0
  8. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/btor.py +32 -27
  9. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/msat.py +18 -3
  10. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/options.py +9 -1
  11. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/solver.py +37 -3
  12. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/z3.py +12 -2
  13. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_model_validation.py +23 -0
  14. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_unsat_cores.py +40 -1
  15. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/LICENSE +0 -0
  16. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/MANIFEST.in +0 -0
  17. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/NOTICE +0 -0
  18. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/PySMT.egg-info/SOURCES.txt +0 -0
  19. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/PySMT.egg-info/dependency_links.txt +0 -0
  20. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/PySMT.egg-info/entry_points.txt +0 -0
  21. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/PySMT.egg-info/top_level.txt +0 -0
  22. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/docs/api_ref.rst +0 -0
  23. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/docs/development.rst +0 -0
  24. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/docs/getting_started.rst +0 -0
  25. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/docs/index.rst +0 -0
  26. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/docs/tutorials/boolean_logic.rst +0 -0
  27. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/docs/tutorials.rst +0 -0
  28. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/__main__.py +0 -0
  29. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/__init__.py +0 -0
  30. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/check_version.py +0 -0
  31. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/install.py +0 -0
  32. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/installers/__init__.py +0 -0
  33. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/installers/base.py +0 -0
  34. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/installers/bdd.py +0 -0
  35. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/installers/btor.py +0 -0
  36. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/installers/cvcfive.py +0 -0
  37. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/installers/cvcfour.py +0 -0
  38. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/installers/msat.py +0 -0
  39. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/installers/optimsat.py +0 -0
  40. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/installers/pico.py +0 -0
  41. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/installers/yices.py +0 -0
  42. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/installers/z3.py +0 -0
  43. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/cmd/shell.py +0 -0
  44. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/configuration.py +0 -0
  45. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/constants.py +0 -0
  46. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/decorators.py +0 -0
  47. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/environment.py +0 -0
  48. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/exceptions.py +0 -0
  49. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/factory.py +0 -0
  50. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/fnode.py +0 -0
  51. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/formula.py +0 -0
  52. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/logics.py +0 -0
  53. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/operators.py +0 -0
  54. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/optimization/__init__.py +0 -0
  55. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/optimization/goal.py +0 -0
  56. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/optimization/msat.py +0 -0
  57. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/optimization/optimizer.py +0 -0
  58. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/optimization/optimsat.py +0 -0
  59. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/optimization/yices.py +0 -0
  60. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/optimization/z3.py +0 -0
  61. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/oracles.py +0 -0
  62. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/parsing.py +0 -0
  63. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/printers.py +0 -0
  64. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/rewritings.py +0 -0
  65. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/simplifier.py +0 -0
  66. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/smtlib/__init__.py +0 -0
  67. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/smtlib/annotations.py +0 -0
  68. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/smtlib/commands.py +0 -0
  69. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/smtlib/parser/__init__.py +0 -0
  70. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/smtlib/printers.py +0 -0
  71. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/smtlib/script.py +0 -0
  72. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/smtlib/solver.py +0 -0
  73. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/smtlib/utils.py +0 -0
  74. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/__init__.py +0 -0
  75. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/bdd.py +0 -0
  76. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/cvcfive.py +0 -0
  77. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/cvcfour.py +0 -0
  78. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/dynmsat.py +0 -0
  79. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/eager.py +0 -0
  80. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/interpolation.py +0 -0
  81. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/pico.py +0 -0
  82. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/portfolio.py +0 -0
  83. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/qelim.py +0 -0
  84. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/smtlib.py +0 -0
  85. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/solvers/yices.py +0 -0
  86. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/substituter.py +0 -0
  87. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/__init__.py +0 -0
  88. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/configs/config1.ini +0 -0
  89. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/configs/config_bad.ini +0 -0
  90. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/examples.py +0 -0
  91. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/omt_examples.py +0 -0
  92. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/optimization_utils.py +0 -0
  93. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/__init__.py +0 -0
  94. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/parser_utils.py +0 -0
  95. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_annotations.py +0 -0
  96. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_fuzzed.py +0 -0
  97. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_generic_wrapper.py +0 -0
  98. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_griggio.py +0 -0
  99. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_omt_lib_solver.py +0 -0
  100. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_parser_examples.py +0 -0
  101. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_parser_extensibility.py +0 -0
  102. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_parser_lra.py +0 -0
  103. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_parser_omt.py +0 -0
  104. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_parser_qf_arrays.py +0 -0
  105. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_parser_qf_lia.py +0 -0
  106. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_parser_qf_lira.py +0 -0
  107. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_parser_qf_lra.py +0 -0
  108. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_parser_qf_nia.py +0 -0
  109. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_parser_qf_nra.py +0 -0
  110. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_parser_qf_uf.py +0 -0
  111. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_parser_qf_ufbv.py +0 -0
  112. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_parser_type_error.py +0 -0
  113. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/smtlib/test_smtlibscript.py +0 -0
  114. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_array.py +0 -0
  115. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_back.py +0 -0
  116. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_bdd.py +0 -0
  117. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_bv.py +0 -0
  118. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_bv_simplification.py +0 -0
  119. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_cnf.py +0 -0
  120. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_configuration.py +0 -0
  121. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_constants.py +0 -0
  122. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_cvc_quantifiers.py +0 -0
  123. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_dwf.py +0 -0
  124. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_eager_model.py +0 -0
  125. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_env.py +0 -0
  126. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_euf.py +0 -0
  127. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_formula.py +0 -0
  128. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_hr_parsing.py +0 -0
  129. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_imports.py +0 -0
  130. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_int.py +0 -0
  131. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_interpolation.py +0 -0
  132. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_lira.py +0 -0
  133. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_logics.py +0 -0
  134. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_models.py +0 -0
  135. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_native_qe.py +0 -0
  136. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_nia.py +0 -0
  137. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_nlira.py +0 -0
  138. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_optimization.py +0 -0
  139. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_optimizing.py +0 -0
  140. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_oracles.py +0 -0
  141. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_portfolio.py +0 -0
  142. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_printing.py +0 -0
  143. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_qe.py +0 -0
  144. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_regressions.py +0 -0
  145. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_rewritings.py +0 -0
  146. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_shannon_expansion.py +0 -0
  147. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_simplify.py +0 -0
  148. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_size.py +0 -0
  149. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_solving.py +0 -0
  150. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_sorts.py +0 -0
  151. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_string.py +0 -0
  152. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_typechecker.py +0 -0
  153. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_walker_ext.py +0 -0
  154. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/test/test_walkers.py +0 -0
  155. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/type_checker.py +0 -0
  156. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/typing.py +0 -0
  157. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/utils.py +0 -0
  158. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/walkers/__init__.py +0 -0
  159. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/walkers/dag.py +0 -0
  160. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/walkers/generic.py +0 -0
  161. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/walkers/identitydag.py +0 -0
  162. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/pysmt/walkers/tree.py +0 -0
  163. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/setup.cfg +0 -0
  164. {pysmt-0.9.7.dev470 → pysmt-0.9.7.dev477}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PySMT
3
- Version: 0.9.7.dev470
3
+ Version: 0.9.7.dev477
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.dev470
3
+ Version: 0.9.7.dev477
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
@@ -243,7 +243,7 @@ each of the available solvers.
243
243
  +------------------+-----------+-----------------------------------+-------------+------------------------+------------+--------------+
244
244
  | Yices | yices | UF, LIA, LRA, BV | No | No | No | No |
245
245
  +------------------+-----------+-----------------------------------+-------------+------------------------+------------+--------------+
246
- | Boolector | btor | UF, BV, AX | No | No | No | No |
246
+ | Boolector | btor | UF, BV, AX | No | No | Yes | No |
247
247
  +------------------+-----------+-----------------------------------+-------------+------------------------+------------+--------------+
248
248
  | SMT-Lib Interface| <custom> | UF, LIA, LRA, BV, AX | Yes | No | No | No |
249
249
  +------------------+-----------+-----------------------------------+-------------+------------------------+------------+--------------+
@@ -1,6 +1,29 @@
1
1
  Change Log
2
2
  ==========
3
3
 
4
+ (unreleased)
5
+ ------------
6
+
7
+ * Fixed: The assumptions passed to ``solve()`` were missing from the
8
+ unsat core. ``get_unsat_core()`` now reports them alongside the
9
+ assertions, in both the "all" and the "named" unsat cores mode
10
+ (PR #680).
11
+
12
+ Assumptions carry no name, so they are *not* reported by
13
+ ``get_named_unsat_core()``, which keeps returning only the
14
+ assertions added via ``add_assertion(..., named=...)``.
15
+
16
+ * Fixed: Boolector's ``get_unsat_core`` and ``get_named_unsat_core``
17
+ raised ``BoolectorException: 'exp' must be an assumption`` when
18
+ solving under assumptions, and ``get_named_unsat_core`` could pair a
19
+ name with the wrong assertion (PR #680).
20
+
21
+ * Fixed: Boolector dropped the assumptions passed to ``solve()`` when
22
+ they were given as an iterator rather than as a list (PR #680).
23
+
24
+ * Docs: README listed Boolector as not supporting unsat cores; it does.
25
+
26
+
4
27
  0.9.6: 2022-06-24 -- CVC5 and upgraded solvers
5
28
  ----------------------------------------------
6
29
 
@@ -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", 470)
22
+ VERSION: Union[Tuple[int, int, int], Tuple[int, int, int, str, int]] = (0, 9, 7, "dev", 477)
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
@@ -1113,6 +1113,11 @@ def get_unsat_core(clauses: Iterable[FNode], solver_name: Optional[str]=None, lo
1113
1113
  """Similar to :py:func:`get_model` but returns the unsat core of the
1114
1114
  conjunction of the input clauses
1115
1115
 
1116
+ Every clause is asserted separately, so the returned core is a
1117
+ subset of ``clauses``. This function takes no assumptions; to get a
1118
+ core under assumptions, call :py:func:`Solver.solve` with them and
1119
+ then :py:func:`UnsatCoreSolver.get_unsat_core`.
1120
+
1116
1121
  :param clauses: Specify the list of input clauses
1117
1122
  :param solver_name: Specify the name of the solver_name
1118
1123
  :param logic: Specify the logic that is going to be used
@@ -561,6 +561,10 @@ class SmtLibParser(object):
561
561
  return res
562
562
  stack[-1].append(handler)
563
563
  else:
564
+ # pySMT binds one type per symbol name, but SMT-LIB model values
565
+ # reuse the same @name across sorts, so we qualify it with the sort
566
+ if what.startswith('@'):
567
+ what += "_" + str(ty)
564
568
  def handler():
565
569
  return self.env.formula_manager.Symbol(what, ty)
566
570
  stack[-1].append(handler)
@@ -209,6 +209,9 @@ class BoolectorSolver(IncrementalTrackingSolver, UnsatCoreSolver, SmtLibBasicSol
209
209
  self.mgr = environment.formula_manager
210
210
  self.declarations = {}
211
211
  self._named_assertions = {}
212
+ self._assumptions = []
213
+ self._core = []
214
+ self._core_assumptions = []
212
215
  return
213
216
 
214
217
  # EOC BoolectorOptions
@@ -246,17 +249,34 @@ class BoolectorSolver(IncrementalTrackingSolver, UnsatCoreSolver, SmtLibBasicSol
246
249
  assignment[s] = self.get_value(s)
247
250
  return EagerModel(assignment=assignment, environment=self.environment)
248
251
 
252
+ def _failed(self, formulae):
253
+ """Returns the formulae of the given list that are in the unsat core.
254
+
255
+ Only valid immediately after an UNSAT Sat() call: Boolector
256
+ drops this information as soon as new assumptions are made.
257
+ """
258
+ if len(formulae) == 0:
259
+ return []
260
+ terms = [self.converter.convert(f) for f in formulae]
261
+ return [f for f, failed in zip(formulae, self.btor.Failed(*terms)) if failed]
262
+
249
263
  @clear_pending_pop
250
264
  def _solve(self, assumptions=None):
251
- if assumptions is not None:
252
- btor_assumptions = [self.converter.convert(a) for a in assumptions]
253
- self.btor.Assume(*btor_assumptions)
265
+ # materialized because assumptions can be a one-shot iterator
266
+ self._assumptions = [] if assumptions is None else list(assumptions)
267
+ if len(self._assumptions) > 0:
268
+ self.btor.Assume(*(self.converter.convert(a)
269
+ for a in self._assumptions))
254
270
 
255
271
  res = self.btor.Sat()
256
272
 
257
- # need to re-add assumptions if in unsat-core mode
258
- # which uses Assume instead of Assert
259
273
  if self.options.unsat_cores_mode is not None:
274
+ if res == self.btor.UNSAT:
275
+ # must be extracted before the re-assertion below invalidates it
276
+ self._core = self._failed(self._assertion_stack)
277
+ self._core_assumptions = self._failed(self._assumptions)
278
+ # need to re-add assumptions if in unsat-core mode
279
+ # which uses Assume instead of Assert
260
280
  for a in self._assertion_stack:
261
281
  self._add_assertion(a)
262
282
 
@@ -273,18 +293,10 @@ class BoolectorSolver(IncrementalTrackingSolver, UnsatCoreSolver, SmtLibBasicSol
273
293
  self._check_unsat_core_config()
274
294
 
275
295
  if self.options.unsat_cores_mode == 'all':
276
- unsat_core = set()
277
- # relies on this assertion stack being ordered
278
- assert isinstance(self._assertion_stack, list)
279
- btor_assertions = [self.converter.convert(
280
- a) for a in self._assertion_stack]
281
- in_unsat_core = self.btor.Failed(*btor_assertions)
282
- for a, in_core in zip(self._assertion_stack, in_unsat_core):
283
- if in_core:
284
- unsat_core.add(a)
285
- return unsat_core
296
+ return set(self._core) | set(self._core_assumptions)
286
297
  else:
287
- return set(self.get_named_unsat_core().values())
298
+ return set(self.get_named_unsat_core().values()) | \
299
+ set(self._core_assumptions)
288
300
 
289
301
  def get_named_unsat_core(self) -> Dict[str, FNode]:
290
302
  """After a call to solve() yielding UNSAT, returns the unsat core as a
@@ -292,17 +304,10 @@ class BoolectorSolver(IncrementalTrackingSolver, UnsatCoreSolver, SmtLibBasicSol
292
304
  self._check_unsat_core_config()
293
305
 
294
306
  if self.options.unsat_cores_mode == "named":
295
- unsat_core = {}
296
- # relies on this assertion stack being ordered
297
- assert isinstance(self._assertion_stack, list)
298
- btor_named_assertions = [self.converter.convert(
299
- a) for a in self._named_assertions.keys()]
300
- in_unsat_core = self.btor.Failed(*btor_named_assertions)
301
- for a, in_core in zip(self._assertion_stack, in_unsat_core):
302
- if in_core:
303
- name = self._named_assertions[a]
304
- unsat_core[name] = a
305
- return unsat_core
307
+ # solve-time assumptions have no name, they are reported by
308
+ # get_unsat_core() only
309
+ return dict((self._named_assertions[a], a) for a in self._core
310
+ if a in self._named_assertions)
306
311
  else:
307
312
  return dict(("_a%d" % i, f)
308
313
  for i, f in enumerate(self.get_unsat_core()))
@@ -314,14 +314,27 @@ class MathSAT5Solver(IncrementalTrackingSolver, UnsatCoreSolver, SmtLibBasicSolv
314
314
  set of formulae"""
315
315
  self._check_unsat_core_config()
316
316
  if self.options.unsat_cores_mode == "all":
317
-
318
317
  terms = self._msat_lib.msat_get_unsat_core(self.msat_env())
319
318
  if terms is None:
320
319
  raise InternalSolverError(
321
320
  self._msat_lib.msat_last_error_message(self.msat_env()))
322
- return set(self.converter.back(t) for t in terms)
321
+ res = set(self.converter.back(t) for t in terms)
322
+ return res | self._unsat_assumptions()
323
323
  else:
324
- return set(self.get_named_unsat_core().values())
324
+ return set(self.get_named_unsat_core().values()) | \
325
+ self._unsat_assumptions()
326
+
327
+ def _unsat_assumptions(self):
328
+ """Returns the solve-time assumptions occurring in the last unsat core."""
329
+ terms = self._msat_lib.msat_get_unsat_assumptions(self.msat_env())
330
+ if not terms:
331
+ return set()
332
+ res = set(self.converter.back(t) for t in terms)
333
+ n_ass_map = self._named_assertions_map()
334
+ if n_ass_map is not None:
335
+ # in named mode the named assertions are passed as assumptions too
336
+ res -= set(n_ass_map)
337
+ return res
325
338
 
326
339
  def get_named_unsat_core(self):
327
340
  """After a call to solve() yielding UNSAT, returns the unsat core as a
@@ -341,6 +354,8 @@ class MathSAT5Solver(IncrementalTrackingSolver, UnsatCoreSolver, SmtLibBasicSolv
341
354
  name = "_a_%d" % cnt
342
355
  cnt += 1
343
356
  res[name] = formula
357
+ # solve-time assumptions have no name, they are reported by
358
+ # get_unsat_core() only
344
359
  return res
345
360
 
346
361
  else:
@@ -48,7 +48,15 @@ class SolverOptions(object):
48
48
  Enable incremental interface (push, pop)
49
49
 
50
50
  * unsat_cores_mode: None, "named", "all"
51
- Enable UNSAT core extraction using "named" or "all" strategy.
51
+ Enable UNSAT core extraction. With "all", every assertion is a
52
+ candidate for the core; get_named_unsat_core() still works, but
53
+ the names it returns are generated ones with no meaning to the
54
+ caller. With "named", the core is restricted to the assertions
55
+ added with a name (see Solver.add_assertion), and
56
+ get_named_unsat_core() reports them under those names. In both
57
+ modes the assumptions passed to solve() are reported by
58
+ get_unsat_core(). None (the default) disables core extraction
59
+ altogether.
52
60
 
53
61
  * random_seed: None, integer
54
62
  Sets the random seed for the solver
@@ -68,6 +68,13 @@ class Solver(object):
68
68
 
69
69
  but is in general more efficient.
70
70
 
71
+ The two differ in how they report unsat cores: assumptions are
72
+ reported individually by
73
+ :py:func:`UnsatCoreSolver.get_unsat_core`, whereas the encoding
74
+ above contributes the single conjunction ``And(a1, ..., an)``.
75
+ Assumptions carry no name and therefore never appear in
76
+ :py:func:`UnsatCoreSolver.get_named_unsat_core`.
77
+
71
78
  Other convenience methods (is_sat, is_unsat, is_valid) are
72
79
  wrappers around this function.
73
80
 
@@ -203,7 +210,18 @@ class Solver(object):
203
210
  raise NotImplementedError
204
211
 
205
212
  def add_assertion(self, formula: FNode, named: Optional[str]=None):
206
- """Add assertion to the solver."""
213
+ """Add assertion to the solver.
214
+
215
+ The optional ``named`` argument labels the assertion, so that
216
+ :py:func:`UnsatCoreSolver.get_named_unsat_core` reports it under
217
+ that name. The label is honored only if the solver was created
218
+ with the ``unsat_cores_mode="named"`` option; with the other
219
+ modes some solvers keep it and others replace it with a
220
+ generated name, so do not rely on it.
221
+
222
+ :param formula: The Boolean formula to assert
223
+ :param named: The name to label this assertion with, if any
224
+ """
207
225
  raise NotImplementedError
208
226
 
209
227
  def add_assertions(self, formulae: Iterable[FNode]):
@@ -415,7 +433,16 @@ class UnsatCoreSolver(Solver):
415
433
  """Returns the unsat core as a set of formulae.
416
434
 
417
435
  After a call to solve() yielding UNSAT, returns the unsat core
418
- as a set of formulae
436
+ as a set of formulae.
437
+
438
+ The core contains the assertions that caused the
439
+ unsatisfiability, together with the assumptions passed to the
440
+ failing :py:func:`Solver.solve` call, if any. Both are reported
441
+ in either unsat cores mode. In ``"named"`` mode only named
442
+ assertions are considered, so the core is made of the named
443
+ assertions and of the assumptions.
444
+
445
+ :returns: The unsat core, as a set of formulae
419
446
  """
420
447
  raise NotImplementedError
421
448
 
@@ -423,7 +450,14 @@ class UnsatCoreSolver(Solver):
423
450
  """Returns the unsat core as a dict of names to formulae.
424
451
 
425
452
  After a call to solve() yielding UNSAT, returns the unsat core as a
426
- dict of names to formulae
453
+ dict of names to formulae.
454
+
455
+ Only assertions added with a ``named`` argument can be reported
456
+ here. Assumptions passed to :py:func:`Solver.solve` carry no
457
+ name and are therefore omitted: use
458
+ :py:func:`get_unsat_core` to obtain them.
459
+
460
+ :returns: The unsat core, as a map from assertion name to formula
427
461
  """
428
462
  raise NotImplementedError
429
463
 
@@ -235,7 +235,8 @@ class Z3Solver(IncrementalTrackingSolver, UnsatCoreSolver, SmtLibBasicSolver):
235
235
  def get_unsat_core(self):
236
236
  """After a call to solve() yielding UNSAT, returns the unsat core as a
237
237
  set of formulae"""
238
- return set(self.get_named_unsat_core().values())
238
+ named, assumptions = self._unsat_core()
239
+ return set(named.values()) | assumptions
239
240
 
240
241
  def _named_assertions_map(self):
241
242
  if self.options.unsat_cores_mode is not None:
@@ -245,6 +246,12 @@ class Z3Solver(IncrementalTrackingSolver, UnsatCoreSolver, SmtLibBasicSolver):
245
246
  def get_named_unsat_core(self):
246
247
  """After a call to solve() yielding UNSAT, returns the unsat core as a
247
248
  dict of names to formulae"""
249
+ # solve-time assumptions have no name, they are reported by
250
+ # get_unsat_core() only
251
+ return self._unsat_core()[0]
252
+
253
+ def _unsat_core(self):
254
+ """Splits the last unsat core into named assertions and assumptions."""
248
255
  if self.options.unsat_cores_mode is None:
249
256
  raise SolverNotConfiguredForUnsatCoresError
250
257
 
@@ -261,6 +268,7 @@ class Z3Solver(IncrementalTrackingSolver, UnsatCoreSolver, SmtLibBasicSolver):
261
268
  pysmt_assumptions = set(self.converter.back(t) for t in assumptions)
262
269
 
263
270
  res = {}
271
+ core_assumptions = set()
264
272
  n_ass_map = self._named_assertions_map()
265
273
  cnt = 0
266
274
  for key in pysmt_assumptions:
@@ -270,7 +278,9 @@ class Z3Solver(IncrementalTrackingSolver, UnsatCoreSolver, SmtLibBasicSolver):
270
278
  name = "_a_%d" % cnt
271
279
  cnt += 1
272
280
  res[name] = formula
273
- return res
281
+ else:
282
+ core_assumptions.add(key)
283
+ return res, core_assumptions
274
284
 
275
285
  @clear_pending_pop
276
286
  def all_sat(self, important, callback):
@@ -97,6 +97,29 @@ class TestModelValidation(TestCase):
97
97
  simp = simplifier.simplify(formula.substitute(model, interpretations))
98
98
  self.assertEqual(simp, self.fm.TRUE())
99
99
 
100
+ def test_same_value_name_different_sorts(self):
101
+ # SMT-COMP/postprocessors#10: solvers reuse @0 across sorts
102
+ model_source ="""\
103
+ (model
104
+ (define-fun a () U (as @0 U))
105
+ (define-fun c () U (as @1 U))
106
+ (define-fun b () V (as @0 V))
107
+ (define-fun d () V (as @0 V))
108
+ )
109
+ """
110
+ U = self.tm.Type('U', 0)
111
+ V = self.tm.Type('V', 0)
112
+ a = self.fm.Symbol('a', U)
113
+ b = self.fm.Symbol('b', V)
114
+ c = self.fm.Symbol('c', U)
115
+ d = self.fm.Symbol('d', V)
116
+ formula = self.fm.And(self.fm.Not(self.fm.Equals(a, c)),
117
+ self.fm.Equals(b, d))
118
+
119
+ model, interpretations = SmtLibParser().parse_model(StringIO(model_source))
120
+ simp = SmtLibModelValidationSimplifier(self.env).simplify(
121
+ formula.substitute(model, interpretations))
122
+ self.assertEqual(simp, self.fm.TRUE())
100
123
 
101
124
 
102
125
  if __name__ == '__main__':
@@ -18,7 +18,7 @@
18
18
  from pysmt.test import (TestCase, skipIfSolverNotAvailable,
19
19
  skipIfNoUnsatCoreSolverForLogic, main)
20
20
  from pysmt.shortcuts import (get_unsat_core, And, Or, Not, Symbol, UnsatCoreSolver,
21
- Solver, is_unsat, Int, GT)
21
+ Solver, is_unsat, Int, GT, get_env)
22
22
  from pysmt.typing import INT
23
23
  from pysmt.logics import QF_BOOL, QF_BV, QF_LIA
24
24
  from pysmt.exceptions import (SolverStatusError, SolverReturnedUnknownResultError,
@@ -185,5 +185,44 @@ class TestUnsatCores(TestCase):
185
185
  s.get_unsat_core()
186
186
 
187
187
 
188
+ @skipIfNoUnsatCoreSolverForLogic(QF_BOOL)
189
+ def test_assumptions(self):
190
+ x = Symbol("x")
191
+ with UnsatCoreSolver(logic=QF_BOOL) as s:
192
+ check = s.solve([x, Not(x)])
193
+ self.assertFalse(check)
194
+ core = s.get_unsat_core()
195
+ self.assertEqual(len(core), 2)
196
+
197
+
198
+ @skipIfNoUnsatCoreSolverForLogic(QF_BOOL)
199
+ def test_assumptions_in_unsat_core(self):
200
+ x, y = Symbol("x"), Symbol("y")
201
+ for name in get_env().factory.all_unsat_core_solvers(logic=QF_BOOL):
202
+ for mode in ["all", "named"]:
203
+ with UnsatCoreSolver(name=name, logic=QF_BOOL,
204
+ unsat_cores_mode=mode) as s:
205
+ s.add_assertion(Or(x, y), named="n1")
206
+ self.assertFalse(s.solve([Not(x), Not(y)]))
207
+ core = s.get_unsat_core()
208
+ self.assertEqual(len(core), 3, (name, mode))
209
+ self.assertIn(Not(x), core, (name, mode))
210
+ self.assertIn(Not(y), core, (name, mode))
211
+ if mode == "named":
212
+ # assumptions carry no name: they stay out of this core
213
+ self.assertEqual(s.get_named_unsat_core(),
214
+ {"n1": Or(x, y)}, name)
215
+
216
+
217
+ @skipIfNoUnsatCoreSolverForLogic(QF_BOOL)
218
+ def test_assumptions_as_iterator(self):
219
+ x, y = Symbol("x"), Symbol("y")
220
+ for name in get_env().factory.all_unsat_core_solvers(logic=QF_BOOL):
221
+ with UnsatCoreSolver(name=name, logic=QF_BOOL) as s:
222
+ s.add_assertion(Or(x, y))
223
+ self.assertFalse(s.solve(a for a in [Not(x), Not(y)]))
224
+ self.assertEqual(len(s.get_unsat_core()), 3, name)
225
+
226
+
188
227
  if __name__ == '__main__':
189
228
  main()
File without changes
File without changes
File without changes
File without changes
File without changes