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/CtoI.h
ADDED
@@ -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
|
+
|
data/ext/zdd_so/SOP.cc
ADDED
@@ -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
|
+
|