6
6
7
7
\*******************************************************************/
8
8
9
+ #include " smt2_parser.h"
10
+
11
+ #include " smt2_format.h"
12
+
9
13
#include < fstream>
10
14
#include < iostream>
11
15
12
- #include " smt2_parser.h"
13
-
14
16
#include < util/message.h>
15
17
#include < util/namespace.h>
16
18
#include < util/replace_symbol.h>
23
25
class smt2_solvert :public smt2_parsert
24
26
{
25
27
public:
26
- smt2_solvert (
27
- std::istream &_in,
28
- decision_proceduret &_solver):
29
- smt2_parsert (_in),
30
- solver (_solver)
28
+ smt2_solvert (std::istream &_in, decision_proceduret &_solver)
29
+ : smt2_parsert(_in), solver(_solver), status(NOT_SOLVED)
31
30
{
32
31
}
33
32
@@ -39,6 +38,13 @@ class smt2_solvert:public smt2_parsert
39
38
void expand_function_applications (exprt &);
40
39
41
40
std::set<irep_idt> constants_done;
41
+
42
+ enum
43
+ {
44
+ NOT_SOLVED,
45
+ SAT,
46
+ UNSAT
47
+ } status;
42
48
};
43
49
44
50
void smt2_solvert::define_constants (const exprt &expr)
@@ -139,14 +145,17 @@ void smt2_solvert::command(const std::string &c)
139
145
{
140
146
case decision_proceduret::resultt::D_SATISFIABLE:
141
147
std::cout << " sat\n " ;
148
+ status = SAT;
142
149
break ;
143
150
144
151
case decision_proceduret::resultt::D_UNSATISFIABLE:
145
152
std::cout << " unsat\n " ;
153
+ status = UNSAT;
146
154
break ;
147
155
148
156
case decision_proceduret::resultt::D_ERROR:
149
157
std::cout << " error\n " ;
158
+ status = NOT_SOLVED;
150
159
}
151
160
}
152
161
else if (c==" check-sat-assuming" )
@@ -162,6 +171,63 @@ void smt2_solvert::command(const std::string &c)
162
171
std::cout << e.pretty () << ' \n ' ; // need to do an 'smt2_format'
163
172
}
164
173
}
174
+ else if (c == " get-value" )
175
+ {
176
+ std::vector<exprt> ops;
177
+
178
+ if (next_token () != OPEN)
179
+ throw " get-value expects list as argument" ;
180
+
181
+ while (peek () != CLOSE && peek () != END_OF_FILE)
182
+ ops.push_back (expression ()); // any term
183
+
184
+ if (next_token () != CLOSE)
185
+ throw " get-value expects ')' at end of list" ;
186
+
187
+ if (status != SAT)
188
+ throw " model is not available" ;
189
+
190
+ std::vector<exprt> values;
191
+ values.reserve (ops.size ());
192
+
193
+ for (const auto &op : ops)
194
+ {
195
+ if (op.id () != ID_symbol)
196
+ throw " get-value expects symbol" ;
197
+
198
+ const auto &identifier = to_symbol_expr (op).get_identifier ();
199
+
200
+ const auto id_map_it = id_map.find (identifier);
201
+
202
+ if (id_map_it == id_map.end ())
203
+ throw " unexpected symbol " + id2string (identifier);
204
+
205
+ exprt value;
206
+
207
+ if (id_map_it->second .definition .is_nil ())
208
+ value = solver.get (op);
209
+ else
210
+ value = solver.get (id_map_it->second .definition );
211
+
212
+ if (value.is_nil ())
213
+ throw " no value for " + id2string (identifier);
214
+
215
+ values.push_back (value);
216
+ }
217
+
218
+ std::cout << ' (' ;
219
+
220
+ for (std::size_t op_nr = 0 ; op_nr < ops.size (); op_nr++)
221
+ {
222
+ if (op_nr != 0 )
223
+ std::cout << " \n " ;
224
+
225
+ std::cout << ' (' << smt2_format (ops[op_nr]) << ' '
226
+ << smt2_format (values[op_nr]) << ' )' ;
227
+ }
228
+
229
+ std::cout << " )\n " ;
230
+ }
165
231
else if (c==" simplify" )
166
232
{
167
233
// this is a command that Z3 appears to implement
@@ -195,7 +261,6 @@ void smt2_solvert::command(const std::string &c)
195
261
| ( get-proof )
196
262
| ( get-unsat-assumptions )
197
263
| ( get-unsat-core )
198
- | ( get-value ( htermi + ) )
199
264
| ( pop hnumerali )
200
265
| ( push hnumerali )
201
266
| ( reset )
0 commit comments