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,186 @@
1
+ /******************************************
2
+ * Combination-to-Integer function class *
3
+ * (SAPPORO-1.71) - Header *
4
+ * (C) Shin-ichi MINATO (Dec. 15, 2015) *
5
+ ******************************************/
6
+
7
+ class CtoI;
8
+
9
+ #ifndef _CtoI_
10
+ #define _CtoI_
11
+
12
+ #include "ZBDD.h"
13
+
14
+
15
+ class CtoI
16
+ {
17
+ ZBDD _zbdd;
18
+
19
+ public:
20
+ CtoI(void) { _zbdd = 0; }
21
+ CtoI(const CtoI& a) { _zbdd = a._zbdd; }
22
+ CtoI(const ZBDD& f) { _zbdd = f; }
23
+ CtoI(int);
24
+ ~CtoI(void) { }
25
+
26
+ CtoI& operator=(const CtoI& a) { _zbdd = a._zbdd; return *this; }
27
+ CtoI& operator+=(const CtoI&); // inline
28
+ CtoI& operator-=(const CtoI&); // inline
29
+ CtoI& operator*=(const CtoI&); // inline
30
+ CtoI& operator/=(const CtoI&); // inline
31
+ CtoI& operator%=(const CtoI&); // inline
32
+
33
+ int Top(void) const { return _zbdd.Top(); }
34
+ int TopItem(void) const;
35
+ int TopDigit(void) const;
36
+ int IsBool(void) const { return (BDD_LevOfVar(Top()) <= BDD_TopLev()); }
37
+ int IsConst(void) const { return TopItem() == 0; }
38
+
39
+ CtoI AffixVar(int v) const
40
+ { return CtoI((_zbdd.OffSet(v) + _zbdd.OnSet0(v)).Change(v)); }
41
+
42
+ CtoI Factor0(int v) const { return CtoI(_zbdd.OffSet(v)); }
43
+ CtoI Factor1(int v) const { return CtoI(_zbdd.OnSet0(v)); }
44
+
45
+ CtoI FilterThen(const CtoI&) const;
46
+ CtoI FilterElse(const CtoI&) const;
47
+
48
+ CtoI FilterRestrict(const CtoI&) const;
49
+ CtoI FilterPermit(const CtoI&) const;
50
+ CtoI FilterPermitSym(int) const;
51
+ CtoI Support(void) const
52
+ { CtoI h = IsBool()? *this: NonZero(); return CtoI(h._zbdd.Support()); }
53
+
54
+ CtoI NonZero(void) const;
55
+ CtoI Digit(int) const;
56
+ CtoI ConstTerm() const;
57
+
58
+ CtoI EQ_Const(const CtoI&) const;
59
+ CtoI NE_Const(const CtoI&) const;
60
+ CtoI GT_Const(const CtoI&) const;
61
+ CtoI GE_Const(const CtoI&) const;
62
+ CtoI LT_Const(const CtoI&) const;
63
+ CtoI LE_Const(const CtoI&) const;
64
+
65
+ CtoI MaxVal(void) const;
66
+ CtoI MinVal(void) const;
67
+
68
+ CtoI CountTerms(void) const;
69
+ CtoI TotalVal(void) const;
70
+ CtoI TotalValItems(void) const;
71
+
72
+ ZBDD GetZBDD(void) const { return _zbdd; }
73
+
74
+ CtoI Abs(void) const; // inline
75
+ CtoI Sign(void) const; // inline
76
+ CtoI operator-(void) const; // inline
77
+
78
+ CtoI TimesSysVar(int) const;
79
+ CtoI DivBySysVar(int) const;
80
+ CtoI ShiftDigit(int) const;
81
+
82
+ bddword Size(void) const;
83
+
84
+ int GetInt(void) const;
85
+
86
+ int StrNum10(char *) const;
87
+ int StrNum16(char *) const;
88
+
89
+ int PutForm(void) const;
90
+ void Print(void) const;
91
+
92
+ void XPrint(void) const;
93
+ void XPrint0(void) const;
94
+
95
+ CtoI ReduceItems(const CtoI&) const;
96
+ CtoI FreqPatA(int) const;
97
+ CtoI FreqPatAV(int) const;
98
+ CtoI FreqPatM(int) const;
99
+ CtoI FreqPatC(int) const;
100
+
101
+ CtoI FreqPatA2(int) const;
102
+
103
+ // CtoI FilterClosed(CtoI);
104
+ // CtoI FreqPatCV(int);
105
+
106
+ friend int operator==(const CtoI&, const CtoI&);
107
+ friend CtoI operator*(const CtoI&, const CtoI&);
108
+ friend CtoI operator/(const CtoI&, const CtoI&);
109
+ friend CtoI CtoI_Intsec(const CtoI&, const CtoI&);
110
+ friend CtoI CtoI_Union(const CtoI&, const CtoI&);
111
+ friend CtoI CtoI_Diff(const CtoI&, const CtoI&);
112
+ friend CtoI CtoI_Meet(const CtoI&, const CtoI&);
113
+ };
114
+
115
+
116
+ extern CtoI operator+(const CtoI&, const CtoI&);
117
+ extern CtoI operator-(const CtoI&, const CtoI&);
118
+ extern CtoI operator*(const CtoI&, const CtoI&);
119
+ extern CtoI operator/(const CtoI&, const CtoI&);
120
+
121
+ extern CtoI CtoI_GT(const CtoI&, const CtoI&);
122
+ extern CtoI CtoI_GE(const CtoI&, const CtoI&);
123
+
124
+ extern CtoI CtoI_atoi(char *);
125
+
126
+ extern CtoI CtoI_Meet(const CtoI&, const CtoI&);
127
+
128
+ extern int CtoI_Lcm1(char *, char *, int, int);
129
+ extern CtoI CtoI_Lcm2(void);
130
+ extern int CtoI_LcmItems(void);
131
+ extern int CtoI_LcmPerm(int);
132
+ extern CtoI CtoI_LcmA(char *, char *, int);
133
+ extern CtoI CtoI_LcmC(char *, char *, int);
134
+ extern CtoI CtoI_LcmM(char *, char *, int);
135
+ extern CtoI CtoI_LcmAV(char *, char *, int);
136
+ extern CtoI CtoI_LcmCV(char *, char *, int);
137
+ extern CtoI CtoI_LcmMV(char *, char *, int);
138
+
139
+ inline int operator==(const CtoI& a, const CtoI& b) { return a._zbdd == b._zbdd; }
140
+ inline int operator!=(const CtoI& a, const CtoI& b) { return !(a == b); }
141
+ inline CtoI operator%(const CtoI& a, const CtoI& b) { return a - (a / b) * b; }
142
+
143
+ inline CtoI CtoI_Intsec(const CtoI& a, const CtoI& b)
144
+ { return CtoI(a._zbdd & b._zbdd); }
145
+
146
+ inline CtoI CtoI_Union(const CtoI& a, const CtoI& b)
147
+ { return CtoI(a._zbdd + b._zbdd); }
148
+
149
+ inline CtoI CtoI_Diff(const CtoI& a, const CtoI& b)
150
+ { return CtoI(a._zbdd - b._zbdd); }
151
+
152
+ inline CtoI CtoI_ITE(const CtoI& a, const CtoI& b, const CtoI& c)
153
+ { return CtoI_Union(b.FilterThen(a), c.FilterElse(a)); }
154
+
155
+ inline CtoI CtoI_NE(const CtoI& a, const CtoI& b)
156
+ { return CtoI_Union(CtoI_Diff(a, b), CtoI_Diff(b, a)).NonZero(); }
157
+
158
+ inline CtoI CtoI_EQ(const CtoI& a, const CtoI& b)
159
+ { return CtoI_Diff(CtoI_Union(a, b).NonZero(), CtoI_NE(a, b)); }
160
+
161
+ inline CtoI CtoI_LT(const CtoI& a, const CtoI& b) { return CtoI_GT(b, a); }
162
+ inline CtoI CtoI_LE(const CtoI& a, const CtoI& b) { return CtoI_GE(b, a); }
163
+
164
+ inline CtoI CtoI_Max(const CtoI& a, const CtoI& b)
165
+ { return CtoI_ITE(CtoI_GT(a, b), a, b); }
166
+ inline CtoI CtoI_Min(const CtoI& a, const CtoI& b)
167
+ { return CtoI_ITE(CtoI_GT(a, b), b, a); }
168
+
169
+ inline CtoI CtoI_Null(void) { return CtoI(ZBDD(-1)); }
170
+
171
+ inline CtoI CtoI::Abs(void) const
172
+ { CtoI a = CtoI_GT(*this, 0); return CtoI_Union(FilterThen(a), -FilterElse(a)); }
173
+
174
+ inline CtoI CtoI::Sign(void) const
175
+ { CtoI a = CtoI_GT(*this, 0); return a - CtoI_Diff(NonZero(), a); }
176
+
177
+ inline CtoI& CtoI::operator+=(const CtoI& a) { return *this = *this + a; }
178
+ inline CtoI& CtoI::operator-=(const CtoI& a) { return *this = *this - a; }
179
+ inline CtoI& CtoI::operator*=(const CtoI& a) { return *this = *this * a; }
180
+ inline CtoI& CtoI::operator/=(const CtoI& a) { return *this = *this / a; }
181
+ inline CtoI& CtoI::operator%=(const CtoI& a) { return *this = *this % a; }
182
+
183
+ inline CtoI CtoI::operator-(void) const { return 0 - *this; }
184
+
185
+ #endif // _CtoI_
186
+
@@ -0,0 +1,153 @@
1
+ /*****************************************
2
+ * Multi-Level ZBDDV class (SAPPORO-1.59)*
3
+ * (Main part) *
4
+ * (C) Shin-ichi MINATO (Dec. 10, 2013) *
5
+ *****************************************/
6
+
7
+ #include "MLZBDDV.h"
8
+
9
+ using std::cout;
10
+ using std::cerr;
11
+
12
+ //-------------- Class methods of MLZBDDV -----------------
13
+
14
+ MLZBDDV::MLZBDDV()
15
+ {
16
+ _pin = 0;
17
+ _out = 0;
18
+ _sin = 0;
19
+ _zbddv = ZBDDV();
20
+ }
21
+
22
+ MLZBDDV::~MLZBDDV() { }
23
+
24
+ int MLZBDDV::N_pin() { return _pin; }
25
+ int MLZBDDV::N_out() { return _out; }
26
+ int MLZBDDV::N_sin() { return _sin; }
27
+
28
+ MLZBDDV& MLZBDDV::operator=(const MLZBDDV& v)
29
+ {
30
+ _pin = v._pin;
31
+ _out = v._out;
32
+ _sin = v._sin;
33
+ _zbddv = v._zbddv;
34
+ return *this;
35
+ }
36
+
37
+ MLZBDDV::MLZBDDV(ZBDDV& zbddv)
38
+ {
39
+ int pin = BDD_LevOfVar(zbddv.Top());
40
+ int out = zbddv.Last()+1;
41
+ MLZBDDV v = MLZBDDV(zbddv, pin, out);
42
+ _pin = v._pin;
43
+ _out = v._out;
44
+ _sin = v._sin;
45
+ _zbddv = v._zbddv;
46
+ }
47
+
48
+ MLZBDDV::MLZBDDV(ZBDDV& zbddv, int pin, int out)
49
+ {
50
+ if(zbddv == ZBDDV(-1))
51
+ {
52
+ _pin = 0;
53
+ _out = 0;
54
+ _sin = 0;
55
+ _zbddv = zbddv;
56
+ return;
57
+ }
58
+
59
+ _pin = pin;
60
+ _out = out;
61
+ _sin = 0;
62
+ _zbddv = zbddv;
63
+
64
+ /* check each output as a divisor */
65
+ for(int i=0; i<_out; i++)
66
+ {
67
+ _sin++;
68
+ int plev = _pin + _sin;
69
+ if(plev > BDD_TopLev()) BDD_NewVar();
70
+ ZBDD p = _zbddv.GetZBDD(i);
71
+ int pt = BDD_LevOfVar(p.Top());
72
+ if(p != 0)
73
+ {
74
+ for(int j=0; j<_out; j++)
75
+ {
76
+ if(i != j)
77
+ {
78
+ ZBDD f = _zbddv.GetZBDD(j);
79
+ int ft = BDD_LevOfVar(f.Top());
80
+ if(ft >= pt)
81
+ {
82
+ ZBDD q = f / p;
83
+ if(q != 0)
84
+ {
85
+ int v = BDD_VarOfLev(plev);
86
+ _zbddv -= ZBDDV(f, j);
87
+ f = q.Change(v) + (f % p);
88
+ if(f == -1) { cerr << "overflow.\n"; exit(1);}
89
+ _zbddv += ZBDDV(f, j);
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
96
+
97
+ /* extract 0-level kernels */
98
+ for(int i=0; i<_out; i++)
99
+ {
100
+ ZBDD f = _zbddv.GetZBDD(i);
101
+ while(1)
102
+ {
103
+ ZBDD p = f.Divisor();
104
+ int pt = BDD_LevOfVar(p.Top());
105
+ if(p.Top() == 0) break;
106
+ if(p == f) break;
107
+ _sin++;
108
+ cout << _sin << " "; cout.flush();
109
+ int plev = _pin + _sin;
110
+ if(plev > BDD_TopLev()) BDD_NewVar();
111
+ _zbddv += ZBDDV(p, _sin-1);
112
+ int v = BDD_VarOfLev(plev);
113
+ ZBDD q = f / p;
114
+ _zbddv -= ZBDDV(f, i);
115
+ f = q.Change(v) + (f % p);
116
+ if(f == -1) { cerr << "overflow.\n"; exit(1);}
117
+ _zbddv += ZBDDV(f, i);
118
+ for(int j=0; j<_out; j++)
119
+ {
120
+ if(i != j)
121
+ {
122
+ ZBDD f = _zbddv.GetZBDD(j);
123
+ int ft = BDD_LevOfVar(f.Top());
124
+ if(ft >= pt)
125
+ {
126
+ ZBDD q = f / p;
127
+ if(q != 0)
128
+ {
129
+ _zbddv -= ZBDDV(f, j);
130
+ f = q.Change(v) + (f % p);
131
+ if(f == -1) { cerr << "overflow.\n"; exit(1);}
132
+ _zbddv += ZBDDV(f, j);
133
+ }
134
+ }
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
140
+
141
+ void MLZBDDV::Print()
142
+ {
143
+ cout << "pin:" << _pin << "\n";
144
+ cout << "out:" << _out << "\n";
145
+ cout << "sin:" << _sin << "\n";
146
+ _zbddv.Print();
147
+ }
148
+
149
+ ZBDDV MLZBDDV::GetZBDDV()
150
+ {
151
+ return _zbddv;
152
+ }
153
+
@@ -0,0 +1,42 @@
1
+ /***************************************************
2
+ * Multi-Level ZBDDV class (SAPPORO-1.00) - Header *
3
+ * (C) Shin-ichi MINATO (Aug 6, 2008 ) *
4
+ ***************************************************/
5
+
6
+ class MLZBDDV;
7
+
8
+ #ifndef _MLZBDDV_
9
+ #define _MLZBDDV_
10
+
11
+ #include "ZBDD.h"
12
+
13
+ class MLZBDDV;
14
+
15
+ class MLZBDDV
16
+ {
17
+ int _pin;
18
+ int _out;
19
+ int _sin;
20
+ ZBDDV _zbddv;
21
+
22
+ public:
23
+ MLZBDDV(void);
24
+
25
+ MLZBDDV(ZBDDV& zbddv);
26
+ MLZBDDV(ZBDDV& zbddv, int pin, int out);
27
+
28
+ ~MLZBDDV(void);
29
+
30
+ MLZBDDV& operator=(const MLZBDDV&);
31
+
32
+ int N_pin(void);
33
+ int N_out(void);
34
+ int N_sin(void);
35
+ ZBDDV GetZBDDV(void);
36
+
37
+ void Print(void);
38
+
39
+ };
40
+
41
+ #endif // _MLZBDDV_
42
+
@@ -0,0 +1,608 @@
1
+ /****************************************
2
+ * ZBDD-based SOP class (SAPPORO-1.7) *
3
+ * (Main part) *
4
+ * (C) Shin-ichi MINATO (Sep. 4, 2015) *
5
+ ****************************************/
6
+
7
+ #include "SOP.h"
8
+
9
+ using std::cout;
10
+
11
+ //----------- Internal constant data for SOP -----------
12
+ static const char BC_SOP_MULT = 30;
13
+ static const char BC_SOP_DIV = 31;
14
+ static const char BC_SOP_BDD = 33;
15
+ static const char BC_ISOP1 = 34;
16
+ static const char BC_ISOP2 = 35;
17
+ static const char BC_SOP_IMPL = 36;
18
+ static const char BC_SOP_SUPPORT = 37;
19
+
20
+ //----------- Macros for operation cache -----------
21
+ #define SOP_CACHE_CHK_RETURN(op, fx, gx) \
22
+ { ZBDD z = BDD_CacheZBDD(op, fx, gx); \
23
+ if(z != -1) return SOP(z); \
24
+ BDD_RECUR_INC; }
25
+
26
+ #define SOP_CACHE_ENT_RETURN(op, fx, gx, h) \
27
+ { BDD_RECUR_DEC; \
28
+ if(h != -1) BDD_CacheEnt(op, fx, gx, h.GetZBDD().GetID()); \
29
+ return h; }
30
+
31
+ #define BDD_CACHE_CHK_RETURN(op, fx, gx) \
32
+ { BDD h = BDD_CacheBDD(op, fx, gx); \
33
+ if(h != -1) return h; \
34
+ BDD_RECUR_INC; }
35
+
36
+ #define BDD_CACHE_ENT_RETURN(op, fx, gx, h) \
37
+ { BDD_RECUR_DEC; \
38
+ if(h != -1) BDD_CacheEnt(op, fx, gx, h.GetID()); \
39
+ return h; }
40
+
41
+ //----------- External functions for SOP ----------
42
+
43
+ int SOP_NewVar() { BDD_NewVar(); return BDD_NewVar(); }
44
+
45
+ int SOP_NewVarOfLev(int lev)
46
+ {
47
+ if(lev & 1) BDDerr("SOP_NewVarOfLev: Invalid lev.", lev);
48
+ BDD_NewVarOfLev(lev - 1);
49
+ return BDD_NewVarOfLev(lev);
50
+ }
51
+
52
+ SOP operator*(const SOP& pc, const SOP& qc)
53
+ {
54
+ if(pc == -1) return -1;
55
+ if(qc == -1) return -1;
56
+ if(pc == 0) return 0;
57
+ if(qc == 0) return 0;
58
+ if(pc == 1) return qc;
59
+ if(qc == 1) return pc;
60
+
61
+ SOP p = pc; SOP q = qc;
62
+ int top = p.Top();
63
+ if(BDD_LevOfVar(top) < BDD_LevOfVar(q.Top()))
64
+ {
65
+ p = qc; q = pc;
66
+ top = p.Top();
67
+ }
68
+
69
+ bddword px = p.GetZBDD().GetID();
70
+ bddword qx = q.GetZBDD().GetID();
71
+ SOP_CACHE_CHK_RETURN(BC_SOP_MULT, px, qx);
72
+
73
+ SOP p1 = p.Factor1(top);
74
+ SOP p0 = p.Factor0(top);
75
+ SOP pD = p.FactorD(top);
76
+ SOP r;
77
+ if(top != q.Top())
78
+ r = (p1*q).And1(top) + (p0*q).And0(top) + (pD*q);
79
+ else
80
+ {
81
+ SOP q1 = q.Factor1(top);
82
+ SOP q0 = q.Factor0(top);
83
+ SOP qD = q.FactorD(top);
84
+
85
+ r = ((p1*q1)+(p1*qD)+(pD*q1)).And1(top)
86
+ + ((p0*q0)+(p0*qD)+(pD*q0)).And0(top)
87
+ + (pD*qD);
88
+ }
89
+
90
+ SOP_CACHE_ENT_RETURN(BC_SOP_MULT, px, qx, r);
91
+ }
92
+
93
+ SOP operator/(const SOP& fc, const SOP& pc)
94
+ {
95
+ if(fc == -1) return -1;
96
+ if(pc == -1) return -1;
97
+ if(pc == 1) return fc;
98
+ if(fc == pc) return 1;
99
+ if(pc == 0) BDDerr("operator /(): Divided by zero.");
100
+
101
+ SOP f = fc; SOP p = pc;
102
+ int top = p.Top();
103
+ if(BDD_LevOfVar(f.Top()) < BDD_LevOfVar(top)) return 0;
104
+
105
+ bddword fx = f.GetZBDD().GetID();
106
+ bddword px = p.GetZBDD().GetID();
107
+ SOP_CACHE_CHK_RETURN(BC_SOP_DIV, fx, px);
108
+
109
+ SOP q = -1;
110
+ SOP p1 = p.Factor1(top);
111
+ if(p1 != 0) q = f.Factor1(top) / p1;
112
+ if(q != 0)
113
+ {
114
+ SOP p0 = p.Factor0(top);
115
+ if(p0 != 0)
116
+ {
117
+ if(q == -1) q = f.Factor0(top) / p0;
118
+ else q &= f.Factor0(top) / p0;
119
+ }
120
+ if(q != 0)
121
+ {
122
+ SOP pD = p.FactorD(top);
123
+ if(pD != 0)
124
+ {
125
+ if(q == -1) q = f.FactorD(top) / pD;
126
+ else q &= f.FactorD(top) / pD;
127
+ }
128
+ }
129
+ }
130
+
131
+ SOP_CACHE_ENT_RETURN(BC_SOP_DIV, fx, px, q);
132
+ }
133
+
134
+ //-------------- Class methods of SOP -----------------
135
+
136
+ SOP SOP::operator<<(int n) const
137
+ {
138
+ if(n & 1) BDDerr("SOP::operator<<: Invalid shift.", n);
139
+ return SOP(_zbdd << n);
140
+ }
141
+
142
+ SOP SOP::operator>>(int n) const
143
+ {
144
+ if(n & 1) BDDerr("SOP::operator>>: Invalid shift.", n);
145
+ return SOP(_zbdd >> n);
146
+ }
147
+
148
+ SOP SOP::And0(int v) const
149
+ {
150
+ if(v & 1) BDDerr("SOP::And0: VarID must be even number.", v);
151
+ ZBDD f = _zbdd.OffSet(v);
152
+ f = f.OnSet0(v-1) + f.OffSet(v-1);
153
+ f = f.Change(v-1);
154
+ return SOP(f);
155
+ }
156
+
157
+ SOP SOP::And1(int v) const
158
+ {
159
+ if(v & 1) BDDerr("SOP::And1: VarID must be even number.", v);
160
+ ZBDD f = _zbdd.OffSet(v-1);
161
+ f = f.OnSet0(v) + f.OffSet(v);
162
+ f = f.Change(v);
163
+ return SOP(f);
164
+ }
165
+
166
+ SOP SOP::Factor0(int v) const
167
+ {
168
+ if(v & 1) BDDerr("SOP::Factor0: VarID must be even number.", v);
169
+ ZBDD f = _zbdd.OnSet0(v-1);
170
+ return SOP(f);
171
+ }
172
+
173
+ SOP SOP::Factor1(int v) const
174
+ {
175
+ if(v & 1) BDDerr("SOP::Factor1: VarID must be even number.", v);
176
+ ZBDD f = _zbdd.OnSet0(v);
177
+ return SOP(f);
178
+ }
179
+
180
+ SOP SOP::FactorD(int v) const
181
+ {
182
+ if(v & 1) BDDerr("SOP::FactorD: VarID must be even number.", v);
183
+ ZBDD f = _zbdd.OffSet(v).OffSet(v-1);
184
+ return SOP(f);
185
+ }
186
+
187
+ bddword SOP::Size() const { return _zbdd.Size(); }
188
+ bddword SOP::Cube() const { return _zbdd.Card(); }
189
+ bddword SOP::Lit() const { return _zbdd.Lit(); }
190
+
191
+ void SOP::Print() const
192
+ {
193
+ cout << "[ " << _zbdd.GetID();
194
+ cout << " Var:" << Top() << "(" << BDD_LevOfVar(Top()) << ")";
195
+ cout << " Size:" << Size() << " ]\n";
196
+ cout.flush();
197
+ }
198
+
199
+ int SOP::PrintPla() const { return SOPV(*this).PrintPla(); }
200
+
201
+ BDD SOP::GetBDD() const
202
+ {
203
+ if(*this == -1) return -1;
204
+ if(*this == 0) return 0;
205
+ if(*this == 1) return 1;
206
+
207
+ bddword sx = GetZBDD().GetID();
208
+ BDD_CACHE_CHK_RETURN(BC_SOP_BDD, sx, 0);
209
+
210
+ int top = Top();
211
+ BDD x = BDDvar(top);
212
+ SOP p1 = Factor1(top);
213
+ SOP p0 = Factor0(top);
214
+ SOP pD = FactorD(top);
215
+ BDD f = (x & p1.GetBDD()) | (~x & p0.GetBDD()) | pD.GetBDD();
216
+
217
+ BDD_CACHE_ENT_RETURN(BC_SOP_BDD, sx, 0, f);
218
+ }
219
+
220
+ SOP SOP::InvISOP() const { return SOP_ISOP(~GetBDD()); }
221
+
222
+ int SOP::IsPolyCube() const
223
+ {
224
+ int top = Top();
225
+ if(top == 0) return 0;
226
+ SOP f1 = Factor1(top);
227
+ SOP f0 = Factor0(top);
228
+ SOP fD = FactorD(top);
229
+ if(f1 != 0)
230
+ {
231
+ if(f0 != 0) return 1;
232
+ if(fD != 0) return 1;
233
+ return f1.IsPolyCube();
234
+ }
235
+ if(fD != 0) return 1;
236
+ return f0.IsPolyCube();
237
+ }
238
+
239
+ int SOP::IsPolyLit() const
240
+ {
241
+ int top = Top();
242
+ if(top == 0) return 0;
243
+ SOP fD = FactorD(top);
244
+ if(fD != 0) return 1;
245
+ SOP f0 = Factor0(top);
246
+ SOP f1 = Factor1(top);
247
+ if(f0 == 1) if(f1 == 0) return 0;
248
+ if(f0 == 0) if(f1 == 1) return 0;
249
+ return 1;
250
+ }
251
+
252
+ SOP SOP::Support() const
253
+ {
254
+ if(*this == -1) return -1;
255
+ if(*this == 0) return 0;
256
+ if(*this == 1) return 0;
257
+
258
+ ZBDD fz = GetZBDD().Support();
259
+ SOP f = SOP(fz);
260
+ int t;
261
+ while(fz != 0)
262
+ {
263
+ t = fz.Top();
264
+ fz = fz.OffSet(t);
265
+ if(t & 1) f = f.FactorD(t+1) + SOP(1).And1(t+1);
266
+ }
267
+
268
+ return f;
269
+ }
270
+
271
+ SOP SOP::Divisor() const
272
+ {
273
+ if(*this == -1) return -1;
274
+ if(*this == 0) return 0;
275
+ if(IsPolyCube() == 0) return 1;
276
+ int top = Top();
277
+ SOP f = *this;
278
+ SOP g = Support();
279
+ int t;
280
+ while(g != 0)
281
+ {
282
+ t = g.Top();
283
+ g = g.FactorD(t);
284
+ SOP f0 = f.Factor0(t);
285
+ SOP f1 = f.Factor1(t);
286
+ if(f0.IsPolyCube() == 1) f = f0;
287
+ else if(f1.IsPolyCube() == 1) f = f1;
288
+ }
289
+ return f;
290
+ }
291
+
292
+ SOP SOP::Swap(int v1, int v2) const
293
+ {
294
+ if(v1 & 1) BDDerr("SOP::Swap: VarID must be even number.", v1);
295
+ if(v2 & 1) BDDerr("SOP::Swap: VarID must be even number.", v2);
296
+ ZBDD z = GetZBDD();
297
+ z = z.Swap(v1, v2);
298
+ z = z.Swap(v1-1, v2-1);
299
+ return SOP(z);
300
+ }
301
+
302
+ SOP SOP::Implicants(BDD f) const
303
+ {
304
+ if(*this == 0) return 0;
305
+ if(f == 0) return 0;
306
+ if(f == 1) return *this;
307
+ if(*this == 1) return 0;
308
+
309
+ bddword fx = GetZBDD().GetID();
310
+ bddword gx = f.GetID();
311
+ SOP_CACHE_CHK_RETURN(BC_SOP_IMPL, fx, gx);
312
+
313
+ int top = Top();
314
+ if(BDD_LevOfVar(top) < BDD_LevOfVar(f.Top())) top = f.Top();
315
+
316
+ BDD f0 = f.At0(top);
317
+ BDD f1 = f.At1(top);
318
+ SOP imp = Factor0(top).Implicants(f0).And0(top)
319
+ + Factor1(top).Implicants(f1).And1(top);
320
+ SOP pD = FactorD(top);
321
+ if(pD != 0) imp += pD.Implicants(f0 & f1);
322
+
323
+ SOP_CACHE_ENT_RETURN(BC_SOP_IMPL, fx, gx, imp);
324
+ }
325
+
326
+
327
+ //----------- External functions for SOP ----------
328
+
329
+ int SOPV_NewVar() { BDD_NewVar(); return BDD_NewVar(); }
330
+
331
+ int SOPV_NewVarOfLev(int lev)
332
+ {
333
+ BDD_NewVarOfLev(lev - 1);
334
+ return BDD_NewVarOfLev(lev);
335
+ }
336
+
337
+ //-------------- Class methods of SOPV -----------------
338
+
339
+ SOPV SOPV::operator<<=(int n) { return *this = *this << n; }
340
+ SOPV SOPV::operator>>=(int n) { return *this = *this >> n; }
341
+
342
+ SOPV SOPV::And0(int v) const
343
+ {
344
+ if(v & 1) BDDerr("SOPV::And0: VarID must be even number.", v);
345
+ ZBDDV f = _v.OffSet(v);
346
+ f = f.OnSet0(v-1) + f.OffSet(v-1);
347
+ f = f.Change(v-1);
348
+ return SOPV(f);
349
+ }
350
+
351
+ SOPV SOPV::And1(int v) const
352
+ {
353
+ if(v & 1) BDDerr("SOPV::And1: VarID must be even number.", v);
354
+ ZBDDV f = _v.OffSet(v-1);
355
+ f = f.OnSet0(v) + f.OffSet(v);
356
+ f = f.Change(v);
357
+ return SOPV(f);
358
+ }
359
+
360
+ SOPV SOPV::Factor0(int v) const
361
+ {
362
+ if(v & 1) BDDerr("SOPV::Factor0: VarID must be even number.", v);
363
+ ZBDDV f = _v.OnSet0(v-1);
364
+ return SOPV(f);
365
+ }
366
+
367
+ SOPV SOPV::Factor1(int v) const
368
+ {
369
+ if(v & 1) BDDerr("SOPV::Factor1: VarID must be even number.", v);
370
+ ZBDDV f = _v.OnSet0(v);
371
+ return SOPV(f);
372
+ }
373
+
374
+ SOPV SOPV::FactorD(int v) const
375
+ {
376
+ if(v & 1) BDDerr("SOPV::FactorD: VarID must be even number.", v);
377
+ ZBDDV f = _v.OffSet(v).OffSet(v-1);
378
+ return SOPV(f);
379
+ }
380
+
381
+ bddword SOPV::Size() const { return _v.Size(); }
382
+
383
+ SOP SOPV::GetSOP(int index) const { return SOP(_v.GetZBDD(index)); }
384
+
385
+ SOPV SOPV::Swap(int v1, int v2) const
386
+ {
387
+ if(v1 & 1) BDDerr("SOPV::Swap: VarID must be even number.", v1);
388
+ if(v2 & 1) BDDerr("SOPV::Swap: VarID must be even number.", v2);
389
+ ZBDDV z = GetZBDDV();
390
+ z = z.Swap(v1, v2);
391
+ z = z.Swap(v1-1, v2-1);
392
+ return SOPV(z);
393
+ }
394
+
395
+ bddword SOPV::Cube() const
396
+ {
397
+ SOPV v = *this;
398
+ SOP sum = 0;
399
+ while(v != SOPV())
400
+ {
401
+ if(v == SOPV(-1)) return 0;
402
+ int last = v.Last();
403
+ sum += v.GetSOP(last);
404
+ v -= v.Mask(last);
405
+ }
406
+ return sum.Cube();
407
+ }
408
+
409
+ bddword SOPV::Lit() const
410
+ {
411
+ SOPV v = *this;
412
+ SOP sum = 0;
413
+ while(v != SOPV())
414
+ {
415
+ if(v == SOPV(-1)) return 0;
416
+ int last = v.Last();
417
+ SOP f = v.GetSOP(last);
418
+ sum += f;
419
+ v -= v.Mask(last);
420
+ }
421
+ return sum.Lit();
422
+ }
423
+
424
+ void SOPV::Print() const
425
+ {
426
+ int len = this -> Last() + 1;
427
+ for(int i=0; i<len; i++)
428
+ {
429
+ cout << "f" << i << ": ";
430
+ GetSOP(i).Print();
431
+ }
432
+ cout << "Size= " << Size() << "\n";
433
+ cout << "Cube= " << Cube() << "\n";
434
+ cout << "Lit= " << Lit() << "\n\n";
435
+ cout.flush();
436
+ }
437
+
438
+ static int Len;
439
+ static char* Array;
440
+ static int SOPV_PLA(const SOPV &, int);
441
+ static int SOPV_PLA(const SOPV& v, int tlev)
442
+ {
443
+ if(v == SOPV(-1)) return 1;
444
+ if(v == SOPV()) return 0;
445
+ SOPV vv = v;
446
+ if(tlev == 0)
447
+ {
448
+ cout << Array << " ";
449
+ for(int i=0; i<Len; i++)
450
+ if(vv.GetSOP(i) == 0) cout << "~";
451
+ else cout << "1";
452
+ cout << "\n";
453
+ cout.flush();
454
+ return 0;
455
+ }
456
+ else
457
+ {
458
+ Array[tlev/2-1] = '1';
459
+ if(SOPV_PLA(vv.Factor1(BDD_VarOfLev(tlev)), tlev-2) == 1)
460
+ return 1;
461
+ Array[tlev/2-1] = '0';
462
+ if(SOPV_PLA(vv.Factor0(BDD_VarOfLev(tlev)), tlev-2) == 1)
463
+ return 1;
464
+ Array[tlev/2-1] = '-';
465
+ return SOPV_PLA(vv.FactorD(BDD_VarOfLev(tlev)), tlev-2);
466
+ }
467
+ }
468
+
469
+ int SOPV::PrintPla() const
470
+ {
471
+ if(*this == SOPV(-1)) return 1;
472
+ int tlev = BDD_LevOfVar(Top());
473
+ Len = Last() + 1;
474
+ cout << ".i " << tlev/2 << "\n";
475
+ cout << ".o " << Len << "\n";
476
+ if(tlev > 0)
477
+ {
478
+ Array = new char[tlev/2 + 1];
479
+ Array[tlev/2] = 0;
480
+ int err = SOPV_PLA(*this, tlev);
481
+ delete[] Array;
482
+ if(err == 1) return 1;
483
+ }
484
+ else
485
+ {
486
+ for(int i=0; i<Len; i++)
487
+ if(GetSOP(i) == 0) cout << "0";
488
+ else cout << "1";
489
+ cout << "\n";
490
+ }
491
+ cout << ".e\n";
492
+ cout.flush();
493
+ return 0;
494
+ }
495
+
496
+ //--------- Advanced external functions for SOP/SOPV ---------
497
+
498
+ struct BCpair
499
+ {
500
+ BDD _f;
501
+ SOP _cs;
502
+ BCpair() { _f = 0; _cs = 0; }
503
+ BCpair(const BDD& f, const SOP& cs) { _f = f; _cs = cs; }
504
+ BCpair(const BCpair& p) { _f = p._f; _cs = p._cs; }
505
+ };
506
+
507
+ static BCpair ISOP(BDD, BDD);
508
+ BCpair ISOP(BDD s, BDD r)
509
+ {
510
+ if(s == -1) return BCpair(-1, -1);
511
+ if(r == -1) return BCpair(-1, -1);
512
+ if(r == 1) return BCpair(0, 0);
513
+ if(s == 1) return BCpair(1, 1);
514
+
515
+ bddword sx = s.GetID();
516
+ bddword rx = r.GetID();
517
+ BDD f = BDD_CacheBDD(BC_ISOP1, sx, rx);
518
+ ZBDD z = BDD_CacheZBDD(BC_ISOP2, sx, rx);
519
+ if(f != -1) if(z != -1) return BCpair(f, SOP(z));
520
+ BDD_RECUR_INC;
521
+
522
+ int top = s.Top();
523
+ if(BDD_LevOfVar(top) < BDD_LevOfVar(r.Top())) top = r.Top();
524
+
525
+ BDD s0 = s.At0(top);
526
+ BDD r0 = r.At0(top);
527
+ BDD s1 = s.At1(top);
528
+ BDD r1 = r.At1(top);
529
+
530
+ BCpair bc1 = ISOP(s1, r1 | s0);
531
+ SOP c1 = bc1._cs.And1(top);
532
+
533
+ BCpair bc0 = ISOP(s0, r0 | s1);
534
+ SOP c0 = bc0._cs.And0(top);
535
+
536
+ BDD sD = (s0 & s1);
537
+ BCpair bcD = ISOP(sD, ~sD |( (r0|bc0._f) & (r1|bc1._f) ));
538
+ SOP cD = bcD._cs;
539
+
540
+ BDD x = BDDvar(top);
541
+ f = (~x & bc0._f)|(x & bc1._f)| bcD._f;
542
+ SOP cs = c1 + c0 + cD;
543
+
544
+ BDD_RECUR_DEC;
545
+ if(f == -1) return BCpair(-1, -1);
546
+ if(cs == -1) return BCpair(-1, -1);
547
+ BDD_CacheEnt(BC_ISOP1, sx, rx, f.GetID());
548
+ BDD_CacheEnt(BC_ISOP2, sx, rx, cs.GetZBDD().GetID());
549
+ return BCpair(f, cs);
550
+ }
551
+
552
+ SOP SOP_ISOP(BDD f) { return ISOP(f, ~f)._cs; }
553
+
554
+ SOP SOP_ISOP(BDD on, BDD dc)
555
+ {
556
+ return ISOP(on | dc, ~on |dc)._cs;
557
+ }
558
+
559
+ SOPV SOPV_ISOP(BDDV v) { return SOPV_ISOP(v, BDDV(0, v.Len())); }
560
+
561
+ SOPV SOPV_ISOP(BDDV on, BDDV dc)
562
+ {
563
+ int len = on.Len();
564
+ if(len != dc.Len()) BDDerr("SOPV_ISOP(): Len mismatch.");
565
+ int top = on.Top();
566
+ if(BDD_LevOfVar(top) < BDD_LevOfVar(dc.Top())) top = dc.Top();
567
+ SOPV csv(0, 0);
568
+ for(int i=0; i<len; i++)
569
+ {
570
+ SOP cs = SOP_ISOP(on.GetBDD(i), dc.GetBDD(i));
571
+ csv += SOPV(cs, i);
572
+ }
573
+ return csv;
574
+ }
575
+
576
+ SOPV SOPV_ISOP2(BDDV v) { return SOPV_ISOP2(v, BDDV(0, v.Len())); }
577
+
578
+ SOPV SOPV_ISOP2(BDDV on, BDDV dc)
579
+ {
580
+ int len = on.Len();
581
+ if(len != dc.Len()) BDDerr("SOPV_ISOP2(): Len mismatch,");
582
+ int top = on.Top();
583
+ if(BDD_LevOfVar(top) < BDD_LevOfVar(dc.Top())) top = dc.Top();
584
+ SOPV csv;
585
+ SOPV phase;
586
+ for(int i=0; i<len; i++)
587
+ {
588
+ SOP cs1 = SOP_ISOP(on.GetBDD(i), dc.GetBDD(i));
589
+ if(cs1 == -1) return SOPV(-1);
590
+ SOP cs2 = SOP_ISOP(~on.GetBDD(i), dc.GetBDD(i));
591
+ if(cs2 == -1) return SOPV(-1);
592
+ int lit1 = (csv + SOPV(cs1, i)).Lit();
593
+ int lit2 = (csv + SOPV(cs2, i)).Lit();
594
+
595
+ if(lit1 <= lit2)
596
+ {
597
+ csv += SOPV(cs1, i);
598
+ phase += SOPV(0, i+len);
599
+ }
600
+ else
601
+ {
602
+ csv += SOPV(cs2, i);
603
+ phase += SOPV(1, i+len);
604
+ }
605
+ }
606
+ return csv + phase;
607
+ }
608
+