@@ -103,19 +103,25 @@ static exprt make_or(exprt a, exprt b)
103
103
return or_exprt{std::move (a), std::move (b)};
104
104
}
105
105
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
+
106
115
// / Helper function for \c bddt to \c exprt conversion
107
116
// / \param r: node to convert
108
- // / \param complement: whether we want the negation of the expression
109
- // / represented by r
110
117
// / \param cache: map of already computed values
111
118
exprt bdd_exprt::as_expr (
112
119
const bdd_nodet &r,
113
- bool complement,
114
120
std::unordered_map<bdd_nodet::idt, exprt> &cache) const
115
121
{
116
122
if (r.is_constant ())
117
123
{
118
- if (complement )
124
+ if (r. is_complement () )
119
125
return false_exprt ();
120
126
else
121
127
return true_exprt ();
@@ -129,63 +135,45 @@ exprt bdd_exprt::as_expr(
129
135
auto insert_result = cache.emplace (r.id (), nil_exprt ());
130
136
if (insert_result.second )
131
137
{
132
- insert_result. first -> second = [&]() -> exprt {
138
+ auto result_ignoring_complementation = [&]() -> exprt {
133
139
if (r.else_branch ().is_constant ())
134
140
{
135
141
if (r.then_branch ().is_constant ())
136
142
{
137
- if (r.else_branch ().is_complement () != complement)
143
+ if (r.else_branch ().is_complement ()) // else is false
138
144
return n_expr;
139
- return not_exprt (n_expr);
145
+ return not_exprt (n_expr); // else is true
140
146
}
141
147
else
142
148
{
143
- if (r.else_branch ().is_complement () != complement)
149
+ if (r.else_branch ().is_complement ()) // else is false
144
150
{
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);
151
153
}
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);
158
156
}
159
157
}
160
158
else if (r.then_branch ().is_constant ())
161
159
{
162
- if (r.then_branch ().is_complement () != complement)
160
+ if (r.then_branch ().is_complement ()) // then is false
163
161
{
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);
170
164
}
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);
177
167
}
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);
188
172
}();
173
+
174
+ insert_result.first ->second =
175
+ r.is_complement () ? make_not (std::move (result_ignoring_complementation))
176
+ : result_ignoring_complementation;
189
177
}
190
178
return insert_result.first ->second ;
191
179
}
@@ -194,5 +182,5 @@ exprt bdd_exprt::as_expr(const bddt &root) const
194
182
{
195
183
std::unordered_map<bdd_nodet::idt, exprt> cache;
196
184
bdd_nodet node = bdd_mgr.bdd_node (root);
197
- return as_expr (node, node. is_complement (), cache);
185
+ return as_expr (node, cache);
198
186
}
0 commit comments