PySMT 0.9.7.dev414__tar.gz → 0.9.7.dev426__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. {pysmt-0.9.7.dev414/PySMT.egg-info → pysmt-0.9.7.dev426}/PKG-INFO +1 -1
  2. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426/PySMT.egg-info}/PKG-INFO +1 -1
  3. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/__init__.py +1 -1
  4. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/rewritings.py +168 -6
  5. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/z3.py +8 -5
  6. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_back.py +29 -3
  7. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_cnf.py +21 -22
  8. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_regressions.py +1 -1
  9. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/LICENSE +0 -0
  10. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/MANIFEST.in +0 -0
  11. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/NOTICE +0 -0
  12. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/PySMT.egg-info/SOURCES.txt +0 -0
  13. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/PySMT.egg-info/dependency_links.txt +0 -0
  14. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/PySMT.egg-info/entry_points.txt +0 -0
  15. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/PySMT.egg-info/top_level.txt +0 -0
  16. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/README.rst +0 -0
  17. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/CHANGES.rst +0 -0
  18. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/api_ref.rst +0 -0
  19. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/development.rst +0 -0
  20. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/getting_started.rst +0 -0
  21. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/index.rst +0 -0
  22. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/tutorials/boolean_logic.rst +0 -0
  23. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/docs/tutorials.rst +0 -0
  24. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/__main__.py +0 -0
  25. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/__init__.py +0 -0
  26. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/check_version.py +0 -0
  27. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/install.py +0 -0
  28. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/__init__.py +0 -0
  29. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/base.py +0 -0
  30. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/bdd.py +0 -0
  31. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/btor.py +0 -0
  32. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/cvcfive.py +0 -0
  33. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/cvcfour.py +0 -0
  34. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/msat.py +0 -0
  35. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/optimsat.py +0 -0
  36. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/pico.py +0 -0
  37. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/yices.py +0 -0
  38. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/installers/z3.py +0 -0
  39. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/cmd/shell.py +0 -0
  40. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/configuration.py +0 -0
  41. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/constants.py +0 -0
  42. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/decorators.py +0 -0
  43. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/environment.py +0 -0
  44. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/exceptions.py +0 -0
  45. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/factory.py +0 -0
  46. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/fnode.py +0 -0
  47. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/formula.py +0 -0
  48. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/logics.py +0 -0
  49. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/operators.py +0 -0
  50. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/__init__.py +0 -0
  51. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/goal.py +0 -0
  52. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/msat.py +0 -0
  53. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/optimizer.py +0 -0
  54. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/optimsat.py +0 -0
  55. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/yices.py +0 -0
  56. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/optimization/z3.py +0 -0
  57. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/oracles.py +0 -0
  58. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/parsing.py +0 -0
  59. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/printers.py +0 -0
  60. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/shortcuts.py +0 -0
  61. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/simplifier.py +0 -0
  62. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/__init__.py +0 -0
  63. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/annotations.py +0 -0
  64. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/commands.py +0 -0
  65. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/parser/__init__.py +0 -0
  66. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/parser/parser.py +0 -0
  67. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/printers.py +0 -0
  68. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/script.py +0 -0
  69. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/solver.py +0 -0
  70. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/smtlib/utils.py +0 -0
  71. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/__init__.py +0 -0
  72. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/bdd.py +0 -0
  73. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/btor.py +0 -0
  74. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/cvcfive.py +0 -0
  75. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/cvcfour.py +0 -0
  76. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/dynmsat.py +0 -0
  77. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/eager.py +0 -0
  78. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/interpolation.py +0 -0
  79. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/msat.py +0 -0
  80. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/options.py +0 -0
  81. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/pico.py +0 -0
  82. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/portfolio.py +0 -0
  83. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/qelim.py +0 -0
  84. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/smtlib.py +0 -0
  85. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/solver.py +0 -0
  86. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/solvers/yices.py +0 -0
  87. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/substituter.py +0 -0
  88. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/__init__.py +0 -0
  89. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/configs/config1.ini +0 -0
  90. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/configs/config_bad.ini +0 -0
  91. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/examples.py +0 -0
  92. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/omt_examples.py +0 -0
  93. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/optimization_utils.py +0 -0
  94. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/__init__.py +0 -0
  95. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/parser_utils.py +0 -0
  96. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_annotations.py +0 -0
  97. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_fuzzed.py +0 -0
  98. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_generic_wrapper.py +0 -0
  99. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_griggio.py +0 -0
  100. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_model_validation.py +0 -0
  101. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_omt_lib_solver.py +0 -0
  102. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_examples.py +0 -0
  103. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_extensibility.py +0 -0
  104. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_lra.py +0 -0
  105. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_omt.py +0 -0
  106. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_arrays.py +0 -0
  107. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_lia.py +0 -0
  108. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_lira.py +0 -0
  109. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_lra.py +0 -0
  110. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_nia.py +0 -0
  111. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_nra.py +0 -0
  112. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_uf.py +0 -0
  113. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_qf_ufbv.py +0 -0
  114. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_parser_type_error.py +0 -0
  115. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/smtlib/test_smtlibscript.py +0 -0
  116. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_array.py +0 -0
  117. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_bdd.py +0 -0
  118. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_bv.py +0 -0
  119. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_bv_simplification.py +0 -0
  120. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_configuration.py +0 -0
  121. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_constants.py +0 -0
  122. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_cvc_quantifiers.py +0 -0
  123. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_dwf.py +0 -0
  124. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_eager_model.py +0 -0
  125. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_env.py +0 -0
  126. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_euf.py +0 -0
  127. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_formula.py +0 -0
  128. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_hr_parsing.py +0 -0
  129. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_imports.py +0 -0
  130. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_int.py +0 -0
  131. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_interpolation.py +0 -0
  132. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_lira.py +0 -0
  133. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_logics.py +0 -0
  134. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_models.py +0 -0
  135. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_native_qe.py +0 -0
  136. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_nia.py +0 -0
  137. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_nlira.py +0 -0
  138. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_optimization.py +0 -0
  139. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_optimizing.py +0 -0
  140. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_oracles.py +0 -0
  141. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_portfolio.py +0 -0
  142. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_printing.py +0 -0
  143. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_qe.py +0 -0
  144. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_rewritings.py +0 -0
  145. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_shannon_expansion.py +0 -0
  146. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_simplify.py +0 -0
  147. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_size.py +0 -0
  148. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_solving.py +0 -0
  149. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_sorts.py +0 -0
  150. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_string.py +0 -0
  151. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_typechecker.py +0 -0
  152. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_unsat_cores.py +0 -0
  153. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_walker_ext.py +0 -0
  154. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/test/test_walkers.py +0 -0
  155. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/type_checker.py +0 -0
  156. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/typing.py +0 -0
  157. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/utils.py +0 -0
  158. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/walkers/__init__.py +0 -0
  159. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/walkers/dag.py +0 -0
  160. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/walkers/generic.py +0 -0
  161. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/walkers/identitydag.py +0 -0
  162. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/pysmt/walkers/tree.py +0 -0
  163. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/setup.cfg +0 -0
  164. {pysmt-0.9.7.dev414 → pysmt-0.9.7.dev426}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PySMT
3
- Version: 0.9.7.dev414
3
+ Version: 0.9.7.dev426
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.dev414
3
+ Version: 0.9.7.dev426
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
@@ -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", 414)
22
+ VERSION: Union[Tuple[int, int, int], Tuple[int, int, int, str, int]] = (0, 9, 7, "dev", 426)
23
23
 
24
24
  # Try to provide human-readable version of latest commit for dev versions
25
25
  # E.g. v0.5.1-4-g49a49f2-wip
@@ -53,10 +53,12 @@ class CNFizer(DagWalker):
53
53
  def convert(self, formula):
54
54
  """Convert formula into an Equisatisfiable CNF.
55
55
 
56
- Returns a set of clauses: a set of set of literals.
56
+ Returns a set of clauses: a set of sets of literals.
57
57
  """
58
58
  tl, _cnf = self.walk(formula)
59
- res = [frozenset([tl])]
59
+ if len(_cnf) == 0:
60
+ return frozenset([frozenset([tl])])
61
+ res = []
60
62
  for clause in _cnf:
61
63
  if len(clause) == 0:
62
64
  return CNFizer.FALSE_CNF
@@ -66,6 +68,14 @@ class CNFizer(DagWalker):
66
68
  # Prune clauses that are trivially TRUE
67
69
  simp = None
68
70
  break
71
+ elif lit == tl:
72
+ # Prune clauses as ~tl -> l1 v ... v lk
73
+ simp = None
74
+ break
75
+ elif lit == self.mgr.Not(tl).simplify():
76
+ # Simplify tl -> l1 v ... v lk
77
+ # into l1 v ... v lk
78
+ continue
69
79
  elif not lit.is_false():
70
80
  # Prune FALSE literals
71
81
  simp.append(lit)
@@ -126,10 +136,7 @@ class CNFizer(DagWalker):
126
136
  elif a.is_false():
127
137
  return self.mgr.TRUE(), CNFizer.TRUE_CNF
128
138
  else:
129
- k = self._key_var(formula)
130
- return k, _cnf | frozenset([frozenset([self.mgr.Not(k),
131
- self.mgr.Not(a).simplify()]),
132
- frozenset([k, a])])
139
+ return self.mgr.Not(a).simplify(), _cnf
133
140
 
134
141
  def walk_implies(self, formula, args, **kwargs):
135
142
  a, cnf_a = args[0]
@@ -214,6 +221,161 @@ class CNFizer(DagWalker):
214
221
  # EOC CNFizer
215
222
 
216
223
 
224
+ class PolarityCNFizer(CNFizer):
225
+ """
226
+ Convert formula into an Equisatisfiable CNF using the polarity-based transformation.
227
+ """
228
+
229
+ def _get_children(self, formula, pol=None):
230
+ if formula.is_not():
231
+ return [(formula.arg(0), not pol)]
232
+
233
+ elif formula.is_implies():
234
+ return [(formula.arg(0), not pol), (formula.arg(1), pol)]
235
+
236
+ elif formula.is_iff():
237
+ return [(formula.arg(0), pol), (formula.arg(1), pol),
238
+ (formula.arg(0), not pol), (formula.arg(1), not pol)]
239
+
240
+ elif formula.is_and() or formula.is_or() or formula.is_quantifier():
241
+ return [(a, pol) for a in formula.args()]
242
+
243
+ elif formula.is_ite():
244
+ # This must be a boolean ITE as we do not recur within
245
+ # theory atoms
246
+ assert self.env.stc.get_type(formula).is_bool_type()
247
+ i, t, e = formula.args()
248
+ return [(i, pol), (i, not pol), (t, pol), (e, pol)]
249
+
250
+ else:
251
+ assert formula.is_str_op() or \
252
+ formula.is_symbol() or \
253
+ formula.is_function_application() or \
254
+ formula.is_bool_constant() or \
255
+ formula.is_theory_relation(), str(formula)
256
+ return []
257
+
258
+ def _push_with_children_to_stack(self, formula, pol=None, **kwargs):
259
+ self.stack.append((True, formula, pol))
260
+
261
+ for s, p in self._get_children(formula, pol):
262
+ # Add only if not memoized already
263
+ key = self._get_key(s, p, **kwargs)
264
+ if key not in self.memoization:
265
+ self.stack.append((False, s, p))
266
+
267
+ def _compute_node_result(self, formula, pol=None, **kwargs):
268
+ key = self._get_key(formula, pol, **kwargs)
269
+ if key not in self.memoization:
270
+ try:
271
+ f = self.functions[formula.node_type()]
272
+ except KeyError:
273
+ f = self.walk_error
274
+
275
+ args = [self.memoization[self._get_key(s, p, **kwargs)] \
276
+ for s, p in self._get_children(formula, pol)]
277
+
278
+ self.memoization[key] = f(formula, args=args, pol=pol, **kwargs)
279
+ else:
280
+ pass
281
+
282
+ def _process_stack(self, **kwargs):
283
+ while self.stack:
284
+ (was_expanded, formula, pol) = self.stack.pop()
285
+ if was_expanded:
286
+ self._compute_node_result(formula, pol, **kwargs)
287
+ else:
288
+ self._push_with_children_to_stack(formula, pol, **kwargs)
289
+
290
+ def iter_walk(self, formula, **kwargs):
291
+ self.stack.append((False, formula, True))
292
+ self._process_stack(**kwargs)
293
+ res_key = self._get_key(formula, pol=True, **kwargs)
294
+ return self.memoization[res_key]
295
+
296
+ def _get_key(self, formula, pol=None, **kwargs):
297
+ return formula, pol
298
+
299
+ def walk_and(self, formula, args, pol=None, **kwargs):
300
+ if len(args) == 1:
301
+ return args[0]
302
+
303
+ k = self._key_var(formula)
304
+ _cnf = [clause for a, c in args for clause in c]
305
+ if pol:
306
+ _cnf.extend(frozenset([a, self.mgr.Not(k)]) for a, _ in args)
307
+ else:
308
+ _cnf.extend([frozenset([k] + [self.mgr.Not(a).simplify() for a, _ in args])])
309
+
310
+ return k, frozenset(_cnf)
311
+
312
+ def walk_or(self, formula, args, pol=None, **kwargs):
313
+ if len(args) == 1:
314
+ return args[0]
315
+
316
+ k = self._key_var(formula)
317
+ _cnf = [clause for a, c in args for clause in c]
318
+ if pol:
319
+ _cnf.extend([frozenset([self.mgr.Not(k)] + [a for a, _ in args])])
320
+ else:
321
+ _cnf.extend(frozenset([k, self.mgr.Not(a).simplify()]) for a, c in args)
322
+
323
+ return k, frozenset(_cnf)
324
+
325
+ def walk_implies(self, formula, args, pol=None, **kwargs):
326
+ a, cnf_a = args[0]
327
+ b, cnf_b = args[1]
328
+
329
+ k = self._key_var(formula)
330
+ not_a = self.mgr.Not(a).simplify()
331
+ not_b = self.mgr.Not(b).simplify()
332
+ not_k = self.mgr.Not(k)
333
+ _cnf = []
334
+ if pol:
335
+ _cnf.extend([frozenset([not_a, b, not_k])])
336
+ else:
337
+ _cnf.extend([frozenset([a, k]), frozenset([not_b, k])])
338
+
339
+ return k, (cnf_a | cnf_b | frozenset(_cnf))
340
+
341
+ def walk_iff(self, formula, args, pol=None, **kwargs):
342
+ a, cnf_ap = args[0]
343
+ b, cnf_bp = args[1]
344
+ _, cnf_an = args[2]
345
+ _, cnf_bn = args[3]
346
+
347
+ k = self._key_var(formula)
348
+ not_a = self.mgr.Not(a).simplify()
349
+ not_b = self.mgr.Not(b).simplify()
350
+ not_k = self.mgr.Not(k)
351
+
352
+ return k, (cnf_ap | cnf_an | cnf_bp | cnf_bn
353
+ | frozenset([frozenset([not_a, not_b, k]),
354
+ frozenset([not_a, b, not_k]),
355
+ frozenset([a, not_b, not_k]),
356
+ frozenset([a, b, k])]))
357
+
358
+ def walk_ite(self, formula, args, pol=None, **kwargs):
359
+ if any(a == CNFizer.THEORY_PLACEHOLDER for a in args):
360
+ return CNFizer.THEORY_PLACEHOLDER
361
+ (i, cnf_ip), (_, cnf_in), (t, cnf_t), (e, cnf_e) = args
362
+ k = self._key_var(formula)
363
+ not_i = self.mgr.Not(i).simplify()
364
+ not_t = self.mgr.Not(t).simplify()
365
+ not_e = self.mgr.Not(e).simplify()
366
+ not_k = self.mgr.Not(k)
367
+
368
+ _cnf = []
369
+ if pol:
370
+ _cnf.extend([frozenset([not_i, t, not_k]), frozenset([i, e, not_k])])
371
+ else:
372
+ _cnf.extend([frozenset([not_i, not_t, k]), frozenset([i, not_e, k])])
373
+
374
+ return k, (cnf_ip | cnf_in | cnf_t | cnf_e | frozenset(_cnf))
375
+
376
+ # EOC PolarityCNFizer
377
+
378
+
217
379
  class NNFizer(DagWalker):
218
380
  """Converts a formula into Negation Normal Form.
219
381
 
@@ -340,12 +340,12 @@ class Z3Converter(Converter, DagWalker):
340
340
  z3.Z3_OP_IMPLIES: lambda args, expr: self.mgr.Implies(args[0], args[1]),
341
341
  z3.Z3_OP_ITE: lambda args, expr: self.mgr.Ite(args[0], args[1], args[2]),
342
342
  z3.Z3_OP_TO_REAL: lambda args, expr: self.mgr.ToReal(args[0]),
343
- z3.Z3_OP_BAND : lambda args, expr: self.mgr.BVAnd(args[0], args[1]),
344
- z3.Z3_OP_BOR : lambda args, expr: self.mgr.BVOr(args[0], args[1]),
343
+ z3.Z3_OP_BAND : lambda args, expr: self.mgr.BVAnd(args),
344
+ z3.Z3_OP_BOR : lambda args, expr: self.mgr.BVOr(args),
345
345
  z3.Z3_OP_BXOR : lambda args, expr: self.mgr.BVXor(args[0], args[1]),
346
346
  z3.Z3_OP_BNOT : lambda args, expr: self.mgr.BVNot(args[0]),
347
347
  z3.Z3_OP_BNEG : lambda args, expr: self.mgr.BVNeg(args[0]),
348
- z3.Z3_OP_CONCAT : lambda args, expr: self.mgr.BVConcat(args[0], args[1]),
348
+ z3.Z3_OP_CONCAT : lambda args, expr: self.mgr.BVConcat(args),
349
349
  z3.Z3_OP_ULT : lambda args, expr: self.mgr.BVULT(args[0], args[1]),
350
350
  z3.Z3_OP_ULEQ : lambda args, expr: self.mgr.BVULE(args[0], args[1]),
351
351
  z3.Z3_OP_SLT : lambda args, expr: self.mgr.BVSLT(args[0], args[1]),
@@ -354,8 +354,8 @@ class Z3Converter(Converter, DagWalker):
354
354
  z3.Z3_OP_UGEQ : lambda args, expr: self.mgr.BVUGE(args[0], args[1]),
355
355
  z3.Z3_OP_SGT : lambda args, expr: self.mgr.BVSGT(args[0], args[1]),
356
356
  z3.Z3_OP_SGEQ : lambda args, expr: self.mgr.BVSGE(args[0], args[1]),
357
- z3.Z3_OP_BADD : lambda args, expr: self.mgr.BVAdd(args[0], args[1]),
358
- z3.Z3_OP_BMUL : lambda args, expr: self.mgr.BVMul(args[0], args[1]),
357
+ z3.Z3_OP_BADD : lambda args, expr: self.mgr.BVAdd(args),
358
+ z3.Z3_OP_BMUL : lambda args, expr: self.mgr.BVMul(args),
359
359
  z3.Z3_OP_BUDIV : lambda args, expr: self.mgr.BVUDiv(args[0], args[1]),
360
360
  z3.Z3_OP_BSDIV : lambda args, expr: self.mgr.BVSDiv(args[0], args[1]),
361
361
  z3.Z3_OP_BUREM : lambda args, expr: self.mgr.BVURem(args[0], args[1]),
@@ -513,6 +513,9 @@ class Z3Converter(Converter, DagWalker):
513
513
  assert not len(args) > 2 or \
514
514
  (z3.is_and(expr) or z3.is_or(expr) or
515
515
  z3.is_add(expr) or z3.is_mul(expr) or
516
+ z3.is_app_of(expr, z3.Z3_OP_BAND) or z3.is_app_of(expr, z3.Z3_OP_BOR) or
517
+ z3.is_app_of(expr, z3.Z3_OP_BADD) or z3.is_app_of(expr, z3.Z3_OP_BMUL) or
518
+ z3.is_app_of(expr, z3.Z3_OP_CONCAT) or
516
519
  (len(args) == 3 and (z3.is_ite(expr) or z3.is_array_store(expr)))),\
517
520
  "Unexpected n-ary term: %s" % expr
518
521
 
@@ -16,11 +16,12 @@
16
16
  # limitations under the License.
17
17
  #
18
18
  from pysmt.shortcuts import FreshSymbol, GT, And, Plus, Real, Int, LE, Iff
19
- from pysmt.shortcuts import Solver
20
- from pysmt.typing import REAL, INT
19
+ from pysmt.shortcuts import Solver, Symbol, EqualsOrIff
20
+ from pysmt.shortcuts import BVAdd, BVMul, BVAnd, BVOr, BVConcat
21
+ from pysmt.typing import REAL, INT, BVType
21
22
  from pysmt.test import TestCase, skipIfSolverNotAvailable, main
22
23
  from pysmt.test.examples import get_example_formulae
23
- from pysmt.logics import QF_UFLIRA
24
+ from pysmt.logics import QF_UFLIRA, QF_BV
24
25
  from pysmt.exceptions import NoSolverAvailableError
25
26
 
26
27
 
@@ -87,6 +88,31 @@ class TestBasic(TestCase):
87
88
  self.do_back("z3", via_smtlib=True)
88
89
  self.do_back("z3", via_smtlib=False)
89
90
 
91
+ @skipIfSolverNotAvailable("z3")
92
+ def test_z3_back_nary_bv(self):
93
+ # Z3 simplification can produce n-ary (more than two arguments)
94
+ # bit-vector operations. Back-converting them used to fail because
95
+ # only the binary case was handled (unlike the integer operations).
96
+ import z3 # type: ignore[import]
97
+
98
+ s = Solver(name="z3", logic=QF_BV)
99
+ conv = s.converter
100
+ a = Symbol("a", BVType(8))
101
+ b = Symbol("b", BVType(8))
102
+ c = Symbol("c", BVType(8))
103
+
104
+ for f in (BVAdd(BVAdd(a, b), c),
105
+ BVMul(BVMul(a, b), c),
106
+ BVAnd(BVAnd(a, b), c),
107
+ BVOr(BVOr(a, b), c),
108
+ BVConcat(BVConcat(a, b), c)):
109
+ # Simplify in Z3 to flatten the associative operators into a
110
+ # single n-ary application before converting back.
111
+ simplified = z3.simplify(conv.convert(f))
112
+ res = conv.back(simplified)
113
+ self.assertValid(EqualsOrIff(f, res), logic=QF_BV,
114
+ solver_name="z3")
115
+
90
116
 
91
117
  if __name__ == '__main__':
92
118
  main()
@@ -19,7 +19,7 @@ import os
19
19
  import pytest
20
20
 
21
21
  from pysmt.shortcuts import Implies, is_sat, is_valid, reset_env, Symbol, Iff, Select, ArrayType, INT, BOOL, And, get_env
22
- from pysmt.rewritings import CNFizer
22
+ from pysmt.rewritings import CNFizer, PolarityCNFizer
23
23
  from pysmt.logics import QF_BOOL, QF_LRA, QF_LIA, QF_UFLIRA, QF_UFLRA, QF_ALIA
24
24
  from pysmt.test import TestCase, skipIfNoSolverForLogic, main
25
25
  from pysmt.test.examples import get_example_formulae
@@ -29,16 +29,16 @@ from pysmt.smtlib.parser import get_formula_fname
29
29
  class TestCnf(TestCase):
30
30
 
31
31
  def do_examples(self, logic):
32
- conv = CNFizer()
33
- for example in get_example_formulae():
34
- if example.logic != logic:
35
- continue
36
- cnf = conv.convert_as_formula(example.expr)
32
+ for conv in (CNFizer(), PolarityCNFizer()):
33
+ for example in get_example_formulae():
34
+ if example.logic != logic:
35
+ continue
36
+ cnf = conv.convert_as_formula(example.expr)
37
37
 
38
- self.assertValid(Implies(cnf, example.expr), logic=logic)
38
+ self.assertValid(Implies(cnf, example.expr), logic=logic)
39
39
 
40
- res = is_sat(cnf, logic=logic)
41
- self.assertEqual(res, example.is_sat)
40
+ res = is_sat(cnf, logic=logic)
41
+ self.assertEqual(res, example.is_sat)
42
42
 
43
43
 
44
44
  @skipIfNoSolverForLogic(QF_BOOL)
@@ -80,31 +80,30 @@ class TestCnf(TestCase):
80
80
 
81
81
  def _smtlib_cnf(self, filename, logic, res_is_sat):
82
82
  reset_env()
83
- conv = CNFizer()
84
83
  smtfile = os.path.join(SMTLIB_DIR, filename)
85
84
  assert os.path.exists(smtfile)
86
85
 
87
86
  expr = get_formula_fname(smtfile)
88
- if not logic.quantifier_free:
89
- with self.assertRaises(NotImplementedError):
90
- conv.convert_as_formula(expr)
91
- return
87
+ for conv in (CNFizer(), PolarityCNFizer()):
88
+ if not logic.quantifier_free:
89
+ with self.assertRaises(NotImplementedError):
90
+ conv.convert_as_formula(expr)
91
+ return
92
+ cnf = conv.convert_as_formula(expr)
93
+ self.assertTrue(is_valid(Implies(cnf, expr), logic=logic))
92
94
 
93
- cnf = conv.convert_as_formula(expr)
94
- self.assertTrue(is_valid(Implies(cnf, expr), logic=logic))
95
-
96
- res = is_sat(cnf, logic=logic)
97
- self.assertEqual(res, res_is_sat)
95
+ res = is_sat(cnf, logic=logic)
96
+ self.assertEqual(res, res_is_sat)
98
97
 
99
98
  @skipIfNoSolverForLogic(QF_BOOL)
100
99
  def test_implies(self):
101
100
  a,b,c,d = (Symbol(x) for x in "abcd")
102
101
  f = Implies(Iff(a, b), Iff(c, d))
103
102
 
104
- conv = CNFizer()
105
- cnf = conv.convert_as_formula(f)
103
+ for conv in [CNFizer(), PolarityCNFizer()]:
104
+ cnf = conv.convert_as_formula(f)
106
105
 
107
- self.assertValid(Implies(cnf, f), logic=QF_BOOL)
106
+ self.assertValid(Implies(cnf, f), logic=QF_BOOL)
108
107
 
109
108
  @skipIfNoSolverForLogic(QF_ALIA)
110
109
  def test_CNFizer_bool_theory(self):
@@ -258,7 +258,7 @@ class TestRegressions(TestCase):
258
258
 
259
259
  def test_cnf_as_set(self):
260
260
  r = cnf_as_set(Symbol("x"))
261
- self.assertTrue(type(r) == frozenset)
261
+ self.assertEqual(type(r), frozenset)
262
262
 
263
263
  def test_substitute_to_real(self):
264
264
  p = Symbol("p", INT)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes