Skip to content

Commit 2d33fde

Browse files
thomasspriggsTGWDB
authored andcommitted
Use set_to to infer missing boolean identifier values
This fixes some of the cases where `z3` returns an error instead of a value for some of the values cbmc is attempting to get.
1 parent a3fe258 commit 2d33fde

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

src/solvers/smt2/smt2_conv.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -4415,6 +4415,7 @@ void smt2_convt::set_to(const exprt &expr, bool value)
44154415
// This is a converted expression, we can just assert the literal name
44164416
// since the expression is already defined
44174417
out << found_literal->second;
4418+
set_values[found_literal->second] = value;
44184419
}
44194420
else
44204421
{

src/solvers/smt2/smt2_conv.h

+4
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ class smt2_convt : public stack_decision_proceduret
250250

251251
typedef std::map<exprt, irep_idt> defined_expressionst;
252252
defined_expressionst defined_expressions;
253+
/// The values which boolean identifiers have been `smt2_convt::set_to` or
254+
/// in other words those which are asserted as true / false in the output
255+
/// smt2 formula.
256+
std::unordered_map<irep_idt, bool> set_values;
253257

254258
defined_expressionst object_sizes;
255259

src/solvers/smt2/smt2_dec.cpp

+20-7
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ decision_proceduret::resultt smt2_dect::read_result(std::istream &in)
139139
boolean_assignment.resize(no_boolean_variables, false);
140140

141141
typedef std::unordered_map<irep_idt, irept> valuest;
142-
valuest values;
142+
valuest parsed_values;
143143

144144
while(in)
145145
{
@@ -167,7 +167,7 @@ decision_proceduret::resultt smt2_dect::read_result(std::istream &in)
167167
// ( (|some_integer| 0) )
168168
// ( (|some_integer| (- 10)) )
169169

170-
values[s0.id()]=s1;
170+
parsed_values[s0.id()] = s1;
171171
}
172172
else if(
173173
parsed.id().empty() && parsed.get_sub().size() == 2 &&
@@ -207,16 +207,29 @@ decision_proceduret::resultt smt2_dect::read_result(std::istream &in)
207207

208208
for(auto &assignment : identifier_map)
209209
{
210-
std::string conv_id=convert_identifier(assignment.first);
211-
const irept &value=values[conv_id];
212-
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);
213213
}
214214

215215
// Booleans
216216
for(unsigned v=0; v<no_boolean_variables; v++)
217217
{
218-
const irept &value=values["B"+std::to_string(v)];
219-
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+
}();
220233
}
221234

222235
return res;

0 commit comments

Comments
 (0)