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

Annotation of OpenXM_contrib/PHC/Ada/Schubert/localization_posets.adb, Revision 1.1

1.1     ! maekawa     1: with unchecked_deallocation;
        !             2:
        !             3: package body Localization_Posets is
        !             4:
        !             5: -- NOTE :
        !             6: --   The field nd.roco is set to -1 if all its children have been created.
        !             7: --   This flag prevents traversing the poset needlessly.
        !             8:
        !             9: -- CREATOR AUXILIARIES :
        !            10:
        !            11:   function Max ( i,j : integer ) return integer is
        !            12:   begin
        !            13:     if i > j
        !            14:      then return i;
        !            15:      else return j;
        !            16:     end if;
        !            17:   end Max;
        !            18:
        !            19:   function Last_Sibling ( root : Link_to_Node; level : natural )
        !            20:                         return Link_to_Node is
        !            21:
        !            22:   -- DESCRIPTION :
        !            23:   --   Returns the last sibling at the level, or the empty pointer if
        !            24:   --   there is no node at that level.
        !            25:
        !            26:     res : Link_to_Node := null;
        !            27:     sibnd : Link_to_Node := Find_Node(root,level);
        !            28:
        !            29:     procedure Search_Next ( current : in Link_to_Node ) is
        !            30:     begin
        !            31:       if current.next_sibling = null
        !            32:        then res := current;
        !            33:        else Search_Next(current.next_sibling);
        !            34:       end if;
        !            35:     end Search_Next;
        !            36:
        !            37:   begin
        !            38:     if sibnd /= null
        !            39:      then Search_Next(sibnd);
        !            40:     end if;
        !            41:     return res;
        !            42:   end Last_Sibling;
        !            43:
        !            44:   procedure Search_Sibling ( root : in Link_to_Node; nd : in Node;
        !            45:                              lnd : out Link_to_Node; found : out boolean ) is
        !            46:
        !            47:   -- DESCRIPTION :
        !            48:   --   Searches the poset for the link to a node with contents nd.
        !            49:   --   If found is true, then lnd is a pointer to that node, otherwise
        !            50:   --   lnd points to the last sibling, or is empty when there is no
        !            51:   --   node at level nd.level.
        !            52:
        !            53:     sibnd : Link_to_Node := Find_Node(root,nd.level);
        !            54:
        !            55:     procedure Search_Next ( current : in Link_to_Node ) is
        !            56:     begin
        !            57:       if Equal(current.all,nd)
        !            58:        then found := true;
        !            59:             lnd := current;
        !            60:        elsif current.next_sibling = null
        !            61:            then found := false;
        !            62:                 lnd := current;
        !            63:            else Search_Next(current.next_sibling);
        !            64:       end if;
        !            65:     end Search_Next;
        !            66:
        !            67:   begin
        !            68:     if sibnd = null
        !            69:      then lnd := sibnd; found := false;
        !            70:      else Search_Next(sibnd);
        !            71:     end if;
        !            72:   end Search_Sibling;
        !            73:
        !            74:   function Create_Child ( root : Link_to_Node; child : Node; share : boolean )
        !            75:                         return Link_to_Node is
        !            76:
        !            77:   -- DESCRIPTION :
        !            78:   --   If the flag share is on, then the poset is searched for a node
        !            79:   --   with the same contents as the child.  If a sibling is found,
        !            80:   --   then the pointer to this sibling is returned, otherwise the link
        !            81:   --   on return is a newly created link to node with contents child.
        !            82:   --   If the flag share is off, then the link on return points to the
        !            83:   --   last sibling node on that level, which has now contents child.
        !            84:
        !            85:     res,lnd : Link_to_Node;
        !            86:     found : boolean;
        !            87:
        !            88:   begin
        !            89:     if share
        !            90:      then Search_Sibling(root,child,lnd,found);
        !            91:           if found
        !            92:            then res := lnd;
        !            93:           end if;
        !            94:      else lnd := Last_Sibling(root,child.level);
        !            95:           found := false;
        !            96:     end if;
        !            97:     if not found
        !            98:      then res := new Node'(child);
        !            99:           if lnd /= null
        !           100:            then lnd.next_sibling := res;
        !           101:                 res.prev_sibling := lnd;
        !           102:           end if;
        !           103:     end if;
        !           104:     return res;
        !           105:   end Create_Child;
        !           106:
        !           107:   function Find_Index ( indexed_poset : Array_of_Array_of_Nodes;
        !           108:                         nd : Link_to_Node ) return natural is
        !           109:
        !           110:   -- DESCRIPTION :
        !           111:   --   Returns 0 if the node does not occur at indexed_poset(nd.level),
        !           112:   --   otherwise returns the index of the node nd in that array.
        !           113:   --   Note that the pointers are compared to deal with sharing.
        !           114:
        !           115:   begin
        !           116:     if indexed_poset(nd.level) /= null
        !           117:      then for i in indexed_poset(nd.level)'range loop
        !           118:             if indexed_poset(nd.level)(i) = nd
        !           119:              then return i;
        !           120:             end if;
        !           121:           end loop;
        !           122:     end if;
        !           123:     return 0;
        !           124:   end Find_Index;
        !           125:
        !           126:   function Labels_of_Children ( indexed_poset : Array_of_Array_of_Nodes;
        !           127:                                 nd : Node ) return Link_to_Vector is
        !           128:
        !           129:   -- DESCRIPTION :
        !           130:   --   Returns the labels of the children of the current node.
        !           131:
        !           132:   -- REQUIRED : indexed_poset(i) created for i < nd.level.
        !           133:
        !           134:     res : Link_to_Vector;
        !           135:     nbc : constant natural := Number_of_Children(nd);
        !           136:     cnt : natural;
        !           137:
        !           138:   begin
        !           139:     if nbc /= 0
        !           140:      then res := new Standard_Natural_Vectors.Vector(1..nbc);
        !           141:           cnt := 0;
        !           142:           for i in nd.children'range(1) loop
        !           143:             for j in nd.children'range(2) loop
        !           144:               if nd.children(i,j) /= null
        !           145:                then cnt := cnt+1;
        !           146:                     res(cnt) := Find_Index(indexed_poset,nd.children(i,j));
        !           147:               end if;
        !           148:             end loop;
        !           149:           end loop;
        !           150:     end if;
        !           151:     return res;
        !           152:   end Labels_of_Children;
        !           153:
        !           154: -- SPECIAL TEST FOR GENERAL QUANTUM PIERI RULE :
        !           155:
        !           156:   function Special_Plane ( piv : Bracket; lag : natural ) return Bracket is
        !           157:
        !           158:   -- DESCRIPTION :
        !           159:   --   Returns the indices of the basis vectors that span the special
        !           160:   --   m-dimensional plane, defined by the complementary indices in piv.
        !           161:
        !           162:     res : Bracket(1..lag-piv'last);
        !           163:     ind : natural := 0;
        !           164:     found : boolean;
        !           165:
        !           166:   begin
        !           167:     for i in 1..lag loop
        !           168:       found := false;
        !           169:       for j in piv'range loop
        !           170:         found := (piv(j) = i);
        !           171:         exit when found or (piv(j) > i);
        !           172:       end loop;
        !           173:       if not found
        !           174:        then ind := ind+1;
        !           175:             res(ind) := i;
        !           176:       end if;
        !           177:     end loop;
        !           178:     return res;
        !           179:   end Special_Plane;
        !           180:
        !           181:   function Intersect_Spaces ( b1,b2 : Bracket ) return Bracket is
        !           182:
        !           183:   -- DESCRIPTION :
        !           184:   --   Returns the pivots that are common to both brackets.
        !           185:
        !           186:     res : Bracket(b1'range);
        !           187:     cnt : natural := 0;
        !           188:     found : boolean;
        !           189:
        !           190:   begin
        !           191:     for i in b1'range loop
        !           192:       found := false;
        !           193:       for j in b2'range loop
        !           194:         found := (b2(j) = b1(i));
        !           195:         exit when found;
        !           196:       end loop;
        !           197:       if found
        !           198:        then cnt := cnt+1;
        !           199:             res(cnt) := b1(i);
        !           200:       end if;
        !           201:     end loop;
        !           202:     return res(1..cnt);
        !           203:   end Intersect_Spaces;
        !           204:
        !           205:   function Merging_Top_Pivot_Test ( piv,spc : Bracket ) return boolean is
        !           206:
        !           207:   -- DESCRIPTION :
        !           208:   --   Returns true if there exists a decreasing sequence of successive
        !           209:   --   pivots from piv and spc that has length strictly higher than the
        !           210:   --   value of the last pivot used, starting at the tails of the brackets.
        !           211:
        !           212:     max : constant natural := piv'last + spc'last;
        !           213:     acc : Bracket(1..max) := (1..max => 0);
        !           214:     acc_ind : natural := max+1;
        !           215:     piv_ind : natural := piv'last;
        !           216:     spc_ind : natural := spc'last;
        !           217:     stop : boolean;
        !           218:
        !           219:     procedure Merge ( fail : out boolean ) is
        !           220:
        !           221:     -- DESCRIPTION :
        !           222:     --   A consecutive pivot is added to the accumulator;
        !           223:     --   failure is reported when such is not possible.
        !           224:
        !           225:       procedure Add_from_Pivots is
        !           226:       begin
        !           227:         if (acc_ind = max+1) or else (piv(piv_ind) >= acc(acc_ind) - 1)
        !           228:          then acc_ind := acc_ind-1;
        !           229:               acc(acc_ind) := piv(piv_ind);
        !           230:               piv_ind := piv_ind-1;
        !           231:               fail := false;
        !           232:         end if;
        !           233:       end Add_from_Pivots;
        !           234:
        !           235:       procedure Add_from_Space is
        !           236:       begin
        !           237:         if (acc_ind = max+1) or else (spc(spc_ind) >= acc(acc_ind) - 1)
        !           238:          then acc_ind := acc_ind-1;
        !           239:               acc(acc_ind) := spc(spc_ind);
        !           240:               spc_ind := spc_ind-1;
        !           241:               fail := false;
        !           242:         end if;
        !           243:       end Add_from_Space;
        !           244:
        !           245:     begin
        !           246:       fail := true;
        !           247:       if piv_ind >= piv'first
        !           248:        then if spc_ind >= spc'first
        !           249:              then if piv(piv_ind) >= spc(spc_ind)
        !           250:                    then Add_from_Pivots;
        !           251:                    else Add_from_Space;
        !           252:                   end if;
        !           253:              else Add_from_Pivots;
        !           254:             end if;
        !           255:        else if spc_ind >= spc'first
        !           256:              then Add_from_Space;
        !           257:             end if;
        !           258:       end if;
        !           259:     end Merge;
        !           260:
        !           261:   begin
        !           262:     loop
        !           263:       Merge(stop);
        !           264:       if acc(acc_ind) > (acc_ind + (acc(max) - max))
        !           265:        then return true;
        !           266:       end if;
        !           267:       exit when stop;
        !           268:     end loop;
        !           269:     return false;
        !           270:   end Merging_Top_Pivot_Test;
        !           271:
        !           272:   function Merging_Bottom_Pivot_Test ( piv,spc : Bracket ) return boolean is
        !           273:
        !           274:   -- DESCRIPTION :
        !           275:   --   Returns true if there exists a increasing sequence of successive
        !           276:   --   pivots from piv and spc that has length strictly higher than the
        !           277:   --   value of the last pivot used, starting at the heads of the brackets.
        !           278:
        !           279:     max : constant natural := piv'last + spc'last;
        !           280:     acc : Bracket(1..max) := (1..max => 0);
        !           281:     acc_ind : natural := 0;
        !           282:     piv_ind : natural := piv'first;
        !           283:     spc_ind : natural := spc'first;
        !           284:     stop : boolean;
        !           285:
        !           286:     procedure Merge ( fail : out boolean ) is
        !           287:
        !           288:     -- DESCRIPTION :
        !           289:     --   A consecutive pivot is added to the accumulator;
        !           290:     --   failure is reported when such is not possible.
        !           291:
        !           292:       procedure Add_from_Pivots is
        !           293:       begin
        !           294:         if (acc_ind = 0) or else (piv(piv_ind) <= acc(acc_ind) + 1)
        !           295:          then acc_ind := acc_ind+1;
        !           296:               acc(acc_ind) := piv(piv_ind);
        !           297:               piv_ind := piv_ind+1;
        !           298:               fail := false;
        !           299:         end if;
        !           300:       end Add_from_Pivots;
        !           301:
        !           302:       procedure Add_from_Space is
        !           303:       begin
        !           304:         if (acc_ind = 0) or else (spc(spc_ind) <= acc(acc_ind) + 1)
        !           305:          then acc_ind := acc_ind+1;
        !           306:               acc(acc_ind) := spc(spc_ind);
        !           307:               spc_ind := spc_ind+1;
        !           308:               fail := false;
        !           309:         end if;
        !           310:       end Add_from_Space;
        !           311:
        !           312:     begin
        !           313:       fail := true;
        !           314:       if piv_ind <= piv'last
        !           315:        then if spc_ind <= spc'last
        !           316:              then if piv(piv_ind) <= spc(spc_ind)
        !           317:                    then Add_from_Pivots;
        !           318:                    else Add_from_Space;
        !           319:                   end if;
        !           320:              else Add_from_Pivots;
        !           321:             end if;
        !           322:        else if spc_ind <= spc'last
        !           323:              then Add_from_Space;
        !           324:             end if;
        !           325:       end if;
        !           326:     end Merge;
        !           327:
        !           328:   begin
        !           329:     loop
        !           330:       Merge(stop);
        !           331:       if acc(acc_ind) < (acc_ind + (acc(1) - 1))
        !           332:        then return true;
        !           333:       end if;
        !           334:       exit when stop;
        !           335:     end loop;
        !           336:     return false;
        !           337:   end Merging_Bottom_Pivot_Test;
        !           338:
        !           339: -- CREATOR PRIMITIVES I : CHECK IF CREATION IS POSSIBLE AND ALLOWED
        !           340:
        !           341:   function Top_Creatable ( nd : Node; n,i : natural ) return boolean is
        !           342:
        !           343:   -- DESCRIPTION :
        !           344:   --   Returns true if the i-th top pivot can be incremented.
        !           345:   --   The n is the dimension of the working space.
        !           346:
        !           347:   begin
        !           348:     if nd.bottom(i) <= nd.top(i)
        !           349:      then return false;
        !           350:      elsif i = nd.p
        !           351:          then return (nd.top(i) < n);
        !           352:          else return (nd.top(i)+1 < nd.top(i+1));
        !           353:     end if;
        !           354:   end Top_Creatable;
        !           355:
        !           356:   function Q_Top_Creatable ( nd : Node; n,lag,i : natural ) return boolean is
        !           357:
        !           358:   -- DESCRIPTION :
        !           359:   --   Returns true if the i-th top pivot can be incremented.
        !           360:   --   The n is the dimension of the working space.
        !           361:
        !           362:   begin
        !           363:     if not Top_Creatable(nd,n,i)
        !           364:      then return false;
        !           365:      elsif i < nd.p
        !           366:          then return true;
        !           367:          else return (nd.top(nd.p) - nd.top(1) + 1 < lag);
        !           368:     end if;
        !           369:   end Q_Top_Creatable;
        !           370:
        !           371:   function Q_Top_Creatable
        !           372:                ( nd : Node; modtop,space : Bracket; n,lag,pi,i : natural )
        !           373:                return boolean is
        !           374:
        !           375:   -- DESCRIPTION :
        !           376:   --   This is the quantum analogue to implement the modular bottom-left
        !           377:   --   rule as needed in the general intersection case.
        !           378:
        !           379:   -- ON ENTRY :
        !           380:   --   nd        current node;
        !           381:   --   modtop    top pivots of nd, modulo the lag;
        !           382:   --   space     generators of the intersection of special m-planes;
        !           383:   --   n         dimension of the working space;
        !           384:   --   lag       equals m+p;
        !           385:   --   pi        index in nd.top, permuted index i used to sort modtop;
        !           386:   --   i         modtop(i) will be increased to derive the child.
        !           387:
        !           388:     child : Bracket(modtop'range) := modtop;
        !           389:
        !           390:   begin
        !           391:     if not Q_Top_Creatable(nd,n,lag,pi)                -- valid pattern ?
        !           392:      then return false;
        !           393:      else -- valid pattern => valid child, only last entry might be zero
        !           394:           child(i) := modtop(i)+1;
        !           395:           if i = child'last and child(i) = lag+1
        !           396:            then for j in reverse child'first+1..child'last loop
        !           397:                   child(j) := child(j-1);
        !           398:                 end loop;
        !           399:                 child(child'first) := 1;
        !           400:           end if;
        !           401:           return Merging_Top_Pivot_Test(child,space);
        !           402:     end if;
        !           403:   end Q_Top_Creatable;
        !           404:
        !           405:   function Bottom_Creatable ( nd : Node; i : natural ) return boolean is
        !           406:
        !           407:   -- DESCRIPTION :
        !           408:   --   Returns true if the i-th bottom pivot can be decremented.
        !           409:
        !           410:   begin
        !           411:     if nd.bottom(i) <= nd.top(i)
        !           412:      then return false;
        !           413:      elsif i = 1
        !           414:          then return (nd.bottom(i) > 1);
        !           415:          else return (nd.bottom(i)-1 > nd.bottom(i-1));
        !           416:     end if;
        !           417:   end Bottom_Creatable;
        !           418:
        !           419:   function Q_Bottom_Creatable ( nd : Node; lag,i : natural ) return boolean is
        !           420:
        !           421:   -- DESCRIPTION :
        !           422:   --   Returns true if the i-th bottom pivot can be decremented and if
        !           423:   --   the spacing between first and last bottom pivot will remain < lag.
        !           424:
        !           425:   begin
        !           426:     if not Bottom_Creatable(nd,i)
        !           427:      then return false;
        !           428:      elsif i > 1
        !           429:          then return true;
        !           430:          else return (nd.bottom(nd.p) - nd.bottom(1) + 1 < lag);
        !           431:     end if;
        !           432:   end Q_Bottom_Creatable;
        !           433:
        !           434:   function Q_Bottom_Creatable
        !           435:                ( nd : Node; modbot,space : Bracket; lag,pi,i : natural )
        !           436:                return boolean is
        !           437:
        !           438:   -- DESCRIPTION :
        !           439:   --   This is the quantum analogue to implement the modular bottom-left
        !           440:   --   rule as needed in the general intersection case.
        !           441:
        !           442:   -- ON ENTRY :
        !           443:   --   nd        current node;
        !           444:   --   modbot    bottom pivots of nd, modulo the lag;
        !           445:   --   space     generators of the intersection of special m-planes;
        !           446:   --   lag       equals m+p;
        !           447:   --   pi        index in nd.bottom, permuted index i used to sort modbot;
        !           448:   --   i         modbot(i) will be decreased to derive the child.
        !           449:
        !           450:     child : Bracket(modbot'range) := modbot;
        !           451:
        !           452:   begin
        !           453:     if not Q_Bottom_Creatable(nd,lag,pi)             -- valid pattern ?
        !           454:      then return false;
        !           455:      else -- valid pattern => valid child, only 1st entry might be zero
        !           456:           child(i) := modbot(i)-1;
        !           457:           if i = 1 and child(i) = 0
        !           458:            then for j in child'first..child'last-1 loop
        !           459:                   child(j) := child(j+1);
        !           460:                 end loop;
        !           461:                 child(child'last) := lag;
        !           462:           end if;
        !           463:           return Merging_Bottom_Pivot_Test(child,space);
        !           464:     end if;
        !           465:   end Q_Bottom_Creatable;
        !           466:
        !           467:   function Top_Bottom_Creatable ( nd : Node; n,i,j : natural )
        !           468:                                 return boolean is
        !           469:
        !           470:   -- DESCRIPTION :
        !           471:   --   Returns true if the i-th top pivot can be incremented and if
        !           472:   --   the j-th bottom pivot can be decremented.
        !           473:
        !           474:   begin
        !           475:     if not Top_Creatable(nd,n,i)
        !           476:      then return false;
        !           477:      elsif not Bottom_Creatable(nd,j)
        !           478:          then return false;
        !           479:          elsif i /= j
        !           480:              then return true;
        !           481:              else return (nd.bottom(i) - nd.top(i) > 1);
        !           482:     end if;
        !           483:   end Top_Bottom_Creatable;
        !           484:
        !           485:   function Q_Top_Bottom_Creatable ( nd : Node; n,lag,i,j : natural )
        !           486:                                   return boolean is
        !           487:
        !           488:   -- DESCRIPTION :
        !           489:   --   Returns true if the i-th top pivot can be incremented and if
        !           490:   --   the j-th bottom pivot can be decremented.
        !           491:
        !           492:   begin
        !           493:     if not Q_Top_Creatable(nd,n,lag,i)
        !           494:      then return false;
        !           495:      elsif not Q_Bottom_Creatable(nd,lag,j)
        !           496:          then return false;
        !           497:          elsif i /= j
        !           498:              then return true;
        !           499:              else return (nd.bottom(i) - nd.top(i) > 1);
        !           500:     end if;
        !           501:   end Q_Top_Bottom_Creatable;
        !           502:
        !           503:   function Q_Top_Bottom_Creatable
        !           504:               ( nd : Node; modtop,topspc,modbot,botspc : Bracket;
        !           505:                 n,lag,pi,i,pj,j : natural ) return boolean is
        !           506:
        !           507:   -- DESCRIPTION :
        !           508:   --   Returns true if the i-th top pivot can be incremented and if
        !           509:   --   the j-th bottom pivot can be decremented in the general quantum
        !           510:   --   Pieri homotopy algorithm.
        !           511:
        !           512:   begin
        !           513:     if not Q_Top_Creatable(nd,modtop,topspc,n,lag,pi,i)
        !           514:      then return false;
        !           515:      elsif not Q_Bottom_Creatable(nd,modbot,botspc,lag,pj,j)
        !           516:          then return false;
        !           517:          elsif pi /= pj
        !           518:              then return true;
        !           519:              else return (nd.bottom(pi) - nd.top(pi) > 1);
        !           520:     end if;
        !           521:   end Q_Top_Bottom_Creatable;
        !           522:
        !           523: -- CREATOR PRIMITIVES II : DERIVE CHILD FROM NODE
        !           524:
        !           525:   procedure Create_Top_Child ( root,nd : in out Link_to_Node;
        !           526:                                i : in natural; share : in boolean ) is
        !           527:
        !           528:   -- DESCRIPTION :
        !           529:   --   Creates a child of the given node by incrementing the i-th top pivot.
        !           530:
        !           531:     child : Node(nd.p);
        !           532:
        !           533:   begin
        !           534:     child.level := nd.level-1;
        !           535:     child.roco := 0;
        !           536:     child.bottom := nd.bottom;
        !           537:     child.top := nd.top;
        !           538:     child.top(i) := nd.top(i)+1;
        !           539:     nd.children(i,0) := Create_Child(root,child,share);
        !           540:   end Create_Top_Child;
        !           541:
        !           542:   procedure Create_Bottom_Child ( root,nd : in out Link_to_Node;
        !           543:                                   i : in natural; share : in boolean ) is
        !           544:
        !           545:   -- DESCRIPTION :
        !           546:   --   Creates a child of the node nd by decrementing the i-th bottom pivot.
        !           547:
        !           548:     child : Node(nd.p);
        !           549:
        !           550:   begin
        !           551:     child.level := nd.level-1;
        !           552:     child.roco := 0;
        !           553:     child.bottom := nd.bottom;
        !           554:     child.top := nd.top;
        !           555:     child.bottom(i) := nd.bottom(i)-1;
        !           556:     nd.children(0,i) := Create_Child(root,child,share);
        !           557:   end Create_Bottom_Child;
        !           558:
        !           559:   procedure Create_Top_Bottom_Child
        !           560:                ( root,nd : in out Link_to_Node;
        !           561:                  i,j : in natural; share : in boolean ) is
        !           562:
        !           563:   -- DESCRIPTION :
        !           564:   --   Creates a child of the node nd by incrementing the i-th top pivot
        !           565:   --   and decrementing the i-th bottom pivot.
        !           566:
        !           567:     child : Node(nd.p);
        !           568:
        !           569:   begin
        !           570:     child.level := nd.level-2;
        !           571:     child.roco := 0;
        !           572:     child.top := nd.top;
        !           573:     child.top(i) := nd.top(i)+1;
        !           574:     child.bottom := nd.bottom;
        !           575:     child.bottom(j) := nd.bottom(j)-1;
        !           576:     nd.children(i,j) := Create_Child(root,child,share);
        !           577:   end Create_Top_Bottom_Child;
        !           578:
        !           579: -- CREATOR PRIMITIVES III : TREAT ONE/TWO DEGREE(S) OF FREEDOM
        !           580:
        !           581:   procedure Top_Create1 ( root,nd : in out Link_to_Node; n : in natural ) is
        !           582:
        !           583:   -- DESCRIPTION :
        !           584:   --   Creates new nodes by incrementing the top pivots, bounded by n.
        !           585:   --   The levels of the children nodes decrease by one as this is the
        !           586:   --   hypersurface case.
        !           587:
        !           588:   begin
        !           589:     nd.tp := top;
        !           590:     for i in nd.top'range loop
        !           591:       if Top_Creatable(nd.all,n,i)
        !           592:        then Create_Top_Child(root,nd,i,true);
        !           593:       end if;
        !           594:     end loop;
        !           595:   end Top_Create1;
        !           596:
        !           597:   procedure Q_Top_Create1 ( root,nd : in out Link_to_Node;
        !           598:                             n,lag : in natural ) is
        !           599:
        !           600:   -- DESCRIPTION :
        !           601:   --   Creates new nodes by incrementing the top pivots, for general q,
        !           602:   --   where we need the parameters n = dimension of working space
        !           603:   --   and lag = m+p, to bound the space between first and last entry.
        !           604:
        !           605:   begin
        !           606:     nd.tp := top;
        !           607:     for i in nd.top'range loop
        !           608:       if Q_Top_Creatable(nd.all,n,lag,i)
        !           609:        then Create_Top_Child(root,nd,i,true);
        !           610:       end if;
        !           611:     end loop;
        !           612:   end Q_Top_Create1;
        !           613:
        !           614:   procedure Top_Create1 ( root,nd : in out Link_to_Node;
        !           615:                           k,n,c : in natural ) is
        !           616:
        !           617:   -- DESCRIPTION :
        !           618:   --   Does k steps of the other Top_Create1 taking pivots larger than c.
        !           619:   --   This is the general case, for k=1 we have the hypersurface case.
        !           620:
        !           621:     share : boolean := (k = 1);
        !           622:
        !           623:   begin
        !           624:     if k > 0
        !           625:      then nd.tp := top;
        !           626:           for i in c..nd.top'last loop
        !           627:             if Top_Creatable(nd.all,n,i)
        !           628:              then Create_Top_Child(root,nd,i,share);
        !           629:                   if k > 1
        !           630:                    then Top_Create1(root,nd.children(i,0),k-1,n,i);
        !           631:                   end if;
        !           632:             end if;
        !           633:           end loop;
        !           634:     end if;
        !           635:   end Top_Create1;
        !           636:
        !           637:   procedure Q_Top_Create1 ( root,nd : in out Link_to_Node;
        !           638:                             first : in boolean; space : in Bracket;
        !           639:                             k,n,lag : in natural ) is
        !           640:
        !           641:   -- DESCRIPTION :
        !           642:   --   Does k steps in a top-right chain on modular brackets.
        !           643:   --   The top-right rule is enforced by the merging pivot test involving
        !           644:   --   top pivots and the indices of the vectors that span the space of
        !           645:   --   intersection of special m-planes.
        !           646:
        !           647:   -- ON ENTRY :
        !           648:   --   root       root of the poset where the construction started;
        !           649:   --   nd         current node;
        !           650:   --   first      if true, then this is the first step in the sequence,
        !           651:   --              and the space has yet to be determined;
        !           652:   --   space      contains generators of the intersection of special m-planes;
        !           653:   --   k          number of steps still left to do;
        !           654:   --   n          dimension of the space;
        !           655:   --   lag        m+p.
        !           656:
        !           657:     share : boolean := (k=1);
        !           658:     modtop : Bracket(nd.top'range);
        !           659:     perm : Standard_Natural_Vectors.Vector(modtop'range);
        !           660:     special : Bracket(1..lag-nd.p);
        !           661:
        !           662:     procedure Recursive_Top_Create1 ( new_space : in Bracket ) is
        !           663:
        !           664:     -- DESCRIPTION :
        !           665:     --   Additional layer needed for the determination of the updated space.
        !           666:
        !           667:     begin
        !           668:       for i in modtop'range loop
        !           669:         if Q_Top_Creatable(nd.all,modtop,new_space,n,lag,perm(i),i)
        !           670:          then Create_Top_Child(root,nd,perm(i),share);
        !           671:               if k > 1
        !           672:                then Q_Top_Create1(root,nd.children(perm(i),0),
        !           673:                                   false,new_space,k-1,n,lag);
        !           674:               end if;
        !           675:         end if;
        !           676:       end loop;
        !           677:     end Recursive_Top_Create1;
        !           678:
        !           679:   begin
        !           680:     if k > 0
        !           681:      then nd.tp := top;
        !           682:           Modulo(nd.top,lag,perm,modtop);
        !           683:           special := Special_Plane(modtop,lag);
        !           684:           if first
        !           685:            then Recursive_Top_Create1(special);
        !           686:            else declare
        !           687:                   int_spc : constant Bracket
        !           688:                           := Intersect_Spaces(space,special);
        !           689:                 begin
        !           690:                   Recursive_Top_Create1(int_spc);
        !           691:                 end;
        !           692:           end if;
        !           693:     end if;
        !           694:   end Q_Top_Create1;
        !           695:
        !           696:   procedure Bottom_Create1 ( root,nd : in out Link_to_Node ) is
        !           697:
        !           698:   -- DESCRIPTION :
        !           699:   --   Creates new nodes by decrementing the bottom pivots.
        !           700:   --   The levels of the children nodes decrease by one as this is
        !           701:   --   the hypersurface case.
        !           702:
        !           703:   begin
        !           704:     nd.tp := bottom;
        !           705:     for i in nd.top'range loop
        !           706:       if Bottom_Creatable(nd.all,i)
        !           707:        then Create_Bottom_Child(root,nd,i,true);
        !           708:       end if;
        !           709:     end loop;
        !           710:   end Bottom_Create1;
        !           711:
        !           712:   procedure Q_Bottom_Create1
        !           713:                 ( root,nd : in out Link_to_Node; lag : in natural ) is
        !           714:
        !           715:   -- DESCRIPTION :
        !           716:   --   Creates new nodes by decrementing the bottom pivots for general q,
        !           717:   --   where the parameter lag > max space between first and last entry.
        !           718:
        !           719:   begin
        !           720:     nd.tp := bottom;
        !           721:     for i in nd.top'range loop
        !           722:       if Q_Bottom_Creatable(nd.all,lag,i)
        !           723:        then Create_Bottom_Child(root,nd,i,true);
        !           724:       end if;
        !           725:     end loop;
        !           726:   end Q_Bottom_Create1;
        !           727:
        !           728:   procedure Bottom_Create1 ( root,nd : in out Link_to_Node;
        !           729:                              k,c : in natural ) is
        !           730:
        !           731:   -- DESCRIPTION :
        !           732:   --   Does k steps of the other Bottom_Create1 taking pivots smaller than c.
        !           733:   --   This is the general case, for k=1 we have the hypersurface case.
        !           734:
        !           735:     share : boolean := (k=1);
        !           736:
        !           737:   begin
        !           738:     if k > 0
        !           739:      then nd.tp := bottom;
        !           740:           for i in nd.bottom'first..c loop
        !           741:             if Bottom_Creatable(nd.all,i)
        !           742:              then Create_Bottom_Child(root,nd,i,share);
        !           743:                   if k > 1
        !           744:                    then Bottom_Create1(root,nd.children(0,i),k-1,i);
        !           745:                   end if;
        !           746:             end if;
        !           747:           end loop;
        !           748:     end if;
        !           749:   end Bottom_Create1;
        !           750:
        !           751:   procedure Q_Bottom_Create1 ( root,nd : in out Link_to_Node;
        !           752:                                first : in boolean; space : in Bracket;
        !           753:                                k,lag : in natural ) is
        !           754:
        !           755:   -- DESCRIPTION :
        !           756:   --   Does k steps in a bottom-left chain on modular brackets.
        !           757:   --   The bottom-left rule is enforced by the merging pivot test involving
        !           758:   --   bottom pivots and the indices of the vectors that span the space of
        !           759:   --   intersection of special m-planes.
        !           760:
        !           761:   -- ON ENTRY :
        !           762:   --   root       root of the poset where the construction started;
        !           763:   --   nd         current node;
        !           764:   --   first      if true, then this is the first step in the sequence,
        !           765:   --              and the space has yet to be determined;
        !           766:   --   space      contains generators of the intersection of special m-planes;
        !           767:   --   k          number of steps still left to do;
        !           768:   --   lag        m+p.
        !           769:
        !           770:     share : boolean := (k=1);
        !           771:     modbot : Bracket(nd.bottom'range);
        !           772:     perm : Standard_Natural_Vectors.Vector(modbot'range);
        !           773:     special : Bracket(1..lag-nd.p);
        !           774:
        !           775:     procedure Recursive_Bottom_Create1 ( new_space : in Bracket ) is
        !           776:
        !           777:     -- DESCRIPTION :
        !           778:     --   Additional layer needed for the determination of the updated space.
        !           779:
        !           780:     begin
        !           781:       for i in modbot'range loop
        !           782:         if Q_Bottom_Creatable(nd.all,modbot,new_space,lag,perm(i),i)
        !           783:          then Create_Bottom_Child(root,nd,perm(i),share);
        !           784:               if k > 1
        !           785:                then Q_Bottom_Create1(root,nd.children(0,perm(i)),
        !           786:                                      false,new_space,k-1,lag);
        !           787:               end if;
        !           788:         end if;
        !           789:       end loop;
        !           790:     end Recursive_Bottom_Create1;
        !           791:
        !           792:   begin
        !           793:     if k > 0
        !           794:      then nd.tp := bottom;
        !           795:           Modulo(nd.bottom,lag,perm,modbot);
        !           796:           special := Special_Plane(modbot,lag);
        !           797:           if first
        !           798:            then Recursive_Bottom_Create1(special);
        !           799:            else declare
        !           800:                   int_spc : constant Bracket
        !           801:                           := Intersect_Spaces(space,special);
        !           802:                 begin
        !           803:                   Recursive_Bottom_Create1(int_spc);
        !           804:                 end;
        !           805:           end if;
        !           806:     end if;
        !           807:   end Q_Bottom_Create1;
        !           808:
        !           809:   procedure Top_Bottom_Create1 ( root,nd : in out Link_to_Node;
        !           810:                                  n : in natural ) is
        !           811:
        !           812:   -- DESCRIPTION :
        !           813:   --   Creates new nodes by incrementing top pivots and decrementing bottom
        !           814:   --   pivots, with n the maximal entry in any pivot.
        !           815:   --   If no top create is possible, then a bottom create will be done,
        !           816:   --   and we have only a bottom create when no top create is possible.
        !           817:
        !           818:     nocreate : boolean := true;
        !           819:
        !           820:   begin
        !           821:     nd.tp := mixed;
        !           822:     for i in nd.top'range loop                      -- first do top+bottom
        !           823:       for j in nd.bottom'range loop
        !           824:         if Top_Bottom_Creatable(nd.all,n,i,j)
        !           825:          then Create_Top_Bottom_Child(root,nd,i,j,true);
        !           826:               nocreate := false;
        !           827:         end if;
        !           828:       end loop;
        !           829:     end loop;
        !           830:     if nocreate                            -- no top+bottom create possible
        !           831:      then Bottom_Create1(root,nd);
        !           832:           if Is_Leaf(nd.all)                   -- no bottom create possible
        !           833:            then Top_Create1(root,nd,n);
        !           834:           end if;
        !           835:     end if;
        !           836:   end Top_Bottom_Create1;
        !           837:
        !           838:   procedure Q_Top_Bottom_Create1 ( root,nd : in out Link_to_Node;
        !           839:                                    n,lag : in natural ) is
        !           840:
        !           841:   -- DESCRIPTION :
        !           842:   --   Creates new nodes by incrementing top pivots and decrementing bottom
        !           843:   --   pivots, with n the maximal entry in any pivot.
        !           844:   --   If no top create is possible, then a bottom create will be done,
        !           845:   --   and we have only a bottom create when no top create is possible.
        !           846:
        !           847:     nocreate : boolean := true;
        !           848:
        !           849:   begin
        !           850:     nd.tp := mixed;
        !           851:     for i in nd.top'range loop                      -- first do top+bottom
        !           852:       for j in nd.bottom'range loop
        !           853:         if Q_Top_Bottom_Creatable(nd.all,n,lag,i,j)
        !           854:          then Create_Top_Bottom_Child(root,nd,i,j,true);
        !           855:               nocreate := false;
        !           856:         end if;
        !           857:       end loop;
        !           858:     end loop;
        !           859:     if nocreate                            -- no top+bottom create possible
        !           860:      then Q_Bottom_Create1(root,nd,lag);
        !           861:           if Is_Leaf(nd.all)                   -- no bottom create possible
        !           862:            then Q_Top_Create1(root,nd,n,lag);
        !           863:           end if;
        !           864:     end if;
        !           865:   end Q_Top_Bottom_Create1;
        !           866:
        !           867:   procedure Top_Bottom_Create1 ( root,nd : in out Link_to_Node;
        !           868:                                  k1,k2,n,c1,c2 : in natural ) is
        !           869:
        !           870:   -- DESCRIPTION :
        !           871:   --   Applies the hypersurface Top_Bottom_Create max(k1,k2) times,
        !           872:   --   taking top pivots in c1..p and bottom pivots in 1..c2.
        !           873:   --   This is the top-bottom create that takes the codimensions in pairs,
        !           874:   --   which allows more possibilities for sharing.
        !           875:
        !           876:     share : constant boolean := ((k1=1) and (k2=1));
        !           877:
        !           878:   begin
        !           879:     if (k1 > 0) and (k2 > 0)
        !           880:      then
        !           881:        nd.tp := mixed;
        !           882:        for i in c1..nd.top'last loop                    -- first do top+bottom
        !           883:          for j in nd.bottom'first..c2 loop
        !           884:            if Top_Bottom_Creatable(nd.all,n,i,j)
        !           885:             then
        !           886:               Create_Top_Bottom_Child(root,nd,i,j,share);
        !           887:               if ((k1 > 1) or (k2 > 1))
        !           888:                then Top_Bottom_Create1(root,nd.children(i,j),k1-1,k2-1,n,i,j);
        !           889:               end if;
        !           890:            end if;
        !           891:          end loop;
        !           892:        end loop;
        !           893:     end if;
        !           894:     if ((k1 = 0) and (k2 > 0))
        !           895:      then Bottom_Create1(root,nd,k2,c2);
        !           896:      elsif ((k1 > 0) and (k2 = 0))
        !           897:          then Top_Create1(root,nd,k1,n,c1);
        !           898:     end if;
        !           899:   end Top_Bottom_Create1;
        !           900:
        !           901:   procedure Recursive_Top_Bottom_Create
        !           902:               ( root,nd : in out Link_to_Node;
        !           903:                 codim : in Bracket; ind,k1,k2,n,c1,c2 : in natural;
        !           904:                 hyper : in boolean ) is
        !           905:
        !           906:   -- DESCRIPTION :
        !           907:   --   Applies the hypersurface Top_Bottom_Create max(k1,k2) times,
        !           908:   --   taking top pivots in c1..p and bottom pivots in 1..c2.
        !           909:   --   In case k1 and/or k2 are zero, new conditions will be treated.
        !           910:
        !           911:   -- ON ENTRY :
        !           912:   --   root     root of the localization poset;
        !           913:   --   nd       current node;
        !           914:   --   codim    list of co-dimension conditions;
        !           915:   --   ind      index of lowest condition being treated;
        !           916:   --   k1       co-dimension condition satisfied decrementing top pivots;
        !           917:   --   k2       co-dimension condition satisfied incrementing bottom pivots;
        !           918:   --   n        dimension of the working space;
        !           919:   --   c1       needed to enforce the top-right rule;
        !           920:   --   c2       needed to enforce the bottom-left rule;
        !           921:   --   hyper    indicates whether or not in the hypersurface case.
        !           922:
        !           923:     newhyper : boolean;
        !           924:
        !           925:   begin
        !           926:     if (k1 > 0) and (k2 > 0)
        !           927:      then
        !           928:        nd.tp := mixed;
        !           929:        for i in c1..nd.top'last loop                    -- first do top+bottom
        !           930:          for j in nd.bottom'first..c2 loop
        !           931:            if Top_Bottom_Creatable(nd.all,n,i,j)
        !           932:             then Create_Top_Bottom_Child(root,nd,i,j,hyper);
        !           933:                  Recursive_Top_Bottom_Create
        !           934:                    (root,nd.children(i,j),codim,ind,k1-1,k2-1,n,i,j,false);
        !           935:            end if;
        !           936:          end loop;
        !           937:        end loop;
        !           938:        nd.roco := -1;
        !           939:     else
        !           940:       if ((k1 = 0) and (k2 > 0))
        !           941:        then if ind > codim'first
        !           942:              then Recursive_Top_Bottom_Create
        !           943:                     (root,nd,codim,ind-1,codim(ind-1),k2,n,1,c2,false);
        !           944:              else Bottom_Create1(root,nd,k2,c2);
        !           945:             end if;
        !           946:        elsif ((k1 > 0) and (k2 = 0))
        !           947:            then if ind > codim'first
        !           948:                  then Recursive_Top_Bottom_Create
        !           949:                         (root,nd,codim,ind-1,k1,codim(ind-1),n,c1,nd.p,false);
        !           950:                  else Top_Create1(root,nd,k1,n,c1);
        !           951:                 end if;
        !           952:            else -- k1 = 0 and k2 = 0
        !           953:                 if ind > codim'first + 1
        !           954:                  then newhyper
        !           955:                         := ((codim(ind-2) = 1) and (codim(ind-1) = 1));
        !           956:                       Recursive_Top_Bottom_Create
        !           957:                         (root,nd,codim,ind-2,codim(ind-2),codim(ind-1),n,1,
        !           958:                          nd.p,newhyper);
        !           959:                  elsif ind > codim'first
        !           960:                      then Bottom_Create1(root,nd,codim(ind-1),nd.p);
        !           961:                 end if;
        !           962:       end if;
        !           963:     end if;
        !           964:   end Recursive_Top_Bottom_Create;
        !           965:
        !           966:   procedure Q_Recursive_Top_Bottom_Create
        !           967:               ( root,nd : in out Link_to_Node; codim : in Bracket;
        !           968:                 fsttop : in boolean; topspc : in Bracket;
        !           969:                 fstbot : in boolean; botspc : in Bracket;
        !           970:                 ind,k1,k2,n,lag : in natural; hyper : in boolean ) is
        !           971:
        !           972:   -- DESCRIPTION :
        !           973:   --   Applies the hypersurface Q_Top_Bottom_Create max(k1,k2) times,
        !           974:   --   simulating the bottom-left and top-right rules with the modular
        !           975:   --   brackets and corresponding spaces.
        !           976:
        !           977:   -- ON ENTRY :
        !           978:   --   root     root of the localization poset;
        !           979:   --   nd       current node;
        !           980:   --   codim    list of co-dimension conditions;
        !           981:   --   fsttop   if true, then first step taken using top pivots;
        !           982:   --   topspc   intersection of special m-planes for top pivots;
        !           983:   --   fstbot   if true, then first step taken using bottom pivots;
        !           984:   --   botspc   intersection of special m-planes for bottom pivots;
        !           985:   --   ind      index of lowest condition being treated;
        !           986:   --   k1       co-dimension condition satisfied decrementing top pivots;
        !           987:   --   k2       co-dimension condition satisfied incrementing bottom pivots;
        !           988:   --   n        dimension of the working space;
        !           989:   --   lag      space in the poset that is of interest;
        !           990:   --   hyper    indicates whether or not in the hypersurface case.
        !           991:
        !           992:     newhyper : boolean;
        !           993:     modtop,modbot : Bracket(1..nd.p);
        !           994:     topprm,botprm : Standard_Natural_Vectors.Vector(1..nd.p);
        !           995:     top_special,bot_special : Bracket(1..lag-nd.p);
        !           996:
        !           997:     procedure Mixed_Create ( new_top_space,new_bot_space : in Bracket ) is
        !           998:     begin
        !           999:       for i in modtop'range loop
        !          1000:         for j in modbot'range loop
        !          1001:           if Q_Top_Bottom_Creatable
        !          1002:                (nd.all,modtop,new_top_space,modbot,new_bot_space,
        !          1003:                 n,lag,topprm(i),i,botprm(j),j)
        !          1004:            then Create_Top_Bottom_Child(root,nd,topprm(i),botprm(j),hyper);
        !          1005:                 Q_Recursive_Top_Bottom_Create
        !          1006:                    (root,nd.children(topprm(i),botprm(j)),codim,
        !          1007:                     false,new_top_space,false,new_bot_space,
        !          1008:                     ind,k1-1,k2-1,n,lag,false);
        !          1009:           end if;
        !          1010:         end loop;
        !          1011:       end loop;
        !          1012:       nd.roco := -1;
        !          1013:     end Mixed_Create;
        !          1014:
        !          1015:   begin
        !          1016:     if (k1 > 0) and (k2 > 0)   -- first do top + bottom
        !          1017:      then
        !          1018:        nd.tp := mixed;
        !          1019:        Modulo(nd.top,lag,topprm,modtop);
        !          1020:        top_special := Special_Plane(modtop,lag);
        !          1021:        Modulo(nd.bottom,lag,botprm,modbot);
        !          1022:        bot_special := Special_Plane(modbot,lag);
        !          1023:        if fsttop
        !          1024:         then if fstbot
        !          1025:               then Mixed_Create(top_special,bot_special);
        !          1026:               else declare
        !          1027:                      int_spc : constant Bracket
        !          1028:                              := Intersect_Spaces(botspc,bot_special);
        !          1029:                    begin
        !          1030:                      Mixed_Create(top_special,int_spc);
        !          1031:                    end;
        !          1032:              end if;
        !          1033:         else if fstbot
        !          1034:               then declare
        !          1035:                      int_spc : constant Bracket
        !          1036:                              := Intersect_Spaces(topspc,top_special);
        !          1037:                    begin
        !          1038:                      Mixed_Create(int_spc,bot_special);
        !          1039:                    end;
        !          1040:               else declare
        !          1041:                      int_top : constant Bracket
        !          1042:                              := Intersect_Spaces(topspc,top_special);
        !          1043:                      int_bot : constant Bracket
        !          1044:                              := Intersect_Spaces(botspc,bot_special);
        !          1045:                    begin
        !          1046:                      Mixed_Create(int_top,int_bot);
        !          1047:                    end;
        !          1048:              end if;
        !          1049:        end if;
        !          1050:      else
        !          1051:        if ((k1 = 0) and (k2 > 0))
        !          1052:         then if ind > codim'first
        !          1053:               then Q_Recursive_Top_Bottom_Create
        !          1054:                      (root,nd,codim,true,topspc,fstbot,botspc,
        !          1055:                       ind-1,codim(ind-1),k2,n,lag,false);
        !          1056:               else Q_Bottom_Create1(root,nd,fstbot,botspc,k2,lag);
        !          1057:              end if;
        !          1058:         elsif ((k1 > 0) and (k2 = 0))
        !          1059:             then if ind > codim'first
        !          1060:                   then Q_Recursive_Top_Bottom_Create
        !          1061:                          (root,nd,codim,fsttop,topspc,true,botspc,
        !          1062:                           ind-1,k1,codim(ind-1),n,lag,false);
        !          1063:                   else Q_Top_Create1(root,nd,fsttop,topspc,k1,n,lag);
        !          1064:                  end if;
        !          1065:             else -- k1 = 0 and k2 = 0
        !          1066:                  if ind > codim'first + 1
        !          1067:                   then newhyper
        !          1068:                          := ((codim(ind-2) = 1) and (codim(ind-1) = 1));
        !          1069:                        Q_Recursive_Top_Bottom_Create
        !          1070:                          (root,nd,codim,true,topspc,true,botspc,
        !          1071:                           ind-2,codim(ind-2),codim(ind-1),n,lag,newhyper);
        !          1072:                  elsif ind > codim'first
        !          1073:                      then Q_Bottom_Create1
        !          1074:                             (root,nd,true,botspc,codim(ind-1),lag);
        !          1075:                 end if;
        !          1076:       end if;
        !          1077:     end if;
        !          1078:   end Q_Recursive_Top_Bottom_Create;
        !          1079:
        !          1080: -- TARGET CREATORS :
        !          1081:
        !          1082:   function Trivial_Root ( m,p : natural ) return Node is
        !          1083:
        !          1084:     nd : Node(p);
        !          1085:
        !          1086:   begin
        !          1087:     nd.level := m*p;
        !          1088:     nd.roco := 0;
        !          1089:     for i in 1..p loop
        !          1090:       nd.top(i) := i;
        !          1091:       nd.bottom(i) := m+i;
        !          1092:     end loop;
        !          1093:     return nd;
        !          1094:   end Trivial_Root;
        !          1095:
        !          1096:   function Trivial_Root ( m,p,q : natural ) return Node is
        !          1097:
        !          1098:     nd : Node(p);
        !          1099:     last : natural;
        !          1100:
        !          1101:   begin
        !          1102:     if q = 0
        !          1103:      then nd := Trivial_Root(m,p);
        !          1104:      else nd := Trivial_Root(m,p,q-1);
        !          1105:           nd.level := nd.level + m+p;
        !          1106:           last := nd.bottom(1)+m+p;
        !          1107:           for i in 1..(p-1) loop
        !          1108:             nd.bottom(i) := nd.bottom(i+1);
        !          1109:           end loop;
        !          1110:           nd.bottom(p) := last;
        !          1111:     end if;
        !          1112:     return nd;
        !          1113:   end Trivial_Root;
        !          1114:
        !          1115:   procedure Top_Create ( root : in out Link_to_Node; n : in natural ) is
        !          1116:
        !          1117:     procedure Create_Next ( root,nd : in out Link_to_Node ) is
        !          1118:     begin
        !          1119:       if ((nd.level > 0) and (nd.roco >= 0))
        !          1120:        then Top_Create1(root,nd,n);
        !          1121:             for i in nd.children'range(1) loop
        !          1122:               if nd.children(i,0) /= null
        !          1123:                then Create_Next(root,nd.children(i,0));
        !          1124:               end if;
        !          1125:             end loop;
        !          1126:             nd.roco := -1;
        !          1127:       end if;
        !          1128:     end Create_Next;
        !          1129:
        !          1130:   begin
        !          1131:     Create_Next(root,root);
        !          1132:   end Top_Create;
        !          1133:
        !          1134:   procedure Q_Top_Create ( root : in out Link_to_Node; n,lag : in natural ) is
        !          1135:
        !          1136:     procedure Create_Next ( root,nd : in out Link_to_Node ) is
        !          1137:     begin
        !          1138:       if ((nd.level > 0) and (nd.roco >= 0))
        !          1139:        then Q_Top_Create1(root,nd,n,lag);
        !          1140:             for i in nd.children'range(1) loop
        !          1141:               if nd.children(i,0) /= null
        !          1142:                then Create_Next(root,nd.children(i,0));
        !          1143:               end if;
        !          1144:             end loop;
        !          1145:             nd.roco := -1;
        !          1146:       end if;
        !          1147:     end Create_Next;
        !          1148:
        !          1149:   begin
        !          1150:     Create_Next(root,root);
        !          1151:   end Q_Top_Create;
        !          1152:
        !          1153:   procedure Top_Create ( root : in out Link_to_Node;
        !          1154:                          k : in Bracket; n : in natural ) is
        !          1155:
        !          1156:     procedure Create ( current : in out Link_to_Node; ind : in natural );
        !          1157:
        !          1158:     -- DESCRIPTION :
        !          1159:     --   Creates k(ind) levels above the current node.
        !          1160:
        !          1161:     procedure Create_Children ( child : in out Link_to_Node;
        !          1162:                                 cnt,ind : in natural ) is
        !          1163:
        !          1164:     -- DESCRIPTION :
        !          1165:     --   Goes to the topmost child to create, counting down with cnt.
        !          1166:
        !          1167:     begin
        !          1168:       if cnt = 0
        !          1169:        then Create(child,ind);
        !          1170:        else for i in child.children'range(1) loop
        !          1171:               if child.children(i,0) /= null
        !          1172:                then Create_Children(child.children(i,0),cnt-1,ind);
        !          1173:               end if;
        !          1174:             end loop;
        !          1175:       end if;
        !          1176:     end Create_Children;
        !          1177:
        !          1178:     procedure Create ( current : in out Link_to_Node; ind : in natural ) is
        !          1179:     begin
        !          1180:       if ((current.level > 0) and (ind <= k'last) and (current.roco >= 0))
        !          1181:        then
        !          1182:          Top_Create1(root,current,k(ind),n,1);
        !          1183:          if ind > k'first
        !          1184:           then
        !          1185:             for i in current.children'range(1) loop
        !          1186:               if current.children(i,0) /= null
        !          1187:                then Create_Children(current.children(i,0),k(ind)-1,ind-1);
        !          1188:               end if;
        !          1189:             end loop;
        !          1190:          end if;
        !          1191:          current.roco := -1;
        !          1192:       end if;
        !          1193:     end Create;
        !          1194:
        !          1195:   begin
        !          1196:     Create(root,k'last);
        !          1197:   end Top_Create;
        !          1198:
        !          1199:   procedure Q_Top_Create ( root : in out Link_to_Node;
        !          1200:                            k : in Bracket; n,lag : in natural ) is
        !          1201:
        !          1202:     procedure Create ( current : in out Link_to_Node; ind : in natural );
        !          1203:
        !          1204:     -- DESCRIPTION :
        !          1205:     --   Creates k(ind) levels above the current node.
        !          1206:
        !          1207:     procedure Create_Children ( child : in out Link_to_Node;
        !          1208:                                 cnt,ind : in natural ) is
        !          1209:
        !          1210:     -- DESCRIPTION :
        !          1211:     --   Goes to the topmost child to create, counting down with cnt.
        !          1212:
        !          1213:     begin
        !          1214:       if cnt = 0
        !          1215:        then Create(child,ind);
        !          1216:        else for i in child.children'range(1) loop
        !          1217:               if child.children(i,0) /= null
        !          1218:                then Create_Children(child.children(i,0),cnt-1,ind);
        !          1219:               end if;
        !          1220:             end loop;
        !          1221:       end if;
        !          1222:     end Create_Children;
        !          1223:
        !          1224:     procedure Create ( current : in out Link_to_Node; ind : in natural ) is
        !          1225:
        !          1226:       space : Bracket(1..lag-current.p) := (1..lag-current.p => 0);
        !          1227:
        !          1228:     begin
        !          1229:       if ((current.level > 0) and (ind <= k'last) and (current.roco >= 0))
        !          1230:        then
        !          1231:          Q_Top_Create1(root,current,true,space,k(ind),n,lag);
        !          1232:          if ind > k'first
        !          1233:           then
        !          1234:             for i in current.children'range(1) loop
        !          1235:               if current.children(i,0) /= null
        !          1236:                then Create_Children(current.children(i,0),k(ind)-1,ind-1);
        !          1237:               end if;
        !          1238:             end loop;
        !          1239:          end if;
        !          1240:          current.roco := -1;
        !          1241:       end if;
        !          1242:     end Create;
        !          1243:
        !          1244:   begin
        !          1245:     Create(root,k'last);
        !          1246:   end Q_Top_Create;
        !          1247:
        !          1248:   procedure Bottom_Create ( root : in out Link_to_Node ) is
        !          1249:
        !          1250:     procedure Create_Next ( root,nd : in out Link_to_Node ) is
        !          1251:     begin
        !          1252:       if ((nd.level > 0) and (nd.roco >= 0))
        !          1253:        then Bottom_Create1(root,nd);
        !          1254:             for i in nd.children'range(2) loop
        !          1255:               if nd.children(0,i) /= null
        !          1256:                then Create_Next(root,nd.children(0,i));
        !          1257:               end if;
        !          1258:             end loop;
        !          1259:             nd.roco := -1;
        !          1260:       end if;
        !          1261:     end Create_Next;
        !          1262:
        !          1263:   begin
        !          1264:     Create_Next(root,root);
        !          1265:   end Bottom_Create;
        !          1266:
        !          1267:   procedure Q_Bottom_Create ( root : in out Link_to_Node; lag : in natural ) is
        !          1268:
        !          1269:     procedure Create_Next ( root,nd : in out Link_to_Node ) is
        !          1270:     begin
        !          1271:       if ((nd.level > 0) and (nd.roco >= 0))
        !          1272:        then Q_Bottom_Create1(root,nd,lag);
        !          1273:             for i in nd.children'range(2) loop
        !          1274:               if nd.children(0,i) /= null
        !          1275:                then Create_Next(root,nd.children(0,i));
        !          1276:               end if;
        !          1277:             end loop;
        !          1278:             nd.roco := -1;
        !          1279:       end if;
        !          1280:     end Create_Next;
        !          1281:
        !          1282:   begin
        !          1283:     Create_Next(root,root);
        !          1284:   end Q_Bottom_Create;
        !          1285:
        !          1286:   procedure Bottom_Create ( root : in out Link_to_Node; k : in Bracket ) is
        !          1287:
        !          1288:     procedure Create ( current : in out Link_to_Node; ind : in natural );
        !          1289:
        !          1290:     -- DESCRIPTION :
        !          1291:     --   Creates k(ind) levels above the current node.
        !          1292:
        !          1293:     procedure Create_Children ( child : in out Link_to_Node;
        !          1294:                                 cnt,ind : in natural ) is
        !          1295:
        !          1296:     -- DESCRIPTION :
        !          1297:     --   Goes to the topmost child to create, counting down with cnt.
        !          1298:
        !          1299:     begin
        !          1300:       if cnt = 0
        !          1301:        then Create(child,ind);
        !          1302:        else for i in child.children'range(1) loop
        !          1303:               if child.children(0,i) /= null
        !          1304:                then Create_Children(child.children(0,i),cnt-1,ind);
        !          1305:               end if;
        !          1306:             end loop;
        !          1307:       end if;
        !          1308:     end Create_Children;
        !          1309:
        !          1310:     procedure Create ( current : in out Link_to_Node; ind : in natural ) is
        !          1311:     begin
        !          1312:       if ((current.level > 0) and (ind <= k'last) and (current.roco >= 0))
        !          1313:        then
        !          1314:          Bottom_Create1(root,current,k(ind),current.p);
        !          1315:          if ind > k'first
        !          1316:           then
        !          1317:             for i in current.children'range(1) loop
        !          1318:               if current.children(0,i) /= null
        !          1319:                then Create_Children(current.children(0,i),k(ind)-1,ind-1);
        !          1320:               end if;
        !          1321:             end loop;
        !          1322:          end if;
        !          1323:          current.roco := -1;
        !          1324:       end if;
        !          1325:     end Create;
        !          1326:
        !          1327:   begin
        !          1328:     Create(root,k'last);
        !          1329:   end Bottom_Create;
        !          1330:
        !          1331:   procedure Q_Bottom_Create ( root : in out Link_to_Node; k : in Bracket;
        !          1332:                               lag : in natural ) is
        !          1333:
        !          1334:     procedure Create ( current : in out Link_to_Node; ind : in natural );
        !          1335:
        !          1336:     -- DESCRIPTION :
        !          1337:     --   Creates k(ind) levels above the current node.
        !          1338:
        !          1339:     procedure Create_Children ( child : in out Link_to_Node;
        !          1340:                                 cnt,ind : in natural ) is
        !          1341:
        !          1342:     -- DESCRIPTION :
        !          1343:     --   Goes to the topmost child to create, counting down with cnt.
        !          1344:
        !          1345:     begin
        !          1346:       if cnt = 0
        !          1347:        then Create(child,ind);
        !          1348:        else for i in child.children'range(1) loop
        !          1349:               if child.children(0,i) /= null
        !          1350:                then Create_Children(child.children(0,i),cnt-1,ind);
        !          1351:               end if;
        !          1352:             end loop;
        !          1353:       end if;
        !          1354:     end Create_Children;
        !          1355:
        !          1356:     procedure Create ( current : in out Link_to_Node; ind : in natural ) is
        !          1357:
        !          1358:       space : Bracket(1..lag-current.p) := (1..lag-current.p => 0);
        !          1359:
        !          1360:     begin
        !          1361:       if ((current.level > 0) and (ind <= k'last) and (current.roco >= 0))
        !          1362:        then
        !          1363:          Q_Bottom_Create1(root,current,true,space,k(ind),lag);
        !          1364:          if ind > k'first
        !          1365:           then
        !          1366:             for i in current.children'range(1) loop
        !          1367:               if current.children(0,i) /= null
        !          1368:                then Create_Children(current.children(0,i),k(ind)-1,ind-1);
        !          1369:               end if;
        !          1370:             end loop;
        !          1371:          end if;
        !          1372:          current.roco := -1;
        !          1373:       end if;
        !          1374:     end Create;
        !          1375:
        !          1376:   begin
        !          1377:     Create(root,k'last);
        !          1378:   end Q_Bottom_Create;
        !          1379:
        !          1380:   procedure Top_Bottom_Create ( root : in out Link_to_Node; n : in natural ) is
        !          1381:
        !          1382:     procedure Create_Next ( root,nd : in out Link_to_Node ) is
        !          1383:     begin
        !          1384:       if ((nd.level > 0) and (nd.roco >= 0))
        !          1385:        then Top_Bottom_Create1(root,nd,n);
        !          1386:             for i in nd.children'range(1) loop
        !          1387:               for j in nd.children'range(2) loop
        !          1388:                 if nd.children(i,j) /= null
        !          1389:                  then Create_Next(root,nd.children(i,j));
        !          1390:                 end if;
        !          1391:               end loop;
        !          1392:             end loop;
        !          1393:             nd.roco := -1;
        !          1394:       end if;
        !          1395:     end Create_Next;
        !          1396:
        !          1397:   begin
        !          1398:     Create_Next(root,root);
        !          1399:   end Top_Bottom_Create;
        !          1400:
        !          1401:   procedure Q_Top_Bottom_Create ( root : in out Link_to_Node;
        !          1402:                                   n,lag : in natural ) is
        !          1403:
        !          1404:     procedure Create_Next ( root,nd : in out Link_to_Node ) is
        !          1405:     begin
        !          1406:       if ((nd.level > 0) and (nd.roco >= 0))
        !          1407:        then Q_Top_Bottom_Create1(root,nd,n,lag);
        !          1408:             for i in nd.children'range(1) loop
        !          1409:               for j in nd.children'range(2) loop
        !          1410:                 if nd.children(i,j) /= null
        !          1411:                  then Create_Next(root,nd.children(i,j));
        !          1412:                 end if;
        !          1413:               end loop;
        !          1414:             end loop;
        !          1415:             nd.roco := -1;
        !          1416:       end if;
        !          1417:     end Create_Next;
        !          1418:
        !          1419:   begin
        !          1420:     Create_Next(root,root);
        !          1421:   end Q_Top_Bottom_Create;
        !          1422:
        !          1423:   procedure Old_Top_Bottom_Create ( root : in out Link_to_Node;
        !          1424:                                     k : in Bracket; n : in natural ) is
        !          1425:
        !          1426:   -- NOTE :
        !          1427:   --   This top-bottom create treats the co-dimension conditions in pairs,
        !          1428:   --   which allows more possibilities for sharing.
        !          1429:
        !          1430:     procedure Create ( current : in out Link_to_Node; ind : in natural );
        !          1431:
        !          1432:     -- DESCRIPTION :
        !          1433:     --   Creates k(ind) levels above the current node.
        !          1434:
        !          1435:     procedure Create_Children ( child : in out Link_to_Node;
        !          1436:                                 cnt,ind : in natural ) is
        !          1437:
        !          1438:     -- DESCRIPTION :
        !          1439:     --   Goes to the topmost child to create, counting down with cnt.
        !          1440:
        !          1441:     begin
        !          1442:       if cnt = 0
        !          1443:        then Create(child,ind);
        !          1444:        else for i in child.children'range(1) loop
        !          1445:               for j in child.children'range(2) loop
        !          1446:                 if child.children(i,j) /= null
        !          1447:                  then Create_Children(child.children(i,j),cnt-1,ind);
        !          1448:                 end if;
        !          1449:               end loop;
        !          1450:             end loop;
        !          1451:       end if;
        !          1452:     end Create_Children;
        !          1453:
        !          1454:     procedure Create ( current : in out Link_to_Node; ind : in natural ) is
        !          1455:
        !          1456:       cnt : natural;
        !          1457:
        !          1458:     begin
        !          1459:       if ((current.level > 0) and (current.roco >= 0))
        !          1460:        then
        !          1461:          if ind = k'first
        !          1462:           then Bottom_Create1(root,current,k(ind),current.p);
        !          1463:                cnt := k(ind);
        !          1464:           elsif ind > k'first
        !          1465:               then
        !          1466:                 Top_Bottom_Create1(root,current,k(ind),k(ind-1),n,1,current.p);
        !          1467:                 cnt := max(k(ind),k(ind-1));
        !          1468:          end if;
        !          1469:          if ind > k'first-1
        !          1470:           then for i in current.children'range(1) loop
        !          1471:                  for j in current.children'range(2) loop
        !          1472:                    if current.children(i,j) /= null
        !          1473:                     then Create_Children(current.children(i,j),cnt-1,ind-2);
        !          1474:                    end if;
        !          1475:                 end loop;
        !          1476:               end loop;
        !          1477:          end if;
        !          1478:          current.roco := -1;
        !          1479:       end if;
        !          1480:     end Create;
        !          1481:
        !          1482:   begin
        !          1483:     Create(root,k'last);
        !          1484:   end Old_Top_Bottom_Create;
        !          1485:
        !          1486:   procedure Top_Bottom_Create ( root : in out Link_to_Node;
        !          1487:                                 k : in Bracket; n : in natural ) is
        !          1488:
        !          1489:     ind : constant natural := k'last;
        !          1490:     hyper : boolean;
        !          1491:
        !          1492:   begin
        !          1493:     if ind = k'first
        !          1494:      then Bottom_Create1(root,root,k(k'last),root.p);
        !          1495:      elsif ind > k'first
        !          1496:          then hyper := ((k(ind-1) = 1) and (k(ind) = 1));
        !          1497:               Recursive_Top_Bottom_Create
        !          1498:                 (root,root,k,ind-1,k(ind-1),k(ind),n,1,root.p,hyper);
        !          1499:     end if;
        !          1500:   end Top_Bottom_Create;
        !          1501:
        !          1502:   procedure Q_Top_Bottom_Create ( root : in out Link_to_Node;
        !          1503:                                   k : in Bracket; n,lag : in natural ) is
        !          1504:
        !          1505:     ind : constant natural := k'last;
        !          1506:     hyper : boolean;
        !          1507:     space : Bracket(1..lag-root.p) := (1..lag-root.p => 0);
        !          1508:
        !          1509:   begin
        !          1510:     if ind = k'first
        !          1511:      then Q_Bottom_Create1(root,root,true,space,k(k'last),lag);
        !          1512:      elsif ind > k'first
        !          1513:          then hyper := ((k(ind-1) = 1) and (k(ind) = 1));
        !          1514:               Q_Recursive_Top_Bottom_Create
        !          1515:                 (root,root,k,true,space,true,space,
        !          1516:                  ind-1,k(ind-1),k(ind),n,lag,hyper);
        !          1517:     end if;
        !          1518:   end Q_Top_Bottom_Create;
        !          1519:
        !          1520:   function Create_Leveled_Poset ( root : Link_to_Node )
        !          1521:                                 return Array_of_Nodes is
        !          1522:
        !          1523:     res : Array_of_Nodes(0..root.level);
        !          1524:
        !          1525:   begin
        !          1526:     for i in res'range loop
        !          1527:       res(i) := Find_Node(root,i);
        !          1528:     end loop;
        !          1529:     return res;
        !          1530:   end Create_Leveled_Poset;
        !          1531:
        !          1532:   function Create_Indexed_Poset ( poset : Array_of_Nodes )
        !          1533:                                 return Array_of_Array_of_Nodes is
        !          1534:
        !          1535:     res : Array_of_Array_of_Nodes(poset'range);
        !          1536:     ptr : Link_to_Node;
        !          1537:
        !          1538:   begin
        !          1539:     for i in poset'range loop
        !          1540:       if poset(i) /= null
        !          1541:        then res(i) := new Array_of_Nodes(1..Number_of_Siblings(poset(i)));
        !          1542:             ptr := poset(i);
        !          1543:             for j in res(i)'range loop
        !          1544:                res(i)(j) := ptr;
        !          1545:                res(i)(j).label := j;
        !          1546:                res(i)(j).child_labels := Labels_of_Children(res,ptr.all);
        !          1547:                ptr := ptr.next_sibling;
        !          1548:             end loop;
        !          1549:       end if;
        !          1550:     end loop;
        !          1551:     return res;
        !          1552:   end Create_Indexed_Poset;
        !          1553:
        !          1554: -- SELECTORS :
        !          1555:
        !          1556:   function Equal ( nd1,nd2 : Node ) return boolean is
        !          1557:   begin
        !          1558:     if nd1.level /= nd2.level
        !          1559:      then return false;
        !          1560:      elsif not Equal(nd1.top,nd2.top)
        !          1561:          then return false;
        !          1562:          else return Equal(nd1.bottom,nd2.bottom);
        !          1563:     end if;
        !          1564:   end Equal;
        !          1565:
        !          1566:   function Is_Leaf ( nd : Node ) return boolean is
        !          1567:   begin
        !          1568:     for i in nd.children'range(1) loop
        !          1569:       for j in nd.children'range(2) loop
        !          1570:         if nd.children(i,j) /= null
        !          1571:          then return false;
        !          1572:         end if;
        !          1573:       end loop;
        !          1574:     end loop;
        !          1575:     return true;
        !          1576:   end Is_Leaf;
        !          1577:
        !          1578:   function Find_Node ( root : Link_to_Node; lvl : natural )
        !          1579:                      return Link_to_Node is
        !          1580:
        !          1581:     res,fst : Link_to_Node := null;
        !          1582:
        !          1583:     procedure Search_First ( current : in Link_to_Node ) is
        !          1584:
        !          1585:     -- DESCRIPTION :
        !          1586:     --   Scans the list of previous siblings and sets fst to the node
        !          1587:     --   that does not have any previous siblings.
        !          1588:
        !          1589:     -- REQUIRED : current /= null.
        !          1590:
        !          1591:     begin
        !          1592:       if current.prev_sibling = null
        !          1593:        then fst := current;
        !          1594:        else Search_First(current.prev_sibling);
        !          1595:       end if;
        !          1596:     end Search_First;
        !          1597:
        !          1598:   begin
        !          1599:     if root.level = lvl
        !          1600:      then res := root;
        !          1601:      elsif root.level > lvl
        !          1602:          then for i in root.children'range(1) loop
        !          1603:                 for j in root.children'range(2) loop
        !          1604:                   if root.children(i,j) /= null
        !          1605:                    then res := Find_Node(root.children(i,j),lvl);
        !          1606:                   end if;
        !          1607:                   exit when (res /= null);
        !          1608:                 end loop;
        !          1609:                 exit when (res /= null);
        !          1610:               end loop;
        !          1611:     end if;
        !          1612:     if res = null
        !          1613:      then fst := res;
        !          1614:      else Search_First(res);
        !          1615:     end if;
        !          1616:     return fst;
        !          1617:   end Find_Node;
        !          1618:
        !          1619:   function Number_of_Siblings ( nd : Link_to_Node ) return natural is
        !          1620:   begin
        !          1621:     if nd = null
        !          1622:      then return 0;
        !          1623:      else return 1 + Number_of_Siblings(nd.next_sibling);
        !          1624:     end if;
        !          1625:   end Number_of_Siblings;
        !          1626:
        !          1627:   function Number_of_Children ( nd : Node ) return natural is
        !          1628:
        !          1629:     cnt : natural := 0;
        !          1630:
        !          1631:   begin
        !          1632:     for i in nd.children'range(1) loop
        !          1633:       for j in nd.children'range(2) loop
        !          1634:         if nd.children(i,j) /= null
        !          1635:          then cnt := cnt + 1;
        !          1636:         end if;
        !          1637:       end loop;
        !          1638:     end loop;
        !          1639:     return cnt;
        !          1640:   end Number_of_Children;
        !          1641:
        !          1642: -- ITERATORS :
        !          1643:
        !          1644:   procedure Enumerate_Siblings ( nd : in Node ) is
        !          1645:
        !          1646:     cont : boolean := true;
        !          1647:
        !          1648:   begin
        !          1649:     Report(nd,cont);
        !          1650:     if cont and nd.next_sibling /= null
        !          1651:      then Enumerate_Siblings(nd.next_sibling.all);
        !          1652:     end if;
        !          1653:   end Enumerate_Siblings;
        !          1654:
        !          1655:   procedure Enumerate_Grand_Children ( nd : in Node; k : in positive ) is
        !          1656:
        !          1657:     cont : boolean := true;
        !          1658:
        !          1659:     procedure Enumerate_Children ( current : in node; l : in positive ) is
        !          1660:     begin
        !          1661:       for i in current.children'range(1) loop
        !          1662:         for j in current.children'range(1) loop
        !          1663:           if current.children(i,j) /= null
        !          1664:            then if l = 1
        !          1665:                  then Report(current.children(i,j),cont);
        !          1666:                  else Enumerate_Children(current.children(i,j).all,l-1);
        !          1667:                 end if;
        !          1668:           end if;
        !          1669:           exit when not cont;
        !          1670:         end loop;
        !          1671:         exit when not cont;
        !          1672:       end loop;
        !          1673:     end Enumerate_Children;
        !          1674:
        !          1675:   begin
        !          1676:     Enumerate_Children(nd,k);
        !          1677:   end Enumerate_Grand_Children;
        !          1678:
        !          1679:   procedure Modify_Siblings ( nd : in out Node ) is
        !          1680:
        !          1681:     cont : boolean := true;
        !          1682:
        !          1683:   begin
        !          1684:     Modify(nd,cont);
        !          1685:     if cont and nd.next_sibling /= null
        !          1686:      then Modify_Siblings(nd.next_sibling.all);
        !          1687:     end if;
        !          1688:   end Modify_Siblings;
        !          1689:
        !          1690: -- COMBINATORIAL ROOT COUNTING :
        !          1691:
        !          1692:   procedure Count_Roots ( poset : in out Array_of_Nodes ) is
        !          1693:
        !          1694:     procedure Initialize ( nd : in out Node; continue : out boolean ) is
        !          1695:     begin
        !          1696:       nd.roco := 1;
        !          1697:       continue := true;
        !          1698:     end Initialize;
        !          1699:     procedure Initialize_Leaves is new Modify_Siblings(Initialize);
        !          1700:
        !          1701:     procedure Add_Children ( nd : in out Node; continue : out boolean ) is
        !          1702:     begin
        !          1703:       nd.roco := 0;
        !          1704:       for i in nd.children'range(1) loop
        !          1705:         for j in nd.children'range(2) loop
        !          1706:           if nd.children(i,j) /= null
        !          1707:            then nd.roco := nd.roco + nd.children(i,j).roco;
        !          1708:           end if;
        !          1709:         end loop;
        !          1710:       end loop;
        !          1711:       continue := true;
        !          1712:     end Add_Children;
        !          1713:     procedure Add_Children_Counts is new Modify_Siblings(Add_Children);
        !          1714:
        !          1715:   begin
        !          1716:     if poset(0) /= null
        !          1717:      then Initialize_Leaves(poset(0).all);
        !          1718:     end if;
        !          1719:     for i in 1..poset'last loop
        !          1720:       if poset(i) /= null
        !          1721:        then Add_Children_Counts(poset(i).all);
        !          1722:       end if;
        !          1723:     end loop;
        !          1724:   end Count_Roots;
        !          1725:
        !          1726:   function Row_Root_Count_Sum
        !          1727:              ( poset : Array_of_Nodes; i : natural ) return natural is
        !          1728:
        !          1729:     res : natural := 0;
        !          1730:
        !          1731:     procedure Count ( lnd : in Link_to_Node ) is
        !          1732:     begin
        !          1733:       if lnd /= null
        !          1734:        then res := res + lnd.roco;
        !          1735:             Count(lnd.next_sibling);
        !          1736:       end if;
        !          1737:     end Count;
        !          1738:
        !          1739:   begin
        !          1740:     Count(poset(i));
        !          1741:     return res;
        !          1742:   end Row_Root_Count_Sum;
        !          1743:
        !          1744:   function Root_Count_Sum ( poset : Array_of_Nodes ) return natural is
        !          1745:
        !          1746:     res : natural := 0;
        !          1747:
        !          1748:   begin
        !          1749:     for i in 1..poset'last loop
        !          1750:       res := res + Row_Root_Count_Sum(poset,i);
        !          1751:     end loop;
        !          1752:     return res;
        !          1753:   end Root_Count_Sum;
        !          1754:
        !          1755: -- DESTRUCTORS :
        !          1756:
        !          1757:   procedure free is new unchecked_deallocation(Node,Link_to_Node);
        !          1758:   procedure free is
        !          1759:     new unchecked_deallocation(Array_of_Nodes,Link_to_Array_of_Nodes);
        !          1760:
        !          1761:   procedure Clear ( nd : in out Node ) is
        !          1762:   begin
        !          1763:     if nd.next_sibling /= null
        !          1764:      then Clear(nd.next_sibling);
        !          1765:     end if;
        !          1766:   end Clear;
        !          1767:
        !          1768:   procedure Clear ( lnd : in out Link_to_Node ) is
        !          1769:   begin
        !          1770:     if lnd /= null
        !          1771:      then Clear(lnd.all);
        !          1772:           free(lnd);
        !          1773:     end if;
        !          1774:   end Clear;
        !          1775:
        !          1776:   procedure Clear ( arrnd : in out Array_of_Nodes ) is
        !          1777:   begin
        !          1778:     for i in arrnd'range loop
        !          1779:       Clear(arrnd(i));
        !          1780:     end loop;
        !          1781:   end Clear;
        !          1782:
        !          1783:   procedure Clear ( arrnd : in out Link_to_Array_of_Nodes ) is
        !          1784:
        !          1785:     procedure free is
        !          1786:       new unchecked_deallocation(Array_of_Nodes,Link_to_Array_of_Nodes);
        !          1787:
        !          1788:   begin
        !          1789:     if arrnd /= null
        !          1790:      then Clear(arrnd.all);
        !          1791:           free(arrnd);
        !          1792:     end if;
        !          1793:   end Clear;
        !          1794:
        !          1795:   procedure Clear ( arrnd : in out Array_of_Array_of_Nodes ) is
        !          1796:   begin
        !          1797:     for i in arrnd'range loop
        !          1798:       Clear(arrnd(i));
        !          1799:     end loop;
        !          1800:   end Clear;
        !          1801:
        !          1802:   procedure Clear ( matnd : in out Matrix_of_Nodes ) is
        !          1803:   begin
        !          1804:     for i in matnd'range(1) loop
        !          1805:       for j in matnd'range(2) loop
        !          1806:         if matnd(i,j) /= null
        !          1807:          then free(matnd(i,j));
        !          1808:         end if;
        !          1809:       end loop;
        !          1810:     end loop;
        !          1811:   end Clear;
        !          1812:
        !          1813: end Localization_Posets;

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