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