Skip to content

Commit 4a16145

Browse files
committed
SMT2 back-end: detect when solver returns unexpected model
We have seen examples of Z3 responding with ``` ((B1502 (forall ((|main::tmp_cc$0!0@1#0| (_ BitVec 64))) (let ((a!1 (or (and (not (bvule #x000000000000000c |main::tmp_cc$0!0@1#0|)) (bvule #x000000000000000b |main::tmp_cc$0!0@1#0|) [...] ``` when we expected just `true` or `false` as model (which Bitwuzla seemed to get right on the very same input program). Report these as errors rather than using the incomplete assignment. Such an incomplete assignment would make us re-try forever without making progress. Fixes: diffblue#8365
1 parent 629dbcd commit 4a16145

File tree

1 file changed

+34
-11
lines changed

1 file changed

+34
-11
lines changed

src/solvers/smt2/smt2_dec.cpp

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -236,22 +236,45 @@ decision_proceduret::resultt smt2_dect::read_result(std::istream &in)
236236
{
237237
const std::string boolean_identifier =
238238
convert_identifier("B" + std::to_string(v));
239-
boolean_assignment[v] = [&]() {
240239
const auto found_parsed_value =
241240
parsed_values.find(drop_quotes(boolean_identifier));
242241
if(found_parsed_value != parsed_values.end())
243242
{
244-
return found_parsed_value->second.id() == ID_true;
243+
const irept &value = found_parsed_value->second;
244+
245+
if(value.id() != ID_true && value.id() != ID_false)
246+
{
247+
messaget log{message_handler};
248+
log.error() << "SMT2 solver returned non-Boolean value for variable "
249+
<< boolean_identifier << messaget::eom;
250+
return decision_proceduret::resultt::D_ERROR;
251+
}
252+
boolean_assignment[v] = value.id() == ID_true;
253+
}
254+
else
255+
{
256+
// Work out the value based on what set_to was called with.
257+
const auto found_set_value = set_values.find(boolean_identifier);
258+
if(found_set_value != set_values.end())
259+
boolean_assignment[v] = found_set_value->second;
260+
else
261+
{
262+
// Old code used the computation
263+
// const irept &value=values["B"+std::to_string(v)];
264+
// boolean_assignment[v]=(value.id()==ID_true);
265+
const irept &value = parsed_values[boolean_identifier];
266+
267+
if(value.id() != ID_true && value.id() != ID_false)
268+
{
269+
messaget log{message_handler};
270+
log.error()
271+
<< "SMT2 solver returned non-Boolean value for variable "
272+
<< boolean_identifier << messaget::eom;
273+
return decision_proceduret::resultt::D_ERROR;
274+
}
275+
boolean_assignment[v] = value.id() == ID_true;
276+
}
245277
}
246-
// Work out the value based on what set_to was called with.
247-
const auto found_set_value = set_values.find(boolean_identifier);
248-
if(found_set_value != set_values.end())
249-
return found_set_value->second;
250-
// Old code used the computation
251-
// const irept &value=values["B"+std::to_string(v)];
252-
// boolean_assignment[v]=(value.id()==ID_true);
253-
return parsed_values[boolean_identifier].id() == ID_true;
254-
}();
255278
}
256279

257280
return res;

0 commit comments

Comments
 (0)