Skip to content

Commit 1776a9e

Browse files
Merge pull request diffblue#1950 from romainbrenguier/refactor/prop_conv_straightforward
Partial solver cleanup (straightforward changes)
2 parents 1bd9efd + 4147243 commit 1776a9e

File tree

6 files changed

+77
-150
lines changed

6 files changed

+77
-150
lines changed

src/cbmc/bv_cbmc.cpp

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,11 @@ bvt bv_cbmct::convert_waitfor(const exprt &expr)
2020
throw 0;
2121
}
2222

23-
exprt new_cycle;
2423
const exprt &old_cycle=expr.op0();
2524
const exprt &cycle_var=expr.op1();
2625
const exprt &bound=expr.op2();
2726
const exprt &predicate=expr.op3();
28-
29-
make_free_bv_expr(expr.type(), new_cycle);
27+
const exprt new_cycle = make_free_bv_expr(expr.type());
3028

3129
mp_integer bound_value;
3230
if(to_integer(bound, bound_value))
@@ -98,18 +96,9 @@ bvt bv_cbmct::convert_waitfor(const exprt &expr)
9896

9997
bvt bv_cbmct::convert_waitfor_symbol(const exprt &expr)
10098
{
101-
if(expr.operands().size()!=1)
102-
{
103-
error().source_location=expr.find_source_location();
104-
error() << "waitfor_symbol expected to have one operand" << eom;
105-
throw 0;
106-
}
107-
108-
exprt result;
99+
PRECONDITION(expr.operands().size() == 1);
109100
const exprt &bound=expr.op0();
110-
111-
make_free_bv_expr(expr.type(), result);
112-
101+
const exprt result = make_free_bv_expr(expr.type());
113102
// constraint: result<=bound
114103

115104
set_to_true(binary_relation_exprt(result, ID_le, bound));

src/solvers/flattening/boolbv.cpp

Lines changed: 17 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -631,54 +631,33 @@ bool boolbvt::boolbv_set_equality_to_true(const equal_exprt &expr)
631631

632632
void boolbvt::set_to(const exprt &expr, bool value)
633633
{
634-
if(expr.type().id()!=ID_bool)
635-
{
636-
error() << "boolbvt::set_to got non-boolean operand: "
637-
<< expr.pretty() << eom;
638-
throw 0;
639-
}
634+
PRECONDITION(expr.type().id() == ID_bool);
640635

641-
if(value)
642-
{
643-
if(expr.id()==ID_equal)
644-
{
645-
if(!boolbv_set_equality_to_true(to_equal_expr(expr)))
646-
return;
647-
}
648-
}
649-
650-
return SUB::set_to(expr, value);
636+
const auto equal_expr = expr_try_dynamic_cast<equal_exprt>(expr);
637+
if(value && equal_expr && !boolbv_set_equality_to_true(*equal_expr))
638+
return;
639+
SUB::set_to(expr, value);
651640
}
652641

653-
void boolbvt::make_bv_expr(const typet &type, const bvt &bv, exprt &dest)
642+
exprt boolbvt::make_bv_expr(const typet &type, const bvt &bv)
654643
{
655-
dest=exprt(ID_bv_literals, type);
644+
exprt dest(ID_bv_literals, type);
656645
irept::subt &bv_sub=dest.add(ID_bv).get_sub();
657-
658646
bv_sub.resize(bv.size());
659647

660648
for(std::size_t i=0; i<bv.size(); i++)
661649
bv_sub[i].id(std::to_string(bv[i].get()));
650+
return dest;
662651
}
663652

664-
void boolbvt::make_free_bv_expr(const typet &type, exprt &dest)
653+
exprt boolbvt::make_free_bv_expr(const typet &type)
665654
{
666-
std::size_t width=boolbv_width(type);
667-
668-
if(width==0)
669-
{
670-
error() << "failed to get width of " << type.pretty() << eom;
671-
throw 0;
672-
}
673-
674-
bvt bv;
675-
bv.resize(width);
676-
677-
// make result free variables
678-
Forall_literals(it, bv)
679-
*it=prop.new_variable();
680-
681-
make_bv_expr(type, bv, dest);
655+
const std::size_t width = boolbv_width(type);
656+
PRECONDITION(width != 0);
657+
bvt bv(width);
658+
for(auto &lit : bv)
659+
lit = prop.new_variable();
660+
return make_bv_expr(type, bv);
682661
}
683662

684663
bool boolbvt::is_unbounded_array(const typet &type) const
@@ -708,12 +687,8 @@ bool boolbvt::is_unbounded_array(const typet &type) const
708687
void boolbvt::print_assignment(std::ostream &out) const
709688
{
710689
arrayst::print_assignment(out);
711-
712-
for(const auto &it : map.mapping)
713-
{
714-
out << it.first << "="
715-
<< it.second.get_value(prop) << '\n';
716-
}
690+
for(const auto &pair : map.mapping)
691+
out << pair.first << "=" << pair.second.get_value(prop) << '\n';
717692
}
718693

719694
void boolbvt::build_offset_map(const struct_typet &src, offset_mapt &dest)

src/solvers/flattening/boolbv.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class boolbvt:public arrayst
9999
boolbv_mapt map;
100100

101101
// overloading
102-
virtual literalt convert_rest(const exprt &expr) override;
102+
literalt convert_rest(const exprt &expr) override;
103103
virtual bool boolbv_set_equality_to_true(const equal_exprt &expr);
104104

105105
// NOLINTNEXTLINE(readability/identifiers)
@@ -176,8 +176,8 @@ class boolbvt:public arrayst
176176
virtual bvt convert_function_application(
177177
const function_application_exprt &expr);
178178

179-
virtual void make_bv_expr(const typet &type, const bvt &bv, exprt &dest);
180-
virtual void make_free_bv_expr(const typet &type, exprt &dest);
179+
virtual exprt make_bv_expr(const typet &type, const bvt &bv);
180+
virtual exprt make_free_bv_expr(const typet &type);
181181

182182
void convert_with(
183183
const typet &type,

src/solvers/prop/prop.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ class propt:public messaget, public prop_assignmentt
8787

8888
// variables
8989
virtual literalt new_variable()=0;
90-
virtual void set_variable_name(literalt a, const std::string &name) { }
90+
virtual void set_variable_name(literalt a, const irep_idt &name) { }
9191
virtual size_t no_variables() const=0;
9292
bvt new_variables(std::size_t width);
9393

src/solvers/prop/prop_conv.cpp

Lines changed: 30 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,30 @@ Author: Daniel Kroening, [email protected]
77
\*******************************************************************/
88

99
#include "prop_conv.h"
10-
11-
#include <cassert>
12-
#include <cstdlib>
13-
#include <map>
14-
15-
#include <util/std_expr.h>
16-
#include <util/symbol.h>
17-
#include <util/threeval.h>
18-
19-
#include "prop.h"
20-
#include "literal_expr.h"
10+
#include <algorithm>
2111

2212
/// determine whether a variable is in the final conflict
2313
bool prop_convt::is_in_conflict(literalt l) const
2414
{
25-
assert(false);
15+
UNREACHABLE;
2616
return false;
2717
}
2818

2919
void prop_convt::set_assumptions(const bvt &)
3020
{
31-
assert(false);
21+
UNREACHABLE;
3222
}
3323

3424
void prop_convt::set_frozen(const literalt)
3525
{
36-
assert(false);
26+
UNREACHABLE;
3727
}
3828

3929
void prop_convt::set_frozen(const bvt &bv)
4030
{
41-
for(unsigned i=0; i<bv.size(); i++)
42-
if(!bv[i].is_constant())
43-
set_frozen(bv[i]);
31+
for(const auto &bit : bv)
32+
if(!bit.is_constant())
33+
set_frozen(bit);
4434
}
4535

4636
bool prop_conv_solvert::literal(const exprt &expr, literalt &dest) const
@@ -65,17 +55,14 @@ bool prop_conv_solvert::literal(const exprt &expr, literalt &dest) const
6555

6656
literalt prop_conv_solvert::get_literal(const irep_idt &identifier)
6757
{
68-
std::pair<symbolst::iterator, bool> result=
58+
auto result =
6959
symbols.insert(std::pair<irep_idt, literalt>(identifier, literalt()));
7060

7161
if(!result.second)
7262
return result.first->second;
7363

74-
// produce new variable
7564
literalt literal=prop.new_variable();
76-
77-
// set the name of the new variable
78-
prop.set_variable_name(literal, id2string(identifier));
65+
prop.set_variable_name(literal, identifier);
7966

8067
// insert
8168
result.first->second=literal;
@@ -183,10 +170,9 @@ literalt prop_conv_solvert::convert(const exprt &expr)
183170
prop.set_frozen(literal);
184171
return literal;
185172
}
186-
// check cache first
187173

188-
std::pair<cachet::iterator, bool> result=
189-
cache.insert(std::pair<exprt, literalt>(expr, literalt()));
174+
// check cache first
175+
auto result = cache.insert({expr, literalt()});
190176

191177
if(!result.second)
192178
return result.first->second;
@@ -208,13 +194,7 @@ literalt prop_conv_solvert::convert(const exprt &expr)
208194

209195
literalt prop_conv_solvert::convert_bool(const exprt &expr)
210196
{
211-
if(expr.type().id()!=ID_bool)
212-
{
213-
std::string msg="prop_convt::convert_bool got "
214-
"non-boolean expression: ";
215-
msg+=expr.pretty();
216-
throw msg;
217-
}
197+
PRECONDITION(expr.type().id() == ID_bool);
218198

219199
const exprt::operandst &op=expr.operands();
220200

@@ -280,8 +260,9 @@ literalt prop_conv_solvert::convert_bool(const exprt &expr)
280260
else if(expr.id()==ID_or || expr.id()==ID_and || expr.id()==ID_xor ||
281261
expr.id()==ID_nor || expr.id()==ID_nand)
282262
{
283-
if(op.empty())
284-
throw "operator `"+expr.id_string()+"' takes at least one operand";
263+
INVARIANT(
264+
!op.empty(),
265+
"operator `" + expr.id_string() + "' takes at least one operand");
285266

286267
bvt bv;
287268

@@ -304,16 +285,12 @@ literalt prop_conv_solvert::convert_bool(const exprt &expr)
304285
}
305286
else if(expr.id()==ID_not)
306287
{
307-
if(op.size()!=1)
308-
throw "not takes one operand";
309-
288+
INVARIANT(op.size() == 1, "not takes one operand");
310289
return !convert(op.front());
311290
}
312291
else if(expr.id()==ID_equal || expr.id()==ID_notequal)
313292
{
314-
if(op.size()!=2)
315-
throw "equality takes two operands";
316-
293+
INVARIANT(op.size() == 2, "equality takes two operands");
317294
bool equal=(expr.id()==ID_equal);
318295

319296
if(op[0].type().id()==ID_bool &&
@@ -387,24 +364,14 @@ bool prop_conv_solvert::set_equality_to_true(const equal_exprt &expr)
387364

388365
void prop_conv_solvert::set_to(const exprt &expr, bool value)
389366
{
390-
if(expr.type().id()!=ID_bool)
391-
{
392-
std::string msg="prop_convt::set_to got "
393-
"non-boolean expression: ";
394-
msg+=expr.pretty();
395-
throw msg;
396-
}
367+
PRECONDITION(expr.type().id() == ID_bool);
397368

398-
bool boolean=true;
399-
400-
forall_operands(it, expr)
401-
if(it->type().id()!=ID_bool)
402-
{
403-
boolean=false;
404-
break;
405-
}
369+
const bool has_only_boolean_operands = std::all_of(
370+
expr.operands().begin(),
371+
expr.operands().end(),
372+
[](const exprt &expr) { return expr.type().id() == ID_bool; });
406373

407-
if(boolean)
374+
if(has_only_boolean_operands)
408375
{
409376
if(expr.id()==ID_not)
410377
{
@@ -507,16 +474,12 @@ decision_proceduret::resultt prop_conv_solvert::dec_solve()
507474

508475
statistics() << "Solving with " << prop.solver_text() << eom;
509476

510-
propt::resultt result=prop.prop_solve();
511-
512-
switch(result)
477+
switch(prop.prop_solve())
513478
{
514479
case propt::resultt::P_SATISFIABLE: return resultt::D_SATISFIABLE;
515480
case propt::resultt::P_UNSATISFIABLE: return resultt::D_UNSATISFIABLE;
516481
default: return resultt::D_ERROR;
517482
}
518-
519-
return resultt::D_ERROR;
520483
}
521484

522485
exprt prop_conv_solvert::get(const exprt &expr) const
@@ -534,19 +497,17 @@ exprt prop_conv_solvert::get(const exprt &expr) const
534497
}
535498
}
536499

537-
exprt tmp=expr;
538-
539-
Forall_operands(it, tmp)
500+
exprt tmp = expr;
501+
for(auto &op : tmp.operands())
540502
{
541-
exprt tmp_op=get(*it);
542-
it->swap(tmp_op);
503+
exprt tmp_op = get(op);
504+
op.swap(tmp_op);
543505
}
544-
545506
return tmp;
546507
}
547508

548509
void prop_conv_solvert::print_assignment(std::ostream &out) const
549510
{
550-
for(const auto &it : symbols)
551-
out << it.first << " = " << prop.l_get(it.second) << "\n";
511+
for(const auto &symbol : symbols)
512+
out << symbol.first << " = " << prop.l_get(symbol.second) << '\n';
552513
}

0 commit comments

Comments
 (0)