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,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
+