@@ -139,7 +139,7 @@ decision_proceduret::resultt smt2_dect::read_result(std::istream &in)
139
139
boolean_assignment.resize (no_boolean_variables, false );
140
140
141
141
typedef std::unordered_map<irep_idt, irept> valuest;
142
- valuest values ;
142
+ valuest parsed_values ;
143
143
144
144
while (in)
145
145
{
@@ -167,37 +167,69 @@ decision_proceduret::resultt smt2_dect::read_result(std::istream &in)
167
167
// ( (|some_integer| 0) )
168
168
// ( (|some_integer| (- 10)) )
169
169
170
- values [s0.id ()]= s1;
170
+ parsed_values [s0.id ()] = s1;
171
171
}
172
172
else if (
173
173
parsed.id ().empty () && parsed.get_sub ().size () == 2 &&
174
174
parsed.get_sub ().front ().id () == " error" )
175
175
{
176
176
// We ignore errors after UNSAT because get-value after check-sat
177
177
// returns unsat will give an error.
178
- if (res!= resultt::D_UNSATISFIABLE)
178
+ if (res != resultt::D_UNSATISFIABLE)
179
179
{
180
- messaget log {message_handler};
181
- log .error () << " SMT2 solver returned error message:\n "
182
- << " \t\" " << parsed.get_sub ()[1 ].id () << " \" "
183
- << messaget::eom;
184
- return decision_proceduret::resultt::D_ERROR;
180
+ const auto &message = id2string (parsed.get_sub ()[1 ].id ());
181
+ // Special case error handling
182
+ if (
183
+ solver == solvert::Z3 &&
184
+ message.find (" must not contain quantifiers" ) != std::string::npos)
185
+ {
186
+ // We tried to "(get-value |XXXX|)" where |XXXX| is determined to
187
+ // include a quantified expression
188
+ // Nothing to do, this should be caught and value assigned by the
189
+ // set_to defaults later.
190
+ }
191
+ // Unhandled error, log the error and report it back up to caller
192
+ else
193
+ {
194
+ messaget log {message_handler};
195
+ log .error () << " SMT2 solver returned error message:\n "
196
+ << " \t\" " << message << " \" " << messaget::eom;
197
+ return decision_proceduret::resultt::D_ERROR;
198
+ }
185
199
}
186
200
}
187
201
}
188
202
203
+ // If the result is not satisfiable don't bother updating the assignments and
204
+ // values (since we didn't get any), just return.
205
+ if (res != resultt::D_SATISFIABLE)
206
+ return res;
207
+
189
208
for (auto &assignment : identifier_map)
190
209
{
191
- std::string conv_id= convert_identifier (assignment.first );
192
- const irept &value=values [conv_id];
193
- assignment.second .value = parse_rec (value, assignment.second .type );
210
+ std::string conv_id = convert_identifier (assignment.first );
211
+ const irept &value = parsed_values [conv_id];
212
+ assignment.second .value = parse_rec (value, assignment.second .type );
194
213
}
195
214
196
215
// Booleans
197
216
for (unsigned v=0 ; v<no_boolean_variables; v++)
198
217
{
199
- const irept &value=values[" B" +std::to_string (v)];
200
- boolean_assignment[v]=(value.id ()==ID_true);
218
+ const std::string boolean_identifier = " B" + std::to_string (v);
219
+ boolean_assignment[v] = [&]() {
220
+ const auto found_parsed_value = parsed_values.find (boolean_identifier);
221
+ if (found_parsed_value != parsed_values.end ())
222
+ return found_parsed_value->second .id () == ID_true;
223
+ // Work out the value based on what set_to was called with.
224
+ const auto found_set_value =
225
+ set_values.find (' |' + boolean_identifier + ' |' );
226
+ if (found_set_value != set_values.end ())
227
+ return found_set_value->second ;
228
+ // Old code used the computation
229
+ // const irept &value=values["B"+std::to_string(v)];
230
+ // boolean_assignment[v]=(value.id()==ID_true);
231
+ return parsed_values[boolean_identifier].id () == ID_true;
232
+ }();
201
233
}
202
234
203
235
return res;
0 commit comments