8 extern int CtoI_Lcm1_ub(char *, char *, int, int, int); // by ham
12 #define RSTRING_PTR(s) (RSTRING(s)->ptr)
15 #define RARRAY_PTR(s) (RARRAY(s)->ptr)
21 CtoI* string2ctoi(char *str);
22 CtoI* int2ctoi(int val);
23 CtoI *value2ctoi(VALUE v);
24 //------------------------------------------------------------------------------
26 //------------------------------------------------------------------------------
32 kgAutoPtr2(T* ptr=0) : _ptr(ptr) {};
33 virtual ~kgAutoPtr2(void) { if(_ptr != NULL) delete[] _ptr; }
34 T* get(void) const throw() { return _ptr; }
35 void set(T* ptr) throw() { if(_ptr!=NULL) delete[] _ptr; _ptr=ptr; }
36 void clear(void) { if(_ptr!=NULL) delete[] _ptr; _ptr=0;}
44 if(cmod!=0) delete cmod;
47 void free_rmod(Vsop_Ruby* rmod){
55 #define DEF_ENV_NMAX 400000000
57 bool env_warning = false;
59 #include "setfunc.cpp"
62 #define MAX_LEN 409600
67 #define HASH_MAX 409600
77 static int Depth_item;
78 static int* S_Var_item;
80 static int* S_Var_ary;
83 static int PutNum(CtoI a, int base,ofstream &fs)
85 if(a.TopItem() > 0) a = a.MaxVal();
86 int d = a.TopDigit() / 3 + 14;
87 kgAutoPtr2<char> a_ptr;
90 a_ptr.set(new char[d]);
93 rb_raise(rb_eRuntimeError,"memory allocation error");
96 if(base == 16) err = a.StrNum16(s);
97 else err = a.StrNum10(s);
98 if(err == 1) return 1;
104 static int PF(CtoI a, int base,ofstream &fs)
108 if(PFflag == 1){fs << endl;}
109 if(a.TopDigit() & 1) {fs << "-" ; a = -a; }
115 if(PutNum(a, base,fs) == 1) return 1;
120 for(int i=0; i<Depth; i++)
122 if(i==0){fs << VTable.GetName(S_Var[i]);}
123 else{fs << " " << VTable.GetName(S_Var[i]);}
128 CtoI b = a.Factor1(v);
129 if(b == CtoI_Null()) return 1;
132 if(PF(b, base,fs) == 1) return 1;
136 if(b == CtoI_Null()) return 1;
137 return PF(b, base,fs);
140 int CsvoutCtoI(CtoI a,ofstream &fs)
142 if(a == CtoI_Null()) return 1;
146 int lev = BDD_LevOfVar(a.TopItem());
148 kgAutoPtr2<int> a_ptr;
150 a_ptr.set(new int[lev]);
153 rb_raise(rb_eRuntimeError,"memory allocation error");
156 int err = PF(a, 10,fs);
158 rb_raise(rb_eRuntimeError,"memory over flow");
167 * zdd.csvout(fileName) -> self : CSV出力
170 * fileName : Ruby String
173 * zddオブジェクトの内容をfileNameで指定したファイル名にCSV形式で出力する。
174 * 項目は、重みとアイテム集合がこの順番で出力される。
176 * 空のアイテム集合はnull値として出力される。
180 * > a.show # -> a b + 2 b c + 3 d + 4
181 * > a.csvout("output.csv")
192 VALUE vsop_csvout(int argc, VALUE *argv, VALUE self) {
195 Data_Get_Struct(self,Vsop_Ruby,rmod);
196 rb_scan_args(argc, argv,"10",&v);
197 char *str = RSTRING_PTR(v);
200 CsvoutCtoI(*rmod->cmod,fs);
205 static int PF_hash(CtoI a, int base,VALUE& hash)
209 char valstr[MAX_LEN];
210 if(a.TopDigit() & 1) {strcpy(valstr,"-") ; a = -a; }
211 else{ strcpy(valstr,"");}
217 kgAutoPtr2<char> a_ptr;
220 if(a.TopItem() > 0) a = a.MaxVal();
221 int d = a.TopDigit() / 3 + 14;
223 a_ptr.set(new char[d]);
224 valrtn = a_ptr.get();
226 rb_raise(rb_eRuntimeError,"memory allocation error");
229 if(base == 16) err = a.StrNum16(valrtn);
230 else err = a.StrNum10(valrtn);
233 rb_raise(rb_eRuntimeError,"memory over flow");
236 strcat(valstr,valrtn);
242 char keystr[MAX_LEN];
244 for(int i=0; i<Depth; i++)
246 int size = strlen(keystr)+strlen(VTable.GetName(S_Var[i]))+2;
248 rb_raise(rb_eRuntimeError,"string size over flow");
251 strcpy(keystr,VTable.GetName(S_Var[i]));
255 strcat(keystr,VTable.GetName(S_Var[i]));
259 VALUE key = rb_str_new2(keystr);
260 VALUE val = INT2NUM(atoi(valstr));
261 rb_hash_aset(hash, key, val);
263 if(hashcnt> HASH_MAX){return 2;}
267 printf("HPF_2 %d\n",v);
268 CtoI b = a.Factor1(v);
269 if(b == CtoI_Null()) return 1;
272 int chk=PF_hash(b, base,hash);
273 if(chk > 0) return chk;
277 if(b == CtoI_Null()) return 1;
279 return PF_hash(b, base,hash);
283 static void num_check(char *str){
284 //数値チェック(アイテムが数値なら警告)
286 if(*p=='-' || *p=='+' ) p++;
288 if( ( *p>='0' && *p<='9' ) || *p == '.' ){
289 fprintf(stderr,"chech %c\n",*p);
290 fprintf(stderr,"use numbers for symbol Variable\n");
299 VALUE HashoutCtoI(CtoI a,int *rtn)
302 VALUE hash = rb_hash_new();
303 if(a == CtoI_Null()) return 1;
307 int lev = BDD_LevOfVar(a.TopItem());
309 kgAutoPtr2<int> a_ptr;
311 a_ptr.set(new int[lev]);
314 rb_raise(rb_eRuntimeError,"memory allocation error");
317 int err = PF_hash(a, 10,hash);
320 rb_raise(rb_eRuntimeError,"memory over flow");
321 return rb_hash_new();
332 * zdd.hashout -> hash : Hash出力
338 * zddの内容をrubyのHashオブジェクトに変換し、そのオブジェクトを返す。
339 * ハッシュキーはアイテム集合、対応する値は重み。
343 * a b + 2 b c + 3 d + 4
347 * {""=>4, "a b"=>1, "d"=>3, "b c"=>2}
352 VALUE vsop_hashout(VALUE self){
355 Data_Get_Struct(self,Vsop_Ruby,rmod);
356 VALUE hash = HashoutCtoI(*rmod->cmod,&rtnflg);
358 rb_iv_set(self,"@partly", Qtrue );
361 rb_iv_set(self,"@partly", Qfalse);
369 static int PF_array_each(CtoI a, VALUE& self)
374 char valstr[MAX_LEN];
375 if(a.TopDigit() & 1) {sign= -1 ; a = -a; }
379 kgAutoPtr2<char> a_ptr;
380 if(c1 || Depth_e == 0)
382 if(a.TopItem() > 0) a = a.MaxVal();
383 int d = a.TopDigit() / 3 + 14;
385 a_ptr.set(new char[d]);
386 valrtn = a_ptr.get();
388 rb_raise(rb_eRuntimeError,"memory allocation error");
390 int err = a.StrNum10(valrtn);
392 rb_raise(rb_eRuntimeError,"memory over flow");
395 rtn = CtoI(CtoI_atoi(valrtn));
398 rtn = CtoI(CtoI_atoi("1"));;
401 for(int i=0; i<Depth_e; i++)
403 char *str = VTable.GetName(S_Var_e[i]);
404 int ckck = VTable.GetID(str);
405 rtn =Product(rtn, CtoI(1).AffixVar( ckck));
408 Vsop_Ruby* rmod=new Vsop_Ruby;
409 rmod->cmod = new CtoI (rtn) ;
410 rb_yield_values(1,Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod));
415 CtoI b = a.Factor1(v);
416 if(b == CtoI_Null()) return 1;
417 S_Var_e[Depth_e] = v;
419 int chk=PF_array_each(b, self);
420 if(chk > 0) return chk;
424 if(b == CtoI_Null()) return 1;
425 return PF_array_each(b,self);
428 //////////////////////////////////////////////
429 void CtoI2Array_each(CtoI a,VALUE &self)
431 if(a == CtoI_Null()) return ;
435 int lev = BDD_LevOfVar(a.TopItem());
437 kgAutoPtr2<int> a_ptr;
439 a_ptr.set(new int[lev]);
440 S_Var_e = a_ptr.get();
442 rb_raise(rb_eRuntimeError,"memory allocation error");
444 PF_array_each(a, self);
449 * zdd.each{|x|} -> Qtrue
451 * ZDDからアイテムセットを1つずつ読み込み,指定されたブロックを実行する.
456 * # x,yが上記の通り定義されていたとする。
465 VALUE vsop_each(VALUE self){
467 Data_Get_Struct(self,Vsop_Ruby,rmod);
468 CtoI2Array_each(*rmod->cmod,self);
478 static int PF_array(CtoI a,VALUE& array)
482 char valstr[MAX_LEN];
483 if(a.TopDigit() & 1) {strcpy(valstr,"-") ; a = -a; }
484 else{ strcpy(valstr,"");}
490 kgAutoPtr2<char> a_ptr;
493 if(a.TopItem() > 0) a = a.MaxVal();
494 int d = a.TopDigit() / 3 + 14;
496 a_ptr.set(new char[d]);
497 valrtn = a_ptr.get();
499 rb_raise(rb_eRuntimeError,"memory allocation error");
502 err = a.StrNum10(valrtn);
505 rb_raise(rb_eRuntimeError,"memory over flow");
508 strcat(valstr,valrtn);
511 char keystr[MAX_LEN];
513 for(int i=0; i<Depth; i++)
515 int size = strlen(keystr)+strlen(VTable.GetName(S_Var_ary[i]))+2;
517 rb_raise(rb_eRuntimeError,"string size over flow");
520 strcpy(keystr,VTable.GetName(S_Var_ary[i]));
524 strcat(keystr,VTable.GetName(S_Var_ary[i]));
527 if(*valstr&& *keystr){
529 strcat(valstr,keystr);
531 else{strcat(valstr,keystr); }
533 VALUE val = rb_str_new2(valstr);
534 rb_ary_push(array,val);
538 CtoI b = a.Factor1(v);
539 if(b == CtoI_Null()) return 1;
540 S_Var_ary[Depth] = v;
542 int chk=PF_array(b, array);
543 if(chk > 0) return chk;
547 if(b == CtoI_Null()) return 1;
549 return PF_array(b, array);
553 VALUE CtoI2Array(CtoI a)
555 VALUE array = rb_ary_new();
556 if(a == CtoI_Null()) return array;
557 if(a == 0) return array;
560 int lev = BDD_LevOfVar(a.TopItem());
562 kgAutoPtr2<int> a_ptr;
564 a_ptr.set(new int[lev]);
565 S_Var_ary = a_ptr.get();
567 rb_raise(rb_eRuntimeError,"memory allocation error");
569 int err = PF_array(a, array);
571 rb_raise(rb_eRuntimeError,"memory over flow");
581 * ZDDからアイテムセット文字列の配列を返す.
586 * # x,yが上記の通り定義されていたとする。
589 * [ "4 a c","2 a","2 b"]
591 VALUE vsop_to_a(VALUE self){
593 Data_Get_Struct(self,Vsop_Ruby,rmod);
594 VALUE array = CtoI2Array(*rmod->cmod);
604 static int PutNum_str(CtoI a, int base,VALUE &str)
606 if(a.TopItem() > 0) a = a.MaxVal();
607 int d = a.TopDigit() / 3 + 14;
608 kgAutoPtr2<char> a_ptr;
611 a_ptr.set(new char[d]);
614 rb_raise(rb_eRuntimeError,"memory allocation error");
617 if(base == 16) err = a.StrNum16(s);
618 else err = a.StrNum10(s);
619 if(err == 1) return 1;
620 rb_str_cat(str,s,strlen(s));
625 static int PF_str(CtoI a,VALUE str)
629 if(PFflag == 1){rb_str_cat(str," + ",strlen(" + "));}
630 if(a.TopDigit() & 1) {rb_str_cat(str," - ",strlen(" - ")); a = -a; }
636 if(PutNum_str(a, 10,str) == 1) return 1;
637 rb_str_cat(str," ",strlen(" "));
640 for(int i=0; i<Depth; i++)
642 char *p = VTable.GetName(S_Var[i]);
643 rb_str_cat(str,p,strlen(p));
644 if( i<Depth-1) rb_str_cat(str," ",strlen(" "));
649 CtoI b = a.Factor1(v);
650 if(b == CtoI_Null()) return 1;
653 if(PF_str(b, str) == 1) return 1;
657 if(b == CtoI_Null()) return 1;
658 return PF_str(b,str);
661 VALUE CtoI2String(CtoI a)
663 VALUE str = rb_str_new2("");
665 if(a == CtoI_Null()) return str;
666 if(a == 0) return str;
669 int lev = BDD_LevOfVar(a.TopItem());
671 kgAutoPtr2<int> a_ptr;
673 a_ptr.set(new int[lev]);
676 rb_raise(rb_eRuntimeError,"memory allocation error");
679 int err = PF_str(a, str);
681 rb_raise(rb_eRuntimeError,"memory over flow");
692 * ZDDからアイテムセット文字列を返す.
697 * # x,yが上記の通り定義されていたとする。
700 * "4 a c + 2 a + 2 b"
702 VALUE vsop_to_s(VALUE self){
704 Data_Get_Struct(self,Vsop_Ruby,rmod);
705 VALUE str = CtoI2String(*rmod->cmod);
711 /////////// each_item用
712 static int PF_itemarray(CtoI a, VALUE& self)
717 char valstr[MAX_LEN];
718 if(a.TopDigit() & 1) {sign= -1 ; a = -a; }
722 kgAutoPtr2<char> a_ptr;
723 if(c1 || Depth_item == 0)
725 if(a.TopItem() > 0) a = a.MaxVal();
726 int d = a.TopDigit() / 3 + 14;
728 a_ptr.set(new char[d]);
729 valrtn = a_ptr.get();
731 rb_raise(rb_eRuntimeError,"memory allocation error");
733 int err = a.StrNum10(valrtn);
735 rb_raise(rb_eRuntimeError,"memory over flow");
738 weight = INT2NUM(atoi(valrtn));
746 for(int i=0; i<Depth_item; i++){
747 char *str = VTable.GetName(S_Var_item[i]);
748 int ckck = VTable.GetID(str);
749 Vsop_Ruby* rmod=new Vsop_Ruby;
750 rmod->cmod = new CtoI (CtoI(1).AffixVar( ckck)) ;
751 if( i>0 ) top=Qfalse;
752 if( i+1==Depth_item ) bottom=Qtrue;
753 rb_yield_values(4,weight,Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod) ,top,bottom);
758 CtoI b = a.Factor1(v);
759 if(b == CtoI_Null()) return 1;
760 S_Var_item[Depth_item] = v;
762 int chk=PF_itemarray(b, self);
763 if(chk > 0) return chk;
767 if(b == CtoI_Null()) return 1;
768 return PF_itemarray(b,self);
771 //////////////////////////////////////////////
772 void CtoI2ItemArray(CtoI a,VALUE &self)
774 VALUE ary = rb_ary_new();
775 if(a == CtoI_Null()) return;
779 int lev = BDD_LevOfVar(a.TopItem());
781 kgAutoPtr2<int> a_ptr;
783 a_ptr.set(new int[lev]);
784 S_Var_item = a_ptr.get();
786 rb_raise(rb_eRuntimeError,"memory allocation error");
788 PF_itemarray(a, self);
796 * zdd.each_item{|val ,item,top,botom |} -> Qtrue
798 * ZDDをアイテムセットのアイテムを1つずつ読み込み,指定されたブロックを実行する.
801 * zddeach {|weight,item,top,bottom|}
802 * weight :: アイテムセットの重み
804 * top :: アイテムセットの最初のアイテムであればture、それ以外はfalse
805 * bottom :: アイテムセットの最後のアイテムであればture、それ以外はfalse.
810 * # x,yが上記の通り定義されていたとする。
812 * > f.each_item{|val,x,t,b|
840 VALUE vsop_each_item(VALUE self){
842 Data_Get_Struct(self,Vsop_Ruby,rmod);
843 CtoI2ItemArray(*rmod->cmod,self);
848 //この値はBDDライブラリとかぶらないよう注意すること
850 static const char BC_CtoI_DELTA = 50;
852 CtoI CtoI_Delta(CtoI a, CtoI b)
854 if(a == CtoI_Null()) return a;
855 if(b == CtoI_Null()) return b;
858 if(a == 1 && b==1) return 1;
863 if(BDD_LevOfVar(atop) < BDD_LevOfVar(btop)) return CtoI_Delta(b, a);
865 bddword ax = a.GetZBDD().GetID();
866 bddword bx = b.GetZBDD().GetID();
867 if(atop == btop && ax < bx) return CtoI_Delta(b, a);
869 ZBDD z = BDD_CacheZBDD(BC_CtoI_DELTA, ax, bx);
870 if(z != -1) return CtoI(z);
872 CtoI a0 = a.Factor0(atop);
873 CtoI a1 = a.Factor1(atop);
877 if(a.IsBool()) c = CtoI_Union( CtoI_Delta(a0, b), CtoI_Delta(a1, b).AffixVar(atop) );
878 else c = CtoI_Delta(a0, b) + CtoI_Delta(a1, b).TimesSysVar(atop);
882 CtoI b0 = b.Factor0(atop);
883 CtoI b1 = b.Factor1(atop);
885 c = CtoI_Union( CtoI_Delta(a0, b0) + CtoI_Delta(a1, b1),
886 (CtoI_Delta(a1, b0)+ CtoI_Delta(a0, b1)).AffixVar(atop) ) ;
888 c = CtoI_Delta(a0, b0)
889 + (CtoI_Delta(a1, b0) + CtoI_Delta(a0, b1)).TimesSysVar(atop)
890 + CtoI_Delta(a1, b1).TimesSysVar(atop-1);
891 else BDDerr("CtoI_Delta(): SysVar overflow.");
893 BDD_CacheEnt(BC_CtoI_DELTA, ax, bx, c.GetZBDD().GetID());
899 * zdd1.delta(zdd2) -> ZDD Object : delta演算
901 * zdd1,zdd2 : ZDD Object
904 * zdd1に含まれるアイテム集合αとzdd2に含まれるアイテム集合βのα ⊕βを求める。
905 * 例えば、アイテム集合abc と bcd の排他的論理和は以下の通り。
906 * abc.delta(bcd) = abc ⊕ bcd = ad
907 * 複数のアイテム集合間の演算では全組合せについて排他的論理和を求める。
908 * (abc + a).delta(bcd + b) = abc ⊕ bcd + abc ⊕ b + a ⊕ bcd + a ⊕ b
909 * = ad + ac + abcd + ab
910 * 重みについては、同じアイテム集合を複数に展開して計算すればよい。
911 * (2abc).delta(bcd) = (abc+abc).delta(bcd) = ad + ad = 2ad
914 * > a=VSOP.itemset("a")
915 * > b=VSOP.itemset("b")
918 * # a + 2ab + 3b の各アイテム集合と引き数で指定されたアイテム集合 a との排他的論理和を求めると、
919 * # 3 a b + 2 b + 1 となる。
923 * # アイテム集合bとの排他的論理和を求めると a b + 2 a + 3 となる。
927 * # アイテム集合 ab との排他的論理和を求めると 3 a + b + 2 となる。
928 * > f.delta(a*b).show
931 * # 定数1は空のアイテム集合なので、それとの排他的論理和を求めると元の集合のままとなる。
936 * > a=VSOP.itemset("a")
937 * > b=VSOP.itemset("b")
938 * > c=VSOP.itemset("c")
940 * > f=((a*b*c)+2*(a*b)+(b*c)+1)
942 * a b c + 2 a b + b c + 1
947 * # abc + 2ab + bc + 1 の各アイテム集合と引き数で指定された 2ab + a の各アイテム集合との排他的論理和を求めると、
948 * # 以下の通りとなる(アイテム間のスペースは省略)。
957 * # 結果をまとめると a b c + 2 a b + 2 a c + a + b c + 2 b + 2 c + 4 となる。
960 * a b c + 2 a b + 2 a c + a + b c + 2 b + 2 c + 4
962 * ====== 上記の例において出力結果を示したコメントでは、アイテムをアルファベット小文字1文字で表し、項における重みとアイテム間のスペースおよびアイテム間のスペースを省略して表記している。
965 VALUE vsop_delta(int argc, VALUE *argv,VALUE self){
968 Data_Get_Struct(self,Vsop_Ruby,rmod);
969 rb_scan_args(argc, argv,"10",&v);
970 CtoI *ctoi_moda =new CtoI(*rmod->cmod);
971 CtoI *ctoi_modc = value2ctoi(v);
973 *ctoi_moda = CtoI_Delta(*ctoi_moda, *ctoi_modc);
974 ctoi_fin = ctoi_moda;
976 Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
977 rmod_rtn->cmod = ctoi_fin;
978 return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
981 CtoI* string2ctoi(char *str){
984 v = rb_cv_get(self,"@@init_cnt");
985 int init_cnt_v = NUM2INT(v);
986 if(init_cnt_v==0){ BDDV_Init(256, env_nmax);}
988 rb_cv_set(self,"@@init_cnt",INT2NUM(init_cnt_v));
991 if(init_cnt==0){ BDDV_Init(256, env_nmax);}
994 for(char *p=str;*p;p++){
1000 kgAutoPtr2<CtoI> a_ptr;
1003 a_ptr.set(new CtoI[sep_cnt]);
1004 ctoitmp = a_ptr.get();
1006 rb_raise(rb_eRuntimeError,"memory allocation error");
1015 int var = VTable.GetID(q);
1017 if(env_warning){ num_check(q); }
1018 VTable.SetB(q, power16/2);
1019 var = VTable.GetID(q);
1021 ctoitmp[i] = CtoI(1).AffixVar(var);
1025 else if(*p=='\0'){//終了時文字
1026 int var = VTable.GetID(q);
1028 if(env_warning){ num_check(q); }
1029 VTable.SetB(q, power16/2);
1030 var = VTable.GetID(q);
1032 ctoitmp[i] = CtoI(1).AffixVar(var);
1037 CtoI ctmp = ctoitmp[0];
1038 for(int i=1;i<sep_cnt;i++){
1039 ctmp = Product(ctmp,ctoitmp[i]);
1041 CtoI *rtnctoi = new CtoI(ctmp);
1045 //VALUEを受け取り、CtoI*を返す
1046 CtoI *value2ctoi(VALUE v){
1049 if(TYPE(v)==T_STRING){
1050 rtnctoi=string2ctoi(RSTRING_PTR(v));
1052 else if(TYPE(v)==T_FIXNUM){
1053 rtnctoi=int2ctoi(FIX2INT(v));
1055 else if(TYPE(v)==T_BIGNUM){
1056 rtnctoi=int2ctoi(NUM2INT(v));
1059 Data_Get_Struct(v,Vsop_Ruby,argrmod);
1060 rtnctoi =new CtoI(*argrmod->cmod);
1067 * 書式1) ZDD.symbol(itemName, value, to) -> Qture : シンボル変数の宣言
1068 * 書式2) ZDD.symbol -> itemList : シンボル変数の一覧
1070 * itemName : Ruby String
1071 * value : Ruby Float
1073 * itemList : Ruby String
1077 * itemNameで指定した文字列のZDDアイテム名を宣言する。
1078 * アイテム名として利用できる文字種に特に制限はない。また文字列長についても特に制限はない(メモリ容量制限のみ)。
1079 * valueは、そのアイテムに与える値で、valueやmaxcoverなどのメソッドで利用される。詳しくは、valueメソッドを参照のこと。
1081 * toは宣言したアイテムの追加する方向を指定する(top | bottom)。
1082 * 省略時にはbottomが設定される。
1084 * 引数なしでこのメソッドを呼び出すと、シンボル変数の一覧がスペース区切りの文字列として返される。
1087 * > ZDD.symbol("a",1.0)
1088 * > ZDD.symbol("b",0.5)
1089 * > ZDD.symbol("c",2.0,"top")
1094 * > (1..10).each{|i|
1095 * > ZDD.symbol("s_#{i}",i)
1098 * c a b d s_1 s_2 s_3 s_4 s_5 s_6 s_7 s_8 s_9 s_10
1103 VALUE vsop_symbol(int argc, VALUE *argv, VALUE self) {
1107 if(init_cnt==0){ BDDV_Init(256, env_nmax);}
1115 rb_scan_args(argc, argv,"12",&v1,&v2,&v3);
1118 if(TYPE(v3)!=T_STRING){
1119 rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
1121 to = RSTRING_PTR(v3);
1123 if(TYPE(v2)==T_FLOAT){
1124 val = (int)( NUM2DBL(v2)*power16);
1126 else if(TYPE(v2)==T_FIXNUM){
1127 val = NUM2INT(v2)*power16;
1129 else if(TYPE(v2)==T_NIL){
1132 rb_raise(rb_eRuntimeError,"argument type error (arguments must be FLOAT or INT or NIL)");
1135 if(TYPE(v1)!=T_STRING){
1136 rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
1138 str = RSTRING_PTR(v1);
1139 //数値チェック(アイテムが数値なら警告)
1140 if(env_warning){ num_check(str); }
1143 rb_raise(rb_eRuntimeError,"argument type error");
1147 int var = VTable.GetID(str);
1149 if(!strcmp(to,"top")) { VTable.SetT(str, val);}
1150 else { VTable.SetB(str, val);}
1156 int n = VTable.Used();
1158 for(int i=n; i>0; i--)
1160 int var = BDD_VarOfLev(i);
1161 str += VTable.GetName(var);
1164 rtn = rb_str_new2(str.c_str());
1170 * ZDD.itemset(itemSets) -> zdd : アイテム集合のzddオブジェクトの作成
1172 * itemSets : Ruby String
1176 * itemSetsで指定されたアイテム集合のzddオブジェクトを生成する。
1177 * 複数のアイテムは半角スペースで区切る。
1178 * 空文字("")が指定された場合は空のアイテム集合と扱われ、積和表現の定数項1として設定される(zdd.constant(1)と同様)。
1179 * symbolメソッドで宣言されていないアイテムは現在のアイテム順の最後に追加される。
1180 * またアイテムに設定される値はデフォルトの0.5となる。
1183 * > a=ZDD.itemset("a b")
1187 * > b=ZDD.itemset("b")
1191 * > c=ZDD.itemset("")
1195 * # 数字をアイテム名として利用することも可能
1196 * > x0=ZDD.itemset("2")
1200 * # ただし、表示上重みと区別がつかなくなるので注意が必要。
1204 * # こんな記号ばかりのアイテム名もOK。
1205 * > x1=ZDD.itemset("!#%&'()=~|@[;:]")
1209 * # ただし、rubyで特殊な意味を持つ記号はエスケープする必要がある。
1210 * > x2=ZDD.itemset("\\\$\"")
1215 * > x3=ZDD.itemset("りんご ばなな")
1220 * symbol, constant, value
1222 VALUE vsop_itemset(int argc, VALUE *argv, VALUE self) {
1224 Vsop_Ruby* rmod=new Vsop_Ruby;
1228 rb_scan_args(argc, argv,"10",&v);
1229 if(TYPE(v)!=T_STRING){
1230 rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
1233 char *str = RSTRING_PTR(v);
1235 rmod->cmod = int2ctoi(1);
1238 rmod->cmod = string2ctoi(str);
1241 return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod);
1244 CtoI * int2ctoi(int val){
1246 if(init_cnt==0){ BDDV_Init(256, env_nmax);}
1249 sprintf(wrkval,"%d",val);
1250 CtoI *rtnctoi = new CtoI(CtoI_atoi(wrkval));
1256 * ZDD.constant(weight) -> zdd : ZDD重みオブジェクトの生成
1258 * weight : Ruby Integer
1262 * weightで指定した整数をZDDの重みオブジェクト(空のアイテム集合の重み)に変換する。
1265 * > c=ZDD.constant(10)
1269 * > c*"a" -> 10 a # ZDD重みオブジェクトとruby文字列との演算では、ruby文字列はアイテム集合と見なされ自動でZDDオブジェクトにキャストされる。
1270 * > 0*c -> 0 # ZDD重みオブジェクトとruby整数との演算では、ruby整数はZDD重みオブジェクトと見なされる。
1271 * > puts c.to_i*10 # ZDD重みオブジェクトをruby整数に変換し、ruby整数として演算する。
1274 * # 以下のように、0の重みを定義しておくと、そのオブジェクトとの演算においては、RubyStringを自動的にキャストしてくれるので便利である。
1275 * > a=ZDD.constant(0)
1285 VALUE vsop_constant(int argc, VALUE *argv, VALUE self) {
1286 Vsop_Ruby* rmod=new Vsop_Ruby;
1290 rb_scan_args(argc, argv,"10",&v);
1294 if(TYPE(v)==T_FIXNUM){
1295 rmod->cmod = int2ctoi(FIX2INT(v));
1298 else if(TYPE(v)==T_BIGNUM){
1299 rmod->cmod = int2ctoi(NUM2INT(v));
1302 rb_raise(rb_eRuntimeError,"argument type error (arguments must be FIXNUM or BIGNUM)");
1304 VALUE rtn = Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod);
1309 * ZDD.lcm(transaction, type,fixnum [,order]) -> zdd : lcm over zdd(最大サポート指定可能)
1311 * transaction : RubyString
1313 * minSupport : RubyInteger
1314 * order : RubyString
1318 * transactionで指定されたファイルから、LCM over zdd アルゴリズムを利用し頻出パターンを列挙しそのZDDオブジェクトを返す。
1319 * 列挙する頻出パターンの種別はtypeで与える("F":頻出集合, "M":極大集合, "C":飽和集合)。
1321 * orderファイルによりアイテムの宣言順序を制御できる。
1322 * 同じtransactionデータに対して異なる最小サポートで実行すると、本メソッドにおける内部的なアイテム宣言方法 (得られる全パターンにのみ含まれるアイテムについて、頻度の高い順に宣言される)が原因して宣言順序にずれが生じる可能性がある。
1323 * それを回避するために、頻度1以上の全アイテムを頻度の高い順に登録したorderファイルを用意し、本メソッドに与える。
1324 * orderファイルの作成についてはlcm-ruby拡張パッケージのメソッドを利用することで得ることができる。
1326 * transactionのデータ値は数字に変換しておく必要がある。
1330 * generates frequent patterns using LCM algorithm from the FIMI format database file "string2" with minimum support = "fixnum".
1331 * ===== "string1" specifies LCM parameter as:
1333 * * C clesed patterns,
1334 * * M maximal patterns,
1335 * * FQ all patterns with frequencies,
1336 * * CQ clesed patterns with frequencies,
1337 * * MQ maximal patterns with frequencies.
1339 * generates frequent patterns using LCM algorithm from the FIMI format database file "string1" with minimum support = "fixnum" and variable order file "string3".
1340 * ===== "string1" specifies LCM parameter as:
1342 * * C clesed patterns,
1343 * * M maximal patterns,
1344 * * FQ all patterns with frequencies,
1345 * * CQ clesed patterns with frequencies,
1346 * * MQ maximal patterns with frequencies.
1349 VALUE vsop_lcm(int argc, VALUE *argv, VALUE self){
1352 rtnval = vsop_lcm_order(argc,argv,self);
1355 rtnval = vsop_lcm_nomal(argc,argv,self);
1362 // ------------------------------ パターン長制約を入れたlcm over zdd
1364 VALUE vsop_lcm_nomal_ub(int argc, VALUE *argv, VALUE self){
1366 VALUE vz = rb_cv_get(self,"@@init_cnt");
1367 int init_cnt_v = NUM2INT(vz);
1368 if(init_cnt_v==0){ BDDV_Init(256, env_nmax);}
1370 rb_cv_set(self,"@@init_cnt",INT2NUM(init_cnt_v));
1372 if(init_cnt==0){ BDDV_Init(256, env_nmax);}
1377 rb_scan_args(argc, argv,"40",&v1,&v2,&v3,&v4);
1378 if(TYPE(v1)!=T_STRING){
1379 rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
1381 if(TYPE(v2)!=T_STRING){
1382 rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
1384 if(TYPE(v3)!=T_FIXNUM){
1385 rb_raise(rb_eRuntimeError,"argument type error (3rd argument must be FIXNUM)");
1387 if(TYPE(v4)!=T_FIXNUM){
1388 rb_raise(rb_eRuntimeError,"argument type error (4th argument must be FIXNUM)");
1390 char *arg1 = RSTRING_PTR(v1);
1391 char *arg2 = RSTRING_PTR(v2);
1392 int arg3_fix = FIX2INT(v3);
1393 int len_ub = FIX2INT(v4);
1398 char *str_c = new char[len+3];
1399 sprintf(str_c,"\"%s\"",arg1);
1403 char *str_d = new char[len+3];
1404 sprintf(str_d,"\"%s\"",arg2);
1407 char *str_e = new char[64];
1408 sprintf(str_e,"%d",arg3_fix);
1409 str_c[len_c - 1] = 0;
1410 str_d[len_d - 1] = 0;
1411 int th = atoi(str_e);
1412 if(strcmp(str_c+1, "F" ) == 0) CtoI_Lcm1_ub(str_d+1, 0, th, 0, len_ub);
1413 else if(strcmp(str_c+1, "C" ) == 0) CtoI_Lcm1_ub(str_d+1, 0, th, 1, len_ub);
1414 else if(strcmp(str_c+1, "M" ) == 0) CtoI_Lcm1_ub(str_d+1, 0, th, 2, len_ub);
1415 else if(strcmp(str_c+1, "FQ") == 0) CtoI_Lcm1_ub(str_d+1, 0, th, 10, len_ub);
1416 else if(strcmp(str_c+1, "CQ") == 0) CtoI_Lcm1_ub(str_d+1, 0, th, 11, len_ub);
1417 else if(strcmp(str_c+1, "MQ") == 0) CtoI_Lcm1_ub(str_d+1, 0, th, 12, len_ub); //11 -> 12 by ham
1418 for(int i=VTable.Used(); i<CtoI_LcmItems(); i++)
1422 int x = CtoI_LcmPerm(i);
1423 sprintf(s, "x%d", x);
1424 while(VTable.GetID(s) != 0)
1427 sprintf(s, "x%d_%d", x, t);
1429 VTable.SetT(s, power16/2);
1431 CtoI a = CtoI_Lcm2();
1432 ctoi_fin = new CtoI(a);
1437 Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1438 rmod_rtn->cmod = ctoi_fin;
1439 return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1443 VALUE vsop_lcm_order_ub(int argc, VALUE *argv, VALUE self){
1444 if(init_cnt==0){ BDDV_Init(256, env_nmax);}
1447 VALUE v1,v2,v3,v4,v5;
1449 rb_scan_args(argc, argv,"50",&v1,&v2,&v3,&v4,&v5);
1450 if(TYPE(v1)!=T_STRING){
1451 rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
1453 if(TYPE(v2)!=T_STRING){
1454 rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
1456 if(TYPE(v3)!=T_FIXNUM){
1457 rb_raise(rb_eRuntimeError,"argument type error (3rd argument must be FIXNUM)");
1459 if(TYPE(v4)!=T_STRING){
1460 rb_raise(rb_eRuntimeError,"argument type error (4th argument must be STRING)");
1462 if(TYPE(v5)!=T_FIXNUM){
1463 rb_raise(rb_eRuntimeError,"argument type error (5th argument must be FIXNUM)");
1465 char *arg1 = RSTRING_PTR(v1);
1466 char *arg2 = RSTRING_PTR(v2);
1467 int arg3_fix = FIX2INT(v3);
1468 char *arg4 = RSTRING_PTR(v4);
1470 int len_ub = FIX2INT(v5);
1475 char *str_c = new char[len+3];
1476 sprintf(str_c,"\"%s\"",arg1);
1480 char *str_d = new char[len+3];
1481 sprintf(str_d,"\"%s\"",arg2);
1484 char *str_e = new char[64];
1485 sprintf(str_e,"%d",arg3_fix);
1488 char *str_f = new char[len+3];
1489 sprintf(str_f,"\"%s\"",arg4);
1492 str_c[len_c - 1] = 0;
1493 str_d[len_d - 1] = 0;
1494 int th = atoi(str_e);
1495 str_f[len_f - 1] = 0;
1496 if(strcmp(str_c+1, "F" ) == 0) CtoI_Lcm1_ub(str_d+1, str_f+1, th, 0, len_ub);
1497 else if(strcmp(str_c+1, "C" ) == 0) CtoI_Lcm1_ub(str_d+1, str_f+1, th, 1, len_ub);
1498 else if(strcmp(str_c+1, "M" ) == 0) CtoI_Lcm1_ub(str_d+1, str_f+1, th, 2, len_ub);
1499 else if(strcmp(str_c+1, "FQ") == 0) CtoI_Lcm1_ub(str_d+1, str_f+1, th, 10, len_ub);
1500 else if(strcmp(str_c+1, "CQ") == 0) CtoI_Lcm1_ub(str_d+1, str_f+1, th, 11, len_ub);
1501 else if(strcmp(str_c+1, "MQ") == 0) CtoI_Lcm1_ub(str_d+1, str_f+1, th, 12, len_ub);
1502 for(int i=VTable.Used(); i<CtoI_LcmItems(); i++)
1506 int x = CtoI_LcmPerm(i);
1507 sprintf(s, "x%d", x);
1508 while(VTable.GetID(s) != 0)
1511 sprintf(s, "x%d_%d", x, t);
1513 VTable.SetT(s, power16/2);
1515 CtoI a = CtoI_Lcm2();
1516 ctoi_fin = new CtoI(a);
1523 Vsop_Ruby *rmod_rtn = new Vsop_Ruby;
1524 rmod_rtn->cmod = ctoi_fin;
1525 return Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod_rtn);
1532 * ZDD.lcm_ub() -> zdd : lcm over zdd(最大サポート指定可能)
1539 VALUE vsop_lcm_ub(int argc, VALUE *argv, VALUE self){
1542 rtnval = vsop_lcm_order_ub(argc,argv,self);
1545 rtnval = vsop_lcm_nomal_ub(argc,argv,self);
1550 // ------------------------------ パターン長制約を入れたlcm over zdd ここまで 2010/02/28
1555 * zdd.map -> self : カルノー図の表示
1560 * zddのカルノー図を標準出力に表示する。
1564 * > a=2*ZDD.itemset("a b")+3*ZDD.itemset("b")+4
1574 * # アイテムaが1列目のビット列に、アイテムbが1行目のビット列に対応してアイテム集合が表現されている。
1575 * # セルの値は重みを表す。左上のセルはaが0、bが0、すなわち定数項が4であることが示されている。
1578 * > a=ZDD.itemset("a b")+2*ZDD.itemset("b c")+3*ZDD.itemset("d")+4
1580 * a b + 2 b c + 3 d + 4
1593 VALUE vsop_print_map(int argc, VALUE *argv, VALUE self){
1595 Data_Get_Struct(self,Vsop_Ruby,rmod);
1598 rb_scan_args(argc, argv,"01",&v);
1600 if(TYPE(v)==T_STRING){
1601 char *str = RSTRING_PTR(v);
1605 rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
1609 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
1610 CtoI *ctoitmp = auto_p.get();
1611 if(MapAll(*ctoitmp) == 1){
1612 rb_raise(rb_eRuntimeError,"01Memory overflow");
1622 * zdd.rmap -> self : 冗長性を排除したカルノー図の表示
1627 * zddのカルノー図を標準出力に表示する。ただし、使われていないアイテムは省いて表示される。
1630 * # 4つのアイテムa,b,c,dを宣言
1636 * > a=ZDD.itemset("a b")+2*ZDD.itemset("b c")+4
1640 * # mapで表示させると以下の通り。
1649 * # rmapで表示させるとdが省かれて表示される。
1658 VALUE vsop_print_rmap(int argc, VALUE *argv, VALUE self){
1660 Data_Get_Struct(self,Vsop_Ruby,rmod);
1663 rb_scan_args(argc, argv,"01",&v);
1665 if(TYPE(v)==T_STRING){
1666 char *str = RSTRING_PTR(v);
1670 rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
1674 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
1675 CtoI *ctoitmp = auto_p.get();
1676 if(MapSel(*ctoitmp) == 1){
1677 rb_raise(rb_eRuntimeError,"02Memory overflow");
1686 * zdd.hex -> self : 16進数表現積和表示
1691 * 係数を16進数で表現し積和形で標準出力に出力する。
1694 * > a=ZDD.itemset("a b")+11*ZDD.itemset("b c")+30*ZDD.itemset("d")+4
1696 * a b + 11 b c + 30 d + 4
1698 * a b + B b c + 1E d + 4
1703 VALUE vsop_print_hex(int argc, VALUE *argv, VALUE self){
1705 Data_Get_Struct(self,Vsop_Ruby,rmod);
1708 rb_scan_args(argc, argv,"01",&v);
1710 if(TYPE(v)==T_STRING){
1711 char *str = RSTRING_PTR(v);
1715 rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
1718 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
1719 CtoI *ctoitmp = auto_p.get();
1720 if(PrintCtoI_16(*ctoitmp) == 1){
1721 rb_raise(rb_eRuntimeError,"03Memory overflow");
1729 * zdd.bit -> self : 重みの(-2)進数の各桁別アイテム集合の表示
1734 * ZDDでは重みをマイナス2進数で表現し、各桁ごとにZDDを生成している。
1735 * このメソッドにより各桁別に、そのZDDに登録されているアイテム集合を標準出力に出力できる。
1738 * > a=5*ZDD.itemset("a b c")+3*ZDD.itemset("a b")+2*ZDD.itemset("b c")+1*ZDD.it
1740 * 5 a b c - 3 a b + 2 b c + c
1744 * 2: a b c + a b + b c
1746 * 0: a b c + a b + c
1748 * # "a b c"の重み5の(-2)進数は101となる。
1749 * # 1*(-2)^2+0*(-2)^1+1*(-2)^0 = 5
1750 * # よって0桁目と2桁目にアイテム集合"a b c"が表示されている。
1751 * # "a b"の重み-3の(-2)進数は1101となる。
1752 * # 1*(-2)^3+1*(-2)^2+0*(-2)^1+1*(-2)^0 = -3
1753 * # よって0,2,3桁目にアイテム集合"a b"が表示されている。
1755 VALUE vsop_print_bit(int argc, VALUE *argv, VALUE self){
1757 Data_Get_Struct(self,Vsop_Ruby,rmod);
1760 rb_scan_args(argc, argv,"01",&v);
1762 if(TYPE(v)==T_STRING){
1763 char *str = RSTRING_PTR(v);
1767 rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
1770 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
1771 CtoI *ctoitmp = auto_p.get();
1772 if(PrintDigital(*ctoitmp) == 1){
1773 rb_raise(rb_eRuntimeError,"04Memory overflow");
1781 * zdd.case -> self : 重み別アイテム集合の表示
1786 * 重みの値別にアイテム集合を標準出力に出力する。
1789 * > a=5*ZDD.itemset("a b c")+3*ZDD.itemset("a b")+2*ZDD.itemset("b c")+1*ZDD.it
1791 * 5 a b c - 3 a b + 2 b c + c
1802 VALUE vsop_print_case(int argc, VALUE *argv, VALUE self){
1804 Data_Get_Struct(self,Vsop_Ruby,rmod);
1807 rb_scan_args(argc, argv,"01",&v);
1809 if(TYPE(v)==T_STRING){
1810 char *str = RSTRING_PTR(v);
1814 rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
1818 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
1819 CtoI *ctoitmp = auto_p.get();
1820 if(PrintCase(*ctoitmp) == 1){
1821 rb_raise(rb_eRuntimeError,"05Memory overflow");
1831 * zdd1.same?(zdd2) -> bool : 等価比較
1832 * zdd1 === (zdd2) -> bool : 等価比較
1834 * bool : Qtrue or Qfalse
1835 * zdd1,zdd2 : ZDD Object
1838 * zdd1とzdd2を比較し、同じならtrue、異なるならfalseを返す
1843 VALUE vsop_same(int argc, VALUE *argv,VALUE self){
1846 Data_Get_Struct(self,Vsop_Ruby,rmod);
1847 rb_scan_args(argc, argv,"10",&v);
1849 CtoI *ctoi_modc = value2ctoi(v);
1850 if ( *rmod->cmod == *ctoi_modc){
1860 * zdd1.diff?(zdd2) -> bool : 不等価比較
1862 * bool : Qtrue or Qfalse
1863 * zdd1,zdd2 : ZDD Object
1866 * zdd1とzdd2を比較し、同じならfalse、異なるならtrueを返す
1871 VALUE vsop_diff(int argc, VALUE *argv,VALUE self){
1874 Data_Get_Struct(self,Vsop_Ruby,rmod);
1875 rb_scan_args(argc, argv,"10",&v);
1877 CtoI *ctoi_modc = value2ctoi(v);
1878 if ( *rmod->cmod != *ctoi_modc){
1889 * zdd.size -> nodeSize : ZDD節点数
1892 * nodeSize : Ruby Integer
1898 * > a=5*ZDD.ƒ("a b c")-3*ZDD.itemset("a b")+2*ZDD.itemset("b c")+1*ZDD.itemset("c")
1900 * 5 a b c - 3 a b + 2 b c + c
1908 VALUE vsop_print_size( VALUE self){
1910 Data_Get_Struct(self,Vsop_Ruby,rmod);
1911 int val = rmod->cmod->Size();
1912 return INT2NUM(val);
1917 * ZDD.totalsize -> nodeSize : 処理系全体のZDD節点数
1919 * nodeSize : Ruby Integer
1922 * 動作中のrubyインタープリタ上で構築された全ZDDオブジェクトの節点数を返す。
1925 * > a=5*ZDD.itemset("a b c")-3*ZDD.itemset("a b")+2*ZDD.itemset("b c")+1*ZDD.itemset("c")
1927 * 5 a b c - 3 a b + 2 b c + c
1930 * > puts ZDD.totalsize
1933 * > b=-3*ZDD.itemset("a c")
1938 * > puts ZDD.nodesize
1944 VALUE vsop_print_totalsize(VALUE self){
1947 VALUE rtn = INT2NUM(BDD_Used());
1954 * zdd.count -> numItemsets : 項数計算
1956 * numItemsets : Ruby Integer
1959 * zddに格納された項の数(アイテム集合の数)を返す。
1962 * > A=ZDD.itemset("a")
1963 * > B=ZDD.itemset("b")
1976 * > c=ZDD.constant(0)
1980 * > d=ZDD.constant(1)
1985 VALUE vsop_print_count( VALUE self){
1987 Data_Get_Struct(self,Vsop_Ruby,rmod);
1988 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
1989 CtoI *ctoitmp = auto_p.get();
1990 *ctoitmp = ctoitmp -> CountTerms();
1991 if(*ctoitmp == CtoI_Null())
1994 rb_raise(rb_eRuntimeError,"06Memory overflow");
1996 int slen = ctoitmp->TopDigit() / 3 + 14;
1997 kgAutoPtr2<char> a_ptr;
2000 a_ptr.set(new char[slen]);
2003 rb_raise(rb_eRuntimeError,"memory allocation error");
2005 ctoitmp -> StrNum10(s);
2006 // VALUE rtn = LL2NUM(atoll(s));
2007 VALUE rtn = rb_cstr_to_inum(s, 10, Qfalse);
2013 * zdd.density -> dens : ZDDの濃度計算
2018 * 濃度とは、登録されている全アイテムから構成可能なアイテム集合の総数に対するzddに格納されたアイテム集合の数の割合と定義される。
2021 * > a=ZDD.itemset("a")
2022 * > b=ZDD.itemset("b")
2023 * > c=ZDD.itemset("c")
2025 * # a,b,cの3アイテムを使った全組合せ数は8通り。
2026 * # 以下で、Fにはそのすべての組合せが格納されているので濃度は1.0となる。
2027 * > F=(a+1)*(b+1)*(c+1)
2029 * a b c + a b + a c + a + b c + b + c + 1
2033 * # 以下で、Fには1通りの組合せ(a b)が格納されているので濃度は1/8=0.125となる。
2040 * # 以下で、Fには3通りの組合せ(a b,a,b)が格納されているので濃度は3/8=0.375となる。
2049 VALUE vsop_print_density( VALUE self){
2051 Data_Get_Struct(self,Vsop_Ruby,rmod);
2052 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2053 CtoI *ctoitmp = auto_p.get();
2055 *ctoitmp = ctoitmp -> NonZero();
2056 if(*ctoitmp == CtoI_Null())
2059 rb_raise(rb_eRuntimeError,"07Memory overflow");
2061 int d = Density(ctoitmp -> GetZBDD(), VTable.Used());
2062 if(d == 0 && *ctoitmp != 0){
2063 rb_raise(rb_eRuntimeError,"Bit underflow occurred");
2065 VALUE rtn = rb_float_new((float)d / power30);
2071 * zdd.value -> cost : アイテムの値による式の評価
2076 * アイテムに設定された値(symbolメソッドを参照のこと)をzddの各アイテムに代入したときの式の値を返す(この値をコストと呼ぶ)。
2079 * # シンボルa, b, cに値1.0, 0.5, 1.8をそれぞれ与える。
2080 * > ZDD.symbol("a",1.0)
2081 * > ZDD.symbol("b",0.5)
2082 * > ZDD.symbol("c",2.0)
2084 * > a=ZDD.itemset("a")
2085 * > b=ZDD.itemset("b")
2086 * > c=ZDD.itemset("c")
2088 * # 式は1つのシンボルaから構成されa=1.0
2094 * # 式"a b"にa=1.0,b=0.5を代入すると1.0*0.5=0.5
2101 * # 式"a b + 2 a + c + 3"にa=1.0,b=0.5,c=2.0を代入すると 1.0*0.5+2*1.0+2.0+3=7.5
2109 * itemset,maxcover,maxcost,mincover,mincost
2112 VALUE vsop_print_value( VALUE self){
2114 Data_Get_Struct(self,Vsop_Ruby,rmod);
2115 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2116 CtoI *ctoitmp = auto_p.get();
2118 if(OVF.Check()!= 0){
2119 rb_raise(rb_eRuntimeError,"Bit overflow occurred");
2121 VALUE rtn = rb_float_new((float)Value(*ctoitmp)/power16);
2127 * zdd.maxcover -> self : コスト最大のアイテム集合の表示
2132 * zddに含まれるアイテム集合の中で、コストが最大となるアイテム集合を表示する。
2133 * そのコストの値を表示するにはzdd.maxcostを用いる。
2136 * > ZDD.symbol("a",1.0)
2137 * > ZDD.symbol("b",0.5)
2138 * > ZDD.symbol("c",2.0)
2140 * > a=ZDD.itemset("a")
2141 * > b=ZDD.itemset("b")
2142 * > c=ZDD.itemset("c")
2144 * > f=a*b + b*c + c*a
2146 * # a b のコスト=1.0+0.5=1.5
2147 * # b c のコスト=0.5+2.0=2.5
2148 * # c a のコスト=2.0+1.0=3.0
2165 VALUE vsop_print_maxcover(int argc, VALUE *argv, VALUE self){
2167 Data_Get_Struct(self,Vsop_Ruby,rmod);
2170 rb_scan_args(argc, argv,"01",&v);
2172 if(TYPE(v)==T_STRING){
2173 char *str = RSTRING_PTR(v);
2177 rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
2181 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2182 CtoI *ctoitmp = auto_p.get();
2184 *ctoitmp = ctoitmp -> NonZero();
2185 if(*ctoitmp == CtoI_Null())
2188 rb_raise(rb_eRuntimeError,"08Memory overflow");
2195 ZBDD f = ctoitmp -> GetZBDD();
2201 // bout << "<Items>: ";
2206 ZBDD f0 = f.OffSet(var);
2207 ZBDD f1 = f.OnSet0(var);
2208 int c1 = MaxCost(f1) + VTable.GetValue(var);
2209 if(MaxCost(f0) < c1)
2211 bout << VTable.GetName(var);
2227 * zdd.maxcost -> cost : コスト最大のアイテム集合のコスト値を返す
2233 * maxcoverメソッドを参照のこと。
2242 VALUE vsop_print_maxcost( VALUE self){
2244 Data_Get_Struct(self,Vsop_Ruby,rmod);
2245 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2246 CtoI *ctoitmp = auto_p.get();
2248 *ctoitmp = ctoitmp -> NonZero();
2249 if(*ctoitmp == CtoI_Null())
2252 rb_raise(rb_eRuntimeError,"09Memory overflow");
2260 int c = MaxCost(ctoitmp -> GetZBDD());
2261 rtn = rb_float_new((float)c/power16);
2268 * zdd.mincover -> self : コスト最小のアイテム集合の表示
2273 * maxcoverメソッドを参照のこと。
2282 VALUE vsop_print_mincover(int argc, VALUE *argv, VALUE self){
2284 Data_Get_Struct(self,Vsop_Ruby,rmod);
2286 rb_scan_args(argc, argv,"01",&v);
2288 if(TYPE(v)==T_STRING){
2289 char *str = RSTRING_PTR(v);
2293 rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
2297 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2298 CtoI *ctoitmp = auto_p.get();
2300 *ctoitmp = ctoitmp -> NonZero();
2301 if(*ctoitmp == CtoI_Null())
2304 rb_raise(rb_eRuntimeError,"10Memory overflow");
2311 ZBDD f = ctoitmp -> GetZBDD();
2317 // bout << "<Items>: ";
2322 ZBDD f0 = f.OffSet(var);
2323 ZBDD f1 = f.OnSet0(var);
2324 int c1 = MinCost(f1) + VTable.GetValue(var);
2325 if(MinCost(f0) > c1)
2327 bout << VTable.GetName(var);
2342 * zdd.mincost -> cost : コスト最小のアイテム集合のコストを返す
2348 * maxcoverメソッドを参照のこと。
2357 VALUE vsop_print_mincost( VALUE self){
2359 Data_Get_Struct(self,Vsop_Ruby,rmod);
2360 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2361 CtoI *ctoitmp = auto_p.get();
2363 *ctoitmp = ctoitmp -> NonZero();
2364 if(*ctoitmp == CtoI_Null())
2367 rb_raise(rb_eRuntimeError,"11Memory overflow");
2375 int c = MinCost(ctoitmp -> GetZBDD());
2376 rtn = rb_float_new((float)c/power16);
2383 * zdd.decomp([fileName]) -> self : 単純直交分解形式での出力
2386 * fileName : Ruby String
2389 * zddを単純直交分解(simple disjoint decomposition)形式で出力する。
2390 * fileNameの指定があれば、そのファイルに出力する。
2394 * > a=ZDD.itemset("a")
2395 * > b=ZDD.itemset("b")
2396 * > c=ZDD.itemset("c")
2403 * # a,b,cのANDということでa*b*c=a b c
2405 * > f2=((a*b*c)+(a*b))
2409 * AND( a b OR( c 1 ) )
2410 * # c,1のORにて(c+1)、それとa bとのANDで(a b)*(c+1)=a b c + a b
2412 * > f3=((a*b*c)+(a*b)+(b*c))
2417 * # [ a c ]はaとcによる全組合せ集合、すなわち(a c + a + c)。
2418 * # それとbとのANDで b*(a c + a + c) = a b c + a b + b c
2420 * > f4=((a*b*c)+(a*b)+(b*c)+(c*a))
2422 * a b c + a b + a c + b c
2425 * # [ a b c ]はa,b,cによる全組合せ集合、すなわち(a b c + a b + b c + c a)
2428 VALUE vsop_print_decomp(int argc, VALUE *argv, VALUE self){
2430 Data_Get_Struct(self,Vsop_Ruby,rmod);
2432 rb_scan_args(argc, argv,"01",&v);
2434 if(TYPE(v)==T_STRING){
2435 char *str = RSTRING_PTR(v);
2439 rb_raise(rb_eRuntimeError,"argument type error (arguments must be STRING)");
2443 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2444 CtoI *ctoitmp = auto_p.get();
2446 if(PrintDecomp(*ctoitmp) == 1)
2448 rb_raise(rb_eRuntimeError,"12Memory overflow");
2456 * zdd.export([fileName]) : ZDDのエキスポート
2459 * fileName : Ruby String
2462 * zddオブジェクトのZDD内部構造をテキストで出力する。
2463 * fileNameを指定すれば、そのファイルに出力する。
2467 * > a=ZDD.itemset("a")
2468 * > b=ZDD.itemset("b")
2469 * > c=ZDD.itemset("c")
2470 * > f=5*a*b*c+3*a*b++2*b*c+c
2472 * 5 a b c + 3 a b + 2 b c + c
2489 VALUE vsop_print_export(int argc, VALUE *argv, VALUE self){
2491 Data_Get_Struct(self,Vsop_Ruby,rmod);
2492 auto_ptr<CtoI> auto_p(new CtoI(*rmod->cmod));
2493 CtoI *ctoitmp = auto_p.get();
2497 rb_scan_args(argc, argv,"0*",&v1);
2498 if(TYPE(RARRAY_PTR(v1)[0])==T_STRING){
2499 char *str = RSTRING_PTR(RARRAY_PTR(v1)[0]);
2500 fp = fopen(str, "w");
2502 rb_raise(rb_eRuntimeError,"Can't open the file");
2506 rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
2510 rb_raise(rb_eRuntimeError,"number of argument is 0 or 1 ");
2513 int d = ctoitmp -> TopDigit();
2515 for(int i=0; i<=d; i++){
2516 v += ZBDDV(ctoitmp -> Digit(i).GetZBDD(), i);
2530 * zdd.show([switch] [,fileName]) : 出力及び表示用メソッド
2533 * switch : Ruby String
2536 * string1でスイッチを指定し出力形式を決定する。exportを指定した場合のみstring2を指定可能(ファイル名)
2539 * * (スイッチ無し) : 式のカッコを展開した積和形での表示
2540 * * /bit : 重みの(-2)進数の各桁別アイテム集合の表示(bitメソッドに同じ)
2541 * * /hex : 整数値を 16 進数で表現する積和形表示(hexメソッドに同じ)
2542 * * /map : カルノー図で表示。アイテム変数6個まで表示できる(mapメソッドに同じ)
2543 * * /rmap : カルノー図で表示。冗長なアイテム変数は省いて表示(rmapメソッドに同じ)
2544 * * /case : 整数値ごとに場合分けして積和形表示(caseメソッドに同じ)
2545 * * /size : 計算結果のBDD節点数(および処理系全体の節点数)を表示(sizeメソッドに同じ)
2546 * * /count : 式に現れる(0 以外の値を持つ)組合せの個数を表示(countメソッドに同じ)
2547 * * /density : 集合の濃度(0 以外の値を持つ組合せの比率)を表示(densityメソッドに同じ)
2548 * * /value : シンボル変数にすべて数値を代入したときの式の値を表示(valueメソッドに同じ)
2549 * * /maxcover : 式に含まれる(0 以外の値を持つ)コスト最大の組合せを1つ表示(maxcoverメソッドに同じ)
2550 * * /maxcost : コスト最大組合せのコスト値を表示(maxcostメソッドに同じ)
2551 * * /mincover : 式に含まれる(0 以外の値を持つ)コスト最小の組合せを1つ表示(mincoverメソッドに同じ)
2552 * * /mincost : コスト最小組合せのコスト値を表示(mincostメソッドに同じ)
2553 * * /plot : BDDの形を図示する。(使用不可)
2554 * * /decomp : 単純直交分解形式での出力
2555 * * /export : BDDの形を図示する(否定枝不使用)。string2に指定があれば、指定されたファイルに出力(exportメソッドに同じ)
2558 * bit hex map rmap case size count density value maxcover mincover mincost decomp export
2560 VALUE vsop_show(int argc, VALUE *argv, VALUE self){
2563 rtnval = vsop_print(self);
2565 else if(argc == 1) {
2567 rb_scan_args(argc, argv,"10",&v);
2568 if(TYPE(v)!=T_STRING){
2569 rb_raise(rb_eRuntimeError,"argument type error (1st argument must be STRING)");
2571 char *argtmp = RSTRING_PTR(v);
2572 int len = strlen(argtmp);
2575 str_c = new char[len];
2576 strcpy(str_c,argtmp+1);
2579 str_c = new char[len+1];
2580 strcpy(str_c,argtmp);
2582 rtnval = vsop_print_arg1(self,str_c);
2587 rtnval = vsop_print_arg2(argc,argv,self);
2590 rb_raise(rb_eRuntimeError,"number of argument is 0 or 1 or 2");
2597 * ZDD.partly -> bool : 部分hash出力フラグ
2599 * bool : Qtrue or Qfalse
2602 * hashoutメソッドにて全データをセット出来なかった場合、このメソッドはtrueを返す。
2607 VALUE vsop_partly(VALUE self){
2608 return rb_iv_get(self,"@partly");
2612 VALUE vsop_coerce(int argc, VALUE *argv, VALUE self){
2614 Vsop_Ruby* rmod=new Vsop_Ruby;
2615 rb_scan_args(argc, argv,"10",&v);
2616 rmod->cmod =value2ctoi(v);
2617 VALUE rtn_v = Data_Wrap_Struct(rb_class_of(self),0,free_rmod,rmod);
2618 return rb_ary_new3(2,rtn_v,self);
2623 * zdd.to_i -> int : ZDDの重みをRuby整数に変換
2625 * int : Ruby Integer
2628 * ZDD重みオブジェクト(空のアイテム集合の重み)をruby整数に変換する。重みオブジェクトでないZDDオブジェクトに適用した場合はnilを返す。
2631 * > c=ZDD.constant(10)
2632 * > c.show # ZDD重みオブジェクト
2634 * > puts c.to_i # ruby整数
2636 * a=ZDD.itemset("a") # ZDDアイテム集合オブジェクトに対して適用するとnil
2644 VALUE vsop_const_to_i(VALUE self){
2646 Data_Get_Struct(self,Vsop_Ruby,rmod);
2648 if(rmod->cmod->IsConst()){
2649 int val = rmod->cmod->GetInt();
2650 return INT2NUM(val);
2657 void Init_zdd_so() {
2659 * Document-class: ZDD
2661 * (version: ##version##.##revision##)
2664 * ZDD(Zero-suppressed Binary Decision Diagrams: ゼロサプレス型二分決定グラフ)を利用し、
2665 * 重み付きのアイテムの組み合わせ集合をコンパクトに格納することを可能とするZDD
2666 * (Valued-Sum-Of-Products calculator)をruby拡張ライブラリとして実装したもの。
2667 * ZDDオブジェクトに対する演算子(`+',`-',`=='など)の多くは、ZDD演算としてオーバーロードしており、
2668 * ZDDの各種機能とrubyの制御などの各種機能をシームレスに組み合わせて利用することを可能としている。
2670 * 本マニュアルはRDocとしても提供されているので、コマンドライン上からも閲覧可能である。
2672 * $ ri ZDD # ZDDモジュール全体のマニュアルの閲覧
2673 * $ ri ZDD.symbol # symbolメソッドの閲覧
2676 * 注: 本モジュールは開発途上であり、本文書の仕様は予告なしに変更することがある。
2678 * 科学技術振興機構 ERATO湊離散構造系プロジェクト 関西サテライトラボ
2680 * === 1.はじめよう!(チュートリアル)
2681 * 以下では、4つのアイテムの全組合せ集合を列挙する方法を示す。
2682 * rubyスクリプトを記述して実行してもよいし、irbで一行ずつ実行してもよい。
2683 * ZDD ruby拡張ライブラリが既に正しくインストールされており、またrubyについての基本的な知識があることを前提としている。
2685 * 注:本マニュアルでの例で使われている記号の意味は以下の通り。
2686 * ">" : rubyのメソッド入力を表す。
2687 * "$" : シェルのコマンドライン入力を表す。
2691 * ==== 1-1. ZDD ruby拡張ライブラリのrequire
2692 * vsop ruby拡張ライブラリはrubygemsを使ってパッケージングされているので、以下の通りrubygemsをrequireした後にvsopをrequireする。
2695 * > require 'rubygems'
2699 * ==== 1-2. 利用するアイテムの宣言
2700 * 利用するアイテム名を宣言するためにZDD.symbolメソッドを利用する。一つのメソッドで一つのアイテムが宣言できる。
2701 * アイテム宣言の順序は重要で、その順序がZDDの木構造における根からのレベルに対応する。宣言の順序により異なる構造のZDDが作成され、よってそのサイズに大幅に影響を与えることがある。
2702 * 以下では、"a","b","c","d"という名前の4つのアイテムを宣言している。
2712 * symbolでは単に利用するアイテムを宣言しただけなので、次に、それらのアイテムから構成されるアイテム集合の定義、すなわちZDDオブジェクトを作成していく。
2713 * 以下では、1つのアイテムから構成されるアイテム集合を作る。次のステップで、それらのアイテム集合に対して様々な演算を加えることで全組合せを列挙する。
2716 * > a=ZDD.itemset("a")
2717 * > b=ZDD.itemset("b")
2718 * > c=ZDD.itemset("c")
2719 * > d=ZDD.itemset("d")
2722 * 最初の行は、"a"というアイテムから構成されるアイテム集合のZDDオブジェクトがruby変数aに格納される。以下同様にb,c,dの変数にもZDDオブジェクトが格納される。
2725 * ZDDで定義されている様々な演算を利用してアイテム集合を変換していく。
2726 * 以下のような式を入力すると、4つのアイテムa,b,c,dの全組合せが列挙されることになる。
2727 * 式の展開方法は、以下のケースにおいては、一般的な多項式の展開方法と同様に考えれば良い。
2728 * 右辺の演算結果として構築されたZDDオブジェクトがruby変数fに代入されている。
2729 * そしてZDDオブジェクトの内容を表示するshowメソッドにより表示する。
2730 * showはZDDオブジェクトの内容を重み付き積和形で表示するメソッドである。
2731 * 最後の項の"1"は空集合の係数である。
2734 * > f=(a+1)*(b+1)*(c+1)*(d+1)
2736 * a b c d + a b c + a b d + a b + a c d + a c + a d + a + b c d + b c +
2737 * b d + b + c d + c + d + 1
2740 * 他にも、2つほど異なる演算結果を示す。なぜこのような結果になるかは本マニュアルの"*"演算子(乗算)を参照のこと。
2743 * > g=(a+b)*(b+c)*(c+d)*(d+a)
2745 * 2 a b c d + 3 a b c + 3 a b d + 3 a c d + a c + 3 b c d + b d
2747 * > h=(a+1)*(a+1)*(a+1)*(a+1)
2753 * 以下では、よく利用するメソッドを中心にして、vsopライブラリの様々な用法について学ぶ。
2755 * ==== 2-1. symbolメソッドによる宣言なしにitemsetメソッドを使う
2756 * ZDD.symbolメソッドは利用するアイテムの宣言に利用するが、これは省くことができる。省略した場合は、itemsetメソッドで定義されたアイテムの登場順にsymbolで宣言することに等しい。
2759 * > a=ZDD.itemset("a")
2760 * > b=ZDD.itemset("b")
2761 * > c=ZDD.itemset("c")
2762 * > ZDD.itemset # itemsetメソッドを引き数なしで呼び出すと、宣言されたアイテムがその順番で表示される。
2765 * > a=ZDD.itemset("a")
2766 * > c=ZDD.itemset("c")
2767 * > b=ZDD.itemset("b")
2772 * ==== 2-2. アイテム集合のZDDオブジェクトを一行で生成する方法
2773 * ZDD.itemsetメソッドにアイテム名をスペース区切りで列挙することでアイテム集合のZDDオブジェクトを作成することができる。
2776 * # 3つのアイテム`a',`b',`c'で構成されるアイテム集合{a,b,c}を表すZDDオブジェクトをrubyの変数`a'にセットする。
2777 * > a=ZDD.itemset("a b c")
2783 * 重みを表す整数値定数項(空のアイテム集合の重み)はconstantメソッドを利用する。
2786 * > a=ZDD.itemset("a b c")
2787 * > q=ZDD.constant(4) # 重み4の空のアイテム集合ZDDオブジェクトが作成されruby変数qに格納される。
2792 * ==== 2-4. ZDDオブジェクトに対する演算
2793 * ZDDオブジェクトを一つでも引数に持つ演算子はオーバーロードされたZDD演算子となる。
2796 * > a=ZDD.itemset("a b c") # rubyの変数`a'はZDDオブジェクト
2797 * > (4*a).show # よって`*'はZDD演算子として機能し、ruby整数`4'は自動的にZDDオブジェクトに型変換される。
2798 * 4 a b c # 内部的には、(ZDD.constant(4)*a).show を実行している。
2799 * > (a+"a b").show # ruby文字列"a b"は自動的にZDDオブジェクトに変換される。
2800 * a b c + a b # 内部的には、(a+ZDD.itemset("a b")).show を実行している。
2801 * > a="a b"+"c d" #これは演算子の引数が二つともrubyのStringオブジェクトであるため、単なる文字列の結合となってしまう。
2804 * ==== 2-5. 制御文との組合せ
2805 * 制御文と組み合わせると以下のような書き方も可能である
2808 * > z=ZDD.constant(0)
2809 * > ["a","b","c"].each{|item|
2810 * > z += item # `z'はZDDオブジェクトなので、それに対する`+'演算はZDD演算子となる。
2815 * > z=ZDD.constant(0)
2817 * > z += "item_#{i}"
2820 * item_1 + item_2 + item_3 + item_4 + item_5
2824 * 以下の環境変数を設定することでデフォルトの動作を変更することができる
2826 * 最大節点数 デフォルト値:1000000
2828 * 警告メッセージ出力 設定すると数値文字をアイテムに使用使用とした場合に警告メッセージが出力される
2833 envStr=getenv("ZDDLimitNode");
2835 env_nmax=atoi(envStr);
2837 env_nmax=DEF_ENV_NMAX ;
2839 envStr=getenv("ZDDWarning");
2847 VALUE vsop_main=rb_define_module("ZDD");
2849 rb_define_module_function(vsop_main, "itemset", RUBY_METHOD_FUNC(vsop_itemset), -1);
2850 rb_define_module_function(vsop_main, "constant", RUBY_METHOD_FUNC(vsop_constant), -1);
2851 rb_define_module_function(vsop_main, "symbol", RUBY_METHOD_FUNC(vsop_symbol), -1);
2852 rb_define_module_function(vsop_main, "each", RUBY_METHOD_FUNC(vsop_each), 0);
2853 rb_define_module_function(vsop_main, "each_item", RUBY_METHOD_FUNC(vsop_each_item), 0);
2855 rb_define_module_function(vsop_main, "show", RUBY_METHOD_FUNC(vsop_show), -1);
2856 rb_define_module_function(vsop_main, "lcm", RUBY_METHOD_FUNC(vsop_lcm), -1);
2857 rb_define_module_function(vsop_main, "lcm_ub", RUBY_METHOD_FUNC(vsop_lcm_ub), -1);
2858 rb_define_module_function(vsop_main, "permit", RUBY_METHOD_FUNC(vsop_permit), -1);
2859 rb_define_module_function(vsop_main, "permitsym", RUBY_METHOD_FUNC(vsop_permitsym), -1);
2860 rb_define_module_function(vsop_main, "restrict", RUBY_METHOD_FUNC(vsop_restrict), -1);
2861 rb_define_module_function(vsop_main, "freqpatC", RUBY_METHOD_FUNC(vsop_freqpatC), -1);
2862 rb_define_module_function(vsop_main, "freqpatM", RUBY_METHOD_FUNC(vsop_freqpatM), -1);
2863 rb_define_module_function(vsop_main, "freqpatA", RUBY_METHOD_FUNC(vsop_freqpatA), -1);
2864 rb_define_module_function(vsop_main, "termsLE", RUBY_METHOD_FUNC(vsop_termsLE), -1);
2865 rb_define_module_function(vsop_main, "termsLT", RUBY_METHOD_FUNC(vsop_termsLT), -1);
2866 rb_define_module_function(vsop_main, "termsGE", RUBY_METHOD_FUNC(vsop_termsGE), -1);
2867 rb_define_module_function(vsop_main, "termsGT", RUBY_METHOD_FUNC(vsop_termsGT), -1);
2868 rb_define_module_function(vsop_main, "termsNE", RUBY_METHOD_FUNC(vsop_termsNE), -1);
2869 rb_define_module_function(vsop_main, "termsEQ", RUBY_METHOD_FUNC(vsop_termsEQ), -1);
2871 rb_define_module_function(vsop_main, "<=", RUBY_METHOD_FUNC(vsop_le), -1);
2872 rb_define_module_function(vsop_main, "<", RUBY_METHOD_FUNC(vsop_lt), -1);
2873 rb_define_module_function(vsop_main, ">=", RUBY_METHOD_FUNC(vsop_ge), -1);
2874 rb_define_module_function(vsop_main, ">", RUBY_METHOD_FUNC(vsop_gt), -1);
2875 rb_define_module_function(vsop_main, "ne?", RUBY_METHOD_FUNC(vsop_ne), -1);
2876 rb_define_module_function(vsop_main, "==", RUBY_METHOD_FUNC(vsop_eq), -1);
2877 rb_define_module_function(vsop_main, "iif", RUBY_METHOD_FUNC(vsop_iif), -1);
2878 //rb_define_module_function(vsop_main, "meet", RUBY_METHOD_FUNC(vsop_meet), -1);
2879 rb_define_module_function(vsop_main, "same?", RUBY_METHOD_FUNC(vsop_same), -1);
2880 rb_define_module_function(vsop_main, "===", RUBY_METHOD_FUNC(vsop_same), -1);
2881 rb_define_module_function(vsop_main, "diff?", RUBY_METHOD_FUNC(vsop_diff), -1);
2882 rb_define_module_function(vsop_main, "delta", RUBY_METHOD_FUNC(vsop_delta), -1);
2884 rb_define_module_function(vsop_main, "+", RUBY_METHOD_FUNC(vsop_plus), -1);
2885 rb_define_module_function(vsop_main, "-", RUBY_METHOD_FUNC(vsop_minus), -1);
2886 rb_define_module_function(vsop_main, "+@", RUBY_METHOD_FUNC(vsop_plus_op), 0);
2887 rb_define_module_function(vsop_main, "-@", RUBY_METHOD_FUNC(vsop_minus_op), 0);
2888 rb_define_module_function(vsop_main, "*", RUBY_METHOD_FUNC(vsop_multiply), -1);
2889 rb_define_module_function(vsop_main, "/", RUBY_METHOD_FUNC(vsop_quotiment), -1);
2890 rb_define_module_function(vsop_main, "%", RUBY_METHOD_FUNC(vsop_remainder), -1);
2891 rb_define_module_function(vsop_main, "csvout", RUBY_METHOD_FUNC(vsop_csvout), -1);
2892 rb_define_module_function(vsop_main, "import", RUBY_METHOD_FUNC(vsop_import), -1);
2893 rb_define_module_function(vsop_main, "hashout", RUBY_METHOD_FUNC(vsop_hashout), 0);
2894 rb_define_module_function(vsop_main, "maxval", RUBY_METHOD_FUNC(vsop_maxval), 0);
2895 rb_define_module_function(vsop_main, "minval", RUBY_METHOD_FUNC(vsop_minval), 0);
2896 rb_define_module_function(vsop_main, "totalval", RUBY_METHOD_FUNC(vsop_totalval), 0);
2897 rb_define_module_function(vsop_main, "items", RUBY_METHOD_FUNC(vsop_items), 0);
2898 rb_define_module_function(vsop_main, "symgrp", RUBY_METHOD_FUNC(vsop_symgrp), 0);
2900 rb_define_module_function(vsop_main, "map", RUBY_METHOD_FUNC(vsop_print_map), -1);
2901 rb_define_module_function(vsop_main, "rmap", RUBY_METHOD_FUNC(vsop_print_rmap), -1);
2902 rb_define_module_function(vsop_main, "hex", RUBY_METHOD_FUNC(vsop_print_hex), -1);
2903 rb_define_module_function(vsop_main, "bit", RUBY_METHOD_FUNC(vsop_print_bit), -1);
2904 rb_define_module_function(vsop_main, "case", RUBY_METHOD_FUNC(vsop_print_case), -1);
2905 rb_define_module_function(vsop_main, "size", RUBY_METHOD_FUNC(vsop_print_size), 0);
2906 rb_define_module_function(vsop_main, "totalsize", RUBY_METHOD_FUNC(vsop_print_totalsize), 0);
2907 rb_define_module_function(vsop_main, "count", RUBY_METHOD_FUNC(vsop_print_count), 0);
2908 rb_define_module_function(vsop_main, "density", RUBY_METHOD_FUNC(vsop_print_density), 0);
2909 rb_define_module_function(vsop_main, "value", RUBY_METHOD_FUNC(vsop_print_value), 0);
2910 rb_define_module_function(vsop_main, "maxcover", RUBY_METHOD_FUNC(vsop_print_maxcover), -1);
2911 rb_define_module_function(vsop_main, "maxcost", RUBY_METHOD_FUNC(vsop_print_maxcost), 0);
2912 rb_define_module_function(vsop_main, "mincover", RUBY_METHOD_FUNC(vsop_print_mincover), -1);
2913 rb_define_module_function(vsop_main, "mincost", RUBY_METHOD_FUNC(vsop_print_mincost), 0);
2914 rb_define_module_function(vsop_main, "decomp", RUBY_METHOD_FUNC(vsop_print_decomp), -1);
2915 rb_define_module_function(vsop_main, "export", RUBY_METHOD_FUNC(vsop_print_export), -1);
2916 rb_define_module_function(vsop_main, "partly", RUBY_METHOD_FUNC(vsop_partly), 0);
2917 rb_define_module_function(vsop_main, "coerce", RUBY_METHOD_FUNC(vsop_coerce), -1);
2918 rb_define_module_function(vsop_main, "to_i", RUBY_METHOD_FUNC(vsop_const_to_i), 0);
2919 rb_define_module_function(vsop_main, "to_a", RUBY_METHOD_FUNC(vsop_to_a), 0);
2920 rb_define_module_function(vsop_main, "to_s", RUBY_METHOD_FUNC(vsop_to_s), 0);
2921 rb_define_module_function(vsop_main, "inspect", RUBY_METHOD_FUNC(vsop_to_s), 0);