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