@@ -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
200200protected:
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,125 @@ 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+ default :
338+ assert (false );
339+ }
340+ }
341+
342+ assert (u.is_initialized ());
343+
344+ return u;
345+ }
346+
243347bool equal_fkt (bool x, bool y)
244348{
245349 return x==y;
0 commit comments