PySMT 0.9.7.dev112__py2.py3-none-any.whl → 0.9.7.dev129__py2.py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PySMT
3
- Version: 0.9.7.dev112
3
+ Version: 0.9.7.dev129
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,4 +1,4 @@
1
- pysmt/__init__.py,sha256=TKZ-kovL6HGfhI1GXWf0irhLNCok5tC7mk91ClJgyas,1598
1
+ pysmt/__init__.py,sha256=VlooMhA5oranwltuSSmGVfWSC_cU2b57cM2N4SkTAv4,1598
2
2
  pysmt/__main__.py,sha256=rR-MV1QtLYqtVoJyY3m5B5Iz-lua0-5o6YSB0W4lKy8,1085
3
3
  pysmt/configuration.py,sha256=q4Ncd6f2d0VZUpyQAOR8sTPlTodgDnYhUBeRgYYXqTE,4539
4
4
  pysmt/constants.py,sha256=QelM9r5fGWSq8UNjjYoEJK2FaLHRr4Z9NZxzjeajEWA,5249
@@ -7,14 +7,14 @@ pysmt/environment.py,sha256=rdaxQ0uwmMPmcW4d5WnTYAyHNSCpRTgzRLaXQccG5-4,6522
7
7
  pysmt/exceptions.py,sha256=uG3FochPO1Y18cv1lXUjQtNbW-qZKd68zqs8oo2OEF4,4420
8
8
  pysmt/factory.py,sha256=6QFbob7LV3x8uT4w2nG_rHqXWCqbwNg5oCUMPhpnwmY,24107
9
9
  pysmt/fnode.py,sha256=zKZP4yda8JxK6AXW3vCasRLYsLH5NzK_2Bjiy5ogtqo,33256
10
- pysmt/formula.py,sha256=baexe5-GgrG7z_qH3Wb9s8XQqFcBgyLXnv8Rik5t2YY,43318
10
+ pysmt/formula.py,sha256=gmK3b9481aI6rvHJTPZVOsw-YsIBFpeqKZ1-gdWHE2k,43371
11
11
  pysmt/logics.py,sha256=yJ1Yv24dVj4LlpnbspgcRT1t5e65RmvGas_bdHOGCAA,28774
12
12
  pysmt/operators.py,sha256=RU4H9E5eVjPgAar_9hIoCexq-Yc5v0xdHAMM69FcYX8,8132
13
13
  pysmt/oracles.py,sha256=lfRbPoiX4SXuJZktwmKUqA1FJ-7lRyP49LRIH8C7VoQ,19461
14
- pysmt/parsing.py,sha256=a3RY-ogJUSCx1BwePHL51AoD4jGjap1_6ML7S18hzuc,20786
14
+ pysmt/parsing.py,sha256=cT2cEgm31_3au4xD-F3_QvXtvq5aVHaEBbLWB17OKZY,20729
15
15
  pysmt/printers.py,sha256=ZtV0j7jVcOGJxzKELtKJIJh1T6m_4xv1dc_3lwinHbs,13389
16
16
  pysmt/rewritings.py,sha256=00gTDbyF6sGoAKcVwRsQMKEXIt6iIrJnmrS5FRvfMCA,33290
17
- pysmt/shortcuts.py,sha256=dDIbmnda_MGQVF32seU1fJ5TC-LuMk5VDrHAgxBQzu0,38486
17
+ pysmt/shortcuts.py,sha256=p-xDS69rMr_uDoBoVzXYJuXdyBWbMxb3JAeLjfcvY1U,39378
18
18
  pysmt/simplifier.py,sha256=igDczAkE5f3ctDxN_Hh2iP54ZFj_ezKRucPtgrodGzo,41464
19
19
  pysmt/substituter.py,sha256=rzdZos9zYNzq3DSKFkLR2Gu6ktwBCjdPEPM48tIzUwk,13811
20
20
  pysmt/type_checker.py,sha256=g5Mbh42ZxsjtLHnS0qizYLZ3kH3bMtNkIuyiZtTuinE,13273
@@ -27,7 +27,7 @@ pysmt/cmd/shell.py,sha256=ww1juthvLnJQciVHWxYvTJaA5W3-Np0ORfESyePF0bI,4333
27
27
  pysmt/cmd/installers/__init__.py,sha256=nHJaEXfCpsEkzBy0NL91P9extUda6jb0u88nwPYTvGo,1170
28
28
  pysmt/cmd/installers/base.py,sha256=1usHiBHrIBam9BlbVKG-6F52KPsIkJBeghkd_ckh-8U,12811
29
29
  pysmt/cmd/installers/bdd.py,sha256=Qq8YlYAVvxUqNXjoOlH9_Lhj4cj6WEt7HuhbSiF_L6k,2539
30
- pysmt/cmd/installers/btor.py,sha256=0fsCJEKqQ_Y4HURYNct-F3ui8Zsk5qd4Gp0AWRXAUBo,4067
30
+ pysmt/cmd/installers/btor.py,sha256=gUl_urKcWtbSYS_Vde_O7RJM0H-kRqh6hceTju-Sbcs,4995
31
31
  pysmt/cmd/installers/cvcfive.py,sha256=PRSuEd2_y2qQO0G3gUGtCsKB2PMV40C1WwjpgbJkefE,1493
32
32
  pysmt/cmd/installers/cvcfour.py,sha256=uBZkKIX4gZEMfjrhrparUSDydMcvGIGZM2Y8JYD0GzE,3916
33
33
  pysmt/cmd/installers/msat.py,sha256=hNz7TbqYrEg9I0vvkSaBiKdy4v8RxH8oXGhXQhgNIVU,5409
@@ -42,10 +42,10 @@ pysmt/smtlib/script.py,sha256=4tATsRYDavjz1DVKXzfVVZxVXYOtBRhh4Ya0Ng4XxHY,13387
42
42
  pysmt/smtlib/solver.py,sha256=dWBzYBuYDVyCsQI1KlqndxpqX4xHQUDcHAuefwbHv24,7987
43
43
  pysmt/smtlib/utils.py,sha256=XNp7mW1DB6cZRtQhkAOTR-xrwYaGDBEcF3Q-edKDeU8,2043
44
44
  pysmt/smtlib/parser/__init__.py,sha256=Tgl8AAjZPmCrABGmKRSC4Yu634mn8r22qn18M3u-pfk,4771
45
- pysmt/smtlib/parser/parser.py,sha256=3eMEhW6t2XHSK_1EkGmjB4ZWrg6kWgfwVDVcyOxyWS0,58387
45
+ pysmt/smtlib/parser/parser.py,sha256=vublFYMDAucq85WVaoq882WJ6kgcrRwUWh31bdH2u6M,58453
46
46
  pysmt/solvers/__init__.py,sha256=JXBHtcb4Lv-Sb8whc9JuGbRH2EBLWwtLUh3PL9HhNE8,650
47
47
  pysmt/solvers/bdd.py,sha256=my3398_-8Rkqy1pluzZa7_12qsA43ARbs8-YAPqdMWs,15938
48
- pysmt/solvers/btor.py,sha256=DFBnYsa4oG8GC58UWvKf6FHwVK9AmnOQ8ytrEaYlZbI,25295
48
+ pysmt/solvers/btor.py,sha256=2oT1PfXSGTSTPaXQUwVy0M799slSH2FJ-3QNb3YQmGw,25953
49
49
  pysmt/solvers/cvcfive.py,sha256=z8o4VxrZBC6sdb_JYTWfRS3BXdWJPznakN3k7rD4EY8,21073
50
50
  pysmt/solvers/cvcfour.py,sha256=odWm_MAgoPlhOf6gaarZQAqQS4fN-8PH-xGIYaiErQE,24538
51
51
  pysmt/solvers/eager.py,sha256=Py2_XaFj7YIOotH3Zv14JhmyLiZPTxKwzLuLztFqNIs,3297
@@ -74,8 +74,8 @@ pysmt/test/test_dwf.py,sha256=nQubO2IYjW3NnRjNz3xkhpXgK_5coZp9uZ_U-ElmFRw,2850
74
74
  pysmt/test/test_eager_model.py,sha256=hF9V8wQYXVeyW2Bo4sACa98xeJtfOMYjMvjWMHQaGag,3662
75
75
  pysmt/test/test_env.py,sha256=tshVfiKotjMUNXl0RCo7-itTnVJimWGPyMkuGHX_B6I,4118
76
76
  pysmt/test/test_euf.py,sha256=B0VRx1NwfKZZIG5Fc6gYPj7G6gNWMzYJvgbh-2q2E28,3455
77
- pysmt/test/test_formula.py,sha256=k-Gy5-8lHQ-1tGRI_ta8bJ-DjdYLQxYZJ-zPhH_anO8,38595
78
- pysmt/test/test_hr_parsing.py,sha256=xp6FLs_6UMAJEcIfEIytB3KCa1pE8-rGoU8v1N-n3X4,2754
77
+ pysmt/test/test_formula.py,sha256=8KEBOfXVPa-oiX7j95ZFs-PWNqUt78TCR8UCyNwZMYw,40039
78
+ pysmt/test/test_hr_parsing.py,sha256=bi-iTu7y1C7diMcWsQ7EI40MipDbzTKbMGPnLWX85A8,3118
79
79
  pysmt/test/test_imports.py,sha256=micwbKICxYXjEcKgc3eBEsnTKFRiLSBaso2l2cX0GDw,1561
80
80
  pysmt/test/test_int.py,sha256=dk72Q6viqRUs9XiPB40n6RrwiqsV6GbbKuSlYaQMU9k,1980
81
81
  pysmt/test/test_interpolation.py,sha256=WTodZtnxH5slIvUWbHbjjnI2o0naXgZwZawTGhh3E0o,3941
@@ -89,7 +89,7 @@ pysmt/test/test_oracles.py,sha256=cHBPTUoi9cPmIvR-DG4bbzohOaBdUJzpKLoQXImxS_c,56
89
89
  pysmt/test/test_portfolio.py,sha256=k0Jdrdr-EX-BVCxqYNUS3YjC77aCpzzdhezjB8U3OCM,7125
90
90
  pysmt/test/test_printing.py,sha256=glsnaMRungLc31JIJTmHlT69JnTPsC5pnYn1rZriV2s,8765
91
91
  pysmt/test/test_qe.py,sha256=k8zYX-lcij0ua9yuRXl7wErUklEgLSEh68QDpV8J9xs,7157
92
- pysmt/test/test_regressions.py,sha256=OHBptJUWQnUkXT17VH4z9Qea0QQeUF2v4sw_RYyottE,20119
92
+ pysmt/test/test_regressions.py,sha256=RnZmdszTOIbDnMZ7wjVnMwdboJCcObtQeM0YumLd3ng,20400
93
93
  pysmt/test/test_rewritings.py,sha256=1eeseDwZyQD2VrOFBABXHTYJFJOXszP4olbCNeLcwfA,15607
94
94
  pysmt/test/test_shannon_expansion.py,sha256=yaiZuB24wj1Zi-KdzRTmWuzAVaF9bQ603uto7zi6XBs,3082
95
95
  pysmt/test/test_simplify.py,sha256=ckQn_DUxVvGspaRNZmSPHkudhpUlG5K2w6C0wDqhL1w,7620
@@ -97,7 +97,7 @@ pysmt/test/test_size.py,sha256=p3aqCMHfBiGLxvF0P8hE-PRQTT8VMPIJCjblq8Txh1w,3261
97
97
  pysmt/test/test_solving.py,sha256=8x9dNHbICFzHmCLZDR_Nnm3ScRal6seGoRRA89uOB4w,24906
98
98
  pysmt/test/test_sorts.py,sha256=erfInyPH91WVB8JBUYLteTo5X5skKKP3vEXdUUKC-YE,6033
99
99
  pysmt/test/test_string.py,sha256=Y6VBfkLNKuePo8-HIzcwBH3eaYj0i-k1Y8tpFyw03zw,8096
100
- pysmt/test/test_typechecker.py,sha256=obrRf5LSkrZjw2Kn7B4WNWVUykE7c9tU3jW-dEteHBs,6977
100
+ pysmt/test/test_typechecker.py,sha256=S2O8HjN_bLN6sz86TnsWqpRtxHk2VcVsGDoRZCcQnzE,7309
101
101
  pysmt/test/test_unsat_cores.py,sha256=J-ip4SInZ9l96NCsLsKmvIiSI04hKpdyrPeKRh6b6aM,6563
102
102
  pysmt/test/test_walker_ext.py,sha256=4x6Ew522P_0fLpKRIL0_0igB4I3_VrWWA4juuqolhag,3522
103
103
  pysmt/test/test_walkers.py,sha256=AKVMvEUtMBht08bE1vCMaeMtdgGa6j_weDSHz_9Br3Q,9481
@@ -122,16 +122,16 @@ pysmt/test/smtlib/test_parser_qf_nra.py,sha256=a6VWFQtv_v2bqLe598NTdcK1v9cM9Q3lo
122
122
  pysmt/test/smtlib/test_parser_qf_uf.py,sha256=iKWadVfvZEKkjuP0lXo3BoEk3ISoDYyi_x4MhTt6Q_Q,978
123
123
  pysmt/test/smtlib/test_parser_qf_ufbv.py,sha256=G3Nnt4awK1A6nwDvKRv4zoFwtGHawvlf4KSVYJRltGA,984
124
124
  pysmt/test/smtlib/test_parser_type_error.py,sha256=cnil1KNDYkxc52pnqOC1ch8joGbaWWqepQmYABtTHLM,1129
125
- pysmt/test/smtlib/test_smtlibscript.py,sha256=x-ukB65HeccNZ9I3GUxvOf8MHCyfzc8qKBXgtQwOgmg,11013
125
+ pysmt/test/smtlib/test_smtlibscript.py,sha256=pGNEPwCinr0oIAYbp0kx4dkczi5Z5frHKTzOdlwf350,11930
126
126
  pysmt/walkers/__init__.py,sha256=D6iHibVpqaZFzcpgYnNf3NVMxPyouAeeonTDSwCToRg,1585
127
127
  pysmt/walkers/dag.py,sha256=pUdVTZx7CQyjrAb6jMfmsqS07J4kiDqHU8R4_9UvwkQ,5352
128
128
  pysmt/walkers/generic.py,sha256=q1j1T2RvCeJn1PM0H5d8vNV4FTYAEQgT7h8X5DJhDf8,4534
129
129
  pysmt/walkers/identitydag.py,sha256=f_D5qA198ayd3QO4u59fBX1RS_UiSBnPeV9O3ULvQv0,8737
130
130
  pysmt/walkers/tree.py,sha256=WIWN9IM0riWkaD40iP4Tt3BCN21iSdE1S7gRZqy56SU,2846
131
- PySMT-0.9.7.dev112.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
132
- PySMT-0.9.7.dev112.dist-info/METADATA,sha256=jyBArgrTBLc7CC6a2QaWphz8zjnXBWJdPLC5jIdbv4o,1617
133
- PySMT-0.9.7.dev112.dist-info/NOTICE,sha256=Ns-Jsa6nbqZUiTEEAM6HqioSZIxQ2RCJzxoBlWQaUfc,601
134
- PySMT-0.9.7.dev112.dist-info/WHEEL,sha256=Kh9pAotZVRFj97E15yTA4iADqXdQfIVTHcNaZTjxeGM,110
135
- PySMT-0.9.7.dev112.dist-info/entry_points.txt,sha256=si0hIk-v3V35G3p8QGINoQ4QW-v4RYDRqj-asgyCgeM,58
136
- PySMT-0.9.7.dev112.dist-info/top_level.txt,sha256=NwHQbpTaZMEvjIUdC0bvvj-WUyULe-nt-opK3YQNRMk,6
137
- PySMT-0.9.7.dev112.dist-info/RECORD,,
131
+ PySMT-0.9.7.dev129.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
132
+ PySMT-0.9.7.dev129.dist-info/METADATA,sha256=R2RMcBG8AfOdQ3QlgdfMrTtjMbGv4t3lY-SMtBns3X4,1617
133
+ PySMT-0.9.7.dev129.dist-info/NOTICE,sha256=Ns-Jsa6nbqZUiTEEAM6HqioSZIxQ2RCJzxoBlWQaUfc,601
134
+ PySMT-0.9.7.dev129.dist-info/WHEEL,sha256=Kh9pAotZVRFj97E15yTA4iADqXdQfIVTHcNaZTjxeGM,110
135
+ PySMT-0.9.7.dev129.dist-info/entry_points.txt,sha256=si0hIk-v3V35G3p8QGINoQ4QW-v4RYDRqj-asgyCgeM,58
136
+ PySMT-0.9.7.dev129.dist-info/top_level.txt,sha256=NwHQbpTaZMEvjIUdC0bvvj-WUyULe-nt-opK3YQNRMk,6
137
+ PySMT-0.9.7.dev129.dist-info/RECORD,,
pysmt/__init__.py CHANGED
@@ -16,7 +16,7 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- VERSION = (0, 9, 7, "dev", 112)
19
+ VERSION = (0, 9, 7, "dev", 129)
20
20
 
21
21
  # Try to provide human-readable version of latest commit for dev versions
22
22
  # E.g. v0.5.1-4-g49a49f2-wip
@@ -12,9 +12,24 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  import os
15
+ from tempfile import NamedTemporaryFile
15
16
 
16
17
  from pysmt.cmd.installers.base import SolverInstaller
17
18
 
19
+ CYTHON_PATCH = '''\
20
+ --- pyboolector.pyx 2025-05-12 14:01:27.528128358 +0200
21
+ +++ pyboolector.pyx.patched 2025-05-12 14:07:26.685645023 +0200
22
+ @@ -1274,7 +1274,7 @@
23
+ Parameter ``width`` is only required if ``c`` is an integer.
24
+ """
25
+ cdef BoolectorConstNode r
26
+ - if isinstance(c, int) or (sys.version < '3' and isinstance(c, long)):
27
+ + if isinstance(c, int):
28
+ if c != 0 and c.bit_length() > width:
29
+ raise BoolectorException(
30
+ "Value of constant {} (bit width {}) exceeds bit "\\
31
+ '''
32
+
18
33
 
19
34
  class BtorInstaller(SolverInstaller):
20
35
 
@@ -59,6 +74,14 @@ class BtorInstaller(SolverInstaller):
59
74
  SolverInstaller.untar(os.path.join(self.base_dir, self.archive_name),
60
75
  self.extract_path)
61
76
 
77
+ # Patching for cython 3.8
78
+ with NamedTemporaryFile() as f:
79
+ f.write(CYTHON_PATCH.encode())
80
+ f.flush()
81
+ f.seek(0)
82
+ SolverInstaller.run("patch src/api/python/pyboolector.pyx -i %s" % f.name,
83
+ directory=self.extract_path)
84
+
62
85
  # Build lingeling
63
86
  SolverInstaller.run("bash ./contrib/setup-lingeling.sh",
64
87
  directory=self.extract_path)
pysmt/formula.py CHANGED
@@ -89,7 +89,9 @@ class FormulaManager(object):
89
89
  def create_node(self, node_type, args, payload=None):
90
90
  content = FNodeContent(node_type, args, payload)
91
91
  if content in self.formulae:
92
- return self.formulae[content]
92
+ n = self.formulae[content]
93
+ self._do_type_check(n)
94
+ return n
93
95
  else:
94
96
  n = FNode(content, self._next_free_id)
95
97
  self._next_free_id += 1
pysmt/parsing.py CHANGED
@@ -126,9 +126,6 @@ class HRLexer(Lexer):
126
126
  Rule(r"\"(.*?)\"", self.string_constant, True), # String Constant
127
127
  Rule(r"BV\{(\d+)\}", self.bv_type, True),# BV Type
128
128
  Rule(r"(Array\{)", OpenArrayTypeTok(), False),# Array Type
129
- Rule(r"(Int)", IntTypeTok(), False),# Int Type
130
- Rule(r"(Real)", RealTypeTok(), False),# Real Type
131
- Rule(r"(Bool)", BoolTypeTok(), False),# Bool Type
132
129
  Rule(r"(&)", InfixOpAdapter(self.AndOrBVAnd, 40), False),# conjunction
133
130
  Rule(r"(\|)", InfixOpAdapter(self.OrOrBVOr, 30), False),# disjunction
134
131
  Rule(r"(!)", UnaryOpAdapter(self.NotOrBVNot, 50), False),# negation
@@ -168,19 +165,10 @@ class HRLexer(Lexer):
168
165
  Rule(r"(:=)", ArrStore(), False),# ArrStore
169
166
  Rule(r"(::)", InfixOpAdapter(self.mgr.BVConcat, 90), False),# BVXor
170
167
  Rule(r"(:)", ExprElse(), False),# colon
171
- Rule(r"(False)", Constant(self.mgr.FALSE()), False), # False
172
- Rule(r"(True)", Constant(self.mgr.TRUE()), False),# True
173
168
  Rule(r"(,)", ExprComma(), False),# comma
174
169
  Rule(r"(\.)", ExprDot(), False),# dot
175
- Rule(r"(xor)", InfixOpAdapter(self.mgr.BVXor, 10), False),# BVXor
176
- Rule(r"(ROR)", InfixOpAdapter(self.BVHack(self.mgr.BVRor), 90), False),# BVRor
177
- Rule(r"(ROL)", InfixOpAdapter(self.BVHack(self.mgr.BVRol), 90), False),# BVRol
178
- Rule(r"(ZEXT)", InfixOpAdapter(self.BVHack(self.mgr.BVZExt), 90), False),# BVZext
179
- Rule(r"(SEXT)", InfixOpAdapter(self.BVHack(self.mgr.BVSExt), 90), False),# BVSext
180
- Rule(r"(bvcomp)", InfixOpAdapter(self.mgr.BVComp, 90), False),#
181
- Rule(r"(forall)", Quantifier(self.mgr.ForAll, 20), False),#
182
- Rule(r"(exists)", Quantifier(self.mgr.Exists, 20), False),#
183
- Rule(r"(ToReal)", UnaryOpAdapter(self.mgr.ToReal, 100), False),#
170
+ Rule(r"(forall\s+)", Quantifier(self.mgr.ForAll, 20), False),#
171
+ Rule(r"(exists\s+)", Quantifier(self.mgr.Exists, 20), False),#
184
172
  Rule(r"(str\.len)", FunctionCallAdapter(self.mgr.StrLength, 100), False), # str_length
185
173
  Rule(r"(str\.\+\+)", FunctionCallAdapter(self.mgr.StrConcat, 100), False), # str_concat
186
174
  Rule(r"(str\.at)", FunctionCallAdapter(self.mgr.StrCharAt, 100), False), # str_charat
@@ -192,14 +180,28 @@ class HRLexer(Lexer):
192
180
  Rule(r"(str\.suffixof)", FunctionCallAdapter(self.mgr.StrSuffixOf, 100), False), # str_suffixof
193
181
  Rule(r"(str\.to\.int)", FunctionCallAdapter(self.mgr.StrToInt, 100), False), # str_to_int
194
182
  Rule(r"(int\.to\.str)", FunctionCallAdapter(self.mgr.IntToStr, 100), False), # int_to_str
195
- Rule(r"(bv2nat)", UnaryOpAdapter(self.mgr.BVToNatural, 100), False),#
196
183
  Rule(r"'(.*?)'", self.identifier, True), # quoted identifiers
197
184
  Rule(r"([A-Za-z_][A-Za-z0-9_]*)", self.identifier, True),# identifiers
198
185
  Rule(r"(.)", self.lexing_error, True), # input error
199
186
  ]
200
-
201
187
  self.rules += hr_rules
202
188
 
189
+ self._identifier_map = {
190
+ "False": Constant(self.mgr.FALSE()), # False
191
+ "True": Constant(self.mgr.TRUE()),# True
192
+ "xor": InfixOpAdapter(self.mgr.BVXor, 10),# BVXor
193
+ "bv2nat": UnaryOpAdapter(self.mgr.BVToNatural, 100),#
194
+ "bvcomp": InfixOpAdapter(self.mgr.BVComp, 90),#
195
+ "ROR": InfixOpAdapter(self.BVHack(self.mgr.BVRor), 90),# BVRor
196
+ "ROL": InfixOpAdapter(self.BVHack(self.mgr.BVRol), 90),# BVRol
197
+ "ZEXT": InfixOpAdapter(self.BVHack(self.mgr.BVZExt), 90),# BVZext
198
+ "SEXT": InfixOpAdapter(self.BVHack(self.mgr.BVSExt), 90),# BVSext
199
+ "ToReal": UnaryOpAdapter(self.mgr.ToReal, 100),#
200
+ "Int": IntTypeTok(),# Int Type
201
+ "Real": RealTypeTok(),# Real Type
202
+ "Bool": BoolTypeTok(),# Bool Type
203
+ }
204
+
203
205
  self.compile()
204
206
 
205
207
  def bv_type(self, read):
@@ -219,6 +221,9 @@ class HRLexer(Lexer):
219
221
  return Constant(self.mgr.String(read))
220
222
 
221
223
  def identifier(self, read):
224
+ res = self._identifier_map.get(read, None)
225
+ if res is not None:
226
+ return res
222
227
  return Identifier(read, env=self.env)
223
228
 
224
229
  def UMinusOrBvNeg(self, x):
pysmt/shortcuts.py CHANGED
@@ -233,6 +233,31 @@ def Ite(iff, left, right):
233
233
  return get_env().formula_manager.Ite(iff, left, right)
234
234
 
235
235
 
236
+ def Abs(formula):
237
+ r"""Returns the absolute value of the formula.
238
+
239
+ This is implemented as If(formula > 0, formula, -formula).
240
+ Works for both integer and real values.
241
+
242
+ :param formula: The formula to compute the absolute value of
243
+ :returns: The absolute value of the formula
244
+ :raises: ValueError if the formula type is not integer or real
245
+ """
246
+ # Get the type of the formula to determine the appropriate zero value
247
+ formula_type = get_type(formula)
248
+
249
+ # Create a zero value of the same type as the formula
250
+ if formula_type == types.INT:
251
+ zero = Int(0)
252
+ elif formula_type == types.REAL:
253
+ zero = Real(0)
254
+ else:
255
+ # Raise an error for unsupported types
256
+ raise ValueError(f"Abs function only supports integer and real types, got {formula_type}")
257
+
258
+ return Ite(GT(formula, zero), formula, Minus(zero, formula))
259
+
260
+
236
261
  def Symbol(name, typename=types.BOOL):
237
262
  """Returns a symbol with the given name and type.
238
263
 
@@ -344,13 +344,15 @@ class SmtLibParser(object):
344
344
  get_type = self.env.stc.get_type
345
345
  get_free_variables = self.env.fvo.get_free_variables
346
346
  new_args = []
347
+ changed = False
347
348
  for x in args:
348
349
  if get_type(x).is_int_type() and\
349
350
  len(get_free_variables(x)) == 0:
350
351
  new_args.append(mgr.ToReal(x))
352
+ changed = True
351
353
  else:
352
354
  new_args.append(x)
353
- if args == new_args:
355
+ if not changed:
354
356
  raise
355
357
  return op(*new_args)
356
358
 
pysmt/solvers/btor.py CHANGED
@@ -15,12 +15,29 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
  #
18
+ from enum import Enum
19
+ import inspect
18
20
  from math import log, ceil
19
21
 
20
22
  from pysmt.exceptions import SolverAPINotFound
21
23
 
22
24
  try:
23
25
  import pyboolector
26
+
27
+ # Fixing interface for cython 3.1+
28
+ #
29
+ # Cython 3.1 changed the way enums are handled: the enum values are no
30
+ # longer added to the global namespace, while the documentation of btor
31
+ # relied on the old behavior of cython, Here, we first collect all the nums
32
+ # in the module and then we add their enumerands to the pyboolector module,
33
+ # making it work on either cython 3.0 or 3.1.
34
+ enums = []
35
+ for x in pyboolector.__dict__.values():
36
+ if inspect.isclass(x) and issubclass(x, Enum):
37
+ enums.append(x)
38
+ for x in enums:
39
+ pyboolector.__dict__.update(x.__members__)
40
+
24
41
  except ImportError:
25
42
  raise SolverAPINotFound
26
43
 
@@ -27,7 +27,7 @@ from pysmt.smtlib.script import smtlibscript_from_formula, evaluate_command
27
27
  from pysmt.smtlib.parser import get_formula_strict, get_formula, SmtLibParser
28
28
  from pysmt.solvers.smtlib import SmtLibIgnoreMixin
29
29
  from pysmt.logics import QF_UFLIRA
30
- from pysmt.exceptions import UndefinedLogicError, PysmtValueError
30
+ from pysmt.exceptions import UndefinedLogicError, PysmtValueError, PysmtTypeError
31
31
 
32
32
 
33
33
 
@@ -175,6 +175,29 @@ class TestSmtLibScript(TestCase):
175
175
  # No exceptions are thrown
176
176
  self.assertEqual(smtlib_script.replace('var', '__var0'), script.commands[0].serialize_to_string())
177
177
 
178
+ def test_twice_fix_real(self):
179
+ smtlib_script = "\n".join([
180
+ '(declare-fun r () Real)',
181
+ '(assert (< (* 1 r) 0))',
182
+ '(assert (< 2 (* 1 r)))'
183
+ ])
184
+ stream = StringIO(smtlib_script)
185
+ parser = SmtLibParser()
186
+ _ = parser.get_script(stream)
187
+ # No exceptions are thrown
188
+ self.assertTrue(True)
189
+
190
+ def test_type_error(self):
191
+ smtlib_script = "\n".join([
192
+ "(declare-sort B 0)",
193
+ "(declare-const e B)",
194
+ "(declare-const x Bool)",
195
+ "(assert (= e x))",
196
+ ])
197
+ stream = StringIO(smtlib_script)
198
+ parser = SmtLibParser()
199
+ with self.assertRaises(PysmtTypeError):
200
+ _ = parser.get_script(stream)
178
201
 
179
202
  def test_evaluate_command(self):
180
203
  class SmtLibIgnore(SmtLibIgnoreMixin):
@@ -233,14 +256,19 @@ class TestSmtLibScript(TestCase):
233
256
  # Create a small file that tests all commands of smt-lib 2
234
257
  parser = SmtLibParser()
235
258
 
259
+ te = 0
236
260
  nie = 0
237
261
  for cmd in DEMO_SMTSCRIPT:
238
262
  try:
239
263
  next(parser.get_command_generator(StringIO(cmd)))
240
264
  except NotImplementedError:
241
265
  nie += 1
266
+ except PysmtTypeError:
267
+ te += 1
242
268
  # There are currently 3 not-implemented commands
243
269
  self.assertEqual(nie, 3)
270
+ # There is currently 1 type error
271
+ self.assertEqual(te, 1)
244
272
 
245
273
  DEMO_SMTSCRIPT = [ "(declare-fun a () Bool)",
246
274
  "(declare-fun b () Bool)",
@@ -19,7 +19,7 @@ import pysmt
19
19
 
20
20
  from pysmt.typing import BOOL, REAL, INT, FunctionType, BV8, BVType
21
21
  from pysmt.shortcuts import Symbol, is_sat, Not, Implies, GT, Plus, Int, Real
22
- from pysmt.shortcuts import Minus, Times, Xor, And, Or, TRUE, Iff, FALSE, Ite
22
+ from pysmt.shortcuts import Minus, Times, Xor, And, Or, TRUE, Iff, FALSE, Ite, Abs
23
23
  from pysmt.shortcuts import Equals
24
24
  from pysmt.shortcuts import get_env
25
25
  from pysmt.environment import Environment
@@ -317,6 +317,38 @@ class TestFormulaManager(TestCase):
317
317
  inv = self.mgr.Real(Fraction(1) / self.rconst.constant_value())
318
318
  self.assertEqual(n, self.mgr.Times(self.s, inv))
319
319
 
320
+ def test_abs_shortcut(self):
321
+ # Test with integer
322
+ abs_int = Abs(self.p)
323
+
324
+ # Verify the structure of the Abs node
325
+ self.assertTrue(abs_int.is_ite())
326
+ self.assertTrue(abs_int.arg(0).is_lt()) # GT is converted to LT with inverted args
327
+ self.assertEqual(abs_int.arg(0).arg(0), Int(0)) # First arg is 0
328
+ self.assertEqual(abs_int.arg(0).arg(1), self.p) # Second arg is p
329
+ self.assertEqual(abs_int.arg(1), self.p)
330
+ self.assertTrue(abs_int.arg(2).is_minus())
331
+ self.assertEqual(abs_int.arg(2).arg(0), Int(0))
332
+ self.assertEqual(abs_int.arg(2).arg(1), self.p)
333
+
334
+ # Test with real
335
+ abs_real = Abs(self.r)
336
+
337
+ # Verify the structure of the Abs node
338
+ self.assertTrue(abs_real.is_ite())
339
+ self.assertTrue(abs_real.arg(0).is_lt()) # GT is converted to LT with inverted args
340
+ self.assertEqual(abs_real.arg(0).arg(0), Real(0)) # First arg is 0
341
+ self.assertEqual(abs_real.arg(0).arg(1), self.r) # Second arg is r
342
+ self.assertEqual(abs_real.arg(1), self.r)
343
+ self.assertTrue(abs_real.arg(2).is_minus())
344
+ self.assertEqual(abs_real.arg(2).arg(0), Real(0))
345
+ self.assertEqual(abs_real.arg(2).arg(1), self.r)
346
+
347
+ # Test with boolean (should raise ValueError)
348
+ bool_var = Symbol("z", BOOL)
349
+ with self.assertRaises(ValueError):
350
+ Abs(bool_var)
351
+
320
352
  def test_equals(self):
321
353
  n = self.mgr.Equals(self.real_expr, self.real_expr)
322
354
  self.assertIsNotNone(n)
@@ -18,8 +18,10 @@
18
18
  import unittest
19
19
  import tempfile, os
20
20
 
21
+ from fractions import Fraction
22
+
21
23
  from pysmt.parsing import HRParser, parse
22
- from pysmt.shortcuts import Iff, Symbol, And, Or, LE, Real, Plus, Minus
24
+ from pysmt.shortcuts import Iff, Symbol, And, Or, LE, GT, Real, Plus, Minus
23
25
  from pysmt.test.examples import get_example_formulae
24
26
  from pysmt.exceptions import NoSolverAvailableError
25
27
  from pysmt.test import TestCase
@@ -76,6 +78,7 @@ class TestHRParser(TestCase):
76
78
  p = HRParser()
77
79
  for (f, _, _, _) in get_example_formulae():
78
80
  s = f.serialize()
81
+ print(s)
79
82
  res = p.parse(s)
80
83
  check = (res == f)
81
84
  if not check:
@@ -84,6 +87,12 @@ class TestHRParser(TestCase):
84
87
  except NoSolverAvailableError:
85
88
  pass
86
89
 
90
+ def test_substring(self):
91
+ p = HRParser()
92
+ s=Symbol('Intake_Pressure', REAL)
93
+ res = p.parse('(Intake_Pressure > 91.988 & Intake_Pressure<=116.892)')
94
+ print(res.serialize())
95
+ self.assertEqual(res, And(GT(s, Real(Fraction("91.988"))), LE(s, Real(Fraction("116.892")))))
87
96
 
88
97
 
89
98
  if __name__ == '__main__':
@@ -456,13 +456,20 @@ class TestRegressions(TestCase):
456
456
  self.assertEqual(ex.pos_info[1], 19)
457
457
 
458
458
  def test_parse_bvconst_width(self):
459
- smtlib_input = "(assert (> #x10 #x10))"
459
+ smtlib_input = "(assert (bvugt #x10 #x10))"
460
460
  parser = SmtLibParser()
461
461
  buffer_ = StringIO(smtlib_input)
462
462
  expr = parser.get_script(buffer_).get_last_formula()
463
463
  const = expr.args()[0]
464
464
  self.assertEqual(const.bv_width(), 8, const.bv_width())
465
465
 
466
+ def test_parse_bvconst_type_check(self):
467
+ smtlib_input = "(assert (> #x10 #x10))"
468
+ parser = SmtLibParser()
469
+ buffer_ = StringIO(smtlib_input)
470
+ with self.assertRaises(PysmtTypeError):
471
+ _ = parser.get_script(buffer_).get_last_formula()
472
+
466
473
  def test_equality_typing(self):
467
474
  x = Symbol('x', BOOL)
468
475
  y = Symbol('y', BOOL)
@@ -212,6 +212,15 @@ class TestSimpleTypeChecker(TestCase):
212
212
  with self.assertRaises(PysmtTypeError):
213
213
  super_bad_function()
214
214
 
215
+ def test_multiple_creations(self):
216
+ def bad_formula():
217
+ return Times(self.p, self.r)
218
+ with self.assertRaises(PysmtTypeError):
219
+ bad_formula()
220
+ # When building the same formula a second time, should raise again.
221
+ with self.assertRaises(PysmtTypeError):
222
+ bad_formula()
223
+
215
224
  def test_examples(self):
216
225
  for (f, _, _, _) in get_example_formulae():
217
226
  self.assertIs(f.get_type(), BOOL, f)