@@ -194,18 +194,19 @@ class mini_bdd_applyt
194
194
195
195
mini_bddt operator ()(const mini_bddt &x, const mini_bddt &y)
196
196
{
197
- return APP (x, y);
197
+ return APP_non_rec (x, y);
198
198
}
199
199
200
200
protected:
201
201
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);
203
204
204
205
typedef std::map<std::pair<unsigned , unsigned >, mini_bddt> Gt;
205
206
Gt G;
206
207
};
207
208
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)
209
210
{
210
211
assert (x.is_initialized () && y.is_initialized ());
211
212
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)
224
225
u=mini_bddt (fkt (x.is_true (), y.is_true ())?mgr->True ():mgr->False ());
225
226
else if (x.var ()==y.var ())
226
227
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 ()));
229
230
else if (x.var ()<y.var ())
230
231
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));
233
234
else /* x.var() > y.var() */
234
235
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 ()));
237
238
238
239
G[key]=u;
239
240
240
241
return u;
241
242
}
242
243
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
+
243
344
bool equal_fkt (bool x, bool y)
244
345
{
245
346
return x==y;
0 commit comments