nysol-zdd 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ext/zdd_so/BDD.cc +495 -0
- data/ext/zdd_so/BDD.h +356 -0
- data/ext/zdd_so/BDDDG.cc +1818 -0
- data/ext/zdd_so/BDDDG.h +107 -0
- data/ext/zdd_so/BDDHASH.cc +91 -0
- data/ext/zdd_so/BtoI.cc +503 -0
- data/ext/zdd_so/BtoI.h +144 -0
- data/ext/zdd_so/CtoI.cc +1072 -0
- data/ext/zdd_so/CtoI.h +186 -0
- data/ext/zdd_so/MLZBDDV.cc +153 -0
- data/ext/zdd_so/MLZBDDV.h +42 -0
- data/ext/zdd_so/SOP.cc +608 -0
- data/ext/zdd_so/SOP.h +199 -0
- data/ext/zdd_so/ZBDD.cc +1035 -0
- data/ext/zdd_so/ZBDD.h +243 -0
- data/ext/zdd_so/ZBDDDG.cc +1834 -0
- data/ext/zdd_so/ZBDDDG.h +105 -0
- data/ext/zdd_so/ZBDDHASH.cc +91 -0
- data/ext/zdd_so/bddc.c +2816 -0
- data/ext/zdd_so/bddc.h +132 -0
- data/ext/zdd_so/extconf.rb +25 -0
- data/ext/zdd_so/include/aheap.c +211 -0
- data/ext/zdd_so/include/aheap.h +111 -0
- data/ext/zdd_so/include/base.c +93 -0
- data/ext/zdd_so/include/base.h +60 -0
- data/ext/zdd_so/include/itemset.c +473 -0
- data/ext/zdd_so/include/itemset.h +153 -0
- data/ext/zdd_so/include/problem.c +371 -0
- data/ext/zdd_so/include/problem.h +160 -0
- data/ext/zdd_so/include/queue.c +518 -0
- data/ext/zdd_so/include/queue.h +177 -0
- data/ext/zdd_so/include/sgraph.c +331 -0
- data/ext/zdd_so/include/sgraph.h +170 -0
- data/ext/zdd_so/include/stdlib2.c +832 -0
- data/ext/zdd_so/include/stdlib2.h +746 -0
- data/ext/zdd_so/include/trsact.c +723 -0
- data/ext/zdd_so/include/trsact.h +167 -0
- data/ext/zdd_so/include/vec.c +583 -0
- data/ext/zdd_so/include/vec.h +159 -0
- data/ext/zdd_so/lcm-vsop.cc +596 -0
- data/ext/zdd_so/print.cc +683 -0
- data/ext/zdd_so/table.cc +330 -0
- data/ext/zdd_so/vsop.h +88 -0
- data/ext/zdd_so/zdd_so.cpp +3277 -0
- data/lib/nysol/zdd.rb +31 -0
- metadata +131 -0
data/ext/zdd_so/SOP.h
ADDED
@@ -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
|
+
|
data/ext/zdd_so/ZBDD.cc
ADDED
@@ -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
|
+
|