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>