Skip to content

Commit fedc957

Browse files
Remove is_complement argument of bdd_exprt::as_exprt
Because of how the cache is handled, the expression for one node and its complement will collide in the cache. It is better to get rid of the complement argument and only reason about nodes.
1 parent 06ef36d commit fedc957

File tree

2 files changed

+32
-43
lines changed

2 files changed

+32
-43
lines changed

src/solvers/prop/bdd_expr.cpp

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,27 @@ static exprt make_or(exprt a, exprt b)
103103
return or_exprt{std::move(a), std::move(b)};
104104
}
105105

106+
/// Negation of an expression.
107+
/// If \p a is already of the form `not b` then return b.
108+
static exprt make_not(exprt a)
109+
{
110+
if(a.id() == ID_not)
111+
return a.op0();
112+
return not_exprt{a};
113+
}
114+
106115
/// Helper function for \c bddt to \c exprt conversion
107116
/// \param r: node to convert
108117
/// \param complement: whether we want the negation of the expression
109118
/// represented by r
110119
/// \param cache: map of already computed values
111120
exprt bdd_exprt::as_expr(
112121
const bdd_nodet &r,
113-
bool complement,
114122
std::unordered_map<bdd_nodet::idt, exprt> &cache) const
115123
{
116124
if(r.is_constant())
117125
{
118-
if(complement)
126+
if(r.is_complement())
119127
return false_exprt();
120128
else
121129
return true_exprt();
@@ -129,63 +137,45 @@ exprt bdd_exprt::as_expr(
129137
auto insert_result = cache.emplace(r.id(), nil_exprt());
130138
if(insert_result.second)
131139
{
132-
insert_result.first->second = [&]() -> exprt {
140+
auto result_ignoring_complementation = [&]() -> exprt {
133141
if(r.else_branch().is_constant())
134142
{
135143
if(r.then_branch().is_constant())
136144
{
137-
if(r.else_branch().is_complement() != complement)
145+
if(r.else_branch().is_complement()) // else is false
138146
return n_expr;
139-
return not_exprt(n_expr);
147+
return not_exprt(n_expr); // else is true
140148
}
141149
else
142150
{
143-
if(r.else_branch().is_complement() != complement)
151+
if(r.else_branch().is_complement()) // else is false
144152
{
145-
return make_and(
146-
n_expr,
147-
as_expr(
148-
r.then_branch(),
149-
complement != r.then_branch().is_complement(),
150-
cache));
153+
exprt then_case = as_expr(r.then_branch(), cache);
154+
return make_and(n_expr, then_case);
151155
}
152-
return make_or(
153-
not_exprt(n_expr),
154-
as_expr(
155-
r.then_branch(),
156-
complement != r.then_branch().is_complement(),
157-
cache));
156+
exprt then_case = as_expr(r.then_branch(), cache);
157+
return make_or(not_exprt(n_expr), then_case);
158158
}
159159
}
160160
else if(r.then_branch().is_constant())
161161
{
162-
if(r.then_branch().is_complement() != complement)
162+
if(r.then_branch().is_complement()) // then is false
163163
{
164-
return make_and(
165-
not_exprt(n_expr),
166-
as_expr(
167-
r.else_branch(),
168-
complement != r.else_branch().is_complement(),
169-
cache));
164+
exprt else_case = as_expr(r.else_branch(), cache);
165+
return make_and(not_exprt(n_expr), else_case);
170166
}
171-
return make_or(
172-
n_expr,
173-
as_expr(
174-
r.else_branch(),
175-
complement != r.else_branch().is_complement(),
176-
cache));
167+
exprt else_case = as_expr(r.else_branch(), cache);
168+
return make_or(n_expr, else_case);
177169
}
178-
return if_exprt(
179-
n_expr,
180-
as_expr(
181-
r.then_branch(),
182-
r.then_branch().is_complement() != complement,
183-
cache),
184-
as_expr(
185-
r.else_branch(),
186-
r.else_branch().is_complement() != complement,
187-
cache));
170+
171+
exprt then_branch = as_expr(r.then_branch(), cache);
172+
exprt else_branch = as_expr(r.else_branch(), cache);
173+
return if_exprt(n_expr, then_branch, else_branch);
188174
}();
175+
176+
insert_result.first->second =
177+
r.is_complement() ? make_not(std::move(result_ignoring_complementation))
178+
: result_ignoring_complementation;
189179
}
190180
return insert_result.first->second;
191181
}
@@ -194,5 +184,5 @@ exprt bdd_exprt::as_expr(const bddt &root) const
194184
{
195185
std::unordered_map<bdd_nodet::idt, exprt> cache;
196186
bdd_nodet node = bdd_mgr.bdd_node(root);
197-
return as_expr(node, node.is_complement(), cache);
187+
return as_expr(node, cache);
198188
}

src/solvers/prop/bdd_expr.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ class bdd_exprt
5050
bddt from_expr_rec(const exprt &expr);
5151
exprt as_expr(
5252
const bdd_nodet &r,
53-
bool complement,
5453
std::unordered_map<bdd_nodet::idt, exprt> &cache) const;
5554
};
5655

0 commit comments

Comments
 (0)