[BACK]Return to partitions_of_sets_of_unknowns.adb CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / PHC / Ada / Root_Counts / Product

Annotation of OpenXM_contrib/PHC/Ada/Root_Counts/Product/partitions_of_sets_of_unknowns.adb, Revision 1.1

1.1     ! maekawa     1: package body Partitions_of_Sets_of_Unknowns is
        !             2:
        !             3: -- CREATORS :
        !             4:
        !             5:   procedure Create ( p : in out Partition; n : in natural ) is
        !             6:   begin
        !             7:     for i in p'range loop
        !             8:       p(i) := Create(n);
        !             9:     end loop;
        !            10:   end Create;
        !            11:
        !            12:   function Create ( p : Partition ) return Partition is
        !            13:
        !            14:     res : Partition(p'range);
        !            15:
        !            16:   begin
        !            17:     for i in p'range loop
        !            18:       res(i) := Create(p(i));
        !            19:     end loop;
        !            20:     return res;
        !            21:   end Create;
        !            22:
        !            23: -- CONSTRUCTOR :
        !            24:
        !            25:   procedure Generate_Partitions ( s : in Set ) is
        !            26:
        !            27:   -- NOTE :
        !            28:   --   The algorithm below is a rather unelegant construction.
        !            29:   --   The VADS compiler for IBM RS/6000 had problems with the nested
        !            30:   --   generics, so the generation of all subsets is repeated here in full.
        !            31:
        !            32:     n : constant natural := Dimension(s);
        !            33:     continue : boolean := true;
        !            34:     p : Partition(1..n);
        !            35:     cnt : natural := 0;
        !            36:
        !            37:     procedure Generate ( v : in Set; cont : out boolean );
        !            38:
        !            39:     -- DESCRIPTION :
        !            40:     --   Generation of all partitions makes use of a double recursive process.
        !            41:
        !            42:     procedure Empty_Subsets ( w : in Set; cont : out boolean ) is
        !            43:
        !            44:       rest : Set := Difference(w,p(cnt));
        !            45:
        !            46:     begin
        !            47:       if Extent_of(rest) = 0
        !            48:        then Process(p(1..cnt),cont);
        !            49:        else Generate(rest,cont);
        !            50:       end if;
        !            51:       Clear(rest);
        !            52:     end Empty_Subsets;
        !            53:
        !            54:     procedure All_Subsets ( w : in Set; cont : out boolean ) is
        !            55:
        !            56:       sb : Set := Create(n);
        !            57:
        !            58:       procedure Create_Partition ( sub : in Set; cont : out boolean ) is
        !            59:
        !            60:         rest : Set;
        !            61:         back : Set := Create(p(cnt));   -- back up copy needed to restore
        !            62:
        !            63:       begin
        !            64:         Union(p(cnt),sub);
        !            65:         rest := Difference(w,p(cnt));
        !            66:         if Extent_Of(rest) = 0
        !            67:          then Process(p(1..cnt),cont);
        !            68:          else Generate(rest,cont);
        !            69:         end if;
        !            70:         Clear(p(cnt)); p(cnt) := Create(back);
        !            71:         Clear(rest); Clear(back);
        !            72:       end Create_Partition;
        !            73:
        !            74:       procedure Generate_Subset ( level,start : in natural ) is
        !            75:       begin
        !            76:         if level > 0
        !            77:          then for i in start..n loop
        !            78:                 if Is_In(w,i)
        !            79:                  then Add(sb,i);
        !            80:                       Create_Partition(sb,continue);
        !            81:                       if continue
        !            82:                        then Generate_Subset(level-1,i+1);
        !            83:                             Remove(sb,i);
        !            84:                       end if;
        !            85:                 end if;
        !            86:                 exit when not continue;
        !            87:               end loop;
        !            88:               cont := continue;
        !            89:         end if;
        !            90:       end Generate_Subset;
        !            91:
        !            92:     begin
        !            93:       Generate_Subset(n,1);
        !            94:       Clear(sb);
        !            95:     end All_Subsets;
        !            96:
        !            97:     procedure Generate ( v : in Set; cont : out boolean ) is
        !            98:     begin
        !            99:       for i in 1..n loop
        !           100:         if Is_In(v,i)
        !           101:          then cnt := cnt + 1;
        !           102:               p(cnt) := Create(n); Add(p(cnt),i);
        !           103:               Empty_Subsets(v,continue);
        !           104:               if continue
        !           105:                then declare
        !           106:                       w : Set := Create(v);
        !           107:                     begin
        !           108:                       Remove(w,i);
        !           109:                       All_Subsets(w,cont);
        !           110:                       Clear(w);
        !           111:                     end;
        !           112:               end if;
        !           113:               Clear(p(cnt)); cnt := cnt - 1;
        !           114:               cont := continue;
        !           115:         end if;
        !           116:         exit when Is_In(v,i);
        !           117:       end loop;
        !           118:     end Generate;
        !           119:
        !           120:   begin
        !           121:     Generate(s,continue);
        !           122:   end Generate_Partitions;
        !           123:
        !           124: -- SELECTOR :
        !           125:
        !           126:   function Number_of_Partitions ( n : natural ) return natural is
        !           127:
        !           128:     sum : natural;
        !           129:
        !           130:     function comb ( n,i : natural ) return natural is
        !           131:       n1,n2 : natural := 1;
        !           132:     begin
        !           133:       if (i = 0) or (i = n)
        !           134:        then return 1;
        !           135:        else for k in 1..i loop
        !           136:               n1 := n1 * (n - k + 1);
        !           137:               n2 := n2 * k;
        !           138:             end loop;
        !           139:             return (n1/n2);
        !           140:       end if;
        !           141:     end comb;
        !           142:
        !           143:   begin
        !           144:     if (n = 0) or (n = 1)
        !           145:      then return 1;
        !           146:      else sum := 0;
        !           147:           for k in 0..(n-1) loop
        !           148:             sum := sum + comb(n-1,k) * Number_Of_Partitions(n-1-k);
        !           149:           end loop;
        !           150:           return sum;
        !           151:     end if;
        !           152:   end Number_of_Partitions;
        !           153:
        !           154: -- DESTRUCTOR :
        !           155:
        !           156:   procedure Clear ( p : in out Partition ) is
        !           157:   begin
        !           158:     for i in p'range loop
        !           159:       Clear(p(i));
        !           160:     end loop;
        !           161:   end Clear;
        !           162:
        !           163: end Partitions_of_Sets_of_Unknowns;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>