OSDN Git Service

zdd overflow対策
[nysol/mining.git] / zdd / lib / gensrc_rb_org
1 #!/usr/bin/env ruby
2 # encoding: utf-8
3
4 #パターン&ソースの登録
5 func = Hash.new()
6
7 func['| expr QUESTION expr COLON expr'] =<<'SCP_EOF'
8 "
9 /*
10  * call-seq:
11  * zdd1.iif(zdd2,zdd3) -> ZDD Object : 条件演算
12  *
13  *  zdd1,zdd2,zdd3,zdd4 : ZDD Object
14  *
15  * === 説明
16  *  zdd1に含まれるアイテム集合については、zdd2の項を選択し、それ以外のアイテム集合についてはzdd3の項を選択する。
17  *  (a+b).iif(2a+3b+4c+5d,3a+4b+5c+6d) -> 2a+3b+5c+6d # zdd1に含まれるアイテム集合a,bは、zdd2の項2a,3bを選択し、それ以外はzdd3の項5c,6dを選択する。
18  *
19  * 典型的には比較演算子と組み合わせて以下のように利用する。
20  *  > x.show # -> 3a+2b+2c
21  *  > y.show # -> 2a+2b+4c
22  *  # (x,yが上記の通り定義されていたとする)
23  *
24  *  # xとyを比較し、yより大きい重みを持つ項をxから、それ以外をyから選ぶ。
25  *  # x>yの結果はaであり、第1引数xから3aが選択され、その他のアイテム集合は第2引数yから2b,4cが選ばれる。
26  *  > (x>y).iif(x,y) # -> 3a+2b+4c
27  *
28  *  # xとyを比較し、yより大きい重みを持つ項をxから選ぶ。
29  *  # 上の例と同様であるが、第2引数が0なのでa以外のアイテム集合は何も選択されない。
30  *  > (x>y).iif(x,0) # -> 3a
31  *
32  *  # xとyを比較し、yと同じ重みを持つ項をxから選ぶ。
33  *  > (x==y).iif(x,0) # -> 2b
34  * ----
35  * ====== 上記の例において出力結果を示したコメントでは、アイテムをアルファベット小文字1文字で表し、項における重みとアイテム間のスペースおよびアイテム間のスペースを省略して表記している。
36  */
37
38 VALUE vsop_iif(int argc, VALUE *argv,VALUE self){
39         Vsop_Ruby* rmod;
40         VALUE v1;
41         VALUE v2;
42         Data_Get_Struct(self,Vsop_Ruby,rmod);
43         rb_scan_args(argc, argv,\"20\",&v1,&v2);
44         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
45         CtoI *ctoi_modc = value2ctoi(v1);
46         CtoI *ctoi_mode = value2ctoi(v2);
47         CtoI *ctoi_fin; 
48         #{pgm_src}
49         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
50         rmod_rtn->cmod = ctoi_fin;
51         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
52 }
53 "
54 SCP_EOF
55
56 func['| expr MEET expr'] =<<'SCP_EOF'
57 "
58 /*
59  * call-seq:
60  * zdd1.meet(zdd2) -> ZDD Object : meet演算
61  *
62  *  zdd1,zdd2 : ZDD Object
63  *
64  * === 説明
65  *  zdd1に含まれるアイテム集合αとzdd2に含まれるアイテム集合βの共通集合α∩βを求める。
66  *  例えば、アイテム集合abc と bcd の共通集合は以下の通り。
67  *   abc.meet(bcd) = abc ∩ bcd = bc
68  *  複数のアイテム集合間の演算では全組合せについて共通集合を求める。
69  *  (abc + a).meet(bcd + b) = abc ∩ bcd + abc ∩ b + a ∩ bcd + a ∩ b
70  *                          = bc        + b       + 1       + 1
71  *                          = bc + b + 2
72  *  重みについては、同じアイテム集合を複数に展開して計算すればよい。
73  *  (2abc).meet(bcd) = (abc+abc).meet(bcd) = bc + bc = 2bc
74  *
75  * === 例
76  *  > a=VSOP.itemset(\"a\")
77  *  > b=VSOP.itemset(\"b\")
78  *  > f=a+2*a*b+3*b
79  *  
80  *  # a + 2ab + 3b の各アイテム集合と引き数で指定されたアイテム集合 a との共通集合を求めると、
81  *  # a + 2a + 3 = 3 a + 3となる。
82  *  > f.meet(a).show
83  *  3 a + 3
84  *
85  *  # アイテム集合bとの共通集合を求めると 1 + 2b + 3b = 5b + 1 となる。
86  *  > f.meet(b).show
87  *  5 b + 1
88  *
89  *  # アイテム集合 ab との共通集合を求めると a + 2ab + 3b となる。
90  *  > f.meet(a*b).show
91  *  2 a b + a + 3 b
92  *
93  *  # 定数1は空のアイテム集合なので、それとの共通集合を求めると係数だけが残り 1 + 2 + 3 = 6 となる。
94  *  > f.meet(1).show
95  *  6
96  *  > exit
97  *
98  *  > a=VSOP.itemset(\"a\")
99  *  > b=VSOP.itemset(\"b\")
100  *  > c=VSOP.itemset(\"c\")
101  *  >
102  *  > f=((a*b*c)+2*(a*b)+(b*c)+1)
103  *  > f.show
104  *   a b c + 2 a b + b c + 1
105  *
106  *  > g=2*a*b + a
107  *  > g.show
108  *   a b + a
109  *  # abc + 2ab + bc + 1 の各アイテム集合と引き数で指定された 2ab + a の各アイテム集合との共通集合を求めると、
110  *  # 以下の通りとなる(アイテム間のスペースは省略)。
111  *  # abc ∩ 2ab = 2ab
112  *  # 2ab ∩ 2ab = 4ab
113  *  # bc  ∩ 2ab = 2b
114  *  # 1   ∩ 2ab = 2
115  *  # abc ∩ a   = a
116  *  # 2ab ∩ a   = 2a
117  *  # bc  ∩ a   = 1
118  *  # 1   ∩ a   = 1
119  *  # 結果をまとめると 6ab + 3a + 2b + 4 となる。
120  *  #
121  *  > f.meet(g).show
122  *   6 a b + 3 a + 2 b + 4
123  * ----
124  * ====== 上記の例において出力結果を示したコメントでは、アイテムをアルファベット小文字1文字で表し、項における重みとアイテム間のスペースおよびアイテム間のスペースを省略して表記している。
125  */
126
127 VALUE vsop_meet(int argc, VALUE *argv,VALUE self){
128         Vsop_Ruby* rmod;
129         VALUE v;
130         Data_Get_Struct(self,Vsop_Ruby,rmod);
131         rb_scan_args(argc, argv,\"10\",&v);
132         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
133         CtoI *ctoi_modc = value2ctoi(v);
134         CtoI *ctoi_fin; 
135         #{pgm_src}
136         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
137         rmod_rtn->cmod = ctoi_fin;
138         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
139 }
140 "
141 SCP_EOF
142
143 func['| expr NE expr'] =<<'SCP_EOF'
144 "
145 /*
146  * call-seq:
147  * zdd1.ne?(zdd2) -> ZDD Object : 不等比較演算
148  *
149  *  zdd1,zdd2 : ZDD Object
150  *
151  * === 説明
152  * zdd1に含まれるアイテム集合とzdd2に含まれるアイテム集合を比較し、重みが異なるアイテム集合を選択する。
153  *  詳しくは==演算子を参照のこと。
154  *
155  * === 関連
156  *  ==, >=, >, <=, <, iif
157  */
158
159 VALUE vsop_ne(int argc, VALUE *argv,VALUE self){
160         Vsop_Ruby* rmod;
161         VALUE v;
162         Data_Get_Struct(self,Vsop_Ruby,rmod);
163         rb_scan_args(argc, argv,\"10\",&v);
164         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
165         CtoI *ctoi_modc = value2ctoi(v);
166         CtoI *ctoi_fin; 
167         #{pgm_src}
168         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
169         rmod_rtn->cmod = ctoi_fin;
170         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
171 }
172 "
173 SCP_EOF
174
175 func['| print QUOTIENT IDVAR expr'] =<<'SCP_EOF'
176 "
177 VALUE vsop_print_arg1(VALUE self,char *arg){
178         Vsop_Ruby* rmod;
179 //      VALUE v;
180         Data_Get_Struct(self,Vsop_Ruby,rmod);
181         CtoI *ctoi_modd =new CtoI(*rmod->cmod);
182         int len = strlen(arg);
183         char *str_c;
184         str_c = new char[len+1];
185         strcpy(str_c,arg);              
186         #{pgm_src}
187         return self;
188 }
189
190 "
191 SCP_EOF
192
193
194 func['| print QUOTIENT IDVAR FNAME expr'] =<<'SCP_EOF'
195 "
196 VALUE vsop_print_arg2(int argc, VALUE *argv, VALUE self){
197         Vsop_Ruby* rmod;
198         VALUE v1,v2;
199         Data_Get_Struct(self,Vsop_Ruby,rmod);
200         CtoI *ctoi_mode =new CtoI(*rmod->cmod);
201         rb_scan_args(argc, argv,\"20\",&v1,&v2);
202         if(TYPE(v1)!=T_STRING){
203                 rb_raise(rb_eRuntimeError,\"argument type error (1st argument must be STRING)\");
204         }
205         if(TYPE(v2)!=T_STRING){
206                 rb_raise(rb_eRuntimeError,\"argument type error (2nd argument must be STRING)\");
207         }
208         char *arg1=RSTRING_PTR(v1);
209         char *arg2=RSTRING_PTR(v2);
210
211         int len;
212         len = strlen(arg1);
213         char *str_c;
214         if(*arg1=='/'){
215                 str_c = new char[len];
216                 strcpy(str_c,arg1+1);
217         }
218         else{
219                 str_c = new char[len+1];
220                 strcpy(str_c,arg1);             
221         }
222
223         len = strlen(arg2);
224         char *str_d = new char[len+3];
225         sprintf(str_d,\"\\\"%s\\\"\",arg2);
226         int len_d = len+2;
227
228         #{pgm_src}
229         return self;
230 }
231 "
232 SCP_EOF
233
234
235 func['| IMPORT LPAREN FNAME RPAREN'] =<<'SCP_EOF'
236 "
237 /*
238  * call-seq:
239  * VSOP.import(fileName) -> ZDD Object : ZDDのインポート
240  *
241  *  fileName : Ruby String
242  *
243  * === 説明
244  *  exportメソッドで出力されたZDDファイル(fileNameで指定)をインポートしZDDオブジェクトを復元する。
245  *  exportする時のsymbolによるアイテムの宣言順序とimportする時の宣言順序は同じでなければならない。
246  *
247  * === 例
248  *
249  *  # まずZDDオブジェクトfをファイル\"dat.zdd\"にエキスポートする。
250  *  > VSOP.symbol(\"a\")
251  *  > VSOP.symbol(\"b\")
252  *  > VSOP.symbol(\"c\")
253  *  > f=5*a*b*c+3*a*b+2*b*c+c
254  *  > f.show
255  *   5 a b c + 3 a b + 2 b c + c
256  *  > f.export(\"dat.zdd\")
257  *  > exit
258  *
259  *  # エキスポートされたファイル内容は以下の通り。
260  *  $ more xxa
261  *   _i 3
262  *   _o 3
263  *   _n 7
264  *   4 1 F T
265  *   248 2 F 5
266  *   276 3 4 248
267  *   232 2 F 4
268  *   2 2 F T
269  *   272 3 232 2
270  *   268 3 232 248
271  *   276
272  *   272
273  *   268
274  *
275  *  # 以下のようにsymbolを宣言した後にimportすれば正しく復元される。
276  *  > VSOP.symbol(\"a\")
277  *  > VSOP.symbol(\"b\")
278  *  > VSOP.symbol(\"c\")
279  *  > f=VSOP.import(\"dat.zdd\")
280  *  > f.show
281  *   5 a b c + 3 a b + 2 b c + c
282  *  > exit
283  *
284  *  # もしアイテムb,cの宣言順序を入れ替えると結果においてもbとcが入れ替わってしまう。
285  *  > VSOP.symbol(\"a\")
286  *  > VSOP.symbol(\"c\")
287  *  > VSOP.symbol(\"b\")
288  *  > f=VSOP.import(\"dat.zdd\")
289  *  > f.show
290  *   5 a c b + 3 a c + 2 c b + b
291  *  > exit
292  *
293  *  # 宣言せずにインポートすると、x1,x2,x3のようなアイテム名が使われる。
294  *  # この時、各アイテムの後ろに付いた数字は、アイテムの宣言の逆順による連番となる。
295  *  # 以下の例では、x1=c, x2=b, x3=cである。
296  *  > VSOP.import(\"dat.zdd\")
297  *  > f.show
298  *   5 x3 x2 x1 + 3 x3 x2 + 2 x2 x1 + x1
299  *  > exit
300  */
301
302 VALUE vsop_import(int argc, VALUE *argv, VALUE self){
303         VALUE v;
304         CtoI *ctoi_fin; 
305 /*
306         VALUE vz = rb_cv_get(self,\"@@init_cnt\");
307         int init_cnt_v =  NUM2INT(vz);
308         if(init_cnt_v==0){ BDDV_Init(256, env_nmax);}
309         init_cnt_v++;
310         rb_cv_set(self,\"@@init_cnt\",INT2NUM(init_cnt_v));
311 */
312         if(init_cnt==0){ BDDV_Init(256, env_nmax);}
313         init_cnt++;
314
315         rb_scan_args(argc, argv,\"10\",&v);
316         if(TYPE(v)!=T_STRING){
317                 rb_raise(rb_eRuntimeError,\"argument type error (1st argument must be STRING)\");
318         }
319         char *argtmp = RSTRING_PTR(v);
320         int len;
321         len = strlen(argtmp);
322         char *str_c = new char[len+3];
323         sprintf(str_c,\"\\\"%s\\\"\",argtmp);
324         int len_c = len+2;
325         #{pgm_src}
326         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
327         rmod_rtn->cmod = ctoi_fin;
328         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
329 }
330 "
331 SCP_EOF
332
333
334 func['| expr LE expr'] =<<'SCP_EOF'
335 "
336 /*
337  * call-seq:
338  * zdd1 <= zdd2 : 以下比較演算
339  *
340  *  zdd1,zdd2 : ZDD Object
341  *
342  * === 説明
343  * zdd1に含まれるアイテム集合とzdd2に含まれるアイテム集合を比較し、重みがzdd2以下のアイテム集合を選択する。
344  *  詳しくは==演算子を参照のこと。
345  *
346  * === 関連
347  *  ==, >=, >, <, ne?, iif
348  */
349
350 VALUE vsop_le(int argc, VALUE *argv,VALUE self){
351         Vsop_Ruby* rmod;
352         VALUE v;
353         Data_Get_Struct(self,Vsop_Ruby,rmod);
354         rb_scan_args(argc, argv,\"10\",&v);
355         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
356         CtoI *ctoi_modc = value2ctoi(v);
357         CtoI *ctoi_fin; 
358         #{pgm_src}
359         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
360         rmod_rtn->cmod = ctoi_fin;
361         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
362 }
363 "
364 SCP_EOF
365
366 func['| expr LT expr'] =<<'SCP_EOF'
367 "
368 /*
369  * call-seq:
370  * zdd1 < zdd2 -> ZDD Object : 小なり比較演算
371  *
372  *  zdd1,zdd2 : ZDD Object
373  *
374  * === 説明
375  *  zdd1に含まれるアイテム集合とzdd2に含まれるアイテム集合を比較し、重みがzdd2より小さいアイテム集合を選択する。
376  *  詳しくは==演算子を参照のこと。
377  *
378  * === 関連
379  *  ==, >=, >, <=, ne?, iif
380  */
381
382 VALUE vsop_lt(int argc, VALUE *argv,VALUE self){
383         Vsop_Ruby* rmod;
384         VALUE v;
385         Data_Get_Struct(self,Vsop_Ruby,rmod);
386         rb_scan_args(argc, argv,\"10\",&v);
387         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
388         CtoI *ctoi_modc = value2ctoi(v);
389         CtoI *ctoi_fin; 
390         #{pgm_src}
391         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
392         rmod_rtn->cmod = ctoi_fin;
393         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
394 }
395 "
396 SCP_EOF
397
398 func['| expr GE expr'] =<<'SCP_EOF'
399 "
400 /*
401  * call-seq:
402  * zdd1 >= zdd2 -> ZDD Object : 以上比較演算
403  *
404  *  zdd1,zdd2 : ZDD Object
405  *
406  * === 説明
407  * zdd1に含まれるアイテム集合とzdd2に含まれるアイテム集合を比較し、重みがzdd2以上のアイテム集合を選択する。
408  *  詳しくは==演算子を参照のこと。
409  *
410  * === 関連
411  *  ==, >, <=, <, ne?, iif
412  */
413
414 VALUE vsop_ge(int argc, VALUE *argv,VALUE self){
415         Vsop_Ruby* rmod;
416         VALUE v;
417         Data_Get_Struct(self,Vsop_Ruby,rmod);
418         rb_scan_args(argc, argv,\"10\",&v);
419         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
420         CtoI *ctoi_modc = value2ctoi(v);
421         CtoI *ctoi_fin; 
422         #{pgm_src}
423         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
424         rmod_rtn->cmod = ctoi_fin;
425         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
426 }
427 "
428 SCP_EOF
429
430 func['| expr GT expr'] =<<'SCP_EOF'
431 "
432 /*
433  * call-seq:
434  * zdd1 > zdd2 -> ZDD Object : 大なり比較演算
435  *
436  *  zdd1,zdd2 : ZDD Object
437  *
438  * === 説明
439  * zdd1に含まれるアイテム集合とzdd2に含まれるアイテム集合を比較し、重みがzdd2より大きいアイテム集合を選択する。
440  *  詳しくは==演算子を参照のこと。
441  *
442  * === 関連
443  *  ==, >=, <=, <, ne?, iif
444  */
445
446 VALUE vsop_gt(int argc, VALUE *argv,VALUE self){
447         Vsop_Ruby* rmod;
448         VALUE v;
449         Data_Get_Struct(self,Vsop_Ruby,rmod);
450         rb_scan_args(argc, argv,\"10\",&v);
451         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
452         CtoI *ctoi_modc = value2ctoi(v);
453         CtoI *ctoi_fin; 
454         #{pgm_src}
455         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
456         rmod_rtn->cmod = ctoi_fin;
457         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
458 }
459 "
460 SCP_EOF
461
462
463 func['| expr EQ expr'] =<<'SCP_EOF'
464 "
465 /**//*
466  * call-seq:
467  * zdd1 == zdd2 -> ZDD Object : 等価比較演算子
468  *
469  *  zdd1,zdd2 : ZDD Object
470  *
471  * === 説明
472  * zdd1に含まれるアイテム集合とzdd2に含まれるアイテム集合を比較し、重みが同じアイテム集合を選択する。アイテム集合のみを返し、重みは1となることに注意する。
473  *
474  * 本パッケージで扱える比較演算子(関数)は以下の通り。
475  *  zdd1 == zdd2   : 等価演算子
476  *  zdd1 >= zdd2   : 以上演算子
477  *  zdd1 >  zdd2   : 大なり演算子
478  *  zdd1 <= zdd2   : 以下演算子
479  *  zdd1 <  zdd2   : 小なり演算子
480  *  zdd1.ne?(zdd2) : 不等関数
481  * 
482  * === 例
483  *  > x.show
484  *   3 a + 2 b + 2 c
485  *  > y.show
486  *   2 a + 2 b + 4 c
487  *  # (x,yが上記の通り定義されていたとする)
488  *
489  *  # xとyを比較し、同じ重みを持つアイテム集合を選択する。
490  *  > (x==y).show
491  *   b
492  *
493  *  # xとyを比較し、y以上の重みを持つアイテム集合を選択する。
494  *  > (x>=y).show
495  *   a + b
496  *
497  *  # xとyを比較し、異なる重みを持つアイテム集合を選択する。
498  *  > (x.ne?(y)).show
499  *   a + c
500  *
501  * zdd1にあってzdd2にない(もしくはその逆)アイテム集合の重みは0と考えればよい。
502  *  x.show
503  *   3 a + 2 b + 2 c
504  *  y.show
505  *   2 a + 2 b
506  *  # (x,yが上記の通り定義されていたとする)
507  *
508  *  # アイテム集合cはyにないので項0cを考えればよい。
509  *  > (x>y).show
510  *   a + c
511  *  > (x.ne?(y)).show
512  *   a + c
513  *  > (x==y).show
514  *   b
515  * ----
516  * ====== 上記の例において出力結果を示したコメントでは、アイテムをアルファベット小文字1文字で表し、項における重みとアイテム間のスペースおよびアイテム間のスペースを省略して表記している。
517  */
518
519 VALUE vsop_eq(int argc, VALUE *argv,VALUE self){
520         Vsop_Ruby* rmod;
521         VALUE v;
522         Data_Get_Struct(self,Vsop_Ruby,rmod);
523         rb_scan_args(argc, argv,\"10\",&v);
524         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
525         CtoI *ctoi_modc = value2ctoi(v);
526         CtoI *ctoi_fin; 
527         #{pgm_src}
528         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
529         rmod_rtn->cmod = ctoi_fin;
530         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
531 }
532 "
533 SCP_EOF
534
535 func['| u_expr TLE LPAREN expr RPAREN'] =<<'SCP_EOF'
536 "
537 /*
538  * call-seq:
539  * zdd1.termsLE(zdd2) -> ZDD Object : 重み比較による項選択(以下比較)
540  *
541  *  zdd1,zdd2 : ZDD Object
542  *
543  * === 説明
544  * zdd1に含まれる項のうち、zdd2で与えられた定数以下の重みを持つ項(重み+アイテム集合)を選択する。
545  *  詳しくはtermsEQ演算子を参照のこと。
546  *
547  * === 関連
548  *  termsEQ, termsNE, termsGE, termsGT, termsLE, termsLT, terms
549  */
550
551 VALUE vsop_termsLE(int argc, VALUE *argv, VALUE self){
552         Vsop_Ruby* rmod;
553         VALUE v;
554         Data_Get_Struct(self,Vsop_Ruby,rmod);
555         rb_scan_args(argc, argv,\"10\",&v);
556         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
557         CtoI *ctoi_modd = value2ctoi(v);
558         CtoI *ctoi_fin; 
559         #{pgm_src}
560         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
561         rmod_rtn->cmod = ctoi_fin;
562         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
563 }
564 "
565 SCP_EOF
566
567 func['| u_expr TLT LPAREN expr RPAREN'] =<<'SCP_EOF'
568 "
569 /*
570  * call-seq:
571  * zdd1.termsLT(zdd2) -> ZDD Object : 重み比較による項選択(小なり比較)
572  *
573  *  zdd1,zdd2 : ZDD Object
574  *
575  * === 説明
576  * zdd1に含まれる項のうち、zdd2で与えられた定数より小さい重みを持つ項(重み+アイテム集合)を選択する。
577  *  詳しくはtermsEQ演算子を参照のこと。
578  *
579  * === 関連
580  *  termsEQ, termsNE, termsGE, termsGT, termsLE, termsLT, terms
581  */
582
583 VALUE vsop_termsLT(int argc, VALUE *argv, VALUE self){
584         Vsop_Ruby* rmod;
585         VALUE v;
586         Data_Get_Struct(self,Vsop_Ruby,rmod);
587         rb_scan_args(argc, argv,\"10\",&v);
588         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
589         CtoI *ctoi_modd = value2ctoi(v);
590         CtoI *ctoi_fin; 
591         #{pgm_src}
592         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
593         rmod_rtn->cmod = ctoi_fin;
594         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
595 }
596 "
597 SCP_EOF
598
599 func['| u_expr TGE LPAREN expr RPAREN'] =<<'SCP_EOF'
600 "
601 /*
602  * call-seq:
603  * zdd1.termsGE(zdd2) -> ZDD Object : 重み比較による項選択(以上比較)
604  *
605  *  zdd1,zdd2 : ZDD Object
606  *
607  * === 説明
608  * zdd1に含まれる項のうち、zdd2で与えられた定数以上の重みを持つ項(重み+アイテム集合)を選択する。
609  *  詳しくはtermsEQ演算子を参照のこと。
610  *
611  * === 関連
612  *  termsEQ, termsNE, termsGE, termsGT, termsLE, termsLT, terms
613  */
614
615 VALUE vsop_termsGE(int argc, VALUE *argv, VALUE self){
616         Vsop_Ruby* rmod;
617         VALUE v;
618         Data_Get_Struct(self,Vsop_Ruby,rmod);
619         rb_scan_args(argc, argv,\"10\",&v);
620         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
621         CtoI *ctoi_modd = value2ctoi(v);
622         CtoI *ctoi_fin; 
623         #{pgm_src}
624         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
625         rmod_rtn->cmod = ctoi_fin;
626         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
627 }
628 "
629 SCP_EOF
630
631 func['| u_expr TGT LPAREN expr RPAREN'] =<<'SCP_EOF'
632 "
633 /*
634  * call-seq:
635  * 書式 zdd1.termsGT(zdd2) -> ZDD Object : 重み比較による項選択(大なり比較)
636  *
637  *  zdd1,zdd2 : ZDD Object
638  *
639  * === 説明
640  * zdd1に含まれる項のうち、zdd2で与えられた定数より大きい重みを持つ項(重み+アイテム集合)を選択する。
641  *  詳しくはtermsEQ演算子を参照のこと。
642  *
643  * === 関連
644  *  termsEQ, termsNE, termsGE, termsGT, termsLE, termsLT, terms
645  */
646
647
648 VALUE vsop_termsGT(int argc, VALUE *argv, VALUE self){
649         Vsop_Ruby* rmod;
650         VALUE v;
651         Data_Get_Struct(self,Vsop_Ruby,rmod);
652         rb_scan_args(argc, argv,\"10\",&v);
653         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
654         CtoI *ctoi_modd = value2ctoi(v);
655         CtoI *ctoi_fin; 
656         #{pgm_src}
657         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
658         rmod_rtn->cmod = ctoi_fin;
659         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
660 }
661 "
662 SCP_EOF
663
664 func['| u_expr TNE LPAREN expr RPAREN'] =<<'SCP_EOF'
665 "
666 /*
667  * call-seq:
668  * zdd1.termsNE(zdd2) -> ZDD Object : 重み比較による項選択(不等比較)
669  *
670  *  zdd1,zdd2 : ZDD Object
671  *
672  * === 説明
673  * zdd1に含まれる項のうち、zdd2で与えられた定数と異なる重みを持つ項(重み+アイテム集合)を選択する。
674  *  詳しくはtermsEQ演算子を参照のこと。
675  *
676  * === 関連
677  *  termsEQ, termsNE, termsGE, termsGT, termsLE, termsLT, terms
678  */
679
680 VALUE vsop_termsNE(int argc, VALUE *argv, VALUE self){
681         Vsop_Ruby* rmod;
682         VALUE v;
683         Data_Get_Struct(self,Vsop_Ruby,rmod);
684         rb_scan_args(argc, argv,\"10\",&v);
685         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
686         CtoI *ctoi_modd = value2ctoi(v);
687         CtoI *ctoi_fin; 
688         #{pgm_src}
689         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
690         rmod_rtn->cmod = ctoi_fin;
691         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
692 }
693 "
694 SCP_EOF
695
696 func['| u_expr TEQ LPAREN expr RPAREN'] =<<'SCP_EOF'
697 "
698 /*
699  * call-seq:
700  * zdd1.termsEQ(zdd2) -> ZDD Object : 重み比較による項選択(等価比較)
701  *
702  *  zdd1,zdd2 : ZDD Object
703  *
704  * === 説明
705  * zdd1に含まれる項のうち、zdd2で与えられた定数と同じ重みを持つ項(重み+アイテム集合)を選択する。
706  * zdd2にはconstantメソッドにより生成されたVSOP定数オブジェクト、もしくはFixnum,Bignumのrubyオブジェクトで指定する。
707  *
708  * 本パッケージで扱える全ての項選択メソッドは以下の通り。
709  *  zdd1.termsEQ(zdd2) : 等価比較
710  *  zdd1.termsGE(zdd2) : 以上比較
711  *  zdd1.termsGT(zdd2) : 大なり比較
712  *  zdd1.termsLE(zdd2) : 以下比較
713  *  zdd1.termsLT(zdd2) : 小なり比較
714  *  zdd1.termsNE(zdd2) : 不等比較
715  * 
716  * === 例
717  *  > x.show
718  *   5 a + 3 b + c
719  *  # xが上記の通り定義されていたとする。
720  *
721  *  # 3の重みを持つ項を選択する。
722  *  > x.termsEQ(3).show
723  *   3 b
724  *
725  *  # 3以上の重みを持つ項を選択する。
726  *  > x.termsGE(3).show
727  *   5 a + 3 b
728  *
729  *  # 3でない重みを持つ項を選択する。
730  *  > x.termsNE(3).show
731  *   5 a + c
732  *
733  *  # 条件に合う項がなければ0
734  *  > x.termsGT(10).show
735  *   0
736  */
737
738 VALUE vsop_termsEQ(int argc, VALUE *argv, VALUE self){
739         Vsop_Ruby* rmod;
740         VALUE v;
741         Data_Get_Struct(self,Vsop_Ruby,rmod);
742         rb_scan_args(argc, argv,\"10\",&v);
743         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
744         CtoI *ctoi_modd = value2ctoi(v);
745         CtoI *ctoi_fin; 
746         #{pgm_src}
747         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
748         rmod_rtn->cmod = ctoi_fin;
749         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
750 }
751 "
752 SCP_EOF
753
754 func['| u_expr FPC LPAREN expr RPAREN'] =<<'SCP_EOF'
755 "
756 /*
757  * call-seq:
758  * zdd.freqpatC(minsup) : 頻出飽和アイテム集合の列挙
759  *
760  *  zdd    : ZDD Object
761  *  minsup : Ruby Integer
762  *
763  * === 説明
764  *  zddから最小サポートminsup以上出現する頻出飽和アイテム集合を全て列挙し、そのZDDオブジェクトを返す。
765  *
766  * === 例
767  * freqpatAを参照のこと。
768  */
769 VALUE vsop_freqpatC(int argc, VALUE *argv, VALUE self){
770         Vsop_Ruby* rmod;
771         VALUE v;
772         Data_Get_Struct(self,Vsop_Ruby,rmod);
773         rb_scan_args(argc, argv,\"10\",&v);
774         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
775         CtoI *ctoi_modd = value2ctoi(v);
776         CtoI *ctoi_fin; 
777         #{pgm_src}
778         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
779         rmod_rtn->cmod = ctoi_fin;
780         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
781 }
782 "
783 SCP_EOF
784
785 func['| u_expr FPM LPAREN expr RPAREN'] =<<'SCP_EOF'
786 "
787 /**//*
788  * call-seq:
789  * zdd.freqpatM(minsup) -> ZDD Object : 頻出極大アイテム集合の列挙
790  *
791  *  zdd    : ZDD Object
792  *  minsup : Ruby Integer
793  *
794  * === 説明
795  *  zddから最小サポートminsup以上出現する頻出極大アイテム集合を全て列挙し、そのZDDオブジェクトを返す。
796  *
797  * === 例
798  * freqpatAを参照のこと。
799  */
800 VALUE vsop_freqpatM(int argc, VALUE *argv, VALUE self){
801         Vsop_Ruby* rmod;
802         VALUE v;
803         Data_Get_Struct(self,Vsop_Ruby,rmod);
804         rb_scan_args(argc, argv,\"10\",&v);
805         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
806         CtoI *ctoi_modd = value2ctoi(v);
807         CtoI *ctoi_fin; 
808         #{pgm_src}
809         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
810         rmod_rtn->cmod = ctoi_fin;
811         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
812 }
813 "
814 SCP_EOF
815
816 func['| u_expr FPA LPAREN expr RPAREN'] =<<'SCP_EOF'
817 "
818 /*
819  * call-seq:
820  * zdd.freqpatA(minsup) : 頻出アイテム集合の列挙
821  *
822  *  zdd    : ZDD Object
823  *  minsup : Ruby Integer
824  *
825  * === 説明
826  *  zddから最小サポートminsup以上出現する頻出アイテム集合を全て列挙し、そのZDDオブジェクトを返す。
827  *
828  * === 例
829  *  > a=VSOP.itemset(\"a\")
830  *  > b=VSOP.itemset(\"b\")
831  *  > c=VSOP.itemset(\"c\")
832  *  > d=VSOP.itemset(\"d\")
833  *  > t=a*b + a + b*c*d + a*b*c + a 
834  *  > t.show
835  *   a b c + a b + 2 a + b c d
836  * 
837  *  > t.freqpatA(1).show
838  *   a b c + a b + a c + a + b c d + b c + b d + b + c d + c + d + 1
839  *  > t.freqpatM(1).show
840  *   a b c + b c d
841  *  > t.freqpatC(1).show
842  *   a b c + a b + a + b c d + b c + b + 1
843  *
844  *  > t.freqpatA(2).show
845  *   a b + a + b c + b + c + 1
846  *  > t.freqpatM(2).show
847  *   a b + b c
848  *  > t.freqpatC(2).show
849  *   a b + a + b c + b + 1
850  *  > t.freqpatA(3).show
851  *   a + b + 1
852  *  > t.freqpatM(3).show
853  *   a + b
854  *  > t.freqpatC(3).show
855  *   a + b + 1
856  *
857  * === 関連
858  * freqpatM, freqpatC
859  */
860 VALUE vsop_freqpatA(int argc, VALUE *argv, VALUE self){
861         Vsop_Ruby* rmod;
862         VALUE v;
863         Data_Get_Struct(self,Vsop_Ruby,rmod);
864         rb_scan_args(argc, argv,\"10\",&v);
865         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
866         CtoI *ctoi_modd = value2ctoi(v);
867         CtoI *ctoi_fin; 
868         #{pgm_src}
869         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
870         rmod_rtn->cmod = ctoi_fin;
871         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
872 }
873 "
874 SCP_EOF
875
876 func['| u_expr SYMGRP'] =<<'SCP_EOF'
877 "
878 /*
879  * call-seq:
880  * zdd.symgrp : Generates symmetric item sets in zdd.
881  *
882  *  zdd : ZDD Object
883  *
884  * === 説明
885  *
886  */
887 VALUE vsop_symgrp(VALUE self){
888         Vsop_Ruby* rmod;
889         Data_Get_Struct(self,Vsop_Ruby,rmod);
890         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
891         CtoI *ctoi_fin; 
892         #{pgm_src}
893         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
894         rmod_rtn->cmod = ctoi_fin;
895         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
896 }
897 "
898 SCP_EOF
899
900 func['| MINUS expr %prec UMINUS'] =<<'SCP_EOF'
901 "
902 /*
903  * call-seq:
904  * - zdd -> ZDD Object : -単項演算子
905  *
906  *  zdd : ZDD Object
907  *
908  * === 説明
909  * zddに含まれる全てのアイテム集合の重みの符合を変える。
910  *
911  * === 例
912  *  > x.show
913  *  3 a + 2 b
914  *  > (-x).show
915  *   -3 a - 2 b
916  */
917
918 VALUE vsop_minus_op(VALUE self){
919         Vsop_Ruby* rmod;
920         Data_Get_Struct(self,Vsop_Ruby,rmod);
921         CtoI *ctoi_modb =new CtoI(*rmod->cmod);
922         CtoI *ctoi_fin; 
923         #{pgm_src}
924         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
925         rmod_rtn->cmod = ctoi_fin;
926         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
927 }
928 "
929 SCP_EOF
930
931 func['| PLUS expr %prec UPLUS'] =<<'SCP_EOF'
932 "
933 /*
934  * call-seq:
935  * + zdd -> ZDD Object : 単項演算子
936  *
937  *  zdd : ZDD Object
938  *
939  * === 説明
940  * zddに含まれる全てのアイテム集合をそのまま返す(何もしない)。
941  *
942  * === 例
943  *  > x.show
944  *   3 a + 2 b
945  *  > (+x).show
946  *   3 a + 2 b
947  */
948
949 VALUE vsop_plus_op(VALUE self){
950         Vsop_Ruby* rmod;
951         Data_Get_Struct(self,Vsop_Ruby,rmod);
952         CtoI *ctoi_modb =new CtoI(*rmod->cmod);
953         CtoI *ctoi_fin; 
954         #{pgm_src}
955         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
956         rmod_rtn->cmod = ctoi_fin;
957         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
958 }
959 "
960 SCP_EOF
961
962 func['| u_expr PERMITSYM LPAREN expr RPAREN'] =<<'SCP_EOF'
963 "
964 /*
965  * call-seq:
966  * zdd1.permitsym(zdd2) : Filters terms in zdd1 each of which consists of zdd2 number of items.
967  *
968  *  zdd1,zdd2 : ZDD Object
969  *
970  * === 説明
971  *
972  */
973
974 VALUE vsop_permitsym(int argc, VALUE *argv, VALUE self){
975         Vsop_Ruby* rmod;
976         VALUE v;
977         Data_Get_Struct(self,Vsop_Ruby,rmod);
978         rb_scan_args(argc, argv,\"10\",&v);
979         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
980         CtoI *ctoi_modd = value2ctoi(v);
981         CtoI *ctoi_fin; 
982         #{pgm_src}
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 SCP_EOF
989
990 func['| u_expr RESTRICT LPAREN expr RPAREN'] =<<'SCP_EOF'
991 "
992 /*
993  * call-seq:
994  * zdd1.restrict(zdd2) : restrict
995  *
996  *  zdd1,zdd2 : ZDD Object
997  *
998  * === 説明
999  * zdd1に含まれる組合せの中から、zdd2中の少なくとも1つの組合せを包含する要素だけを抽出する。
1000  *
1001  * === 例
1002  *  > x.show
1003  *   5 a + 3 b + c
1004  *  > y.show
1005  *   a + b
1006  *  # x,yが上記の通り定義されていたとする。
1007  *  > z.show
1008  *   a b
1009  *  > x.restrinct(y).show
1010  *   5 a + 3 b
1011  *  > x.restrinct(z).show
1012  *   0
1013  *  > x.restrinct(\"a\").show
1014  *   5 a
1015  */
1016
1017 VALUE vsop_restrict(int argc, VALUE *argv, VALUE self){
1018         Vsop_Ruby* rmod;
1019         VALUE v;
1020         Data_Get_Struct(self,Vsop_Ruby,rmod);
1021         rb_scan_args(argc, argv,\"10\",&v);
1022         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1023         CtoI *ctoi_modd = value2ctoi(v);
1024         CtoI *ctoi_fin; 
1025         #{pgm_src}
1026         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1027         rmod_rtn->cmod = ctoi_fin;
1028         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1029 }
1030 "
1031 SCP_EOF
1032
1033
1034 func['| u_expr ITEMS'] =<<'SCP_EOF'
1035 "
1036 /*
1037  * call-seq:
1038  * zdd.items -> ZDD Object : ZDDを構成する全アイテムの列挙
1039  *
1040  *  zdd : ZDD Object
1041  *
1042  * === 説明
1043  *  zdd上の全アイテムとその重みについて、新しいZDDオブジェクトを生成し返す。
1044  *
1045  * === 例
1046  *  > a=VSOP.itemset(\"a\")
1047  *  > b=VSOP.itemset(\"b\")
1048  *  > c=VSOP.itemset(\"c\")
1049  *  > f=((a*b*c)+(a*b)+(b*c))
1050  *  > f.show
1051  *   a b c + 2 a b + b c
1052  *
1053  *  # ZDDオブジェクトfは3つのアイテムa,b,cから構成されており、それぞれのアイテムの重みを以下の通り計算する。
1054  *  # アイテムaを含む項は\"a b c\"と\"2 a b\"で、その重み合計は3となる。
1055  *  # アイテムbは全ての項に含まれ、その重み合計は4となる。
1056  *  # アイテムcを含む項は\"a b c\"と\"b c\"で、その重み合計は2となる。
1057  *  > f.items.show
1058  *   3 a + 4 b + 2 c
1059  */
1060
1061 VALUE vsop_items(VALUE self){
1062         Vsop_Ruby* rmod;
1063         Data_Get_Struct(self,Vsop_Ruby,rmod);
1064         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1065         CtoI *ctoi_fin; 
1066         #{pgm_src}
1067         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1068         rmod_rtn->cmod = ctoi_fin;
1069         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1070 }
1071 "
1072 SCP_EOF
1073
1074 func['| u_expr TOTALVAL'] =<<'SCP_EOF'
1075 "
1076 /*
1077  * call-seq:
1078  * zdd.totalval -> Ruby Integer : 重みの合計
1079  *
1080  *  zdd : ZDD Object
1081  *
1082  * === 説明
1083  * zddに含まれる項(定数項も含む)の重みの合計をruby整数で返す。
1084  *
1085  * === 例
1086  *  > x.show
1087  *   5 a + 3 b + c
1088  *  # xが上記の通り定義されていたとする。
1089  *
1090  *  > puts x.totalval
1091  *   9
1092  *
1093  *  # 定数項も含めて求められる。
1094  *  > x.show
1095  *   5 a + 3 b + c - 10
1096  *  # xが上記の通り定義されていたとする。
1097  *  > puts x.totalval
1098  *   -1
1099  * === 関連
1100  *  minval, maxval
1101  */
1102
1103 VALUE vsop_totalval(VALUE self){
1104         Vsop_Ruby* rmod;
1105         Data_Get_Struct(self,Vsop_Ruby,rmod);
1106   int val = rmod->cmod->TotalVal().GetInt();
1107         return INT2NUM(val);
1108 /*
1109         Vsop_Ruby* rmod;
1110         Data_Get_Struct(self,Vsop_Ruby,rmod);
1111         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1112         CtoI *ctoi_fin; 
1113         #{pgm_src}
1114         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1115         rmod_rtn->cmod = ctoi_fin;
1116         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1117 */
1118 }
1119 "
1120 SCP_EOF
1121
1122 func['| u_expr MINVAL'] =<<'SCP_EOF'
1123 "
1124 /*
1125  * call-seq:
1126  * zdd.minval -> ZDD Object : 重みの最小値
1127  *
1128  *  zdd : ZDD Object
1129  *
1130  * === 説明
1131  * zddに含まれる項(定数項も含む)のうち、最小の重みをVSOP定数オブジェクトで返す。
1132  *
1133  * === 例
1134  *  > x.show
1135  *   5 a - 3 b + c
1136  *  # xが上記の通り定義されていたとする。
1137  *
1138  *  > x.maxval.show
1139  *   -3
1140  *
1141  *  # 最小値は定数項も含めて求められる。
1142  *  > x.show
1143  *   5 a - 3 b + c - 10
1144  *  # xが上記の通り定義されていたとする。
1145  *  > x.maxval.show
1146  *   -10
1147  *
1148  *  # 最小の重みを持つ項を選択する。
1149  *  > x.show
1150  *   5 a - 3 b + 5 c - 3
1151  *  # xが上記の通り定義されていたとする。
1152  *  > x.termsEQ(x.maxval).show
1153  *   -3 b - 3
1154  *
1155  * === 関連
1156  *  maxval
1157  */
1158
1159 VALUE vsop_minval(VALUE self){
1160         Vsop_Ruby* rmod;
1161         Data_Get_Struct(self,Vsop_Ruby,rmod);
1162         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1163         CtoI *ctoi_fin; 
1164         #{pgm_src}
1165         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1166         rmod_rtn->cmod = ctoi_fin;
1167         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1168 }
1169 "
1170 SCP_EOF
1171
1172 func['| u_expr MAXVAL'] =<<'SCP_EOF'
1173 "
1174 /*
1175  * call-seq:
1176  * zdd.maxval -> ZDD Object : 重みの最大値
1177  *
1178  *  zdd : ZDD Object
1179  *
1180  * === 説明
1181  * zddに含まれる項(定数項も含む)のうち、最大の重みをVSOP定数オブジェクトで返す。
1182  *
1183  * === 例
1184  *  > x.show
1185  *   5 a + 3 b + c
1186  *  # xが上記の通り定義されていたとする。
1187  *  > x.maxval.show
1188  *   5
1189  *
1190  *  # 最大値は定数項も含めて求められる。
1191  *  > x.show
1192  *   5 a + 3 b + c + 10
1193  *  # xが上記の通り定義されていたとする。
1194  *  > x.maxval.show
1195  *   10
1196  *
1197  *  # 最大の重みを持つ項を選択する。
1198  *  > x.show
1199  *   5 a + 3 b + 5 c + 2
1200  *  # xが上記の通り定義されていたとする。
1201  *  > x.termsEQ(x.maxval).show
1202  *   5 a + 5 c
1203  *
1204  * === 関連
1205  *  minval
1206  */
1207
1208 VALUE vsop_maxval(VALUE self){
1209         Vsop_Ruby* rmod;
1210         Data_Get_Struct(self,Vsop_Ruby,rmod);
1211         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1212         CtoI *ctoi_fin; 
1213         #{pgm_src}
1214         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1215         rmod_rtn->cmod = ctoi_fin;
1216         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1217 }
1218 "
1219 SCP_EOF
1220
1221 func['| expr REMAINDER expr'] =<<'SCP_EOF'
1222 "
1223 /*
1224  * call-seq:
1225  * zdd1 % zdd2 -> ZDD Object : 剰余演算子
1226  *
1227  *  zdd1,zdd2 : ZDD Object
1228  *
1229  * ===説明
1230  *  剰余演算を行う。詳しくは / 演算子を参照。
1231  */
1232
1233 VALUE vsop_remainder(int argc, VALUE *argv,VALUE self){
1234         Vsop_Ruby* rmod;
1235         VALUE v;
1236         Data_Get_Struct(self,Vsop_Ruby,rmod);
1237         rb_scan_args(argc, argv,\"10\",&v);
1238         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1239         CtoI *ctoi_modc = value2ctoi(v);
1240         CtoI *ctoi_fin; 
1241         #{pgm_src}
1242         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1243         rmod_rtn->cmod = ctoi_fin;
1244         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1245 }
1246 "
1247 SCP_EOF
1248
1249 func['| expr QUOTIENT expr'] =<<'SCP_EOF'
1250 "
1251 /*
1252  * call-seq:
1253  * zdd1 / zdd2 -> ZDD Object : 除算演算子
1254  *
1255  *  zdd1,zdd2 : ZDD Object
1256  *
1257  * === 説明
1258  * ==== a. 定数除算
1259  *  重み付き積和集合xの定数cによる除算x/cは、
1260  *  xの各項(アイテム集合)の重み(頻度)をcで整数除算した商を重みに持つアイテム集合が計算される。
1261  *  通常の多項式と同様に考えれば良い。
1262  *  x.show # -> 13a+3b (xが左記の通り定義されていたとする)
1263  *  x/5 -> 2a    # aの項:13/5の商は2であるから2a。bの項:3/5の商は0であるから0bとなり表示されない。
1264  *  x%5 -> 3a+3b # aの項:13/5の余りは3であるから3a。bの項:3/5の余りは3であるから3bとなる。
1265  *
1266  * ==== b. 1つのアイテム集合による除算
1267  *  重み付き積和集合xのアイテム集合vによる除算x/vは、xの各項をvで除する演算である。
1268  *  通常の多項式と同様に考えれば良い。
1269  *  x.show # -> 7ab+5bc
1270  *  y.show # -> 7ab+5bc+2c
1271  *  # (x,yが上記の通り定義されていたとする)
1272  *  x/'b'  # -> 7a+5c     # 7ab/bの商は7a。5bc/bの商は5c。
1273  *  y/'3b' # -> 2a+c      # 7ab/3bの商は2a。5bc/3bの商は1c。2c/3bの商は0となり表示されない。
1274  *  x%'b'  # -> 0         # 7ab/bの余りは0。5bc/bの余り0。
1275  *  y%'3b' # -> ab+2bc+2c # 7ab/3bの余りはab。5bc/3bの余りは2bc。2c/3bの余りは2c。
1276  *
1277  * ==== c. 2つ以上のアイテム集合による除算
1278  *  2つの重み付き積和集合x,yの除算x/yは次のように計算される。
1279  *  除数yの各項をT_iとしたときQ_i=x/T_iを全てのT_iについて得られたQ_i全て共通に含まれるアイテム集合(項)について、重みの絶対値が最小の項を商Qと定義する。
1280  *  通常の多項式とは異なることに注意する。
1281  *  x.show # -> 2ab+4ac+ad-2bc+3bd
1282  *  y.show # -> a+b
1283  *  # (x,yが上記の通り定義されていたとする)
1284  *  # Q_1=(x/'a')=2b +4c +d +0  +0  = 0  +2b +4c +d
1285  *  # Q_2=(x/'b')=2a +0  +0 -2c +3d = 2a +0  -2c +3d
1286  *  # Q_1,Q_2で共通のアイテム集合はcとdであり、それぞれで絶対値が最小の項は-2cとdである。よって求める商は以下の通りとなる。
1287  *  (x/y).show # -> -2c+d
1288  *  # x%yについてはx-(y*Q)を計算すればよい。
1289  *  (x%y).show # -> 2ab+6ac+2bd
1290  * ----
1291  * ====== 上記の例において出力結果を示したコメントでは、アイテムをアルファベット小文字1文字で表し、項における重みとアイテム間のスペースおよびアイテム間のスペースを省略して表記している。
1292  */
1293
1294 VALUE vsop_quotiment(int argc, VALUE *argv,VALUE self){
1295         Vsop_Ruby* rmod;
1296         VALUE v;
1297         Data_Get_Struct(self,Vsop_Ruby,rmod);
1298         rb_scan_args(argc, argv,\"10\",&v);
1299         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1300         CtoI *ctoi_modc = value2ctoi(v);
1301         CtoI *ctoi_fin; 
1302         #{pgm_src}
1303         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1304         rmod_rtn->cmod = ctoi_fin;
1305         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1306 }
1307 "
1308 SCP_EOF
1309
1310 func['| expr MULTIPLY expr'] =<<'SCP_EOF'
1311 "
1312 /*
1313  * call-seq:
1314  * zdd1 * zdd2 -> ZDD Object : 乗算演算子
1315  *
1316  *  zdd1,zdd2 : ZDD Object
1317  *
1318  * === 説明
1319  * ==== a. 定数乗算
1320  *  重み付き積和集合xに定数cを掛けるx*cでは、xの各項の重みをc倍する。
1321  *  通常の多項式と同様に考えれば良い。
1322  *  a=VSOP.itemset('a'); b=VSOP.itemset('b'); c=VSOP.itemset('c');
1323  *  (a*3).show           # -> 3a
1324  *  (-2*a).show          # -> -2a
1325  *  ((a+2*b+3*c)*4).show # -> 4a+8b+12c
1326  *
1327  * ==== b. 1つのアイテム集合の乗算
1328  *  重み付き積和集合xに1つのアイテム集合yを掛けるx*yでは、xの各項目にアイテム集合yを加える。
1329  *  ただし、同じアイテム同士の掛け算 a*a=a となることに注意する。
1330  *  x.show  # -> a+2ab+3c (xが左記の通り定義されていたとする)
1331  *  x*'d'   # -> ad+2abd+3cd
1332  *  x*'b'   # -> ab+2ab+3bc
1333  *  4*x*'a' # -> 4a+8ab+12ac
1334  *
1335  * ==== c. 2つ以上のアイテム集合の乗算
1336  *  2つの重み付き積和集合x,yの乗算x*yでは、xとyそれぞれの各項から一つずつ選ぶ組み合わせ全てについて上記a,bの乗算を付す。
1337  *  乗算の結果同じアイテム集合の項は加減算される。
1338  *  a=VSOP.itemset('a'); b=VSOP.itemset('b');
1339  *  c=VSOP.itemset('c'); d=VSOP.itemset('d');
1340  *  ((a+b)*(c+d)).show # -> ac+ad+bc+bd
1341  *  ((a+b)*(b+c)).show # -> ab+ac+b+bc
1342  *  ((a+b)*(a+b)).show # -> a+2ab+b
1343  *  ((a+b)*(a-b)).show # -> a-b
1344  * ----
1345  * ====== 上記の例において出力結果を示したコメントでは、アイテムをアルファベット小文字1文字で表し、項における重みとアイテム間のスペースおよびアイテム間のスペースを省略して表記している。
1346  */
1347
1348 VALUE vsop_multiply(int argc, VALUE *argv,VALUE self){
1349         Vsop_Ruby* rmod;
1350         VALUE v;
1351         Data_Get_Struct(self,Vsop_Ruby,rmod);
1352         rb_scan_args(argc, argv,\"10\",&v);
1353         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1354         CtoI *ctoi_modc = value2ctoi(v);
1355         CtoI *ctoi_fin; 
1356         #{pgm_src}
1357         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1358         rmod_rtn->cmod = ctoi_fin;
1359         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1360 }
1361 "
1362 SCP_EOF
1363
1364 func['| LCM LPAREN FNAME FNAME NUMBER FNAME RPAREN'] =<<'SCP_EOF'
1365 "
1366 VALUE vsop_lcm_order(int argc, VALUE *argv, VALUE self){
1367         if(init_cnt==0){ BDDV_Init(256, env_nmax);}
1368         init_cnt++;
1369
1370         VALUE v1,v2,v3,v4;
1371         CtoI *ctoi_fin; 
1372         rb_scan_args(argc, argv,\"40\",&v1,&v2,&v3,&v4);
1373         if(TYPE(v1)!=T_STRING){
1374                 rb_raise(rb_eRuntimeError,\"argument type error (1st argument must be STRING)\");
1375         }
1376         if(TYPE(v2)!=T_STRING){
1377                 rb_raise(rb_eRuntimeError,\"argument type error (1st argument must be STRING)\");
1378         }
1379         if(TYPE(v3)!=T_FIXNUM){
1380                 rb_raise(rb_eRuntimeError,\"argument type error (3rd argument must be FIXNUM)\");
1381         }
1382         if(TYPE(v4)!=T_STRING){
1383                 rb_raise(rb_eRuntimeError,\"argument type error (4th argument must be STRING)\");
1384         }
1385         char *arg1 = RSTRING_PTR(v1);
1386         char *arg2 = RSTRING_PTR(v2);
1387         int arg3_fix = FIX2INT(v3);
1388         char *arg4 = RSTRING_PTR(v4);
1389
1390         int len;
1391
1392         len = strlen(arg1);
1393         char *str_c = new char[len+3];
1394         sprintf(str_c,\"\\\"%s\\\"\",arg1);
1395         int len_c = len+2;
1396
1397         len = strlen(arg2);
1398         char *str_d = new char[len+3];
1399         sprintf(str_d,\"\\\"%s\\\"\",arg2);
1400         int len_d = len+2;
1401
1402         char *str_e = new char[64];
1403         sprintf(str_e,\"%d\",arg3_fix);
1404
1405         len = strlen(arg4);
1406         char *str_f = new char[len+3];
1407         sprintf(str_f,\"\\\"%s\\\"\",arg4);
1408         int len_f = len+2;
1409
1410         #{pgm_src}
1411
1412         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1413         rmod_rtn->cmod = ctoi_fin;
1414         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1415 }
1416 "
1417 SCP_EOF
1418
1419
1420
1421 func['| LCM LPAREN FNAME FNAME NUMBER RPAREN'] =<<'SCP_EOF'
1422 "
1423 VALUE vsop_lcm_nomal(int argc, VALUE *argv, VALUE self){
1424         if(init_cnt==0){ BDDV_Init(256, env_nmax);}
1425         init_cnt++;
1426
1427         VALUE v1,v2,v3;
1428         CtoI *ctoi_fin; 
1429         rb_scan_args(argc, argv,\"30\",&v1,&v2,&v3);
1430         if(TYPE(v1)!=T_STRING){
1431                 rb_raise(rb_eRuntimeError,\"argument type error (1st argument must be STRING)\");
1432         }
1433         if(TYPE(v2)!=T_STRING){
1434                 rb_raise(rb_eRuntimeError,\"argument type error (1st argument must be STRING)\");
1435         }
1436         if(TYPE(v3)!=T_FIXNUM){
1437                 rb_raise(rb_eRuntimeError,\"argument type error (3rd argument must be FIXNUM)\");
1438         }
1439         char *arg1 = RSTRING_PTR(v1);
1440         char *arg2 = RSTRING_PTR(v2);
1441         int arg3_fix = FIX2INT(v3);
1442
1443         int len;
1444
1445         len = strlen(arg1);
1446         char *str_c = new char[len+3];
1447         sprintf(str_c,\"\\\"%s\\\"\",arg1);
1448         int len_c = len+2;
1449
1450         len = strlen(arg2);
1451         char *str_d = new char[len+3];
1452         sprintf(str_d,\"\\\"%s\\\"\",arg2);
1453         int len_d = len+2;
1454
1455         char *str_e = new char[64];
1456         sprintf(str_e,\"%d\",arg3_fix);
1457         #{pgm_src}
1458         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1459         rmod_rtn->cmod = ctoi_fin;
1460         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1461 }
1462 "
1463 SCP_EOF
1464
1465 func['| u_expr PERMIT LPAREN expr RPAREN']=<<'SCP_EOF'
1466 "
1467 /*
1468  * call-seq:
1469  * zdd1.permit(zdd2) : permit演算子
1470  * 
1471  *  zdd1,zdd2 : ZDD Object
1472  *
1473  * === 説明
1474  *  zdd1に含まれる組合せの中から、zdd2中の少なくとも1つの組合せに包含される要素だけを抽出する。
1475  *
1476  * === 例
1477  *  > x.show
1478  *   5 a + 3 b + c
1479  *  > y.show
1480  *   a + b
1481  *  > z.show
1482  *   a b
1483  *  # x,y,zが上記の通り定義されていたとする。
1484  *
1485  *  > x.permit(y).show
1486  *   5 a + 3 b
1487  *  > x.permit(z).show
1488  *   0
1489  *  > x.permit(\"a\").show
1490  *   5 a
1491  */
1492 VALUE vsop_permit(int argc, VALUE *argv, VALUE self){
1493         Vsop_Ruby* rmod;
1494         VALUE v;
1495         Data_Get_Struct(self,Vsop_Ruby,rmod);
1496         rb_scan_args(argc, argv,\"10\",&v);
1497         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1498         CtoI *ctoi_modd = value2ctoi(v);
1499         CtoI *ctoi_fin; 
1500         #{pgm_src}
1501         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1502         rmod_rtn->cmod = ctoi_fin;
1503         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1504 }
1505 "
1506 SCP_EOF
1507
1508 func[': print expr']=<<'SCP_EOF'
1509 "
1510 /*
1511  *  : print expr
1512  */
1513
1514 VALUE vsop_print(VALUE self){
1515         Vsop_Ruby* rmod;
1516         Data_Get_Struct(self,Vsop_Ruby,rmod);
1517         CtoI *ctoi_modb =new CtoI(*rmod->cmod);
1518         #{pgm_src}
1519         return self;
1520 }
1521 "
1522 SCP_EOF
1523
1524 func['| expr PLUS expr']=<<'SCP_EOF'
1525 "
1526 /*
1527  * call-seq:
1528  * zdd1 + zdd2 -> ZDD Object : 加算演算子
1529  *
1530  *  zdd1,zdd2 : ZDD Object
1531  *
1532  * === 説明
1533  * zdd1とzdd2の対応するアイテム集合同士の重みの加算を行う。
1534  *
1535  * === 例
1536  *  > x.show
1537  *   3 a + 2 b
1538  *  > y.show
1539  *   2 a + 2 b + 4 c
1540  *  # x,yが上記の通り定義されていたとする。
1541  *
1542  *  > (x+y).show
1543  *   5 a + 4 b + 4 c
1544  */
1545
1546 VALUE vsop_plus(int argc, VALUE *argv,VALUE self){
1547         Vsop_Ruby* rmod;
1548         VALUE v;
1549         Data_Get_Struct(self,Vsop_Ruby,rmod);
1550         rb_scan_args(argc, argv,\"10\",&v);
1551         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1552         CtoI *ctoi_modc = value2ctoi(v);
1553         CtoI *ctoi_fin;
1554         #{pgm_src}
1555         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1556         rmod_rtn->cmod = ctoi_fin;
1557         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1558 }
1559 "
1560 SCP_EOF
1561
1562 func['| expr MINUS expr']=<<'SCP_EOF'
1563 "
1564 /*
1565  * call-seq:
1566  * zdd1 - zdd2 -> ZDD Object : 減算演算子
1567  *
1568  *  zdd1,zdd2 : ZDD Object
1569  *
1570  * === 説明
1571  * zdd1とzdd2の対応するアイテム集合同士の重みの減算を行う。
1572  *
1573  * === 例
1574  *  > x.show
1575  *   3 a + 2 b
1576  *  > y.show
1577  *   2 a + 2 b + 4 c
1578  *  # x,yが上記の通り定義されていたとする。
1579  *
1580  *  > (x-y).show
1581  *   a - 4 c
1582  *  > (y-x).show
1583  *   -a + 4 c
1584  */
1585
1586 VALUE vsop_minus(int argc, VALUE *argv,VALUE self){
1587         Vsop_Ruby* rmod;
1588         VALUE v;
1589         Data_Get_Struct(self,Vsop_Ruby,rmod);
1590         rb_scan_args(argc, argv,\"10\",&v);
1591         CtoI *ctoi_moda =new CtoI(*rmod->cmod);
1592         CtoI *ctoi_modc = value2ctoi(v);
1593         CtoI *ctoi_fin; 
1594         #{pgm_src}
1595         Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1596         rmod_rtn->cmod = ctoi_fin;
1597         return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1598 }
1599 "
1600 SCP_EOF
1601
1602
1603
1604
1605 def extract_pgm(src)
1606         start_char =0
1607         end_char =0
1608         writeflg=1
1609         pgmsrc = ""
1610
1611         src.each{|line|
1612                 writeflg =1
1613                 if "#{line}" =~ /\{/ then
1614                         if(start_char==0) then 
1615                                 writeflg= 0
1616                         end
1617                         start_char= start_char + 1
1618                 elsif "#{line}" =~ /\}/ then
1619                         end_char = end_char + 1
1620                         if(start_char==end_char) then
1621                                 pgmsrc =pgmsrc.gsub("$1.str", "str_a")
1622                                 pgmsrc =pgmsrc.gsub("$2.str", "str_b")
1623                                 pgmsrc =pgmsrc.gsub("$3.str", "str_c")
1624                                 pgmsrc =pgmsrc.gsub("$4.str", "str_d")
1625                                 pgmsrc =pgmsrc.gsub("$5.str", "str_e")
1626                                 pgmsrc =pgmsrc.gsub("$6.str", "str_f")
1627                                 pgmsrc =pgmsrc.gsub("$1.len", "len_a")
1628                                 pgmsrc =pgmsrc.gsub("$2.len", "len_b")
1629                                 pgmsrc =pgmsrc.gsub("$3.len", "len_c")
1630                                 pgmsrc =pgmsrc.gsub("$4.len", "len_d")
1631                                 pgmsrc =pgmsrc.gsub("$5.len", "len_e")
1632                                 pgmsrc =pgmsrc.gsub("$6.len", "len_f")
1633                                 pgmsrc =pgmsrc.gsub("$$", "ctoi_fin")
1634                                 pgmsrc =pgmsrc.gsub("$1", "ctoi_moda")
1635                                 pgmsrc =pgmsrc.gsub("$2", "ctoi_modb")
1636                                 pgmsrc =pgmsrc.gsub("$3", "ctoi_modc")
1637                                 pgmsrc =pgmsrc.gsub("$4", "ctoi_modd")
1638                                 pgmsrc =pgmsrc.gsub("$5", "ctoi_mode")
1639                                 pgmsrc =pgmsrc.gsub("$6", "ctoi_modf")
1640                                 return pgmsrc
1641                         end
1642                 end
1643                 if(writeflg == 1)then
1644                         pgmsrc = pgmsrc + "#{line}"
1645                 end
1646         }
1647 end
1648
1649 def func_set(func)
1650         ##最初に%{から%}までint main以外をすべて抜き出す
1651         File.open("SAPPOROBDD/app/VSOP/vsopyacc.y++","r"){|src|
1652                 writeflg=0
1653                 mainflg=0
1654                 main_s=0
1655                 main_e=0
1656                 src.each{|line| 
1657                         if "#{line}" =~ /^%\{/ then
1658                                 writeflg=1
1659                         elsif "#{line}" =~ /^%\}/ then
1660                                 break 
1661                         elsif "#{line}" =~ /^int main/ then
1662                                 mainflg=1
1663                                 writeflg=0
1664                         elsif "#{line}" =~ /\{|\}/ and mainflg == 1 then
1665                                 if "#{line}" =~ /\{/ then
1666                                         main_s = main_s+1
1667                                 end 
1668                                 if "#{line}" =~ /\}/ then
1669                                         main_e = main_e+1
1670                                         if main_s == main_e then
1671                                                 writeflg =1
1672                                                 mainflg = 0
1673                                         end 
1674                                 end 
1675                         else
1676                                 if writeflg==1 then
1677                                         File.open("zdd_so.cpp","a"){|file|
1678                                                 file.puts line
1679                                         }
1680                                 end                             
1681                         end
1682                 }
1683         }
1684         #パターンごとの記述を抜き出す
1685         File.open("SAPPOROBDD/app/VSOP/vsopyacc.y++","r"){|src|
1686                 src.each{|line| 
1687                         if not func[line.squeeze(" ").chomp.lstrip.rstrip].nil?then
1688                         key = line.squeeze(" ").chomp.lstrip.rstrip
1689                         pgm_src = extract_pgm(src)
1690                         File.open("zdd_so.cpp","a"){|file|
1691                                 eval "file.puts " + func[key]
1692                         }
1693                         end
1694                 }
1695         }
1696 end             
1697
1698
1699 if(File.exist?("zdd_so.cpp"))then
1700         File.delete("zdd_so.cpp")
1701 end
1702
1703
1704 #zdd.cxxにsetfunc.cppを入れ込み、zdd_so.cppを作成
1705 File.open("zdd_so.cxx","r"){|src|
1706         src.each{|line| 
1707                 if "#{line}" =~ /^#include \"setfunc\.cpp\"/ then
1708                         func_set(func)
1709                 else
1710                         File.open("zdd_so.cpp","a"){|file|
1711                                 file.puts line
1712                         }
1713                 end
1714         }
1715 }
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725