nysol-zdd 3.0.2

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