Skip to content

Commit bda4ec5

Browse files
author
Daniel Kroening
committed
added a non-recursive variant of APPLY
1 parent 71e973c commit bda4ec5

File tree

1 file changed

+110
-9
lines changed

1 file changed

+110
-9
lines changed

src/solvers/miniBDD/miniBDD.cpp

+110-9
Original file line numberDiff line numberDiff line change
@@ -194,18 +194,19 @@ class mini_bdd_applyt
194194

195195
mini_bddt operator()(const mini_bddt &x, const mini_bddt &y)
196196
{
197-
return APP(x, y);
197+
return APP_non_rec(x, y);
198198
}
199199

200200
protected:
201201
bool (*fkt)(bool, bool);
202-
mini_bddt APP(const mini_bddt &x, const mini_bddt &y);
202+
mini_bddt APP_rec(const mini_bddt &x, const mini_bddt &y);
203+
mini_bddt APP_non_rec(const mini_bddt &x, const mini_bddt &y);
203204

204205
typedef std::map<std::pair<unsigned, unsigned>, mini_bddt> Gt;
205206
Gt G;
206207
};
207208

208-
mini_bddt mini_bdd_applyt::APP(const mini_bddt &x, const mini_bddt &y)
209+
mini_bddt mini_bdd_applyt::APP_rec(const mini_bddt &x, const mini_bddt &y)
209210
{
210211
assert(x.is_initialized() && y.is_initialized());
211212
assert(x.node->mgr==y.node->mgr);
@@ -224,22 +225,122 @@ mini_bddt mini_bdd_applyt::APP(const mini_bddt &x, const mini_bddt &y)
224225
u=mini_bddt(fkt(x.is_true(), y.is_true())?mgr->True():mgr->False());
225226
else if(x.var()==y.var())
226227
u=mgr->mk(x.var(),
227-
APP(x.low(), y.low()),
228-
APP(x.high(), y.high()));
228+
APP_rec(x.low(), y.low()),
229+
APP_rec(x.high(), y.high()));
229230
else if(x.var()<y.var())
230231
u=mgr->mk(x.var(),
231-
APP(x.low(), y),
232-
APP(x.high(), y));
232+
APP_rec(x.low(), y),
233+
APP_rec(x.high(), y));
233234
else /* x.var() > y.var() */
234235
u=mgr->mk(y.var(),
235-
APP(x, y.low()),
236-
APP(x, y.high()));
236+
APP_rec(x, y.low()),
237+
APP_rec(x, y.high()));
237238

238239
G[key]=u;
239240

240241
return u;
241242
}
242243

244+
mini_bddt mini_bdd_applyt::APP_non_rec(
245+
const mini_bddt &_x,
246+
const mini_bddt &_y)
247+
{
248+
struct stack_elementt
249+
{
250+
stack_elementt(
251+
mini_bddt &_result,
252+
const mini_bddt &_x,
253+
const mini_bddt &_y):
254+
result(_result), x(_x), y(_y), var(0), phase(phaset::INIT) { }
255+
mini_bddt &result, x, y, lr, hr;
256+
std::pair<unsigned, unsigned> key;
257+
unsigned var;
258+
enum class phaset { INIT, FINISH } phase;
259+
};
260+
261+
mini_bddt u; // return value
262+
263+
std::stack<stack_elementt> stack;
264+
stack.push(stack_elementt(u, _x, _y));
265+
266+
while(!stack.empty())
267+
{
268+
auto &t=stack.top();
269+
const mini_bddt &x=t.x;
270+
const mini_bddt &y=t.y;
271+
assert(x.is_initialized() && y.is_initialized());
272+
assert(x.node->mgr==y.node->mgr);
273+
274+
switch(t.phase)
275+
{
276+
case stack_elementt::phaset::INIT:
277+
{
278+
// dynamic programming
279+
t.key=std::pair<unsigned, unsigned>(x.node_number(), y.node_number());
280+
Gt::const_iterator G_it=G.find(t.key);
281+
if(G_it!=G.end())
282+
{
283+
t.result=G_it->second;
284+
stack.pop();
285+
}
286+
else
287+
{
288+
if(x.is_constant() && y.is_constant())
289+
{
290+
bool result_truth=fkt(x.is_true(), y.is_true());
291+
const mini_bdd_mgrt &mgr=*x.node->mgr;
292+
t.result=result_truth?mgr.True():mgr.False();
293+
stack.pop();
294+
}
295+
else if(x.var()==y.var())
296+
{
297+
t.var=x.var();
298+
t.phase=stack_elementt::phaset::FINISH;
299+
assert(x.low().var()>t.var);
300+
assert(y.low().var()>t.var);
301+
assert(x.high().var()>t.var);
302+
assert(y.high().var()>t.var);
303+
stack.push(stack_elementt(t.lr, x.low(), y.low()));
304+
stack.push(stack_elementt(t.hr, x.high(), y.high()));
305+
}
306+
else if(x.var()<y.var())
307+
{
308+
t.var=x.var();
309+
t.phase=stack_elementt::phaset::FINISH;
310+
assert(x.low().var()>t.var);
311+
assert(x.high().var()>t.var);
312+
stack.push(stack_elementt(t.lr, x.low(), y));
313+
stack.push(stack_elementt(t.hr, x.high(), y));
314+
}
315+
else /* x.var() > y.var() */
316+
{
317+
t.var=y.var();
318+
t.phase=stack_elementt::phaset::FINISH;
319+
assert(y.low().var()>t.var);
320+
assert(y.high().var()>t.var);
321+
stack.push(stack_elementt(t.lr, x, y.low()));
322+
stack.push(stack_elementt(t.hr, x, y.high()));
323+
}
324+
}
325+
}
326+
break;
327+
328+
case stack_elementt::phaset::FINISH:
329+
{
330+
mini_bdd_mgrt *mgr=x.node->mgr;
331+
t.result=mgr->mk(t.var, t.lr, t.hr);
332+
G[t.key]=t.result;
333+
stack.pop();
334+
}
335+
break;
336+
}
337+
}
338+
339+
assert(u.is_initialized());
340+
341+
return u;
342+
}
343+
243344
bool equal_fkt(bool x, bool y)
244345
{
245346
return x==y;

0 commit comments

Comments
 (0)