nysol-zdd 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/ext/zdd_so/BDD.cc +495 -0
  3. data/ext/zdd_so/BDD.h +356 -0
  4. data/ext/zdd_so/BDDDG.cc +1818 -0
  5. data/ext/zdd_so/BDDDG.h +107 -0
  6. data/ext/zdd_so/BDDHASH.cc +91 -0
  7. data/ext/zdd_so/BtoI.cc +503 -0
  8. data/ext/zdd_so/BtoI.h +144 -0
  9. data/ext/zdd_so/CtoI.cc +1072 -0
  10. data/ext/zdd_so/CtoI.h +186 -0
  11. data/ext/zdd_so/MLZBDDV.cc +153 -0
  12. data/ext/zdd_so/MLZBDDV.h +42 -0
  13. data/ext/zdd_so/SOP.cc +608 -0
  14. data/ext/zdd_so/SOP.h +199 -0
  15. data/ext/zdd_so/ZBDD.cc +1035 -0
  16. data/ext/zdd_so/ZBDD.h +243 -0
  17. data/ext/zdd_so/ZBDDDG.cc +1834 -0
  18. data/ext/zdd_so/ZBDDDG.h +105 -0
  19. data/ext/zdd_so/ZBDDHASH.cc +91 -0
  20. data/ext/zdd_so/bddc.c +2816 -0
  21. data/ext/zdd_so/bddc.h +132 -0
  22. data/ext/zdd_so/extconf.rb +25 -0
  23. data/ext/zdd_so/include/aheap.c +211 -0
  24. data/ext/zdd_so/include/aheap.h +111 -0
  25. data/ext/zdd_so/include/base.c +93 -0
  26. data/ext/zdd_so/include/base.h +60 -0
  27. data/ext/zdd_so/include/itemset.c +473 -0
  28. data/ext/zdd_so/include/itemset.h +153 -0
  29. data/ext/zdd_so/include/problem.c +371 -0
  30. data/ext/zdd_so/include/problem.h +160 -0
  31. data/ext/zdd_so/include/queue.c +518 -0
  32. data/ext/zdd_so/include/queue.h +177 -0
  33. data/ext/zdd_so/include/sgraph.c +331 -0
  34. data/ext/zdd_so/include/sgraph.h +170 -0
  35. data/ext/zdd_so/include/stdlib2.c +832 -0
  36. data/ext/zdd_so/include/stdlib2.h +746 -0
  37. data/ext/zdd_so/include/trsact.c +723 -0
  38. data/ext/zdd_so/include/trsact.h +167 -0
  39. data/ext/zdd_so/include/vec.c +583 -0
  40. data/ext/zdd_so/include/vec.h +159 -0
  41. data/ext/zdd_so/lcm-vsop.cc +596 -0
  42. data/ext/zdd_so/print.cc +683 -0
  43. data/ext/zdd_so/table.cc +330 -0
  44. data/ext/zdd_so/vsop.h +88 -0
  45. data/ext/zdd_so/zdd_so.cpp +3277 -0
  46. data/lib/nysol/zdd.rb +31 -0
  47. metadata +131 -0
@@ -0,0 +1,330 @@
1
+ // VSOP Tables (v1.36)
2
+ // Shin-ichi MINATO (Dec. 18, 2010)
3
+
4
+ #include <cstring>
5
+ #include <iostream>
6
+ #include "CtoI.h"
7
+ #include "vsop.h"
8
+ using namespace std;
9
+
10
+ struct VarEntry
11
+ {
12
+ int _val;
13
+ int _gvar;
14
+ char* _name;
15
+ int _len;
16
+ int _var;
17
+
18
+ VarEntry(void);
19
+ ~VarEntry(void);
20
+ };
21
+
22
+ VarEntry::VarEntry(void)
23
+ {
24
+ _val = 0;
25
+ _gvar = 0;
26
+ _var = 0;
27
+ _len = 0;
28
+ _name = 0;
29
+ }
30
+
31
+ VarEntry::~VarEntry(void) { if(_len > 0) delete[] _name; }
32
+
33
+ typedef VarEntry* VarEntPtr;
34
+
35
+ VarTable::VarTable(int size)
36
+ {
37
+ if(size <= 0)
38
+ {
39
+ cerr << "Error at VarTable. (a)\n";
40
+ exit(1);
41
+ }
42
+ for(_hashsize=128; _hashsize<size; _hashsize<<=1)
43
+ ; // empty
44
+ _wheel = new VarEntry[_hashsize];
45
+ _index = new VarEntPtr[_hashsize>>1];
46
+ if(_wheel == 0 || _index == 0)
47
+ {
48
+ cerr << "Error at VarTable. (b)\n";
49
+ exit(1);
50
+ }
51
+ for(int i=0; i<(_hashsize>>1); i++) _index[i] = 0;
52
+ _used = 0;
53
+ }
54
+
55
+ VarTable::~VarTable()
56
+ {
57
+ delete[] _wheel;
58
+ delete[] _index;
59
+ }
60
+
61
+ VarEntry* VarTable::GetEntry(char* name)
62
+ {
63
+ if(name == 0)
64
+ {
65
+ cerr << "Error at VarTable. (c)\n";
66
+ exit(1);
67
+ }
68
+ int hash = 0;
69
+ for(int i=0; i<32; i++)
70
+ {
71
+ if(name[i] == 0) break;
72
+ hash = (hash * 123456 + name[i]) & (_hashsize - 1);
73
+ }
74
+ int i = hash;
75
+ while(_wheel[i]._len > 0)
76
+ {
77
+ if(strcmp(name, _wheel[i]._name) == 0)
78
+ return & _wheel[i];
79
+ i++;
80
+ i &= (_hashsize -1);
81
+ }
82
+ i = hash;
83
+ while(_wheel[i]._len > 0)
84
+ {
85
+ if(_wheel[i]._var == 0) break;
86
+ i++;
87
+ i &= (_hashsize -1);
88
+ }
89
+ _wheel[i]._len = strlen(name)+1;
90
+ _wheel[i]._name = new char[_wheel[i]._len];
91
+ strcpy(_wheel[i]._name, name);
92
+ return & _wheel[i];
93
+ }
94
+
95
+ int VarTable::GetID(char* name) { return GetEntry(name) -> _var; }
96
+
97
+ char* VarTable::GetName(int var)
98
+ { return _index[var-BDDV_SysVarTop-1] -> _name; }
99
+
100
+ int VarTable::GetValue(int var)
101
+ { return _index[var-BDDV_SysVarTop-1] -> _val; }
102
+
103
+ int VarTable::GetGID(int var)
104
+ { return _index[var-BDDV_SysVarTop-1] -> _gvar; }
105
+
106
+ void VarTable::SetB(char* name, int val)
107
+ {
108
+ VarEntry* entry = GetEntry(name);
109
+ entry -> _val = val;
110
+ if(entry -> _var == 0)
111
+ {
112
+ entry -> _var = BDD_NewVarOfLev(1);
113
+ entry -> _gvar = entry -> _var;
114
+ _index[_used] = entry;
115
+ if(++_used >= (_hashsize>>1)) Enlarge();
116
+ }
117
+ }
118
+
119
+ void VarTable::SetB(char* name, int val, int gvar)
120
+ {
121
+ VarEntry* entry = GetEntry(name);
122
+ entry -> _val = val;
123
+ entry -> _gvar = gvar;
124
+ if(entry -> _var == 0)
125
+ {
126
+ entry -> _var = BDD_NewVarOfLev(1);
127
+ _index[_used] = entry;
128
+ if(++_used >= (_hashsize>>1)) Enlarge();
129
+ }
130
+ }
131
+
132
+ void VarTable::SetT(char* name, int val)
133
+ {
134
+ VarEntry* entry = GetEntry(name);
135
+ entry -> _val = val;
136
+ if(entry -> _var == 0)
137
+ {
138
+ entry -> _var = BDD_NewVar();
139
+ entry -> _gvar = entry -> _var;
140
+ _index[_used] = entry;
141
+ if(++_used >= (_hashsize>>1)) Enlarge();
142
+ }
143
+ }
144
+
145
+ void VarTable::SetT0(int var, char* name)
146
+ {
147
+ VarEntry* entry = GetEntry(name);
148
+ entry -> _val = 1 << 15;
149
+ if(entry -> _var == 0)
150
+ {
151
+ entry -> _var = var;
152
+ entry -> _gvar = entry -> _var;
153
+ _index[_used] = entry;
154
+ if(++_used >= (_hashsize>>1)) Enlarge();
155
+ }
156
+ }
157
+
158
+ void VarTable::SetT(char* name, int val, int gvar)
159
+ {
160
+ VarEntry* entry = GetEntry(name);
161
+ entry -> _val = val;
162
+ entry -> _gvar = gvar;
163
+ if(entry -> _var == 0)
164
+ {
165
+ entry -> _var = BDD_NewVar();
166
+ _index[_used] = entry;
167
+ if(++_used >= (_hashsize>>1)) Enlarge();
168
+ }
169
+ }
170
+
171
+ int VarTable::Used(void) { return _used; }
172
+
173
+ void VarTable::Enlarge(void)
174
+ {
175
+ int oldsize = _hashsize;
176
+ VarEntry* oldwheel = _wheel;
177
+ VarEntry** oldindex = _index;
178
+
179
+ _hashsize <<= 2;
180
+ _wheel = new VarEntry[_hashsize];
181
+ _index = new VarEntPtr[_hashsize>>1];
182
+ if(_wheel == 0 || _index == 0)
183
+ {
184
+ cerr << "Error at VarTable. (d)\n";
185
+ exit(1);
186
+ }
187
+ for(int i=0; i<(_hashsize>>1); i++) _index[i] = 0;
188
+ _used = 0;
189
+ for(int i=0; i<(oldsize>>1); i++)
190
+ {
191
+ VarEntry* oldentry = oldindex[i];
192
+ if(oldentry)
193
+ {
194
+ _used++;
195
+ VarEntry* entry = GetEntry(oldentry->_name);
196
+ entry -> _val = oldentry -> _val;
197
+ entry -> _gvar = oldentry -> _gvar;
198
+ entry -> _var = oldentry -> _var;
199
+ _index[i] = entry;
200
+ }
201
+ }
202
+ delete[] oldwheel;
203
+ delete[] oldindex;
204
+ }
205
+
206
+ //
207
+ // FuncTable class definition
208
+ //
209
+
210
+ struct FuncEntry
211
+ {
212
+ CtoI _ctoi;
213
+ char* _name;
214
+ short _len;
215
+ char _live;
216
+ char _autoexport;
217
+
218
+ FuncEntry(void);
219
+ ~FuncEntry(void);
220
+ };
221
+
222
+ FuncEntry::FuncEntry(void)
223
+ {
224
+ _ctoi = CtoI_Null();
225
+ _name = 0;
226
+ _len = 0;
227
+ _live = 0;
228
+ _autoexport = -1;
229
+ }
230
+
231
+ FuncEntry::~FuncEntry(void) { if(_len > 0) delete[] _name; }
232
+
233
+ FuncTable::FuncTable(int size)
234
+ {
235
+ if(size <= 0)
236
+ {
237
+ cerr << "Error at FuncTable. (a)\n";
238
+ exit(1);
239
+ }
240
+ for(_hashsize=256; _hashsize<size; _hashsize<<=1)
241
+ ; // empty
242
+ _wheel = new FuncEntry[_hashsize];
243
+ if(_wheel == 0)
244
+ {
245
+ cerr << "Error at FuncTable. (b)\n";
246
+ exit(1);
247
+ }
248
+ _used = 0;
249
+ }
250
+
251
+ FuncTable::~FuncTable() { delete[] _wheel; }
252
+
253
+ FuncEntry* FuncTable::GetEntry(char* name)
254
+ {
255
+ if(name == 0)
256
+ {
257
+ cerr << "Error at FuncTable. (b)\n";
258
+ exit(1);
259
+ }
260
+ int hash = 0;
261
+ for(int i=0; i<32; i++)
262
+ {
263
+ if(name[i] == 0) break;
264
+ hash = (hash * 123456 + name[i]) & (_hashsize - 1);
265
+ }
266
+ int i = hash;
267
+ while(_wheel[i]._len > 0)
268
+ {
269
+ if(strcmp(name, _wheel[i]._name) == 0)
270
+ return & _wheel[i];
271
+ i++;
272
+ i &= (_hashsize -1);
273
+ }
274
+ i = hash;
275
+ while(_wheel[i]._len > 0)
276
+ {
277
+ if(_wheel[i]._live == 0) break;
278
+ i++;
279
+ i &= (_hashsize -1);
280
+ }
281
+ _wheel[i]._len = strlen(name)+1;
282
+ _wheel[i]._name = new char[_wheel[i]._len];
283
+ strcpy(_wheel[i]._name, name);
284
+ return & _wheel[i];
285
+ }
286
+
287
+ CtoI& FuncTable::GetCtoI(char* name) { return GetEntry(name) -> _ctoi; }
288
+ char FuncTable::GetAutoExportID(char* name) { return GetEntry(name) -> _autoexport; }
289
+
290
+ void FuncTable::SetAutoExportID(char *name, char id)
291
+ {
292
+ FuncEntry* entry = GetEntry(name);
293
+ if (entry)
294
+ entry -> _autoexport = id;
295
+ }
296
+
297
+ void FuncTable::Set(char* name, CtoI& ctoi)
298
+ {
299
+ FuncEntry* entry = GetEntry(name);
300
+ entry -> _ctoi = ctoi;
301
+ if(entry -> _live == 0)
302
+ {
303
+ entry -> _live = 1;
304
+ if(++_used >= (_hashsize>>1)) Enlarge();
305
+ }
306
+ }
307
+
308
+ int FuncTable::Used(void) { return _used; }
309
+
310
+ void FuncTable::Enlarge(void)
311
+ {
312
+ int oldsize = _hashsize;
313
+ FuncEntry* oldwheel = _wheel;
314
+
315
+ _hashsize <<= 2;
316
+ _wheel = new FuncEntry[_hashsize];
317
+ if(_wheel == 0)
318
+ {
319
+ cerr << "Error at FuncTable. (b)\n";
320
+ exit(1);
321
+ }
322
+ _used = 0;
323
+ for(int i=0; i<oldsize; i++)
324
+ if(oldwheel[i]._live != 0)
325
+ Set(oldwheel[i]._name, oldwheel[i]._ctoi);
326
+ delete[] oldwheel;
327
+ }
328
+
329
+ VarTable VTable;
330
+ FuncTable FTable;
@@ -0,0 +1,88 @@
1
+ // VSOP - Header (v1.39)
2
+ // Shin-ichi MINATO (Nov. 22, 2013)
3
+ #include <fstream>
4
+ #define PROMPT "vsop> "
5
+ #define DOCUMENT "vsop.help"
6
+
7
+ int yyparse();
8
+
9
+ struct VarEntry;
10
+
11
+ class VarTable
12
+ {
13
+ int _used;
14
+ int _hashsize;
15
+ VarEntry* _wheel;
16
+ VarEntry** _index;
17
+
18
+ void Enlarge(void);
19
+ public:
20
+ VarEntry* GetEntry(char *);
21
+ VarTable(int size = 64);
22
+ ~VarTable(void);
23
+ int GetID(char *);
24
+ char* GetName(int);
25
+ int GetValue(int);
26
+ int GetGID(int);
27
+ void SetB(char *, int);
28
+ void SetB(char *, int, int);
29
+ void SetT(char *, int);
30
+ void SetT0(int, char *);
31
+ void SetT(char *, int, int);
32
+ int Used(void);
33
+ };
34
+
35
+ struct FuncEntry;
36
+ class CtoI;
37
+
38
+ class FuncTable
39
+ {
40
+ int _used;
41
+ int _hashsize;
42
+ FuncEntry* _wheel;
43
+
44
+ void Enlarge(void);
45
+ public:
46
+ FuncEntry* GetEntry(char *);
47
+ FuncTable(int size = 256);
48
+ ~FuncTable(void);
49
+ int CheckNew(char *);
50
+ CtoI& GetCtoI(char *);
51
+ void Set(char *, CtoI &);
52
+ int Used(void);
53
+ char GetAutoExportID(char *);
54
+ void SetAutoExportID(char *, char);
55
+ };
56
+
57
+ class BOut
58
+ {
59
+ short _column;
60
+ std::ostream* _ffp;
61
+ std::ofstream _fp;
62
+ bool _isStdout;
63
+ public:
64
+ BOut(void);
65
+ BOut(char * str);
66
+ ~BOut();
67
+ BOut& operator <<(const char *);
68
+ void Delimit(void);
69
+ void Return(void);
70
+ void Set(char *);
71
+ void Unset(void);
72
+ };
73
+
74
+ extern VarTable VTable;
75
+ extern FuncTable FTable;
76
+ extern BOut bout;
77
+
78
+ extern void yyerror(const char *);
79
+
80
+ extern int PrintCtoI(CtoI);
81
+ extern int PrintCtoI_16(CtoI);
82
+ extern int PrintDigital(CtoI);
83
+ extern int PrintCase(CtoI);
84
+ extern int MapAll(CtoI);
85
+ extern int MapSel(CtoI);
86
+
87
+ extern int PrintDecomp(CtoI);
88
+ extern int PrintDecompDot(CtoI);
@@ -0,0 +1,3277 @@
1
+ //lcmのruby拡張
2
+ #include <ruby.h>
3
+ #include <fstream>
4
+ #include <memory>
5
+ #include <stack>
6
+ //Vsop_Rubyクラス
7
+ #include"CtoI.h"
8
+
9
+ extern int CtoI_Lcm1_ub(char *, char *, int, int, int); // by ham
10
+
11
+ // ruby 1.8.5以下対応
12
+ #ifndef RSTRING_PTR
13
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
14
+ #endif
15
+ #ifndef RARRAY_PTR
16
+ #define RARRAY_PTR(s) (RARRAY(s)->ptr)
17
+ #endif
18
+
19
+ CtoI* string2ctoi(char *str);
20
+ CtoI* int2ctoi(int val);
21
+ CtoI *value2ctoi(VALUE v);
22
+
23
+ //------------------------------------------------------------------------------
24
+ // 配列型に拡張したauto_ptr
25
+ //------------------------------------------------------------------------------
26
+ template<class T>
27
+ class kgAutoPtr2
28
+ {
29
+ T* _ptr;
30
+ public:
31
+ kgAutoPtr2(T* ptr=0) : _ptr(ptr) {};
32
+ virtual ~kgAutoPtr2(void) { if(_ptr != NULL) delete[] _ptr; }
33
+ T* get(void) const throw() { return _ptr; }
34
+ void set(T* ptr) throw() { if(_ptr!=NULL) delete[] _ptr; _ptr=ptr; }
35
+ void clear(void) { if(_ptr!=NULL) delete[] _ptr; _ptr=0;}
36
+ };
37
+
38
+ class Vsop_Ruby
39
+ {
40
+ public:
41
+ CtoI *cmod;
42
+ ~Vsop_Ruby(void){
43
+ if(cmod!=0) delete cmod;
44
+ }
45
+ };
46
+
47
+ void free_rmod(Vsop_Ruby* rmod){
48
+ if(rmod!=0){
49
+ delete rmod;
50
+ }
51
+ }
52
+
53
+ //初期化カウント
54
+ int init_cnt=0;
55
+ //ノード数
56
+ #define DEF_ENV_NMAX 40000000
57
+ #define MAX_LEN 409600
58
+ #define HASH_MAX 4096000
59
+
60
+ int env_nmax=0;
61
+ bool env_warning = false;
62
+
63
+ // VSOP Parser(Yacc) (v1.41)
64
+ // Shin-ichi MINATO (Dec. 15, 2015)
65
+
66
+ #define YYMAXDEPTH 1000
67
+ #include <cstdio>
68
+ #include <cstring>
69
+ #include <iostream>
70
+ #include <vector>
71
+ #include <string>
72
+ #include "CtoI.h"
73
+ #include "ZBDDDG.h"
74
+ #include "vsop.h"
75
+
76
+ #ifdef B_64
77
+ # define B_STRTOI strtoll
78
+ # define B_ITOSTR(n, s) sprintf(s, "%lld", n)
79
+ #else
80
+ # define B_STRTOI strtol
81
+ # define B_ITOSTR(n, s) sprintf(s, "%d", n)
82
+ #endif
83
+
84
+ using namespace std;
85
+
86
+ extern int yylineno;
87
+ extern char* yytext;
88
+ extern FILE* yyin;
89
+ extern int yywrap();
90
+ extern int yylex();
91
+
92
+ extern "C"
93
+ {
94
+ extern int system(const char*);
95
+ extern int isatty(int);
96
+ extern void bddfree(bddword);
97
+ }
98
+
99
+ void yyerror(const char* s)
100
+ {
101
+ cerr << s << " in line " << yylineno << ".\n";
102
+ cerr.flush();
103
+ }
104
+
105
+ int yywrap() { return(1); }
106
+
107
+ #define NDEF 1000000
108
+
109
+ int VarOrdTop;
110
+
111
+
112
+ struct OV
113
+ {
114
+ char _ovf;
115
+
116
+ OV(void) { _ovf = 0; }
117
+ void Set(void) { _ovf = 1; }
118
+ char Check(void)
119
+ {
120
+ char a = _ovf;
121
+ _ovf = 0;
122
+ return a;
123
+ }
124
+ } OVF;
125
+
126
+ static const int power16 = 1 << 16;
127
+ static const char BC_VSOP_VALUE = 50;
128
+ static const char BC_VSOP_DENSITY = 51;
129
+ static const char BC_VSOP_MAXCOST = 52;
130
+ static const char BC_VSOP_MINCOST = 53;
131
+ static const char BC_VSOP_PRODUCT = 54;
132
+
133
+ static CtoI Product(CtoI, CtoI);
134
+ CtoI Product(CtoI ac, CtoI bc)
135
+ {
136
+ if(ac == 1) return bc;
137
+ if(bc == 1) return ac;
138
+ if(ac == CtoI_Null()) return ac;
139
+ if(bc == CtoI_Null()) return bc;
140
+ if(ac == 0) return 0;
141
+ if(bc == 0) return 0;
142
+
143
+ CtoI a = ac; CtoI b = bc;
144
+ int atop = a.Top();
145
+ int btop = b.Top();
146
+ if(BDD_LevOfVar(atop) < BDD_LevOfVar(btop))
147
+ {
148
+ a = bc; b = ac;
149
+ atop = a.Top(); btop = b.Top();
150
+ }
151
+
152
+ bddword ax = a.GetZBDD().GetID();
153
+ bddword bx = b.GetZBDD().GetID();
154
+ if(atop == btop && ax < bx)
155
+ {
156
+ a = bc; b = ac;
157
+ ax = a.GetZBDD().GetID();
158
+ bx = b.GetZBDD().GetID();
159
+ }
160
+
161
+ ZBDD z = BDD_CacheZBDD(BC_VSOP_PRODUCT, ax, bx);
162
+ if(z != -1) return CtoI(z);
163
+ BDD_RECUR_INC;
164
+
165
+ CtoI a0 = a.Factor0(atop);
166
+ CtoI a1 = a.Factor1(atop);
167
+ CtoI c;
168
+ if(atop != btop)
169
+ {
170
+ if(atop > BDDV_SysVarTop)
171
+ {
172
+ int azvar = VTable.GetGID(atop);
173
+ CtoI bz = b;
174
+ int bztop = bz.Top();
175
+ while(BDD_LevOfVar(azvar) <= BDD_LevOfVar(bztop))
176
+ {
177
+ bz = bz.Factor0(bztop);
178
+ bztop = bz.Top();
179
+ }
180
+ c = CtoI_Union(Product(a0, b), Product(a1, bz).AffixVar(atop));
181
+ }
182
+ else c = Product(a0, b) + Product(a1, b).TimesSysVar(atop);
183
+ }
184
+ else
185
+ {
186
+ CtoI b0 = b.Factor0(atop);
187
+ CtoI b1 = b.Factor1(atop);
188
+ if(atop > BDDV_SysVarTop)
189
+ {
190
+ int azvar = VTable.GetGID(atop);
191
+ CtoI az = a;
192
+ int aztop = az.Top();
193
+ while(BDD_LevOfVar(azvar) <= BDD_LevOfVar(aztop))
194
+ {
195
+ az = az.Factor0(aztop);
196
+ aztop = az.Top();
197
+ }
198
+ CtoI bz = b;
199
+ int bztop = bz.Top();
200
+ while(BDD_LevOfVar(azvar) <= BDD_LevOfVar(bztop))
201
+ {
202
+ bz = bz.Factor0(bztop);
203
+ bztop = bz.Top();
204
+ }
205
+ c = CtoI_Union(Product(a0, b0),
206
+ (Product(a1,bz)+Product(az,b1)+Product(a1,b1)).AffixVar(atop));
207
+ }
208
+ else if(atop > 1)
209
+ c = Product(a0,b0) + (Product(a1,b0)+Product(a0,b1)).TimesSysVar(atop)
210
+ + Product(a1,b1).TimesSysVar(atop - 1);
211
+ else BDDerr("CtoI::operator*(): SysVar overflow.");
212
+ }
213
+
214
+ BDD_RECUR_DEC;
215
+ BDD_CacheEnt(BC_VSOP_PRODUCT, ax, bx, c.GetZBDD().GetID());
216
+ return c;
217
+ }
218
+
219
+ static int Value(CtoI);
220
+ int Value(CtoI a)
221
+ {
222
+ if(a == CtoI()) return 0;
223
+ if(a == 0) return 0;
224
+ if(a == 1) return power16;
225
+
226
+ int val = BDD_CacheInt(BC_VSOP_VALUE, a.GetZBDD().GetID(), 0);
227
+ if(val <= BDD_MaxNode) return val;
228
+ BDD_RECUR_INC;
229
+
230
+ int var = a.Top();
231
+ float f;
232
+ if(var > BDDV_SysVarTop)
233
+ f = (float)VTable.GetValue(var) / power16;
234
+ else
235
+ {
236
+ f = -2;
237
+ for(int i=0; i<(BDDV_SysVarTop-var); i++) f *= f;
238
+ }
239
+ int val1 = Value(a.Factor1(var));
240
+ val = (int)(f * val1);
241
+ if(val)
242
+ {
243
+ if((val1<0)^(f<0)^(val<0)) OVF.Set();
244
+ }
245
+ else if((f!=0) && val1) OVF.Set();
246
+ int val0 = Value(a.Factor0(var));
247
+ val1 = val;
248
+ val += val0;
249
+ if(val1>0 && val0>0 && val<0) OVF.Set();
250
+ if(val1<0 && val0<0 && val>0) OVF.Set();
251
+
252
+ BDD_RECUR_DEC;
253
+ BDD_CacheEnt(BC_VSOP_VALUE, a.GetZBDD().GetID(), 0, val);
254
+ return val;
255
+ }
256
+
257
+ static const int power30 = 1 << 30;
258
+
259
+ static int Density(ZBDD, int);
260
+ int Density(ZBDD f, int tlev)
261
+ {
262
+ if(f == -1) return 0;
263
+ if(f == 0) return 0;
264
+
265
+ int var = f.Top();
266
+ int lev = BDD_LevOfVar(var);
267
+ int c;
268
+ if(f == 1) c = power30;
269
+ else
270
+ {
271
+ c = BDD_CacheInt(BC_VSOP_DENSITY, f.GetID(), 0);
272
+ if(c > BDD_MaxNode)
273
+ {
274
+ BDD_RECUR_INC;
275
+ c = (Density(f.OffSet(var), lev-1) >> 1)
276
+ + (Density(f.OnSet0(var), lev-1) >> 1);
277
+ BDD_RECUR_DEC;
278
+ BDD_CacheEnt(BC_VSOP_DENSITY, f.GetID(), 0, c);
279
+ }
280
+ }
281
+ for(int i=1; i<=tlev-lev; i++) c >>= 1;
282
+ return c;
283
+ }
284
+
285
+ static int MaxCost(ZBDD);
286
+ int MaxCost(ZBDD f)
287
+ {
288
+ if(f == -1) return 0;
289
+ if(f == 0) return -power30;
290
+ if(f == 1) return 0;
291
+
292
+ int c = BDD_CacheInt(BC_VSOP_MAXCOST, f.GetID(), 0);
293
+ if(c <= BDD_MaxNode) return c;
294
+ BDD_RECUR_INC;
295
+
296
+ int var = f.Top();
297
+ int c0 = MaxCost(f.OffSet(var));
298
+ int c1 = MaxCost(f.OnSet0(var)) + VTable.GetValue(var);
299
+ c = (c0 > c1)? c0: c1;
300
+
301
+ BDD_RECUR_DEC;
302
+ BDD_CacheEnt(BC_VSOP_MAXCOST, f.GetID(), 0, c);
303
+ return c;
304
+ }
305
+
306
+ static int MinCost(ZBDD);
307
+ int MinCost(ZBDD f)
308
+ {
309
+ if(f == -1) return 0;
310
+ if(f == 0) return power30;
311
+ if(f == 1) return 0;
312
+
313
+ int c = BDD_CacheInt(BC_VSOP_MINCOST, f.GetID(), 0);
314
+ if(c <= BDD_MaxNode) return c;
315
+ BDD_RECUR_INC;
316
+
317
+ int var = f.Top();
318
+ int c0 = MinCost(f.OffSet(var));
319
+ int c1 = MinCost(f.OnSet0(var)) + VTable.GetValue(var);
320
+ c = (c0 > c1)? c1: c0;
321
+
322
+ BDD_RECUR_DEC;
323
+ BDD_CacheEnt(BC_VSOP_MINCOST, f.GetID(), 0, c);
324
+ return c;
325
+ }
326
+
327
+ int CurGID;
328
+ char AutoExportID = 0;
329
+ std::vector<std::string> AutoExportPaths;
330
+
331
+
332
+ /*##vsop_maxval##*/
333
+ VALUE vsop_maxval(VALUE self){
334
+ Vsop_Ruby* rmod;
335
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
336
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
337
+ CtoI *ctoi_fin;
338
+ *ctoi_moda = ctoi_moda -> MaxVal();
339
+ ctoi_fin = ctoi_moda;
340
+
341
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
342
+ rmod_rtn->cmod = ctoi_fin;
343
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
344
+ }
345
+
346
+ /*##vsop_minval##*/
347
+ VALUE vsop_minval(VALUE self){
348
+ Vsop_Ruby* rmod;
349
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
350
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
351
+ CtoI *ctoi_fin;
352
+ *ctoi_moda = ctoi_moda -> MinVal();
353
+ ctoi_fin = ctoi_moda;
354
+
355
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
356
+ rmod_rtn->cmod = ctoi_fin;
357
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
358
+ }
359
+
360
+ /*##vsop_totalval##*/
361
+ VALUE vsop_totalval(VALUE self){
362
+ Vsop_Ruby* rmod;
363
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
364
+
365
+ CtoI a = rmod->cmod->TotalVal();
366
+ if(a.IsConst())
367
+ {
368
+ if(a.TopItem() > 0) a = a.MaxVal();
369
+ int d = a.TopDigit() / 3 + 14;
370
+ kgAutoPtr2<char> a_ptr;
371
+ char *s;
372
+ try{
373
+ a_ptr.set(new char[d]);
374
+ s = a_ptr.get();
375
+ }catch(...){
376
+ rb_raise(rb_eRuntimeError,"memory allocation error");
377
+ }
378
+ int err = a.StrNum10(s);
379
+ if (err) { rb_raise(rb_eRuntimeError,"StrNum10 error"); }
380
+ return rb_cstr2inum(s,10);
381
+ }
382
+ return 0;
383
+ }
384
+
385
+ /*##vsop_restrict##*/
386
+ VALUE vsop_restrict(int argc, VALUE *argv, VALUE self){
387
+ Vsop_Ruby* rmod;
388
+ VALUE v;
389
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
390
+ rb_scan_args(argc, argv,"10",&v);
391
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
392
+ CtoI *ctoi_modd = value2ctoi(v);
393
+ CtoI *ctoi_fin;
394
+ *ctoi_moda = ctoi_moda -> FilterRestrict(*ctoi_modd);
395
+ ctoi_fin = ctoi_moda;
396
+ delete ctoi_modd;
397
+
398
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
399
+ rmod_rtn->cmod = ctoi_fin;
400
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
401
+ }
402
+
403
+ /*##vsop_permit##*/
404
+ VALUE vsop_permit(int argc, VALUE *argv, VALUE self){
405
+ Vsop_Ruby* rmod;
406
+ VALUE v;
407
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
408
+ rb_scan_args(argc, argv,"10",&v);
409
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
410
+ CtoI *ctoi_modd = value2ctoi(v);
411
+ CtoI *ctoi_fin;
412
+ *ctoi_moda = ctoi_moda -> FilterPermit(*ctoi_modd);
413
+ ctoi_fin = ctoi_moda;
414
+ delete ctoi_modd;
415
+
416
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
417
+ rmod_rtn->cmod = ctoi_fin;
418
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
419
+ }
420
+
421
+ /*##vsop_permitsym##*/
422
+ VALUE vsop_permitsym(int argc, VALUE *argv, VALUE self){
423
+ Vsop_Ruby* rmod;
424
+ VALUE v;
425
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
426
+ rb_scan_args(argc, argv,"10",&v);
427
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
428
+ CtoI *ctoi_modd = value2ctoi(v);
429
+ CtoI *ctoi_fin;
430
+ *ctoi_moda = ctoi_moda -> FilterPermitSym(ctoi_modd->GetInt());
431
+ ctoi_fin = ctoi_moda;
432
+ delete ctoi_modd;
433
+
434
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
435
+ rmod_rtn->cmod = ctoi_fin;
436
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
437
+ }
438
+
439
+ /*##vsop_items##*/
440
+ VALUE vsop_items(VALUE self){
441
+ Vsop_Ruby* rmod;
442
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
443
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
444
+ CtoI *ctoi_fin;
445
+ *ctoi_moda = ctoi_moda -> TotalValItems();
446
+ ctoi_fin = ctoi_moda;
447
+
448
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
449
+ rmod_rtn->cmod = ctoi_fin;
450
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
451
+ }
452
+
453
+ /*##vsop_termsEQ##*/
454
+ VALUE vsop_termsEQ(int argc, VALUE *argv, VALUE self){
455
+ Vsop_Ruby* rmod;
456
+ VALUE v;
457
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
458
+ rb_scan_args(argc, argv,"10",&v);
459
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
460
+ CtoI *ctoi_modd = value2ctoi(v);
461
+ CtoI *ctoi_fin;
462
+ *ctoi_moda = ctoi_moda -> FilterThen(ctoi_moda -> EQ_Const(ctoi_modd->GetInt()));
463
+ ctoi_fin = ctoi_moda;
464
+ delete ctoi_modd;
465
+
466
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
467
+ rmod_rtn->cmod = ctoi_fin;
468
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
469
+ }
470
+
471
+ /*##vsop_termsNE##*/
472
+ VALUE vsop_termsNE(int argc, VALUE *argv, VALUE self){
473
+ Vsop_Ruby* rmod;
474
+ VALUE v;
475
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
476
+ rb_scan_args(argc, argv,"10",&v);
477
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
478
+ CtoI *ctoi_modd = value2ctoi(v);
479
+ CtoI *ctoi_fin;
480
+ *ctoi_moda = ctoi_moda -> FilterThen(ctoi_moda -> NE_Const(ctoi_modd->GetInt()));
481
+ ctoi_fin = ctoi_moda;
482
+ delete ctoi_modd;
483
+
484
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
485
+ rmod_rtn->cmod = ctoi_fin;
486
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
487
+ }
488
+
489
+ /*##vsop_termsGT##*/
490
+ VALUE vsop_termsGT(int argc, VALUE *argv, VALUE self){
491
+ Vsop_Ruby* rmod;
492
+ VALUE v;
493
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
494
+ rb_scan_args(argc, argv,"10",&v);
495
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
496
+ CtoI *ctoi_modd = value2ctoi(v);
497
+ CtoI *ctoi_fin;
498
+ *ctoi_moda = ctoi_moda -> FilterThen(ctoi_moda -> GT_Const(ctoi_modd->GetInt()));
499
+ ctoi_fin = ctoi_moda;
500
+ delete ctoi_modd;
501
+
502
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
503
+ rmod_rtn->cmod = ctoi_fin;
504
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
505
+ }
506
+
507
+ /*##vsop_termsGE##*/
508
+ VALUE vsop_termsGE(int argc, VALUE *argv, VALUE self){
509
+ Vsop_Ruby* rmod;
510
+ VALUE v;
511
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
512
+ rb_scan_args(argc, argv,"10",&v);
513
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
514
+ CtoI *ctoi_modd = value2ctoi(v);
515
+ CtoI *ctoi_fin;
516
+ *ctoi_moda = ctoi_moda -> FilterThen(ctoi_moda -> GE_Const(ctoi_modd->GetInt()));
517
+ ctoi_fin = ctoi_moda;
518
+ delete ctoi_modd;
519
+
520
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
521
+ rmod_rtn->cmod = ctoi_fin;
522
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
523
+ }
524
+
525
+ /*##vsop_termsLT##*/
526
+ VALUE vsop_termsLT(int argc, VALUE *argv, VALUE self){
527
+ Vsop_Ruby* rmod;
528
+ VALUE v;
529
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
530
+ rb_scan_args(argc, argv,"10",&v);
531
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
532
+ CtoI *ctoi_modd = value2ctoi(v);
533
+ CtoI *ctoi_fin;
534
+ *ctoi_moda = ctoi_moda -> FilterThen(ctoi_moda -> LT_Const(ctoi_modd->GetInt()));
535
+ ctoi_fin = ctoi_moda;
536
+ delete ctoi_modd;
537
+
538
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
539
+ rmod_rtn->cmod = ctoi_fin;
540
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
541
+ }
542
+
543
+ /*##vsop_termsLE##*/
544
+ VALUE vsop_termsLE(int argc, VALUE *argv, VALUE self){
545
+ Vsop_Ruby* rmod;
546
+ VALUE v;
547
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
548
+ rb_scan_args(argc, argv,"10",&v);
549
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
550
+ CtoI *ctoi_modd = value2ctoi(v);
551
+ CtoI *ctoi_fin;
552
+ *ctoi_moda = ctoi_moda -> FilterThen(ctoi_moda -> LE_Const(ctoi_modd->GetInt()));
553
+ ctoi_fin = ctoi_moda;
554
+ delete ctoi_modd;
555
+
556
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
557
+ rmod_rtn->cmod = ctoi_fin;
558
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
559
+ }
560
+
561
+ /*##vsop_freqpatA##*/
562
+ VALUE vsop_freqpatA(int argc, VALUE *argv, VALUE self){
563
+ Vsop_Ruby* rmod;
564
+ VALUE v;
565
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
566
+ rb_scan_args(argc, argv,"10",&v);
567
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
568
+ CtoI *ctoi_modd = value2ctoi(v);
569
+ CtoI *ctoi_fin;
570
+ *ctoi_moda = ctoi_moda -> FreqPatA(ctoi_modd->GetInt() );
571
+ //*ctoi_moda = ctoi_moda -> ReduceItems(ctoi_moda->TotalValItems().GE_Const(*ctoi_modd)).FreqPatA(ctoi_modd->GetInt());
572
+ ctoi_fin = ctoi_moda;
573
+ delete ctoi_modd;
574
+
575
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
576
+ rmod_rtn->cmod = ctoi_fin;
577
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
578
+ }
579
+
580
+ /*##vsop_freqpatM##*/
581
+ VALUE vsop_freqpatM(int argc, VALUE *argv, VALUE self){
582
+ Vsop_Ruby* rmod;
583
+ VALUE v;
584
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
585
+ rb_scan_args(argc, argv,"10",&v);
586
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
587
+ CtoI *ctoi_modd = value2ctoi(v);
588
+ CtoI *ctoi_fin;
589
+ *ctoi_moda = ctoi_moda -> FreqPatM(ctoi_modd->GetInt() );
590
+ ctoi_fin = ctoi_moda;
591
+ delete ctoi_modd;
592
+
593
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
594
+ rmod_rtn->cmod = ctoi_fin;
595
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
596
+ }
597
+
598
+ /*##vsop_freqpatC##*/
599
+ VALUE vsop_freqpatC(int argc, VALUE *argv, VALUE self){
600
+ Vsop_Ruby* rmod;
601
+ VALUE v;
602
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
603
+ rb_scan_args(argc, argv,"10",&v);
604
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
605
+ CtoI *ctoi_modd = value2ctoi(v);
606
+ CtoI *ctoi_fin;
607
+ *ctoi_moda = ctoi_moda -> FreqPatC(ctoi_modd->GetInt() );
608
+ ctoi_fin = ctoi_moda;
609
+ delete ctoi_modd;
610
+
611
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
612
+ rmod_rtn->cmod = ctoi_fin;
613
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
614
+ }
615
+
616
+ /*##vsop_symgrp##*/
617
+ VALUE vsop_symgrp(VALUE self){
618
+ Vsop_Ruby* rmod;
619
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
620
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
621
+ CtoI *ctoi_fin;
622
+ *ctoi_moda = ctoi_moda -> NonZero().GetZBDD().SymGrp();
623
+ ctoi_fin = ctoi_moda;
624
+
625
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
626
+ rmod_rtn->cmod = ctoi_fin;
627
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
628
+ }
629
+
630
+ /*##vsop_import##*/
631
+ VALUE vsop_import(int argc, VALUE *argv, VALUE self){
632
+ VALUE v;
633
+ CtoI *ctoi_fin;
634
+ /*
635
+ VALUE vz = rb_cv_get(self,"@@init_cnt");
636
+ int init_cnt_v = NUM2INT(vz);
637
+ if(init_cnt_v==0){ BDDV_Init(256, env_nmax);}
638
+ init_cnt_v++;
639
+ rb_cv_set(self,"@@init_cnt",INT2NUM(init_cnt_v));
640
+ */
641
+ if(init_cnt==0){ BDDV_Init(256, env_nmax);}
642
+ init_cnt++;
643
+
644
+ rb_scan_args(argc, argv,"10",&v);
645
+ if(TYPE(v)!=T_STRING){
646
+ rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
647
+ }
648
+ char *argtmp = RSTRING_PTR(v);
649
+ int len;
650
+ len = strlen(argtmp);
651
+ char *str_c = new char[len+3];
652
+ sprintf(str_c,"\"%s\"",argtmp);
653
+ int len_c = len+2;
654
+ str_c[len_c - 1] = 0;
655
+ FILE *fp;
656
+ fp = fopen(str_c+1, "r");
657
+ if(fp == NULL)
658
+ {
659
+ yyerror("Can't open the file");
660
+ ctoi_fin = new CtoI(0);
661
+ }
662
+ else
663
+ {
664
+ ZBDDV v = ZBDDV_Import(fp);
665
+ fclose(fp);
666
+ if(v != ZBDDV(-1))
667
+ {
668
+ int t = 1;
669
+ char s[32];
670
+ while(BDD_LevOfVar(v.Top()) > VTable.Used())
671
+ {
672
+ sprintf(s, "x%d", t);
673
+ while(VTable.GetID(s) != 0)
674
+ {
675
+ t++;
676
+ sprintf(s, "x%d", t);
677
+ }
678
+ VTable.SetT0(BDD_VarOfLev(t), s);
679
+ }
680
+ int len = v.Last()+1;
681
+ CtoI a = CtoI(0);
682
+ for(int i=0; i<len; i++)
683
+ a += CtoI(v.GetZBDD(i)).ShiftDigit(i);
684
+ ctoi_fin = new CtoI(a);
685
+ }
686
+ else
687
+ {
688
+ yyerror("<WARNING> import error");
689
+ ctoi_fin = new CtoI(0);
690
+ }
691
+ }
692
+ delete[] str_c;
693
+
694
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
695
+ rmod_rtn->cmod = ctoi_fin;
696
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
697
+ }
698
+
699
+ VALUE vsop_lcm_nomal(int argc, VALUE *argv, VALUE self){
700
+ if(init_cnt==0){ BDDV_Init(256, env_nmax);}
701
+ init_cnt++;
702
+
703
+ VALUE v1,v2,v3;
704
+ CtoI *ctoi_fin;
705
+ rb_scan_args(argc, argv,"30",&v1,&v2,&v3);
706
+ if(TYPE(v1)!=T_STRING){
707
+ rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
708
+ }
709
+ if(TYPE(v2)!=T_STRING){
710
+ rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
711
+ }
712
+ if(TYPE(v3)!=T_FIXNUM){
713
+ rb_raise(rb_eRuntimeError,"argument type error (3rd argument must be FIXNUM)");
714
+ }
715
+ char *arg1 = RSTRING_PTR(v1);
716
+ char *arg2 = RSTRING_PTR(v2);
717
+ int arg3_fix = FIX2INT(v3);
718
+
719
+ int len;
720
+
721
+ len = strlen(arg1);
722
+ char *str_c = new char[len+3];
723
+ sprintf(str_c,"\"%s\"",arg1);
724
+ int len_c = len+2;
725
+
726
+ len = strlen(arg2);
727
+ char *str_d = new char[len+3];
728
+ sprintf(str_d,"\"%s\"",arg2);
729
+ int len_d = len+2;
730
+
731
+ char *str_e = new char[64];
732
+ sprintf(str_e,"%d",arg3_fix);
733
+ str_c[len_c - 1] = 0;
734
+ str_d[len_d - 1] = 0;
735
+ int th = atoi(str_e);
736
+ if(strcmp(str_c+1, "F") == 0) CtoI_Lcm1(str_d+1, 0, th, 0);
737
+ else if(strcmp(str_c+1, "C") == 0) CtoI_Lcm1(str_d+1, 0, th, 1);
738
+ else if(strcmp(str_c+1, "M") == 0) CtoI_Lcm1(str_d+1, 0, th, 2);
739
+ else if(strcmp(str_c+1, "FQ") == 0) CtoI_Lcm1(str_d+1, 0, th, 10);
740
+ else if(strcmp(str_c+1, "CQ") == 0) CtoI_Lcm1(str_d+1, 0, th, 11);
741
+ else if(strcmp(str_c+1, "MQ") == 0) CtoI_Lcm1(str_d+1, 0, th, 12);
742
+ for(int i=VTable.Used(); i<CtoI_LcmItems(); i++)
743
+ {
744
+ char s[32];
745
+ int x = CtoI_LcmPerm(i);
746
+ sprintf(s, "x%d", i+1);
747
+ VTable.SetT(s, power16/2);
748
+ }
749
+ CtoI a = CtoI_Lcm2();
750
+ ctoi_fin = new CtoI(a);
751
+ delete[] str_c;
752
+ delete[] str_d;
753
+ delete[] str_e;
754
+
755
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
756
+ rmod_rtn->cmod = ctoi_fin;
757
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
758
+ }
759
+
760
+ VALUE vsop_lcm_order(int argc, VALUE *argv, VALUE self){
761
+ if(init_cnt==0){ BDDV_Init(256, env_nmax);}
762
+ init_cnt++;
763
+
764
+ VALUE v1,v2,v3,v4;
765
+ CtoI *ctoi_fin;
766
+ rb_scan_args(argc, argv,"40",&v1,&v2,&v3,&v4);
767
+ if(TYPE(v1)!=T_STRING){
768
+ rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
769
+ }
770
+ if(TYPE(v2)!=T_STRING){
771
+ rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
772
+ }
773
+ if(TYPE(v3)!=T_FIXNUM){
774
+ rb_raise(rb_eRuntimeError,"argument type error (3rd argument must be FIXNUM)");
775
+ }
776
+ if(TYPE(v4)!=T_STRING){
777
+ rb_raise(rb_eRuntimeError,"argument type error (4th argument must be STRING)");
778
+ }
779
+ char *arg1 = RSTRING_PTR(v1);
780
+ char *arg2 = RSTRING_PTR(v2);
781
+ int arg3_fix = FIX2INT(v3);
782
+ char *arg4 = RSTRING_PTR(v4);
783
+
784
+ int len;
785
+
786
+ len = strlen(arg1);
787
+ char *str_c = new char[len+3];
788
+ sprintf(str_c,"\"%s\"",arg1);
789
+ int len_c = len+2;
790
+
791
+ len = strlen(arg2);
792
+ char *str_d = new char[len+3];
793
+ sprintf(str_d,"\"%s\"",arg2);
794
+ int len_d = len+2;
795
+
796
+ char *str_e = new char[64];
797
+ sprintf(str_e,"%d",arg3_fix);
798
+
799
+ len = strlen(arg4);
800
+ char *str_f = new char[len+3];
801
+ sprintf(str_f,"\"%s\"",arg4);
802
+ int len_f = len+2;
803
+
804
+ str_c[len_c - 1] = 0;
805
+ str_d[len_d - 1] = 0;
806
+ int th = atoi(str_e);
807
+ str_f[len_f - 1] = 0;
808
+ if(strcmp(str_c+1, "F") == 0) CtoI_Lcm1(str_d+1, str_f+1, th, 0);
809
+ else if(strcmp(str_c+1, "C") == 0) CtoI_Lcm1(str_d+1, str_f+1, th, 1);
810
+ else if(strcmp(str_c+1, "M") == 0) CtoI_Lcm1(str_d+1, str_f+1, th, 2);
811
+ else if(strcmp(str_c+1, "FQ") == 0) CtoI_Lcm1(str_d+1, str_f+1, th, 10);
812
+ else if(strcmp(str_c+1, "CQ") == 0) CtoI_Lcm1(str_d+1, str_f+1, th, 11);
813
+ else if(strcmp(str_c+1, "MQ") == 0) CtoI_Lcm1(str_d+1, str_f+1, th, 12);
814
+ for(int i=VTable.Used(); i<CtoI_LcmItems(); i++)
815
+ {
816
+ char s[32];
817
+ int x = CtoI_LcmPerm(i);
818
+ sprintf(s, "x%d", i+1);
819
+ VTable.SetT(s, power16/2);
820
+ }
821
+ CtoI a = CtoI_Lcm2();
822
+ ctoi_fin = new CtoI(a);
823
+ delete[] str_c;
824
+ delete[] str_d;
825
+ delete[] str_e;
826
+ delete[] str_f;
827
+
828
+
829
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
830
+ rmod_rtn->cmod = ctoi_fin;
831
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
832
+ }
833
+
834
+ /*##vsop_minus_op##*/
835
+ VALUE vsop_minus_op(VALUE self){
836
+ Vsop_Ruby* rmod;
837
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
838
+ CtoI *ctoi_modb =new CtoI(*rmod->cmod);
839
+ CtoI *ctoi_fin;
840
+ *ctoi_modb = - *ctoi_modb;
841
+ ctoi_fin = ctoi_modb;
842
+
843
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
844
+ rmod_rtn->cmod = ctoi_fin;
845
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
846
+ }
847
+
848
+ /*##vsop_plus_op##*/
849
+ VALUE vsop_plus_op(VALUE self){
850
+ Vsop_Ruby* rmod;
851
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
852
+ CtoI *ctoi_modb =new CtoI(*rmod->cmod);
853
+ CtoI *ctoi_fin;
854
+ ctoi_fin = ctoi_modb;
855
+
856
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
857
+ rmod_rtn->cmod = ctoi_fin;
858
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
859
+ }
860
+
861
+ /*##vsop_plus##*/
862
+ VALUE vsop_plus(int argc, VALUE *argv,VALUE self){
863
+ Vsop_Ruby* rmod;
864
+ VALUE v;
865
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
866
+ rb_scan_args(argc, argv,"10",&v);
867
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
868
+ CtoI *ctoi_modc = value2ctoi(v);
869
+ CtoI *ctoi_fin;
870
+ *ctoi_moda = *ctoi_moda + *ctoi_modc;
871
+ ctoi_fin = ctoi_moda;
872
+ delete ctoi_modc;
873
+
874
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
875
+ rmod_rtn->cmod = ctoi_fin;
876
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
877
+ }
878
+
879
+ /*##vsop_minus##*/
880
+ VALUE vsop_minus(int argc, VALUE *argv,VALUE self){
881
+ Vsop_Ruby* rmod;
882
+ VALUE v;
883
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
884
+ rb_scan_args(argc, argv,"10",&v);
885
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
886
+ CtoI *ctoi_modc = value2ctoi(v);
887
+ CtoI *ctoi_fin;
888
+ *ctoi_moda = *ctoi_moda - *ctoi_modc;
889
+ ctoi_fin = ctoi_moda;
890
+ delete ctoi_modc;
891
+
892
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
893
+ rmod_rtn->cmod = ctoi_fin;
894
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
895
+ }
896
+
897
+ /*##vsop_meet##*/
898
+ VALUE vsop_meet(int argc, VALUE *argv,VALUE self){
899
+ Vsop_Ruby* rmod;
900
+ VALUE v;
901
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
902
+ rb_scan_args(argc, argv,"10",&v);
903
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
904
+ CtoI *ctoi_modc = value2ctoi(v);
905
+ CtoI *ctoi_fin;
906
+ *ctoi_moda = CtoI_Meet(*ctoi_moda, *ctoi_modc);
907
+ //*ctoi_moda = ZBDD_Meet(ctoi_moda->NonZero().GetZBDD(), ctoi_modc->NonZero().GetZBDD());
908
+ ctoi_fin = ctoi_moda;
909
+ delete ctoi_modc;
910
+
911
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
912
+ rmod_rtn->cmod = ctoi_fin;
913
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
914
+ }
915
+
916
+ /*##vsop_eq##*/
917
+ VALUE vsop_eq(int argc, VALUE *argv,VALUE self){
918
+ Vsop_Ruby* rmod;
919
+ VALUE v;
920
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
921
+ rb_scan_args(argc, argv,"10",&v);
922
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
923
+ CtoI *ctoi_modc = value2ctoi(v);
924
+ CtoI *ctoi_fin;
925
+ *ctoi_moda = CtoI_EQ(*ctoi_moda, *ctoi_modc);
926
+ ctoi_fin = ctoi_moda;
927
+ delete ctoi_modc;
928
+
929
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
930
+ rmod_rtn->cmod = ctoi_fin;
931
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
932
+ }
933
+
934
+ /*##vsop_ne##*/
935
+ VALUE vsop_ne(int argc, VALUE *argv,VALUE self){
936
+ Vsop_Ruby* rmod;
937
+ VALUE v;
938
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
939
+ rb_scan_args(argc, argv,"10",&v);
940
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
941
+ CtoI *ctoi_modc = value2ctoi(v);
942
+ CtoI *ctoi_fin;
943
+ *ctoi_moda = CtoI_NE(*ctoi_moda, *ctoi_modc);
944
+ ctoi_fin = ctoi_moda;
945
+ delete ctoi_modc;
946
+
947
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
948
+ rmod_rtn->cmod = ctoi_fin;
949
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
950
+ }
951
+
952
+ /*##vsop_gt##*/
953
+ VALUE vsop_gt(int argc, VALUE *argv,VALUE self){
954
+ Vsop_Ruby* rmod;
955
+ VALUE v;
956
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
957
+ rb_scan_args(argc, argv,"10",&v);
958
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
959
+ CtoI *ctoi_modc = value2ctoi(v);
960
+ CtoI *ctoi_fin;
961
+ *ctoi_moda = CtoI_GT(*ctoi_moda, *ctoi_modc);
962
+ ctoi_fin = ctoi_moda;
963
+ delete ctoi_modc;
964
+
965
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
966
+ rmod_rtn->cmod = ctoi_fin;
967
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
968
+ }
969
+
970
+ /*##vsop_ge##*/
971
+ VALUE vsop_ge(int argc, VALUE *argv,VALUE self){
972
+ Vsop_Ruby* rmod;
973
+ VALUE v;
974
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
975
+ rb_scan_args(argc, argv,"10",&v);
976
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
977
+ CtoI *ctoi_modc = value2ctoi(v);
978
+ CtoI *ctoi_fin;
979
+ *ctoi_moda = CtoI_GE(*ctoi_moda, *ctoi_modc);
980
+ ctoi_fin = ctoi_moda;
981
+ delete ctoi_modc;
982
+
983
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
984
+ rmod_rtn->cmod = ctoi_fin;
985
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
986
+ }
987
+
988
+ /*##vsop_lt##*/
989
+ VALUE vsop_lt(int argc, VALUE *argv,VALUE self){
990
+ Vsop_Ruby* rmod;
991
+ VALUE v;
992
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
993
+ rb_scan_args(argc, argv,"10",&v);
994
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
995
+ CtoI *ctoi_modc = value2ctoi(v);
996
+ CtoI *ctoi_fin;
997
+ *ctoi_moda = CtoI_LT(*ctoi_moda, *ctoi_modc);
998
+ ctoi_fin = ctoi_moda;
999
+ delete ctoi_modc;
1000
+
1001
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1002
+ rmod_rtn->cmod = ctoi_fin;
1003
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1004
+ }
1005
+
1006
+ /*##vsop_le##*/
1007
+ VALUE vsop_le(int argc, VALUE *argv,VALUE self){
1008
+ Vsop_Ruby* rmod;
1009
+ VALUE v;
1010
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
1011
+ rb_scan_args(argc, argv,"10",&v);
1012
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1013
+ CtoI *ctoi_modc = value2ctoi(v);
1014
+ CtoI *ctoi_fin;
1015
+ *ctoi_moda = CtoI_LE(*ctoi_moda, *ctoi_modc);
1016
+ ctoi_fin = ctoi_moda;
1017
+ delete ctoi_modc;
1018
+
1019
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1020
+ rmod_rtn->cmod = ctoi_fin;
1021
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1022
+ }
1023
+
1024
+ /*##vsop_iif##*/
1025
+ VALUE vsop_iif(int argc, VALUE *argv,VALUE self){
1026
+ Vsop_Ruby* rmod;
1027
+ VALUE v1;
1028
+ VALUE v2;
1029
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
1030
+ rb_scan_args(argc, argv,"20",&v1,&v2);
1031
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1032
+ CtoI *ctoi_modc = value2ctoi(v1);
1033
+ CtoI *ctoi_mode = value2ctoi(v2);
1034
+ CtoI *ctoi_fin;
1035
+ *ctoi_moda = CtoI_ITE(*ctoi_moda, *ctoi_modc, *ctoi_mode);
1036
+ ctoi_fin = ctoi_moda;
1037
+ delete ctoi_modc;
1038
+ delete ctoi_mode;
1039
+
1040
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1041
+ rmod_rtn->cmod = ctoi_fin;
1042
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1043
+ }
1044
+
1045
+ /*##vsop_multiply##*/
1046
+ VALUE vsop_multiply(int argc, VALUE *argv,VALUE self){
1047
+ Vsop_Ruby* rmod;
1048
+ VALUE v;
1049
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
1050
+ rb_scan_args(argc, argv,"10",&v);
1051
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1052
+ CtoI *ctoi_modc = value2ctoi(v);
1053
+ CtoI *ctoi_fin;
1054
+ *ctoi_moda = Product(*ctoi_moda, *ctoi_modc);
1055
+ ctoi_fin = ctoi_moda;
1056
+ delete ctoi_modc;
1057
+
1058
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1059
+ rmod_rtn->cmod = ctoi_fin;
1060
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1061
+ }
1062
+
1063
+ /*##vsop_quotiment##*/
1064
+ VALUE vsop_quotiment(int argc, VALUE *argv,VALUE self){
1065
+ Vsop_Ruby* rmod;
1066
+ VALUE v;
1067
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
1068
+ rb_scan_args(argc, argv,"10",&v);
1069
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1070
+ CtoI *ctoi_modc = value2ctoi(v);
1071
+ CtoI *ctoi_fin;
1072
+ if(*ctoi_modc == 0)
1073
+ {
1074
+ yyerror("<WARNING> Divide by zero");
1075
+ *ctoi_moda = 0;
1076
+ }
1077
+ else *ctoi_moda = *ctoi_moda / *ctoi_modc;
1078
+ ctoi_fin = ctoi_moda;
1079
+ delete ctoi_modc;
1080
+
1081
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1082
+ rmod_rtn->cmod = ctoi_fin;
1083
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1084
+ }
1085
+
1086
+ /*##vsop_remainder##*/
1087
+ VALUE vsop_remainder(int argc, VALUE *argv,VALUE self){
1088
+ Vsop_Ruby* rmod;
1089
+ VALUE v;
1090
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
1091
+ rb_scan_args(argc, argv,"10",&v);
1092
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1093
+ CtoI *ctoi_modc = value2ctoi(v);
1094
+ CtoI *ctoi_fin;
1095
+ if(*ctoi_modc == 0)
1096
+ {
1097
+ yyerror("<WARNING> Divide by zero");
1098
+ *ctoi_moda = 0;
1099
+ }
1100
+ else *ctoi_moda = *ctoi_moda % *ctoi_modc;
1101
+ ctoi_fin = ctoi_moda;
1102
+ delete ctoi_modc;
1103
+
1104
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1105
+ rmod_rtn->cmod = ctoi_fin;
1106
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1107
+ }
1108
+
1109
+ /*
1110
+ * : print expr
1111
+ */
1112
+
1113
+ VALUE vsop_print(VALUE self){
1114
+ Vsop_Ruby* rmod;
1115
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
1116
+ CtoI *ctoi_modb =new CtoI(*rmod->cmod);
1117
+ if(*ctoi_modb == CtoI_Null())
1118
+ {
1119
+ *ctoi_modb = 0;
1120
+ yyerror("<WARNING> Memory overflow");
1121
+ }
1122
+ if(PrintCtoI(*ctoi_modb) == 1)
1123
+ yyerror("<WARNING> Memory overflow");
1124
+ delete ctoi_modb;
1125
+
1126
+ return self;
1127
+ }
1128
+
1129
+ VALUE vsop_print_arg1(VALUE self,char *arg){
1130
+ Vsop_Ruby* rmod;
1131
+ // VALUE v;
1132
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
1133
+ CtoI *ctoi_modd =new CtoI(*rmod->cmod);
1134
+ int len = strlen(arg);
1135
+ char *str_c;
1136
+ str_c = new char[len+1];
1137
+ strcpy(str_c,arg);
1138
+ if(*ctoi_modd == CtoI_Null())
1139
+ {
1140
+ *ctoi_modd = 0;
1141
+ yyerror("<WARNING> Memory overflow");
1142
+ }
1143
+ else if(strcmp(str_c, "hex") == 0)
1144
+ {
1145
+ if(PrintCtoI_16(*ctoi_modd) == 1)
1146
+ yyerror("<WARNING> Memory overflow");
1147
+ delete ctoi_modd;
1148
+ }
1149
+ else if(strcmp(str_c, "bit") == 0)
1150
+ {
1151
+ if(PrintDigital(*ctoi_modd) == 1)
1152
+ yyerror("<WARNING> Memory overflow");
1153
+ delete ctoi_modd;
1154
+ }
1155
+ else if(strcmp(str_c, "case") == 0)
1156
+ {
1157
+ if(PrintCase(*ctoi_modd) == 1)
1158
+ yyerror("<WARNING> Memory overflow");
1159
+ delete ctoi_modd;
1160
+ }
1161
+ else if(strcmp(str_c, "map") == 0)
1162
+ {
1163
+ if(MapAll(*ctoi_modd) == 1)
1164
+ yyerror("<WARNING> Memory overflow");
1165
+ delete ctoi_modd;
1166
+ }
1167
+ else if(strcmp(str_c, "rmap") == 0)
1168
+ {
1169
+ if(MapSel(*ctoi_modd) == 1)
1170
+ yyerror("<WARNING> Memory overflow");
1171
+ delete ctoi_modd;
1172
+ }
1173
+ else if(strcmp(str_c, "size") == 0)
1174
+ {
1175
+ char s[32];
1176
+ B_ITOSTR(ctoi_modd -> Size(), s);
1177
+ bout << " " << s;
1178
+ bout.Delimit();
1179
+ BDD_GC();
1180
+ B_ITOSTR(BDD_Used(), s);
1181
+ bout << "(" << s << ")";
1182
+ bout.Return();
1183
+ delete ctoi_modd;
1184
+ }
1185
+ else if(strcmp(str_c, "count") == 0)
1186
+ {
1187
+ *ctoi_modd = ctoi_modd -> CountTerms();
1188
+ if(*ctoi_modd == CtoI_Null())
1189
+ {
1190
+ *ctoi_modd = 0;
1191
+ yyerror("<WARNING> Memory overflow");
1192
+ }
1193
+
1194
+ int slen = ctoi_modd->TopDigit() / 3 + 14;
1195
+ char* s = new char[slen];
1196
+ if(s == 0)
1197
+ {
1198
+ yyerror("<WARNING> Memory overflow");
1199
+ }
1200
+
1201
+ ctoi_modd -> StrNum10(s);
1202
+ bout << " " << s;
1203
+ bout.Return();
1204
+ delete[] s;
1205
+ delete ctoi_modd;
1206
+ }
1207
+ else if(strcmp(str_c, "density") == 0)
1208
+ {
1209
+ *ctoi_modd = ctoi_modd -> NonZero();
1210
+ if(*ctoi_modd == CtoI_Null())
1211
+ {
1212
+ *ctoi_modd = 0;
1213
+ yyerror("<WARNING> Memory overflow");
1214
+ }
1215
+
1216
+ char s[32];
1217
+ int d = Density(ctoi_modd -> GetZBDD(), VTable.Used());
1218
+ sprintf(s, "%g", (float)d / power30);
1219
+ if(d == 0 && *ctoi_modd != 0)
1220
+ yyerror("<WARNING> Bit underflow occurred");
1221
+ bout << " " << s;
1222
+ bout.Return();
1223
+
1224
+ delete ctoi_modd;
1225
+ }
1226
+ else if(strcmp(str_c, "value") == 0)
1227
+ {
1228
+ char s[32];
1229
+ sprintf(s, " %g", (float)Value(*ctoi_modd)/power16);
1230
+ if(OVF.Check()!= 0)
1231
+ yyerror("<WARNING> Bit overflow occurred");
1232
+ bout << s;
1233
+ bout.Return();
1234
+ delete ctoi_modd;
1235
+ }
1236
+ else if(strcmp(str_c, "maxcover") == 0)
1237
+ {
1238
+ *ctoi_modd = ctoi_modd -> NonZero();
1239
+ if(*ctoi_modd == CtoI_Null())
1240
+ {
1241
+ *ctoi_modd = 0;
1242
+ yyerror("<WARNING> Memory overflow");
1243
+ }
1244
+ if(*ctoi_modd == 0) bout << " 0";
1245
+ else
1246
+ {
1247
+ ZBDD f = ctoi_modd -> GetZBDD();
1248
+ if(MaxCost(f)==0)
1249
+ bout << " 1";
1250
+ else
1251
+ {
1252
+ bout << "<Items>: ";
1253
+ while(1)
1254
+ {
1255
+ int var = f.Top();
1256
+ if(var == 0) break;
1257
+ ZBDD f0 = f.OffSet(var);
1258
+ ZBDD f1 = f.OnSet0(var);
1259
+ int c1 = MaxCost(f1) + VTable.GetValue(var);
1260
+ if(MaxCost(f0) < c1)
1261
+ {
1262
+ bout << VTable.GetName(var);
1263
+ bout.Delimit();
1264
+ f = f1;
1265
+ }
1266
+ else f = f0;
1267
+ }
1268
+ }
1269
+ }
1270
+ bout.Return();
1271
+ delete ctoi_modd;
1272
+ }
1273
+ else if(strcmp(str_c, "maxcost") == 0)
1274
+ {
1275
+ *ctoi_modd = ctoi_modd -> NonZero();
1276
+ if(*ctoi_modd == CtoI_Null())
1277
+ {
1278
+ *ctoi_modd = 0;
1279
+ yyerror("<WARNING> Memory overflow");
1280
+ }
1281
+ if(*ctoi_modd == 0) bout << "<No cover.>";
1282
+ else
1283
+ {
1284
+ char s[32];
1285
+ int c = MaxCost(ctoi_modd -> GetZBDD());
1286
+ sprintf(s, "%g", (float)c / power16);
1287
+ bout << s;
1288
+ }
1289
+ bout.Return();
1290
+ delete ctoi_modd;
1291
+ }
1292
+ else if(strcmp(str_c, "mincover") == 0)
1293
+ {
1294
+ *ctoi_modd = ctoi_modd -> NonZero();
1295
+ if(*ctoi_modd == CtoI_Null())
1296
+ {
1297
+ *ctoi_modd = 0;
1298
+ yyerror("<WARNING> Memory overflow");
1299
+ }
1300
+ if(*ctoi_modd == 0) bout << " 0";
1301
+ else
1302
+ {
1303
+ ZBDD f = ctoi_modd -> GetZBDD();
1304
+ if(MinCost(f)==0)
1305
+ bout << " 1";
1306
+ else
1307
+ {
1308
+ bout << "<Items>: ";
1309
+ while(1)
1310
+ {
1311
+ int var = f.Top();
1312
+ if(var == 0) break;
1313
+ ZBDD f0 = f.OffSet(var);
1314
+ ZBDD f1 = f.OnSet0(var);
1315
+ int c1 = MinCost(f1) + VTable.GetValue(var);
1316
+ if(MinCost(f0) > c1)
1317
+ {
1318
+ bout << VTable.GetName(var);
1319
+ bout.Delimit();
1320
+ f = f1;
1321
+ }
1322
+ else f = f0;
1323
+ }
1324
+ }
1325
+ }
1326
+ bout.Return();
1327
+ delete ctoi_modd;
1328
+ }
1329
+ else if(strcmp(str_c, "mincost") == 0)
1330
+ {
1331
+ *ctoi_modd = ctoi_modd -> NonZero();
1332
+ if(*ctoi_modd == CtoI_Null())
1333
+ {
1334
+ *ctoi_modd = 0;
1335
+ yyerror("<WARNING> Memory overflow");
1336
+ }
1337
+ if(*ctoi_modd == 0) bout << "<No cover.>";
1338
+ else
1339
+ {
1340
+ char s[32];
1341
+ int c = MinCost(ctoi_modd -> GetZBDD());
1342
+ sprintf(s, "%g", (float)c / power16);
1343
+ bout << s;
1344
+ }
1345
+ bout.Return();
1346
+ delete ctoi_modd;
1347
+ }
1348
+ else if(strcmp(str_c, "plot") == 0)
1349
+ {
1350
+ #ifdef B_STATIC
1351
+ bout << "sorry, not supported in this version.";
1352
+ bout.Return();
1353
+ #else
1354
+ ctoi_modd -> XPrint();
1355
+ #endif
1356
+ delete ctoi_modd;
1357
+ }
1358
+ else if(strcmp(str_c, "decomp") == 0)
1359
+ {
1360
+ if(PrintDecomp(*ctoi_modd) == 1)
1361
+ {
1362
+ bout << "...";
1363
+ bout.Return();
1364
+ yyerror("<WARNING> Memory overflow");
1365
+ }
1366
+ delete ctoi_modd;
1367
+ }
1368
+ else if(strcmp(str_c, "decompd") == 0)
1369
+ {
1370
+ if(PrintDecompDot(*ctoi_modd) == 1)
1371
+ {
1372
+ bout << "...";
1373
+ bout.Return();
1374
+ yyerror("<WARNING> Memory overflow");
1375
+ }
1376
+ delete ctoi_modd;
1377
+ }
1378
+ else if(strcmp(str_c, "imply0") == 0)
1379
+ {
1380
+ ZBDD f = ctoi_modd -> NonZero().GetZBDD();
1381
+ ZBDD g = f.Support();
1382
+ while(g != 0)
1383
+ {
1384
+ int t = g.Top();
1385
+ g = g.OffSet(t);
1386
+ ZBDD g2 = f.Support();
1387
+ while(g2 != 0)
1388
+ {
1389
+ int t2 = g2.Top();
1390
+ g2 = g2.OffSet(t2);
1391
+ if(t != t2)
1392
+ {
1393
+ int y = f.ImplyChk(t, t2);
1394
+ if(y == 1)
1395
+ {
1396
+ bout << VTable.GetName(t);
1397
+ bout << "->";
1398
+ bout << VTable.GetName(t2);
1399
+ bout << ";";
1400
+ bout.Delimit();
1401
+ }
1402
+ }
1403
+ }
1404
+ }
1405
+ bout.Return();
1406
+ delete ctoi_modd;
1407
+ }
1408
+ else if(strcmp(str_c, "symmetry") == 0)
1409
+ {
1410
+ ZBDD f = ctoi_modd -> NonZero().GetZBDD();
1411
+ ZBDD g = f.Support();
1412
+ while(g != 0)
1413
+ {
1414
+ int t = g.Top();
1415
+ g = g.OffSet(t);
1416
+ ZBDD g2 = f.SymSet(t);
1417
+ g -= g2;
1418
+ while(g2 != 0)
1419
+ {
1420
+ int t2 = g2.Top();
1421
+ g2 = g2.OffSet(t2);
1422
+ bout << VTable.GetName(t);
1423
+ bout << "==";
1424
+ bout << VTable.GetName(t2);
1425
+ bout << ";";
1426
+ bout.Delimit();
1427
+ }
1428
+ }
1429
+ bout.Return();
1430
+ delete ctoi_modd;
1431
+ }
1432
+ else if(strcmp(str_c, "imply") == 0)
1433
+ {
1434
+ ZBDD f = ctoi_modd -> NonZero().GetZBDD();
1435
+ ZBDD g = f.Support();
1436
+ while(g != 0)
1437
+ {
1438
+ int t = g.Top();
1439
+ g = g.OffSet(t);
1440
+ ZBDD g2 = f.ImplySet(t);
1441
+ while(g2 != 0)
1442
+ {
1443
+ int t2 = g2.Top();
1444
+ g2 = g2.OffSet(t2);
1445
+ bout << VTable.GetName(t);
1446
+ bout << "->";
1447
+ bout << VTable.GetName(t2);
1448
+ bout << ";";
1449
+ bout.Delimit();
1450
+ }
1451
+ }
1452
+ bout.Return();
1453
+ delete ctoi_modd;
1454
+ }
1455
+ else if(strcmp(str_c, "coimply0") == 0)
1456
+ {
1457
+ ZBDD f = ctoi_modd -> NonZero().GetZBDD();
1458
+ ZBDD g = f.Support();
1459
+ while(g != 0)
1460
+ {
1461
+ int t = g.Top();
1462
+ g = g.OffSet(t);
1463
+ ZBDD g2 = f.Support();
1464
+ while(g2 != 0)
1465
+ {
1466
+ int t2 = g2.Top();
1467
+ g2 = g2.OffSet(t2);
1468
+ if(t != t2)
1469
+ {
1470
+ int y = f.CoImplyChk(t, t2);
1471
+ if(y == 1)
1472
+ {
1473
+ bout << VTable.GetName(t);
1474
+ bout << "->";
1475
+ bout << VTable.GetName(t2);
1476
+ bout << ";";
1477
+ bout.Delimit();
1478
+ }
1479
+ }
1480
+ }
1481
+ }
1482
+ bout.Return();
1483
+ delete ctoi_modd;
1484
+ }
1485
+ else if(strcmp(str_c, "coimply") == 0)
1486
+ {
1487
+ ZBDD f = ctoi_modd -> NonZero().GetZBDD();
1488
+ ZBDD g = f.Support();
1489
+ while(g != 0)
1490
+ {
1491
+ int t = g.Top();
1492
+ g = g.OffSet(t);
1493
+ ZBDD g2 = f.CoImplySet(t);
1494
+ while(g2 != 0)
1495
+ {
1496
+ int t2 = g2.Top();
1497
+ g2 = g2.OffSet(t2);
1498
+ bout << VTable.GetName(t);
1499
+ bout << "->";
1500
+ bout << VTable.GetName(t2);
1501
+ bout << ";";
1502
+ bout.Delimit();
1503
+ }
1504
+ }
1505
+ bout.Return();
1506
+ delete ctoi_modd;
1507
+ }
1508
+ else if(strcmp(str_c, "coimply2") == 0)
1509
+ {
1510
+ ZBDD f = ctoi_modd -> NonZero().GetZBDD();
1511
+ ZBDD g = f.Support();
1512
+ while(g != 0)
1513
+ {
1514
+ int t = g.Top();
1515
+ g = g.OffSet(t);
1516
+ ZBDD g2 = f.CoImplySet(t) - f.ImplySet(t);
1517
+ while(g2 != 0)
1518
+ {
1519
+ int t2 = g2.Top();
1520
+ g2 = g2.OffSet(t2);
1521
+ bout << VTable.GetName(t);
1522
+ bout << "->";
1523
+ bout << VTable.GetName(t2);
1524
+ bout << ";";
1525
+ bout.Delimit();
1526
+ }
1527
+ }
1528
+ bout.Return();
1529
+ delete ctoi_modd;
1530
+ }
1531
+ else if(strcmp(str_c, "export") == 0)
1532
+ {
1533
+ int d = ctoi_modd -> TopDigit();
1534
+ ZBDDV v = ZBDDV();
1535
+ for(int i=0; i<=d; i++)
1536
+ v += ZBDDV(ctoi_modd -> Digit(i).GetZBDD(), i);
1537
+ v.Export();
1538
+ delete ctoi_modd;
1539
+ }
1540
+ else if(strcmp(str_c, "exports") == 0)
1541
+ {
1542
+ int n = VTable.Used();
1543
+ for(int i=n; i>0; i--)
1544
+ {
1545
+ int var = BDD_VarOfLev(i);
1546
+ cout << VTable.GetName(var) << " ";
1547
+ }
1548
+ cout << "\n";
1549
+ int d = ctoi_modd -> TopDigit();
1550
+ ZBDDV v = ZBDDV();
1551
+ for(int i=0; i<=d; i++)
1552
+ v += ZBDDV(ctoi_modd -> Digit(i).GetZBDD(), i);
1553
+ v.Export();
1554
+ delete ctoi_modd;
1555
+ }
1556
+ else
1557
+ {
1558
+ yyerror("Illegal switch");
1559
+ delete ctoi_modd;
1560
+ }
1561
+ delete[] str_c;
1562
+
1563
+ return self;
1564
+ }
1565
+
1566
+
1567
+ VALUE vsop_print_arg2(int argc, VALUE *argv, VALUE self){
1568
+ Vsop_Ruby* rmod;
1569
+ VALUE v1,v2;
1570
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
1571
+ CtoI *ctoi_mode =new CtoI(*rmod->cmod);
1572
+ rb_scan_args(argc, argv,"20",&v1,&v2);
1573
+ if(TYPE(v1)!=T_STRING){
1574
+ rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
1575
+ }
1576
+ if(TYPE(v2)!=T_STRING){
1577
+ rb_raise(rb_eRuntimeError,"argument type error (2nd argument must be STRING)");
1578
+ }
1579
+ char *arg1=RSTRING_PTR(v1);
1580
+ char *arg2=RSTRING_PTR(v2);
1581
+
1582
+ int len;
1583
+ len = strlen(arg1);
1584
+ char *str_c;
1585
+ if(*arg1=='/'){
1586
+ str_c = new char[len];
1587
+ strcpy(str_c,arg1+1);
1588
+ }
1589
+ else{
1590
+ str_c = new char[len+1];
1591
+ strcpy(str_c,arg1);
1592
+ }
1593
+
1594
+ len = strlen(arg2);
1595
+ char *str_d = new char[len+3];
1596
+ sprintf(str_d,"\"%s\"",arg2);
1597
+ int len_d = len+2;
1598
+
1599
+ if(strcmp(str_c, "export") == 0)
1600
+ {
1601
+ str_d[len_d - 1] = 0;
1602
+ FILE *fp;
1603
+ fp = fopen(str_d+1, "w");
1604
+ if(fp == NULL) yyerror("Can't open the file");
1605
+ else
1606
+ {
1607
+ int d = ctoi_mode -> TopDigit();
1608
+ ZBDDV v = ZBDDV();
1609
+ for(int i=0; i<=d; i++)
1610
+ v += ZBDDV(ctoi_mode -> Digit(i).GetZBDD(), i);
1611
+ v.Export(fp);
1612
+ fclose(fp);
1613
+ }
1614
+ }
1615
+ else
1616
+ {
1617
+ yyerror("Illegal switch");
1618
+ }
1619
+ delete[] str_c;
1620
+ delete[] str_d;
1621
+ delete ctoi_mode;
1622
+
1623
+ return self;
1624
+ }
1625
+
1626
+ extern "C"{
1627
+ void Init_zdd_so();
1628
+ }
1629
+
1630
+ int yylineno=1;
1631
+
1632
+ static int hashcnt;
1633
+ static int Depth;
1634
+ static int* S_Var;
1635
+ static int PFflag;
1636
+
1637
+ static int Depth_e;
1638
+ static int* S_Var_e;
1639
+
1640
+ static int Depth_item;
1641
+ static int* S_Var_item;
1642
+
1643
+ static int* S_Var_ary;
1644
+
1645
+ //数値チェック(アイテムが数値なら警告)
1646
+ static void num_check(char *str)
1647
+ {
1648
+ char *p=str;
1649
+ if(*p=='-' || *p=='+' ) p++;
1650
+ while(*p){
1651
+ if( ( *p>='0' && *p<='9' ) || *p == '.' ){
1652
+ fprintf(stderr,"chech %c\n",*p);
1653
+ fprintf(stderr,"use numbers for symbol Variable\n");
1654
+ break;
1655
+ }
1656
+ p++;
1657
+ }
1658
+ }
1659
+
1660
+ //----------------------- vsop_csvout -------------------------------
1661
+ static int PutNum(CtoI a, int base,ofstream &fs)
1662
+ {
1663
+ if(a.TopItem() > 0) a = a.MaxVal();
1664
+ int d = a.TopDigit() / 3 + 14;
1665
+ kgAutoPtr2<char> a_ptr;
1666
+ char *s;
1667
+ try{
1668
+ a_ptr.set(new char[d]);
1669
+ s = a_ptr.get();
1670
+ }catch(...){
1671
+ rb_raise(rb_eRuntimeError,"memory allocation error");
1672
+ }
1673
+ int err;
1674
+ if(base == 16) err = a.StrNum16(s);
1675
+ else err = a.StrNum10(s);
1676
+ if(err == 1) return 1;
1677
+ fs << s<< ",";
1678
+ return 0;
1679
+ }
1680
+
1681
+ static int PF(CtoI a, int base,ofstream &fs)
1682
+ {
1683
+ if(a.IsConst())
1684
+ {
1685
+ if(PFflag == 1){fs << endl;}
1686
+ if(a.TopDigit() & 1) {fs << "-" ; a = -a; }
1687
+
1688
+ PFflag = 1;
1689
+ int c1 = (a != 1);
1690
+ if(c1 || Depth == 0)
1691
+ {
1692
+ if(PutNum(a, base,fs) == 1) return 1;
1693
+ }
1694
+ else if(!c1){
1695
+ fs << "1,";
1696
+ }
1697
+ for(int i=0; i<Depth; i++)
1698
+ {
1699
+ if(i==0){ fs << VTable.GetName(S_Var[i]);}
1700
+ else { fs << " " << VTable.GetName(S_Var[i]);}
1701
+ }
1702
+ return 0;
1703
+ }
1704
+ int v = a.TopItem();
1705
+ CtoI b = a.Factor1(v);
1706
+ if(b == CtoI_Null()) return 1;
1707
+ S_Var[Depth] = v;
1708
+ Depth++;
1709
+ if(PF(b, base,fs) == 1) return 1;
1710
+ Depth--;
1711
+ b = a.Factor0(v);
1712
+ if(b == 0) return 0;
1713
+ if(b == CtoI_Null()) return 1;
1714
+ return PF(b, base,fs);
1715
+ }
1716
+
1717
+ int CsvoutCtoI(CtoI a,ofstream &fs)
1718
+ {
1719
+ if(a == CtoI_Null()) return 1;
1720
+ if(a == 0) return 0;
1721
+ else
1722
+ {
1723
+ int lev = BDD_LevOfVar(a.TopItem());
1724
+ Depth = 0;
1725
+ kgAutoPtr2<int> a_ptr;
1726
+ try{
1727
+ a_ptr.set(new int[lev]);
1728
+ S_Var = a_ptr.get();
1729
+ }catch(...){
1730
+ rb_raise(rb_eRuntimeError,"memory allocation error");
1731
+ }
1732
+ PFflag = 0;
1733
+ int err = PF(a, 10,fs);
1734
+ if(err == 1){
1735
+ rb_raise(rb_eRuntimeError,"memory over flow");
1736
+ return 1;
1737
+ }
1738
+ }
1739
+ fs << endl;
1740
+ return 0;
1741
+ }
1742
+ /*##vsop_csvout##*/
1743
+ VALUE vsop_csvout(int argc, VALUE *argv, VALUE self) {
1744
+ Vsop_Ruby* rmod;
1745
+ VALUE v;
1746
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
1747
+ rb_scan_args(argc, argv,"10",&v);
1748
+ char *str = RSTRING_PTR(v);
1749
+ ofstream fs;
1750
+ fs.open(str);
1751
+ if(fs.is_open()){
1752
+ CsvoutCtoI(*rmod->cmod,fs);
1753
+ fs.close();
1754
+ }
1755
+ else{
1756
+ rb_raise(rb_eRuntimeError,"file oepn error");
1757
+ }
1758
+ return self;
1759
+ }
1760
+ //----------------------- vsop_csvout -------------------------------
1761
+
1762
+ //----------------------- vsop_hashout -------------------------------
1763
+ static int PF_hash(CtoI a, int base,VALUE& hash)
1764
+ {
1765
+ if(a.IsConst())
1766
+ {
1767
+ char *valstr;
1768
+ kgAutoPtr2<char> a_ptr0;
1769
+ try{
1770
+ a_ptr0.set(new char[MAX_LEN]);
1771
+ valstr = a_ptr0.get();
1772
+ }catch(...){
1773
+ rb_raise(rb_eRuntimeError,"memory allocation error");
1774
+ }
1775
+ if(a.TopDigit() & 1) {strcpy(valstr,"-") ; a = -a; }
1776
+ else{ strcpy(valstr,"");}
1777
+
1778
+ PFflag = 1;
1779
+ int c1 = (a != 1);
1780
+
1781
+ char *valrtn;
1782
+ kgAutoPtr2<char> a_ptr;
1783
+ if(c1 || Depth == 0)
1784
+ {
1785
+ if(a.TopItem() > 0) a = a.MaxVal();
1786
+ int d = a.TopDigit() / 3 + 14;
1787
+ try{
1788
+ a_ptr.set(new char[d]);
1789
+ valrtn = a_ptr.get();
1790
+ }catch(...){
1791
+ rb_raise(rb_eRuntimeError,"memory allocation error");
1792
+ }
1793
+ int err;
1794
+ if(base == 16) err = a.StrNum16(valrtn);
1795
+ else err = a.StrNum10(valrtn);
1796
+ if(err == 1)
1797
+ {
1798
+ rb_raise(rb_eRuntimeError,"memory over flow");
1799
+ return 1;
1800
+ }
1801
+ strcat(valstr,valrtn);
1802
+ }
1803
+ else if(!c1){
1804
+ strcat(valstr,"1");
1805
+ }
1806
+ char *keystr;
1807
+ kgAutoPtr2<char> a_ptr1;
1808
+ try{
1809
+ a_ptr1.set(new char[MAX_LEN]);
1810
+ keystr = a_ptr1.get();
1811
+ }catch(...){
1812
+ rb_raise(rb_eRuntimeError,"memory allocation error");
1813
+ }
1814
+ *keystr = '\0';
1815
+ for(int i=0; i<Depth; i++)
1816
+ {
1817
+ int size = strlen(keystr)+strlen(VTable.GetName(S_Var[i]))+2;
1818
+ if(size>MAX_LEN){
1819
+ rb_raise(rb_eRuntimeError,"string size over flow");
1820
+ }
1821
+ if(i==0){
1822
+ strcpy(keystr,VTable.GetName(S_Var[i]));
1823
+ }
1824
+ else{
1825
+ strcat(keystr," ");
1826
+ strcat(keystr,VTable.GetName(S_Var[i]));
1827
+ }
1828
+ }
1829
+ VALUE key = rb_str_new2(keystr);
1830
+ VALUE val = INT2NUM(atoi(valstr));
1831
+ rb_hash_aset(hash, key, val);
1832
+ hashcnt++;
1833
+ if(hashcnt> HASH_MAX){return 2;}
1834
+ return 0;
1835
+ }
1836
+ int v = a.TopItem();
1837
+ CtoI b = a.Factor1(v);
1838
+ if(b == CtoI_Null()) return 1;
1839
+ S_Var[Depth] = v;
1840
+ Depth++;
1841
+ int chk=PF_hash(b, base,hash);
1842
+ if(chk > 0) return chk;
1843
+ Depth--;
1844
+ b = a.Factor0(v);
1845
+ if(b == 0) return 0;
1846
+ if(b == CtoI_Null()) return 1;
1847
+
1848
+ return PF_hash(b, base,hash);
1849
+ }
1850
+ VALUE HashoutCtoI(CtoI a,int *rtn)
1851
+ {
1852
+ hashcnt=0;
1853
+ VALUE hash = rb_hash_new();
1854
+ if(a == CtoI_Null()) return 1;
1855
+ if(a == 0) return 0;
1856
+ else
1857
+ {
1858
+ int lev = BDD_LevOfVar(a.TopItem());
1859
+ Depth = 0;
1860
+ kgAutoPtr2<int> a_ptr;
1861
+ try{
1862
+ a_ptr.set(new int[lev]);
1863
+ S_Var = a_ptr.get();
1864
+ }catch(...){
1865
+ rb_raise(rb_eRuntimeError,"memory allocation error");
1866
+ }
1867
+ PFflag = 0;
1868
+ int err = PF_hash(a, 10,hash);
1869
+ *rtn = err;
1870
+ if(err == 1){
1871
+ rb_raise(rb_eRuntimeError,"memory over flow");
1872
+ return rb_hash_new();
1873
+ }
1874
+ }
1875
+ return hash;
1876
+ }
1877
+
1878
+ /*##vsop_hashout##*/
1879
+ VALUE vsop_hashout(VALUE self){
1880
+ int rtnflg=0;
1881
+ Vsop_Ruby* rmod;
1882
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
1883
+ VALUE hash = HashoutCtoI(*rmod->cmod,&rtnflg);
1884
+ if(rtnflg==2){
1885
+ rb_iv_set(self,"@partly", Qtrue );
1886
+ }
1887
+ else{
1888
+ rb_iv_set(self,"@partly", Qfalse);
1889
+ }
1890
+ return hash;
1891
+ }
1892
+ //----------------------- vsop_hashout -------------------------------
1893
+
1894
+ //----------------------- vsop_each -------------------------------
1895
+ static int PF_array_each(CtoI a, VALUE& self)
1896
+ {
1897
+ int sign=1;
1898
+ if(a.IsConst())
1899
+ {
1900
+ if(a.TopDigit() & 1) {sign= -1 ; a = -a; }
1901
+ CtoI rtn;
1902
+ int c1 = (a != 1);
1903
+ char *valrtn;
1904
+ kgAutoPtr2<char> a_ptr;
1905
+ if(c1 || Depth_e == 0)
1906
+ {
1907
+ if(a.TopItem() > 0) a = a.MaxVal();
1908
+ int d = a.TopDigit() / 3 + 14;
1909
+ try{
1910
+ a_ptr.set(new char[d]);
1911
+ valrtn = a_ptr.get();
1912
+ }catch(...){
1913
+ rb_raise(rb_eRuntimeError,"memory allocation error");
1914
+ }
1915
+ int err = a.StrNum10(valrtn);
1916
+ if(err == 1){
1917
+ rb_raise(rb_eRuntimeError,"memory over flow");
1918
+ return 1;
1919
+ }
1920
+ rtn = CtoI(CtoI_atoi(valrtn));
1921
+ }
1922
+ else if(!c1){
1923
+ rtn = CtoI(CtoI_atoi("1"));;
1924
+ }
1925
+
1926
+ for(int i=0; i<Depth_e; i++)
1927
+ {
1928
+ char *str = VTable.GetName(S_Var_e[i]);
1929
+ int ckck = VTable.GetID(str);
1930
+ rtn =Product(rtn, CtoI(1).AffixVar( ckck));
1931
+ }
1932
+
1933
+ Vsop_Ruby* rmod=new Vsop_Ruby;
1934
+ rmod->cmod = new CtoI (rtn) ;
1935
+ rb_yield(Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod));
1936
+ return 0;
1937
+ }
1938
+
1939
+ int v = a.TopItem();
1940
+ CtoI b = a.Factor1(v);
1941
+ if(b == CtoI_Null()) return 1;
1942
+ S_Var_e[Depth_e] = v;
1943
+ Depth_e++;
1944
+ int chk=PF_array_each(b, self);
1945
+ if(chk > 0) return chk;
1946
+ Depth_e--;
1947
+ b = a.Factor0(v);
1948
+ if(b == 0) return 0;
1949
+ if(b == CtoI_Null()) return 1;
1950
+ return PF_array_each(b,self);
1951
+ }
1952
+
1953
+ void CtoI2Array_each(CtoI a,VALUE &self)
1954
+ {
1955
+ if(a == CtoI_Null()) return ;
1956
+ if(a == 0) return ;
1957
+ else
1958
+ {
1959
+ int lev = BDD_LevOfVar(a.TopItem());
1960
+ Depth_e = 0;
1961
+ kgAutoPtr2<int> a_ptr;
1962
+ try{
1963
+ a_ptr.set(new int[lev]);
1964
+ S_Var_e = a_ptr.get();
1965
+ }catch(...){
1966
+ rb_raise(rb_eRuntimeError,"memory allocation error");
1967
+ }
1968
+ PF_array_each(a, self);
1969
+ }
1970
+ }
1971
+ /*##vsop_each##*/
1972
+ VALUE vsop_each(VALUE self){
1973
+ Vsop_Ruby* rmod;
1974
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
1975
+ CtoI2Array_each(*rmod->cmod,self);
1976
+ return Qtrue;
1977
+ }
1978
+ //----------------------- vsop_each -------------------------------
1979
+
1980
+ //----------------------- vsop_to_a -------------------------------
1981
+ static int PF_array(CtoI a,VALUE& array)
1982
+ {
1983
+ if(a.IsConst())
1984
+ {
1985
+ char *valstr;
1986
+ kgAutoPtr2<char> a_ptr0;
1987
+ try{
1988
+ a_ptr0.set(new char[MAX_LEN]);
1989
+ valstr = a_ptr0.get();
1990
+ }catch(...){
1991
+ rb_raise(rb_eRuntimeError,"memory allocation error");
1992
+ }
1993
+ if(a.TopDigit() & 1) {strcpy(valstr,"-") ; a = -a; }
1994
+ else{ strcpy(valstr,"");}
1995
+
1996
+ PFflag = 1;
1997
+ int c1 = (a != 1);
1998
+
1999
+ char *valrtn;
2000
+ kgAutoPtr2<char> a_ptr;
2001
+ if(c1 || Depth == 0)
2002
+ {
2003
+ if(a.TopItem() > 0) a = a.MaxVal();
2004
+ int d = a.TopDigit() / 3 + 14;
2005
+ try{
2006
+ a_ptr.set(new char[d]);
2007
+ valrtn = a_ptr.get();
2008
+ }catch(...){
2009
+ rb_raise(rb_eRuntimeError,"memory allocation error");
2010
+ }
2011
+ int err;
2012
+ err = a.StrNum10(valrtn);
2013
+ if(err == 1)
2014
+ {
2015
+ rb_raise(rb_eRuntimeError,"memory over flow");
2016
+ return 1;
2017
+ }
2018
+ strcat(valstr,valrtn);
2019
+ }
2020
+ char *keystr;
2021
+ kgAutoPtr2<char> a_ptr1;
2022
+ try{
2023
+ a_ptr1.set(new char[MAX_LEN]);
2024
+ keystr = a_ptr1.get();
2025
+ }catch(...){
2026
+ rb_raise(rb_eRuntimeError,"memory allocation error");
2027
+ }
2028
+ *keystr = '\0';
2029
+ for(int i=0; i<Depth; i++)
2030
+ {
2031
+ int size = strlen(keystr)+strlen(VTable.GetName(S_Var_ary[i]))+2;
2032
+ if(size>MAX_LEN){
2033
+ rb_raise(rb_eRuntimeError,"string size over flow");
2034
+ }
2035
+ if(i==0){
2036
+ strcpy(keystr,VTable.GetName(S_Var_ary[i]));
2037
+ }
2038
+ else{
2039
+ strcat(keystr," ");
2040
+ strcat(keystr,VTable.GetName(S_Var_ary[i]));
2041
+ }
2042
+ }
2043
+ if(*valstr&& *keystr){
2044
+ strcat(valstr," ");
2045
+ strcat(valstr,keystr);
2046
+ }
2047
+ else{strcat(valstr,keystr); }
2048
+
2049
+ VALUE val = rb_str_new2(valstr);
2050
+ rb_ary_push(array,val);
2051
+ return 0;
2052
+ }
2053
+ int v = a.TopItem();
2054
+ CtoI b = a.Factor1(v);
2055
+ if(b == CtoI_Null()) return 1;
2056
+ S_Var_ary[Depth] = v;
2057
+ Depth++;
2058
+ int chk=PF_array(b, array);
2059
+ if(chk > 0) return chk;
2060
+ Depth--;
2061
+ b = a.Factor0(v);
2062
+ if(b == 0) return 0;
2063
+ if(b == CtoI_Null()) return 1;
2064
+
2065
+ return PF_array(b, array);
2066
+ }
2067
+
2068
+ VALUE CtoI2Array(CtoI a)
2069
+ {
2070
+ VALUE array = rb_ary_new();
2071
+ if(a == CtoI_Null()) return array;
2072
+ if(a == 0) return array;
2073
+ else
2074
+ {
2075
+ int lev = BDD_LevOfVar(a.TopItem());
2076
+ Depth = 0;
2077
+ kgAutoPtr2<int> a_ptr;
2078
+ try{
2079
+ a_ptr.set(new int[lev]);
2080
+ S_Var_ary = a_ptr.get();
2081
+ }catch(...){
2082
+ rb_raise(rb_eRuntimeError,"memory allocation error");
2083
+ }
2084
+ int err = PF_array(a, array);
2085
+ if(err == 1){
2086
+ rb_raise(rb_eRuntimeError,"memory over flow");
2087
+ return array;
2088
+ }
2089
+ }
2090
+ return array;
2091
+ }
2092
+ /*##vsop_to_a##*/
2093
+ VALUE vsop_to_a(VALUE self){
2094
+ Vsop_Ruby* rmod;
2095
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2096
+ VALUE array = CtoI2Array(*rmod->cmod);
2097
+
2098
+ return array;
2099
+ }
2100
+ //----------------------- vsop_to_a -------------------------------
2101
+
2102
+ //----------------------- vsop_to_s -------------------------------
2103
+ static int PutNum_str(CtoI a, int base,VALUE &str)
2104
+ {
2105
+ if(a.TopItem() > 0) a = a.MaxVal();
2106
+ int d = a.TopDigit() / 3 + 14;
2107
+ kgAutoPtr2<char> a_ptr;
2108
+ char *s;
2109
+ try{
2110
+ a_ptr.set(new char[d]);
2111
+ s = a_ptr.get();
2112
+ }catch(...){
2113
+ rb_raise(rb_eRuntimeError,"memory allocation error");
2114
+ }
2115
+ int err;
2116
+ if(base == 16) err = a.StrNum16(s);
2117
+ else err = a.StrNum10(s);
2118
+ if(err == 1) return 1;
2119
+ rb_str_cat(str,s,strlen(s));
2120
+
2121
+ return 0;
2122
+ }
2123
+
2124
+ static int PF_str(CtoI a,VALUE str)
2125
+ {
2126
+ if(a.IsConst())
2127
+ {
2128
+ if(PFflag == 1){rb_str_cat(str," + ",strlen(" + "));}
2129
+ if(a.TopDigit() & 1) {rb_str_cat(str," - ",strlen(" - ")); a = -a; }
2130
+
2131
+ PFflag = 1;
2132
+ int c1 = (a != 1);
2133
+ if(c1 || Depth == 0)
2134
+ {
2135
+ if(PutNum_str(a, 10,str) == 1) return 1;
2136
+ rb_str_cat(str," ",strlen(" "));
2137
+ }
2138
+
2139
+ for(int i=0; i<Depth; i++)
2140
+ {
2141
+ char *p = VTable.GetName(S_Var[i]);
2142
+ rb_str_cat(str,p,strlen(p));
2143
+ if( i<Depth-1) rb_str_cat(str," ",strlen(" "));
2144
+ }
2145
+ return 0;
2146
+ }
2147
+ int v = a.TopItem();
2148
+ CtoI b = a.Factor1(v);
2149
+ if(b == CtoI_Null()) return 1;
2150
+ S_Var[Depth] = v;
2151
+ Depth++;
2152
+ if(PF_str(b, str) == 1) return 1;
2153
+ Depth--;
2154
+ b = a.Factor0(v);
2155
+ if(b == 0) return 0;
2156
+ if(b == CtoI_Null()) return 1;
2157
+ return PF_str(b,str);
2158
+ }
2159
+
2160
+ VALUE CtoI2String(CtoI a)
2161
+ {
2162
+ VALUE str = rb_str_new2("");
2163
+
2164
+ if(a == CtoI_Null()) return str;
2165
+ if(a == 0) return str;
2166
+ else
2167
+ {
2168
+ int lev = BDD_LevOfVar(a.TopItem());
2169
+ Depth = 0;
2170
+ kgAutoPtr2<int> a_ptr;
2171
+ try{
2172
+ a_ptr.set(new int[lev]);
2173
+ S_Var = a_ptr.get();
2174
+ }catch(...){
2175
+ rb_raise(rb_eRuntimeError,"memory allocation error");
2176
+ }
2177
+ PFflag = 0;
2178
+ int err = PF_str(a, str);
2179
+ if(err == 1){
2180
+ rb_raise(rb_eRuntimeError,"memory over flow");
2181
+ return str;
2182
+ }
2183
+ }
2184
+ return str;
2185
+ }
2186
+
2187
+ /*##vsop_to_s##*/
2188
+ VALUE vsop_to_s(VALUE self){
2189
+ Vsop_Ruby* rmod;
2190
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2191
+ VALUE str = CtoI2String(*rmod->cmod);
2192
+ return str;
2193
+ }
2194
+ //----------------------- vsop_to_s -------------------------------
2195
+
2196
+
2197
+ //----------------------- vsop_each_item -------------------------------
2198
+ static int PF_itemarray(CtoI a, VALUE& self)
2199
+ {
2200
+ int sign=1;
2201
+ if(a.IsConst())
2202
+ {
2203
+ if(a.TopDigit() & 1) {sign= -1 ; a = -a; }
2204
+ int c1 = (a != 1);
2205
+ VALUE weight;
2206
+ char *valrtn;
2207
+ kgAutoPtr2<char> a_ptr;
2208
+ if(c1 || Depth_item == 0)
2209
+ {
2210
+ if(a.TopItem() > 0) a = a.MaxVal();
2211
+ int d = a.TopDigit() / 3 + 14;
2212
+ try{
2213
+ a_ptr.set(new char[d]);
2214
+ valrtn = a_ptr.get();
2215
+ }catch(...){
2216
+ rb_raise(rb_eRuntimeError,"memory allocation error");
2217
+ }
2218
+ int err = a.StrNum10(valrtn);
2219
+ if(err == 1){
2220
+ rb_raise(rb_eRuntimeError,"memory over flow");
2221
+ return 1;
2222
+ }
2223
+ weight = INT2NUM(atoi(valrtn));
2224
+ }
2225
+ else if(!c1){
2226
+ weight = INT2NUM(1);
2227
+ }
2228
+
2229
+ VALUE top=Qtrue;
2230
+ VALUE bottom=Qfalse;
2231
+ for(int i=0; i<Depth_item; i++){
2232
+ char *str = VTable.GetName(S_Var_item[i]);
2233
+ int ckck = VTable.GetID(str);
2234
+ Vsop_Ruby* rmod=new Vsop_Ruby;
2235
+ rmod->cmod = new CtoI (CtoI(1).AffixVar(ckck)) ;
2236
+ if( i>0 ) top=Qfalse;
2237
+ if( i+1==Depth_item ) bottom=Qtrue;
2238
+ rb_yield_values(4,weight,Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod) ,top,bottom);
2239
+ }
2240
+ return 0;
2241
+ }
2242
+ int v = a.TopItem();
2243
+ CtoI b = a.Factor1(v);
2244
+ if(b == CtoI_Null()) return 1;
2245
+ S_Var_item[Depth_item] = v;
2246
+ Depth_item++;
2247
+ int chk=PF_itemarray(b, self);
2248
+ if(chk > 0) return chk;
2249
+ Depth_item--;
2250
+ b = a.Factor0(v);
2251
+ if(b == 0) return 0;
2252
+ if(b == CtoI_Null()) return 1;
2253
+ return PF_itemarray(b,self);
2254
+ }
2255
+
2256
+ void CtoI2ItemArray(CtoI a,VALUE &self)
2257
+ {
2258
+ VALUE ary = rb_ary_new();
2259
+ if(a == CtoI_Null()) return;
2260
+ if(a == 0) return;
2261
+ else
2262
+ {
2263
+ int lev = BDD_LevOfVar(a.TopItem());
2264
+ Depth_item = 0;
2265
+ kgAutoPtr2<int> a_ptr;
2266
+ try{
2267
+ a_ptr.set(new int[lev]);
2268
+ S_Var_item = a_ptr.get();
2269
+ }catch(...){
2270
+ rb_raise(rb_eRuntimeError,"memory allocation error");
2271
+ }
2272
+ PF_itemarray(a, self);
2273
+ }
2274
+ }
2275
+
2276
+ /*##vsop_each_item##*/
2277
+ VALUE vsop_each_item(VALUE self){
2278
+ Vsop_Ruby* rmod;
2279
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2280
+ CtoI2ItemArray(*rmod->cmod,self);
2281
+ return Qtrue;
2282
+ }
2283
+ //----------------------- vsop_each_item -------------------------------
2284
+
2285
+
2286
+ //この値はBDDライブラリとかぶらないよう注意すること
2287
+ // キャッシュがおかしくなる
2288
+ static const char BC_CtoI_DELTA = 50;
2289
+
2290
+ CtoI CtoI_Delta(CtoI a, CtoI b)
2291
+ {
2292
+ if(a == CtoI_Null()) return a;
2293
+ if(b == CtoI_Null()) return b;
2294
+ if(a == 0) return 0;
2295
+ if(b == 0) return 0;
2296
+ if(a == 1 && b==1) return 1;
2297
+
2298
+
2299
+ int atop = a.Top();
2300
+ int btop = b.Top();
2301
+ if(BDD_LevOfVar(atop) < BDD_LevOfVar(btop)) return CtoI_Delta(b, a);
2302
+
2303
+ bddword ax = a.GetZBDD().GetID();
2304
+ bddword bx = b.GetZBDD().GetID();
2305
+ if(atop == btop && ax < bx) return CtoI_Delta(b, a);
2306
+
2307
+ ZBDD z = BDD_CacheZBDD(BC_CtoI_DELTA, ax, bx);
2308
+ if(z != -1) return CtoI(z);
2309
+
2310
+ CtoI a0 = a.Factor0(atop);
2311
+ CtoI a1 = a.Factor1(atop);
2312
+ CtoI c;
2313
+ if(atop != btop)
2314
+ {
2315
+ if(a.IsBool()) c = CtoI_Union( CtoI_Delta(a0, b), CtoI_Delta(a1, b).AffixVar(atop) );
2316
+ else c = CtoI_Delta(a0, b) + CtoI_Delta(a1, b).TimesSysVar(atop);
2317
+ }
2318
+ else
2319
+ {
2320
+ CtoI b0 = b.Factor0(atop);
2321
+ CtoI b1 = b.Factor1(atop);
2322
+ if(a.IsBool())
2323
+ c = CtoI_Union( CtoI_Delta(a0, b0) + CtoI_Delta(a1, b1),
2324
+ (CtoI_Delta(a1, b0)+ CtoI_Delta(a0, b1)).AffixVar(atop) ) ;
2325
+ else if(atop > 1)
2326
+ c = CtoI_Delta(a0, b0)
2327
+ + (CtoI_Delta(a1, b0) + CtoI_Delta(a0, b1)).TimesSysVar(atop)
2328
+ + CtoI_Delta(a1, b1).TimesSysVar(atop-1);
2329
+ else BDDerr("CtoI_Delta(): SysVar overflow.");
2330
+ }
2331
+ BDD_CacheEnt(BC_CtoI_DELTA, ax, bx, c.GetZBDD().GetID());
2332
+ return c;
2333
+ }
2334
+
2335
+ /*##vsop_delta##*/
2336
+ VALUE vsop_delta(int argc, VALUE *argv,VALUE self){
2337
+ Vsop_Ruby* rmod;
2338
+ VALUE v;
2339
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2340
+ rb_scan_args(argc, argv,"10",&v);
2341
+ CtoI *ctoi_moda =new CtoI(*rmod->cmod);
2342
+ CtoI *ctoi_modc = value2ctoi(v);
2343
+ CtoI *ctoi_fin;
2344
+ *ctoi_moda = CtoI_Delta(*ctoi_moda, *ctoi_modc);
2345
+ ctoi_fin = ctoi_moda;
2346
+ delete ctoi_modc;
2347
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
2348
+ rmod_rtn->cmod = ctoi_fin;
2349
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
2350
+ }
2351
+
2352
+ CtoI* string2ctoi(char *str)
2353
+ {
2354
+ if(init_cnt==0){ BDDV_Init(256, env_nmax);}
2355
+ init_cnt++;
2356
+ int sep_cnt=0;
2357
+ for(char *p=str;*p;p++){
2358
+ if(*p==' '){
2359
+ sep_cnt++;
2360
+ }
2361
+ }
2362
+ sep_cnt++;
2363
+ kgAutoPtr2<CtoI> a_ptr;
2364
+ CtoI * ctoitmp;
2365
+ try{
2366
+ a_ptr.set(new CtoI[sep_cnt]);
2367
+ ctoitmp = a_ptr.get();
2368
+ }catch(...){
2369
+ rb_raise(rb_eRuntimeError,"memory allocation error");
2370
+ }
2371
+ int i=0;
2372
+ char *p,*q;
2373
+ p=str;
2374
+ q=str;
2375
+ while(1){
2376
+ if(*p==' '){//区切り文字
2377
+ *p='\0';
2378
+ int var = VTable.GetID(q);
2379
+ if(var == 0){
2380
+ if(env_warning){ num_check(q); }
2381
+ VTable.SetB(q, power16/2);
2382
+ var = VTable.GetID(q);
2383
+ }
2384
+ ctoitmp[i] = CtoI(1).AffixVar(var);
2385
+ q=p+1;
2386
+ i++;
2387
+ }
2388
+ else if(*p=='\0'){//終了時文字
2389
+ int var = VTable.GetID(q);
2390
+ if(var == 0){
2391
+ if(env_warning){ num_check(q); }
2392
+ VTable.SetB(q, power16/2);
2393
+ var = VTable.GetID(q);
2394
+ }
2395
+ ctoitmp[i] = CtoI(1).AffixVar(var);
2396
+ break;
2397
+ }
2398
+ p++;
2399
+ }
2400
+ CtoI ctmp = ctoitmp[0];
2401
+ for(int i=1;i<sep_cnt;i++){
2402
+ ctmp = Product(ctmp,ctoitmp[i]);
2403
+ }
2404
+ CtoI *rtnctoi = new CtoI(ctmp);
2405
+ return rtnctoi;
2406
+ }
2407
+
2408
+ //VALUEを受け取り、CtoI*を返す
2409
+ CtoI *value2ctoi(VALUE v)
2410
+ {
2411
+ CtoI *rtnctoi;
2412
+ Vsop_Ruby* argrmod;
2413
+ if(TYPE(v)==T_STRING){
2414
+ rtnctoi=string2ctoi(RSTRING_PTR(v));
2415
+ }
2416
+ else if(TYPE(v)==T_FIXNUM){
2417
+ rtnctoi=int2ctoi(FIX2INT(v));
2418
+ }
2419
+ else if(TYPE(v)==T_BIGNUM){
2420
+ rtnctoi=int2ctoi(NUM2INT(v));
2421
+ }
2422
+ else{
2423
+ Data_Get_Struct(v,Vsop_Ruby,argrmod);
2424
+ rtnctoi =new CtoI(*argrmod->cmod);
2425
+ }
2426
+ return rtnctoi;
2427
+ }
2428
+
2429
+ /*##vsop_symbol##*/
2430
+ VALUE vsop_symbol(int argc, VALUE *argv, VALUE self)
2431
+ {
2432
+ //引数読み込み
2433
+ VALUE rtn;
2434
+ //初回呼び出し時のみBDDの初期化
2435
+ if(init_cnt==0){ BDDV_Init(256, env_nmax);}
2436
+ init_cnt++;
2437
+
2438
+ if(argc>=1){
2439
+ int val=power16/2;
2440
+ char *to ="bottom";
2441
+ char *str;
2442
+ VALUE v1,v2,v3;
2443
+ rb_scan_args(argc, argv,"12",&v1,&v2,&v3);
2444
+ switch(argc){
2445
+ case 3:
2446
+ if(TYPE(v3)!=T_STRING){
2447
+ rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
2448
+ }
2449
+ to = RSTRING_PTR(v3);
2450
+ case 2:
2451
+ if(TYPE(v2)==T_FLOAT){
2452
+ val = (int)( NUM2DBL(v2)*power16);
2453
+ }
2454
+ else if(TYPE(v2)==T_FIXNUM){
2455
+ val = NUM2INT(v2)*power16;
2456
+ }
2457
+ else if(TYPE(v2)==T_NIL){
2458
+ }
2459
+ else{
2460
+ rb_raise(rb_eRuntimeError,"argument type error (arguments must be FLOAT or INT or NIL)");
2461
+ }
2462
+ case 1:
2463
+ if(TYPE(v1)!=T_STRING){
2464
+ rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
2465
+ }
2466
+ str = RSTRING_PTR(v1);
2467
+ //数値チェック(アイテムが数値なら警告)
2468
+ if(env_warning){ num_check(str); }
2469
+ break;
2470
+ default:
2471
+ rb_raise(rb_eRuntimeError,"argument type error");
2472
+ break;
2473
+ }
2474
+ if(*str!='\0'){
2475
+ int var = VTable.GetID(str);
2476
+ if(var == 0){
2477
+ if(!strcmp(to,"top")) { VTable.SetT(str, val);}
2478
+ else { VTable.SetB(str, val);}
2479
+ }
2480
+ }
2481
+ rtn = Qtrue;
2482
+ }
2483
+ else{
2484
+ int n = VTable.Used();
2485
+ string str ;
2486
+ for(int i=n; i>0; i--)
2487
+ {
2488
+ int var = BDD_VarOfLev(i);
2489
+ str += VTable.GetName(var);
2490
+ str += " ";
2491
+ }
2492
+ rtn = rb_str_new2(str.c_str());
2493
+ }
2494
+ return rtn;
2495
+ }
2496
+
2497
+ /*##vsop_itemset##*/
2498
+ VALUE vsop_itemset(int argc, VALUE *argv, VALUE self)
2499
+ {
2500
+ Vsop_Ruby* rmod=new Vsop_Ruby;
2501
+ VALUE v;
2502
+
2503
+ //引数読み込み
2504
+ rb_scan_args(argc, argv,"10",&v);
2505
+ if(TYPE(v)!=T_STRING){
2506
+ rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
2507
+ }
2508
+
2509
+ char *str = RSTRING_PTR(v);
2510
+ if (*str =='\0'){
2511
+ rmod->cmod = int2ctoi(1);
2512
+ }
2513
+ else{
2514
+ rmod->cmod = string2ctoi(str);
2515
+ }
2516
+
2517
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod);
2518
+ }
2519
+
2520
+ CtoI * int2ctoi(int val)
2521
+ {
2522
+ //初回呼び出し時のみBDDの初期化
2523
+ if(init_cnt==0){ BDDV_Init(256, env_nmax);}
2524
+ init_cnt++;
2525
+ char wrkval[64];
2526
+ sprintf(wrkval,"%d",val);
2527
+ CtoI *rtnctoi = new CtoI(CtoI_atoi(wrkval));
2528
+ return rtnctoi;
2529
+ }
2530
+
2531
+ /*##vsop_constant##*/
2532
+ VALUE vsop_constant(int argc, VALUE *argv, VALUE self)
2533
+ {
2534
+ Vsop_Ruby* rmod=new Vsop_Ruby;
2535
+ VALUE v;
2536
+
2537
+ //引数読み込み
2538
+ rb_scan_args(argc, argv,"10",&v);
2539
+
2540
+ CtoI ctoitmp;
2541
+ //定数FIXNUM
2542
+ if(TYPE(v)==T_FIXNUM){
2543
+ rmod->cmod = int2ctoi(FIX2INT(v));
2544
+ }
2545
+ //定数BIGNUM
2546
+ else if(TYPE(v)==T_BIGNUM){
2547
+ rmod->cmod = int2ctoi(NUM2INT(v));
2548
+ }
2549
+ else{
2550
+ rb_raise(rb_eRuntimeError,"argument type error (arguments must be FIXNUM or BIGNUM)");
2551
+ }
2552
+ VALUE rtn = Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod);
2553
+ return rtn;
2554
+ }
2555
+ // ------------------------------ パターン長制約を入れたlcm over zdd
2556
+
2557
+ VALUE vsop_lcm_nomal_ub(VALUE v1,VALUE v2,VALUE v3,VALUE v4 , VALUE self)
2558
+ {
2559
+ if(init_cnt==0){ BDDV_Init(256, env_nmax);}
2560
+ init_cnt++;
2561
+
2562
+ CtoI *ctoi_fin;
2563
+ if(TYPE(v1)!=T_STRING){
2564
+ rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
2565
+ }
2566
+ if(TYPE(v2)!=T_STRING){
2567
+ rb_raise(rb_eRuntimeError,"argument type error (2nd argument must be STRING)");
2568
+ }
2569
+ if(TYPE(v3)!=T_FIXNUM){
2570
+ rb_raise(rb_eRuntimeError,"argument type error (3rd argument must be FIXNUM)");
2571
+ }
2572
+ if(TYPE(v4)!=T_FIXNUM){
2573
+ rb_raise(rb_eRuntimeError,"argument type error (5th argument must be FIXNUM)");
2574
+ }
2575
+ char *arg1 = RSTRING_PTR(v1);
2576
+ char *arg2 = RSTRING_PTR(v2);
2577
+ int arg3_fix = FIX2INT(v3);
2578
+ int len_ub = FIX2INT(v4);
2579
+
2580
+ int len;
2581
+
2582
+ len = strlen(arg1);
2583
+ char *str_c = new char[len+3];
2584
+ sprintf(str_c,"\"%s\"",arg1);
2585
+ int len_c = len+2;
2586
+
2587
+ len = strlen(arg2);
2588
+ char *str_d = new char[len+3];
2589
+ sprintf(str_d,"\"%s\"",arg2);
2590
+ int len_d = len+2;
2591
+
2592
+ char *str_e = new char[64];
2593
+ sprintf(str_e,"%d",arg3_fix);
2594
+ str_c[len_c - 1] = 0;
2595
+ str_d[len_d - 1] = 0;
2596
+ int th = atoi(str_e);
2597
+ if(strcmp(str_c+1, "F" ) == 0) CtoI_Lcm1_ub(str_d+1, 0, th, 0, len_ub);
2598
+ else if(strcmp(str_c+1, "C" ) == 0) CtoI_Lcm1_ub(str_d+1, 0, th, 1, len_ub);
2599
+ else if(strcmp(str_c+1, "M" ) == 0) CtoI_Lcm1_ub(str_d+1, 0, th, 2, len_ub);
2600
+ else if(strcmp(str_c+1, "FQ") == 0) CtoI_Lcm1_ub(str_d+1, 0, th, 10, len_ub);
2601
+ else if(strcmp(str_c+1, "CQ") == 0) CtoI_Lcm1_ub(str_d+1, 0, th, 11, len_ub);
2602
+ else if(strcmp(str_c+1, "MQ") == 0) CtoI_Lcm1_ub(str_d+1, 0, th, 12, len_ub); //11 -> 12 by ham
2603
+ for(int i=VTable.Used(); i<CtoI_LcmItems(); i++)
2604
+ {
2605
+ int t = 1;
2606
+ char s[32];
2607
+ int x = CtoI_LcmPerm(i);
2608
+ sprintf(s, "x%d", x);
2609
+ while(VTable.GetID(s) != 0)
2610
+ {
2611
+ t++;
2612
+ sprintf(s, "x%d_%d", x, t);
2613
+ }
2614
+ VTable.SetT(s, power16/2);
2615
+ }
2616
+ CtoI a = CtoI_Lcm2();
2617
+ ctoi_fin = new CtoI(a);
2618
+ delete[] str_c;
2619
+ delete[] str_d;
2620
+ delete[] str_e;
2621
+
2622
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
2623
+ rmod_rtn->cmod = ctoi_fin;
2624
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
2625
+ }
2626
+
2627
+
2628
+ VALUE vsop_lcm_order_ub(VALUE v1,VALUE v2,VALUE v3,VALUE v4 ,VALUE v5, VALUE self)
2629
+ {
2630
+ if(init_cnt==0){ BDDV_Init(256, env_nmax);}
2631
+ init_cnt++;
2632
+
2633
+ CtoI *ctoi_fin;
2634
+ if(TYPE(v1)!=T_STRING){
2635
+ rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
2636
+ }
2637
+ if(TYPE(v2)!=T_STRING){
2638
+ rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
2639
+ }
2640
+ if(TYPE(v3)!=T_FIXNUM){
2641
+ rb_raise(rb_eRuntimeError,"argument type error (3rd argument must be FIXNUM)");
2642
+ }
2643
+ if(TYPE(v4)!=T_STRING){
2644
+ rb_raise(rb_eRuntimeError,"argument type error (4th argument must be STRING)");
2645
+ }
2646
+ if(TYPE(v5)!=T_FIXNUM){
2647
+ rb_raise(rb_eRuntimeError,"argument type error (5th argument must be FIXNUM)");
2648
+ }
2649
+ char *arg1 = RSTRING_PTR(v1);
2650
+ char *arg2 = RSTRING_PTR(v2);
2651
+ int arg3_fix = FIX2INT(v3);
2652
+ char *arg4 = RSTRING_PTR(v4);
2653
+
2654
+ int len_ub = FIX2INT(v5);
2655
+
2656
+ int len;
2657
+
2658
+ len = strlen(arg1);
2659
+ char *str_c = new char[len+3];
2660
+ sprintf(str_c,"\"%s\"",arg1);
2661
+ int len_c = len+2;
2662
+
2663
+ len = strlen(arg2);
2664
+ char *str_d = new char[len+3];
2665
+ sprintf(str_d,"\"%s\"",arg2);
2666
+ int len_d = len+2;
2667
+
2668
+ char *str_e = new char[64];
2669
+ sprintf(str_e,"%d",arg3_fix);
2670
+
2671
+ len = strlen(arg4);
2672
+ char *str_f = new char[len+3];
2673
+ sprintf(str_f,"\"%s\"",arg4);
2674
+ int len_f = len+2;
2675
+
2676
+ str_c[len_c - 1] = 0;
2677
+ str_d[len_d - 1] = 0;
2678
+ int th = atoi(str_e);
2679
+ str_f[len_f - 1] = 0;
2680
+ if(strcmp(str_c+1, "F" ) == 0) CtoI_Lcm1_ub(str_d+1, str_f+1, th, 0, len_ub);
2681
+ else if(strcmp(str_c+1, "C" ) == 0) CtoI_Lcm1_ub(str_d+1, str_f+1, th, 1, len_ub);
2682
+ else if(strcmp(str_c+1, "M" ) == 0) CtoI_Lcm1_ub(str_d+1, str_f+1, th, 2, len_ub);
2683
+ else if(strcmp(str_c+1, "FQ") == 0) CtoI_Lcm1_ub(str_d+1, str_f+1, th, 10, len_ub);
2684
+ else if(strcmp(str_c+1, "CQ") == 0) CtoI_Lcm1_ub(str_d+1, str_f+1, th, 11, len_ub);
2685
+ else if(strcmp(str_c+1, "MQ") == 0) CtoI_Lcm1_ub(str_d+1, str_f+1, th, 12, len_ub);
2686
+ for(int i=VTable.Used(); i<CtoI_LcmItems(); i++)
2687
+ {
2688
+ int t = 1;
2689
+ char s[32];
2690
+ int x = CtoI_LcmPerm(i);
2691
+ sprintf(s, "x%d", x);
2692
+ while(VTable.GetID(s) != 0)
2693
+ {
2694
+ t++;
2695
+ sprintf(s, "x%d_%d", x, t);
2696
+ }
2697
+ VTable.SetT(s, power16/2);
2698
+ }
2699
+ CtoI a = CtoI_Lcm2();
2700
+ ctoi_fin = new CtoI(a);
2701
+ delete[] str_c;
2702
+ delete[] str_d;
2703
+ delete[] str_e;
2704
+ delete[] str_f;
2705
+
2706
+
2707
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
2708
+ rmod_rtn->cmod = ctoi_fin;
2709
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
2710
+ }
2711
+
2712
+ /*##vsop_lcm##*/
2713
+ VALUE vsop_lcm(int argc, VALUE *argv, VALUE self)
2714
+ {
2715
+ VALUE rtnval;
2716
+ if(argc==3){
2717
+ rtnval = vsop_lcm_nomal(argc,argv,self);
2718
+ }
2719
+ else if(argc==4){
2720
+ rtnval = vsop_lcm_order(argc,argv,self);
2721
+ }
2722
+ else if(argc==5){
2723
+ VALUE v1,v2,v3,v4,v5;
2724
+ rb_scan_args(argc, argv,"50",&v1,&v2,&v3,&v4,&v5);
2725
+ if(TYPE(v4)!=T_STRING || strcmp(RSTRING_PTR(v4),"")==0 ){
2726
+ rtnval = vsop_lcm_nomal_ub(v1,v2,v3,v5,self);
2727
+ }
2728
+ else{
2729
+ rtnval = vsop_lcm_order_ub(v1,v2,v3,v4,v5,self);
2730
+ }
2731
+ }
2732
+ else{
2733
+ rb_raise(rb_eRuntimeError,"argument size error ");
2734
+ }
2735
+ return rtnval;
2736
+ }
2737
+
2738
+ // ------------------------------ パターン長制約を入れたlcm over zdd ここまで 2010/02/28
2739
+
2740
+ /*##vsop_same##*/
2741
+ VALUE vsop_same(int argc, VALUE *argv,VALUE self){
2742
+ Vsop_Ruby* rmod;
2743
+ VALUE v;
2744
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2745
+ rb_scan_args(argc, argv,"10",&v);
2746
+
2747
+ CtoI *ctoi_modc = value2ctoi(v);
2748
+ if ( *rmod->cmod == *ctoi_modc){
2749
+ return Qtrue;
2750
+ }
2751
+ else{
2752
+ return Qfalse;
2753
+ }
2754
+ }
2755
+
2756
+ /*##vsop_diff##*/
2757
+ VALUE vsop_diff(int argc, VALUE *argv,VALUE self){
2758
+ Vsop_Ruby* rmod;
2759
+ VALUE v;
2760
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2761
+ rb_scan_args(argc, argv,"10",&v);
2762
+
2763
+ CtoI *ctoi_modc = value2ctoi(v);
2764
+ if ( *rmod->cmod != *ctoi_modc){
2765
+ return Qtrue;
2766
+ }
2767
+ else{
2768
+ return Qfalse;
2769
+ }
2770
+ }
2771
+
2772
+ /*##vsop_print_size##*/
2773
+ VALUE vsop_print_size( VALUE self){
2774
+ Vsop_Ruby* rmod;
2775
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2776
+ int val = rmod->cmod->Size();
2777
+ return INT2NUM(val);
2778
+ }
2779
+
2780
+ /*##vsop_print_totalsize##*/
2781
+ VALUE vsop_print_totalsize(VALUE self){
2782
+ rb_gc();
2783
+ BDD_GC();
2784
+ VALUE rtn = INT2NUM(BDD_Used());
2785
+
2786
+ return rtn;
2787
+ }
2788
+
2789
+ /*##vsop_print_count##*/
2790
+ VALUE vsop_print_count( VALUE self){
2791
+ Vsop_Ruby* rmod;
2792
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2793
+ auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2794
+ CtoI *ctoitmp = auto_p.get();
2795
+ *ctoitmp = ctoitmp -> CountTerms();
2796
+ if(*ctoitmp == CtoI_Null())
2797
+ {
2798
+ *ctoitmp = 0;
2799
+ rb_raise(rb_eRuntimeError,"06Memory overflow");
2800
+ }
2801
+ int slen = ctoitmp->TopDigit() / 3 + 14;
2802
+ kgAutoPtr2<char> a_ptr;
2803
+ char *s;
2804
+ try{
2805
+ a_ptr.set(new char[slen]);
2806
+ s = a_ptr.get();
2807
+ }catch(...){
2808
+ rb_raise(rb_eRuntimeError,"memory allocation error");
2809
+ }
2810
+ ctoitmp -> StrNum10(s);
2811
+ VALUE rtn = rb_cstr_to_inum(s, 10, Qfalse);
2812
+ return rtn;
2813
+ }
2814
+
2815
+ /*##vsop_print_density##*/
2816
+ VALUE vsop_print_density( VALUE self){
2817
+ Vsop_Ruby* rmod;
2818
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2819
+ auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2820
+ CtoI *ctoitmp = auto_p.get();
2821
+
2822
+ *ctoitmp = ctoitmp -> NonZero();
2823
+ if(*ctoitmp == CtoI_Null())
2824
+ {
2825
+ *ctoitmp = 0;
2826
+ rb_raise(rb_eRuntimeError,"07Memory overflow");
2827
+ }
2828
+ int d = Density(ctoitmp -> GetZBDD(), VTable.Used());
2829
+ if(d == 0 && *ctoitmp != 0){
2830
+ rb_raise(rb_eRuntimeError,"Bit underflow occurred");
2831
+ }
2832
+ VALUE rtn = rb_float_new((float)d / power30);
2833
+ return rtn;
2834
+ }
2835
+
2836
+ /*##vsop_print_value##*/
2837
+ VALUE vsop_print_value( VALUE self){
2838
+ Vsop_Ruby* rmod;
2839
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2840
+ auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2841
+ CtoI *ctoitmp = auto_p.get();
2842
+
2843
+ if(OVF.Check()!= 0){
2844
+ rb_raise(rb_eRuntimeError,"Bit overflow occurred");
2845
+ }
2846
+ VALUE rtn = rb_float_new((float)Value(*ctoitmp)/power16);
2847
+ return rtn;
2848
+ }
2849
+
2850
+ /*##vsop_print_maxcover##*/
2851
+ VALUE vsop_print_maxcover(VALUE self){
2852
+ Vsop_Ruby* rmod;
2853
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2854
+
2855
+ CtoI *ctoi_fin;
2856
+
2857
+ auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2858
+ CtoI *ctoitmp = auto_p.get();
2859
+
2860
+ *ctoitmp = ctoitmp -> NonZero();
2861
+ if(*ctoitmp == CtoI_Null())
2862
+ {
2863
+ *ctoitmp = 0;
2864
+ ctoi_fin = new CtoI(0);
2865
+ rb_raise(rb_eRuntimeError,"08Memory overflow");
2866
+ }
2867
+ if(*ctoitmp == 0){
2868
+ ctoi_fin = new CtoI(0);
2869
+ }
2870
+ else
2871
+ {
2872
+ ZBDD f = ctoitmp -> GetZBDD();
2873
+ if(MaxCost(f)==0){
2874
+ ctoi_fin = new CtoI(1);
2875
+ }
2876
+ else
2877
+ {
2878
+ CtoI ctmp(1);
2879
+ while(1)
2880
+ {
2881
+ int var = f.Top();
2882
+ if(var == 0) break;
2883
+ ZBDD f0 = f.OffSet(var);
2884
+ ZBDD f1 = f.OnSet0(var);
2885
+ int c1 = MaxCost(f1) + VTable.GetValue(var);
2886
+ if(MaxCost(f0) < c1)
2887
+ {
2888
+ f = f1;
2889
+ ctmp = ctmp.AffixVar(var);
2890
+ }
2891
+ else f = f0;
2892
+ }
2893
+ ctoi_fin = new CtoI(ctmp);
2894
+ }
2895
+ }
2896
+
2897
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
2898
+ rmod_rtn->cmod = ctoi_fin;
2899
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
2900
+ }
2901
+
2902
+ /*##vsop_print_maxcost##*/
2903
+ VALUE vsop_print_maxcost( VALUE self){
2904
+ Vsop_Ruby* rmod;
2905
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2906
+ auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2907
+ CtoI *ctoitmp = auto_p.get();
2908
+
2909
+ *ctoitmp = ctoitmp -> NonZero();
2910
+ if(*ctoitmp == CtoI_Null())
2911
+ {
2912
+ *ctoitmp = 0;
2913
+ rb_raise(rb_eRuntimeError,"09Memory overflow");
2914
+ }
2915
+ VALUE rtn;
2916
+ if(*ctoitmp == 0){
2917
+ rtn = Qnil;
2918
+ }
2919
+ else
2920
+ {
2921
+ int c = MaxCost(ctoitmp -> GetZBDD());
2922
+ rtn = rb_float_new((float)c/power16);
2923
+ }
2924
+ return rtn;
2925
+ }
2926
+
2927
+ /*##vsop_print_mincover##*/
2928
+ VALUE vsop_print_mincover( VALUE self){
2929
+ Vsop_Ruby* rmod;
2930
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2931
+
2932
+ CtoI *ctoi_fin;
2933
+
2934
+ auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2935
+ CtoI *ctoitmp = auto_p.get();
2936
+
2937
+ *ctoitmp = ctoitmp -> NonZero();
2938
+ if(*ctoitmp == CtoI_Null())
2939
+ {
2940
+ *ctoitmp = 0;
2941
+ ctoi_fin = new CtoI(0);
2942
+ rb_raise(rb_eRuntimeError,"10Memory overflow");
2943
+ }
2944
+ if(*ctoitmp == 0){
2945
+ ctoi_fin = new CtoI(0);
2946
+ }
2947
+ else
2948
+ {
2949
+ ZBDD f = ctoitmp -> GetZBDD();
2950
+ if(MinCost(f)==0){
2951
+ ctoi_fin = new CtoI(1);
2952
+ }
2953
+ else
2954
+ {
2955
+ CtoI ctmp(1);
2956
+ while(1)
2957
+ {
2958
+ int var = f.Top();
2959
+ if(var == 0) break;
2960
+ ZBDD f0 = f.OffSet(var);
2961
+ ZBDD f1 = f.OnSet0(var);
2962
+ int c1 = MinCost(f1) + VTable.GetValue(var);
2963
+ if(MinCost(f0) > c1)
2964
+ {
2965
+ f = f1;
2966
+ ctmp = ctmp.AffixVar(var);
2967
+ }
2968
+ else f = f0;
2969
+ }
2970
+ ctoi_fin = new CtoI(ctmp);
2971
+ }
2972
+ }
2973
+ Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
2974
+ rmod_rtn->cmod = ctoi_fin;
2975
+ return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
2976
+ }
2977
+
2978
+ /*##vsop_print_mincost##*/
2979
+ VALUE vsop_print_mincost( VALUE self){
2980
+ Vsop_Ruby* rmod;
2981
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
2982
+ auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2983
+ CtoI *ctoitmp = auto_p.get();
2984
+
2985
+ *ctoitmp = ctoitmp -> NonZero();
2986
+ if(*ctoitmp == CtoI_Null())
2987
+ {
2988
+ *ctoitmp = 0;
2989
+ rb_raise(rb_eRuntimeError,"11Memory overflow");
2990
+ }
2991
+ VALUE rtn;
2992
+ if(*ctoitmp == 0){
2993
+ rtn = Qnil;
2994
+ }
2995
+ else
2996
+ {
2997
+ int c = MinCost(ctoitmp -> GetZBDD());
2998
+ rtn = rb_float_new((float)c/power16);
2999
+ }
3000
+ return rtn;
3001
+ }
3002
+
3003
+ /*##vsop_print_decomp##*/
3004
+ VALUE vsop_print_decomp(int argc, VALUE *argv, VALUE self){
3005
+ Vsop_Ruby* rmod;
3006
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
3007
+ VALUE *v;
3008
+ rb_scan_args(argc, argv,"01",&v);
3009
+ if(argc!=0){
3010
+ if(TYPE(v)==T_STRING){
3011
+ char *str = RSTRING_PTR(v);
3012
+ bout.Set(str);
3013
+ }
3014
+ else{
3015
+ rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
3016
+ }
3017
+ }
3018
+
3019
+ auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
3020
+ CtoI *ctoitmp = auto_p.get();
3021
+
3022
+ if(PrintDecomp(*ctoitmp) == 1)
3023
+ {
3024
+ rb_raise(rb_eRuntimeError,"12Memory overflow");
3025
+ }
3026
+ bout.Unset();
3027
+ return self;
3028
+ }
3029
+
3030
+ /*##vsop_print_export##*/
3031
+ VALUE vsop_print_export(int argc, VALUE *argv, VALUE self){
3032
+ Vsop_Ruby* rmod;
3033
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
3034
+ auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
3035
+ CtoI *ctoitmp = auto_p.get();
3036
+ FILE *fp=NULL;
3037
+ if(argc==1){
3038
+ VALUE v1;
3039
+ rb_scan_args(argc, argv,"0*",&v1);
3040
+ if(TYPE(RARRAY_PTR(v1)[0])==T_STRING){
3041
+ char *str = RSTRING_PTR(RARRAY_PTR(v1)[0]);
3042
+ fp = fopen(str, "w");
3043
+ if(fp == NULL){
3044
+ rb_raise(rb_eRuntimeError,"Can't open the file");
3045
+ }
3046
+ }
3047
+ else{
3048
+ rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
3049
+ }
3050
+ }
3051
+ else if(argc!=0){
3052
+ rb_raise(rb_eRuntimeError,"number of argument is 0 or 1 ");
3053
+ }
3054
+
3055
+ int d = ctoitmp -> TopDigit();
3056
+ ZBDDV v = ZBDDV();
3057
+ for(int i=0; i<=d; i++){
3058
+ v += ZBDDV(ctoitmp -> Digit(i).GetZBDD(), i);
3059
+ }
3060
+
3061
+ if(fp){
3062
+ v.Export(fp);
3063
+ fclose(fp);
3064
+ }else{
3065
+ v.Export();
3066
+ }
3067
+ return self;
3068
+ }
3069
+
3070
+
3071
+ static char* show_use_para[][2]={
3072
+ {"hex","/hex"},
3073
+ {"bit", "/bit"},
3074
+ {"case", "/case"},
3075
+ {"map", "/map"},
3076
+ {"rmap", "/rmap"},
3077
+ {"decomp", "/decomp"},
3078
+ {"",""}
3079
+ };
3080
+
3081
+ static char* show_notuse_para[]={
3082
+ "size", "count", "density", "value", "maxcover", "maxcost", "mincover",
3083
+ "mincost", "plot","decompd", "imply0","symmetry",
3084
+ "imply", "coimply0", "coimply2", "coimply","export",
3085
+ "/size", "/count", "/density", "/value", "/maxcover",
3086
+ "/maxcost", "/mincover", "/mincost","/plot",
3087
+ "/decompd", "/imply0", "/symmetry", "/imply",
3088
+ "/coimply0", "/coimply2", "/coimply", "/export",""
3089
+ };
3090
+
3091
+ /*##vsop_show##*/
3092
+ VALUE vsop_show(int argc, VALUE *argv, VALUE self){
3093
+ // bit,hex,map,rmap,case,decompのみ動くようにする
3094
+ VALUE rtnval;
3095
+ if(argc == 0){
3096
+ rtnval = vsop_print(self);
3097
+ }
3098
+ else if(argc == 1) {
3099
+ VALUE v;
3100
+ rb_scan_args(argc, argv,"10",&v);
3101
+ if(TYPE(v)!=T_STRING){
3102
+ rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
3103
+ }
3104
+ char *argtmp = RSTRING_PTR(v);
3105
+ for(size_t i=0;*show_use_para[i][0]!='\0';i++){
3106
+ if( !strcmp(argtmp,show_use_para[i][0])||
3107
+ !strcmp(argtmp,show_use_para[i][1])){
3108
+ rtnval = vsop_print_arg1(self,show_use_para[i][0]);
3109
+ return rtnval;
3110
+ }
3111
+ }
3112
+ bool output = true;
3113
+ for(const char *p=*show_notuse_para ;*p!='\0';p++){
3114
+ if( !strcmp(argtmp,p)){
3115
+ output=false;
3116
+ break;
3117
+ }
3118
+ }
3119
+ if(output){
3120
+ rtnval = vsop_print_arg1(self,argtmp);
3121
+ return rtnval;
3122
+ }
3123
+ rb_raise(rb_eRuntimeError,"Illegal switch(/bit,/hex,/map,/rmap,/case,/decomp)");
3124
+ }
3125
+ else if(argc == 2)
3126
+ {
3127
+ VALUE v1,v2;
3128
+ rb_scan_args(argc, argv,"20",&v1,&v2);
3129
+ char *argtmp = RSTRING_PTR(v1);
3130
+ for(size_t i=0;*show_use_para[i][0]!='\0';i++){
3131
+ if( !strcmp(argtmp,show_use_para[i][0])||
3132
+ !strcmp(argtmp,show_use_para[i][1])){
3133
+ rtnval = vsop_print_arg2(argc,argv,self);
3134
+ return rtnval;
3135
+ }
3136
+ }
3137
+ rb_raise(rb_eRuntimeError,"parameter error(/bit,/hex,/map,/rmap,/case,/decomp)");
3138
+ }
3139
+ else{
3140
+ rb_raise(rb_eRuntimeError,"number of argument is 0 or 1 or 2");
3141
+ }
3142
+ return rtnval;
3143
+ }
3144
+
3145
+ /*##vsop_partly##*/
3146
+ VALUE vsop_partly(VALUE self){
3147
+ return rb_iv_get(self,"@partly");
3148
+ }
3149
+
3150
+ //強制変換用
3151
+ VALUE vsop_coerce(int argc, VALUE *argv, VALUE self){
3152
+ VALUE v;
3153
+ Vsop_Ruby* rmod=new Vsop_Ruby;
3154
+ rb_scan_args(argc, argv,"10",&v);
3155
+ rmod->cmod =value2ctoi(v);
3156
+ VALUE rtn_v = Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod);
3157
+ return rb_ary_new3(2,rtn_v,self);
3158
+ }
3159
+
3160
+ /*##vsop_const_to_i##*/
3161
+ VALUE vsop_const_to_i(VALUE self){
3162
+ Vsop_Ruby* rmod;
3163
+ Data_Get_Struct(self,Vsop_Ruby,rmod);
3164
+
3165
+ CtoI a = *(rmod->cmod);
3166
+
3167
+ if(a.IsConst()){
3168
+ if(a.TopItem() > 0) a = a.MaxVal();
3169
+ int d = a.TopDigit() / 3 + 14;
3170
+ kgAutoPtr2<char> a_ptr;
3171
+ char *s;
3172
+ try{
3173
+ a_ptr.set(new char[d]);
3174
+ s = a_ptr.get();
3175
+ }catch(...){
3176
+ rb_raise(rb_eRuntimeError,"memory allocation error");
3177
+ }
3178
+ int err = a.StrNum10(s);
3179
+ if (err) { rb_raise(rb_eRuntimeError,"StrNum10 error"); }
3180
+ return rb_cstr2inum(s,10);
3181
+ }else{
3182
+ return Qnil;
3183
+ }
3184
+ }
3185
+
3186
+ void Init_zdd_so() {
3187
+ /*##zdd##*/
3188
+
3189
+ //環境変数取得
3190
+ char *envStr;
3191
+ envStr=getenv("ZDDLimitNode");
3192
+ if(envStr!=NULL){
3193
+ env_nmax=atoi(envStr);
3194
+ }else{
3195
+ env_nmax=DEF_ENV_NMAX ;
3196
+ }
3197
+ envStr=getenv("ZDDWarning");
3198
+ if(envStr!=NULL){
3199
+ env_warning=true;
3200
+ }else{
3201
+ env_warning=false;
3202
+ }
3203
+
3204
+
3205
+ VALUE vsop_main=rb_define_module("ZDD");
3206
+
3207
+ rb_iv_set(vsop_main,"@partly", Qfalse );
3208
+
3209
+ //モジュール変数設定
3210
+ rb_define_module_function(vsop_main, "itemset", RUBY_METHOD_FUNC(vsop_itemset), -1);
3211
+ rb_define_module_function(vsop_main, "constant", RUBY_METHOD_FUNC(vsop_constant), -1);
3212
+ rb_define_module_function(vsop_main, "symbol", RUBY_METHOD_FUNC(vsop_symbol), -1);
3213
+ rb_define_module_function(vsop_main, "each", RUBY_METHOD_FUNC(vsop_each), 0);
3214
+ rb_define_module_function(vsop_main, "each_item", RUBY_METHOD_FUNC(vsop_each_item), 0);
3215
+
3216
+ rb_define_module_function(vsop_main, "show", RUBY_METHOD_FUNC(vsop_show), -1);
3217
+ rb_define_module_function(vsop_main, "lcm", RUBY_METHOD_FUNC(vsop_lcm), -1);
3218
+ rb_define_module_function(vsop_main, "permit", RUBY_METHOD_FUNC(vsop_permit), -1);
3219
+ rb_define_module_function(vsop_main, "permitsym", RUBY_METHOD_FUNC(vsop_permitsym), -1);
3220
+ rb_define_module_function(vsop_main, "restrict", RUBY_METHOD_FUNC(vsop_restrict), -1);
3221
+ rb_define_module_function(vsop_main, "freqpatC", RUBY_METHOD_FUNC(vsop_freqpatC), -1);
3222
+ rb_define_module_function(vsop_main, "freqpatM", RUBY_METHOD_FUNC(vsop_freqpatM), -1);
3223
+ rb_define_module_function(vsop_main, "freqpatA", RUBY_METHOD_FUNC(vsop_freqpatA), -1);
3224
+ rb_define_module_function(vsop_main, "termsLE", RUBY_METHOD_FUNC(vsop_termsLE), -1);
3225
+ rb_define_module_function(vsop_main, "termsLT", RUBY_METHOD_FUNC(vsop_termsLT), -1);
3226
+ rb_define_module_function(vsop_main, "termsGE", RUBY_METHOD_FUNC(vsop_termsGE), -1);
3227
+ rb_define_module_function(vsop_main, "termsGT", RUBY_METHOD_FUNC(vsop_termsGT), -1);
3228
+ rb_define_module_function(vsop_main, "termsNE", RUBY_METHOD_FUNC(vsop_termsNE), -1);
3229
+ rb_define_module_function(vsop_main, "termsEQ", RUBY_METHOD_FUNC(vsop_termsEQ), -1);
3230
+
3231
+ rb_define_module_function(vsop_main, "<=", RUBY_METHOD_FUNC(vsop_le), -1);
3232
+ rb_define_module_function(vsop_main, "<", RUBY_METHOD_FUNC(vsop_lt), -1);
3233
+ rb_define_module_function(vsop_main, ">=", RUBY_METHOD_FUNC(vsop_ge), -1);
3234
+ rb_define_module_function(vsop_main, ">", RUBY_METHOD_FUNC(vsop_gt), -1);
3235
+ rb_define_module_function(vsop_main, "ne?", RUBY_METHOD_FUNC(vsop_ne), -1);
3236
+ rb_define_module_function(vsop_main, "==", RUBY_METHOD_FUNC(vsop_eq), -1);
3237
+ rb_define_module_function(vsop_main, "iif", RUBY_METHOD_FUNC(vsop_iif), -1);
3238
+ rb_define_module_function(vsop_main, "meet", RUBY_METHOD_FUNC(vsop_meet), -1);
3239
+ rb_define_module_function(vsop_main, "same?", RUBY_METHOD_FUNC(vsop_same), -1);
3240
+ rb_define_module_function(vsop_main, "===", RUBY_METHOD_FUNC(vsop_same), -1);
3241
+ rb_define_module_function(vsop_main, "diff?", RUBY_METHOD_FUNC(vsop_diff), -1);
3242
+ rb_define_module_function(vsop_main, "delta", RUBY_METHOD_FUNC(vsop_delta), -1);
3243
+
3244
+ rb_define_module_function(vsop_main, "+", RUBY_METHOD_FUNC(vsop_plus), -1);
3245
+ rb_define_module_function(vsop_main, "-", RUBY_METHOD_FUNC(vsop_minus), -1);
3246
+ rb_define_module_function(vsop_main, "+@", RUBY_METHOD_FUNC(vsop_plus_op), 0);
3247
+ rb_define_module_function(vsop_main, "-@", RUBY_METHOD_FUNC(vsop_minus_op), 0);
3248
+ rb_define_module_function(vsop_main, "*", RUBY_METHOD_FUNC(vsop_multiply), -1);
3249
+ rb_define_module_function(vsop_main, "/", RUBY_METHOD_FUNC(vsop_quotiment), -1);
3250
+ rb_define_module_function(vsop_main, "%", RUBY_METHOD_FUNC(vsop_remainder), -1);
3251
+ rb_define_module_function(vsop_main, "csvout", RUBY_METHOD_FUNC(vsop_csvout), -1);
3252
+ rb_define_module_function(vsop_main, "import", RUBY_METHOD_FUNC(vsop_import), -1);
3253
+ rb_define_module_function(vsop_main, "hashout", RUBY_METHOD_FUNC(vsop_hashout), 0);
3254
+ rb_define_module_function(vsop_main, "maxweight", RUBY_METHOD_FUNC(vsop_maxval), 0);
3255
+ rb_define_module_function(vsop_main, "minweight", RUBY_METHOD_FUNC(vsop_minval), 0);
3256
+ rb_define_module_function(vsop_main,"totalweight", RUBY_METHOD_FUNC(vsop_totalval), 0);
3257
+ rb_define_module_function(vsop_main, "items", RUBY_METHOD_FUNC(vsop_items), 0);
3258
+ rb_define_module_function(vsop_main, "symgrp", RUBY_METHOD_FUNC(vsop_symgrp), 0);
3259
+
3260
+ rb_define_module_function(vsop_main, "size", RUBY_METHOD_FUNC(vsop_print_size), 0);
3261
+ rb_define_module_function(vsop_main, "totalsize", RUBY_METHOD_FUNC(vsop_print_totalsize), 0);
3262
+ rb_define_module_function(vsop_main, "count", RUBY_METHOD_FUNC(vsop_print_count), 0);
3263
+ rb_define_module_function(vsop_main, "density", RUBY_METHOD_FUNC(vsop_print_density), 0);
3264
+ rb_define_module_function(vsop_main, "cost", RUBY_METHOD_FUNC(vsop_print_value), 0);
3265
+ rb_define_module_function(vsop_main, "maxcover", RUBY_METHOD_FUNC(vsop_print_maxcover), 0);
3266
+ rb_define_module_function(vsop_main, "maxcost", RUBY_METHOD_FUNC(vsop_print_maxcost), 0);
3267
+ rb_define_module_function(vsop_main, "mincover", RUBY_METHOD_FUNC(vsop_print_mincover), 0);
3268
+ rb_define_module_function(vsop_main, "mincost", RUBY_METHOD_FUNC(vsop_print_mincost), 0);
3269
+ rb_define_module_function(vsop_main, "export", RUBY_METHOD_FUNC(vsop_print_export), -1);
3270
+ rb_define_module_function(vsop_main, "partly", RUBY_METHOD_FUNC(vsop_partly), 0);
3271
+ rb_define_module_function(vsop_main, "coerce", RUBY_METHOD_FUNC(vsop_coerce), -1);
3272
+ rb_define_module_function(vsop_main, "to_i", RUBY_METHOD_FUNC(vsop_const_to_i), 0);
3273
+ rb_define_module_function(vsop_main, "to_a", RUBY_METHOD_FUNC(vsop_to_a), 0);
3274
+ rb_define_module_function(vsop_main, "to_s", RUBY_METHOD_FUNC(vsop_to_s), 0);
3275
+ rb_define_module_function(vsop_main, "inspect", RUBY_METHOD_FUNC(vsop_to_s), 0);
3276
+
3277
+ }