PySMT 0.9.7.dev397__py2.py3-none-any.whl → 0.9.7.dev414__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.
pysmt/__init__.py CHANGED
@@ -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", 397)
22
+ VERSION: Union[Tuple[int, int, int], Tuple[int, int, int, str, int]] = (0, 9, 7, "dev", 414)
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
@@ -1312,15 +1312,39 @@ class SmtLibParser(object):
1312
1312
 
1313
1313
  def _cmd_minmax_maxmin_obj(self, current: str, tokens: Tokenizer) -> SmtLibCommand:
1314
1314
  """(minmax | maxmin <term>+ )"""
1315
- """TODO: [:id <string>] [:signed]"""
1316
- params = []
1315
+ params: List[Tuple[str, Union[str, bool]]] = []
1316
+ terms = []
1317
+ signed = False
1318
+ options = False
1319
+
1317
1320
  while True:
1318
- try:
1319
- c = self.get_expression(tokens)
1320
- params.append(c)
1321
- except PysmtSyntaxError:
1321
+ token = tokens.consume()
1322
+ if token == ")":
1322
1323
  break
1323
- return SmtLibCommand(current, [params,None])
1324
+ if token.startswith(":"):
1325
+ options = True
1326
+ if token == ":id":
1327
+ identifier = self.parse_atom(tokens, "maxmin/minmax")
1328
+ params.append((token, identifier))
1329
+ elif token == ":signed":
1330
+ signed = True
1331
+ params.append((token, signed))
1332
+ else:
1333
+ raise PysmtSyntaxError(
1334
+ "Incorrect option in the '%s' command" % token,
1335
+ tokens.pos_info)
1336
+ else:
1337
+ if options:
1338
+ raise PysmtSyntaxError(
1339
+ "Unexpected token '%s' after options in the '%s' command" % (token, current),
1340
+ tokens.pos_info)
1341
+ tokens.add_extra_token(token)
1342
+ terms.append(self.get_expression(tokens))
1343
+
1344
+ if not any(option[0] == ":signed" for option in params):
1345
+ params.append((":signed", False))
1346
+
1347
+ return SmtLibCommand(current, [terms, params])
1324
1348
 
1325
1349
  def _cmd_objective(self, current: str, tokens: Tokenizer) -> SmtLibCommand:
1326
1350
  """(maximize | minimize <term>"""
pysmt/smtlib/script.py CHANGED
@@ -122,9 +122,15 @@ class SmtLibCommand(namedtuple('SmtLibCommand', ['name', 'args'])):
122
122
 
123
123
  elif self.name in [smtcmd.MINMAX, smtcmd.MAXMIN]:
124
124
  outstream.write("(%s" % self.name)
125
- for a in self.args:
125
+ for a in self.args[0]:
126
126
  outstream.write(" ")
127
127
  printer.printer(a)
128
+ for option_name, value in self.args[1] or []:
129
+ if option_name == ":signed":
130
+ if value:
131
+ outstream.write(" %s" % option_name)
132
+ else:
133
+ outstream.write(" %s %s" % (option_name, value))
128
134
  outstream.write(")")
129
135
 
130
136
  elif self.name == smtcmd.CHECK_ALLSAT:
pysmt/substituter.py CHANGED
@@ -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
@@ -63,6 +63,139 @@ class TestSmtLibParserOMT(TestCase):
63
63
  self.assertEqual(cmd.name, command)
64
64
  self.assertEqual(len(cmd.args), len_args)
65
65
 
66
+ def test_parse_minmax_maxmin_with_options(self):
67
+ parser = SmtLibParser()
68
+
69
+ script = parser.get_script(StringIO(
70
+ "(declare-fun x () Real)\n"
71
+ "(declare-fun y () Real)\n"
72
+ "(minmax x y :id g1 :signed)\n"
73
+ ))
74
+ cmd = script.commands[-1]
75
+ self.assertEqual(cmd.name, "minmax")
76
+ self.assertEqual(cmd.args[1], [(':id', 'g1'), (':signed', True)])
77
+
78
+ buf = StringIO()
79
+ script.serialize(buf)
80
+ self.assertIn("(minmax x y :id g1 :signed)", buf.getvalue())
81
+
82
+ script = parser.get_script(StringIO(
83
+ "(declare-fun x () Real)\n"
84
+ "(declare-fun y () Real)\n"
85
+ "(maxmin x y :id g2)\n"
86
+ ))
87
+ cmd = script.commands[-1]
88
+ self.assertEqual(cmd.name, "maxmin")
89
+ self.assertEqual(cmd.args[1], [(':id', 'g2'), (':signed', False)])
90
+
91
+ def test_parse_minmax_maxmin_signed_only(self):
92
+ parser = SmtLibParser()
93
+
94
+ script = parser.get_script(StringIO(
95
+ "(declare-fun x () Real)\n"
96
+ "(declare-fun y () Real)\n"
97
+ "(maxmin x y :signed)\n"
98
+ ))
99
+ cmd = script.commands[-1]
100
+ self.assertEqual(cmd.name, "maxmin")
101
+ self.assertEqual(cmd.args[1], [(':signed', True)])
102
+
103
+ buf = StringIO()
104
+ script.serialize(buf)
105
+ self.assertIn("(maxmin x y :signed)", buf.getvalue())
106
+
107
+ def test_parse_minmax_maxmin_invalid_option(self):
108
+ parser = SmtLibParser()
109
+ with self.assertRaises(PysmtSyntaxError):
110
+ parser.get_script(StringIO(
111
+ "(declare-fun x () Real)\n"
112
+ "(declare-fun y () Real)\n"
113
+ "(minmax x y :foo 1)\n"
114
+ ))
115
+
116
+ def test_parse_minmax_multiple_terms_with_options(self):
117
+ parser = SmtLibParser()
118
+
119
+ script = parser.get_script(StringIO(
120
+ "(declare-fun x () Real)\n"
121
+ "(declare-fun y () Real)\n"
122
+ "(declare-fun z () Real)\n"
123
+ "(minmax x y z :id g1 :signed)\n"
124
+ ))
125
+ cmd = script.commands[-1]
126
+ self.assertEqual(cmd.name, "minmax")
127
+ self.assertEqual([term.symbol_name() for term in cmd.args[0]], ['x', 'y', 'z'])
128
+ self.assertEqual(cmd.args[1], [(':id', 'g1'), (':signed', True)])
129
+
130
+ buf = StringIO()
131
+ script.serialize(buf)
132
+ self.assertIn("(minmax x y z :id g1 :signed)", buf.getvalue())
133
+
134
+ def test_parse_minmax_option_order(self):
135
+ parser = SmtLibParser()
136
+
137
+ script = parser.get_script(StringIO(
138
+ "(declare-fun x () Real)\n"
139
+ "(declare-fun y () Real)\n"
140
+ "(maxmin x y :signed :id g2)\n"
141
+ ))
142
+ cmd = script.commands[-1]
143
+ self.assertEqual(cmd.name, "maxmin")
144
+ self.assertEqual(cmd.args[1], [(':signed', True), (':id', 'g2')])
145
+
146
+ buf = StringIO()
147
+ script.serialize(buf)
148
+ self.assertIn("(maxmin x y :signed :id g2)", buf.getvalue())
149
+
150
+ def test_parse_minmax_reverse_option_order(self):
151
+ parser = SmtLibParser()
152
+
153
+ script = parser.get_script(StringIO(
154
+ "(declare-fun x () Real)\n"
155
+ "(declare-fun y () Real)\n"
156
+ "(minmax x y :signed :id g1)\n"
157
+ ))
158
+ cmd = script.commands[-1]
159
+ self.assertEqual(cmd.name, "minmax")
160
+ self.assertEqual(cmd.args[1], [(':signed', True), (':id', 'g1')])
161
+
162
+ buf = StringIO()
163
+ script.serialize(buf)
164
+ self.assertIn("(minmax x y :signed :id g1)", buf.getvalue())
165
+
166
+ def test_parse_minmax_maxmin_syntax_errors(self):
167
+ parser = SmtLibParser()
168
+ with self.assertRaises(PysmtSyntaxError):
169
+ parser.get_script(StringIO(
170
+ "(declare-fun x () Real)\n"
171
+ "(declare-fun y () Real)\n"
172
+ "(minmax x y :id)\n"
173
+ ))
174
+ with self.assertRaises(PysmtSyntaxError):
175
+ parser.get_script(StringIO(
176
+ "(declare-fun x () Real)\n"
177
+ "(declare-fun y () Real)\n"
178
+ "(maxmin x y :signed true)\n"
179
+ ))
180
+
181
+ def test_parse_minmax_maxmin_round_trip(self):
182
+ parser = SmtLibParser()
183
+ txt = """(declare-fun x () Real)
184
+ (declare-fun y () Real)
185
+ (minmax x y :id g1 :signed)
186
+ (maxmin x y :signed :id g2)
187
+ """
188
+ script = parser.get_script(StringIO(txt))
189
+
190
+ buf = StringIO()
191
+ script.serialize(buf)
192
+ new_script = parser.get_script(StringIO(buf.getvalue()))
193
+
194
+ self.assertEqual(script.commands[-2].name, new_script.commands[-2].name)
195
+ self.assertEqual(script.commands[-2].args[1], new_script.commands[-2].args[1])
196
+ self.assertEqual(script.commands[-1].name, new_script.commands[-1].name)
197
+ self.assertEqual(script.commands[-1].args[1], new_script.commands[-1].args[1])
198
+
66
199
  def parse_from_file(self, file_id: int) -> SmtLibScript:
67
200
  fname = OMT_FILE_PATTERN % file_id
68
201
  reset_env()
@@ -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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PySMT
3
- Version: 0.9.7.dev397
3
+ Version: 0.9.7.dev414
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=ZgfSobTT7ZMC3GRVR4Lb68ibKWwJIMEG0t5vgn0efro,1701
1
+ pysmt/__init__.py,sha256=JhrChEFdfn5oOH9300tA4Bhvjs8Fshqswk2RViJQpO4,1701
2
2
  pysmt/__main__.py,sha256=rR-MV1QtLYqtVoJyY3m5B5Iz-lua0-5o6YSB0W4lKy8,1085
3
3
  pysmt/configuration.py,sha256=Iq_46QZ9z_jpBMk76euJWTqGEwHad2qyiEDPix5sXsA,4538
4
4
  pysmt/constants.py,sha256=pulb6NvROY_X8BePeyyX8T9MJLB79HZ_1FUYSlZ7Jfg,5769
@@ -16,7 +16,7 @@ pysmt/printers.py,sha256=nx8N4uQ6Hp591JyE98hdjKlO6x0lqL9dr2AGf07a644,14955
16
16
  pysmt/rewritings.py,sha256=x0h8zUtb5qcwRLJAhXEajI5AC8cNpGtf_C8JWCyJvCU,36486
17
17
  pysmt/shortcuts.py,sha256=EzwH0wXDXDWeQs46GKMQf3W-x1AGkwisaQJt6xodqso,44599
18
18
  pysmt/simplifier.py,sha256=s5jUxql86MjZ77_deoFbOVvnDe-5Tj_xpyK3VQtpj6c,44900
19
- pysmt/substituter.py,sha256=8kcry2i7GJBD5Fiv6LlRMcrzXifpYyUGaj1MH4kjEPA,14249
19
+ pysmt/substituter.py,sha256=sTW-Phkq6Ae8xft_eLrXR06wJZ6C3EgpkZoqj_HLLMc,14446
20
20
  pysmt/type_checker.py,sha256=0XfiYad4swJeKRXy1W4eGbidrU371s4qqHcy8AfXZ7g,15793
21
21
  pysmt/typing.py,sha256=aI8ZKEin4J2XLAHsY5fW1Pt4hZvlBlArxM4nrrmBas4,19550
22
22
  pysmt/utils.py,sha256=_dSgl45k-u9cMXSyR672GBJcKMKdtl6xSTjqXKTSfcs,2906
@@ -46,11 +46,11 @@ pysmt/smtlib/__init__.py,sha256=JXBHtcb4Lv-Sb8whc9JuGbRH2EBLWwtLUh3PL9HhNE8,650
46
46
  pysmt/smtlib/annotations.py,sha256=UTl_nnBikMGKzdpW5N17yIpvx-_8HZmo8hxXIKsm7Wo,4596
47
47
  pysmt/smtlib/commands.py,sha256=hwWnXrzZxJmKtkIitHRtuin01WDUErT0VERR9h45t2A,2277
48
48
  pysmt/smtlib/printers.py,sha256=ZZMx1d0aS5kGDqJj1c7PYCEXqgXnk_CugcVAVinrtzk,25940
49
- pysmt/smtlib/script.py,sha256=3kxhDnOxcNaermcX6baM_NgRVJvZ5uRFPHH3dVJ-zIo,23811
49
+ pysmt/smtlib/script.py,sha256=RWJT9KA_LH23YNqhtosc10LaH8Z_6Hj1YNDuf_qqLIc,24099
50
50
  pysmt/smtlib/solver.py,sha256=NUtBsghqgTAPEH2am4_Aq6BYz2ugGPRWGzpdzMQpAr4,8062
51
51
  pysmt/smtlib/utils.py,sha256=C-P8RPgR8RDRQnrB8xfLGc5aFso11u0sEtFw04NMbKQ,2126
52
52
  pysmt/smtlib/parser/__init__.py,sha256=Pfdm6pv9hwOv8D9NbAaHEokDZXkRg3CwYLN5Ny7UNyY,5055
53
- pysmt/smtlib/parser/parser.py,sha256=70_1fAI8w62SmDMtrHZDbOIJUQSBCgWalX_RnqojGKw,66475
53
+ pysmt/smtlib/parser/parser.py,sha256=yXNm3VJDgtSFDA41-iKkgeZVhlUXqKskj9Xsgbja7iE,67454
54
54
  pysmt/solvers/__init__.py,sha256=JXBHtcb4Lv-Sb8whc9JuGbRH2EBLWwtLUh3PL9HhNE8,650
55
55
  pysmt/solvers/bdd.py,sha256=NG0BHE5-nqfn6vdUZjJIxiBH1ZwdkTgJKSeQGORaCFc,15961
56
56
  pysmt/solvers/btor.py,sha256=V9pAVMhvjmejyrMiQNrpxQFQ8VzmebhRcvuSSwTcAvQ,26033
@@ -113,7 +113,7 @@ pysmt/test/test_string.py,sha256=Y6VBfkLNKuePo8-HIzcwBH3eaYj0i-k1Y8tpFyw03zw,809
113
113
  pysmt/test/test_typechecker.py,sha256=S2O8HjN_bLN6sz86TnsWqpRtxHk2VcVsGDoRZCcQnzE,7309
114
114
  pysmt/test/test_unsat_cores.py,sha256=-WFx7AsFY4DG5bfRUOYMb38lpVJ_I-7-WZFjsSFD5Aw,6565
115
115
  pysmt/test/test_walker_ext.py,sha256=j7mp46QoD3f-TD4zdqHM2EF40zBCizpV3t7z2f0_CeY,3595
116
- pysmt/test/test_walkers.py,sha256=AKVMvEUtMBht08bE1vCMaeMtdgGa6j_weDSHz_9Br3Q,9481
116
+ pysmt/test/test_walkers.py,sha256=gV0oRpZ2ngYuMiNYeDcJ29N1InWvvs0dN9TgLJwjD-A,10118
117
117
  pysmt/test/configs/config1.ini,sha256=MAXPN6VVW-S7jpWmglMPN5a3JYgorTqKAF6cmfohMpo,224
118
118
  pysmt/test/configs/config_bad.ini,sha256=AOiZPmUcmAjVXOd5Bp4_euaYJG8EfccBy5iKUEcbxz8,88
119
119
  pysmt/test/smtlib/__init__.py,sha256=JXBHtcb4Lv-Sb8whc9JuGbRH2EBLWwtLUh3PL9HhNE8,650
@@ -127,7 +127,7 @@ pysmt/test/smtlib/test_omt_lib_solver.py,sha256=xZZWDSB0eDBsmzu7R8AqRN0fSCvFRW6x
127
127
  pysmt/test/smtlib/test_parser_examples.py,sha256=5e0pNN5rjgi5cLAJl4ZZuUiifCUgVaD__JfBlVJgMR4,10100
128
128
  pysmt/test/smtlib/test_parser_extensibility.py,sha256=MgEVUU-icDEryKh54sW9VC59e8CuC6Q_5Sw65FtxBgo,3933
129
129
  pysmt/test/smtlib/test_parser_lra.py,sha256=N6HD1BqSb88FpOeaHsKME5IOok3Eu3YdpM55XgDFs3s,997
130
- pysmt/test/smtlib/test_parser_omt.py,sha256=9TFf4GYOuVDBPDSPqF9g3KxWnWaHArL9feDKDqVSQJM,4814
130
+ pysmt/test/smtlib/test_parser_omt.py,sha256=XhS6Fmy5c1xRya45QlyJuzuV7jdnFfrkig-zZkQrJO0,9564
131
131
  pysmt/test/smtlib/test_parser_qf_arrays.py,sha256=SnYd5z1gYnTjfDP6eUomA9W0mMyMqR-RLpc20c5XcQo,1036
132
132
  pysmt/test/smtlib/test_parser_qf_lia.py,sha256=_2VKMP-GD1JI16-Bf1jevdjrYjDz62tqdtKoeLE8SLM,1006
133
133
  pysmt/test/smtlib/test_parser_qf_lira.py,sha256=6hPpu6_C2vIT-0TdFOS1y5LfbM8S5Jcbnm2LaztVRNI,1013
@@ -143,10 +143,10 @@ pysmt/walkers/dag.py,sha256=4CWSgoXm6nONhM-1znKRU4SBCb791OTS-M9QlQFhbs8,5751
143
143
  pysmt/walkers/generic.py,sha256=dmp47kJGtO6rhC2t07Mf_FsYN-lcy64LX-dZggNnWm4,5179
144
144
  pysmt/walkers/identitydag.py,sha256=DBPaDuIgvZZz1ohKyoWcDeQVa3RgMQDnqn4Jo7gwtNs,10782
145
145
  pysmt/walkers/tree.py,sha256=8oyDSXZtUsCdExcrwG3hKuEgARHgdW6fvz0LZJwjp-k,2983
146
- pysmt-0.9.7.dev397.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
147
- pysmt-0.9.7.dev397.dist-info/licenses/NOTICE,sha256=Ns-Jsa6nbqZUiTEEAM6HqioSZIxQ2RCJzxoBlWQaUfc,601
148
- pysmt-0.9.7.dev397.dist-info/METADATA,sha256=jaHNVKmsXdhyf2fFPVj6VS4G30dPmvCIV5wBEoIxqGU,1774
149
- pysmt-0.9.7.dev397.dist-info/WHEEL,sha256=TdQ5LtNwLuxTCjgxN51AgdU5w-KkB9ttmLbzjTH02pg,109
150
- pysmt-0.9.7.dev397.dist-info/entry_points.txt,sha256=gDc1XM0xTJJMDGC_nXd0kfbX-Omjke9Dn9F3awMLYIU,57
151
- pysmt-0.9.7.dev397.dist-info/top_level.txt,sha256=NwHQbpTaZMEvjIUdC0bvvj-WUyULe-nt-opK3YQNRMk,6
152
- pysmt-0.9.7.dev397.dist-info/RECORD,,
146
+ pysmt-0.9.7.dev414.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
147
+ pysmt-0.9.7.dev414.dist-info/licenses/NOTICE,sha256=Ns-Jsa6nbqZUiTEEAM6HqioSZIxQ2RCJzxoBlWQaUfc,601
148
+ pysmt-0.9.7.dev414.dist-info/METADATA,sha256=rLW4kfE2YNfXcGxd7Zj4-VlZA7_lfK7RqdMKH-cU3r4,1774
149
+ pysmt-0.9.7.dev414.dist-info/WHEEL,sha256=TdQ5LtNwLuxTCjgxN51AgdU5w-KkB9ttmLbzjTH02pg,109
150
+ pysmt-0.9.7.dev414.dist-info/entry_points.txt,sha256=gDc1XM0xTJJMDGC_nXd0kfbX-Omjke9Dn9F3awMLYIU,57
151
+ pysmt-0.9.7.dev414.dist-info/top_level.txt,sha256=NwHQbpTaZMEvjIUdC0bvvj-WUyULe-nt-opK3YQNRMk,6
152
+ pysmt-0.9.7.dev414.dist-info/RECORD,,