Skip to content

Commit 0937b43

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 0937b43

File tree

2 files changed

+32
-45
lines changed

2 files changed

+32
-45
lines changed

src/solvers/prop/bdd_expr.cpp

Lines changed: 32 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,25 @@ 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
108-
/// \param complement: whether we want the negation of the expression
109-
/// represented by r
110117
/// \param cache: map of already computed values
111118
exprt bdd_exprt::as_expr(
112119
const bdd_nodet &r,
113-
bool complement,
114120
std::unordered_map<bdd_nodet::idt, exprt> &cache) const
115121
{
116122
if(r.is_constant())
117123
{
118-
if(complement)
124+
if(r.is_complement())
119125
return false_exprt();
120126
else
121127
return true_exprt();
@@ -129,63 +135,45 @@ exprt bdd_exprt::as_expr(
129135
auto insert_result = cache.emplace(r.id(), nil_exprt());
130136
if(insert_result.second)
131137
{
132-
insert_result.first->second = [&]() -> exprt {
138+
auto result_ignoring_complementation = [&]() -> exprt {
133139
if(r.else_branch().is_constant())
134140
{
135141
if(r.then_branch().is_constant())
136142
{
137-
if(r.else_branch().is_complement() != complement)
143+
if(r.else_branch().is_complement()) // else is false
138144
return n_expr;
139-
return not_exprt(n_expr);
145+
return not_exprt(n_expr); // else is true
140146
}
141147
else
142148
{
143-
if(r.else_branch().is_complement() != complement)
149+
if(r.else_branch().is_complement()) // else is false
144150
{
145-
return make_and(
146-
n_expr,
147-
as_expr(
148-
r.then_branch(),
149-
complement != r.then_branch().is_complement(),
150-
cache));
151+
exprt then_case = as_expr(r.then_branch(), cache);
152+
return make_and(n_expr, then_case);
151153
}
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));
154+
exprt then_case = as_expr(r.then_branch(), cache);
155+
return make_or(not_exprt(n_expr), then_case);
158156
}
159157
}
160158
else if(r.then_branch().is_constant())
161159
{
162-
if(r.then_branch().is_complement() != complement)
160+
if(r.then_branch().is_complement()) // then is false
163161
{
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));
162+
exprt else_case = as_expr(r.else_branch(), cache);
163+
return make_and(not_exprt(n_expr), else_case);
170164
}
171-
return make_or(
172-
n_expr,
173-
as_expr(
174-
r.else_branch(),
175-
complement != r.else_branch().is_complement(),
176-
cache));
165+
exprt else_case = as_expr(r.else_branch(), cache);
166+
return make_or(n_expr, else_case);
177167
}
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));
168+
169+
exprt then_branch = as_expr(r.then_branch(), cache);
170+
exprt else_branch = as_expr(r.else_branch(), cache);
171+
return if_exprt(n_expr, then_branch, else_branch);
188172
}();
173+
174+
insert_result.first->second =
175+
r.is_complement() ? make_not(std::move(result_ignoring_complementation))
176+
: result_ignoring_complementation;
189177
}
190178
return insert_result.first->second;
191179
}
@@ -194,5 +182,5 @@ exprt bdd_exprt::as_expr(const bddt &root) const
194182
{
195183
std::unordered_map<bdd_nodet::idt, exprt> cache;
196184
bdd_nodet node = bdd_mgr.bdd_node(root);
197-
return as_expr(node, node.is_complement(), cache);
185+
return as_expr(node, cache);
198186
}

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)