Annotation of OpenXM_contrib/PHC/Ada/Schubert/pieri_root_counts.adb, Revision 1.1.1.1
1.1 maekawa 1: with unchecked_deallocation;
2: with integer_io; use integer_io;
3: with Brackets; use Brackets;
4: with Brackets_io; use Brackets_io;
5: with Pieri_Trees_io; use Pieri_Trees_io;
6:
7: package body Pieri_Root_Counts is
8:
9: procedure free is new unchecked_deallocation(Nodal_Pair,Link_to_Nodal_Pair);
10:
11: type Boolean_Array is array ( integer range <> ) of boolean;
12:
13: function Create ( n,d : natural; t1,t2 : Pieri_Tree )
14: return List_of_Paired_Nodes is
15:
16: res,res_last : List_of_Paired_Nodes;
17: h1 : constant natural := Height(t1);
18: h2 : constant natural := Height(t2);
19: b1,b2 : Bracket(1..d);
20: firstlnd : Link_to_Pieri_Node;
21: cnt : natural := 0;
22:
23: procedure Check_Pair ( lnd : in Link_to_Pieri_Node;
24: continue : out boolean ) is
25: begin
26: b2 := lnd.node;
27: if Pieri_Condition(n,b1,b2)
28: then declare
29: lpnd : Paired_Nodes;
30: begin
31: lpnd.left := firstlnd;
32: lpnd.right := lnd;
33: Append(res,res_last,lpnd);
34: end ;
35: end if;
36: continue := true;
37: end Check_Pair;
38: procedure Check_Pairs is new Enumerate_Nodes(Check_Pair);
39:
40: procedure Count_First ( lnd : in Link_to_Pieri_Node;
41: continue : out boolean ) is
42: begin
43: b1 := lnd.node;
44: firstlnd := lnd;
45: Check_Pairs(t2,h2);
46: continue := true;
47: end Count_First;
48: procedure First_Leaves is new Enumerate_Nodes(Count_First);
49:
50: begin
51: First_Leaves(t1,h1);
52: return res;
53: end Create;
54:
55: function Create ( pnd : Paired_Nodes ) return Paired_Chain is
56:
57: res : Paired_Chain(1..Height(pnd));
58: ind : natural := res'last;
59:
60: begin
61: res(ind) := pnd;
62: while not At_First_Branch_Point(res(ind)) loop -- fill in
63: ind := ind - 1;
64: res(ind) := Ancestor(res(ind+1));
65: end loop;
66: if ind = 1
67: then return res;
68: else for i in 1..res'last-ind+1 loop -- shift down
69: res(i) := res(i+ind-1);
70: end loop;
71: return res(1..res'last-ind+1);
72: end if;
73: end Create;
74:
75: procedure Connect ( ancnp,np : in out Link_to_Nodal_Pair ) is
76:
77: -- DESCRIPTION :
78: -- Connects the ancestor paired nodes with the paired nodes np.
79:
80: ancpnd : Paired_Nodes := Ancestor(np.pnd);
81: j1 : constant natural := Jump(ancpnd.left.node,np.pnd.left.node);
82: j2 : constant natural := Jump(ancpnd.right.node,np.pnd.right.node);
83:
84: begin
85: ancnp.pnd := ancpnd;
86: ancnp.children(j1,j2) := np;
87: np.ancestor := ancnp;
88: end Connect;
89:
90: procedure Initial_Branch ( root,np : in out Link_to_Nodal_Pair ) is
91:
92: -- DESCRIPTION :
93: -- Constructs the initial branch in the tree of paired nodes.
94:
95: begin
96: if At_First_Branch_Point(np.pnd)
97: then root := np;
98: else declare
99: acc : Link_to_Nodal_Pair := new Nodal_Pair(np.d);
100: begin
101: acc.sols := 1;
102: Connect(acc,np);
103: Initial_Branch(root,acc);
104: end;
105: end if;
106: end Initial_Branch;
107:
108: procedure Merge ( root : in Nodal_Pair;
109: current : in out Link_to_Nodal_Pair; k : in natural;
110: chain : in Paired_Chain ) is
111:
112: -- DESCRIPTION :
113: -- Merges the chain with the root of the tree, at level k.
114:
115: j1,j2 : natural;
116:
117: begin
118: j1 := Jump(chain(k).left.node,chain(k+1).left.node);
119: j2 := Jump(chain(k).right.node,chain(k+1).right.node);
120: if current.children(j1,j2) = null
121: then declare
122: newnp : Link_to_Nodal_Pair := new Nodal_Pair(current.d);
123: begin
124: newnp.pnd := chain(k+1);
125: if Is_In(root,newnp.pnd)
126: then newnp.sols := 0;
127: else newnp.sols := 1;
128: end if;
129: current.children(j1,j2) := newnp;
130: newnp.ancestor := current;
131: end;
132: else if current.children(j1,j2).sols > 0
133: then current.children(j1,j2).sols
134: := current.children(j1,j2).sols + 1;
135: end if;
136: end if;
137: if k+1 < chain'last
138: then Merge(root,current.children(j1,j2),k+1,chain);
139: end if;
140: end Merge;
141:
142: function Create ( d : natural; lp : List_of_Paired_Nodes )
143: return Nodal_Pair is
144:
145: root : Nodal_Pair(d);
146: lroot : Link_to_Nodal_Pair := new Nodal_Pair'(root);
147: first : Link_to_Nodal_Pair := new Nodal_Pair(d);
148: tmp : List_of_Paired_Nodes := Tail_Of(lp);
149:
150: begin
151: first.pnd := Head_Of(lp);
152: first.sols := 1;
153: lroot.sols := 1;
154: Initial_Branch(lroot,first);
155: while not Is_Null(tmp) loop
156: declare
157: pnd : Paired_Nodes := Head_Of(tmp);
158: chn : constant Paired_Chain := Create(pnd);
159: begin
160: lroot.sols := lroot.sols + 1;
161: Merge(lroot.all,lroot,1,chn);
162: end;
163: tmp := Tail_Of(tmp);
164: end loop;
165: return lroot.all;
166: end Create;
167:
168: -- SELECTORS :
169:
170: function Height ( pnd : Paired_Nodes ) return natural is
171: begin
172: if pnd.left.h >= pnd.right.h
173: then return pnd.left.h;
174: else return pnd.right.h;
175: end if;
176: end Height;
177:
178: function Equal ( pnd1,pnd2 : Paired_Nodes ) return boolean is
179: begin
180: return (Is_Equal(pnd1.left.node,pnd2.left.node)
181: and Is_Equal(pnd1.right.node,pnd2.right.node));
182: end Equal;
183:
184: function At_First_Branch_Point ( pnd : Paired_Nodes ) return boolean is
185: begin
186: if pnd.left.h /= pnd.right.h
187: then return false;
188: elsif ((pnd.left.c > 1) or (pnd.right.c > 1))
189: then return false;
190: else return (((pnd.left.i = 0) and (pnd.left.c = 1))
191: or else ((pnd.right.i = 0) and (pnd.right.c = 1)));
192: end if;
193: end At_First_Branch_Point;
194:
195: function At_Leaves ( pnd : Paired_Nodes ) return boolean is
196: begin
197: return (Is_Leaf(pnd.left.all) and Is_Leaf(pnd.right.all));
198: end At_Leaves;
199:
200: function Ancestor ( pnd : Paired_Nodes ) return Paired_Nodes is
201:
202: res : Paired_Nodes;
203:
204: begin
205: if pnd.left.h = pnd.right.h
206: then res.left := pnd.left.ancestor;
207: res.right := pnd.right.ancestor;
208: elsif pnd.left.h > pnd.right.h
209: then res.left := pnd.left.ancestor;
210: res.right := pnd.right;
211: else res.left := pnd.left;
212: res.right := pnd.right.ancestor;
213: end if;
214: return res;
215: end Ancestor;
216:
217: function First_Branch_Point ( pnd : Paired_Nodes ) return Paired_Nodes is
218: begin
219: if At_First_Branch_Point(pnd)
220: then return pnd;
221: else return First_Branch_Point(Ancestor(pnd));
222: end if;
223: end First_Branch_Point;
224:
225: function Height ( np : Nodal_Pair ) return natural is
226: begin
227: if np.pnd.left.h >= np.pnd.right.h
228: then return np.pnd.left.h;
229: else return np.pnd.right.h;
230: end if;
231: end Height;
232:
233: function Is_In ( root : Nodal_Pair; pnd : Paired_Nodes ) return boolean is
234: begin
235: if Equal(root.pnd,pnd)
236: then return true;
237: else for j1 in root.children'range(1) loop
238: for j2 in root.children'range(2) loop
239: if root.children(j1,j2) /= null
240: then if Is_In(root.children(j1,j2).all,pnd)
241: then return true;
242: end if;
243: end if;
244: end loop;
245: end loop;
246: end if;
247: return false;
248: end Is_In;
249:
250: function Number_of_Paths ( root : Nodal_Pair ) return natural is
251:
252: res : natural := root.sols;
253:
254: begin
255: for j1 in root.children'range(1) loop
256: for j2 in root.children'range(2) loop
257: if root.children(j1,j2) /= null
258: then if not At_Leaves(root.children(j1,j2).pnd)
259: then res := res + Number_of_Paths(root.children(j1,j2).all);
260: end if;
261: end if;
262: end loop;
263: end loop;
264: return res;
265: end Number_of_Paths;
266:
267: -- FORMATTED OUTPUT :
268:
269: procedure Write ( file : in file_type; chn : in Paired_Chain ) is
270: begin
271: for i in chn'first..(chn'last-1) loop
272: put(file,"("); put(file,chn(i).left.node);
273: put(file,","); put(file,chn(i).right.node); put(file,") < ");
274: end loop;
275: put(file,"("); put(file,chn(chn'last).left.node);
276: put(file,","); put(file,chn(chn'last).right.node); put_line(file,")");
277: end Write;
278:
279: function Last_Child ( np : Nodal_Pair; i,j : natural ) return boolean is
280:
281: -- DESCRIPTION :
282: -- Returns true if the (i,j)th child is the last child of the node.
283:
284: begin
285: for j1 in j+1..np.children'last(2) loop
286: if np.children(i,j1) /= null
287: then return false;
288: end if;
289: end loop;
290: for i1 in i+1..np.children'last(1) loop
291: for j1 in np.children'range(2) loop
292: if np.children(i1,j1) /= null
293: then return false;
294: end if;
295: end loop;
296: end loop;
297: return true;
298: end Last_Child;
299:
300: procedure Write_Labels ( file : in file_type; np : in Nodal_Pair;
301: j1,j2,h : in natural; last : in Boolean_Array ) is
302:
303: -- DESCRIPTION :
304: -- Writes the contents of the nodal pair with the jumps, taking into
305: -- account which children appeared last.
306: -- The current node is at height h in the nodal pair tree.
307:
308: first : Paired_Nodes := First_Branch_Point(np.pnd);
309:
310: begin
311: if h /= 0
312: then put(file," ");
313: end if;
314: for i in 1..h-1 loop
315: if last(i)
316: then put(file," ");
317: else put(file,"| ");
318: end if;
319: end loop;
320: if h /= 0
321: then put(file,"!-+(");
322: put(file,j1,1); put(file,","); put(file,j2,1);
323: put(file,")");
324: end if;
325: put(file,"("); put(file,np.pnd.left.node);
326: put(file,","); put(file,np.pnd.right.node);
327: put(file,") ");
328: put(file,np.sols,1);
329: new_line(file);
330: end Write_Labels;
331:
332: procedure Write_Nodes ( file : in file_type; np : in Nodal_Pair;
333: j1,j2,h : in natural; last : in out Boolean_Array ) is
334:
335: -- DESCRIPTION :
336: -- Writes the contents of the nodal pair, followed by the children.
337:
338: begin
339: Write_Labels(file,np,j1,j2,h,last);
340: for jj1 in np.children'range(1) loop
341: for jj2 in np.children'range(2) loop
342: if np.children(jj1,jj2) /= null
343: then last(h+1) := Last_Child(np,jj1,jj2);
344: Write_Nodes(file,np.children(jj1,jj2).all,jj1,jj2,h+1,last);
345: end if;
346: end loop;
347: end loop;
348: end Write_Nodes;
349:
350: procedure Write ( file : in file_type; root : in Nodal_Pair ) is
351:
352: last : Boolean_Array(1..Height(root)+1);
353:
354: begin
355: Write_Nodes(file,root,1,1,0,last);
356: end Write;
357:
358: end Pieri_Root_Counts;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>