nysol-zdd 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/ext/zdd_so/BDD.cc +495 -0
  3. data/ext/zdd_so/BDD.h +356 -0
  4. data/ext/zdd_so/BDDDG.cc +1818 -0
  5. data/ext/zdd_so/BDDDG.h +107 -0
  6. data/ext/zdd_so/BDDHASH.cc +91 -0
  7. data/ext/zdd_so/BtoI.cc +503 -0
  8. data/ext/zdd_so/BtoI.h +144 -0
  9. data/ext/zdd_so/CtoI.cc +1072 -0
  10. data/ext/zdd_so/CtoI.h +186 -0
  11. data/ext/zdd_so/MLZBDDV.cc +153 -0
  12. data/ext/zdd_so/MLZBDDV.h +42 -0
  13. data/ext/zdd_so/SOP.cc +608 -0
  14. data/ext/zdd_so/SOP.h +199 -0
  15. data/ext/zdd_so/ZBDD.cc +1035 -0
  16. data/ext/zdd_so/ZBDD.h +243 -0
  17. data/ext/zdd_so/ZBDDDG.cc +1834 -0
  18. data/ext/zdd_so/ZBDDDG.h +105 -0
  19. data/ext/zdd_so/ZBDDHASH.cc +91 -0
  20. data/ext/zdd_so/bddc.c +2816 -0
  21. data/ext/zdd_so/bddc.h +132 -0
  22. data/ext/zdd_so/extconf.rb +25 -0
  23. data/ext/zdd_so/include/aheap.c +211 -0
  24. data/ext/zdd_so/include/aheap.h +111 -0
  25. data/ext/zdd_so/include/base.c +93 -0
  26. data/ext/zdd_so/include/base.h +60 -0
  27. data/ext/zdd_so/include/itemset.c +473 -0
  28. data/ext/zdd_so/include/itemset.h +153 -0
  29. data/ext/zdd_so/include/problem.c +371 -0
  30. data/ext/zdd_so/include/problem.h +160 -0
  31. data/ext/zdd_so/include/queue.c +518 -0
  32. data/ext/zdd_so/include/queue.h +177 -0
  33. data/ext/zdd_so/include/sgraph.c +331 -0
  34. data/ext/zdd_so/include/sgraph.h +170 -0
  35. data/ext/zdd_so/include/stdlib2.c +832 -0
  36. data/ext/zdd_so/include/stdlib2.h +746 -0
  37. data/ext/zdd_so/include/trsact.c +723 -0
  38. data/ext/zdd_so/include/trsact.h +167 -0
  39. data/ext/zdd_so/include/vec.c +583 -0
  40. data/ext/zdd_so/include/vec.h +159 -0
  41. data/ext/zdd_so/lcm-vsop.cc +596 -0
  42. data/ext/zdd_so/print.cc +683 -0
  43. data/ext/zdd_so/table.cc +330 -0
  44. data/ext/zdd_so/vsop.h +88 -0
  45. data/ext/zdd_so/zdd_so.cpp +3277 -0
  46. data/lib/nysol/zdd.rb +31 -0
  47. metadata +131 -0
@@ -0,0 +1,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
+