Skip to content

Commit 0cad6f4

Browse files
author
Daniel Kroening
authored
Merge pull request #1062 from diffblue/fix_for_miniBDD
fix for operator< on reverse_keyt in miniBDD, fixing segfault in ebmc
2 parents 8e70eaa + ff945b3 commit 0cad6f4

File tree

5 files changed

+296
-6
lines changed

5 files changed

+296
-6
lines changed

src/solvers/miniBDD/miniBDD.cpp

+11-5
Original file line numberDiff line numberDiff line change
@@ -463,14 +463,20 @@ mini_bddt mini_bdd_mgrt::mk(
463463
}
464464

465465
bool mini_bdd_mgrt::reverse_keyt::operator<(
466-
const mini_bdd_mgrt::reverse_keyt &other) const
466+
const mini_bdd_mgrt::reverse_keyt &y) const
467467
{
468-
if(var<other.var || low<other.low)
468+
const reverse_keyt &x=*this;
469+
470+
if(x.var<y.var)
469471
return true;
470-
if(var>other.var || low>other.low)
472+
else if(x.var>y.var)
471473
return false;
472-
473-
return high<other.high;
474+
else if(x.low<y.low)
475+
return true;
476+
else if(x.low>y.low)
477+
return false;
478+
else
479+
return x.high<y.high;
474480
}
475481

476482
void mini_bdd_mgrt::DumpTable(std::ostream &out) const

src/solvers/miniBDD/miniBDD.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class mini_bdd_mgrt
124124
reverse_keyt(
125125
unsigned _var, const mini_bddt &_low, const mini_bddt &_high);
126126

127-
bool operator<(const reverse_keyt &other) const;
127+
bool operator<(const reverse_keyt &) const;
128128
};
129129

130130
typedef std::map<reverse_keyt, mini_bdd_nodet *> reverse_mapt;

src/util/invariant.h

+6
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ void report_exception_to_stderr(const invariant_failedt &);
149149
/// \param params : (variadic) parameters to forward to ET's constructor
150150
/// its backtrace member will be set before it is used.
151151
template<class ET, typename ...Params>
152+
#ifdef __GNUC__
153+
__attribute__((noreturn))
154+
#endif
152155
typename std::enable_if<std::is_base_of<invariant_failedt, ET>::value>::type
153156
invariant_violated_structured(
154157
const std::string &file,
@@ -171,6 +174,9 @@ invariant_violated_structured(
171174
/// \param function : C string giving the name of the function.
172175
/// \param line : The line number of the invariant
173176
/// \param reason : brief description of the invariant violation.
177+
#ifdef __GNUC__
178+
__attribute__((noreturn))
179+
#endif
174180
inline void invariant_violated_string(
175181
const std::string &file,
176182
const std::string &function,

unit/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ SRC += unit_tests.cpp \
1111
analyses/does_remove_const/does_expr_lose_const.cpp \
1212
analyses/does_remove_const/does_type_preserve_const_correctness.cpp \
1313
analyses/does_remove_const/is_type_at_least_as_const_as.cpp \
14+
miniBDD_new.cpp \
1415
catch_example.cpp \
1516
# Empty last line
1617

unit/miniBDD_new.cpp

+277
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for miniBDD
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Unit tests for miniBDD
11+
12+
#include <catch.hpp>
13+
14+
#include <solvers/miniBDD/miniBDD.h>
15+
#include <solvers/flattening/boolbv.h>
16+
17+
#include <util/symbol_table.h>
18+
#include <util/arith_tools.h>
19+
#include <util/expanding_vector.h>
20+
21+
#include <iostream>
22+
23+
class bdd_propt:public propt
24+
{
25+
public:
26+
mini_bdd_mgrt &mgr;
27+
28+
explicit bdd_propt(mini_bdd_mgrt &_mgr):mgr(_mgr)
29+
{
30+
// True and False
31+
bdd_map.push_back(mgr.False());
32+
bdd_map.push_back(mgr.True());
33+
}
34+
35+
mini_bddt to_bdd(literalt a)
36+
{
37+
if(a.is_true())
38+
return mgr.True();
39+
if(a.is_false())
40+
return mgr.False();
41+
INVARIANT(a.var_no()<bdd_map.size(), "literal in map");
42+
mini_bddt bdd=bdd_map[a.var_no()];
43+
INVARIANT(bdd.is_initialized(), "initialized");
44+
if(a.sign())
45+
return !bdd;
46+
else
47+
return bdd;
48+
}
49+
50+
literalt to_literal(const mini_bddt &bdd)
51+
{
52+
if(bdd.is_constant())
53+
return const_literal(bdd.is_true());
54+
std::size_t index=bdd.node_number();
55+
bdd_map[index]=bdd;
56+
return literalt(index, false);
57+
}
58+
59+
literalt land(literalt a, literalt b) override
60+
{
61+
return to_literal(to_bdd(a) & to_bdd(b));
62+
}
63+
64+
literalt lor(literalt a, literalt b) override
65+
{
66+
UNREACHABLE;
67+
}
68+
69+
literalt land(const bvt &bv) override
70+
{
71+
mini_bddt result=mgr.True();
72+
73+
for(const auto &l : bv)
74+
result=result&to_bdd(l);
75+
76+
return to_literal(result);
77+
}
78+
79+
literalt lor(const bvt &bv) override
80+
{
81+
mini_bddt result=mgr.False();
82+
83+
for(const auto &l : bv)
84+
result=result|to_bdd(l);
85+
86+
return to_literal(result);
87+
}
88+
89+
literalt lxor(literalt a, literalt b) override
90+
{
91+
return to_literal(to_bdd(a) ^ to_bdd(b));
92+
}
93+
94+
literalt lxor(const bvt &bv) override
95+
{
96+
UNREACHABLE;
97+
}
98+
99+
literalt lnand(literalt a, literalt b) override
100+
{
101+
UNREACHABLE;
102+
}
103+
104+
literalt lnor(literalt a, literalt b) override
105+
{
106+
UNREACHABLE;
107+
}
108+
109+
literalt lequal(literalt a, literalt b) override
110+
{
111+
return to_literal(to_bdd(a)==to_bdd(b));
112+
}
113+
114+
literalt limplies(literalt a, literalt b) override
115+
{
116+
UNREACHABLE;
117+
}
118+
119+
literalt lselect(literalt a, literalt b, literalt c) override
120+
{
121+
UNREACHABLE;
122+
}
123+
124+
void lcnf(const bvt &bv) override
125+
{
126+
UNREACHABLE;
127+
}
128+
129+
literalt new_variable() override
130+
{
131+
return to_literal(mgr.Var(""));
132+
}
133+
134+
size_t no_variables() const override
135+
{
136+
return bdd_map.size();
137+
}
138+
139+
const std::string solver_text() override
140+
{
141+
return "BDDs";
142+
}
143+
144+
resultt prop_solve() override
145+
{
146+
UNREACHABLE;
147+
}
148+
149+
tvt l_get(literalt a) const override
150+
{
151+
UNREACHABLE;
152+
}
153+
154+
expanding_vectort<mini_bddt> bdd_map;
155+
156+
bool has_set_to() const override { return false; }
157+
bool cnf_handled_well() const override { return false; }
158+
};
159+
160+
SCENARIO("miniBDD", "[core][solver][miniBDD]")
161+
{
162+
GIVEN("A bdd for x&!x")
163+
{
164+
symbol_tablet symbol_table;
165+
namespacet ns(symbol_table);
166+
mini_bdd_mgrt bdd_mgr;
167+
bdd_propt bdd_prop(bdd_mgr);
168+
prop_conv_solvert solver(ns, bdd_prop);
169+
170+
symbol_exprt var("x", bool_typet());
171+
literalt result=
172+
solver.convert(and_exprt(var, not_exprt(var)));
173+
174+
REQUIRE(result.is_false());
175+
}
176+
177+
GIVEN("A bdd for x&!x==0")
178+
{
179+
symbol_tablet symbol_table;
180+
namespacet ns(symbol_table);
181+
mini_bdd_mgrt bdd_mgr;
182+
bdd_propt bdd_prop(bdd_mgr);
183+
boolbvt boolbv(ns, bdd_prop);
184+
185+
unsignedbv_typet type(2);
186+
symbol_exprt var("x", type);
187+
equal_exprt equality(
188+
bitand_exprt(var, bitnot_exprt(var)),
189+
from_integer(0, type));
190+
191+
literalt result=
192+
boolbv.convert(equality);
193+
194+
REQUIRE(result.is_true());
195+
}
196+
197+
GIVEN("A bdd for x+x==1")
198+
{
199+
symbol_tablet symbol_table;
200+
namespacet ns(symbol_table);
201+
mini_bdd_mgrt bdd_mgr;
202+
bdd_propt bdd_prop(bdd_mgr);
203+
boolbvt boolbv(ns, bdd_prop);
204+
205+
unsignedbv_typet type(32);
206+
symbol_exprt var("x", type);
207+
equal_exprt equality(
208+
plus_exprt(var, var),
209+
from_integer(1, type));
210+
211+
literalt result=
212+
boolbv.convert(equality);
213+
214+
REQUIRE(result.is_false());
215+
}
216+
217+
GIVEN("A bdd for x*y==y*x")
218+
{
219+
symbol_tablet symbol_table;
220+
namespacet ns(symbol_table);
221+
mini_bdd_mgrt bdd_mgr;
222+
bdd_propt bdd_prop(bdd_mgr);
223+
boolbvt boolbv(ns, bdd_prop);
224+
225+
unsignedbv_typet type(4);
226+
symbol_exprt var_x("x", type);
227+
symbol_exprt var_y("y", type);
228+
equal_exprt equality(
229+
mult_exprt(var_x, var_y),
230+
mult_exprt(var_y, var_x));
231+
232+
literalt result=
233+
boolbv.convert(equality);
234+
235+
REQUIRE(result.is_true());
236+
}
237+
238+
GIVEN("A bdd for x*x==2")
239+
{
240+
symbol_tablet symbol_table;
241+
namespacet ns(symbol_table);
242+
mini_bdd_mgrt bdd_mgr;
243+
bdd_propt bdd_prop(bdd_mgr);
244+
boolbvt boolbv(ns, bdd_prop);
245+
246+
unsignedbv_typet type(8);
247+
symbol_exprt var_x("x", type);
248+
equal_exprt equality(
249+
mult_exprt(var_x, var_x),
250+
from_integer(2, type));
251+
252+
literalt result=
253+
boolbv.convert(equality);
254+
255+
REQUIRE(result.is_false());
256+
}
257+
258+
GIVEN("A bdd for x*x==4")
259+
{
260+
symbol_tablet symbol_table;
261+
namespacet ns(symbol_table);
262+
mini_bdd_mgrt bdd_mgr;
263+
bdd_propt bdd_prop(bdd_mgr);
264+
boolbvt boolbv(ns, bdd_prop);
265+
266+
unsignedbv_typet type(8);
267+
symbol_exprt var_x("x", type);
268+
equal_exprt equality(
269+
mult_exprt(var_x, var_x),
270+
from_integer(4, type));
271+
272+
literalt result=
273+
boolbv.convert(equality);
274+
275+
REQUIRE(!result.is_constant());
276+
}
277+
}

0 commit comments

Comments
 (0)