[BACK]Return to pieri_trees.adb CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / PHC / Ada / Schubert

Annotation of OpenXM_contrib/PHC/Ada/Schubert/pieri_trees.adb, Revision 1.1.1.1

1.1       maekawa     1: with unchecked_deallocation;
                      2:
                      3: package body Pieri_Trees is
                      4:
                      5: -- UTILITIES FOR CREATION OF Pieri Trees :
                      6:
                      7:   function Index_of_Increase ( nd : Pieri_Node ) return natural is
                      8:
                      9:   -- DESCRIPTION :
                     10:   --   Returns the index of increase between the current node nd and the
                     11:   --   ancestor node.  If the current node is the root, then the index
                     12:   --   of increase equals zero.
                     13:
                     14:     bnd : Link_to_Pieri_Node;
                     15:
                     16:   begin
                     17:     if nd.ancestor = null
                     18:      then return 0;
                     19:      else bnd := nd.ancestor;
                     20:           for i in nd.node'range loop
                     21:             if bnd.node(i) = nd.node(i)-1
                     22:              then return i;
                     23:             end if;
                     24:           end loop;
                     25:           return 0;
                     26:     end if;
                     27:   end Index_of_increase;
                     28:
                     29:   function Branching_Level ( l : natural; r : Vector ) return boolean is
                     30:
                     31:   -- DESCRIPTION :
                     32:   --   Returns true if the current level l is a level where decreasing
                     33:   --   is allowed.
                     34:
                     35:     bl : natural := 1;
                     36:
                     37:   begin
                     38:     for i in r'first..r'last-1 loop
                     39:       bl := bl + r(i);
                     40:       if bl = l
                     41:        then return true;
                     42:        elsif bl > l
                     43:            then return false;
                     44:       end if;
                     45:     end loop;
                     46:     return false;
                     47:   end Branching_Level;
                     48:
                     49:   procedure Create_Next ( n,d,l,h : in natural; r : in Vector;
                     50:                           nd : in out Link_to_Pieri_Node ) is
                     51:
                     52:   -- DESCRIPTION :
                     53:   --   Creates next level of nodes in the Pieri Tree.
                     54:
                     55:   -- ON ENTRY :
                     56:   --   n         maximal entry in a bracket, dimension of whole space;
                     57:   --   d         number of entries in bracket;
                     58:   --   l         current level, must be strictly lower than h;
                     59:   --   h         height of the Pieri tree;
                     60:   --   nd        current node.
                     61:
                     62:   -- ON RETURN :
                     63:   --   nd        node with updated links.
                     64:
                     65:     indinc : constant natural := Index_of_Increase(nd.all);
                     66:
                     67:   begin
                     68:     if Branching_Level(l,r)               -- test if jumping-branching node
                     69:      then nd.i := 0;
                     70:           nd.c := nd.ancestor.c + 1;
                     71:     end if;
                     72:     if nd.node(d) <  n                               -- create right node
                     73:      then declare
                     74:             rnd : Pieri_Node(d);
                     75:             lnd : Link_to_Pieri_Node;
                     76:           begin
                     77:             rnd.node := nd.node;                     -- adjust entries
                     78:             rnd.node(d) := rnd.node(d)+1;
                     79:             rnd.c := nd.c;
                     80:             rnd.i := nd.i + 1;
                     81:             rnd.h := nd.h + 1;
                     82:             lnd := new Pieri_Node'(rnd);
                     83:             lnd.ancestor := nd;                      -- establish connections
                     84:             nd.children(d) := lnd;
                     85:             if l < h                                 -- go to next level
                     86:              then Create_Next(n,d,l+1,h,r,lnd);
                     87:             end if;
                     88:           end;
                     89:     end if;
                     90:     for i in nd.node'first..(nd.node'last-1) loop
                     91:       if nd.node(i) < nd.node(i+1) - 1
                     92:        then if ((i >= indinc)
                     93:               or else ((nd.i = 0) and (nd.c > 0)))        -- jumping-branching
                     94:              then declare                                      -- create node
                     95:                     rnd : Pieri_Node(d);
                     96:                     lnd : Link_to_Pieri_Node;
                     97:                   begin
                     98:                     rnd.node := nd.node;                     -- adjust entries
                     99:                     rnd.node(i) := rnd.node(i)+1;
                    100:                     rnd.c := nd.c;
                    101:                     rnd.i := nd.i + 1;
                    102:                     rnd.h := nd.h + 1;
                    103:                     lnd := new Pieri_Node'(rnd);
                    104:                     lnd.ancestor := nd;               -- establish connections
                    105:                     nd.children(i) := lnd;
                    106:                     if l < h                               -- go to next level
                    107:                      then Create_Next(n,d,l+1,h,r,lnd);
                    108:                     end if;
                    109:                   end;
                    110:           end if;
                    111:       end if;
                    112:     end loop;
                    113:   end Create_Next;
                    114:
                    115: -- CREATOR :
                    116:
                    117:   function Create ( n,d : natural; r : Vector ) return Pieri_Tree is
                    118:
                    119:     res : Pieri_Tree(d,r'last);
                    120:     hei : natural;
                    121:     pnd : Pieri_Node(d);
                    122:
                    123:   begin
                    124:     res.branches := r;
                    125:     for i in pnd.node'range loop                -- root node = [1 2 .. d]
                    126:       pnd.node(i) := i;
                    127:     end loop;
                    128:     pnd.c := 0;
                    129:     pnd.i := 0;
                    130:     pnd.h := 0;
                    131:     res.root := new Pieri_Node'(pnd);
                    132:     res.root.ancestor := null;
                    133:     hei := Height(res);
                    134:     if hei > 0
                    135:      then Create_Next(n,d,1,hei,r,res.root);           -- create children
                    136:     end if;
                    137:     return res;
                    138:   end Create;
                    139:
                    140: -- SELECTORS :
                    141:
                    142:   function Height ( t : Pieri_Tree ) return natural is
                    143:
                    144:     res : natural := 0;
                    145:
                    146:   begin
                    147:     for i in t.branches'range loop
                    148:       res := res + t.branches(i);
                    149:     end loop;
                    150:     return res;
                    151:   end Height;
                    152:
                    153:   function Is_Leaf ( nd : Pieri_Node ) return boolean is
                    154:   begin
                    155:     for i in nd.children'range loop
                    156:       if nd.children(i) /= null
                    157:        then return false;
                    158:       end if;
                    159:     end loop;
                    160:     return true;
                    161:   end Is_Leaf;
                    162:
                    163:   function Jump ( b1,b2 : Bracket ) return natural is
                    164:   begin
                    165:     for i in reverse b1'range loop
                    166:       if b1(i) < b2(i)
                    167:        then return i;
                    168:       end if;
                    169:     end loop;
                    170:     return 0;
                    171:   end Jump;
                    172:
                    173:   function Jump ( nd : Pieri_Node ) return natural is
                    174:   begin
                    175:     if nd.ancestor = null
                    176:      then return 0;
                    177:      else return Jump(nd.ancestor.node,nd.node);
                    178:     end if;
                    179:   end Jump;
                    180:
                    181:   function Lower_Jump_Decrease ( nd : Pieri_Node ) return Bracket is
                    182:   begin
                    183:     if ((nd.i = 0) or else (nd.c = 0))
                    184:      then return nd.node;
                    185:      elsif nd.ancestor /= null
                    186:          then return Lower_Jump_Decrease(nd.ancestor.all);
                    187:          else return nd.node;
                    188:     end if;
                    189:   end Lower_Jump_Decrease;
                    190:
                    191:   function Lowest_Jump_Decrease ( nd : Pieri_Node ) return Bracket is
                    192:   begin
                    193:     if (nd.c = 0) or ((nd.i = 0) and (nd.c = 1))
                    194:      then return nd.node;
                    195:      elsif nd.ancestor /= null
                    196:          then return Lowest_Jump_Decrease(nd.ancestor.all);
                    197:          else return nd.node;
                    198:     end if;
                    199:   end Lowest_Jump_Decrease;
                    200:
                    201:   function Upper_Jump_Decrease ( nd : Pieri_Node ) return Bracket is
                    202:   begin
                    203:     if ((nd.i = 0) or else (nd.c = 0))
                    204:      then return nd.node;
                    205:      elsif nd.children(nd.node'last) /= null
                    206:          then return Upper_Jump_Decrease(nd.children(nd.node'last).all);
                    207:          else return nd.node;
                    208:     end if;
                    209:   end Upper_Jump_Decrease;
                    210:
                    211:   procedure Enumerate_Nodes ( t : in Pieri_Tree; level : in natural ) is
                    212:
                    213:     continue : boolean := true;
                    214:
                    215:     procedure Visit_Nodes ( nd : in Link_to_Pieri_Node ) is
                    216:     begin
                    217:       if nd.h = level
                    218:        then Visit_Node(nd,continue);
                    219:        else for i in nd.children'range loop
                    220:               if nd.children(i) /= null
                    221:                then Visit_Nodes(nd.children(i));
                    222:               end if;
                    223:               exit when not continue;
                    224:             end loop;
                    225:       end if;
                    226:     end Visit_Nodes;
                    227:
                    228:   begin
                    229:     if t.root /= null
                    230:      then Visit_Nodes(t.root);
                    231:     end if;
                    232:   end Enumerate_Nodes;
                    233:
                    234:   procedure Enumerate_Chains ( t : in Pieri_Tree ) is
                    235:
                    236:     b : Bracket_Array(1..Height(t));
                    237:     continue : boolean := true;
                    238:
                    239:     procedure Visit_Nodes ( nd : in Pieri_Node; ind : in natural ) is
                    240:     begin
                    241:       b(ind) := new Bracket'(nd.node);
                    242:       if ind = b'last
                    243:        then Visit_Chain(b,continue);
                    244:        else for i in nd.children'range loop
                    245:               if nd.children(i) /= null
                    246:                then Visit_Nodes(nd.children(i).all,ind+1);
                    247:               end if;
                    248:               exit when not continue;
                    249:             end loop;
                    250:       end if;
                    251:     end Visit_Nodes;
                    252:
                    253:   begin
                    254:     if t.root /= null
                    255:      then Visit_Nodes(t.root.all,1);
                    256:     end if;
                    257:   end Enumerate_Chains;
                    258:
                    259:   procedure Enumerate_Paired_Chains ( t1,t2 : in Pieri_Tree ) is
                    260:
                    261:     continue : boolean := true;
                    262:
                    263:     procedure Outer_Chain ( ob : in Bracket_Array; cont : out boolean ) is
                    264:
                    265:       procedure Inner_Chain ( ib : in Bracket_Array; cont : out boolean ) is
                    266:       begin
                    267:         Visit_Paired_Chain(ob,ib,continue);
                    268:         cont := continue;
                    269:       end Inner_Chain;
                    270:       procedure Inner_Chains is new Enumerate_Chains(Inner_Chain);
                    271:
                    272:     begin
                    273:       Inner_Chains(t2);
                    274:       cont := continue;
                    275:     end Outer_Chain;
                    276:     procedure Outer_Chains is new Enumerate_Chains(Outer_Chain);
                    277:
                    278:   begin
                    279:     Outer_Chains(t1);
                    280:   end Enumerate_Paired_Chains;
                    281:
                    282:   function Pieri_Condition ( n : natural; b1,b2 : Bracket ) return boolean is
                    283:   begin
                    284:     for i in b2'range loop
                    285:       if b2(i) > n+1 - b1(b1'last+1-i)       -- negation of weak inequality
                    286:        then return false;
                    287:       end if;
                    288:     end loop;
                    289:     for i in b1'first..b1'last-1 loop
                    290:       if n+1-b1(b1'last+1-i) >= b2(i+1)      -- negation of strong inequality
                    291:        then return false;
                    292:       end if;
                    293:     end loop;
                    294:     return true;
                    295:   end Pieri_Condition;
                    296:
                    297: -- DESTRUCTOR :
                    298:
                    299:   procedure Clear ( nd : in out Link_to_Pieri_Node ) is
                    300:
                    301:     procedure free is new unchecked_deallocation(Pieri_Node,Link_to_Pieri_Node);
                    302:
                    303:   begin
                    304:     if nd /= null
                    305:      then free(nd);
                    306:     end if;
                    307:   end Clear;
                    308:
                    309:   procedure Clear_Children ( nd : in out Link_to_Pieri_Node ) is
                    310:
                    311:   -- DESCRIPTION :
                    312:   --   Deallocation of the memory of all the children, before the memory
                    313:   --   occupied by the current node nd is released.  Applied recursively.
                    314:
                    315:   begin
                    316:     for i in nd.children'range loop
                    317:       if nd.children(i) /= null
                    318:        then Clear_Children(nd.children(i));
                    319:       end if;
                    320:     end loop;
                    321:     Clear(nd);
                    322:   end Clear_Children;
                    323:
                    324:   procedure Clear ( t : in out Pieri_Tree ) is
                    325:   begin
                    326:     Clear_Children(t.root);
                    327:   end Clear;
                    328:
                    329: end Pieri_Trees;

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