PySMT 0.9.7.dev461__tar.gz → 0.9.7.dev468__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.dev461/PySMT.egg-info → pysmt-0.9.7.dev468}/PKG-INFO +1 -1
  2. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468/PySMT.egg-info}/PKG-INFO +1 -1
  3. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/__init__.py +1 -1
  4. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/environment.py +17 -10
  5. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/optimization/optimizer.py +5 -2
  6. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/optimization/z3.py +4 -4
  7. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/oracles.py +7 -3
  8. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/rewritings.py +3 -6
  9. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/simplifier.py +1 -2
  10. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/smtlib/printers.py +1 -2
  11. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/msat.py +6 -2
  12. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/substituter.py +1 -2
  13. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_dwf.py +47 -0
  14. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_walkers.py +22 -20
  15. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/walkers/dag.py +2 -6
  16. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/walkers/generic.py +29 -36
  17. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/walkers/tree.py +4 -13
  18. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/LICENSE +0 -0
  19. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/MANIFEST.in +0 -0
  20. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/NOTICE +0 -0
  21. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/PySMT.egg-info/SOURCES.txt +0 -0
  22. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/PySMT.egg-info/dependency_links.txt +0 -0
  23. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/PySMT.egg-info/entry_points.txt +0 -0
  24. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/PySMT.egg-info/top_level.txt +0 -0
  25. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/README.rst +0 -0
  26. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/docs/CHANGES.rst +0 -0
  27. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/docs/api_ref.rst +0 -0
  28. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/docs/development.rst +0 -0
  29. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/docs/getting_started.rst +0 -0
  30. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/docs/index.rst +0 -0
  31. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/docs/tutorials/boolean_logic.rst +0 -0
  32. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/docs/tutorials.rst +0 -0
  33. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/__main__.py +0 -0
  34. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/__init__.py +0 -0
  35. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/check_version.py +0 -0
  36. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/install.py +0 -0
  37. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/installers/__init__.py +0 -0
  38. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/installers/base.py +0 -0
  39. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/installers/bdd.py +0 -0
  40. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/installers/btor.py +0 -0
  41. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/installers/cvcfive.py +0 -0
  42. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/installers/cvcfour.py +0 -0
  43. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/installers/msat.py +0 -0
  44. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/installers/optimsat.py +0 -0
  45. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/installers/pico.py +0 -0
  46. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/installers/yices.py +0 -0
  47. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/installers/z3.py +0 -0
  48. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/cmd/shell.py +0 -0
  49. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/configuration.py +0 -0
  50. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/constants.py +0 -0
  51. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/decorators.py +0 -0
  52. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/exceptions.py +0 -0
  53. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/factory.py +0 -0
  54. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/fnode.py +0 -0
  55. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/formula.py +0 -0
  56. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/logics.py +0 -0
  57. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/operators.py +0 -0
  58. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/optimization/__init__.py +0 -0
  59. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/optimization/goal.py +0 -0
  60. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/optimization/msat.py +0 -0
  61. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/optimization/optimsat.py +0 -0
  62. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/optimization/yices.py +0 -0
  63. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/parsing.py +0 -0
  64. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/printers.py +0 -0
  65. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/shortcuts.py +0 -0
  66. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/smtlib/__init__.py +0 -0
  67. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/smtlib/annotations.py +0 -0
  68. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/smtlib/commands.py +0 -0
  69. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/smtlib/parser/__init__.py +0 -0
  70. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/smtlib/parser/parser.py +0 -0
  71. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/smtlib/script.py +0 -0
  72. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/smtlib/solver.py +0 -0
  73. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/smtlib/utils.py +0 -0
  74. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/__init__.py +0 -0
  75. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/bdd.py +0 -0
  76. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/btor.py +0 -0
  77. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/cvcfive.py +0 -0
  78. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/cvcfour.py +0 -0
  79. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/dynmsat.py +0 -0
  80. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/eager.py +0 -0
  81. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/interpolation.py +0 -0
  82. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/options.py +0 -0
  83. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/pico.py +0 -0
  84. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/portfolio.py +0 -0
  85. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/qelim.py +0 -0
  86. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/smtlib.py +0 -0
  87. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/solver.py +0 -0
  88. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/yices.py +0 -0
  89. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/solvers/z3.py +0 -0
  90. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/__init__.py +0 -0
  91. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/configs/config1.ini +0 -0
  92. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/configs/config_bad.ini +0 -0
  93. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/examples.py +0 -0
  94. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/omt_examples.py +0 -0
  95. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/optimization_utils.py +0 -0
  96. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/__init__.py +0 -0
  97. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/parser_utils.py +0 -0
  98. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_annotations.py +0 -0
  99. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_fuzzed.py +0 -0
  100. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_generic_wrapper.py +0 -0
  101. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_griggio.py +0 -0
  102. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_model_validation.py +0 -0
  103. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_omt_lib_solver.py +0 -0
  104. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_parser_examples.py +0 -0
  105. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_parser_extensibility.py +0 -0
  106. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_parser_lra.py +0 -0
  107. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_parser_omt.py +0 -0
  108. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_parser_qf_arrays.py +0 -0
  109. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_parser_qf_lia.py +0 -0
  110. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_parser_qf_lira.py +0 -0
  111. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_parser_qf_lra.py +0 -0
  112. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_parser_qf_nia.py +0 -0
  113. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_parser_qf_nra.py +0 -0
  114. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_parser_qf_uf.py +0 -0
  115. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_parser_qf_ufbv.py +0 -0
  116. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_parser_type_error.py +0 -0
  117. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/smtlib/test_smtlibscript.py +0 -0
  118. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_array.py +0 -0
  119. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_back.py +0 -0
  120. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_bdd.py +0 -0
  121. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_bv.py +0 -0
  122. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_bv_simplification.py +0 -0
  123. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_cnf.py +0 -0
  124. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_configuration.py +0 -0
  125. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_constants.py +0 -0
  126. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_cvc_quantifiers.py +0 -0
  127. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_eager_model.py +0 -0
  128. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_env.py +0 -0
  129. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_euf.py +0 -0
  130. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_formula.py +0 -0
  131. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_hr_parsing.py +0 -0
  132. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_imports.py +0 -0
  133. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_int.py +0 -0
  134. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_interpolation.py +0 -0
  135. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_lira.py +0 -0
  136. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_logics.py +0 -0
  137. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_models.py +0 -0
  138. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_native_qe.py +0 -0
  139. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_nia.py +0 -0
  140. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_nlira.py +0 -0
  141. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_optimization.py +0 -0
  142. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_optimizing.py +0 -0
  143. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_oracles.py +0 -0
  144. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_portfolio.py +0 -0
  145. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_printing.py +0 -0
  146. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_qe.py +0 -0
  147. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_regressions.py +0 -0
  148. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_rewritings.py +0 -0
  149. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_shannon_expansion.py +0 -0
  150. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_simplify.py +0 -0
  151. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_size.py +0 -0
  152. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_solving.py +0 -0
  153. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_sorts.py +0 -0
  154. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_string.py +0 -0
  155. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_typechecker.py +0 -0
  156. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_unsat_cores.py +0 -0
  157. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/test/test_walker_ext.py +0 -0
  158. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/type_checker.py +0 -0
  159. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/typing.py +0 -0
  160. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/utils.py +0 -0
  161. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/walkers/__init__.py +0 -0
  162. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/pysmt/walkers/identitydag.py +0 -0
  163. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/setup.cfg +0 -0
  164. {pysmt-0.9.7.dev461 → pysmt-0.9.7.dev468}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PySMT
3
- Version: 0.9.7.dev461
3
+ Version: 0.9.7.dev468
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.dev461
3
+ Version: 0.9.7.dev468
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", 461)
22
+ VERSION: Union[Tuple[int, int, int], Tuple[int, int, int, str, int]] = (0, 9, 7, "dev", 468)
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
@@ -21,7 +21,7 @@ singleton objects that are used throughout the system, such as the
21
21
  FormulaManager, Simplifier, HRSerializer, SimpleTypeChecker.
22
22
  """
23
23
 
24
- from typing import List, Optional
24
+ from typing import Callable, Dict, List, Optional, Tuple, Type
25
25
 
26
26
  import pysmt.simplifier
27
27
  import pysmt.printers
@@ -87,9 +87,11 @@ class Environment(object):
87
87
  # (e.g. substitution and simplification).
88
88
  self.allow_empty_var_names = False
89
89
 
90
- # Dynamic Walker Configuration Map
90
+ # Dynamic Walker Functions: handlers for custom node types,
91
+ # keyed by (nodetype, walker_class). Kept local to this
92
+ # environment so registrations never leak across environments.
91
93
  # See: add_dynamic_walker_function
92
- self.dwf = {}
94
+ self.dwf: Dict[Tuple[int, Type], Callable] = {}
93
95
 
94
96
  @property
95
97
  def formula_manager(self) -> pysmt.formula.FormulaManager:
@@ -154,15 +156,20 @@ class Environment(object):
154
156
  function to a given walker, so that the walker will be able to
155
157
  handle the new nodetype.
156
158
 
157
- See :py:meth:`pysmt.walkers.generic.Walker.walk_error` for
158
- more information.
159
+ See :py:meth:`pysmt.walkers.generic.Walker.super` for more
160
+ information on how the handler is dispatched.
159
161
  """
160
- # self.dwf is a map of maps: {nodetype, {walker: function}}
161
- if nodetype not in self.dwf:
162
- self.dwf[nodetype] = {}
162
+ key = (nodetype, walker)
163
+ assert key not in self.dwf, "Dynamic Walker Redefinition!"
164
+ self.dwf[key] = function
163
165
 
164
- assert walker not in self.dwf[nodetype], "Redefinition"
165
- self.dwf[nodetype][walker] = function
166
+ def get_dynamic_walker_function(self, nodetype, walker_class):
167
+ """Return the handler registered for (nodetype, walker_class), or None.
168
+
169
+ Used by :py:meth:`pysmt.walkers.generic.Walker.super` to
170
+ dispatch custom node types without mutating the walker class.
171
+ """
172
+ return self.dwf.get((nodetype, walker_class))
166
173
 
167
174
  @property
168
175
  def factory(self) -> "pysmt.factory.Factory":
@@ -16,6 +16,8 @@
16
16
  # limitations under the License.
17
17
  #
18
18
  from fractions import Fraction
19
+
20
+ from pysmt.constants import is_pysmt_integer, is_pysmt_fraction
19
21
  import warnings
20
22
 
21
23
  from pysmt.solvers.solver import Solver
@@ -371,8 +373,9 @@ class OptSearchInterval(OptComparationFunctions):
371
373
  model_value: Union[Fraction, int] = obj_value.bv_signed_value()
372
374
  else:
373
375
  v = obj_value.constant_value()
374
- assert isinstance(v, (int, Fraction))
375
- model_value = v
376
+ # backend-aware: v may be a gmpy2 mpz/mpq, not a python int/Fraction
377
+ assert is_pysmt_integer(v) or is_pysmt_fraction(v)
378
+ model_value = cast(Union[Fraction, int], v)
376
379
  if self._obj.is_minimization_goal():
377
380
  if self._upper is None or self._upper > model_value:
378
381
  self._upper = model_value
@@ -18,7 +18,6 @@
18
18
 
19
19
  from __future__ import absolute_import
20
20
 
21
- from fractions import Fraction
22
21
  from warnings import warn
23
22
 
24
23
  from pysmt.decorators import clear_pending_pop
@@ -63,9 +62,10 @@ class Z3NativeOptimizer(Optimizer, Z3Solver):
63
62
  assert isinstance(goal, MaxSMTGoal)
64
63
  for soft, weight_exp in goal.soft:
65
64
  obj_soft = self.converter.convert(soft)
66
- w: Union[float, int, Fraction, str] = weight_exp.constant_value()
67
- if isinstance(w, Fraction):
68
- w = float(w)
65
+ # str() yields an exact rational numeral ("1/3", "8") for every
66
+ # backend (int/Fraction and gmpy2 mpz/mpq); z3 add_soft parses it,
67
+ # avoiding the precision loss of float() on fractional weights.
68
+ w = str(weight_exp.constant_value())
69
69
  h = self.z3.add_soft(obj_soft, w, "__pysmt_" + str(goal_id))
70
70
  else:
71
71
  term = goal.term()
@@ -27,7 +27,7 @@ properties of formulae.
27
27
  """
28
28
 
29
29
  from itertools import chain
30
- from typing import FrozenSet, Iterable, List, Any, Optional, Union, cast
30
+ from typing import FrozenSet, Iterable, List, Any, Optional, Union, cast, Callable, Dict
31
31
 
32
32
  import pysmt
33
33
  import pysmt.walkers as walkers
@@ -60,7 +60,7 @@ class SizeOracle(walkers.DagWalker):
60
60
  def __init__(self, env: Optional["pysmt.environment.Environment"]=None):
61
61
  walkers.DagWalker.__init__(self, env=env)
62
62
 
63
- self.measure_to_fun = \
63
+ self.measure_to_fun: Dict[int, Callable] = \
64
64
  {SizeOracle.MEASURE_TREE_NODES: self.walk_count_tree,
65
65
  SizeOracle.MEASURE_DAG_NODES: self.walk_count_dag,
66
66
  SizeOracle.MEASURE_LEAVES: self.walk_count_leaves,
@@ -68,12 +68,16 @@ class SizeOracle(walkers.DagWalker):
68
68
  SizeOracle.MEASURE_SYMBOLS: self.walk_count_symbols,
69
69
  SizeOracle.MEASURE_BOOL_DAG: self.walk_count_bool_dag,
70
70
  }
71
+ self._walking_fun: Optional[Callable] = None
71
72
 
73
+ @walkers.handles(*op.ALL_TYPES)
74
+ def walk_measure(self, formula, args, **kwargs):
75
+ return assert_not_none(self._walking_fun)(formula, args, **kwargs)
72
76
 
73
77
  def set_walking_measure(self, measure: int):
74
78
  if measure not in self.measure_to_fun:
75
79
  raise NotImplementedError
76
- self.set_function(self.measure_to_fun[measure], *op.ALL_TYPES)
80
+ self._walking_fun = self.measure_to_fun[measure]
77
81
 
78
82
  def _get_key(self, formula, measure, **kwargs):
79
83
  """Memoize using a tuple (measure, formula)."""
@@ -268,15 +268,12 @@ class PolarityCNFizer(CNFizer):
268
268
  def _compute_node_result(self, formula, pol=None, **kwargs):
269
269
  key = self._get_key(formula, pol, **kwargs)
270
270
  if key not in self.memoization:
271
- try:
272
- f = self.functions[formula.node_type()]
273
- except KeyError:
274
- f = self.walk_error
275
-
276
271
  args = [self.memoization[self._get_key(s, p, **kwargs)] \
277
272
  for s, p in self._get_children(formula, pol)]
278
273
 
279
- self.memoization[key] = f(formula, args=args, pol=pol, **kwargs)
274
+ self.memoization[key] = self.__class__.super(self, formula,
275
+ args=args, pol=pol,
276
+ **kwargs)
280
277
  else:
281
278
  pass
282
279
 
@@ -74,8 +74,7 @@ class Simplifier(pysmt.walkers.DagWalker):
74
74
 
75
75
  args = [self.walk(s, **kwargs) for s in formula.args()]
76
76
 
77
- f = self.functions[formula.node_type()]
78
- res = f(formula, args=args, **kwargs)
77
+ res = self.__class__.super(self, formula, args=args, **kwargs)
79
78
  ltype = get_type(formula)
80
79
  rtype = get_type(res)
81
80
  test = Equals(formula, res) if ltype != BOOL else Iff(formula, res)
@@ -346,8 +346,7 @@ class SmtDagPrinter(DagWalker):
346
346
  if formula.is_quantifier():
347
347
  # 1. We invoke the relevant function (walk_exists or
348
348
  # walk_forall) to print the formula
349
- fun = self.functions[formula.node_type()]
350
- res = fun(formula, args=None, **kwargs)
349
+ res = self.__class__.super(self, formula, args=None, **kwargs)
351
350
 
352
351
  # 2. We memoize the result
353
352
  key = self._get_key(formula, **kwargs)
@@ -41,6 +41,7 @@ from pysmt.decorators import clear_pending_pop, catch_conversion_error
41
41
  from pysmt.solvers.qelim import QuantifierEliminator
42
42
  from pysmt.solvers.interpolation import Interpolator
43
43
  from pysmt.walkers.identitydag import IdentityDagWalker
44
+ from pysmt.walkers.generic import handles
44
45
  from pysmt.environment import Environment
45
46
  from pysmt.fnode import FNode
46
47
  from pysmt.formula import FormulaManager
@@ -1183,8 +1184,6 @@ class MSatQuantifierEliminator(QuantifierEliminator, IdentityDagWalker):
1183
1184
  self.msat_env = MSATCreateEnv(self.__class__.__lib_name__, self.msat_config)
1184
1185
  self._msat_lib.msat_destroy_config(self.msat_config)
1185
1186
 
1186
- self.set_function(self.walk_identity, op.SYMBOL, op.REAL_CONSTANT,
1187
- op.BOOL_CONSTANT, op.INT_CONSTANT)
1188
1187
  self.logic = logic
1189
1188
 
1190
1189
  self.algorithm = algorithm
@@ -1243,6 +1242,11 @@ class MSatQuantifierEliminator(QuantifierEliminator, IdentityDagWalker):
1243
1242
  subf = args[0]
1244
1243
  return self.exist_elim(variables, subf)
1245
1244
 
1245
+ @handles(op.SYMBOL, op.REAL_CONSTANT, op.BOOL_CONSTANT, op.INT_CONSTANT)
1246
+ def walk_identity(self, formula, args, **kwargs):
1247
+ # Leaves are unchanged by quantifier elimination.
1248
+ return formula
1249
+
1246
1250
  def _exit(self):
1247
1251
  del self.msat_env
1248
1252
 
@@ -157,8 +157,7 @@ class Substituter(pysmt.walkers.IdentityDagWalker):
157
157
 
158
158
  # 3. We invoke the relevant function (walk_exists or
159
159
  # walk_forall) to compute the substitution
160
- fun = self.functions[formula.node_type()]
161
- res = fun(formula, args=[res_formula], **kwargs)
160
+ res = self.__class__.super(self, formula, args=[res_formula], **kwargs)
162
161
 
163
162
  # 4. We memoize the result
164
163
  key = self._get_key(formula, **kwargs)
@@ -73,3 +73,50 @@ class TestDwf(TestCase):
73
73
  new_t = new_node_type()
74
74
  new_types_set = set(all_types())
75
75
  self.assertEqual(new_types_set - old_types_set, set([new_t]))
76
+
77
+ def test_03_dwf_is_environment_local(self):
78
+ # A DWF registered in one environment must not leak into another.
79
+ # Handlers are dispatched via Walker.super through the walker's
80
+ # own env, not by mutating the (process-global) walker class.
81
+ from pysmt.environment import Environment
82
+ from pysmt.printers import HRPrinter
83
+
84
+ def make_printer(sep):
85
+ def hrprinter_walk_XOR(self, formula):
86
+ self.stream.write("(")
87
+ yield formula.arg(0)
88
+ self.stream.write(sep)
89
+ yield formula.arg(1)
90
+ self.stream.write(")")
91
+ return hrprinter_walk_XOR
92
+
93
+ XOR = new_node_type()
94
+ env1 = Environment()
95
+ env2 = Environment()
96
+
97
+ # Both envs must be able to build the node, so both get a
98
+ # type-checker handler. Only env1 gets a printer handler.
99
+ for env in (env1, env2):
100
+ env.add_dynamic_walker_function(
101
+ XOR, SimpleTypeChecker, SimpleTypeChecker.walk_bool_to_bool)
102
+ env1.add_dynamic_walker_function(XOR, HRPrinter, make_printer(" *+* "))
103
+
104
+ x1 = env1.formula_manager.Symbol("x")
105
+ f1 = env1.formula_manager.create_node(node_type=XOR, args=(x1, x1))
106
+ self.assertEqual(env1.serializer.serialize(f1), "(x *+* x)")
107
+
108
+ # The handler registered on env1 must NOT leak into env2.
109
+ x2 = env2.formula_manager.Symbol("x")
110
+ f2 = env2.formula_manager.create_node(node_type=XOR, args=(x2, x2))
111
+ with self.assertRaises(UnsupportedOperatorError):
112
+ env2.serializer.serialize(f2)
113
+
114
+ # env2 can register its own, independent handler for the same
115
+ # (nodetype, walker) pair, and env1 stays unaffected.
116
+ env2.add_dynamic_walker_function(XOR, HRPrinter, make_printer(" XOR "))
117
+ self.assertEqual(env2.serializer.serialize(f2), "(x XOR x)")
118
+ self.assertEqual(env1.serializer.serialize(f1), "(x *+* x)")
119
+
120
+ # Redefining the same (nodetype, walker) within one env is caught.
121
+ with self.assertRaises(AssertionError):
122
+ env1.add_dynamic_walker_function(XOR, HRPrinter, make_printer("!"))
@@ -21,7 +21,8 @@ from pysmt.shortcuts import And, Or, Iff, Not, Function, Real
21
21
  from pysmt.shortcuts import LT, GT, Plus, Minus, Equals
22
22
  from pysmt.shortcuts import get_env, substitute, TRUE
23
23
  from pysmt.typing import INT, BOOL, REAL, FunctionType
24
- from pysmt.walkers import TreeWalker, DagWalker, IdentityDagWalker
24
+ from pysmt.walkers import TreeWalker, DagWalker, IdentityDagWalker, handles
25
+ from pysmt.walkers.generic import nt_to_fun
25
26
  from pysmt.test import TestCase, main
26
27
  from pysmt.formula import FormulaManager
27
28
  from pysmt.test.examples import get_example_formulae
@@ -105,36 +106,36 @@ class TestWalkers(TestCase):
105
106
  tree_walker.walk(varA)
106
107
 
107
108
  def test_walker_new_operators_complete(self):
108
- walkerA = IdentityDagWalker(env=self.env)
109
109
  idx = op.new_node_type(node_str="fancy_new_node")
110
- walkerB = IdentityDagWalker(env=self.env)
111
- with self.assertRaises(KeyError):
112
- walkerA.functions[idx]
113
- self.assertEqual(walkerB.functions[idx], walkerB.walk_error)
110
+ fun_name = nt_to_fun(idx)
114
111
 
115
- # Use a mixin to handle the node type
112
+ # A node type introduced after the class was defined has no
113
+ # dedicated walk_* method: dispatch falls back to walk_error.
114
+ self.assertFalse(hasattr(IdentityDagWalker, fun_name))
115
+
116
+ # Use a mixin to handle the node type (the method name matches
117
+ # nt_to_fun, so it is picked up by class-based dispatch).
116
118
  class FancyNewNodeWalkerMixin(object):
117
- def walk_fancy_new_node(self, args, **kwargs):
119
+ def walk_fancy_new_node(self, formula, args, **kwargs):
118
120
  raise UnsupportedOperatorError
119
121
 
120
122
  class IdentityDagWalker2(IdentityDagWalker, FancyNewNodeWalkerMixin):
121
123
  pass
122
- walkerC = IdentityDagWalker2(env=self.env)
123
- self.assertEqual(walkerC.functions[idx],
124
- walkerC.walk_fancy_new_node)
124
+ self.assertEqual(getattr(IdentityDagWalker2, fun_name),
125
+ FancyNewNodeWalkerMixin.walk_fancy_new_node)
125
126
 
126
127
  def test_identity_walker_simple(self):
127
128
 
128
- def walk_and_to_or(formula, args, **kwargs):
129
- return Or(args)
130
-
131
- def walk_or_to_and(formula, args, **kwargs):
132
- return And(args)
129
+ class MyWalker(IdentityDagWalker):
130
+ @handles(op.AND)
131
+ def walk_and_to_or(self, formula, args, **kwargs):
132
+ return Or(args)
133
133
 
134
- walker = IdentityDagWalker(env=get_env())
134
+ @handles(op.OR)
135
+ def walk_or_to_and(self, formula, args, **kwargs):
136
+ return And(args)
135
137
 
136
- walker.set_function(walk_and_to_or, op.AND)
137
- walker.set_function(walk_or_to_and, op.OR)
138
+ walker = MyWalker(env=get_env())
138
139
 
139
140
  x, y, z = Symbol('x'), Symbol('y'), Symbol('z')
140
141
 
@@ -240,8 +241,9 @@ class TestWalkers(TestCase):
240
241
  x = Symbol("x")
241
242
  w = DagWalker()
242
243
  for o in op.ALL_TYPES:
244
+ f = getattr(w, nt_to_fun(o))
243
245
  with self.assertRaises(UnsupportedOperatorError):
244
- w.functions[o](x)
246
+ f(x)
245
247
 
246
248
  def test_walker_super(self):
247
249
  from pysmt.walkers import DagWalker
@@ -68,14 +68,10 @@ class DagWalker(Walker):
68
68
  """
69
69
  key = self._get_key(formula, **kwargs)
70
70
  if key not in self.memoization:
71
- try:
72
- f = self.functions[formula.node_type()]
73
- except KeyError:
74
- f = self.walk_error
75
-
76
71
  args = [self.memoization[self._get_key(s, **kwargs)] \
77
72
  for s in self._get_children(formula)]
78
- self.memoization[key] = f(formula, args=args, **kwargs)
73
+ self.memoization[key] = self.__class__.super(self, formula,
74
+ args=args, **kwargs)
79
75
  else:
80
76
  pass
81
77
 
@@ -15,8 +15,6 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
  #
18
- from functools import partial
19
-
20
18
  import sys
21
19
  from pysmt.fnode import FNode
22
20
  from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union, cast, Iterable
@@ -83,24 +81,15 @@ class Walker(object, metaclass=MetaNodeTypeHandler):
83
81
  env = pysmt.environment.get_env()
84
82
  self.env: "pysmt.environment.Environment" = env
85
83
 
86
- self.functions = {}
87
- for o in op.all_types():
88
- try:
89
- # getattr will raise an AttributeError exception if a
90
- # method does not exist
91
- self.functions[o] = getattr(self, nt_to_fun(o))
92
- except AttributeError:
93
- self.functions[o] = self.walk_error
94
-
95
84
  def set_function(self, function, *node_types):
96
- """Overrides the default walking function for each of the specified
97
- node_types with the given function
85
+ """Instance-based walkers (<=0.6.0) are no longer supported.
86
+
87
+ Use class-based walkers instead: define walk_* methods (or use
88
+ the ``@handles`` decorator) on a subclass.
98
89
  """
99
- from warnings import warn
100
- warn("Instance-based walkers (<=0.6.0) walkers are deprecated. "
101
- "You should use new-style/class based walkers", stacklevel=2)
102
- for nt in node_types:
103
- self.functions[nt] = function
90
+ raise NotImplementedError(
91
+ "Instance-based walkers (<=0.6.0) are deprecated. "
92
+ "You should use new-style/class based walkers.")
104
93
 
105
94
  @classmethod
106
95
  def set_handler(cls, function: Callable, *node_types):
@@ -109,28 +98,32 @@ class Walker(object, metaclass=MetaNodeTypeHandler):
109
98
  setattr(cls, nt_to_fun(nt), function)
110
99
 
111
100
  @classmethod
112
- def super(cls, self, formula: FNode, *args, **kwargs) -> FNode:
113
- """Call the correct walk_* function of cls for the given formula."""
114
- f = getattr(cls, nt_to_fun(formula.node_type()))
101
+ def super(cls, self, formula: FNode, *args, **kwargs) -> Any:
102
+ """Call the correct walk_* function of cls for the given formula.
103
+
104
+ The return type depends on the walker: an FNode for rewriting
105
+ walkers, but a generator (TreeWalker), a set or an int (oracles),
106
+ etc. for others; hence Any.
107
+ """
108
+ nt = formula.node_type()
109
+ try:
110
+ f = getattr(cls, nt_to_fun(nt))
111
+ except AttributeError:
112
+ # Custom node types (see new_node_type) have no walk_* method
113
+ # on the class. Look for a handler registered on this walker's
114
+ # environment via add_dynamic_walker_function; keeping the
115
+ # lookup env-local is what stops registrations from leaking
116
+ # across environments.
117
+ fun = self.env.get_dynamic_walker_function(nt, cls)
118
+ if fun is None:
119
+ raise pysmt.exceptions.UnsupportedOperatorError(
120
+ node_type=nt, expression=formula)
121
+ return fun(self, formula, *args, **kwargs)
115
122
  return f(self, formula, *args, **kwargs)
116
123
 
117
124
  @handles(op.ALL_TYPES)
118
125
  def walk_error(self, formula, **kwargs):
119
- """Default function for a node that is not handled by the Walker.
120
-
121
- This tries to handle the node using the Dynamic Walker
122
- Function information from the environment. If this fails, then
123
- an UnsupportedOperatorError exception is given.
124
-
125
- """
126
- node_type = formula.node_type()
127
- if node_type in self.env.dwf:
128
- dwf = self.env.dwf[node_type]
129
- walker_class = type(self)
130
- if type(self) in dwf:
131
- self.functions[node_type] = partial(dwf[walker_class], self)
132
- return self.functions[node_type](formula, **kwargs)
133
-
126
+ """Default function for a node that is not handled by the Walker."""
134
127
  node_type = formula.node_type()
135
128
  raise pysmt.exceptions.UnsupportedOperatorError(node_type=node_type,
136
129
  expression=formula)
@@ -41,19 +41,14 @@ class TreeWalker(Walker):
41
41
  return
42
42
 
43
43
  def walk(self, formula: FNode, threshold: Optional[int]=None):
44
- """Generic walk method, will apply the function defined by the map
45
- self.functions.
44
+ """Generic walk method, will apply the function associated with
45
+ the node.
46
46
 
47
47
  If threshold parameter is specified, the walk_threshold
48
48
  function will be called for all nodes with depth >= threshold.
49
49
  """
50
50
 
51
- try:
52
- f = self.functions[formula.node_type()]
53
- except KeyError:
54
- f = self.walk_error
55
-
56
- iterator = f(formula)
51
+ iterator = self.__class__.super(self, formula)
57
52
  if iterator is None:
58
53
  return
59
54
 
@@ -67,11 +62,7 @@ class TreeWalker(Walker):
67
62
  if iterator is not None:
68
63
  stack.append(iterator)
69
64
  else:
70
- try:
71
- cf = self.functions[child.node_type()]
72
- except KeyError:
73
- cf = self.walk_error
74
- iterator = cf(child)
65
+ iterator = self.__class__.super(self, child)
75
66
  if iterator is not None:
76
67
  stack.append(iterator)
77
68
  except StopIteration:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes