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.
- 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/BtoI.h
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
/******************************************
|
2
|
+
* Binary-to-Integer function class *
|
3
|
+
* (SAPPORO-1.55) - Header *
|
4
|
+
* (C) Shin-ichi MINATO (Dec. 11, 2012) *
|
5
|
+
******************************************/
|
6
|
+
|
7
|
+
class BtoI;
|
8
|
+
|
9
|
+
#ifndef _BtoI_
|
10
|
+
#define _BtoI_
|
11
|
+
|
12
|
+
#include "BDD.h"
|
13
|
+
|
14
|
+
class BtoI
|
15
|
+
{
|
16
|
+
BDDV _bddv;
|
17
|
+
|
18
|
+
BtoI Shift(int) const;
|
19
|
+
BtoI Sup(void) const;
|
20
|
+
|
21
|
+
public:
|
22
|
+
BtoI(void) { _bddv = BDDV(0); }
|
23
|
+
BtoI(const BtoI& fv) { _bddv = fv._bddv; }
|
24
|
+
BtoI(const BDDV& fv) { _bddv = fv; }
|
25
|
+
BtoI(const BDD& f)
|
26
|
+
{ _bddv = f; if(f != 0 && f != -1) _bddv = _bddv || BDDV(0); }
|
27
|
+
BtoI(int);
|
28
|
+
~BtoI(void) { }
|
29
|
+
|
30
|
+
BtoI& operator=(const BtoI& fv) { _bddv = fv._bddv; return *this; }
|
31
|
+
BtoI& operator+=(const BtoI&);
|
32
|
+
BtoI& operator-=(const BtoI&);
|
33
|
+
BtoI& operator*=(const BtoI&);
|
34
|
+
BtoI& operator/=(const BtoI&);
|
35
|
+
BtoI& operator%=(const BtoI&);
|
36
|
+
BtoI& operator&=(const BtoI&);
|
37
|
+
BtoI& operator|=(const BtoI&);
|
38
|
+
BtoI& operator^=(const BtoI&);
|
39
|
+
BtoI& operator<<=(const BtoI&);
|
40
|
+
BtoI& operator>>=(const BtoI&);
|
41
|
+
|
42
|
+
BtoI operator-(void) const { return 0 - *this; }
|
43
|
+
BtoI operator~(void) const { return BtoI(~_bddv); }
|
44
|
+
BtoI operator!(void) const;
|
45
|
+
BtoI operator<<(const BtoI&) const;
|
46
|
+
BtoI operator>>(const BtoI& fv) const { return *this << -fv; }
|
47
|
+
|
48
|
+
BtoI UpperBound(void) const;
|
49
|
+
BtoI UpperBound(const BDD&) const;
|
50
|
+
BtoI LowerBound(void) const { return -(- *this).UpperBound(); }
|
51
|
+
BtoI LowerBound(const BDD& f) const { return -(- *this).UpperBound(f); }
|
52
|
+
|
53
|
+
BtoI At0(int v) const {
|
54
|
+
if(BDD_LevOfVar(v) > BDD_TopLev())
|
55
|
+
BDDerr("BtoI::At0: Invalid VarID.", v);
|
56
|
+
return BtoI(_bddv.At0(v)).Sup();
|
57
|
+
}
|
58
|
+
|
59
|
+
BtoI At1(int v) const {
|
60
|
+
if(BDD_LevOfVar(v) > BDD_TopLev())
|
61
|
+
BDDerr("BtoI::At1: Invalid VarID.", v);
|
62
|
+
return BtoI(_bddv.At1(v)).Sup();
|
63
|
+
}
|
64
|
+
|
65
|
+
BtoI Cofact(const BtoI&) const;
|
66
|
+
|
67
|
+
BtoI Spread(int k) const { return BtoI(_bddv.Spread(k)).Sup(); }
|
68
|
+
|
69
|
+
int Top(void) const { return _bddv.Top(); }
|
70
|
+
|
71
|
+
BDD GetSignBDD(void) const { return _bddv.GetBDD(Len() - 1); }
|
72
|
+
|
73
|
+
BDD GetBDD(int i) const
|
74
|
+
{ return _bddv.GetBDD((i >= Len())? Len()-1: i); }
|
75
|
+
|
76
|
+
BDDV GetMetaBDDV(void) const { return _bddv; }
|
77
|
+
|
78
|
+
int Len(void) const { return _bddv.Len(); }
|
79
|
+
|
80
|
+
int GetInt(void) const;
|
81
|
+
int StrNum10(char *) const;
|
82
|
+
int StrNum16(char *) const;
|
83
|
+
bddword Size() const;
|
84
|
+
|
85
|
+
void Print() const;
|
86
|
+
|
87
|
+
friend int operator==(const BtoI&, const BtoI&);
|
88
|
+
|
89
|
+
friend BtoI operator+(const BtoI&, const BtoI&);
|
90
|
+
friend BtoI operator-(const BtoI&, const BtoI&);
|
91
|
+
friend BtoI operator&(const BtoI&, const BtoI&);
|
92
|
+
friend BtoI operator|(const BtoI&, const BtoI&);
|
93
|
+
friend BtoI operator^(const BtoI&, const BtoI&);
|
94
|
+
friend BtoI BtoI_ITE(const BDD&, const BtoI&, const BtoI&);
|
95
|
+
};
|
96
|
+
|
97
|
+
extern BtoI operator+(const BtoI&, const BtoI&);
|
98
|
+
extern BtoI operator-(const BtoI&, const BtoI&);
|
99
|
+
extern BtoI operator*(const BtoI&, const BtoI&);
|
100
|
+
extern BtoI operator/(const BtoI&, const BtoI&);
|
101
|
+
extern BtoI operator&(const BtoI&, const BtoI&);
|
102
|
+
extern BtoI operator|(const BtoI&, const BtoI&);
|
103
|
+
extern BtoI operator^(const BtoI&, const BtoI&);
|
104
|
+
extern BtoI BtoI_ITE(const BDD&, const BtoI&, const BtoI&);
|
105
|
+
|
106
|
+
extern BtoI BtoI_EQ(const BtoI&, const BtoI&);
|
107
|
+
|
108
|
+
extern BtoI BtoI_atoi(char *);
|
109
|
+
|
110
|
+
inline int operator==(const BtoI& a, const BtoI& b)
|
111
|
+
{ return a._bddv == b._bddv; }
|
112
|
+
|
113
|
+
inline int operator!=(const BtoI& a, const BtoI& b) { return !(a == b); }
|
114
|
+
|
115
|
+
inline BtoI operator%(const BtoI& a, const BtoI&b )
|
116
|
+
{ return a - (a / b) * b; }
|
117
|
+
|
118
|
+
inline BtoI BtoI_ITE(const BtoI& a, const BtoI& b, const BtoI& c)
|
119
|
+
{ return BtoI_ITE(~(BtoI_EQ(a, 0).GetBDD(0)), b, c); }
|
120
|
+
|
121
|
+
inline BtoI BtoI_GT(const BtoI& a, const BtoI& b)
|
122
|
+
{ return BtoI((b - a).GetSignBDD()); }
|
123
|
+
|
124
|
+
inline BtoI BtoI_LT(const BtoI& a, const BtoI& b)
|
125
|
+
{ return BtoI((a - b).GetSignBDD()); }
|
126
|
+
|
127
|
+
inline BtoI BtoI_NE(const BtoI& a, const BtoI& b)
|
128
|
+
{ return ! BtoI_EQ(a, b); }
|
129
|
+
|
130
|
+
inline BtoI BtoI_GE(const BtoI& a, const BtoI& b)
|
131
|
+
{ return ! BtoI_LT(a, b); }
|
132
|
+
|
133
|
+
inline BtoI BtoI_LE(const BtoI& a, const BtoI& b)
|
134
|
+
{ return ! BtoI_GT(a, b); }
|
135
|
+
|
136
|
+
inline BtoI BtoI::operator!(void) const { return BtoI_EQ(*this, 0); }
|
137
|
+
|
138
|
+
inline BtoI BtoI::Cofact(const BtoI& fv) const {
|
139
|
+
BDDV a = BDDV(BtoI_NE(fv, 0).GetBDD(0), Len());
|
140
|
+
return BtoI(_bddv.Cofact(a)).Sup();
|
141
|
+
}
|
142
|
+
|
143
|
+
#endif // _BtoI_
|
144
|
+
|
data/ext/zdd_so/CtoI.cc
ADDED
@@ -0,0 +1,1072 @@
|
|
1
|
+
/******************************************
|
2
|
+
* Combination-to-Integer function class *
|
3
|
+
* (SAPPORO-1.71) - Body *
|
4
|
+
* (C) Shin-ichi MINATO (Dec. 15, 2015) *
|
5
|
+
******************************************/
|
6
|
+
|
7
|
+
#include "CtoI.h"
|
8
|
+
|
9
|
+
using std::cout;
|
10
|
+
|
11
|
+
static const char BC_CtoI_MULT = 40;
|
12
|
+
static const char BC_CtoI_DIV = 41;
|
13
|
+
static const char BC_CtoI_TV = 42;
|
14
|
+
static const char BC_CtoI_TVI = 43;
|
15
|
+
|
16
|
+
static const char BC_CtoI_RI = 44;
|
17
|
+
static const char BC_CtoI_FPA = 45;
|
18
|
+
static const char BC_CtoI_FPAV = 46;
|
19
|
+
static const char BC_CtoI_FPM = 47;
|
20
|
+
static const char BC_CtoI_FPC = 48;
|
21
|
+
static const char BC_CtoI_MEET = 49;
|
22
|
+
|
23
|
+
//----------- Macros for operation cache -----------
|
24
|
+
#define CtoI_CACHE_CHK_RETURN(op, fx, gx) \
|
25
|
+
{ ZBDD z = BDD_CacheZBDD(op, fx, gx); \
|
26
|
+
if(z != -1) return CtoI(z); \
|
27
|
+
BDD_RECUR_INC; }
|
28
|
+
|
29
|
+
#define CtoI_CACHE_ENT_RETURN(op, fx, gx, h) \
|
30
|
+
{ BDD_RECUR_DEC; \
|
31
|
+
if(h != CtoI_Null()) BDD_CacheEnt(op, fx, gx, h._zbdd.GetID()); \
|
32
|
+
return h; }
|
33
|
+
|
34
|
+
//-------------- Public Methods -----------
|
35
|
+
CtoI::CtoI(int n)
|
36
|
+
{
|
37
|
+
if(n == 0) _zbdd = 0;
|
38
|
+
else if(n == 1) _zbdd = 1;
|
39
|
+
else if(n < 0)
|
40
|
+
{
|
41
|
+
if((n = -n) < 0) BDDerr("CtoI::CtoI(): overflow.", n);
|
42
|
+
*this = -CtoI(n);
|
43
|
+
}
|
44
|
+
else
|
45
|
+
{
|
46
|
+
*this = 0;
|
47
|
+
CtoI a = 1;
|
48
|
+
while(n)
|
49
|
+
{
|
50
|
+
if(n & 1) *this += a;
|
51
|
+
a += a;
|
52
|
+
n >>= 1;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
int CtoI::TopItem() const
|
58
|
+
{
|
59
|
+
int v = Top();
|
60
|
+
if(BDD_LevOfVar(v) <= BDD_TopLev()) return v;
|
61
|
+
int v0 = Factor0(v).TopItem();
|
62
|
+
int v1 = Factor1(v).TopItem();
|
63
|
+
return (BDD_LevOfVar(v0) > BDD_LevOfVar(v1))? v0: v1;
|
64
|
+
}
|
65
|
+
|
66
|
+
int CtoI::TopDigit() const
|
67
|
+
{
|
68
|
+
int v = Top();
|
69
|
+
if(BDD_LevOfVar(v) <= BDD_TopLev()) return 0;
|
70
|
+
int d0 = Factor0(v).TopDigit();
|
71
|
+
int d1 = Factor1(v).TopDigit() + (1 << (BDDV_SysVarTop - v));
|
72
|
+
return (d0 > d1)? d0: d1;
|
73
|
+
}
|
74
|
+
|
75
|
+
CtoI CtoI::FilterThen(const CtoI& a) const
|
76
|
+
{
|
77
|
+
if(*this == 0) return 0;
|
78
|
+
if(*this == CtoI_Null()) return CtoI_Null();
|
79
|
+
CtoI aa = a.IsBool()? a: a.NonZero();
|
80
|
+
if(aa == 0) return 0;
|
81
|
+
if(IsBool()) return CtoI_Intsec(*this, aa);
|
82
|
+
int v = Top();
|
83
|
+
return CtoI_Union(Factor0(v).FilterThen(aa),
|
84
|
+
Factor1(v).FilterThen(aa).AffixVar(v));
|
85
|
+
}
|
86
|
+
|
87
|
+
CtoI CtoI::FilterElse(const CtoI& a) const
|
88
|
+
{
|
89
|
+
if(*this == 0) return 0;
|
90
|
+
if(*this == CtoI_Null()) return CtoI_Null();
|
91
|
+
CtoI aa = a.IsBool()? a: a.NonZero();
|
92
|
+
if(aa == 0) return *this;
|
93
|
+
if(IsBool()) return CtoI_Diff(*this, aa);
|
94
|
+
int v = Top();
|
95
|
+
return CtoI_Union(Factor0(v).FilterElse(aa),
|
96
|
+
Factor1(v).FilterElse(aa).AffixVar(v));
|
97
|
+
}
|
98
|
+
|
99
|
+
CtoI CtoI::FilterRestrict(const CtoI& a) const
|
100
|
+
{
|
101
|
+
CtoI th = IsBool()? *this: NonZero();
|
102
|
+
CtoI aa = a.IsBool()? a: a.NonZero();
|
103
|
+
return FilterThen(CtoI(th._zbdd.Restrict(aa._zbdd)));
|
104
|
+
}
|
105
|
+
|
106
|
+
CtoI CtoI::FilterPermit(const CtoI& a) const
|
107
|
+
{
|
108
|
+
CtoI th = IsBool()? *this: NonZero();
|
109
|
+
CtoI aa = a.IsBool()? a: a.NonZero();
|
110
|
+
return FilterThen(CtoI(th._zbdd.Permit(aa._zbdd)));
|
111
|
+
}
|
112
|
+
|
113
|
+
CtoI CtoI::FilterPermitSym(int n) const
|
114
|
+
{
|
115
|
+
CtoI th = IsBool()? *this: NonZero();
|
116
|
+
return FilterThen(CtoI(th._zbdd.PermitSym(n)));
|
117
|
+
}
|
118
|
+
|
119
|
+
CtoI CtoI::NonZero() const
|
120
|
+
{
|
121
|
+
if(IsBool()) return *this;
|
122
|
+
int v = Top();
|
123
|
+
return CtoI_Union(Factor0(v).NonZero(), Factor1(v).NonZero());
|
124
|
+
}
|
125
|
+
|
126
|
+
CtoI CtoI::ConstTerm() const
|
127
|
+
{
|
128
|
+
if(IsBool()) return CtoI_Intsec(*this, 1);
|
129
|
+
int v = Top();
|
130
|
+
return CtoI_Union(Factor0(v).ConstTerm(),
|
131
|
+
Factor1(v).ConstTerm().AffixVar(v));
|
132
|
+
}
|
133
|
+
|
134
|
+
CtoI CtoI::Digit(int index) const
|
135
|
+
{
|
136
|
+
if(index < 0) BDDerr("CtoI::Digit(): invalid index.", index);
|
137
|
+
CtoI a = *this;
|
138
|
+
for(int i=0; i<BDDV_SysVarTop; i++)
|
139
|
+
{
|
140
|
+
if(index == 0) break;
|
141
|
+
if(index & 1) a = a.Factor1(BDDV_SysVarTop - i);
|
142
|
+
else a = a.Factor0(BDDV_SysVarTop - i);
|
143
|
+
if(a == CtoI_Null()) break;
|
144
|
+
index >>= 1;
|
145
|
+
}
|
146
|
+
while(! a.IsBool()) a = a.Factor0(a.Top());
|
147
|
+
return a;
|
148
|
+
}
|
149
|
+
|
150
|
+
CtoI CtoI::EQ_Const(const CtoI& a) const
|
151
|
+
{
|
152
|
+
return CtoI_Diff(NonZero(), NE_Const(a));
|
153
|
+
}
|
154
|
+
|
155
|
+
CtoI CtoI::NE_Const(const CtoI& a) const
|
156
|
+
{
|
157
|
+
if(a == 0) return CtoI_NE(*this, 0);
|
158
|
+
return CtoI_NE(*this, a * NonZero());
|
159
|
+
}
|
160
|
+
|
161
|
+
CtoI CtoI::GT_Const(const CtoI& a) const
|
162
|
+
{
|
163
|
+
if(a == 0) return CtoI_GT(*this, 0);
|
164
|
+
return CtoI_GT(*this, a * NonZero());
|
165
|
+
}
|
166
|
+
|
167
|
+
CtoI CtoI::GE_Const(const CtoI& a) const
|
168
|
+
{
|
169
|
+
if(a == 0) return CtoI_GE(*this, 0);
|
170
|
+
return CtoI_GE(*this, a * NonZero());
|
171
|
+
}
|
172
|
+
|
173
|
+
CtoI CtoI::LT_Const(const CtoI& a) const
|
174
|
+
{
|
175
|
+
if(a == 0) return CtoI_GT(0, *this);
|
176
|
+
return CtoI_GT(a * NonZero(), *this);
|
177
|
+
}
|
178
|
+
|
179
|
+
CtoI CtoI::LE_Const(const CtoI& a) const
|
180
|
+
{
|
181
|
+
if(a == 0) return CtoI_GE(0, *this);
|
182
|
+
return CtoI_GE(a * NonZero(), *this);
|
183
|
+
}
|
184
|
+
|
185
|
+
CtoI CtoI::MaxVal() const
|
186
|
+
{
|
187
|
+
if(*this == CtoI_Null()) return 0;
|
188
|
+
CtoI a = *this;
|
189
|
+
CtoI cond = NonZero();
|
190
|
+
CtoI c = 0;
|
191
|
+
while(a != 0)
|
192
|
+
{
|
193
|
+
int td = a.TopDigit();
|
194
|
+
CtoI d = Digit(td);
|
195
|
+
if(td & 1)
|
196
|
+
{
|
197
|
+
CtoI cond0 = CtoI_Diff(cond, d);
|
198
|
+
if(cond0 != 0) cond = cond0;
|
199
|
+
else c = CtoI_Union(c, CtoI(1).ShiftDigit(td));
|
200
|
+
}
|
201
|
+
else
|
202
|
+
{
|
203
|
+
CtoI cond0 = CtoI_Intsec(cond, d);
|
204
|
+
if(cond0 != 0)
|
205
|
+
{
|
206
|
+
cond = cond0;
|
207
|
+
c = CtoI_Union(c, CtoI(1).ShiftDigit(td));
|
208
|
+
}
|
209
|
+
}
|
210
|
+
if(td == 0) break;
|
211
|
+
a = CtoI_Diff(a, d.ShiftDigit(td));
|
212
|
+
}
|
213
|
+
return c;
|
214
|
+
}
|
215
|
+
|
216
|
+
CtoI CtoI::MinVal() const { return - (- *this).MaxVal(); }
|
217
|
+
|
218
|
+
CtoI CtoI::TimesSysVar(int v) const
|
219
|
+
{
|
220
|
+
if(v > BDDV_SysVarTop || v <= 0)
|
221
|
+
BDDerr("CtoI::TimesSysVar(): invalid var ID.", v);
|
222
|
+
if(*this == 0) return *this;
|
223
|
+
if(*this == CtoI_Null()) return *this;
|
224
|
+
CtoI a0 = Factor0(v);
|
225
|
+
CtoI a1 = Factor1(v);
|
226
|
+
if(a1 == 0) return a0.AffixVar(v);
|
227
|
+
return CtoI_Union(a0.AffixVar(v), a1.TimesSysVar(v-1));
|
228
|
+
}
|
229
|
+
|
230
|
+
CtoI CtoI::DivBySysVar(int v) const
|
231
|
+
{
|
232
|
+
if(v > BDDV_SysVarTop || v <= 0)
|
233
|
+
BDDerr("CtoI::DivBySysVar(): invalid var ID.", v);
|
234
|
+
if(*this == 0) return *this;
|
235
|
+
if(*this == CtoI_Null()) return *this;
|
236
|
+
CtoI a0 = Factor0(v);
|
237
|
+
CtoI a1 = Factor1(v);
|
238
|
+
if(a0.IsBool() || v == 1) return a1;
|
239
|
+
return CtoI_Union(a1, a0.AffixVar(v).DivBySysVar(v-1));
|
240
|
+
}
|
241
|
+
|
242
|
+
CtoI CtoI::ShiftDigit(int pow) const
|
243
|
+
{
|
244
|
+
CtoI a = *this;
|
245
|
+
int v = BDDV_SysVarTop;
|
246
|
+
int i = (pow >= 0)? pow: -pow;
|
247
|
+
while(i)
|
248
|
+
{
|
249
|
+
if(i & 1)
|
250
|
+
{
|
251
|
+
if(pow > 0) a = a.TimesSysVar(v);
|
252
|
+
else a = a.DivBySysVar(v);
|
253
|
+
}
|
254
|
+
i >>= 1;
|
255
|
+
v--;
|
256
|
+
}
|
257
|
+
return a;
|
258
|
+
}
|
259
|
+
|
260
|
+
bddword CtoI::Size() const { return _zbdd.Size(); }
|
261
|
+
|
262
|
+
int CtoI::GetInt() const
|
263
|
+
{
|
264
|
+
if(*this == CtoI_Null()) return 0;
|
265
|
+
if(IsBool()) return (CtoI_Intsec(*this, 1)== 0)? 0: 1;
|
266
|
+
int v = Top();
|
267
|
+
CtoI a;
|
268
|
+
if((a=Factor0(v)) == CtoI_Null()) return 0;
|
269
|
+
int n = a.GetInt();
|
270
|
+
if((a=Factor1(v)) == CtoI_Null()) return 0;
|
271
|
+
if(v == BDDV_SysVarTop) return n - (a.GetInt() << 1);
|
272
|
+
return n + (a.GetInt() << (1<< (BDDV_SysVarTop - v)));
|
273
|
+
}
|
274
|
+
|
275
|
+
int CtoI::StrNum10(char* s) const
|
276
|
+
{
|
277
|
+
if(*this == CtoI_Null()) { sprintf(s, "0"); return 1; }
|
278
|
+
if(! IsConst()) return FilterThen(1).StrNum10(s);
|
279
|
+
int td = TopDigit();
|
280
|
+
if(td & 1)
|
281
|
+
{
|
282
|
+
if((- *this).StrNum10(s)) return 1;
|
283
|
+
int len = strlen(s);
|
284
|
+
for(int i=len; i>=0; i--) s[i+1] = s[i];
|
285
|
+
s[0] = '-';
|
286
|
+
return 0;
|
287
|
+
}
|
288
|
+
|
289
|
+
CtoI a = *this;
|
290
|
+
int i=0;
|
291
|
+
char s0[12];
|
292
|
+
if(td >= 20)
|
293
|
+
{
|
294
|
+
const int width = 9;
|
295
|
+
CtoI shift = 1000000000; // 10 ** width
|
296
|
+
while(1)
|
297
|
+
{
|
298
|
+
CtoI p = a / shift;
|
299
|
+
if(p == 0) break;
|
300
|
+
CtoI q = a - p * shift;
|
301
|
+
if(q == CtoI_Null()) { sprintf(s, "0"); return 1; }
|
302
|
+
sprintf(s0, "%09d", q.GetInt());
|
303
|
+
for(int j=i-1; j>=0; j--) s[j+width] = s[j];
|
304
|
+
for(int j=0; j<width; j++) s[j] = s0[j];
|
305
|
+
i += width;
|
306
|
+
a = p;
|
307
|
+
}
|
308
|
+
}
|
309
|
+
sprintf(s0, "%d", a.GetInt());
|
310
|
+
int len = strlen(s0);
|
311
|
+
for(int j=i-1; j>=0; j--) s[j+len] = s[j];
|
312
|
+
for(int j=0; j<len; j++) s[j] = s0[j];
|
313
|
+
i += len;
|
314
|
+
s[i] = 0;
|
315
|
+
return 0;
|
316
|
+
}
|
317
|
+
|
318
|
+
int CtoI::StrNum16(char* s) const
|
319
|
+
{
|
320
|
+
if(*this == CtoI_Null()) { sprintf(s, "0"); return 1; }
|
321
|
+
if(! IsConst()) return FilterThen(1).StrNum16(s);
|
322
|
+
int td = TopDigit();
|
323
|
+
if(td & 1)
|
324
|
+
{
|
325
|
+
if((- *this).StrNum16(s)) return 1;
|
326
|
+
int len = strlen(s);
|
327
|
+
for(int i=len; i>=0; i--) s[i+1] = s[i];
|
328
|
+
s[0] = '-';
|
329
|
+
return 0;
|
330
|
+
}
|
331
|
+
|
332
|
+
CtoI a = *this;
|
333
|
+
int i=0;
|
334
|
+
char s0[12];
|
335
|
+
if(td >= 20)
|
336
|
+
{
|
337
|
+
const int width = 6;
|
338
|
+
CtoI shift = 0x1000000; // 0x10 ** width
|
339
|
+
while(1)
|
340
|
+
{
|
341
|
+
CtoI p = a / shift;
|
342
|
+
if(p == 0) break;
|
343
|
+
CtoI q = a - p * shift;
|
344
|
+
if(q == CtoI_Null()) { sprintf(s, "0"); return 1; }
|
345
|
+
sprintf(s0, "%06X", q.GetInt());
|
346
|
+
for(int j=i-1; j>=0; j--) s[j+width] = s[j];
|
347
|
+
for(int j=0; j<width; j++) s[j] = s0[j];
|
348
|
+
i += width;
|
349
|
+
a = p;
|
350
|
+
}
|
351
|
+
}
|
352
|
+
sprintf(s0, "%X", a.GetInt());
|
353
|
+
int len = strlen(s0);
|
354
|
+
for(int j=i-1; j>=0; j--) s[j+len] = s[j];
|
355
|
+
for(int j=0; j<len; j++) s[j] = s0[j];
|
356
|
+
i += len;
|
357
|
+
s[i] = 0;
|
358
|
+
return 0;
|
359
|
+
}
|
360
|
+
|
361
|
+
static int Depth;
|
362
|
+
static int* S_Var;
|
363
|
+
static int PFflag;
|
364
|
+
static int PF(CtoI);
|
365
|
+
static int PF(CtoI a)
|
366
|
+
{
|
367
|
+
if(a.IsConst())
|
368
|
+
{
|
369
|
+
if(a.TopDigit() & 1) { cout << " -"; a = -a; }
|
370
|
+
else if(PFflag == 1) cout << " +";
|
371
|
+
|
372
|
+
PFflag = 1;
|
373
|
+
int c1 = (a != 1);
|
374
|
+
if(c1 || Depth == 0)
|
375
|
+
{
|
376
|
+
char s[80];
|
377
|
+
a.StrNum10(s);
|
378
|
+
cout << " " << s;
|
379
|
+
}
|
380
|
+
for(int i=0; i<Depth; i++) cout << " v" << S_Var[i];
|
381
|
+
cout.flush();
|
382
|
+
return 0;
|
383
|
+
}
|
384
|
+
|
385
|
+
int v = a.TopItem();
|
386
|
+
CtoI b = a.Factor1(v);
|
387
|
+
if(b == CtoI_Null()) return 1;
|
388
|
+
S_Var[Depth] = v;
|
389
|
+
Depth++;
|
390
|
+
if(PF(b) == 1) return 1;
|
391
|
+
|
392
|
+
Depth--;
|
393
|
+
b = a.Factor0(v);
|
394
|
+
if(b == 0) return 0;
|
395
|
+
if(b == CtoI_Null()) return 1;
|
396
|
+
return PF(b);
|
397
|
+
}
|
398
|
+
|
399
|
+
int CtoI::PutForm() const
|
400
|
+
{
|
401
|
+
if(*this == CtoI_Null()) return 1;
|
402
|
+
|
403
|
+
if(*this == 0) cout << " 0";
|
404
|
+
else
|
405
|
+
{
|
406
|
+
int v = TopItem();
|
407
|
+
Depth = 0;
|
408
|
+
S_Var = new int[v];
|
409
|
+
PFflag = 0;
|
410
|
+
int err = PF(*this);
|
411
|
+
delete[] S_Var;
|
412
|
+
if(err == 1)
|
413
|
+
{
|
414
|
+
cout << "...\n";
|
415
|
+
cout.flush();
|
416
|
+
return 1;
|
417
|
+
}
|
418
|
+
}
|
419
|
+
cout << "\n";
|
420
|
+
cout.flush();
|
421
|
+
return 0;
|
422
|
+
}
|
423
|
+
|
424
|
+
void CtoI::Print() const { _zbdd.Print(); }
|
425
|
+
|
426
|
+
CtoI CtoI::CountTerms() const
|
427
|
+
{
|
428
|
+
if(IsBool()) return TotalVal();
|
429
|
+
return NonZero().TotalVal();
|
430
|
+
}
|
431
|
+
|
432
|
+
CtoI CtoI::TotalVal() const
|
433
|
+
{
|
434
|
+
if(*this == CtoI_Null()) return *this;
|
435
|
+
int top = Top();
|
436
|
+
if(top == 0) return *this;
|
437
|
+
|
438
|
+
bddword x = _zbdd.GetID();
|
439
|
+
CtoI_CACHE_CHK_RETURN(BC_CtoI_TV, x, 0);
|
440
|
+
|
441
|
+
CtoI c = Factor0(top).TotalVal();
|
442
|
+
if(c != CtoI_Null())
|
443
|
+
{
|
444
|
+
if(IsBool())
|
445
|
+
c += Factor1(top).TotalVal();
|
446
|
+
else
|
447
|
+
c += Factor1(top).TotalVal().ShiftDigit(1<<(BDDV_SysVarTop - top));
|
448
|
+
}
|
449
|
+
|
450
|
+
CtoI_CACHE_ENT_RETURN(BC_CtoI_TV, x, 0, c);
|
451
|
+
}
|
452
|
+
|
453
|
+
CtoI CtoI::TotalValItems() const
|
454
|
+
{
|
455
|
+
if(*this == CtoI_Null()) return *this;
|
456
|
+
int top = Top();
|
457
|
+
if(top == 0) return CtoI(0);
|
458
|
+
|
459
|
+
bddword x = _zbdd.GetID();
|
460
|
+
CtoI_CACHE_CHK_RETURN(BC_CtoI_TVI, x, 0);
|
461
|
+
|
462
|
+
CtoI c = Factor0(top).TotalValItems();
|
463
|
+
if(c != CtoI_Null())
|
464
|
+
{
|
465
|
+
CtoI a1 = Factor1(top);
|
466
|
+
if(IsBool())
|
467
|
+
c += a1.TotalValItems() + a1.TotalVal().AffixVar(top);
|
468
|
+
else
|
469
|
+
c += a1.TotalValItems().ShiftDigit(1<<(BDDV_SysVarTop - top));
|
470
|
+
}
|
471
|
+
|
472
|
+
CtoI_CACHE_ENT_RETURN(BC_CtoI_TVI, x, 0, c);
|
473
|
+
}
|
474
|
+
|
475
|
+
CtoI CtoI::ReduceItems(const CtoI& b) const
|
476
|
+
{
|
477
|
+
if(*this == CtoI_Null()) return *this;
|
478
|
+
if(b == CtoI_Null()) return b;
|
479
|
+
if(! b.IsBool()) return ReduceItems(b.NonZero());
|
480
|
+
int atop = Top();
|
481
|
+
int btop = b.Top();
|
482
|
+
int top = (BDD_LevOfVar(atop) > BDD_LevOfVar(btop))? atop: btop;
|
483
|
+
if(top == 0) return *this;
|
484
|
+
|
485
|
+
bddword ax = _zbdd.GetID();
|
486
|
+
bddword bx = b._zbdd.GetID();
|
487
|
+
CtoI_CACHE_CHK_RETURN(BC_CtoI_RI, ax, bx);
|
488
|
+
|
489
|
+
CtoI c = CtoI(0);
|
490
|
+
if(BDD_LevOfVar(btop) > BDD_LevOfVar(atop))
|
491
|
+
c = ReduceItems(b.Factor0(btop));
|
492
|
+
else if(!IsBool())
|
493
|
+
c = Factor0(atop).ReduceItems(b)
|
494
|
+
+ Factor1(atop).ReduceItems(b).ShiftDigit(1<<(BDDV_SysVarTop - atop));
|
495
|
+
else if(BDD_LevOfVar(btop) == BDD_LevOfVar(atop))
|
496
|
+
c = Factor0(atop).ReduceItems(b) + Factor1(atop).ReduceItems(b);
|
497
|
+
else
|
498
|
+
{
|
499
|
+
c = Factor0(atop).ReduceItems(b.Factor0(atop))
|
500
|
+
+ Factor1(atop).ReduceItems(b.Factor0(atop)).AffixVar(atop);
|
501
|
+
}
|
502
|
+
|
503
|
+
CtoI_CACHE_ENT_RETURN(BC_CtoI_RI, ax, bx, c);
|
504
|
+
}
|
505
|
+
|
506
|
+
CtoI CtoI::FreqPatA(int Val) const
|
507
|
+
{
|
508
|
+
if(*this == CtoI_Null()) return *this;
|
509
|
+
if(IsConst()) return (GetInt() >= Val)? CtoI(1): CtoI(0);
|
510
|
+
|
511
|
+
int ax = _zbdd.GetID();
|
512
|
+
CtoI_CACHE_CHK_RETURN(BC_CtoI_FPA, ax, Val);
|
513
|
+
|
514
|
+
int top = TopItem();
|
515
|
+
CtoI f1 = Factor1(top);
|
516
|
+
|
517
|
+
CtoI f = f1;
|
518
|
+
int tv = 1 << f.TopDigit();
|
519
|
+
CtoI f2 = f1;
|
520
|
+
if(tv -(tv>>1) < Val)
|
521
|
+
{
|
522
|
+
tv = 0;
|
523
|
+
while(f != CtoI(0))
|
524
|
+
{
|
525
|
+
int d = f.TopDigit();
|
526
|
+
CtoI fd = f.Digit(d);
|
527
|
+
if(d & 1)
|
528
|
+
{
|
529
|
+
tv -= fd.GetZBDD().Card() << d;
|
530
|
+
if(tv >= Val) break;
|
531
|
+
}
|
532
|
+
else
|
533
|
+
{
|
534
|
+
tv += fd.GetZBDD().Card() << d;
|
535
|
+
if((tv>>1) >= Val) break;
|
536
|
+
}
|
537
|
+
f -= fd.ShiftDigit(d);
|
538
|
+
}
|
539
|
+
if(tv < Val) f2 = CtoI(0);
|
540
|
+
}
|
541
|
+
|
542
|
+
CtoI h1 = f2.FreqPatA(Val);
|
543
|
+
CtoI h = CtoI_Union(h1, h1.AffixVar(top));
|
544
|
+
CtoI f0 = Factor0(top);
|
545
|
+
if(f0 != CtoI(0))
|
546
|
+
{
|
547
|
+
//CtoI f1v = f1.GE_Const(CtoI(Val));
|
548
|
+
f0 = f0.FilterElse(h1);
|
549
|
+
if(f0 != CtoI(0))
|
550
|
+
{
|
551
|
+
f1 = f1.FilterElse(h1);
|
552
|
+
h = CtoI_Union(h, (f0 + f1).FreqPatA(Val));
|
553
|
+
}
|
554
|
+
}
|
555
|
+
|
556
|
+
CtoI_CACHE_ENT_RETURN(BC_CtoI_FPA, ax, Val, h);
|
557
|
+
}
|
558
|
+
|
559
|
+
CtoI CtoI::FreqPatA2(int Val) const
|
560
|
+
{
|
561
|
+
if(*this == CtoI_Null()) return *this;
|
562
|
+
if(IsConst()) return (GetInt() >= Val)? CtoI(1): CtoI(0);
|
563
|
+
|
564
|
+
int ax = _zbdd.GetID();
|
565
|
+
CtoI_CACHE_CHK_RETURN(BC_CtoI_FPA, ax, Val);
|
566
|
+
|
567
|
+
int top = TopItem();
|
568
|
+
CtoI f1 = Factor1(top);
|
569
|
+
|
570
|
+
CtoI f = f1;
|
571
|
+
int tv = 1 << f.TopDigit();
|
572
|
+
CtoI f2 = f1;
|
573
|
+
if(tv -(tv>>1) < Val)
|
574
|
+
{
|
575
|
+
tv = 0;
|
576
|
+
while(f != CtoI(0))
|
577
|
+
{
|
578
|
+
int d = f.TopDigit();
|
579
|
+
CtoI fd = f.Digit(d);
|
580
|
+
if(d & 1)
|
581
|
+
{
|
582
|
+
tv -= fd.GetZBDD().Card() << d;
|
583
|
+
if(tv >= Val) break;
|
584
|
+
}
|
585
|
+
else
|
586
|
+
{
|
587
|
+
tv += fd.GetZBDD().Card() << d;
|
588
|
+
if((tv>>1) >= Val) break;
|
589
|
+
}
|
590
|
+
f -= fd.ShiftDigit(d);
|
591
|
+
}
|
592
|
+
if(tv < Val) f2 = CtoI(0);
|
593
|
+
}
|
594
|
+
|
595
|
+
int sz = f2.Size();
|
596
|
+
CtoI s = f2.TotalValItems().LT_Const(CtoI(Val));
|
597
|
+
f2 = f2.ReduceItems(s);
|
598
|
+
cout << (float) (sz - f2.Size())/sz << " ";
|
599
|
+
cout.flush();
|
600
|
+
|
601
|
+
CtoI h1 = f2.FreqPatA2(Val);
|
602
|
+
CtoI h = CtoI_Union(h1, h1.AffixVar(top));
|
603
|
+
CtoI f0 = Factor0(top);
|
604
|
+
if(f0 != CtoI(0))
|
605
|
+
{
|
606
|
+
//CtoI f1v = f1.GE_Const(CtoI(Val));
|
607
|
+
f0 = f0.FilterElse(h1);
|
608
|
+
if(f0 != CtoI(0))
|
609
|
+
{
|
610
|
+
f1 = f1.FilterElse(h1);
|
611
|
+
h = CtoI_Union(h, (f0 + f1).FreqPatA2(Val));
|
612
|
+
}
|
613
|
+
}
|
614
|
+
|
615
|
+
CtoI_CACHE_ENT_RETURN(BC_CtoI_FPA, ax, Val, h);
|
616
|
+
}
|
617
|
+
|
618
|
+
CtoI CtoI::FreqPatAV(int Val) const
|
619
|
+
{
|
620
|
+
if(*this == CtoI_Null()) return *this;
|
621
|
+
if(IsConst()) return (GetInt() >= Val)? *this: CtoI(0);
|
622
|
+
|
623
|
+
int ax = _zbdd.GetID();
|
624
|
+
CtoI_CACHE_CHK_RETURN(BC_CtoI_FPAV, ax, Val);
|
625
|
+
|
626
|
+
int top = TopItem();
|
627
|
+
CtoI f1 = Factor1(top);
|
628
|
+
|
629
|
+
CtoI f = f1;
|
630
|
+
int tv = 1 << f.TopDigit();
|
631
|
+
CtoI f2 = f1;
|
632
|
+
if(tv -(tv>>1) < Val)
|
633
|
+
{
|
634
|
+
tv = 0;
|
635
|
+
while(f != CtoI(0))
|
636
|
+
{
|
637
|
+
int d = f.TopDigit();
|
638
|
+
CtoI fd = f.Digit(d);
|
639
|
+
if(d & 1)
|
640
|
+
{
|
641
|
+
tv -= fd.GetZBDD().Card() << d;
|
642
|
+
if(tv >= Val) break;
|
643
|
+
}
|
644
|
+
else
|
645
|
+
{
|
646
|
+
tv += fd.GetZBDD().Card() << d;
|
647
|
+
if((tv>>1) >= Val) break;
|
648
|
+
}
|
649
|
+
f -= fd.ShiftDigit(d);
|
650
|
+
}
|
651
|
+
if(tv < Val) f2 = CtoI(0);
|
652
|
+
}
|
653
|
+
|
654
|
+
CtoI h1 = f2.FreqPatAV(Val);
|
655
|
+
CtoI h = h1.AffixVar(top);
|
656
|
+
|
657
|
+
CtoI f0 = Factor0(top);
|
658
|
+
if(f0 == CtoI(0)) h = CtoI_Union(h, h1);
|
659
|
+
else h = CtoI_Union(h, (f0 + f1).FreqPatAV(Val));
|
660
|
+
|
661
|
+
CtoI_CACHE_ENT_RETURN(BC_CtoI_FPAV, ax, Val, h);
|
662
|
+
}
|
663
|
+
|
664
|
+
CtoI CtoI::FreqPatM(int Val) const
|
665
|
+
{
|
666
|
+
if(*this == CtoI_Null()) return *this;
|
667
|
+
if(IsConst()) return (GetInt() >= Val)? CtoI(1): CtoI(0);
|
668
|
+
|
669
|
+
int ax = _zbdd.GetID();
|
670
|
+
CtoI_CACHE_CHK_RETURN(BC_CtoI_FPM, ax, Val);
|
671
|
+
|
672
|
+
int top = TopItem();
|
673
|
+
CtoI f1 = Factor1(top);
|
674
|
+
|
675
|
+
CtoI f = f1;
|
676
|
+
int tv = 1 << f.TopDigit();
|
677
|
+
CtoI f2 = f1;
|
678
|
+
if(tv -(tv>>1) < Val)
|
679
|
+
{
|
680
|
+
tv = 0;
|
681
|
+
while(f != CtoI(0))
|
682
|
+
{
|
683
|
+
int d = f.TopDigit();
|
684
|
+
CtoI fd = f.Digit(d);
|
685
|
+
if(d & 1)
|
686
|
+
{
|
687
|
+
tv -= fd.GetZBDD().Card() << d;
|
688
|
+
if(tv >= Val) break;
|
689
|
+
}
|
690
|
+
else
|
691
|
+
{
|
692
|
+
tv += fd.GetZBDD().Card() << d;
|
693
|
+
if((tv>>1) >= Val) break;
|
694
|
+
}
|
695
|
+
f -= fd.ShiftDigit(d);
|
696
|
+
}
|
697
|
+
if(tv < Val) f2 = CtoI(0);
|
698
|
+
}
|
699
|
+
|
700
|
+
CtoI h1 = f2.FreqPatM(Val);
|
701
|
+
CtoI h = h1.AffixVar(top);
|
702
|
+
CtoI f0 = Factor0(top);
|
703
|
+
if(f0 != CtoI(0))
|
704
|
+
{
|
705
|
+
f0 = CtoI_Diff(f0, f0.FilterPermit(h1));
|
706
|
+
if(f0 != CtoI(0))
|
707
|
+
{
|
708
|
+
f1 = CtoI_Diff(f1, f1.FilterPermit(h1));
|
709
|
+
f2 = (f0 + f1).FreqPatM(Val);
|
710
|
+
h = CtoI_Union(h, CtoI_Diff(f2, f2.FilterPermit(h1)));
|
711
|
+
}
|
712
|
+
}
|
713
|
+
|
714
|
+
CtoI_CACHE_ENT_RETURN(BC_CtoI_FPM, ax, Val, h);
|
715
|
+
}
|
716
|
+
|
717
|
+
CtoI CtoI::FreqPatC(int Val) const
|
718
|
+
{
|
719
|
+
if(*this == CtoI_Null()) return *this;
|
720
|
+
if(IsConst()) return (GetInt() >= Val)? CtoI(1): CtoI(0);
|
721
|
+
|
722
|
+
int ax = _zbdd.GetID();
|
723
|
+
CtoI_CACHE_CHK_RETURN(BC_CtoI_FPC, ax, Val);
|
724
|
+
|
725
|
+
int top = TopItem();
|
726
|
+
CtoI f1 = Factor1(top);
|
727
|
+
|
728
|
+
CtoI f = f1;
|
729
|
+
int tv = 1 << f.TopDigit();
|
730
|
+
CtoI f2 = f1;
|
731
|
+
if(tv -(tv>>1) < Val)
|
732
|
+
{
|
733
|
+
tv = 0;
|
734
|
+
while(f != CtoI(0))
|
735
|
+
{
|
736
|
+
int d = f.TopDigit();
|
737
|
+
CtoI fd = f.Digit(d);
|
738
|
+
if(d & 1)
|
739
|
+
{
|
740
|
+
tv -= fd.GetZBDD().Card() << d;
|
741
|
+
if(tv >= Val) break;
|
742
|
+
}
|
743
|
+
else
|
744
|
+
{
|
745
|
+
tv += fd.GetZBDD().Card() << d;
|
746
|
+
if((tv>>1) >= Val) break;
|
747
|
+
}
|
748
|
+
f -= fd.ShiftDigit(d);
|
749
|
+
}
|
750
|
+
if(tv < Val) f2 = CtoI(0);
|
751
|
+
}
|
752
|
+
|
753
|
+
CtoI h1 = f2.FreqPatC(Val);
|
754
|
+
CtoI h = h1.AffixVar(top);
|
755
|
+
CtoI f0 = Factor0(top);
|
756
|
+
if(f0 != CtoI(0))
|
757
|
+
{
|
758
|
+
h1 -= h1.FilterPermit(f0);
|
759
|
+
h = CtoI_Union(h, (f0 + f1).FreqPatC(Val).FilterElse(h1));
|
760
|
+
}
|
761
|
+
|
762
|
+
CtoI_CACHE_ENT_RETURN(BC_CtoI_FPC, ax, Val, h);
|
763
|
+
}
|
764
|
+
|
765
|
+
//----------- External functions -----------
|
766
|
+
|
767
|
+
CtoI operator+(const CtoI& a, const CtoI& b)
|
768
|
+
{
|
769
|
+
CtoI c = CtoI_Intsec(a, b);
|
770
|
+
CtoI s = CtoI_Diff(CtoI_Union(a, b), c);
|
771
|
+
if(c == 0) return s;
|
772
|
+
if(s == CtoI_Null()) return s;
|
773
|
+
BDD_RECUR_INC;
|
774
|
+
CtoI h = s - c.ShiftDigit(1);
|
775
|
+
BDD_RECUR_DEC;
|
776
|
+
return h;
|
777
|
+
}
|
778
|
+
|
779
|
+
CtoI operator-(const CtoI& a, const CtoI& b)
|
780
|
+
{
|
781
|
+
CtoI c = CtoI_Diff(b, a);
|
782
|
+
CtoI s = CtoI_Union(CtoI_Diff(a, b), c);
|
783
|
+
if(c == 0) return s;
|
784
|
+
if(s == CtoI_Null()) return s;
|
785
|
+
BDD_RECUR_INC;
|
786
|
+
CtoI h = s + c.ShiftDigit(1);
|
787
|
+
BDD_RECUR_DEC;
|
788
|
+
return h;
|
789
|
+
}
|
790
|
+
|
791
|
+
CtoI operator *(const CtoI& ac, const CtoI& bc)
|
792
|
+
{
|
793
|
+
if(ac == 1) return bc;
|
794
|
+
if(bc == 1) return ac;
|
795
|
+
if(ac == CtoI_Null()) return ac;
|
796
|
+
if(bc == CtoI_Null()) return bc;
|
797
|
+
if(ac == 0) return 0;
|
798
|
+
if(bc == 0) return 0;
|
799
|
+
|
800
|
+
CtoI a = ac; CtoI b = bc;
|
801
|
+
int atop = a.Top(); int btop = b.Top();
|
802
|
+
if(BDD_LevOfVar(atop) < BDD_LevOfVar(btop))
|
803
|
+
{
|
804
|
+
a = bc; b = ac;
|
805
|
+
atop = a.Top(); btop = b.Top();
|
806
|
+
}
|
807
|
+
|
808
|
+
bddword ax = a._zbdd.GetID();
|
809
|
+
bddword bx = b._zbdd.GetID();
|
810
|
+
if(atop == btop && ax < bx)
|
811
|
+
{
|
812
|
+
a = bc; b = ac;
|
813
|
+
ax = a._zbdd.GetID(); bx = b._zbdd.GetID();
|
814
|
+
}
|
815
|
+
|
816
|
+
CtoI_CACHE_CHK_RETURN(BC_CtoI_MULT, ax, bx);
|
817
|
+
|
818
|
+
CtoI a0 = a.Factor0(atop);
|
819
|
+
CtoI a1 = a.Factor1(atop);
|
820
|
+
CtoI c;
|
821
|
+
if(atop != btop)
|
822
|
+
{
|
823
|
+
if(BDD_LevOfVar(atop) <= BDD_TopLev())
|
824
|
+
c = CtoI_Union(a0*b, (a1*b).AffixVar(atop));
|
825
|
+
else c = a0*b + (a1*b).TimesSysVar(atop);
|
826
|
+
}
|
827
|
+
else
|
828
|
+
{
|
829
|
+
CtoI b0 = b.Factor0(atop);
|
830
|
+
CtoI b1 = b.Factor1(atop);
|
831
|
+
if(BDD_LevOfVar(atop) <= BDD_TopLev())
|
832
|
+
c = CtoI_Union(a0*b0, (a1*b0 + a0*b1 + a1*b1).AffixVar(atop));
|
833
|
+
else if(atop > 1)
|
834
|
+
c = a0*b0 + (a1*b0 + a0*b1).TimesSysVar(atop)
|
835
|
+
+ (a1*b1).TimesSysVar(atop - 1);
|
836
|
+
else BDDerr("CtoI::operator*(): SysVar overflow.");
|
837
|
+
}
|
838
|
+
|
839
|
+
CtoI_CACHE_ENT_RETURN(BC_CtoI_MULT, ax, bx, c);
|
840
|
+
}
|
841
|
+
|
842
|
+
CtoI operator /(const CtoI& ac, const CtoI& bc)
|
843
|
+
{
|
844
|
+
if(ac == CtoI_Null()) return ac;
|
845
|
+
if(bc == CtoI_Null()) return bc;
|
846
|
+
if(ac == 0) return 0;
|
847
|
+
if(ac == bc) return 1;
|
848
|
+
if(bc == 0) BDDerr("CtoI::operator/(): Divide by zero.");
|
849
|
+
|
850
|
+
CtoI a = ac; CtoI b = bc;
|
851
|
+
bddword ax = a._zbdd.GetID();
|
852
|
+
bddword bx = b._zbdd.GetID();
|
853
|
+
CtoI_CACHE_CHK_RETURN(BC_CtoI_DIV, ax, bx);
|
854
|
+
|
855
|
+
int v = b.TopItem();
|
856
|
+
CtoI c;
|
857
|
+
if(v == 0)
|
858
|
+
{
|
859
|
+
if(b.TopDigit() & 1) { a = -a; b = -b; }
|
860
|
+
if(b == 1) return a;
|
861
|
+
CtoI p = a.FilterThen(CtoI_GT(a, 0));
|
862
|
+
if(a != p) c = (p / b) - ((p - a)/ b);
|
863
|
+
else
|
864
|
+
{
|
865
|
+
int atd = a.TopDigit();
|
866
|
+
int btd = b.TopDigit();
|
867
|
+
if(atd < btd) return 0;
|
868
|
+
c = a.Digit(atd);
|
869
|
+
if(atd > btd) c = c.ShiftDigit(atd - btd - 2);
|
870
|
+
else
|
871
|
+
{
|
872
|
+
CtoI cond = CtoI_GE(a, c * b);
|
873
|
+
a = a.FilterThen(cond);
|
874
|
+
c = c.FilterThen(cond);
|
875
|
+
}
|
876
|
+
c += (a - c * b)/ b;
|
877
|
+
}
|
878
|
+
}
|
879
|
+
else
|
880
|
+
{
|
881
|
+
CtoI a0 = a.Factor0(v);
|
882
|
+
CtoI a1 = a.Factor1(v);
|
883
|
+
CtoI b0 = b.Factor0(v);
|
884
|
+
CtoI b1 = b.Factor1(v);
|
885
|
+
|
886
|
+
c = a1 / b1;
|
887
|
+
if(c != 0)
|
888
|
+
if(b0 != 0)
|
889
|
+
{
|
890
|
+
CtoI c0 = a0 / b0;
|
891
|
+
c = CtoI_ITE(CtoI_LT(c.Abs(), c0.Abs()), c, c0);
|
892
|
+
}
|
893
|
+
}
|
894
|
+
|
895
|
+
CtoI_CACHE_ENT_RETURN(BC_CtoI_DIV, ax, bx, c);
|
896
|
+
}
|
897
|
+
|
898
|
+
CtoI CtoI_GT(const CtoI& ac, const CtoI& bc)
|
899
|
+
{
|
900
|
+
CtoI a = ac; CtoI b = bc;
|
901
|
+
CtoI open = CtoI_Union(a, b).NonZero();
|
902
|
+
CtoI awin = 0;
|
903
|
+
CtoI bwin = 0;
|
904
|
+
CtoI awin0, bwin0;
|
905
|
+
|
906
|
+
while(open != 0)
|
907
|
+
{
|
908
|
+
int atd = a.TopDigit();
|
909
|
+
int btd = b.TopDigit();
|
910
|
+
int td = (atd > btd)? atd: btd;
|
911
|
+
CtoI aa = a.Digit(td);
|
912
|
+
CtoI bb = b.Digit(td);
|
913
|
+
if(td & 1)
|
914
|
+
{
|
915
|
+
awin0 = CtoI_Diff(bb, aa);
|
916
|
+
bwin0 = CtoI_Diff(aa, bb);
|
917
|
+
}
|
918
|
+
else
|
919
|
+
{
|
920
|
+
awin0 = CtoI_Diff(aa, bb);
|
921
|
+
bwin0 = CtoI_Diff(bb, aa);
|
922
|
+
}
|
923
|
+
awin = CtoI_Union(awin, awin0);
|
924
|
+
open = CtoI_Diff(open, awin0);
|
925
|
+
bwin = CtoI_Union(bwin, bwin0);
|
926
|
+
open = CtoI_Diff(open, bwin0);
|
927
|
+
if(open == CtoI_Null()) return CtoI_Null();
|
928
|
+
if(td == 0) break;
|
929
|
+
a = CtoI_Diff(a, aa.ShiftDigit(td)).FilterThen(open);
|
930
|
+
b = CtoI_Diff(b, bb.ShiftDigit(td)).FilterThen(open);
|
931
|
+
}
|
932
|
+
return awin;
|
933
|
+
}
|
934
|
+
|
935
|
+
CtoI CtoI_GE(const CtoI& ac, const CtoI& bc)
|
936
|
+
{
|
937
|
+
CtoI a = ac; CtoI b = bc;
|
938
|
+
CtoI open = CtoI_Union(a, b).NonZero();
|
939
|
+
CtoI awin = 0;
|
940
|
+
CtoI bwin = 0;
|
941
|
+
CtoI awin0, bwin0;
|
942
|
+
|
943
|
+
while(open != 0)
|
944
|
+
{
|
945
|
+
int atd = a.TopDigit();
|
946
|
+
int btd = b.TopDigit();
|
947
|
+
int td = (atd > btd)? atd: btd;
|
948
|
+
CtoI aa = a.Digit(td);
|
949
|
+
CtoI bb = b.Digit(td);
|
950
|
+
if(td & 1)
|
951
|
+
{
|
952
|
+
awin0 = CtoI_Diff(bb, aa);
|
953
|
+
bwin0 = CtoI_Diff(aa, bb);
|
954
|
+
}
|
955
|
+
else
|
956
|
+
{
|
957
|
+
awin0 = CtoI_Diff(aa, bb);
|
958
|
+
bwin0 = CtoI_Diff(bb, aa);
|
959
|
+
}
|
960
|
+
awin = CtoI_Union(awin, awin0);
|
961
|
+
open = CtoI_Diff(open, awin0);
|
962
|
+
bwin = CtoI_Union(bwin, bwin0);
|
963
|
+
open = CtoI_Diff(open, bwin0);
|
964
|
+
if(open == CtoI_Null()) return CtoI_Null();
|
965
|
+
if(td == 0) break;
|
966
|
+
a = CtoI_Diff(a, aa.ShiftDigit(td)).FilterThen(open);
|
967
|
+
b = CtoI_Diff(b, bb.ShiftDigit(td)).FilterThen(open);
|
968
|
+
}
|
969
|
+
return CtoI_Union(awin, open);
|
970
|
+
}
|
971
|
+
|
972
|
+
static CtoI atoiX(char *, int, int);
|
973
|
+
static CtoI atoiX(char* s, int base, int blk)
|
974
|
+
{
|
975
|
+
int times = 1;
|
976
|
+
for(int i=0; i<blk; i++) times *= base;
|
977
|
+
CtoI shift = times;
|
978
|
+
int p = 0;
|
979
|
+
int len = strlen(s);
|
980
|
+
char *s0 = new char[blk + 1];
|
981
|
+
CtoI a = 0;
|
982
|
+
while(len - p > blk)
|
983
|
+
{
|
984
|
+
a *= shift;
|
985
|
+
strncpy(s0, s+p, blk);
|
986
|
+
a += CtoI((int)strtol(s0, 0, base));
|
987
|
+
p += blk;
|
988
|
+
}
|
989
|
+
if(len > blk)
|
990
|
+
{
|
991
|
+
times = 1;
|
992
|
+
for(int i=p; i<len; i++) times *= base;
|
993
|
+
a *= CtoI(times);
|
994
|
+
}
|
995
|
+
strncpy(s0, s+p, blk);
|
996
|
+
a += CtoI((int)strtol(s0, 0, base));
|
997
|
+
delete[] s0;
|
998
|
+
return a;
|
999
|
+
}
|
1000
|
+
|
1001
|
+
CtoI CtoI_atoi(char* s)
|
1002
|
+
{
|
1003
|
+
if(s[0] == '0')
|
1004
|
+
{
|
1005
|
+
switch(s[1])
|
1006
|
+
{
|
1007
|
+
case 'x':
|
1008
|
+
case 'X':
|
1009
|
+
return atoiX(s+2, 16, 7);
|
1010
|
+
case 'b':
|
1011
|
+
case 'B':
|
1012
|
+
return atoiX(s+2, 2, 30);
|
1013
|
+
default:
|
1014
|
+
;
|
1015
|
+
}
|
1016
|
+
}
|
1017
|
+
return atoiX(s, 10, 7);
|
1018
|
+
}
|
1019
|
+
|
1020
|
+
CtoI CtoI_Meet(const CtoI& ac, const CtoI& bc)
|
1021
|
+
{
|
1022
|
+
if(ac == CtoI_Null()) return ac;
|
1023
|
+
if(bc == CtoI_Null()) return bc;
|
1024
|
+
if(ac == 0) return 0;
|
1025
|
+
if(bc == 0) return 0;
|
1026
|
+
if(ac == 1 && bc == 1) return 1;
|
1027
|
+
|
1028
|
+
CtoI a = ac; CtoI b = bc;
|
1029
|
+
int atop = ac.Top(); int btop = bc.Top();
|
1030
|
+
if(BDD_LevOfVar(atop) < BDD_LevOfVar(btop))
|
1031
|
+
{
|
1032
|
+
a = bc; b = ac;
|
1033
|
+
atop = a.Top(); btop = b.Top();
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
bddword ax = a._zbdd.GetID();
|
1037
|
+
bddword bx = b._zbdd.GetID();
|
1038
|
+
if(atop == btop && ax < bx)
|
1039
|
+
{
|
1040
|
+
a = bc; b = ac;
|
1041
|
+
ax = a._zbdd.GetID(); bx = b._zbdd.GetID();
|
1042
|
+
}
|
1043
|
+
|
1044
|
+
CtoI_CACHE_CHK_RETURN(BC_CtoI_MEET, ax, bx);
|
1045
|
+
|
1046
|
+
CtoI a0 = a.Factor0(atop);
|
1047
|
+
CtoI a1 = a.Factor1(atop);
|
1048
|
+
CtoI c;
|
1049
|
+
if(atop != btop)
|
1050
|
+
{
|
1051
|
+
if(a.IsBool())
|
1052
|
+
c = CtoI_Meet(a0, b) + CtoI_Meet(a1, b);
|
1053
|
+
else c = CtoI_Meet(a0, b) + CtoI_Meet(a1, b).TimesSysVar(atop);
|
1054
|
+
}
|
1055
|
+
else
|
1056
|
+
{
|
1057
|
+
CtoI b0 = b.Factor0(atop);
|
1058
|
+
CtoI b1 = b.Factor1(atop);
|
1059
|
+
if(a.IsBool())
|
1060
|
+
c = CtoI_Union(
|
1061
|
+
CtoI_Meet(a0, b0) + CtoI_Meet(a1, b0) + CtoI_Meet(a0, b1),
|
1062
|
+
CtoI_Meet(a1, b1).AffixVar(atop));
|
1063
|
+
else if(atop > 1)
|
1064
|
+
c = CtoI_Meet(a0, b0)
|
1065
|
+
+ (CtoI_Meet(a1, b0) + CtoI_Meet(a0, b1)).TimesSysVar(atop)
|
1066
|
+
+ CtoI_Meet(a1, b1).TimesSysVar(atop - 1);
|
1067
|
+
else BDDerr("CtoI_Meet(): SysVar overflow.");
|
1068
|
+
}
|
1069
|
+
|
1070
|
+
CtoI_CACHE_ENT_RETURN(BC_CtoI_MEET, ax, bx, c);
|
1071
|
+
}
|
1072
|
+
|