PySMT 0.9.7.dev408__tar.gz → 0.9.7.dev423__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.dev408/PySMT.egg-info → pysmt-0.9.7.dev423}/PKG-INFO +1 -1
  2. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423/PySMT.egg-info}/PKG-INFO +1 -1
  3. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/__init__.py +1 -1
  4. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/rewritings.py +168 -6
  5. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/substituter.py +5 -3
  6. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_cnf.py +21 -22
  7. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_regressions.py +1 -1
  8. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_walkers.py +16 -1
  9. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/LICENSE +0 -0
  10. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/MANIFEST.in +0 -0
  11. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/NOTICE +0 -0
  12. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/PySMT.egg-info/SOURCES.txt +0 -0
  13. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/PySMT.egg-info/dependency_links.txt +0 -0
  14. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/PySMT.egg-info/entry_points.txt +0 -0
  15. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/PySMT.egg-info/top_level.txt +0 -0
  16. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/README.rst +0 -0
  17. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/CHANGES.rst +0 -0
  18. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/api_ref.rst +0 -0
  19. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/development.rst +0 -0
  20. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/getting_started.rst +0 -0
  21. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/index.rst +0 -0
  22. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/tutorials/boolean_logic.rst +0 -0
  23. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/docs/tutorials.rst +0 -0
  24. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/__main__.py +0 -0
  25. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/__init__.py +0 -0
  26. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/check_version.py +0 -0
  27. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/install.py +0 -0
  28. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/__init__.py +0 -0
  29. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/base.py +0 -0
  30. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/bdd.py +0 -0
  31. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/btor.py +0 -0
  32. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/cvcfive.py +0 -0
  33. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/cvcfour.py +0 -0
  34. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/msat.py +0 -0
  35. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/optimsat.py +0 -0
  36. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/pico.py +0 -0
  37. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/yices.py +0 -0
  38. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/installers/z3.py +0 -0
  39. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/cmd/shell.py +0 -0
  40. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/configuration.py +0 -0
  41. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/constants.py +0 -0
  42. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/decorators.py +0 -0
  43. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/environment.py +0 -0
  44. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/exceptions.py +0 -0
  45. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/factory.py +0 -0
  46. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/fnode.py +0 -0
  47. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/formula.py +0 -0
  48. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/logics.py +0 -0
  49. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/operators.py +0 -0
  50. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/__init__.py +0 -0
  51. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/goal.py +0 -0
  52. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/msat.py +0 -0
  53. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/optimizer.py +0 -0
  54. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/optimsat.py +0 -0
  55. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/yices.py +0 -0
  56. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/optimization/z3.py +0 -0
  57. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/oracles.py +0 -0
  58. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/parsing.py +0 -0
  59. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/printers.py +0 -0
  60. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/shortcuts.py +0 -0
  61. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/simplifier.py +0 -0
  62. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/__init__.py +0 -0
  63. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/annotations.py +0 -0
  64. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/commands.py +0 -0
  65. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/parser/__init__.py +0 -0
  66. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/parser/parser.py +0 -0
  67. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/printers.py +0 -0
  68. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/script.py +0 -0
  69. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/solver.py +0 -0
  70. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/smtlib/utils.py +0 -0
  71. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/__init__.py +0 -0
  72. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/bdd.py +0 -0
  73. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/btor.py +0 -0
  74. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/cvcfive.py +0 -0
  75. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/cvcfour.py +0 -0
  76. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/dynmsat.py +0 -0
  77. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/eager.py +0 -0
  78. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/interpolation.py +0 -0
  79. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/msat.py +0 -0
  80. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/options.py +0 -0
  81. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/pico.py +0 -0
  82. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/portfolio.py +0 -0
  83. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/qelim.py +0 -0
  84. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/smtlib.py +0 -0
  85. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/solver.py +0 -0
  86. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/yices.py +0 -0
  87. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/solvers/z3.py +0 -0
  88. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/__init__.py +0 -0
  89. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/configs/config1.ini +0 -0
  90. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/configs/config_bad.ini +0 -0
  91. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/examples.py +0 -0
  92. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/omt_examples.py +0 -0
  93. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/optimization_utils.py +0 -0
  94. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/__init__.py +0 -0
  95. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/parser_utils.py +0 -0
  96. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_annotations.py +0 -0
  97. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_fuzzed.py +0 -0
  98. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_generic_wrapper.py +0 -0
  99. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_griggio.py +0 -0
  100. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_model_validation.py +0 -0
  101. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_omt_lib_solver.py +0 -0
  102. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_examples.py +0 -0
  103. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_extensibility.py +0 -0
  104. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_lra.py +0 -0
  105. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_omt.py +0 -0
  106. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_arrays.py +0 -0
  107. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_lia.py +0 -0
  108. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_lira.py +0 -0
  109. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_lra.py +0 -0
  110. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_nia.py +0 -0
  111. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_nra.py +0 -0
  112. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_uf.py +0 -0
  113. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_qf_ufbv.py +0 -0
  114. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_parser_type_error.py +0 -0
  115. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/smtlib/test_smtlibscript.py +0 -0
  116. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_array.py +0 -0
  117. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_back.py +0 -0
  118. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_bdd.py +0 -0
  119. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_bv.py +0 -0
  120. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_bv_simplification.py +0 -0
  121. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_configuration.py +0 -0
  122. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_constants.py +0 -0
  123. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_cvc_quantifiers.py +0 -0
  124. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_dwf.py +0 -0
  125. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_eager_model.py +0 -0
  126. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_env.py +0 -0
  127. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_euf.py +0 -0
  128. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_formula.py +0 -0
  129. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_hr_parsing.py +0 -0
  130. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_imports.py +0 -0
  131. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_int.py +0 -0
  132. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_interpolation.py +0 -0
  133. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_lira.py +0 -0
  134. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_logics.py +0 -0
  135. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_models.py +0 -0
  136. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_native_qe.py +0 -0
  137. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_nia.py +0 -0
  138. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_nlira.py +0 -0
  139. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_optimization.py +0 -0
  140. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_optimizing.py +0 -0
  141. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_oracles.py +0 -0
  142. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_portfolio.py +0 -0
  143. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_printing.py +0 -0
  144. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_qe.py +0 -0
  145. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_rewritings.py +0 -0
  146. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_shannon_expansion.py +0 -0
  147. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_simplify.py +0 -0
  148. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_size.py +0 -0
  149. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_solving.py +0 -0
  150. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_sorts.py +0 -0
  151. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_string.py +0 -0
  152. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_typechecker.py +0 -0
  153. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_unsat_cores.py +0 -0
  154. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/test/test_walker_ext.py +0 -0
  155. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/type_checker.py +0 -0
  156. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/typing.py +0 -0
  157. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/utils.py +0 -0
  158. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/walkers/__init__.py +0 -0
  159. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/walkers/dag.py +0 -0
  160. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/walkers/generic.py +0 -0
  161. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/walkers/identitydag.py +0 -0
  162. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/pysmt/walkers/tree.py +0 -0
  163. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/setup.cfg +0 -0
  164. {pysmt-0.9.7.dev408 → pysmt-0.9.7.dev423}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PySMT
3
- Version: 0.9.7.dev408
3
+ Version: 0.9.7.dev423
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.dev408
3
+ Version: 0.9.7.dev423
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", 408)
22
+ VERSION: Union[Tuple[int, int, int], Tuple[int, int, int, str, int]] = (0, 9, 7, "dev", 423)
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
 
@@ -151,7 +151,8 @@ class Substituter(pysmt.walkers.IdentityDagWalker):
151
151
  # 2. We apply the substitution on the quantifier body with
152
152
  # the new 'reduced' map
153
153
  sub = self.__class__(self.env)
154
- res_formula = sub.substitute(formula.arg(0), new_subs)
154
+ res_formula = sub.substitute(formula.arg(0), subs=new_subs,
155
+ interpretations=kwargs.get('interpretations', None))
155
156
 
156
157
  # 3. We invoke the relevant function (walk_exists or
157
158
  # walk_forall) to compute the substitution
@@ -304,8 +305,9 @@ class MSSubstituter(Substituter):
304
305
  def __init__(self, env):
305
306
  Substituter.__init__(self, env=env)
306
307
 
307
- def substitute(self, formula, subs):
308
- return Substituter.substitute(self, formula, subs)
308
+ def substitute(self, formula, subs=None, interpretations=None):
309
+ return Substituter.substitute(self, formula, subs,
310
+ interpretations=interpretations)
309
311
 
310
312
  def _substitute(self, formula, substitutions):
311
313
  """Returns the substitution for formula, if one is defined, otherwise
@@ -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)
@@ -26,7 +26,7 @@ from pysmt.test import TestCase, main
26
26
  from pysmt.formula import FormulaManager
27
27
  from pysmt.test.examples import get_example_formulae
28
28
  from pysmt.exceptions import UnsupportedOperatorError, PysmtTypeError
29
- from pysmt.substituter import MSSubstituter, MGSubstituter
29
+ from pysmt.substituter import FunctionInterpretation, MSSubstituter, MGSubstituter
30
30
 
31
31
 
32
32
  class TestWalkers(TestCase):
@@ -78,6 +78,21 @@ class TestWalkers(TestCase):
78
78
  with self.assertRaisesRegex(PysmtTypeError, "substitute()"):
79
79
  substitute(f, {x:x})
80
80
 
81
+ def test_substituter_interpretations_in_quantifiers(self):
82
+ x = Symbol("x", INT)
83
+ UF_XOR = Symbol('uf_xor', FunctionType(INT, [INT, INT]))
84
+ f = ForAll([x], Equals(Function(UF_XOR, [x, x]), Int(0)))
85
+
86
+ class XORInterpreter(FunctionInterpretation):
87
+ def __init__(self): pass
88
+ def interpret(self, env, args):
89
+ if args[0] == args[1]: return Int(0)
90
+ return Function(UF_XOR, args)
91
+
92
+ subs = f.substitute({}, interpretations={UF_XOR: XORInterpreter()})
93
+
94
+ self.assertEqual(subs, ForAll([x], Equals(Int(0), Int(0))))
95
+
81
96
  def test_undefined_node(self):
82
97
  varA = Symbol("At", INT)
83
98
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes