nysol-zdd 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/ext/zdd_so/BDD.cc +495 -0
  3. data/ext/zdd_so/BDD.h +356 -0
  4. data/ext/zdd_so/BDDDG.cc +1818 -0
  5. data/ext/zdd_so/BDDDG.h +107 -0
  6. data/ext/zdd_so/BDDHASH.cc +91 -0
  7. data/ext/zdd_so/BtoI.cc +503 -0
  8. data/ext/zdd_so/BtoI.h +144 -0
  9. data/ext/zdd_so/CtoI.cc +1072 -0
  10. data/ext/zdd_so/CtoI.h +186 -0
  11. data/ext/zdd_so/MLZBDDV.cc +153 -0
  12. data/ext/zdd_so/MLZBDDV.h +42 -0
  13. data/ext/zdd_so/SOP.cc +608 -0
  14. data/ext/zdd_so/SOP.h +199 -0
  15. data/ext/zdd_so/ZBDD.cc +1035 -0
  16. data/ext/zdd_so/ZBDD.h +243 -0
  17. data/ext/zdd_so/ZBDDDG.cc +1834 -0
  18. data/ext/zdd_so/ZBDDDG.h +105 -0
  19. data/ext/zdd_so/ZBDDHASH.cc +91 -0
  20. data/ext/zdd_so/bddc.c +2816 -0
  21. data/ext/zdd_so/bddc.h +132 -0
  22. data/ext/zdd_so/extconf.rb +25 -0
  23. data/ext/zdd_so/include/aheap.c +211 -0
  24. data/ext/zdd_so/include/aheap.h +111 -0
  25. data/ext/zdd_so/include/base.c +93 -0
  26. data/ext/zdd_so/include/base.h +60 -0
  27. data/ext/zdd_so/include/itemset.c +473 -0
  28. data/ext/zdd_so/include/itemset.h +153 -0
  29. data/ext/zdd_so/include/problem.c +371 -0
  30. data/ext/zdd_so/include/problem.h +160 -0
  31. data/ext/zdd_so/include/queue.c +518 -0
  32. data/ext/zdd_so/include/queue.h +177 -0
  33. data/ext/zdd_so/include/sgraph.c +331 -0
  34. data/ext/zdd_so/include/sgraph.h +170 -0
  35. data/ext/zdd_so/include/stdlib2.c +832 -0
  36. data/ext/zdd_so/include/stdlib2.h +746 -0
  37. data/ext/zdd_so/include/trsact.c +723 -0
  38. data/ext/zdd_so/include/trsact.h +167 -0
  39. data/ext/zdd_so/include/vec.c +583 -0
  40. data/ext/zdd_so/include/vec.h +159 -0
  41. data/ext/zdd_so/lcm-vsop.cc +596 -0
  42. data/ext/zdd_so/print.cc +683 -0
  43. data/ext/zdd_so/table.cc +330 -0
  44. data/ext/zdd_so/vsop.h +88 -0
  45. data/ext/zdd_so/zdd_so.cpp +3277 -0
  46. data/lib/nysol/zdd.rb +31 -0
  47. metadata +131 -0
@@ -0,0 +1,356 @@
1
+ /********************************************
2
+ * BDD+ Manipulator (SAPPORO-1.59) - Header *
3
+ * (C) Shin-ichi MINATO (Dec. 10, 2013) *
4
+ ********************************************/
5
+
6
+ class BDD;
7
+ class BDDV;
8
+
9
+ #ifndef _BDD_
10
+ #define _BDD_
11
+
12
+ #include <cstdlib>
13
+ #include <cstdio>
14
+ #include <cstring>
15
+ #include <cctype>
16
+ #include <iostream>
17
+
18
+ #define BDD_CPP
19
+ #include "bddc.h"
20
+
21
+ //--------- Definition of "bddword" type --------
22
+ #ifdef B_64
23
+ typedef unsigned long long bddword;
24
+ #else
25
+ typedef unsigned int bddword;
26
+ #endif
27
+
28
+ //--------- External data for BDD ---------
29
+ extern const bddword BDD_MaxNode;
30
+ extern const int BDD_MaxVar;
31
+
32
+ //----- External constant data for BDDV ---------
33
+ extern int BDDV_Active;
34
+ extern const int BDDV_SysVarTop;
35
+ extern const int BDDV_MaxLen;
36
+ extern const int BDDV_MaxLenImport;
37
+
38
+ //--------- Stack overflow limitter ---------
39
+ extern const int BDD_RecurLimit;
40
+ extern int BDD_RecurCount;
41
+ #define BDD_RECUR_INC \
42
+ {if(++BDD_RecurCount >= BDD_RecurLimit) \
43
+ BDDerr("BDD_RECUR_INC:Stack overflow ", (bddword) BDD_RecurCount);}
44
+ #define BDD_RECUR_DEC BDD_RecurCount--
45
+
46
+ class BDD
47
+ {
48
+ bddword _bdd;
49
+
50
+ public:
51
+ BDD(void) { _bdd = bddfalse; }
52
+ BDD(int a) { _bdd = (a==0)? bddfalse:(a>0)? bddtrue:bddnull; }
53
+ BDD(const BDD& f) { _bdd = bddcopy(f._bdd); }
54
+
55
+ ~BDD(void) { bddfree(_bdd); }
56
+
57
+ BDD& operator=(const BDD& f) {
58
+ if(_bdd != f._bdd) { bddfree(_bdd); _bdd = bddcopy(f._bdd); }
59
+ return *this;
60
+ }
61
+
62
+ BDD& operator&=(const BDD& f)
63
+ { BDD h; h._bdd = bddand(_bdd, f._bdd); return *this = h; }
64
+ BDD& operator|=(const BDD& f)
65
+ { BDD h; h._bdd = bddor(_bdd, f._bdd); return *this = h; }
66
+ BDD& operator^=(const BDD& f)
67
+ { BDD h; h._bdd = bddxor(_bdd, f._bdd); return *this = h; }
68
+ BDD& operator<<=(const int s)
69
+ { BDD h; h._bdd = bddlshift(_bdd, s); return *this = h; }
70
+ BDD& operator>>=(const int s)
71
+ { BDD h; h._bdd = bddrshift(_bdd, s); return *this = h; }
72
+
73
+ BDD operator~(void) const { BDD h; h._bdd = bddnot(_bdd); return h; }
74
+ BDD operator<<(int s) const
75
+ { BDD h; h._bdd = bddlshift(_bdd, s); return h; }
76
+ BDD operator>>(int s) const
77
+ { BDD h; h._bdd = bddrshift(_bdd, s); return h; }
78
+
79
+ int Top(void) const { return bddtop(_bdd); }
80
+ BDD At0(int v) const { BDD h; h._bdd = bddat0(_bdd, v); return h; }
81
+ BDD At1(int v) const { BDD h; h._bdd = bddat1(_bdd, v); return h; }
82
+ BDD Cofact(const BDD& f) const
83
+ { BDD h; h._bdd = bddcofactor(_bdd, f._bdd); return h; }
84
+ BDD Univ(const BDD& f) const
85
+ { BDD h; h._bdd = bdduniv(_bdd, f._bdd); return h; }
86
+ BDD Exist(const BDD& f) const
87
+ { BDD h; h._bdd = bddexist(_bdd, f._bdd); return h; }
88
+ BDD Support(void) const
89
+ { BDD h; h._bdd = bddsupport(_bdd); return h; }
90
+
91
+ bddword GetID(void) const {return _bdd; }
92
+
93
+ bddword Size(void) const;
94
+ void Export(FILE *strm = stdout) const;
95
+ void Print(void) const;
96
+ void XPrint0(void) const;
97
+ void XPrint(void) const;
98
+
99
+ BDD Swap(const int&, const int&) const;
100
+ BDD Smooth(const int&) const;
101
+ BDD Spread(const int&) const;
102
+
103
+ friend BDD BDD_ID(bddword);
104
+ };
105
+
106
+ //--------- External functions for BDD ---------
107
+ extern void BDD_Init(bddword, bddword);
108
+ extern int BDD_NewVarOfLev(int);
109
+ extern int BDD_VarUsed(void);
110
+ extern bddword BDD_Used(void);
111
+ extern void BDD_GC(void);
112
+ extern BDD BDD_Import(FILE *strm = stdin);
113
+ extern BDD BDD_Random(int, int density = 50);
114
+ extern void BDDerr(const char *);
115
+ extern void BDDerr(const char *, bddword);
116
+ extern void BDDerr(const char *, const char *);
117
+
118
+ //--------- Inline functions for BDD ---------
119
+ inline int BDD_TopLev(void)
120
+ { return BDDV_Active? bddvarused() - BDDV_SysVarTop: bddvarused(); }
121
+
122
+ inline int BDD_NewVar(void)
123
+ { return bddnewvaroflev(BDD_TopLev() + 1); }
124
+
125
+ inline int BDD_LevOfVar(int v) { return bddlevofvar(v); }
126
+ inline int BDD_VarOfLev(int lev) { return bddvaroflev(lev); }
127
+
128
+ inline BDD BDD_ID(bddword bdd)
129
+ { BDD h; h._bdd = bdd; return h; }
130
+
131
+ inline bddword BDD_CacheInt(unsigned char op, bddword fx, bddword gx)
132
+ { return bddrcache(op, fx, gx); }
133
+
134
+ inline BDD BDD_CacheBDD(unsigned char op, bddword fx, bddword gx)
135
+ { return BDD_ID(bddcopy(bddrcache(op, fx, gx))); }
136
+
137
+ inline void BDD_CacheEnt(unsigned char op, bddword fx, bddword gx, bddword hx)
138
+ { bddwcache(op, fx, gx, hx); }
139
+
140
+ inline BDD BDDvar(int v) { return BDD_ID(bddprime(v)); }
141
+
142
+ inline BDD operator&(const BDD& f, const BDD& g)
143
+ { return BDD_ID(bddand(f.GetID(), g.GetID())); }
144
+
145
+ inline BDD operator|(const BDD& f, const BDD& g)
146
+ { return BDD_ID(bddor(f.GetID(), g.GetID())); }
147
+
148
+ inline BDD operator^(const BDD& f, const BDD& g)
149
+ { return BDD_ID(bddxor(f.GetID(), g.GetID())); }
150
+
151
+ inline int operator==(const BDD& f, const BDD& g)
152
+ { return f.GetID() == g.GetID(); }
153
+
154
+ inline int operator!=(const BDD& f, const BDD& g)
155
+ { return f.GetID() != g.GetID(); }
156
+
157
+ inline int BDD_Imply(const BDD& f, const BDD& g)
158
+ { return bddimply(f.GetID(), g.GetID()); }
159
+
160
+ class BDDV
161
+ {
162
+ BDD _bdd;
163
+ int _len;
164
+ int _lev;
165
+
166
+ int GetLev(int len) const {
167
+ int lev = 0;
168
+ for(len--; len>0; len>>=1) lev++;
169
+ return lev;
170
+ }
171
+
172
+ public:
173
+ BDDV(void) { _bdd = 0; _len = 0; _lev = 0; }
174
+
175
+ BDDV(const BDDV& fv)
176
+ { _bdd = fv._bdd; _len = fv._len; _lev = fv._lev; }
177
+
178
+ BDDV(const BDD& f) {
179
+ int t = f.Top();
180
+ if(t > 0 && BDD_LevOfVar(t) > BDD_TopLev())
181
+ BDDerr("BDDV::BDDV: Invalid top var.", t);
182
+ _bdd = f;
183
+ _len = 1;
184
+ _lev = 0;
185
+ }
186
+
187
+ BDDV(const BDD&, int len);
188
+
189
+ ~BDDV(void) { }
190
+
191
+ BDDV& operator=(const BDDV& fv)
192
+ { _bdd = fv._bdd; _len = fv._len; _lev = fv._lev; return *this; }
193
+
194
+ BDDV& operator&=(const BDDV&);
195
+ BDDV& operator|=(const BDDV&);
196
+ BDDV& operator^=(const BDDV&);
197
+ BDDV& operator<<=(int);
198
+ BDDV& operator>>=(int);
199
+
200
+ BDDV operator~(void) const
201
+ { BDDV h; h._bdd = ~_bdd; h._len = _len; h._lev = _lev; return h; }
202
+ BDDV operator<<(int) const;
203
+ BDDV operator>>(int) const;
204
+
205
+ BDDV At0(int v) const {
206
+ if(v > 0 && BDD_LevOfVar(v) > BDD_TopLev())
207
+ BDDerr("BDDV::At0: Invalid var.", v);
208
+ BDDV hv;
209
+ if((hv._bdd = _bdd.At0(v)) == -1) return BDDV(-1);
210
+ hv._len = _len;
211
+ hv._lev = _lev;
212
+ return hv;
213
+ }
214
+
215
+ BDDV At1(int v) const {
216
+ if(v > 0 && BDD_LevOfVar(v) > BDD_TopLev())
217
+ BDDerr("BDDV::At1: Invalid var.", v);
218
+ BDDV hv;
219
+ if((hv._bdd = _bdd.At1(v)) == -1) return BDDV(-1);
220
+ hv._len = _len;
221
+ hv._lev = _lev;
222
+ return hv;
223
+ }
224
+
225
+ BDDV Cofact(const BDDV&) const;
226
+ BDDV Swap(int, int) const;
227
+ BDDV Spread(int) const;
228
+
229
+ int Top(void) const;
230
+
231
+ bddword Size() const;
232
+ void Export(FILE *strm = stdout) const;
233
+
234
+ BDDV Former(void) const {
235
+ BDDV hv;
236
+ if(_len <= 1) return hv;
237
+ if((hv._bdd = _bdd.At0(_lev)) == -1) return BDDV(-1);
238
+ hv._len = 1 << (_lev - 1);
239
+ hv._lev = _lev - 1;
240
+ return hv;
241
+ }
242
+
243
+ BDDV Latter(void) const {
244
+ BDDV hv;
245
+ if(_len == 0) return hv;
246
+ if(_len == 1) return *this;
247
+ if((hv._bdd = _bdd.At1(_lev)) == -1) return BDDV(-1);
248
+ hv._len = _len - (1 << (_lev - 1));
249
+ hv._lev = GetLev(hv._len);
250
+ return hv;
251
+ }
252
+
253
+ BDDV Part(int, int) const;
254
+ BDD GetBDD(int) const;
255
+
256
+ BDD GetMetaBDD(void) const { return _bdd; }
257
+ int Uniform(void) const
258
+ { return BDD_LevOfVar(_bdd.Top()) <= BDD_TopLev(); }
259
+ int Len(void) const { return _len; }
260
+
261
+ void Print() const;
262
+ void XPrint0() const;
263
+ void XPrint() const;
264
+
265
+ friend BDDV operator&(const BDDV&, const BDDV&);
266
+ friend BDDV operator|(const BDDV&, const BDDV&);
267
+ friend BDDV operator^(const BDDV&, const BDDV&);
268
+ friend BDDV operator||(const BDDV&, const BDDV&);
269
+ };
270
+
271
+ //----- External functions for BDDV ---------
272
+ extern void BDDV_Init(bddword, bddword);
273
+ extern int BDDV_NewVarOfLev(int);
274
+ extern BDDV operator||(const BDDV&, const BDDV&);
275
+ extern BDDV BDDV_Mask1(int, int);
276
+ extern BDDV BDDV_Mask2(int, int);
277
+ extern BDDV BDDV_Import(FILE *strm = stdin);
278
+
279
+ //----- Inline functions for BDDV ---------
280
+ inline int BDDV_UserTopLev(void) { return BDD_TopLev(); }
281
+ inline int BDDV_NewVar(void) { return BDD_NewVar(); }
282
+ inline int BDDV_NewVarOfLev(int lev) {return BDD_NewVarOfLev(lev); }
283
+
284
+ inline BDDV operator&(const BDDV& fv, const BDDV& gv) {
285
+ BDDV hv;
286
+ if((hv._bdd = fv._bdd & gv._bdd) == -1) return BDDV(-1);
287
+ if(fv._len != gv._len) BDDerr("BDDV::operator&: Length mismatch");
288
+ hv._len = fv._len;
289
+ hv._lev = fv._lev;
290
+ return hv;
291
+ }
292
+
293
+ inline BDDV operator|(const BDDV& fv, const BDDV& gv) {
294
+ BDDV hv;
295
+ if((hv._bdd = fv._bdd | gv._bdd) == -1) return BDDV(-1);
296
+ if(fv._len != gv._len) BDDerr("BDDV::operator|: Length mismatch");
297
+ hv._len = fv._len;
298
+ hv._lev = fv._lev;
299
+ return hv;
300
+ }
301
+
302
+ inline BDDV operator^(const BDDV& fv, const BDDV& gv) {
303
+ BDDV hv;
304
+ if((hv._bdd = fv._bdd ^ gv._bdd) == -1) return BDDV(-1);
305
+ if(fv._len != gv._len) BDDerr("BDDV::operator^: Length mismatch");
306
+ hv._len = fv._len;
307
+ hv._lev = fv._lev;
308
+ return hv;
309
+ }
310
+
311
+ extern BDDV operator|(const BDDV&, const BDDV&);
312
+ extern BDDV operator^(const BDDV&, const BDDV&);
313
+ inline int operator==(const BDDV& fv, const BDDV& gv)
314
+
315
+ { return fv.GetMetaBDD() == gv.GetMetaBDD() && fv.Len() == gv.Len(); }
316
+
317
+ inline int operator!=(const BDDV& fv, const BDDV& gv)
318
+ { return !(fv == gv); }
319
+
320
+ inline int BDDV_Imply(const BDDV& fv, const BDDV& gv) {
321
+ return fv.Len() == gv.Len()
322
+ && BDD_Imply(fv.GetMetaBDD(), gv.GetMetaBDD());
323
+ }
324
+
325
+ inline BDDV& BDDV::operator&=(const BDDV& fv) { return *this = *this & fv; }
326
+ inline BDDV& BDDV::operator|=(const BDDV& fv) { return *this = *this | fv; }
327
+ inline BDDV& BDDV::operator^=(const BDDV& fv) { return *this = *this ^ fv; }
328
+ inline BDDV& BDDV::operator<<=(int s) { return *this = *this << s; }
329
+ inline BDDV& BDDV::operator>>=(int s) { return *this = *this >> s; }
330
+
331
+
332
+ class BDD_Hash
333
+ {
334
+ struct BDD_Entry
335
+ {
336
+ BDD _key;
337
+ void* _ptr;
338
+ BDD_Entry(void){ _key = -1; }
339
+ };
340
+
341
+ bddword _amount;
342
+ bddword _hashSize;
343
+ BDD_Entry* _wheel;
344
+
345
+ BDD_Entry* GetEntry(BDD);
346
+ void Enlarge(void);
347
+ public:
348
+ BDD_Hash(void);
349
+ ~BDD_Hash(void);
350
+ void Clear(void);
351
+ void Enter(BDD, void *);
352
+ void* Refer(BDD);
353
+ bddword Amount(void);
354
+ };
355
+
356
+ #endif // _BDD_
@@ -0,0 +1,1818 @@
1
+ /*******************************************
2
+ * BDD - Decomposition Graph (SAPPORO-1.59)*
3
+ * (C) Shin-ichi MINATO (Dec. 10, 2013) *
4
+ *******************************************/
5
+
6
+ #include "BDDDG.h"
7
+
8
+ using std::cout;
9
+ using std::cerr;
10
+
11
+ BDDDG_Tag::BDDDG_Tag()
12
+ {
13
+ _dg = 0;
14
+ _ndx = BDDDG_NIL;
15
+ }
16
+
17
+ int BDDDG_Tag::Set(BDDDG* dg, bddword idx)
18
+ {
19
+ _dg = dg;
20
+ if(idx == BDDDG_NIL) return 1;
21
+ _ndx = BDDDG_Ndx(idx);
22
+ if(_ndx >= _dg->_nodeUsed) return 1;
23
+ _lkx = _dg->_nodeA[_ndx]._lkx;
24
+ return 0;
25
+ }
26
+
27
+ bddword BDDDG_Tag::TopIdx()
28
+ {
29
+ _lkx = _dg->_nodeA[_ndx]._lkx;
30
+ if(_lkx == BDDDG_NIL) return BDDDG_NIL;
31
+ return _dg->_linkA[_lkx]._idx;
32
+ }
33
+
34
+ bddword BDDDG_Tag::NextIdx()
35
+ {
36
+ _lkx = _dg->_linkA[_lkx]._nxt;
37
+ if(_lkx == BDDDG_NIL) return BDDDG_NIL;
38
+ return _dg->_linkA[_lkx]._idx;
39
+ }
40
+
41
+ char BDDDG_Tag::Type()
42
+ {
43
+ return _dg->_nodeA[_ndx]._type;
44
+ }
45
+
46
+ BDD BDDDG_Tag::Func()
47
+ {
48
+ return _dg->_nodeA[_ndx]._f;
49
+ }
50
+
51
+ BDDDG::BDDDG()
52
+ {
53
+ _nodeA = 0;
54
+ _linkA = 0;
55
+ _hashWheel = 0;
56
+ Clear();
57
+ }
58
+
59
+ BDDDG::~BDDDG()
60
+ {
61
+ delete[] _hashWheel;
62
+ delete[] _linkA;
63
+ delete[] _nodeA;
64
+ }
65
+
66
+ void BDDDG::Clear()
67
+ {
68
+ delete[] _hashWheel;
69
+ delete[] _linkA;
70
+ delete[] _nodeA;
71
+
72
+ _nodeSize = BDDDG_InitSize;
73
+ _nodeA = new Node[_nodeSize];
74
+ _nodeUsed = 0;
75
+ _linkSize = BDDDG_InitSize;
76
+ _linkA = new NodeLink[_linkSize];
77
+ _linkUsed = 0;
78
+ bddword hashSize = _nodeSize << 1;
79
+ _hashWheel = new bddword[hashSize];
80
+ for(bddword i=0; i<hashSize; i++) _hashWheel[i] = BDDDG_NIL;
81
+ bddword cdx = NewNdx(1, BDDDG_C1);
82
+ _c1 = BDDDG_PackIdx(cdx, 0);
83
+ }
84
+
85
+ bddword BDDDG::HashIndex(BDD key)
86
+ {
87
+ bddword id0 = key.GetID();
88
+ bddword id1 = (~key).GetID();
89
+ bddword id = (id0<id1)? id0: id1;
90
+ bddword hashSize = _nodeSize << 1;
91
+ bddword hash = (id+(id>>10)+(id>>20)) & (hashSize - 1);
92
+ bddword i = hash;
93
+ while(_hashWheel[i] != BDDDG_NIL)
94
+ {
95
+ BDD f = _nodeA[_hashWheel[i]]._f;
96
+ if(key == f) return i;
97
+ if(~key == f) return i;
98
+ i++;
99
+ i &= (hashSize -1);
100
+ }
101
+ return i;
102
+ }
103
+
104
+ bddword BDDDG::NewNdx(BDD f, char type)
105
+ {
106
+ if(_nodeUsed == _nodeSize)
107
+ if(EnlargeNode()) return BDDDG_NIL;
108
+ bddword ndx = _nodeUsed++;
109
+ _nodeA[ndx]._f = f;
110
+ _nodeA[ndx]._type = type;
111
+ bddword i = HashIndex(f);
112
+ if(_hashWheel[i] != BDDDG_NIL)
113
+ {
114
+ cerr << "<ERROR> BDDDG::NewNdx(): Duplicate node\n";
115
+ exit(1);
116
+ }
117
+ _hashWheel[i] = ndx;
118
+ return ndx;
119
+ }
120
+
121
+
122
+ int BDDDG::EnlargeNode()
123
+ {
124
+ bddword oldHS = _nodeSize << 1;
125
+ Node* oldArray = _nodeA;
126
+ bddword* oldWheel = _hashWheel;
127
+
128
+ _nodeSize <<= 2;
129
+ _nodeA = new Node[_nodeSize];
130
+ bddword hashSize = _nodeSize << 1;
131
+ _hashWheel = new bddword[hashSize];
132
+ if(_nodeA == 0 || _hashWheel == 0)
133
+ {
134
+ cerr << "<ERROR> BDDDG::EnlargeNode(): Memory overflow (";
135
+ cerr << _nodeSize << ")\n";
136
+ return 1;
137
+ }
138
+ for(bddword i=0; i<_nodeUsed; i++)
139
+ {
140
+ _nodeA[i]._lkx = oldArray[i]._lkx;
141
+ _nodeA[i]._f = oldArray[i]._f;
142
+ _nodeA[i]._type = oldArray[i]._type;
143
+ _nodeA[i]._mark = oldArray[i]._mark;
144
+ _nodeA[i]._ndxP = oldArray[i]._ndxP;
145
+ _nodeA[i]._invP = oldArray[i]._invP;
146
+ }
147
+ for(bddword i=0; i<hashSize; i++) _hashWheel[i] = BDDDG_NIL;
148
+ for(bddword i=0; i<oldHS; i++)
149
+ {
150
+ bddword ndx = oldWheel[i];
151
+ if(ndx != BDDDG_NIL)
152
+ {
153
+ BDD f = _nodeA[ndx]._f;
154
+ _hashWheel[HashIndex(f)] = ndx;
155
+ }
156
+ }
157
+ delete[] oldArray;
158
+ delete[] oldWheel;
159
+ return 0;
160
+ }
161
+
162
+ bddword BDDDG::NewLkx(bddword idx)
163
+ {
164
+ if(_linkUsed == _linkSize)
165
+ if(EnlargeLink()) return BDDDG_NIL;
166
+ bddword lkx = _linkUsed++;
167
+ _linkA[lkx]._idx = idx;
168
+ return lkx;
169
+ }
170
+
171
+ int BDDDG::EnlargeLink()
172
+ {
173
+ NodeLink* oldArray = _linkA;
174
+
175
+ _linkSize <<= 2;
176
+ _linkA = new NodeLink[_linkSize];
177
+ if(_linkA == 0)
178
+ {
179
+ cerr << "<ERROR> BDDDG::EnlargeLink(): Memory overflow (";
180
+ cerr << _linkSize << ")\n";
181
+ return 1;
182
+ }
183
+ for(bddword i=0; i<_linkUsed; i++)
184
+ {
185
+ _linkA[i]._idx = oldArray[i]._idx;
186
+ _linkA[i]._nxt = oldArray[i]._nxt;
187
+ }
188
+ delete[] oldArray;
189
+ return 0;
190
+ }
191
+
192
+ bddword BDDDG::ReferIdx(BDD key)
193
+ {
194
+ bddword i = HashIndex(key);
195
+ bddword ndx = _hashWheel[i];
196
+ if(ndx == BDDDG_NIL) return ndx;
197
+ return BDDDG_PackIdx(ndx, key != _nodeA[ndx]._f);
198
+ }
199
+
200
+ bddword BDDDG::NodeUsed() { return _nodeUsed; }
201
+
202
+ BDDDG::Node::Node()
203
+ {
204
+ _lkx = BDDDG_NIL;
205
+ _f = BDD(1);
206
+ _type = BDDDG_C1;
207
+ _mark = 0;
208
+ _ndxP = BDDDG_NIL;
209
+ _invP = 0;
210
+ }
211
+
212
+ BDDDG::Node::Node(BDD f, char type)
213
+ {
214
+ _lkx = BDDDG_NIL;
215
+ _f = f;
216
+ _type = type;
217
+ _mark = 0;
218
+ _ndxP = BDDDG_NIL;
219
+ _invP = 0;
220
+ }
221
+
222
+ void BDDDG::PhaseSweep(bddword idx)
223
+ {
224
+ int fin = 0;
225
+ int inv = 0;
226
+ if(idx == BDDDG_NIL) return;
227
+ Node* np = & _nodeA[BDDDG_Ndx(idx)];
228
+ bddword lkx = np->_lkx;
229
+
230
+ switch(np->_type)
231
+ {
232
+ case BDDDG_OR:
233
+ /* Assertion check*/
234
+ while(lkx != BDDDG_NIL)
235
+ {
236
+ NodeLink* lp = _linkA + lkx;
237
+ if(!BDDDG_Inv(lp->_idx) &&
238
+ _nodeA[BDDDG_Ndx(lp->_idx)]._type == BDDDG_OR)
239
+ {
240
+ cerr << "<ERROR> BDDDG::PhaseSweep(): Bad structure (OR)\n";
241
+ exit(1);
242
+ }
243
+ lkx = lp->_nxt;
244
+ fin++;
245
+ }
246
+ if(fin < 2)
247
+ {
248
+ cerr << "<ERROR> BDDDG::PhaseSweep(): Bad fan-in (OR)\n";
249
+ exit(1);
250
+ }
251
+ break;
252
+
253
+ case BDDDG_XOR:
254
+ /* Assertion check*/
255
+ while(lkx != BDDDG_NIL)
256
+ {
257
+ NodeLink* lp = _linkA + lkx;
258
+ if(BDDDG_Inv(lp->_idx))
259
+ {
260
+ inv++;
261
+ lp->_idx = BDDDG_InvReset(lp->_idx);
262
+ }
263
+ if(_nodeA[BDDDG_Ndx(lp->_idx)]._type == BDDDG_XOR)
264
+ {
265
+ cerr << "<ERROR> BDDDG::PhaseSweep(): Bad structure (XOR)\n";
266
+ exit(1);
267
+ }
268
+ lkx = lp->_nxt;
269
+ fin++;
270
+ }
271
+ if(inv & 1) np->_f = ~(np->_f);
272
+ if(fin < 2)
273
+ {
274
+ cerr << "<ERROR> BDDDG::PhaseSweep(): Bad fan-in (XOR)\n";
275
+ exit(1);
276
+ }
277
+ break;
278
+
279
+ case BDDDG_OTHER:
280
+ /* Assertion check*/
281
+ while(lkx != BDDDG_NIL)
282
+ {
283
+ NodeLink* lp = _linkA + lkx;
284
+ if(BDDDG_Inv(lp->_idx))
285
+ lp->_idx = BDDDG_InvReset(lp->_idx);
286
+ lkx = lp->_nxt;
287
+ fin++;
288
+ }
289
+ if(fin < 2)
290
+ {
291
+ cerr << "<ERROR> BDDDG::PhaseSweep(): Bad fan-in (OTHER)\n";
292
+ exit(1);
293
+ }
294
+ break;
295
+ default:
296
+ cerr << "<ERROR> BDDDG::PhaseSweep(): Bad node type\n";
297
+ exit(1);
298
+ }
299
+ }
300
+
301
+ int BDDDG::LinkNodes(bddword idx, bddword idx2)
302
+ {
303
+ if(idx == BDDDG_NIL || idx2 == BDDDG_NIL)
304
+ {
305
+ cerr << "<ERROR> BDDDG::LinkNodes(): Null node\n";
306
+ exit(1);
307
+ }
308
+ bddword ndx = BDDDG_Ndx(idx);
309
+ bddword ndx2 = BDDDG_Ndx(idx2);
310
+ bddword lkx = NewLkx(idx2);
311
+ if(lkx == BDDDG_NIL) return 1;
312
+ _linkA[lkx]._nxt = _nodeA[ndx]._lkx;
313
+ _nodeA[ndx]._lkx = lkx;
314
+
315
+ bddword lkx2 = _linkA[lkx]._nxt;
316
+ while(lkx2 != BDDDG_NIL)
317
+ {
318
+ bddword idx3 = _linkA[lkx]._idx;
319
+ bddword idx4 = _linkA[lkx2]._idx;
320
+ BDD f = _nodeA[BDDDG_Ndx(idx3)]._f;
321
+ BDD f2 = _nodeA[BDDDG_Ndx(idx4)]._f;
322
+ if(f.Top() == f2.Top())
323
+ {
324
+ cerr << "<ERROR> BDDDG::LinkNodes(): Same VarIndex(";
325
+ cerr << f.Top() << ")\n";
326
+ exit(1);
327
+ }
328
+
329
+ if(f.Top() < f2.Top()) break;
330
+
331
+ _linkA[lkx]._idx = idx4;
332
+ _linkA[lkx2]._idx = idx3;
333
+
334
+ lkx = lkx2;
335
+ lkx2 = _linkA[lkx2]._nxt;
336
+ }
337
+ return 0;
338
+ }
339
+
340
+ bddword BDDDG::Decomp(BDD f)
341
+ {
342
+ if(f==0) return BDDDG_InvSet(_c1);
343
+ if(f==1) return _c1;
344
+
345
+ bddword idx = ReferIdx(f);
346
+ if(idx != BDDDG_NIL) return idx;
347
+
348
+ int top = f.Top();
349
+ BDD f0 = f.At0(top);
350
+ BDD f1 = f.At1(top);
351
+ bddword idx0 = Decomp(f0);
352
+ if(idx0 == BDDDG_NIL) return BDDDG_NIL;
353
+ bddword idx1 = Decomp(f1);
354
+ if(idx1 == BDDDG_NIL) return BDDDG_NIL;
355
+ idx = Merge(f, idx0, idx1);
356
+
357
+ return idx;
358
+ }
359
+
360
+ void BDDDG::MarkSweep(bddword idx)
361
+ {
362
+ if(idx == BDDDG_NIL)
363
+ {
364
+ cerr << "<ERROR> BDDDG::MarkSweep(): Bad idx";
365
+ exit(1);
366
+ }
367
+ bddword ndx = BDDDG_Ndx(idx);
368
+ _nodeA[ndx]._mark = 0;
369
+ bddword lkx = _nodeA[ndx]._lkx;
370
+ while(lkx != BDDDG_NIL)
371
+ {
372
+ _nodeA[BDDDG_Ndx(_linkA[lkx]._idx)]._mark = 0;
373
+ lkx = _linkA[lkx]._nxt;
374
+ }
375
+ }
376
+
377
+ void BDDDG::MarkSweepR(bddword idx)
378
+ {
379
+ if(idx == BDDDG_NIL)
380
+ {
381
+ cerr << "<ERROR> BDDDG::MarkSweepR(): Bad idx";
382
+ exit(1);
383
+ }
384
+ bddword ndx = BDDDG_Ndx(idx);
385
+ _nodeA[ndx]._mark = 0;
386
+ _nodeA[ndx]._ndxP = BDDDG_NIL;
387
+ _nodeA[ndx]._invP = 0;
388
+ bddword lkx = _nodeA[ndx]._lkx;
389
+ while(lkx != BDDDG_NIL)
390
+ {
391
+ MarkSweepR(_linkA[lkx]._idx);
392
+ lkx = _linkA[lkx]._nxt;
393
+ }
394
+ }
395
+
396
+ int BDDDG::Mark1(bddword idx)
397
+ {
398
+ if(idx == BDDDG_NIL)
399
+ {
400
+ cerr << "<ERROR> BDDDG::Mark1(): Bad idx";
401
+ exit(1);
402
+ }
403
+ bddword ndx = BDDDG_Ndx(idx);
404
+ int fin = 0;
405
+ bddword lkx = _nodeA[ndx]._lkx;
406
+ while(lkx != BDDDG_NIL)
407
+ {
408
+ bddword idx1 = _linkA[lkx]._idx;
409
+ if(BDDDG_Inv(idx1)) _nodeA[BDDDG_Ndx(idx1)]._mark = 2;
410
+ else _nodeA[BDDDG_Ndx(idx1)]._mark = 1;
411
+ fin++;
412
+ lkx = _linkA[lkx]._nxt;
413
+ }
414
+ return fin;
415
+ }
416
+
417
+ void BDDDG::Mark2R(bddword idx)
418
+ {
419
+ if(idx == BDDDG_NIL)
420
+ {
421
+ cerr << "<ERROR> BDDDG::Mark2R(): Bad idx";
422
+ exit(1);
423
+ }
424
+ bddword ndx = BDDDG_Ndx(idx);
425
+ _nodeA[ndx]._mark++;
426
+ bddword lkx = _nodeA[ndx]._lkx;
427
+ while(lkx != BDDDG_NIL)
428
+ {
429
+ Mark2R(_linkA[lkx]._idx);
430
+ lkx = _linkA[lkx]._nxt;
431
+ }
432
+ }
433
+
434
+ int BDDDG::MarkChkR(bddword idx)
435
+ {
436
+ if(idx == BDDDG_NIL)
437
+ {
438
+ cerr << "<ERROR> BDDDG::MarkChkR(): Bad idx";
439
+ exit(1);
440
+ }
441
+ bddword ndx = BDDDG_Ndx(idx);
442
+ if(_nodeA[ndx]._mark != 0) return 1;
443
+ bddword lkx = _nodeA[ndx]._lkx;
444
+ while(lkx != BDDDG_NIL)
445
+ {
446
+ if(MarkChkR(_linkA[lkx]._idx)) return 1;
447
+ lkx = _linkA[lkx]._nxt;
448
+ }
449
+ return 0;
450
+ }
451
+
452
+ void BDDDG::Mark3R(bddword idx)
453
+ {
454
+ if(idx == BDDDG_NIL)
455
+ {
456
+ cerr << "<ERROR> BDDDG::Mark3R(): Bad idx";
457
+ exit(1);
458
+ }
459
+ bddword ndx = BDDDG_Ndx(idx);
460
+ if(_nodeA[ndx]._mark == 2) return;
461
+
462
+ int cnt1 = 0; // not decided.
463
+ int cnt2 = 0; // shared node.
464
+ int cnt3 = 0; // non-shared node.
465
+ int cnt4 = 0; // (possibly) partly shared node.
466
+
467
+ bddword lkx = _nodeA[ndx]._lkx;
468
+ while(lkx != BDDDG_NIL)
469
+ {
470
+ bddword idt = _linkA[lkx]._idx;
471
+ Mark3R(idt);
472
+ switch(_nodeA[BDDDG_Ndx(idt)]._mark)
473
+ {
474
+ case 1:
475
+ cnt1++;
476
+ break;
477
+ case 2:
478
+ cnt2++;
479
+ break;
480
+ case 3:
481
+ cnt3++;
482
+ break;
483
+ case 4:
484
+ cnt4++;
485
+ break;
486
+ default:
487
+ break;
488
+ }
489
+ lkx = _linkA[lkx]._nxt;
490
+ }
491
+ if(_nodeA[ndx]._type == BDDDG_OR || _nodeA[ndx]._type == BDDDG_XOR)
492
+ {
493
+ if(cnt2 >= 2)
494
+ {
495
+ lkx = _nodeA[ndx]._lkx;
496
+ while(lkx != BDDDG_NIL)
497
+ {
498
+ bddword idt = _linkA[lkx]._idx;
499
+ _nodeA[BDDDG_Ndx(idt)]._ndxP = ndx;
500
+ _nodeA[BDDDG_Ndx(idt)]._invP = (char) BDDDG_Inv(idt);
501
+ lkx = _linkA[lkx]._nxt;
502
+ }
503
+ _nodeA[ndx]._mark = 4;
504
+ return;
505
+ }
506
+ }
507
+
508
+ if(cnt1 + cnt2 + cnt4 == 0 && _nodeA[ndx]._mark == 1)
509
+ _nodeA[ndx]._mark = 3;
510
+ }
511
+
512
+ bddword BDDDG::Merge(BDD f, bddword idx0, bddword idx1)
513
+ {
514
+ if(idx0 == BDDDG_NIL || idx1 == BDDDG_NIL)
515
+ {
516
+ cerr << "<ERROR> BDDDG::Merge(): Null node\n";
517
+ exit(1);
518
+ }
519
+ bddword ndx0 = BDDDG_Ndx(idx0);
520
+ bddword ndx1 = BDDDG_Ndx(idx1);
521
+
522
+ int top = f.Top(); // (top > 0)
523
+
524
+ // Case3-LIT ?
525
+ if(BDDDG_InvReset(idx0) == _c1 && BDDDG_InvReset(idx1) == _c1)
526
+ {
527
+ bddword idx = ReferIdx(f);
528
+ if(idx == BDDDG_NIL)
529
+ {
530
+ bddword ndx = NewNdx(BDDvar(top), BDDDG_LIT);
531
+ if(ndx == BDDDG_NIL) return BDDDG_NIL;
532
+ idx = BDDDG_PackIdx(ndx, f != BDDvar(top));
533
+ }
534
+ return idx;
535
+ }
536
+
537
+ // Case3-OR ?
538
+ if(BDDDG_InvReset(idx1) == _c1)
539
+ {
540
+ bddword idx = ReferIdx(BDDvar(top));
541
+ if(idx == BDDDG_NIL)
542
+ {
543
+ bddword ndx = NewNdx(BDDvar(top), BDDDG_LIT);
544
+ if(ndx == BDDDG_NIL) return BDDDG_NIL;
545
+ idx = BDDDG_PackIdx(ndx, 0);
546
+ }
547
+ bddword ndy = NewNdx(BDDDG_Inv(idx1)? ~f: f, BDDDG_OR);
548
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
549
+ bddword idy = BDDDG_PackIdx(ndy, BDDDG_Inv(idx1));
550
+ if(LinkNodes(idy, idx)) return BDDDG_NIL;
551
+ if(_nodeA[ndx0]._type != BDDDG_OR ||
552
+ BDDDG_Inv(idx0) != BDDDG_Inv(idx1) )
553
+ {
554
+ if(LinkNodes(idy, BDDDG_Inv(idx1)? BDDDG_InvAlt(idx0): idx0))
555
+ return BDDDG_NIL;
556
+ }
557
+ else
558
+ {
559
+ bddword lkx = _nodeA[ndx0]._lkx;
560
+ while(lkx != BDDDG_NIL)
561
+ {
562
+ if(LinkNodes(idy, _linkA[lkx]._idx)) return BDDDG_NIL;
563
+ lkx = _linkA[lkx]._nxt;
564
+ }
565
+ }
566
+ PhaseSweep(idy);
567
+ return idy;
568
+ }
569
+
570
+ if(BDDDG_InvReset(idx0) == _c1)
571
+ {
572
+ bddword idx = ReferIdx(~BDDvar(top));
573
+ if(idx == BDDDG_NIL)
574
+ {
575
+ bddword ndx = NewNdx(BDDvar(top), BDDDG_LIT);
576
+ if(ndx == BDDDG_NIL) return BDDDG_NIL;
577
+ idx = BDDDG_PackIdx(ndx, 1);
578
+ }
579
+ bddword ndy = NewNdx(BDDDG_Inv(idx0)? ~f: f, BDDDG_OR);
580
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
581
+ bddword idy = BDDDG_PackIdx(ndy, BDDDG_Inv(idx0));
582
+ if(LinkNodes(idy, idx)) return BDDDG_NIL;
583
+ if(_nodeA[ndx1]._type != BDDDG_OR ||
584
+ BDDDG_Inv(idx1) != BDDDG_Inv(idx0) )
585
+ {
586
+ if(LinkNodes(idy, BDDDG_Inv(idx0)? BDDDG_InvAlt(idx1): idx1))
587
+ return BDDDG_NIL;
588
+ }
589
+ else
590
+ {
591
+ bddword lkx = _nodeA[ndx1]._lkx;
592
+ while(lkx != BDDDG_NIL)
593
+ {
594
+ if(LinkNodes(idy, _linkA[lkx]._idx)) return BDDDG_NIL;
595
+ lkx = _linkA[lkx]._nxt;
596
+ }
597
+ }
598
+ PhaseSweep(idy);
599
+ return idy;
600
+ }
601
+
602
+ // Case3-XOR ?
603
+ if(ndx0 == ndx1)
604
+ {
605
+ if(idx0 == idx1) { cout << "ERROR\n"; exit(1); }
606
+
607
+ bddword idx = ReferIdx(BDDvar(top));
608
+ if(idx == BDDDG_NIL)
609
+ {
610
+ bddword ndx = NewNdx(BDDvar(top), BDDDG_LIT);
611
+ if(ndx == BDDDG_NIL) return BDDDG_NIL;
612
+ idx = BDDDG_PackIdx(ndx, 0);
613
+ }
614
+
615
+ bddword ndy = NewNdx(BDDDG_Inv(idx0)? ~f: f, BDDDG_XOR);
616
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
617
+ bddword idy = BDDDG_PackIdx(ndy, BDDDG_Inv(idx0));
618
+ if(LinkNodes(idy, idx)) return BDDDG_NIL;
619
+ if(_nodeA[ndx0]._type != BDDDG_XOR)
620
+ {
621
+ if(LinkNodes(idy, BDDDG_InvReset(idx0))) return BDDDG_NIL;
622
+ }
623
+ else
624
+ {
625
+ bddword lkx = _nodeA[ndx0]._lkx;
626
+ while(lkx != BDDDG_NIL)
627
+ {
628
+ if(LinkNodes(idy, _linkA[lkx]._idx)) return BDDDG_NIL;
629
+ lkx = _linkA[lkx]._nxt;
630
+ }
631
+ }
632
+ PhaseSweep(idy);
633
+ return idy;
634
+ }
635
+
636
+ // Case1-OR ?
637
+ if(_nodeA[ndx0]._type == BDDDG_OR && _nodeA[ndx1]._type == BDDDG_OR
638
+ && BDDDG_Inv(idx0) == BDDDG_Inv(idx1))
639
+ {
640
+ int fin0 = 0;
641
+ int fin1 = 0;
642
+ int fin2 = 0;
643
+
644
+ fin0 = Mark1(idx0);
645
+ bddword lkx = _nodeA[ndx1]._lkx;
646
+ while(lkx != BDDDG_NIL)
647
+ {
648
+ bddword idt = _linkA[lkx]._idx;
649
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == (BDDDG_Inv(idt)? 2: 1))
650
+ {
651
+ fin2++;
652
+ _nodeA[BDDDG_Ndx(idt)]._mark = 3;
653
+ }
654
+ lkx = _linkA[lkx]._nxt;
655
+ fin1++;
656
+ }
657
+
658
+ if(fin2 > 0)
659
+ {
660
+ bddword idy0;
661
+ if(fin0 - fin2 > 1)
662
+ {
663
+ BDD g = 0;
664
+ lkx = _nodeA[ndx0]._lkx;
665
+ while(lkx != BDDDG_NIL)
666
+ {
667
+ bddword idt = _linkA[lkx]._idx;
668
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 3)
669
+ {
670
+ BDD g2 = _nodeA[BDDDG_Ndx(idt)]._f;
671
+ g |= BDDDG_Inv(idt)? ~g2: g2;
672
+ }
673
+ lkx = _linkA[lkx]._nxt;
674
+ }
675
+ idy0 = ReferIdx(g);
676
+ if(idy0 == BDDDG_NIL)
677
+ {
678
+ bddword ndy0 = NewNdx(g, BDDDG_OR);
679
+ if(ndy0 == BDDDG_NIL) return BDDDG_NIL;
680
+ idy0 = BDDDG_PackIdx(ndy0, 0);
681
+ lkx = _nodeA[ndx0]._lkx;
682
+ while(lkx != BDDDG_NIL)
683
+ {
684
+ bddword idt = _linkA[lkx]._idx;
685
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 3)
686
+ if(LinkNodes(idy0, idt)) return BDDDG_NIL;
687
+ lkx = _linkA[lkx]._nxt;
688
+ }
689
+ }
690
+ }
691
+ else if(fin0 - fin2 == 1)
692
+ {
693
+ lkx = _nodeA[ndx0]._lkx;
694
+ while(lkx != BDDDG_NIL)
695
+ {
696
+ bddword idt = _linkA[lkx]._idx;
697
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 3)
698
+ { idy0 = _linkA[lkx]._idx; break; }
699
+ lkx = _linkA[lkx]._nxt;
700
+ }
701
+ }
702
+ else idy0 = BDDDG_InvSet(_c1);
703
+
704
+ bddword idy1;
705
+ if(fin1 - fin2 > 1)
706
+ {
707
+ BDD g = 0;
708
+ lkx = _nodeA[ndx1]._lkx;
709
+ while(lkx != BDDDG_NIL)
710
+ {
711
+ bddword idt = _linkA[lkx]._idx;
712
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 3)
713
+ {
714
+ BDD g2 = _nodeA[BDDDG_Ndx(idt)]._f;
715
+ g |= BDDDG_Inv(idt)? ~g2: g2;
716
+ }
717
+ lkx = _linkA[lkx]._nxt;
718
+ }
719
+ idy1 = ReferIdx(g);
720
+ if(idy1 == BDDDG_NIL)
721
+ {
722
+ bddword ndy1 = NewNdx(g, BDDDG_OR);
723
+ if(ndy1 == BDDDG_NIL) return BDDDG_NIL;
724
+ idy1 = BDDDG_PackIdx(ndy1, 0);
725
+ lkx = _nodeA[ndx1]._lkx;
726
+ while(lkx != BDDDG_NIL)
727
+ {
728
+ bddword idt = _linkA[lkx]._idx;
729
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 3)
730
+ if(LinkNodes(idy1, idt)) return BDDDG_NIL;
731
+ lkx = _linkA[lkx]._nxt;
732
+ }
733
+ }
734
+ }
735
+ else if(fin1 - fin2 == 1)
736
+ {
737
+ lkx = _nodeA[ndx1]._lkx;
738
+ while(lkx != BDDDG_NIL)
739
+ {
740
+ bddword idt = _linkA[lkx]._idx;
741
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 3)
742
+ { idy1 = _linkA[lkx]._idx; break; }
743
+ lkx = _linkA[lkx]._nxt;
744
+ }
745
+ }
746
+ else idy1 = BDDDG_InvSet(_c1);
747
+
748
+ bddword ndy = NewNdx(BDDDG_Inv(idx0)? ~f: f, BDDDG_OR);
749
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
750
+ bddword idy = BDDDG_PackIdx(ndy, BDDDG_Inv(idx0));
751
+ lkx = _nodeA[ndx0]._lkx;
752
+ while(lkx != BDDDG_NIL)
753
+ {
754
+ bddword idt = _linkA[lkx]._idx;
755
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 3)
756
+ if(LinkNodes(idy, idt)) return BDDDG_NIL;
757
+ lkx = _linkA[lkx]._nxt;
758
+ }
759
+
760
+ MarkSweep(idx0);
761
+ if(Merge3(idy, idy0, idy1)) return BDDDG_NIL;;
762
+ return idy;
763
+ }
764
+ MarkSweep(idx0);
765
+ }
766
+
767
+ // Case1-XOR ?
768
+ if(_nodeA[ndx0]._type == BDDDG_XOR && _nodeA[ndx1]._type == BDDDG_XOR)
769
+ {
770
+ int fin0 = 0;
771
+ int fin1 = 0;
772
+ int fin2 = 0;
773
+
774
+ fin0 = Mark1(idx0);
775
+ bddword lkx = _nodeA[ndx1]._lkx;
776
+ while(lkx != BDDDG_NIL)
777
+ {
778
+ bddword idt = _linkA[lkx]._idx;
779
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 0)
780
+ { fin2++; _nodeA[BDDDG_Ndx(idt)]._mark = 3; }
781
+ lkx = _linkA[lkx]._nxt;
782
+ fin1++;
783
+ }
784
+
785
+ if(fin2 > 0)
786
+ {
787
+ bddword idy0;
788
+ if(fin0 - fin2 > 1)
789
+ {
790
+ BDD g = 0;
791
+ lkx = _nodeA[ndx0]._lkx;
792
+ while(lkx != BDDDG_NIL)
793
+ {
794
+ bddword idt = _linkA[lkx]._idx;
795
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 3)
796
+ g ^= _nodeA[BDDDG_Ndx(idt)]._f;
797
+ lkx = _linkA[lkx]._nxt;
798
+ }
799
+ idy0 = ReferIdx(g);
800
+ if(idy0 == BDDDG_NIL)
801
+ {
802
+ bddword ndy0 = NewNdx(g, BDDDG_XOR);
803
+ if(ndy0 == BDDDG_NIL) return BDDDG_NIL;
804
+ idy0 = BDDDG_PackIdx(ndy0, 0);
805
+ lkx = _nodeA[ndx0]._lkx;
806
+ while(lkx != BDDDG_NIL)
807
+ {
808
+ bddword idt = _linkA[lkx]._idx;
809
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 3)
810
+ if(LinkNodes(idy0, idt)) return BDDDG_NIL;
811
+ lkx = _linkA[lkx]._nxt;
812
+ }
813
+ }
814
+ }
815
+ else if(fin0 - fin2 == 1)
816
+ {
817
+ lkx = _nodeA[ndx0]._lkx;
818
+ while(lkx != BDDDG_NIL)
819
+ {
820
+ bddword idt = _linkA[lkx]._idx;
821
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 3)
822
+ { idy0 = _linkA[lkx]._idx; break; }
823
+ lkx = _linkA[lkx]._nxt;
824
+ }
825
+ }
826
+ else idy0 = BDDDG_InvSet(_c1);
827
+
828
+ bddword idy1;
829
+ if(fin1 - fin2 > 1)
830
+ {
831
+ BDD g = 0;
832
+ lkx = _nodeA[ndx1]._lkx;
833
+ while(lkx != BDDDG_NIL)
834
+ {
835
+ bddword idt = _linkA[lkx]._idx;
836
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 3)
837
+ g ^= _nodeA[BDDDG_Ndx(idt)]._f;
838
+ lkx = _linkA[lkx]._nxt;
839
+ }
840
+ idy1 = ReferIdx(g);
841
+ if(idy1 == BDDDG_NIL)
842
+ {
843
+ bddword ndy1 = NewNdx(g, BDDDG_XOR);
844
+ if(ndy1 == BDDDG_NIL) return BDDDG_NIL;
845
+ idy1 = BDDDG_PackIdx(ndy1, 0);
846
+ lkx = _nodeA[ndx1]._lkx;
847
+ while(lkx != BDDDG_NIL)
848
+ {
849
+ bddword idt = _linkA[lkx]._idx;
850
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 3)
851
+ if(LinkNodes(idy1, idt)) return BDDDG_NIL;
852
+ lkx = _linkA[lkx]._nxt;
853
+ }
854
+ }
855
+ }
856
+ else if(fin1 - fin2 == 1)
857
+ {
858
+ lkx = _nodeA[ndx1]._lkx;
859
+ while(lkx != BDDDG_NIL)
860
+ {
861
+ bddword idt = _linkA[lkx]._idx;
862
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 3)
863
+ { idy1 = _linkA[lkx]._idx; break; }
864
+ lkx = _linkA[lkx]._nxt;
865
+ }
866
+ }
867
+ else idy1 = BDDDG_InvSet(_c1);
868
+
869
+ if(BDDDG_Inv(idx0)) idy0 = BDDDG_InvAlt(idy0);
870
+ if(BDDDG_Inv(idx1)) idy1 = BDDDG_InvAlt(idy1);
871
+
872
+ bddword ndy = NewNdx(f, BDDDG_XOR);
873
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
874
+ bddword idy = BDDDG_PackIdx(ndy, 0);
875
+ lkx = _nodeA[ndx0]._lkx;
876
+ while(lkx != BDDDG_NIL)
877
+ {
878
+ bddword idt = _linkA[lkx]._idx;
879
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 3)
880
+ if(LinkNodes(idy, idt)) return BDDDG_NIL;
881
+ lkx = _linkA[lkx]._nxt;
882
+ }
883
+
884
+ MarkSweep(idx0);
885
+ if(Merge3(idy, idy0, idy1)) return BDDDG_NIL;;
886
+ return (f == _nodeA[ndy]._f)? idy: BDDDG_InvAlt(idy);
887
+ }
888
+ MarkSweep(idx0);
889
+ }
890
+
891
+ // Case2-OR(a)? part 0
892
+ if(_nodeA[ndx1]._type == BDDDG_OR)
893
+ {
894
+ int fin1 = 0;
895
+ int fin2 = 0;
896
+ _nodeA[ndx0]._mark = 1;
897
+ bddword lkx = _nodeA[ndx1]._lkx;
898
+ while(lkx != BDDDG_NIL)
899
+ {
900
+ bddword idt = _linkA[lkx]._idx;
901
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 1)
902
+ {
903
+ fin2++;
904
+ if(BDDDG_Inv(idt)) _nodeA[BDDDG_Ndx(idt)]._mark = 2;
905
+ }
906
+ fin1++;
907
+ lkx = _linkA[lkx]._nxt;
908
+ }
909
+
910
+ if(fin2 > 0 &&
911
+ (_nodeA[ndx0]._mark == 2) == (BDDDG_Inv(idx0)!=BDDDG_Inv(idx1)))
912
+ {
913
+ bddword idy1;
914
+ if(fin1 > 2)
915
+ {
916
+ BDD g = 0;
917
+ lkx = _nodeA[ndx1]._lkx;
918
+ while(lkx != BDDDG_NIL)
919
+ {
920
+ bddword idt = _linkA[lkx]._idx;
921
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 0)
922
+ {
923
+ BDD g2 = _nodeA[BDDDG_Ndx(idt)]._f;
924
+ g |= BDDDG_Inv(idt)? ~g2: g2;
925
+ }
926
+ lkx = _linkA[lkx]._nxt;
927
+ }
928
+ idy1 = ReferIdx(g);
929
+ if(idy1 == BDDDG_NIL)
930
+ {
931
+ bddword ndy1 = NewNdx(g, BDDDG_OR);
932
+ if(ndy1 == BDDDG_NIL) return BDDDG_NIL;
933
+ idy1 = BDDDG_PackIdx(ndy1, 0);
934
+ lkx = _nodeA[ndx1]._lkx;
935
+ while(lkx != BDDDG_NIL)
936
+ {
937
+ bddword idt = _linkA[lkx]._idx;
938
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 0)
939
+ if(LinkNodes(idy1, idt)) return BDDDG_NIL;
940
+ lkx = _linkA[lkx]._nxt;
941
+ }
942
+ }
943
+ }
944
+ else
945
+ {
946
+ lkx = _nodeA[ndx1]._lkx;
947
+ while(lkx != BDDDG_NIL)
948
+ {
949
+ bddword idt = _linkA[lkx]._idx;
950
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 0)
951
+ { idy1 = _linkA[lkx]._idx; break; }
952
+ lkx = _linkA[lkx]._nxt;
953
+ }
954
+ }
955
+
956
+ bddword ndy = NewNdx(BDDDG_Inv(idx1)? ~f: f, BDDDG_OR);
957
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
958
+ bddword idy = BDDDG_PackIdx(ndy, BDDDG_Inv(idx1));
959
+ if(LinkNodes(idy, (_nodeA[ndx0]._mark==1)?
960
+ BDDDG_InvReset(idx0): BDDDG_InvSet(idx0)) )
961
+ return BDDDG_NIL;
962
+
963
+ _nodeA[ndx0]._mark = 0;
964
+ if(Merge3(idy, BDDDG_InvSet(_c1), idy1)) return BDDDG_NIL;;
965
+ return idy;
966
+ }
967
+ _nodeA[ndx0]._mark = 0;
968
+ }
969
+
970
+ // Case2-OR(a)? part 1
971
+ if(_nodeA[ndx0]._type == BDDDG_OR)
972
+ {
973
+ int fin0 = 0;
974
+ int fin2 = 0;
975
+ _nodeA[ndx1]._mark = 1;
976
+ bddword lkx = _nodeA[ndx0]._lkx;
977
+ while(lkx != BDDDG_NIL)
978
+ {
979
+ bddword idt = _linkA[lkx]._idx;
980
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 1)
981
+ {
982
+ fin2++;
983
+ if(BDDDG_Inv(idt)) _nodeA[BDDDG_Ndx(idt)]._mark = 2;
984
+ }
985
+ fin0++;
986
+ lkx = _linkA[lkx]._nxt;
987
+ }
988
+
989
+ if(fin2 > 0 &&
990
+ (_nodeA[ndx1]._mark == 2) == (BDDDG_Inv(idx0)!=BDDDG_Inv(idx1)))
991
+ {
992
+ bddword idy0;
993
+ if(fin0 > 2)
994
+ {
995
+ BDD g = 0;
996
+ lkx = _nodeA[ndx0]._lkx;
997
+ while(lkx != BDDDG_NIL)
998
+ {
999
+ bddword idt = _linkA[lkx]._idx;
1000
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 0)
1001
+ {
1002
+ BDD g2 = _nodeA[BDDDG_Ndx(idt)]._f;
1003
+ g |= BDDDG_Inv(idt)? ~g2: g2;
1004
+ }
1005
+ lkx = _linkA[lkx]._nxt;
1006
+ }
1007
+ idy0 = ReferIdx(g);
1008
+ if(idy0 == BDDDG_NIL)
1009
+ {
1010
+ bddword ndy0 = NewNdx(g, BDDDG_OR);
1011
+ if(ndy0 == BDDDG_NIL) return BDDDG_NIL;
1012
+ idy0 = BDDDG_PackIdx(ndy0, 0);
1013
+ lkx = _nodeA[ndx0]._lkx;
1014
+ while(lkx != BDDDG_NIL)
1015
+ {
1016
+ bddword idt = _linkA[lkx]._idx;
1017
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 0)
1018
+ if(LinkNodes(idy0, idt)) return BDDDG_NIL;
1019
+ lkx = _linkA[lkx]._nxt;
1020
+ }
1021
+ }
1022
+ }
1023
+ else
1024
+ {
1025
+ lkx = _nodeA[ndx0]._lkx;
1026
+ while(lkx != BDDDG_NIL)
1027
+ {
1028
+ bddword idt = _linkA[lkx]._idx;
1029
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 0)
1030
+ { idy0 = _linkA[lkx]._idx; break; }
1031
+ lkx = _linkA[lkx]._nxt;
1032
+ }
1033
+ }
1034
+
1035
+ bddword ndy = NewNdx(BDDDG_Inv(idx0)? ~f: f, BDDDG_OR);
1036
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
1037
+ bddword idy = BDDDG_PackIdx(ndy, BDDDG_Inv(idx0));
1038
+ if(LinkNodes(idy, (_nodeA[ndx1]._mark==1)?
1039
+ BDDDG_InvReset(idx1): BDDDG_InvSet(idx1)) )
1040
+ return BDDDG_NIL;
1041
+
1042
+ _nodeA[ndx1]._mark = 0;
1043
+ if(Merge3(idy, idy0, BDDDG_InvSet(_c1))) return BDDDG_NIL;;
1044
+ return idy;
1045
+ }
1046
+ _nodeA[ndx1]._mark = 0;
1047
+ }
1048
+
1049
+ // Case2-XOR(a)? part 0
1050
+ if(_nodeA[ndx1]._type == BDDDG_XOR)
1051
+ {
1052
+ int fin1 = 0;
1053
+ int fin2 = 0;
1054
+ _nodeA[ndx0]._mark = 1;
1055
+ bddword lkx = _nodeA[ndx1]._lkx;
1056
+ while(lkx != BDDDG_NIL)
1057
+ {
1058
+ bddword idt = _linkA[lkx]._idx;
1059
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 1) fin2++;
1060
+ fin1++;
1061
+ lkx = _linkA[lkx]._nxt;
1062
+ }
1063
+
1064
+ if(fin2 > 0)
1065
+ {
1066
+ bddword idy1;
1067
+ if(fin1 > 2)
1068
+ {
1069
+ BDD g = 0;
1070
+ lkx = _nodeA[ndx1]._lkx;
1071
+ while(lkx != BDDDG_NIL)
1072
+ {
1073
+ bddword idt = _linkA[lkx]._idx;
1074
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 0)
1075
+ g ^= _nodeA[BDDDG_Ndx(idt)]._f;
1076
+ lkx = _linkA[lkx]._nxt;
1077
+ }
1078
+ idy1 = ReferIdx(g);
1079
+ if(idy1 == BDDDG_NIL)
1080
+ {
1081
+ bddword ndy1 = NewNdx(g, BDDDG_XOR);
1082
+ if(ndy1 == BDDDG_NIL) return BDDDG_NIL;
1083
+ idy1 = BDDDG_PackIdx(ndy1, 0);
1084
+ lkx = _nodeA[ndx1]._lkx;
1085
+ while(lkx != BDDDG_NIL)
1086
+ {
1087
+ bddword idt = _linkA[lkx]._idx;
1088
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 0)
1089
+ if(LinkNodes(idy1, idt)) return BDDDG_NIL;
1090
+ lkx = _linkA[lkx]._nxt;
1091
+ }
1092
+ }
1093
+ }
1094
+ else
1095
+ {
1096
+ lkx = _nodeA[ndx1]._lkx;
1097
+ while(lkx != BDDDG_NIL)
1098
+ {
1099
+ bddword idt = _linkA[lkx]._idx;
1100
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 0)
1101
+ { idy1 = _linkA[lkx]._idx; break; }
1102
+ lkx = _linkA[lkx]._nxt;
1103
+ }
1104
+ }
1105
+
1106
+ bddword idy0 = BDDDG_InvSet(_c1);
1107
+
1108
+ if(BDDDG_Inv(idx0)) idy0 = BDDDG_InvAlt(idy0);
1109
+ if(BDDDG_Inv(idx1)) idy1 = BDDDG_InvAlt(idy1);
1110
+
1111
+ bddword ndy = NewNdx(f, BDDDG_XOR);
1112
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
1113
+ bddword idy = BDDDG_PackIdx(ndy, 0);
1114
+ if(LinkNodes(idy, BDDDG_InvReset(idx0)))
1115
+ return BDDDG_NIL;
1116
+
1117
+ _nodeA[ndx0]._mark = 0;
1118
+ if(Merge3(idy, idy0, idy1)) return BDDDG_NIL;;
1119
+ return (f == _nodeA[ndy]._f)? idy: BDDDG_InvAlt(idy);
1120
+ }
1121
+ _nodeA[ndx0]._mark = 0;
1122
+ }
1123
+
1124
+ // Case2-XOR(a)? part 1
1125
+ if(_nodeA[ndx0]._type == BDDDG_XOR)
1126
+ {
1127
+ int fin0 = 0;
1128
+ int fin2 = 0;
1129
+ _nodeA[ndx1]._mark = 1;
1130
+ bddword lkx = _nodeA[ndx0]._lkx;
1131
+ while(lkx != BDDDG_NIL)
1132
+ {
1133
+ bddword idt = _linkA[lkx]._idx;
1134
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 1) fin2++;
1135
+ fin0++;
1136
+ lkx = _linkA[lkx]._nxt;
1137
+ }
1138
+
1139
+ if(fin2 > 0)
1140
+ {
1141
+ bddword idy0;
1142
+ if(fin0 > 2)
1143
+ {
1144
+ BDD g = 0;
1145
+ lkx = _nodeA[ndx0]._lkx;
1146
+ while(lkx != BDDDG_NIL)
1147
+ {
1148
+ bddword idt = _linkA[lkx]._idx;
1149
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 0)
1150
+ g ^= _nodeA[BDDDG_Ndx(idt)]._f;
1151
+ lkx = _linkA[lkx]._nxt;
1152
+ }
1153
+ idy0 = ReferIdx(g);
1154
+ if(idy0 == BDDDG_NIL)
1155
+ {
1156
+ bddword ndy0 = NewNdx(g, BDDDG_XOR);
1157
+ if(ndy0 == BDDDG_NIL) return BDDDG_NIL;
1158
+ idy0 = BDDDG_PackIdx(ndy0, 0);
1159
+ lkx = _nodeA[ndx0]._lkx;
1160
+ while(lkx != BDDDG_NIL)
1161
+ {
1162
+ bddword idt = _linkA[lkx]._idx;
1163
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 0)
1164
+ if(LinkNodes(idy0, idt)) return BDDDG_NIL;
1165
+ lkx = _linkA[lkx]._nxt;
1166
+ }
1167
+ }
1168
+ }
1169
+ else
1170
+ {
1171
+ lkx = _nodeA[ndx0]._lkx;
1172
+ while(lkx != BDDDG_NIL)
1173
+ {
1174
+ bddword idt = _linkA[lkx]._idx;
1175
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 0)
1176
+ { idy0 = _linkA[lkx]._idx; break; }
1177
+ lkx = _linkA[lkx]._nxt;
1178
+ }
1179
+ }
1180
+
1181
+ bddword idy1 = BDDDG_InvSet(_c1);
1182
+
1183
+ if(BDDDG_Inv(idx0)) idy0 = BDDDG_InvAlt(idy0);
1184
+ if(BDDDG_Inv(idx1)) idy1 = BDDDG_InvAlt(idy1);
1185
+
1186
+ bddword ndy = NewNdx(f, BDDDG_XOR);
1187
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
1188
+ bddword idy = BDDDG_PackIdx(ndy, 0);
1189
+ if(LinkNodes(idy, BDDDG_InvReset(idx1)))
1190
+ return BDDDG_NIL;
1191
+
1192
+ _nodeA[ndx1]._mark = 0;
1193
+ if(Merge3(idy, idy0, idy1)) return BDDDG_NIL;;
1194
+ return (f == _nodeA[ndy]._f)? idy: BDDDG_InvAlt(idy);
1195
+ }
1196
+ _nodeA[ndx1]._mark = 0;
1197
+ }
1198
+
1199
+
1200
+ // Case1-OTHER ?
1201
+ if(_nodeA[ndx0]._type == BDDDG_OTHER
1202
+ && _nodeA[ndx1]._type == BDDDG_OTHER)
1203
+ {
1204
+ int fin0 = 0;
1205
+ int fin1 = 0;
1206
+ int fin2 = 0;
1207
+
1208
+ fin0 = Mark1(idx0);
1209
+ bddword lkx = _nodeA[ndx1]._lkx;
1210
+ while(lkx != BDDDG_NIL)
1211
+ {
1212
+ bddword idt = _linkA[lkx]._idx;
1213
+ if(_nodeA[BDDDG_Ndx(idt)]._mark != 0)
1214
+ { fin2++; _nodeA[BDDDG_Ndx(idt)]._mark = 3; }
1215
+ lkx = _linkA[lkx]._nxt;
1216
+ fin1++;
1217
+ }
1218
+
1219
+ // Case1-OTHER(a) ?
1220
+ if(fin2 > 0 && fin0 - fin2 == 1 && fin1 - fin2 == 1)
1221
+ {
1222
+ bddword idy0;
1223
+ lkx = _nodeA[ndx0]._lkx;
1224
+ while(lkx != BDDDG_NIL)
1225
+ {
1226
+
1227
+ idy0 = _linkA[lkx]._idx;
1228
+ if(_nodeA[BDDDG_Ndx(idy0)]._mark != 3) break;
1229
+ lkx = _linkA[lkx]._nxt;
1230
+ }
1231
+ bddword idy1;
1232
+ lkx = _nodeA[ndx1]._lkx;
1233
+ while(lkx != BDDDG_NIL)
1234
+ {
1235
+
1236
+ idy1 = _linkA[lkx]._idx;
1237
+ if(_nodeA[BDDDG_Ndx(idy1)]._mark != 3) break;
1238
+ lkx = _linkA[lkx]._nxt;
1239
+ }
1240
+
1241
+ BDD f0 = _nodeA[ndx0]._f;
1242
+ BDD f1 = _nodeA[ndx1]._f;
1243
+ BDD g0 = _nodeA[BDDDG_Ndx(idy0)]._f;
1244
+ BDD g1 = _nodeA[BDDDG_Ndx(idy1)]._f;
1245
+
1246
+ if(Func0(f0, g0) == Func0(f1, g1) &&
1247
+ Func0(f0, ~g0) == Func0(f1, ~g1))
1248
+ {
1249
+ bddword ndy = NewNdx(f, BDDDG_OTHER);
1250
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
1251
+ bddword idy = BDDDG_PackIdx(ndy, 0);
1252
+ lkx = _nodeA[ndx1]._lkx;
1253
+ while(lkx != BDDDG_NIL)
1254
+ {
1255
+ bddword idt = _linkA[lkx]._idx;
1256
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 3)
1257
+ if(LinkNodes(idy, idt)) return BDDDG_NIL;
1258
+ lkx = _linkA[lkx]._nxt;
1259
+ }
1260
+
1261
+ MarkSweep(idx0);
1262
+ if(Merge3(idy, idy0, idy1)) return BDDDG_NIL;;
1263
+ return idy;
1264
+ }
1265
+
1266
+ if(Func0(f0, g0) == Func0(f1, ~g1) &&
1267
+ Func0(f0, ~g0) == Func0(f1, g1))
1268
+ {
1269
+ bddword ndy = NewNdx(f, BDDDG_OTHER);
1270
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
1271
+ bddword idy = BDDDG_PackIdx(ndy, 0);
1272
+ lkx = _nodeA[ndx1]._lkx;
1273
+ while(lkx != BDDDG_NIL)
1274
+ {
1275
+ bddword idt = _linkA[lkx]._idx;
1276
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 3)
1277
+ if(LinkNodes(idy, idt)) return BDDDG_NIL;
1278
+ lkx = _linkA[lkx]._nxt;
1279
+ }
1280
+
1281
+ MarkSweep(idx0);
1282
+ if(Merge3(idy, idy0, BDDDG_InvAlt(idy1))) return BDDDG_NIL;;
1283
+ return idy;
1284
+ }
1285
+
1286
+ }
1287
+ MarkSweep(idx0);
1288
+
1289
+ // Case1-OTHER(b) ?
1290
+ if(fin2 > 1 && fin0 == fin2 && fin1 == fin2)
1291
+ {
1292
+ BDD f0 = f.At0(top);
1293
+ BDD f1 = f.At1(top);
1294
+ bddword idy0;
1295
+ lkx = _nodeA[ndx0]._lkx;
1296
+ while(lkx != BDDDG_NIL)
1297
+ {
1298
+ idy0 = _linkA[lkx]._idx;
1299
+ BDD g0 = _nodeA[BDDDG_Ndx(idy0)]._f;
1300
+ if(Func0(f0, g0) == Func0(f1, ~g0) &&
1301
+ Func0(f0, ~g0) == Func0(f1, g0) )
1302
+ {
1303
+ bddword ndy = NewNdx(f, BDDDG_OTHER);
1304
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
1305
+ bddword idy = BDDDG_PackIdx(ndy, 0);
1306
+ bddword lkx2 = _nodeA[ndx0]._lkx;
1307
+ while(lkx2 != BDDDG_NIL)
1308
+ {
1309
+ if(lkx != lkx2)
1310
+ if(LinkNodes(idy, _linkA[lkx2]._idx)) return BDDDG_NIL;
1311
+ lkx2 = _linkA[lkx2]._nxt;
1312
+ }
1313
+
1314
+ if(Merge3(idy, idy0, BDDDG_InvAlt(idy0))) return BDDDG_NIL;
1315
+ return idy;
1316
+ }
1317
+ lkx = _linkA[lkx]._nxt;
1318
+ }
1319
+ }
1320
+ }
1321
+
1322
+ // Case2-OTHER ? part 0
1323
+ if(_nodeA[ndx1]._type == BDDDG_OTHER)
1324
+ {
1325
+ Mark2R(idx0);
1326
+ bddword lkx = _nodeA[ndx1]._lkx;
1327
+ while(lkx != BDDDG_NIL)
1328
+ {
1329
+ bddword idy1 = _linkA[lkx]._idx;
1330
+ if(MarkChkR(idy1) == 0)
1331
+ {
1332
+ BDD f0 = _nodeA[ndx0]._f;
1333
+ f0 = BDDDG_Inv(idx0)? ~f0: f0;
1334
+ BDD f1 = _nodeA[ndx1]._f;
1335
+ f1 = BDDDG_Inv(idx1)? ~f1: f1;
1336
+ BDD g1 = _nodeA[BDDDG_Ndx(idy1)]._f;
1337
+ BDD h = Func0(f1, g1);
1338
+ //if(h == f0 || h == ~f0)
1339
+ if(h == f0)
1340
+ {
1341
+ bddword ndy = NewNdx(f, BDDDG_OTHER);
1342
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
1343
+ bddword idy = BDDDG_PackIdx(ndy, 0);
1344
+ bddword lkx2 = _nodeA[ndx1]._lkx;
1345
+ while(lkx2 != BDDDG_NIL)
1346
+ {
1347
+ if(lkx != lkx2)
1348
+ if(LinkNodes(idy, _linkA[lkx2]._idx)) return BDDDG_NIL;
1349
+ lkx2 = _linkA[lkx2]._nxt;
1350
+ }
1351
+
1352
+ MarkSweepR(idx0);
1353
+ if(Merge3(idy, BDDDG_InvAlt(_c1), idy1)) return BDDDG_NIL;
1354
+ return idy;
1355
+ }
1356
+ h = Func0(f1, ~g1);
1357
+ //if(h == f0 || h == ~f0)
1358
+ if(h == f0)
1359
+ {
1360
+ bddword ndy = NewNdx(f, BDDDG_OTHER);
1361
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
1362
+ bddword idy = BDDDG_PackIdx(ndy, 0);
1363
+ bddword lkx2 = _nodeA[ndx1]._lkx;
1364
+ while(lkx2 != BDDDG_NIL)
1365
+ {
1366
+ if(lkx != lkx2)
1367
+ if(LinkNodes(idy, _linkA[lkx2]._idx)) return BDDDG_NIL;
1368
+ lkx2 = _linkA[lkx2]._nxt;
1369
+ }
1370
+
1371
+ MarkSweepR(idx0);
1372
+ if(Merge3(idy, _c1, idy1)) return BDDDG_NIL;
1373
+ return idy;
1374
+ }
1375
+ }
1376
+ lkx = _linkA[lkx]._nxt;
1377
+ }
1378
+ MarkSweepR(idx0);
1379
+ }
1380
+
1381
+ // Case2-OTHER ? part 1
1382
+ if(_nodeA[ndx0]._type == BDDDG_OTHER)
1383
+ {
1384
+ Mark2R(idx1);
1385
+ bddword lkx = _nodeA[ndx0]._lkx;
1386
+ while(lkx != BDDDG_NIL)
1387
+ {
1388
+ bddword idy0 = _linkA[lkx]._idx;
1389
+ if(MarkChkR(idy0) == 0)
1390
+ {
1391
+ BDD f0 = _nodeA[ndx0]._f;
1392
+ f0 = BDDDG_Inv(idx0)? ~f0: f0;
1393
+ BDD f1 = _nodeA[ndx1]._f;
1394
+ f1 = BDDDG_Inv(idx1)? ~f1: f1;
1395
+ BDD g0 = _nodeA[BDDDG_Ndx(idy0)]._f;
1396
+ BDD h = Func0(f0, g0);
1397
+ //if(h == f1 || f == ~f1)
1398
+ if(h == f1)
1399
+ {
1400
+ bddword ndy = NewNdx(f, BDDDG_OTHER);
1401
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
1402
+ bddword idy = BDDDG_PackIdx(ndy, 0);
1403
+ bddword lkx2 = _nodeA[ndx0]._lkx;
1404
+ while(lkx2 != BDDDG_NIL)
1405
+ {
1406
+ if(lkx != lkx2)
1407
+ if(LinkNodes(idy, _linkA[lkx2]._idx)) return BDDDG_NIL;
1408
+ lkx2 = _linkA[lkx2]._nxt;
1409
+ }
1410
+
1411
+ MarkSweepR(idx1);
1412
+ if(Merge3(idy, idy0, BDDDG_InvAlt(_c1))) return BDDDG_NIL;
1413
+ return idy;
1414
+ }
1415
+ h = Func0(f0, ~g0);
1416
+ //if(h == f1 || f == ~f1)
1417
+ if(h == f1)
1418
+ {
1419
+ bddword ndy = NewNdx(f, BDDDG_OTHER);
1420
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
1421
+ bddword idy = BDDDG_PackIdx(ndy, 0);
1422
+ bddword lkx2 = _nodeA[ndx0]._lkx;
1423
+ while(lkx2 != BDDDG_NIL)
1424
+ {
1425
+ if(lkx != lkx2)
1426
+ if(LinkNodes(idy, _linkA[lkx2]._idx)) return BDDDG_NIL;
1427
+ lkx2 = _linkA[lkx2]._nxt;
1428
+ }
1429
+
1430
+ MarkSweepR(idx1);
1431
+ if(Merge3(idy, idy0, _c1)) return BDDDG_NIL;
1432
+ return idy;
1433
+ }
1434
+ }
1435
+ lkx = _linkA[lkx]._nxt;
1436
+ }
1437
+ MarkSweepR(idx1);
1438
+ }
1439
+
1440
+ // Case3-OTHER?
1441
+ MarkSweepR(idx0);
1442
+ MarkSweepR(idx1);
1443
+ Mark2R(idx0);
1444
+ Mark2R(idx1);
1445
+ Mark3R(idx0);
1446
+ Mark3R(idx1);
1447
+
1448
+ bddword idx = ReferIdx(BDDvar(top));
1449
+ if(idx == BDDDG_NIL)
1450
+ {
1451
+ bddword ndx = NewNdx(BDDvar(top), BDDDG_LIT);
1452
+ if(ndx == BDDDG_NIL) return BDDDG_NIL;
1453
+ idx = BDDDG_PackIdx(ndx, 0);
1454
+ }
1455
+
1456
+ bddword ndy = NewNdx(f, BDDDG_OTHER);
1457
+ if(ndy == BDDDG_NIL) return BDDDG_NIL;
1458
+ bddword idy = BDDDG_PackIdx(ndy, 0);
1459
+ if(LinkNodes(idy, idx)) return BDDDG_NIL;
1460
+ if(LinkNodesC3(idy, idx0)) return BDDDG_NIL;
1461
+ if(LinkNodesC3(idy, idx1)) return BDDDG_NIL;
1462
+ PhaseSweep(idy);
1463
+ MarkSweepR(idx0);
1464
+ MarkSweepR(idx1);
1465
+ return idy;
1466
+ }
1467
+
1468
+ int BDDDG::LinkNodesC3(bddword idy, bddword idx)
1469
+ {
1470
+ bddword ndx = BDDDG_Ndx(idx);
1471
+ bddword lkx;
1472
+ switch(_nodeA[ndx]._mark)
1473
+ {
1474
+ case 1:
1475
+ lkx = _nodeA[ndx]._lkx;
1476
+ while(lkx != BDDDG_NIL)
1477
+ {
1478
+ if(LinkNodesC3(idy, _linkA[lkx]._idx)) return 1;
1479
+ lkx = _linkA[lkx]._nxt;
1480
+ }
1481
+ break;
1482
+ case 2:
1483
+ if(LinkNodes(idy, idx)) return 1;
1484
+ _nodeA[ndx]._mark = 9;
1485
+ break;
1486
+ case 3:
1487
+ if(LinkNodes(idy, idx)) return 1;
1488
+ break;
1489
+ case 4:
1490
+ {
1491
+ lkx = _nodeA[ndx]._lkx;
1492
+ while(lkx != BDDDG_NIL)
1493
+ {
1494
+ bddword idt = _linkA[lkx]._idx;
1495
+ bddword ndxP = _nodeA[BDDDG_Ndx(idt)]._ndxP;
1496
+ if(ndxP != BDDDG_NIL && ndxP != ndx)
1497
+ {
1498
+ if(_nodeA[ndxP]._type == BDDDG_OR &&
1499
+ _nodeA[ndx]._type == BDDDG_OR )
1500
+ {
1501
+ BDD g = 0;
1502
+ int fin = 0;
1503
+ bddword lkx2 = lkx;
1504
+ while(lkx2 != BDDDG_NIL)
1505
+ {
1506
+ bddword idt2 = _linkA[lkx2]._idx;
1507
+ if(ndxP == _nodeA[BDDDG_Ndx(idt2)]._ndxP)
1508
+ {
1509
+ if(_nodeA[BDDDG_Ndx(idt2)]._invP
1510
+ != (char) BDDDG_Inv(idt2))
1511
+ _nodeA[BDDDG_Ndx(idt2)]._ndxP = BDDDG_NIL;
1512
+ else
1513
+ {
1514
+ BDD g2 = _nodeA[BDDDG_Ndx(idt2)]._f;
1515
+ g |= BDDDG_Inv(idt2)? ~g2:g2;
1516
+ fin++;
1517
+ }
1518
+ }
1519
+ lkx2 = _linkA[lkx2]._nxt;
1520
+ }
1521
+ if(fin >= 2)
1522
+ {
1523
+ bddword idy0 = ReferIdx(g);
1524
+ if(idy0 == BDDDG_NIL)
1525
+ {
1526
+ bddword ndy0 = NewNdx(g, BDDDG_OR);
1527
+ if(ndy0 == BDDDG_NIL) return 1;
1528
+ idy0 = BDDDG_PackIdx(ndy0, 0);
1529
+ lkx2 = lkx;
1530
+ while(lkx2 != BDDDG_NIL)
1531
+ {
1532
+ bddword idt2 = _linkA[lkx2]._idx;
1533
+ if(ndxP == _nodeA[BDDDG_Ndx(idt2)]._ndxP)
1534
+ if(LinkNodes(idy0, idt2)) return 1;
1535
+ lkx2 = _linkA[lkx2]._nxt;
1536
+ }
1537
+ }
1538
+ if(LinkNodes(idy, idy0)) return 1;
1539
+
1540
+ lkx2 = lkx;
1541
+ while(lkx2 != BDDDG_NIL)
1542
+ {
1543
+ bddword idt2 = _linkA[lkx2]._idx;
1544
+ if(ndxP == _nodeA[BDDDG_Ndx(idt2)]._ndxP)
1545
+ _nodeA[BDDDG_Ndx(idt2)]._mark = 9;
1546
+ lkx2 = _linkA[lkx2]._nxt;
1547
+ }
1548
+ }
1549
+ lkx2 = lkx;
1550
+ while(lkx2 != BDDDG_NIL)
1551
+ {
1552
+ bddword idt2 = _linkA[lkx2]._idx;
1553
+ if(ndxP == _nodeA[BDDDG_Ndx(idt2)]._ndxP)
1554
+ _nodeA[BDDDG_Ndx(idt2)]._ndxP = BDDDG_NIL;
1555
+ lkx2 = _linkA[lkx2]._nxt;
1556
+ }
1557
+ }
1558
+
1559
+ if(_nodeA[ndxP]._type == BDDDG_XOR &&
1560
+ _nodeA[ndx]._type == BDDDG_XOR )
1561
+ {
1562
+ BDD g = 0;
1563
+ int fin = 0;
1564
+ bddword lkx2 = lkx;
1565
+ while(lkx2 != BDDDG_NIL)
1566
+ {
1567
+ bddword idt2 = _linkA[lkx2]._idx;
1568
+ if(ndxP == _nodeA[BDDDG_Ndx(idt2)]._ndxP)
1569
+ {
1570
+ g ^= _nodeA[BDDDG_Ndx(idt2)]._f;
1571
+ fin++;
1572
+ }
1573
+ lkx2 = _linkA[lkx2]._nxt;
1574
+ }
1575
+ if(fin >= 2)
1576
+ {
1577
+ bddword idy0 = ReferIdx(g);
1578
+ if(idy0 == BDDDG_NIL)
1579
+ {
1580
+ bddword ndy0 = NewNdx(g, BDDDG_XOR);
1581
+ if(ndy0 == BDDDG_NIL) return 1;
1582
+ idy0 = BDDDG_PackIdx(ndy0, 0);
1583
+ lkx2 = lkx;
1584
+ while(lkx2 != BDDDG_NIL)
1585
+ {
1586
+ bddword idt2 = _linkA[lkx2]._idx;
1587
+ if(ndxP == _nodeA[BDDDG_Ndx(idt2)]._ndxP)
1588
+ if(LinkNodes(idy0, idt2)) return 1;
1589
+ lkx2 = _linkA[lkx2]._nxt;
1590
+ }
1591
+ }
1592
+ if(LinkNodes(idy, idy0)) return 1;
1593
+
1594
+ lkx2 = lkx;
1595
+ while(lkx2 != BDDDG_NIL)
1596
+ {
1597
+ bddword idt2 = _linkA[lkx2]._idx;
1598
+ if(ndxP == _nodeA[BDDDG_Ndx(idt2)]._ndxP)
1599
+ _nodeA[BDDDG_Ndx(idt2)]._mark = 9;
1600
+ lkx2 = _linkA[lkx2]._nxt;
1601
+ }
1602
+ }
1603
+ lkx2 = lkx;
1604
+ while(lkx2 != BDDDG_NIL)
1605
+ {
1606
+ bddword idt2 = _linkA[lkx2]._idx;
1607
+ if(ndxP == _nodeA[BDDDG_Ndx(idt2)]._ndxP)
1608
+ _nodeA[BDDDG_Ndx(idt2)]._ndxP = BDDDG_NIL;
1609
+ lkx2 = _linkA[lkx2]._nxt;
1610
+ }
1611
+ }
1612
+ }
1613
+ lkx = _linkA[lkx]._nxt;
1614
+ }
1615
+
1616
+
1617
+ if(_nodeA[ndx]._type == BDDDG_OR)
1618
+ {
1619
+ BDD g = 0;
1620
+ int fin = 0;
1621
+ lkx = _nodeA[ndx]._lkx;
1622
+ while(lkx != BDDDG_NIL)
1623
+ {
1624
+ bddword idt = _linkA[lkx]._idx;
1625
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 3)
1626
+ {
1627
+ g |= _nodeA[BDDDG_Ndx(idt)]._f;
1628
+ fin++;
1629
+ }
1630
+ lkx = _linkA[lkx]._nxt;
1631
+ }
1632
+ if(fin >= 2)
1633
+ {
1634
+ bddword idy0 = ReferIdx(g);
1635
+ if(idy0 == BDDDG_NIL)
1636
+ {
1637
+ bddword ndy0 = NewNdx(g, BDDDG_OR);
1638
+ if(ndy0 == BDDDG_NIL) return 1;
1639
+ idy0 = BDDDG_PackIdx(ndy0, 0);
1640
+ lkx = _nodeA[ndx]._lkx;
1641
+ while(lkx != BDDDG_NIL)
1642
+ {
1643
+ bddword idt = _linkA[lkx]._idx;
1644
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 3)
1645
+ if(LinkNodes(idy0, idt)) return 1;
1646
+ lkx = _linkA[lkx]._nxt;
1647
+ }
1648
+ }
1649
+ if(LinkNodes(idy, idy0)) return 1;
1650
+ lkx = _nodeA[ndx]._lkx;
1651
+ while(lkx != BDDDG_NIL)
1652
+ {
1653
+ bddword idt = _linkA[lkx]._idx;
1654
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 3)
1655
+ _nodeA[BDDDG_Ndx(idt)]._mark = 9;
1656
+ lkx = _linkA[lkx]._nxt;
1657
+ }
1658
+ }
1659
+ }
1660
+
1661
+ if(_nodeA[ndx]._type == BDDDG_XOR)
1662
+ {
1663
+ BDD g = 0;
1664
+ int fin = 0;
1665
+ lkx = _nodeA[ndx]._lkx;
1666
+ while(lkx != BDDDG_NIL)
1667
+ {
1668
+ bddword idt = _linkA[lkx]._idx;
1669
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 3)
1670
+ {
1671
+ g ^= _nodeA[BDDDG_Ndx(idt)]._f;
1672
+ fin++;
1673
+ }
1674
+ lkx = _linkA[lkx]._nxt;
1675
+ }
1676
+ if(fin >= 2)
1677
+ {
1678
+ bddword idy0 = ReferIdx(g);
1679
+ if(idy0 == BDDDG_NIL)
1680
+ {
1681
+ bddword ndy0 = NewNdx(g, BDDDG_XOR);
1682
+ if(ndy0 == BDDDG_NIL) return 1;
1683
+ idy0 = BDDDG_PackIdx(ndy0, 0);
1684
+ lkx = _nodeA[ndx]._lkx;
1685
+ while(lkx != BDDDG_NIL)
1686
+ {
1687
+ bddword idt = _linkA[lkx]._idx;
1688
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 3)
1689
+ if(LinkNodes(idy0, idt)) return 1;
1690
+ lkx = _linkA[lkx]._nxt;
1691
+ }
1692
+ }
1693
+ if(LinkNodes(idy, idy0)) return 1;
1694
+ lkx = _nodeA[ndx]._lkx;
1695
+ while(lkx != BDDDG_NIL)
1696
+ {
1697
+ bddword idt = _linkA[lkx]._idx;
1698
+ if(_nodeA[BDDDG_Ndx(idt)]._mark == 3)
1699
+ _nodeA[BDDDG_Ndx(idt)]._mark = 9;
1700
+ lkx = _linkA[lkx]._nxt;
1701
+ }
1702
+ }
1703
+ }
1704
+ }
1705
+
1706
+ lkx = _nodeA[ndx]._lkx;
1707
+ while(lkx != BDDDG_NIL)
1708
+ {
1709
+ if(LinkNodesC3(idy, _linkA[lkx]._idx)) return 1;
1710
+ lkx = _linkA[lkx]._nxt;
1711
+ }
1712
+ break;
1713
+ case 9:
1714
+ break;
1715
+ default:
1716
+ cerr << "<ERROR> BDDDG::LinkNodesC3(): wrong case (";
1717
+ cerr << _nodeA[ndx]._mark << ")\n";
1718
+ exit(1);
1719
+ }
1720
+ return 0;
1721
+ }
1722
+
1723
+ BDD BDDDG::Func0(BDD f, BDD g)
1724
+ {
1725
+ BDD h = f;
1726
+ while(g != 0)
1727
+ {
1728
+ int top = g.Top();
1729
+ BDD g0 = g.At0(top);
1730
+ if(g0 != 1)
1731
+ {
1732
+ g = g0;
1733
+ h = h.At0(top);
1734
+ }
1735
+ else
1736
+ {
1737
+ g = g.At1(top);
1738
+ h = h.At1(top);
1739
+ }
1740
+ }
1741
+ return h;
1742
+ }
1743
+
1744
+ int BDDDG::Merge3(bddword idy, bddword idy0, bddword idy1)
1745
+ {
1746
+ int top = _nodeA[BDDDG_Ndx(idy)]._f.Top();
1747
+ BDD h0 = BDDDG_Inv(idy0)?
1748
+ ~(_nodeA[BDDDG_Ndx(idy0)]._f): _nodeA[BDDDG_Ndx(idy0)]._f;
1749
+ BDD h1 = BDDDG_Inv(idy1)?
1750
+ ~(_nodeA[BDDDG_Ndx(idy1)]._f): _nodeA[BDDDG_Ndx(idy1)]._f;
1751
+ BDD h = (~BDDvar(top) & h0) | (BDDvar(top) & h1);
1752
+ bddword idx = ReferIdx(h);
1753
+ if(idx == BDDDG_NIL) idx = Merge(h, idy0, idy1);
1754
+ if(idx == BDDDG_NIL) return 1;
1755
+ if(LinkNodes(idy, idx)) return BDDDG_NIL;
1756
+ PhaseSweep(idy);
1757
+ return 0;
1758
+ }
1759
+
1760
+ int BDDDG::PrintDecomp(BDD f)
1761
+ {
1762
+ bddword idx = Decomp(f);
1763
+ if(idx == BDDDG_NIL) return 1;
1764
+ Print0(idx);
1765
+ cout << "\n";
1766
+ return 0;
1767
+ }
1768
+
1769
+ void BDDDG::Print0(bddword idx)
1770
+ {
1771
+ if(BDDDG_Inv(idx)) cout << "!";
1772
+ bddword ndx = BDDDG_Ndx(idx);
1773
+ bddword lkx;
1774
+ switch(_nodeA[ndx]._type)
1775
+ {
1776
+ case BDDDG_C1:
1777
+ cout << "1 ";
1778
+ break;
1779
+ case BDDDG_LIT:
1780
+ cout << "x" << _nodeA[ndx]._f.Top() << " ";
1781
+ break;
1782
+ case BDDDG_OR:
1783
+ cout << "OR( ";
1784
+ lkx = _nodeA[ndx]._lkx;
1785
+ while(lkx != BDDDG_NIL)
1786
+ {
1787
+ Print0(_linkA[lkx]._idx);
1788
+ lkx = _linkA[lkx]._nxt;
1789
+ }
1790
+ cout << ") ";
1791
+ break;
1792
+ case BDDDG_XOR:
1793
+ cout << "XOR( ";
1794
+ lkx = _nodeA[ndx]._lkx;
1795
+ while(lkx != BDDDG_NIL)
1796
+ {
1797
+ Print0(_linkA[lkx]._idx);
1798
+ lkx = _linkA[lkx]._nxt;
1799
+ }
1800
+ cout << ") ";
1801
+ break;
1802
+ case BDDDG_OTHER:
1803
+ cout << "[ ";
1804
+ lkx = _nodeA[ndx]._lkx;
1805
+ while(lkx != BDDDG_NIL)
1806
+ {
1807
+ Print0(_linkA[lkx]._idx);
1808
+ lkx = _linkA[lkx]._nxt;
1809
+ }
1810
+ cout << "] ";
1811
+ break;
1812
+ default:
1813
+ cerr << "<ERROR> BDDDG::Print0: wrong case (";
1814
+ cerr << (int)_nodeA[ndx]._type << ")\n";
1815
+ exit(1);
1816
+ }
1817
+ }
1818
+