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,199 @@
1
+ /************************************************
2
+ * ZBDD-based SOP class (SAPPORO-1.55) - Header *
3
+ * (C) Shin-ichi MINATO (Dec. 11, 2012) *
4
+ ************************************************/
5
+
6
+ class SOP;
7
+ class SOPV;
8
+
9
+ #ifndef _SOP_
10
+ #define _SOP_
11
+
12
+ #include "ZBDD.h"
13
+
14
+ class SOP;
15
+ extern int SOP_NewVar(void);
16
+ extern int SOP_NewVarOfLev(int);
17
+
18
+ extern SOP operator*(const SOP&, const SOP&);
19
+ extern SOP operator/(const SOP&, const SOP&);
20
+ extern SOP operator%(const SOP&, const SOP&);
21
+
22
+ extern SOP SOP_ISOP(BDD);
23
+ extern SOP SOP_ISOP(BDD, BDD);
24
+
25
+ class SOP
26
+ {
27
+ ZBDD _zbdd;
28
+ public:
29
+ SOP() { _zbdd = ZBDD(); }
30
+ SOP(int val) { _zbdd = ZBDD(val); }
31
+ SOP(const SOP& f) { _zbdd = f._zbdd; }
32
+ SOP(const ZBDD& zbdd) { _zbdd = zbdd; }
33
+ ~SOP() { }
34
+
35
+ SOP& operator=(const SOP& f) { _zbdd = f._zbdd; return *this; }
36
+
37
+ SOP& operator&=(const SOP& f)
38
+ { _zbdd = _zbdd & f._zbdd; return *this; }
39
+
40
+ SOP& operator+=(const SOP& f)
41
+ { _zbdd = _zbdd + f._zbdd; return *this; }
42
+
43
+ SOP& operator-=(const SOP& f)
44
+ { _zbdd = _zbdd - f._zbdd; return *this; }
45
+
46
+ SOP& operator*=(const SOP&); // inline
47
+ SOP& operator/=(const SOP&); // inline
48
+ SOP& operator%=(const SOP&); // inline
49
+ SOP& operator<<=(int); // inline
50
+ SOP& operator>>=(int); // inline
51
+
52
+ SOP operator<<(int) const;
53
+ SOP operator>>(int) const;
54
+ SOP And0(int) const;
55
+ SOP And1(int) const;
56
+ SOP Factor0(int) const;
57
+ SOP Factor1(int) const;
58
+ SOP FactorD(int) const;
59
+
60
+ int Top(void) const { return (_zbdd.Top() + 1) & ~1; }
61
+
62
+ bddword Size(void) const;
63
+ bddword Cube(void) const;
64
+ bddword Lit(void) const;
65
+
66
+ int IsPolyCube(void) const;
67
+ int IsPolyLit(void) const;
68
+ SOP Divisor(void) const;
69
+ SOP Implicants(BDD) const;
70
+ SOP Support(void) const;
71
+ //SOP BoolDiv(SOP, int) const;
72
+ //SOP BoolDiv(SOP, SOP, int) const;
73
+ //SOP BoolDiv(BDD, int) const;
74
+
75
+ void Print(void) const;
76
+ int PrintPla(void) const;
77
+
78
+ ZBDD GetZBDD(void) const { return _zbdd; }
79
+ BDD GetBDD(void) const;
80
+ SOP InvISOP(void) const;
81
+
82
+ SOP Swap(int, int) const;
83
+
84
+ friend SOP operator&(const SOP&, const SOP&);
85
+ friend SOP operator+(const SOP&, const SOP&);
86
+ friend SOP operator-(const SOP&, const SOP&);
87
+ friend int operator==(const SOP&, const SOP&);
88
+ };
89
+
90
+ inline SOP operator&(const SOP& f, const SOP& g)
91
+ { return SOP(f._zbdd & g._zbdd); }
92
+
93
+ inline SOP operator+(const SOP& f, const SOP& g)
94
+ { return SOP(f._zbdd + g._zbdd); }
95
+
96
+ inline SOP operator-(const SOP& f, const SOP& g)
97
+ { return SOP(f._zbdd - g._zbdd); }
98
+
99
+ inline int operator==(const SOP& f, const SOP& g)
100
+ { return f._zbdd == g._zbdd; }
101
+
102
+ inline int operator!=(const SOP& f, const SOP& g)
103
+ { return !(f == g); }
104
+
105
+ inline SOP operator%(const SOP& f, const SOP& p)
106
+ { return f - (f/p) * p; }
107
+
108
+ inline SOP& SOP::operator*=(const SOP& f)
109
+ { return *this = *this * f; }
110
+
111
+ inline SOP& SOP::operator/=(const SOP& f)
112
+ { return *this = *this / f; }
113
+
114
+ inline SOP& SOP::operator%=(const SOP& f)
115
+ { return *this = *this - (*this/f) * f; }
116
+
117
+ inline SOP& SOP::operator<<=(int n) { return *this = *this << n; }
118
+ inline SOP& SOP::operator>>=(int n) { return *this = *this >> n; }
119
+
120
+
121
+
122
+
123
+ class SOPV;
124
+ extern int SOPV_NewVar(void);
125
+ extern int SOPV_NewVarOfLev(int);
126
+
127
+ extern SOPV SOPV_ISOP(BDDV);
128
+ extern SOPV SOPV_ISOP(BDDV, BDDV);
129
+ extern SOPV SOPV_ISOP2(BDDV);
130
+ extern SOPV SOPV_ISOP2(BDDV, BDDV);
131
+
132
+ class SOPV
133
+ {
134
+ ZBDDV _v;
135
+
136
+ public:
137
+ SOPV(void) { _v = ZBDDV(); }
138
+ SOPV(const SOPV& v) { _v = v._v; }
139
+ SOPV(const ZBDDV& zbddv) { _v = zbddv; }
140
+ SOPV(const SOP& f, int loc = 0) { _v = ZBDDV(f.GetZBDD(), loc); }
141
+ ~SOPV() { }
142
+
143
+ SOPV& operator=(const SOPV& v) { _v = v._v; return *this; }
144
+ SOPV operator&=(const SOPV& v) { _v = _v & v._v; return *this; }
145
+ SOPV operator+=(const SOPV& v) { _v = _v + v._v; return *this; }
146
+ SOPV operator-=(const SOPV& v) { _v = _v - v._v; return *this; }
147
+
148
+ SOPV operator<<=(int); // inline
149
+ SOPV operator>>=(int); // inline
150
+
151
+ SOPV operator<<(int n) const { return SOPV(_v << (n<<1)); }
152
+ SOPV operator>>(int n) const { return SOPV(_v >> (n<<1)); }
153
+
154
+ SOPV And0(int) const;
155
+ SOPV And1(int) const;
156
+ SOPV Factor0(int) const;
157
+ SOPV Factor1(int) const;
158
+ SOPV FactorD(int) const;
159
+
160
+ int Top(void) const { return (_v.Top() + 1) & ~1; }
161
+ bddword Size(void) const;
162
+ bddword Cube(void) const;
163
+ bddword Lit(void) const;
164
+ void Print(void) const;
165
+ int PrintPla(void) const;
166
+
167
+ int Last(void) const {return _v.Last(); }
168
+ SOPV Mask(int start, int length = 1) const
169
+ { return SOPV(_v.Mask(start, length)); }
170
+
171
+ SOP GetSOP(int) const;
172
+ ZBDDV GetZBDDV(void) const { return _v; }
173
+
174
+ SOPV Swap(int, int) const;
175
+
176
+ friend SOPV operator&(const SOPV&, const SOPV&);
177
+ friend SOPV operator+(const SOPV&, const SOPV&);
178
+ friend SOPV operator-(const SOPV&, const SOPV&);
179
+
180
+ friend int operator==(const SOPV&, const SOPV&);
181
+ };
182
+
183
+ inline SOPV operator&(const SOPV& f, const SOPV& g)
184
+ { return SOPV(f._v & g._v); }
185
+
186
+ inline SOPV operator+(const SOPV& f, const SOPV& g)
187
+ { return SOPV(f._v + g._v); }
188
+
189
+ inline SOPV operator-(const SOPV& f, const SOPV& g)
190
+ { return SOPV(f._v - g._v); }
191
+
192
+ inline int operator==(const SOPV& v1, const SOPV& v2)
193
+ { return v1._v == v2._v; }
194
+
195
+ inline int operator!=(const SOPV& v1, const SOPV& v2)
196
+ { return !(v1 == v2); }
197
+
198
+ #endif // _SOP_
199
+
@@ -0,0 +1,1035 @@
1
+ /****************************************
2
+ * ZBDD+ Manipulator (SAPPORO-1.70) *
3
+ * (Main part) *
4
+ * (C) Shin-ichi MINATO (Sep. 16, 2015) *
5
+ ****************************************/
6
+
7
+ #include "ZBDD.h"
8
+
9
+ #define BDD_CPP
10
+ #include "bddc.h"
11
+
12
+ using std::cout;
13
+
14
+ static const char BC_ZBDD_MULT = 20;
15
+ static const char BC_ZBDD_DIV = 21;
16
+ static const char BC_ZBDD_RSTR = 22;
17
+ static const char BC_ZBDD_PERMIT = 23;
18
+ static const char BC_ZBDD_PERMITSYM = 24;
19
+ static const char BC_ZBDD_SYMCHK = 25;
20
+ static const char BC_ZBDD_ALWAYS = 26;
21
+ static const char BC_ZBDD_SYMSET = 27;
22
+ static const char BC_ZBDD_COIMPSET = 28;
23
+ static const char BC_ZBDD_MEET = 29;
24
+
25
+ static const char BC_ZBDD_ZSkip = 65;
26
+ static const char BC_ZBDD_INTERSEC = 66;
27
+
28
+ extern "C"
29
+ {
30
+ int rand();
31
+ };
32
+
33
+ // class ZBDD ---------------------------------------------
34
+
35
+ void ZBDD::Export(FILE *strm) const
36
+ {
37
+ bddword p = _zbdd;
38
+ bddexport(strm, &p, 1);
39
+ }
40
+
41
+ void ZBDD::Print() const
42
+ {
43
+ cout << "[ " << GetID();
44
+ cout << " Var:" << Top() << "(" << BDD_LevOfVar(Top()) << ")";
45
+ cout << " Size:" << Size() << " Card:";
46
+ cout << Card() << " Lit:" << Lit() << " Len:" << Len() << " ]\n";
47
+ cout.flush();
48
+ }
49
+
50
+ void ZBDD::PrintPla() const { ZBDDV(*this).PrintPla(); }
51
+
52
+ #define ZBDD_CACHE_CHK_RETURN(op, fx, gx) \
53
+ { ZBDD h = BDD_CacheZBDD(op, fx, gx); \
54
+ if(h != -1) return h; \
55
+ BDD_RECUR_INC; }
56
+
57
+ #define ZBDD_CACHE_ENT_RETURN(op, fx, gx, h) \
58
+ { BDD_RECUR_DEC; \
59
+ if(h != -1) BDD_CacheEnt(op, fx, gx, h.GetID()); \
60
+ return h; }
61
+
62
+ ZBDD ZBDD::Swap(int v1, int v2) const
63
+ {
64
+ if(v1 == v2) return *this;
65
+ ZBDD f00 = this->OffSet(v1).OffSet(v2);
66
+ ZBDD f11 = this->OnSet(v1).OnSet(v2);
67
+ ZBDD h = *this - f00 - f11;
68
+ return h.Change(v1).Change(v2) + f00 + f11;
69
+ }
70
+
71
+ ZBDD ZBDD::Restrict(const ZBDD& g) const
72
+ {
73
+ if(*this == -1) return -1;
74
+ if(g == -1) return -1;
75
+ if(*this == 0) return 0;
76
+ if(g == 0) return 0;
77
+ if(*this == g) return g;
78
+ if((g & 1) == 1) return *this;
79
+ ZBDD f = *this - 1;
80
+
81
+ int top = f.Top();
82
+ if(BDD_LevOfVar(top) < BDD_LevOfVar(g.Top())) top = g.Top();
83
+
84
+ bddword fx = f.GetID();
85
+ bddword gx = g.GetID();
86
+ ZBDD_CACHE_CHK_RETURN(BC_ZBDD_RSTR, fx, gx);
87
+
88
+ ZBDD f1 = f.OnSet0(top);
89
+ ZBDD f0 = f.OffSet(top);
90
+ ZBDD g1 = g.OnSet0(top);
91
+ ZBDD g0 = g.OffSet(top);
92
+ ZBDD h = f1.Restrict(g1 + g0).Change(top) + f0.Restrict(g0);
93
+
94
+ ZBDD_CACHE_ENT_RETURN(BC_ZBDD_RSTR, fx, gx, h);
95
+ }
96
+
97
+ ZBDD ZBDD::Permit(const ZBDD& g) const
98
+ {
99
+ if(*this == -1) return -1;
100
+ if(g == -1) return -1;
101
+ if(*this == 0) return 0;
102
+ if(g == 0) return 0;
103
+ if(*this == g) return *this;
104
+ if(g == 1) return *this & 1;
105
+ if(*this == 1) return 1;
106
+
107
+ int top = Top();
108
+ if(BDD_LevOfVar(top) < BDD_LevOfVar(g.Top())) top = g.Top();
109
+
110
+ bddword fx = GetID();
111
+ bddword gx = g.GetID();
112
+ ZBDD_CACHE_CHK_RETURN(BC_ZBDD_PERMIT, fx, gx);
113
+
114
+ ZBDD f1 = OnSet0(top);
115
+ ZBDD f0 = OffSet(top);
116
+ ZBDD g1 = g.OnSet0(top);
117
+ ZBDD g0 = g.OffSet(top);
118
+ ZBDD h = f1.Permit(g1).Change(top) + f0.Permit(g0 + g1);
119
+
120
+ ZBDD_CACHE_ENT_RETURN(BC_ZBDD_PERMIT, fx, gx, h);
121
+ }
122
+
123
+ ZBDD ZBDD::PermitSym(int n) const
124
+ {
125
+ if(*this == -1) return -1;
126
+ if(*this == 0) return 0;
127
+ if(*this == 1) return 1;
128
+ if(n < 1) return *this & 1;
129
+
130
+ int top = Top();
131
+
132
+ bddword fx = GetID();
133
+ ZBDD_CACHE_CHK_RETURN(BC_ZBDD_PERMITSYM, fx, n);
134
+
135
+ ZBDD f1 = OnSet0(top);
136
+ ZBDD f0 = OffSet(top);
137
+ ZBDD h = f1.PermitSym(n - 1).Change(top) + f0.PermitSym(n);
138
+
139
+ ZBDD_CACHE_ENT_RETURN(BC_ZBDD_PERMITSYM, fx, n, h);
140
+ }
141
+
142
+ ZBDD ZBDD::Always() const
143
+ {
144
+ if(*this == -1) return -1;
145
+ if(*this == 0 || *this == 1) return 0;
146
+
147
+ bddword fx = GetID();
148
+ ZBDD_CACHE_CHK_RETURN(BC_ZBDD_ALWAYS, fx, 0);
149
+
150
+ int t = Top();
151
+ ZBDD f1 = OnSet0(t);
152
+ ZBDD f0 = OffSet(t);
153
+ ZBDD h = f1.Always();
154
+ if(f0 == 0) h += ZBDD(1).Change(t);
155
+ else if(h != 0) h &= f0.Always();
156
+
157
+ ZBDD_CACHE_ENT_RETURN(BC_ZBDD_ALWAYS, fx, 0, h);
158
+ }
159
+
160
+ int ZBDD::SymChk(int v1, int v2) const
161
+ {
162
+ if(*this == -1) return -1;
163
+ if(v1 <= 0) BDDerr("ZBDD::SymChk(): invalid v1.", v1);
164
+ if(v2 <= 0) BDDerr("ZBDD::SymChk(): invalid v2.", v2);
165
+ if(*this == 0 || *this == 1) return 1;
166
+ if(v1 == v2) return 1;
167
+ if(v1 < v2) { int tmp = v1; v1 = v2; v2 = tmp; }
168
+
169
+ ZBDD S = ZBDD(1).Change(v1) + ZBDD(1).Change(v2);
170
+ bddword fx = GetID();
171
+ bddword gx = S.GetID();
172
+ int Y = BDD_CacheInt(BC_ZBDD_SYMCHK, fx, gx);
173
+ if(Y != -1) return Y;
174
+ BDD_RECUR_INC;
175
+
176
+ int t = Top();
177
+ if(BDD_LevOfVar(t) > BDD_LevOfVar(v1))
178
+ {
179
+ Y = OnSet0(t).SymChk(v1, v2);
180
+ if(Y == 1) Y = OffSet(t).SymChk(v1, v2);
181
+ }
182
+ else
183
+ {
184
+ ZBDD f0 = OffSet(v1);
185
+ ZBDD f1 = OnSet0(v1);
186
+ int t0 = f0.Top();
187
+ int t1 = f1.Top();
188
+ int t2 = (BDD_LevOfVar(t0) > BDD_LevOfVar(t1))? t0: t1;
189
+ if(BDD_LevOfVar(t2) <= BDD_LevOfVar(v2))
190
+ Y = (f0.OnSet0(v2) == f1.OffSet(v2));
191
+ else
192
+ {
193
+ ZBDD g0 = f0.OffSet(t2) + f1.OffSet(t2).Change(t2);
194
+ ZBDD g1 = f0.OnSet0(t2) + f1.OnSet0(t2).Change(t2);
195
+ Y = g1.SymChk(t2, v2);
196
+ if(Y == 1) Y = g0.SymChk(t2, v2);
197
+ }
198
+ }
199
+
200
+ BDD_RECUR_DEC;
201
+ if(Y != -1) BDD_CacheEnt(BC_ZBDD_SYMCHK, fx, gx, Y);
202
+ return Y;
203
+ }
204
+
205
+ ZBDD ZBDD::SymGrp() const
206
+ {
207
+ ZBDD h = 0;
208
+ ZBDD g = Support();
209
+ while(g != 0)
210
+ {
211
+ int t = g.Top();
212
+ ZBDD hh = ZBDD(1).Change(t);
213
+ g = g.OffSet(t);
214
+
215
+ ZBDD g2 = g;
216
+ while(g2 != 0)
217
+ {
218
+ int t2 = g2.Top();
219
+ g2 = g2.OffSet(t2);
220
+ int y = SymChk(t, t2);
221
+ if(y == -1) return -1;
222
+ if(y)
223
+ {
224
+ hh = hh.Change(t2);
225
+ g = g.OffSet(t2);
226
+ }
227
+ }
228
+ if(hh.OnSet0(t) != 1) h += hh;
229
+ }
230
+ return h;
231
+ }
232
+
233
+ ZBDD ZBDD::SymGrpNaive() const
234
+ {
235
+ ZBDD h = 0;
236
+ ZBDD g = Support();
237
+ while(g != 0)
238
+ {
239
+ int t = g.Top();
240
+ ZBDD hh = ZBDD(1).Change(t);
241
+ g = g.OffSet(t);
242
+ ZBDD f0 = OffSet(t);
243
+ ZBDD f1 = OnSet0(t);
244
+
245
+ ZBDD g2 = g;
246
+ while(g2 != 0)
247
+ {
248
+ int t2 = g2.Top();
249
+ g2 = g2.OffSet(t2);
250
+ if(f0.OnSet0(t2) == f1.OffSet(t2))
251
+ {
252
+ hh = hh.Change(t2);
253
+ g = g.OffSet(t2);
254
+ }
255
+ }
256
+ h += hh;
257
+ }
258
+ return h;
259
+ }
260
+
261
+ static ZBDD ZBDD_SymSet(const ZBDD&, const ZBDD&);
262
+ static ZBDD ZBDD_SymSet(const ZBDD& f0, const ZBDD& f1)
263
+ {
264
+ if(f0 == -1) return -1;
265
+ if(f1 == -1) return -1;
266
+ if(f1 == 0) return 0;
267
+ if(f1 == 1 && (f0 == 0 || f0 == 1)) return 0;
268
+
269
+ bddword fx = f0.GetID();
270
+ bddword gx = f1.GetID();
271
+ ZBDD_CACHE_CHK_RETURN(BC_ZBDD_SYMSET, fx, gx);
272
+
273
+ int t0 = f0.Top();
274
+ int t1 = f1.Top();
275
+ int t = (BDD_LevOfVar(t0) > BDD_LevOfVar(t1))? t0: t1;
276
+
277
+ ZBDD f00 = f0.OffSet(t);
278
+ ZBDD f01 = f0.OnSet0(t);
279
+ ZBDD f10 = f1.OffSet(t);
280
+ ZBDD f11 = f1.OnSet0(t);
281
+
282
+ ZBDD h;
283
+ if(f11 == 0) h = ZBDD_SymSet(f00, f10) - f01.Support();
284
+ else if(f10 == 0) h = ZBDD_SymSet(f01, f11) - f00.Support();
285
+ else
286
+ {
287
+ h = ZBDD_SymSet(f01, f11);
288
+ if(h != 0) h &= ZBDD_SymSet(f00, f10);
289
+ }
290
+ if(f10 == f01) h += ZBDD(1).Change(t);
291
+
292
+ ZBDD_CACHE_ENT_RETURN(BC_ZBDD_SYMSET, fx, gx, h);
293
+ }
294
+
295
+ ZBDD ZBDD::SymSet(int v) const
296
+ {
297
+ if(*this == -1) return -1;
298
+ if(v <= 0) BDDerr("ZBDD::SymSet(): invalid v.", v);
299
+ ZBDD f0 = OffSet(v);
300
+ ZBDD f1 = OnSet0(v);
301
+ return ZBDD_SymSet(f0, f1);
302
+ }
303
+
304
+ int ZBDD::ImplyChk(int v1, int v2) const
305
+ {
306
+ if(*this == -1) return -1;
307
+ if(v1 <= 0) BDDerr("ZBDD::IndImplyChk(): invalid v1.", v1);
308
+ if(v2 <= 0) BDDerr("ZBDD::IndImplyChk(): invalid v2.", v2);
309
+ if(v1 == v2) return 1;
310
+ if(*this == 0 || *this == 1) return 1;
311
+
312
+ ZBDD f10 = OnSet0(v1).OffSet(v2);
313
+ if(f10 == -1) return -1;
314
+ return (f10 == 0);
315
+ }
316
+
317
+ ZBDD ZBDD::ImplySet(int v) const
318
+ {
319
+ if(*this == -1) return -1;
320
+ if(v <= 0) BDDerr("ZBDD::ImplySet(): invalid v.", v);
321
+ ZBDD f1 = OnSet0(v);
322
+ if(f1 == 0) return Support();
323
+ return f1.Always();
324
+ }
325
+
326
+ int ZBDD::CoImplyChk(int v1, int v2) const
327
+ {
328
+ if(*this == -1) return -1;
329
+ if(v1 <= 0) BDDerr("ZBDD::IndImplyChk(): invalid v1.", v1);
330
+ if(v2 <= 0) BDDerr("ZBDD::IndImplyChk(): invalid v2.", v2);
331
+ if(v1 == v2) return 1;
332
+ if(*this == 0 || *this == 1) return 1;
333
+
334
+ ZBDD f10 = OnSet0(v1).OffSet(v2);
335
+ if(f10 == 0) return 1;
336
+
337
+ ZBDD f01 = OffSet(v1).OnSet0(v2);
338
+ ZBDD chk = f10 - f01;
339
+ if(chk == -1) return -1;
340
+ return (chk == 0) ;
341
+ }
342
+
343
+ static ZBDD ZBDD_CoImplySet(const ZBDD&, const ZBDD&);
344
+ static ZBDD ZBDD_CoImplySet(const ZBDD& f0, const ZBDD& f1)
345
+ {
346
+ if(f0 == -1) return -1;
347
+ if(f1 == -1) return -1;
348
+ if(f1 == 0) return 0;
349
+ if(f1 == 1 && (f0 == 0 || f0 == 1)) return 0;
350
+
351
+ bddword fx = f0.GetID();
352
+ bddword gx = f1.GetID();
353
+ ZBDD_CACHE_CHK_RETURN(BC_ZBDD_COIMPSET, fx, gx);
354
+
355
+ int t0 = f0.Top();
356
+ int t1 = f1.Top();
357
+ int t = (BDD_LevOfVar(t0) > BDD_LevOfVar(t1))? t0: t1;
358
+
359
+ ZBDD f00 = f0.OffSet(t);
360
+ ZBDD f01 = f0.OnSet0(t);
361
+ ZBDD f10 = f1.OffSet(t);
362
+ ZBDD f11 = f1.OnSet0(t);
363
+
364
+ ZBDD h;
365
+ if(f11 == 0) h = ZBDD_CoImplySet(f00, f10);
366
+ else if(f10 == 0) h = ZBDD_CoImplySet(f01, f11);
367
+ else
368
+ {
369
+ h = ZBDD_CoImplySet(f01, f11);
370
+ if(h != 0) h &= ZBDD_CoImplySet(f00, f10);
371
+ }
372
+ if(f10 - f01 == 0) h += ZBDD(1).Change(t);
373
+
374
+ ZBDD_CACHE_ENT_RETURN(BC_ZBDD_COIMPSET, fx, gx, h);
375
+ }
376
+
377
+ ZBDD ZBDD::CoImplySet(int v) const
378
+ {
379
+ if(*this == -1) return -1;
380
+ if(v <= 0) BDDerr("ZBDD::CoImplySet(): invalid v.", v);
381
+ ZBDD f0 = OffSet(v);
382
+ ZBDD f1 = OnSet0(v);
383
+ if(f1 == 0) return Support();
384
+ return ZBDD_CoImplySet(f0, f1);
385
+ }
386
+
387
+ int ZBDD::IsPoly() const
388
+ {
389
+ int top = Top();
390
+ if(top == 0) return 0;
391
+ ZBDD f1 = OnSet0(top);
392
+ ZBDD f0 = OffSet(top);
393
+ if(f0 != 0) return 1;
394
+ return f1.IsPoly();
395
+ }
396
+
397
+ ZBDD ZBDD::Divisor() const
398
+ {
399
+ if(*this == -1) return -1;
400
+ if(*this == 0) return 0;
401
+ if(! IsPoly()) return 1;
402
+ ZBDD f = *this;
403
+ ZBDD g = Support();
404
+ int t;
405
+ while(g != 0)
406
+ {
407
+ t = g.Top();
408
+ g = g.OffSet(t);
409
+ ZBDD f1 = f.OnSet0(t);
410
+ if(f1.IsPoly()) f = f1;
411
+ }
412
+ return f;
413
+ }
414
+
415
+
416
+ //--------- External functions for ZBDD ------------
417
+
418
+ ZBDD operator*(const ZBDD& fc, const ZBDD& gc)
419
+ {
420
+ if(fc == -1) return -1;
421
+ if(gc == -1) return -1;
422
+ if(fc == 0) return 0;
423
+ if(gc == 0) return 0;
424
+ if(fc == 1) return gc;
425
+ if(gc == 1) return fc;
426
+
427
+ ZBDD f = fc; ZBDD g = gc;
428
+ int ftop = f.Top(); int gtop = g.Top();
429
+ if(BDD_LevOfVar(ftop) < BDD_LevOfVar(gtop))
430
+ {
431
+ f = gc; g = fc;
432
+ ftop = f.Top(); gtop = g.Top();
433
+ }
434
+
435
+ bddword fx = f.GetID();
436
+ bddword gx = g.GetID();
437
+ if(ftop == gtop && fx < gx)
438
+ {
439
+ f = gc; g = fc;
440
+ fx = f.GetID(); gx = g.GetID();
441
+ }
442
+
443
+ ZBDD_CACHE_CHK_RETURN(BC_ZBDD_MULT, fx, gx);
444
+
445
+ ZBDD f1 = f.OnSet0(ftop);
446
+ ZBDD f0 = f.OffSet(ftop);
447
+ ZBDD h;
448
+ if(ftop != gtop)
449
+ {
450
+ h = f1 * g;
451
+ h = h.Change(ftop) + (f0 * g);
452
+ }
453
+ else
454
+ {
455
+ ZBDD g1 = g.OnSet0(ftop);
456
+ ZBDD g0 = g.OffSet(ftop);
457
+ h = (f1 * g1)+(f1 * g0)+(f0 * g1);
458
+ h = h.Change(ftop) + (f0 * g0);
459
+ }
460
+
461
+ ZBDD_CACHE_ENT_RETURN(BC_ZBDD_MULT, fx, gx, h);
462
+ }
463
+
464
+ ZBDD operator/(const ZBDD& f, const ZBDD& p)
465
+ {
466
+ if(f == -1) return -1;
467
+ if(p == -1) return -1;
468
+ if(p == 1) return f;
469
+ if(f == p) return 1;
470
+ if(p == 0) BDDerr("operator /(): Divided by zero.");
471
+ int top = p.Top();
472
+ if(BDD_LevOfVar(f.Top()) < BDD_LevOfVar(top)) return 0;
473
+
474
+ bddword fx = f.GetID();
475
+ bddword px = p.GetID();
476
+ ZBDD_CACHE_CHK_RETURN(BC_ZBDD_DIV, fx, px);
477
+
478
+ ZBDD q = f.OnSet0(top) / p.OnSet0(top);
479
+ if(q != 0)
480
+ {
481
+ ZBDD p0 = p.OffSet(top);
482
+ if(p0 != 0) q &= f.OffSet(top) / p0;
483
+ }
484
+
485
+ ZBDD_CACHE_ENT_RETURN(BC_ZBDD_DIV, fx, px, q);
486
+ }
487
+
488
+ ZBDD ZBDD_Meet(const ZBDD& fc, const ZBDD& gc)
489
+ {
490
+ if(fc == -1) return -1;
491
+ if(gc == -1) return -1;
492
+ if(fc == 0) return 0;
493
+ if(gc == 0) return 0;
494
+ if(fc == 1) return 1;
495
+ if(gc == 1) return 1;
496
+
497
+ ZBDD f = fc; ZBDD g = gc;
498
+ int ftop = f.Top();
499
+ int gtop = g.Top();
500
+ if(BDD_LevOfVar(ftop) < BDD_LevOfVar(gtop))
501
+ {
502
+ f = gc; g = fc;
503
+ ftop = f.Top(); gtop = g.Top();
504
+ }
505
+
506
+ bddword fx = f.GetID();
507
+ bddword gx = g.GetID();
508
+ if(ftop == gtop && fx < gx)
509
+ {
510
+ f = gc; g = fc;
511
+ fx = f.GetID(); gx = g.GetID();
512
+ }
513
+
514
+ ZBDD_CACHE_CHK_RETURN(BC_ZBDD_MEET, fx, gx);
515
+
516
+ ZBDD f1 = f.OnSet0(ftop);
517
+ ZBDD f0 = f.OffSet(ftop);
518
+ ZBDD h;
519
+ if(ftop != gtop)
520
+ {
521
+ h = ZBDD_Meet(f0, g) + ZBDD_Meet(f1, g);
522
+ }
523
+ else
524
+ {
525
+ ZBDD g1 = g.OnSet0(ftop);
526
+ ZBDD g0 = g.OffSet(ftop);
527
+ h = ZBDD_Meet(f1, g1);
528
+ h = h.Change(ftop) + ZBDD_Meet(f0, g0)
529
+ + ZBDD_Meet(f1, g0) + ZBDD_Meet(f0, g1);
530
+ }
531
+
532
+ ZBDD_CACHE_ENT_RETURN(BC_ZBDD_MEET, fx, gx, h);
533
+ }
534
+
535
+ ZBDD ZBDD_Random(int lev, int density)
536
+ {
537
+ if(lev < 0) BDDerr("ZBDD_Random(): lev < 0.", lev);
538
+ if(lev == 0) return ((rand()%100) < density)? 1: 0;
539
+ return ZBDD_Random(lev-1, density) +
540
+ ZBDD_Random(lev-1, density).Change(BDD_VarOfLev(lev));
541
+ }
542
+
543
+ ZBDD ZBDD_Import(FILE *strm)
544
+ {
545
+ bddword zbdd;
546
+ if(bddimportz(strm, &zbdd, 1)) return -1;
547
+ return ZBDD_ID(zbdd);
548
+ }
549
+
550
+
551
+ // class ZBDDV ---------------------------------------------
552
+
553
+ ZBDDV::ZBDDV(const ZBDD& f, int location)
554
+ {
555
+ if(location < 0) BDDerr("ZBDDV::ZBDDV(): location < 0.", location);
556
+ if(location >= BDDV_MaxLen)
557
+ BDDerr("ZBDDV::ZBDDV(): Too large location.", location);
558
+ if(BDD_LevOfVar(f.Top()) > BDD_TopLev())
559
+ BDDerr("ZBDDV::ZBDDV(): Invalid top var.", f.Top());
560
+ _zbdd = f;
561
+ int var = 1;
562
+ for(int i=location; i>0; i>>=1)
563
+ {
564
+ if((i & 1)!= 0) _zbdd = _zbdd.Change(var);
565
+ var++;
566
+ }
567
+ }
568
+
569
+ ZBDDV ZBDDV::operator<<(int shift) const
570
+ {
571
+ ZBDDV fv1 = *this;
572
+ ZBDDV fv2;
573
+ while(fv1 != ZBDDV())
574
+ {
575
+ if(fv1 == ZBDDV(-1)) return fv1;
576
+ int last = fv1.Last();
577
+ fv2 += ZBDDV(fv1.GetZBDD(last) << shift, last);
578
+ fv1 -= fv1.Mask(last);
579
+ }
580
+ return fv2;
581
+ }
582
+
583
+ ZBDDV ZBDDV::operator>>(int shift) const
584
+ {
585
+ ZBDDV fv1 = *this;
586
+ ZBDDV fv2;
587
+ while(fv1 != ZBDDV())
588
+ {
589
+ if(fv1 == ZBDDV(-1)) return fv1;
590
+ int last = fv1.Last();
591
+ fv2 += ZBDDV(fv1.GetZBDD(last) >> shift, last);
592
+ fv1 -= fv1.Mask(last);
593
+ }
594
+ return fv2;
595
+ }
596
+
597
+ ZBDDV ZBDDV::OffSet(int v) const
598
+ {
599
+ if(BDD_LevOfVar(v) > BDD_TopLev())
600
+ BDDerr("ZBDDV::OffSet(): Invalid VarID.", v);
601
+ ZBDDV tmp;
602
+ tmp._zbdd = _zbdd.OffSet(v);
603
+ return tmp;
604
+ }
605
+
606
+ ZBDDV ZBDDV::OnSet(int v) const
607
+ {
608
+ if(BDD_LevOfVar(v) > BDD_TopLev())
609
+ BDDerr("ZBDDV::OnSet(): Invalid VarID.", v);
610
+ ZBDDV tmp;
611
+ tmp._zbdd = _zbdd.OnSet(v);
612
+ return tmp;
613
+ }
614
+
615
+ ZBDDV ZBDDV::OnSet0(int v) const
616
+ {
617
+ if(BDD_LevOfVar(v) > BDD_TopLev())
618
+ BDDerr("ZBDDV::OnSet0(): Invalid VarID.", v);
619
+ ZBDDV tmp;
620
+ tmp._zbdd = _zbdd.OnSet0(v);
621
+ return tmp;
622
+ }
623
+
624
+ ZBDDV ZBDDV::Change(int v) const
625
+ {
626
+ if(BDD_LevOfVar(v) > BDD_TopLev())
627
+ BDDerr("ZBDDV::Change(): Invalid VarID.", v);
628
+ ZBDDV tmp;
629
+ tmp._zbdd = _zbdd.Change(v);
630
+ return tmp;
631
+ }
632
+
633
+ ZBDDV ZBDDV::Swap(int v1, int v2) const
634
+ {
635
+ if(BDD_LevOfVar(v1) > BDD_TopLev())
636
+ BDDerr("ZBDDV::Swap(): Invalid VarID.", v1);
637
+ if(BDD_LevOfVar(v1) > BDD_TopLev())
638
+ BDDerr("ZBDDV::Swap(): Invalid VarID.", v2);
639
+ ZBDDV tmp;
640
+ tmp._zbdd = _zbdd.Swap(v1, v2);
641
+ return tmp;
642
+ }
643
+
644
+ int ZBDDV::Top() const
645
+ {
646
+ ZBDDV fv1 = *this;
647
+ if(fv1 == ZBDDV(-1)) return 0;
648
+ int top = 0;
649
+ while(fv1 != ZBDDV())
650
+ {
651
+ int last = fv1.Last();
652
+ int t = fv1.GetZBDD(last).Top();
653
+ if(BDD_LevOfVar(t) > BDD_LevOfVar(top)) top = t;
654
+ fv1 -= fv1.Mask(last);
655
+ }
656
+ return top;
657
+ }
658
+
659
+ int ZBDDV::Last() const
660
+ {
661
+ int last = 0;
662
+ ZBDD f = _zbdd;
663
+ while(BDD_LevOfVar(f.Top()) > BDD_TopLev())
664
+ {
665
+ int t = f.Top();
666
+ last += 1 << (t - 1);
667
+ f = f.OnSet0(t);
668
+ }
669
+ return last;
670
+ }
671
+
672
+ ZBDDV ZBDDV::Mask(int start, int len) const
673
+ {
674
+ if(start < 0 || start >= BDDV_MaxLen)
675
+ BDDerr("ZBDDV::Mask(): Illegal start index.", start);
676
+ if(len <= 0 || start+len > BDDV_MaxLen)
677
+ BDDerr("ZBDDV::Mask(): Illegal len.", len);
678
+ ZBDDV tmp;
679
+ for(int i=start; i<start+len; i++)
680
+ tmp += ZBDDV(this -> GetZBDD(i), i);
681
+ return tmp;
682
+ }
683
+
684
+ ZBDD ZBDDV::GetZBDD(int index) const
685
+ {
686
+ if(index < 0 || index >= BDDV_MaxLen)
687
+ BDDerr("ZBDDV::GetZBDD(): Illegal index.",index);
688
+ int level = 0;
689
+ for(int i=1; i<=index; i<<=1) level++;
690
+
691
+ ZBDD f = _zbdd;
692
+ while(BDD_LevOfVar(f.Top()) > BDD_TopLev() + level)
693
+ f = f.OffSet(f.Top());
694
+ while(level > 0)
695
+ {
696
+ if(f == 0) return f;
697
+ if((index & (1<<level-1)) != 0) f = f.OnSet0(level);
698
+ else f = f.OffSet(level);
699
+ level--;
700
+ }
701
+ return f;
702
+ }
703
+
704
+ bddword ZBDDV::Size() const
705
+ {
706
+ int len = this -> Last() + 1;
707
+ bddword* bddv = new bddword[len];
708
+ for(int i=0; i<len; i++) bddv[i] = GetZBDD(i).GetID();
709
+ bddword s = bddvsize(bddv, len);
710
+ delete[] bddv;
711
+ return s;
712
+ }
713
+
714
+ void ZBDDV::Print() const
715
+ {
716
+ int len = this -> Last() + 1;
717
+ for(int i=0; i<len; i++)
718
+ {
719
+ cout << "f" << i << ": ";
720
+ GetZBDD(i).Print();
721
+ }
722
+ cout << "Size= " << Size() << "\n\n";
723
+ cout.flush();
724
+ }
725
+
726
+ void ZBDDV::Export(FILE *strm) const
727
+ {
728
+ int len = this -> Last() + 1;
729
+ bddword* bddv = new bddword[len];
730
+ for(int i=0; i<len; i++) bddv[i] = GetZBDD(i).GetID();
731
+ bddexport(strm, bddv, len);
732
+ delete[] bddv;
733
+ }
734
+
735
+ static int Len;
736
+ static char* Cube;
737
+ static int ZBDDV_PLA(const ZBDDV&, int);
738
+ static int ZBDDV_PLA(const ZBDDV& fv, int tlev)
739
+ {
740
+ if(fv == ZBDDV(-1)) return 1;
741
+ if(fv == ZBDDV()) return 0;
742
+ if(tlev == 0)
743
+ {
744
+ cout << Cube << " ";
745
+ for(int i=0; i<Len; i++)
746
+ if(fv.GetZBDD(i) == 0) cout << "~";
747
+ else cout << "1";
748
+ cout << "\n";
749
+ cout.flush();
750
+ return 0;
751
+ }
752
+ Cube[tlev-1] = '1';
753
+ if(ZBDDV_PLA(fv.OnSet0(BDD_VarOfLev(tlev)), tlev-1) == 1)
754
+ return 1;
755
+ Cube[tlev-1] = '0';
756
+ return ZBDDV_PLA(fv.OffSet(BDD_VarOfLev(tlev)), tlev-1);
757
+ }
758
+
759
+ int ZBDDV::PrintPla() const
760
+ {
761
+ if(*this == ZBDDV(-1)) return 1;
762
+ int tlev = BDD_LevOfVar(Top());
763
+ Len = Last() + 1;
764
+ cout << ".i " << tlev << "\n";
765
+ cout << ".o " << Len << "\n";
766
+ if(tlev == 0)
767
+ {
768
+ for(int i=0; i<Len; i++)
769
+ if(GetZBDD(i) == 0) cout << "0";
770
+ else cout << "1";
771
+ cout << "\n";
772
+ }
773
+ else
774
+ {
775
+ Cube = new char[tlev + 1];
776
+ Cube[tlev] = 0;
777
+ int err = ZBDDV_PLA(*this, tlev);
778
+ delete[] Cube;
779
+ if(err == 1) return 1;
780
+ }
781
+ cout << ".e\n";
782
+ cout.flush();
783
+ return 0;
784
+ }
785
+
786
+ #define IMPORTHASH(x) ((((x)>>1)^((x)<<8)^((x)<<16)) & (hashsize-1))
787
+
788
+ #ifdef B_64
789
+ # define B_STRTOI strtoll
790
+ #else
791
+ # define B_STRTOI strtol
792
+ #endif
793
+
794
+ ZBDDV ZBDDV_Import(FILE *strm)
795
+ {
796
+ int inv, e;
797
+ bddword hashsize;
798
+ ZBDD f, f0, f1;
799
+ char s[256];
800
+ bddword *hash1;
801
+ ZBDD *hash2;
802
+
803
+ if(fscanf(strm, "%s", &s) == EOF) return ZBDDV(-1);
804
+ if(strcmp(s, "_i") != 0) return ZBDDV(-1);
805
+ if(fscanf(strm, "%s", &s) == EOF) return ZBDDV(-1);
806
+ int n = strtol(s, NULL, 10);
807
+ while(n > BDD_TopLev()) BDD_NewVar();
808
+
809
+ if(fscanf(strm, "%s", &s) == EOF) return ZBDDV(-1);
810
+ if(strcmp(s, "_o") != 0) return ZBDDV(-1);
811
+ if(fscanf(strm, "%s", &s) == EOF) return ZBDDV(-1);
812
+ int m = strtol(s, NULL, 10);
813
+
814
+ if(fscanf(strm, "%s", &s) == EOF) return ZBDDV(-1);
815
+ if(strcmp(s, "_n") != 0) return ZBDDV(-1);
816
+ if(fscanf(strm, "%s", &s) == EOF) return ZBDDV(-1);
817
+ bddword n_nd = B_STRTOI(s, NULL, 10);
818
+
819
+ for(hashsize = 1; hashsize < (n_nd<<1); hashsize <<= 1)
820
+ ; /* empty */
821
+ hash1 = new bddword[hashsize];
822
+ if(hash1 == 0) return ZBDDV(-1);
823
+ hash2 = new ZBDD[hashsize];
824
+ if(hash2 == 0) { delete[] hash1; return ZBDDV(-1); }
825
+ for(bddword ix=0; ix<hashsize; ix++)
826
+ {
827
+ hash1[ix] = B_VAL_MASK;
828
+ hash2[ix] = 0;
829
+ }
830
+
831
+ e = 0;
832
+ for(bddword ix=0; ix<n_nd; ix++)
833
+ {
834
+ if(fscanf(strm, "%s", &s) == EOF) { e = 1; break; }
835
+ bddword nd = B_STRTOI(s, NULL, 10);
836
+
837
+ if(fscanf(strm, "%s", &s) == EOF) { e = 1; break; }
838
+ int lev = strtol(s, NULL, 10);
839
+ int var = bddvaroflev(lev);
840
+
841
+ if(fscanf(strm, "%s", &s) == EOF) { e = 1; break; }
842
+ if(strcmp(s, "F") == 0) f0 = 0;
843
+ else if(strcmp(s, "T") == 0) f0 = 1;
844
+ else
845
+ {
846
+ bddword nd0 = B_STRTOI(s, NULL, 10);
847
+
848
+ bddword ixx = IMPORTHASH(nd0);
849
+ while(hash1[ixx] != nd0)
850
+ {
851
+ if(hash1[ixx] == B_VAL_MASK)
852
+ BDDerr("ZBDDV_Import(): internal error", ixx);
853
+ ixx++;
854
+ ixx &= (hashsize-1);
855
+ }
856
+ f0 = hash2[ixx];
857
+ }
858
+
859
+ if(fscanf(strm, "%s", &s) == EOF) { e = 1; break; }
860
+ if(strcmp(s, "F") == 0) f1 = 0;
861
+ else if(strcmp(s, "T") == 0) f1 = 1;
862
+ else
863
+ {
864
+ bddword nd1 = B_STRTOI(s, NULL, 10);
865
+ if(nd1 & 1) { inv = 1; nd1 ^= 1; }
866
+ else inv = 0;
867
+
868
+ bddword ixx = IMPORTHASH(nd1);
869
+ while(hash1[ixx] != nd1)
870
+ {
871
+ if(hash1[ixx] == B_VAL_MASK)
872
+ BDDerr("ZBDDV_Import(): internal error", ixx);
873
+ ixx++;
874
+ ixx &= (hashsize-1);
875
+ }
876
+ f1 = (inv)? (hash2[ixx] + 1): hash2[ixx];
877
+ }
878
+
879
+ f = f1.Change(var) + f0;
880
+ if(f == -1) { e = 1; break; }
881
+
882
+ bddword ixx = IMPORTHASH(nd);
883
+ while(hash1[ixx] != B_VAL_MASK)
884
+ {
885
+ if(hash1[ixx] == nd)
886
+ BDDerr("ZBDDV_Import(): internal error", ixx);
887
+ ixx++;
888
+ ixx &= (hashsize-1);
889
+ }
890
+ hash1[ixx] = nd;
891
+ hash2[ixx] = f;
892
+ }
893
+
894
+ if(e)
895
+ {
896
+ delete[] hash2;
897
+ delete[] hash1;
898
+ return ZBDDV(-1);
899
+ }
900
+
901
+ ZBDDV v = ZBDDV();
902
+ for(int i=0; i<m; i++)
903
+ {
904
+ if(fscanf(strm, "%s", &s) == EOF)
905
+ {
906
+ delete[] hash2;
907
+ delete[] hash1;
908
+ return ZBDDV(-1);
909
+ }
910
+ bddword nd = B_STRTOI(s, NULL, 10);
911
+ if(strcmp(s, "F") == 0) v += ZBDDV(0, i);
912
+ else if(strcmp(s, "T") == 0) v += ZBDDV(1, i);
913
+ else
914
+ {
915
+ if(nd & 1) { inv = 1; nd ^= 1; }
916
+ else inv = 0;
917
+
918
+ bddword ixx = IMPORTHASH(nd);
919
+ while(hash1[ixx] != nd)
920
+ {
921
+ if(hash1[ixx] == B_VAL_MASK)
922
+ BDDerr("ZBDDV_Import(): internal error", ixx);
923
+ ixx++;
924
+ ixx &= (hashsize-1);
925
+ }
926
+ v += ZBDDV((inv? (hash2[ixx] + 1): hash2[ixx]), i);
927
+ }
928
+ }
929
+
930
+ delete[] hash2;
931
+ delete[] hash1;
932
+ return v;
933
+ }
934
+
935
+ #define ZLevNum(n) \
936
+ (n-((n&2)?(n&1)? (n<512)?(n<64)?(n<16)?4:8:(n<128)?32:(n<256)?64:128:(n<4096)?(n<1024)?256:(n<2048)?512:1024:(n<8192)?2048:(n<32768)?4096:8192 \
937
+ : (n<512)?(n<64)?4:(n<256)?16:32:(n<4096)?(n<1024)?64:128:(n<32768)?512:1024 \
938
+ :(n&1)? (n<512)?(n<16)?4:8:(n<2048)?(n<1024)?16:32:(n<32768)?64:128 \
939
+ : (n<1024)?4:(n<32768)?8:16 \
940
+ ))
941
+
942
+ ZBDD ZBDD::ZLev(int lev, int last) const
943
+ {
944
+ if(lev <= 0) return *this & 1;
945
+ ZBDD f = *this;
946
+ ZBDD u = *this & 1;
947
+ int ftop = Top();
948
+ int flev = BDD_LevOfVar(ftop);
949
+ while(flev > lev)
950
+ {
951
+ if(flev - lev >= 5)
952
+ {
953
+ int n = ZLevNum(flev);
954
+ if(flev >= 66)
955
+ {
956
+ if(n < lev || ((flev & 3) < 3 && ZLevNum(flev - 3) >= lev))
957
+ n = flev - 1;
958
+ }
959
+ else if(flev >= 18)
960
+ {
961
+ if(n < lev || ((flev & 1) < 1 && ZLevNum(flev - 1) >= lev))
962
+ n = flev - 1;
963
+ }
964
+ else if(n < lev) n = flev - 1;
965
+
966
+ if(n < flev - 1)
967
+ {
968
+ bddword fx = f.GetID();
969
+ ZBDD g = BDD_CacheZBDD(BC_ZBDD_ZSkip, fx, fx);
970
+ if(g != -1)
971
+ {
972
+ int gtop = g.Top();
973
+ int glev = BDD_LevOfVar(gtop);
974
+ if(glev >= lev)
975
+ {
976
+ f = g;
977
+ ftop = gtop;
978
+ flev = glev;
979
+ continue;
980
+ }
981
+ }
982
+ }
983
+ }
984
+ u = f;
985
+ f = f.OffSet(ftop);
986
+ ftop = f.Top();
987
+ flev = BDD_LevOfVar(ftop);
988
+ }
989
+ return (last == 0 || lev == flev)? f: u;
990
+ }
991
+
992
+ void ZBDD::SetZSkip() const
993
+ {
994
+ int t = Top();
995
+ int lev = BDD_LevOfVar(t);
996
+ if(lev <= 4) return;
997
+ bddword fx = GetID();
998
+ ZBDD g = BDD_CacheZBDD(BC_ZBDD_ZSkip, fx, fx);
999
+ if(g != -1) return;
1000
+ ZBDD f0 = OffSet(t);
1001
+ f0.SetZSkip();
1002
+ g = ZLev(ZLevNum(lev), 1);
1003
+ if(g == *this) g = f0;
1004
+ bddword gx = g.GetID();
1005
+ BDD_CacheEnt(BC_ZBDD_ZSkip, fx, fx, gx);
1006
+ OnSet0(t).SetZSkip();
1007
+ }
1008
+
1009
+ ZBDD ZBDD::Intersec(const ZBDD& g) const
1010
+ {
1011
+ if(g == 0) return 0;
1012
+ if(g == 1) return *this & 1;
1013
+ int ftop = Top();
1014
+ if(ftop == 0) return *this & g;
1015
+ int gtop = g.Top();
1016
+
1017
+ bddword fx = GetID();
1018
+ bddword gx = g.GetID();
1019
+ if(fx < gx) { fx = g.GetID(); gx = GetID(); }
1020
+ ZBDD_CACHE_CHK_RETURN(BC_ZBDD_INTERSEC, fx, gx);
1021
+
1022
+ int flev = BDD_LevOfVar(ftop);
1023
+ int glev = BDD_LevOfVar(gtop);
1024
+ ZBDD h;
1025
+ if(flev > glev) h = ZLev(glev).Intersec(g);
1026
+ else if(flev < glev) h = Intersec(g.OffSet(gtop));
1027
+ else
1028
+ {
1029
+ h = OnSet0(ftop).Intersec(g.OnSet0(ftop)).Change(ftop)
1030
+ + OffSet(ftop).Intersec(g.OffSet(ftop));
1031
+ }
1032
+
1033
+ ZBDD_CACHE_ENT_RETURN(BC_ZBDD_INTERSEC, fx, gx, h);
1034
+ }
1035
+