|
|
1.1 root 1: .\" Copyright (c) 1980 Regents of the University of California.
2: .\" All rights reserved. The Berkeley software License Agreement
3: .\" specifies the terms and conditions for redistribution.
4: .\"
5: .\" @(#)manCh5.rno 6.1 (Berkeley) 4/29/86
6: .\"
7: .NS 1 "Programming Examples"
8: .pp
9: We will start off by developing a larger FP program, \fImergeSort\fP.
10: We measure \fImergeSort\fP using the trace package, and then we
11: comment on the measurements.
12: Following \fImergeSort\fP
13: we show an actual session at the terminal.
14: .NS 2 "MergeSort"
15: .pp
16: The source code for
17: \fImergeSort\fP is:
18: .(b
19: .sp 4p
20: .hl
21: .sp 4p
22: .(c
23: # Use a divide and conquer strategy
24: .sp 3p
25: {mergeSort $^"\fB|\fP"^$ merge}
26: .sp 6p
27: {merge atEnd @ mergeHelp @ [[], fixLists]}
28: .sp 6p
29: # Must convert atomic arguments into sequences
30: # Atomic arguments occur at the leaves of the execution tree
31: .sp 3p
32: {fixLists &(atom -> [id] ; id)}
33: .sp 6p
34: # Merge until one or both input lists are empty
35: .sp 3p
36: {mergeHelp (while \kxand @ &(not@null) @ 2
37: \h'\nxu'(firstIsSmaller -> \kytakeFirst ;
38: \h'\nyu'takeSecond))}
39: .sp 6p
40: # Find the list with the smaller first element
41: .sp 3p
42: {firstIsSmaller < @ [1@1@2, 1@2@2]}
43: .sp 6p
44: # Take the first element of the first list
45: .sp 3p
46: {takeFirst [apndr@[1,1@1@2], [tl@1@2, 2@2]]}
47: .sp 6p
48: # Take the first element of the second list
49: .sp 3p
50: {takeSecond [apndr@[1,1@2@2], [1@2, tl@2@2]]}
51: .sp 6p
52: # If one list isn't null, then append it to the
53: # end of the merged list
54: .sp 3p
55: {atEnd (firstIsNull -> \kzconcat@[1,2@2] ;
56: \h'\nzu'concat@[1,1@2])}
57: .sp 6p
58: {firstIsNull null@1@2}
59: .)c
60: .sp 4p
61: .hl
62: .sp 4p
63: .)b
64: .pp
65: The merge sort algorithm uses a divide and conquer strategy;
66: it splits the input in half, recursively sorts each half,
67: and then merges the sorted lists.
68: Of course, all these sub-sorts can execute
69: in parallel, and the
70: tree-insert ($"\fB|\fP" $) functional form expresses this
71: concurrency. \fIMerge\fP removes successively larger elements
72: from the heads of the
73: two lists (either \fItakeFirst\fP or \fItakeSecond\fP)
74: and appends these elements to the end of the merged sequence.
75: \fIMerge\fP terminates when
76: one sequence is empty, and then
77: \fIatEnd\fP appends
78: any remaining non-empty sequence
79: to the end of the merged one.
80: .CH "Dynamic Statistics"
81: .pp
82: On the next page we
83: give the trace of the function \fImerge\fP, which information
84: we can use to determine the structure of
85: \fImerge\fP's execution tree.
86: Since the tree is well-balanced,
87: many of the \fImerge\fP's
88: could be executed in parallel.
89: Using this trace we
90: can also calculate
91: the average length of the
92: arguments passed to \fImerge\fP, or a distribution of argument lengths.
93: This information is useful for
94: determining communication costs.
95: .(b
96: .nf
97: .sp 4p
98: .nf
99: .hl
100: .sp 4p
101: .(c
102: )trace on merge
103:
104: mergeSort\ :\ <0\ 3\ -2\ 1\ 11\ 8\ -22\ -33>
105: |\ 3\ >Enter>\ merge\ [<0\ 3>]
106: |\ 3\ <EXIT<\ \ merge\ \ <0\ 3>
107: |\ 3\ >Enter>\ merge\ [<-2\ 1>]
108: |\ 3\ <EXIT<\ \ merge\ \ <-2\ 1>
109: |2\ >Enter>\ merge\ [<<0\ 3>\ <-2\ 1>>]
110: |2\ <EXIT<\ \ merge\ \ <-2\ 0\ 1\ 3>
111: |\ 3\ >Enter>\ merge\ [<11\ 8>]
112: |\ 3\ <EXIT<\ \ merge\ \ <8\ 11>
113: |\ 3\ >Enter>\ merge\ [<-22\ -33>]
114: |\ 3\ <EXIT<\ \ merge\ \ <-33\ -22>
115: |2\ >Enter>\ merge\ [<<8\ 11>\ <-33\ -22>>]
116: |2\ <EXIT<\ \ merge\ \ <-33\ -22\ 8\ 11>
117: 1\ >Enter>\ merge\ [<<-2\ 0\ 1\ 3>\ <-33\ -22\ 8\ 11>>]
118: 1\ <EXIT<\ \ merge\ \ <-33\ -22\ -2\ 0\ 1\ 3\ 8\ 11>
119:
120: <-33\ -22\ -2\ 0\ 1\ 3\ 8\ 11>
121: .)c
122: .sp 4p
123: .hl
124: .fi
125: .)b
126: .bp
127: .NS 2 "FP Session"
128: .pp
129: User input is
130: \fBemboldened\fP, terminal output in Roman script.
131: .sp 0.5i
132: .nf
133: \fBfp\fP
134:
135: FP, v. 4.1 11/31/82
136: \fB )load ex_man\fP
137: {all_le}
138: {sort}
139: {abs_val}
140: {find}
141: {ip}
142: {mm}
143: {eq0}
144: {fact}
145: {sub1}
146: {alt_fnd}
147: {alt_fact}
148: \fB )fns\fP
149:
150: .TS
151: l l l l l l l.
152: abs_val all_le alt_fact alt_fnd eq0 fact find
153: ip mm sort sub1 \& \& \&
154: .TE
155:
156: \fB abs_val : 3\fP
157:
158: 3
159:
160: \fB abs_val : -3\fP
161:
162: 3
163:
164: \fB abs_val : 0\fP
165:
166: 0
167:
168: \fB abs_val : <-5 0 66>\fP
169:
170: ?
171:
172: \fB &abs_val : <-5 0 66>\fP
173:
174: <5 0 66>
175:
176: \fB )pfn abs_val\fP
177:
178: {abs_val ((> @ [id,%0]) -> id ; (- @ [%0,id]))}
179:
180: \fB [id,%0] : -3\fP
181:
182: <-3 0>
183:
184: \fB [%0,id] : -3\fP
185:
186: <0 -3>
187:
188: \fB - @ [%0,id] : -3\fP
189:
190: 3
191:
192: \fB all_le : <1 3 5 7>\fP
193:
194: T
195:
196: \fB all_le : <1 0 5 7>\fP
197:
198: F
199:
200: \fB )pfn all_le\fP
201:
202: {all_le ! and @ &<= @ distl @ [1,tl]}
203:
204: \fB distl @ [1,tl] : <1 2 3 4>\fP
205:
206: <<1 2> <1 3> <1 4>>
207:
208: \fB &<= @ distl @ [1,tl] : <1 2 3 4>\fP
209:
210: <T T T>
211:
212: \fB ! and : <F T T>\fP
213:
214: F
215:
216: \fB ! and : <T T T>\fP
217:
218: T
219:
220: \fB sort : <3 1 2 4>\fP
221:
222: <1 2 3 4>
223:
224: \fB sort : <1>\fP
225:
226: <1>
227:
228: \fB sort : <>\fP
229:
230: ?
231:
232: \fB sort : 4\fP
233:
234: ?
235:
236: \fB )pfn sort\fP
237:
238: {sort (null @ tl -> [1] ; (all_le -> apndl @ [1,sort@tl]; sort@rotl))}
239:
240: \fB fact : 3\fP
241:
242: 6
243:
244: \fB )pfn fact sub1 eq0\fP
245:
246: {fact (eq0 -> %1 ; *@[id , fact@sub1])}
247:
248: {sub1 -@[id,%1]}
249:
250: {eq0 = @ [id,%0]}
251:
252: \fB &fact : <1 2 3 4 5>\fP
253:
254: <1 2 6 24 120>
255:
256: \fB eq0 : 3\fP
257:
258: F
259:
260: \fB eq0 : <>\fP
261:
262: F
263:
264: \fB eq0 : 0\fP
265:
266: T
267:
268: \fB sub1 : 3\fP
269:
270: 2
271:
272: \fB %1 : 3\fP
273:
274: 1
275:
276: \fB alt_fact : 3\fP
277:
278: 6
279:
280: \fB )pfn alt_fact\fP
281:
282: {alt_fact !* @ iota}
283:
284: \fB iota : 3\fP
285:
286: <1 2 3>
287:
288: \fB !* @ iota : 3\fP
289:
290: 6
291:
292: \fB !+ : <1 2 3>\fP
293:
294: 6
295:
296: \fB find : <3 <3 4 5>>\fP
297:
298: T
299:
300: \fB find : <<> <3 4 <>>>\fP
301:
302: T
303:
304: \fB find : <3 <4 5>>\fP
305:
306: F
307:
308: \fB )pfn find\fP
309:
310: {find (null@2 -> %F ; (=@[1,1@2] -> %T ; find@[1,tl@2]))}
311:
312: \fB [1,tl@2] : <3 <3 4 5>>\fP
313:
314: <3 <4 5>>
315:
316: \fB [1,1@2] : <3 <3 4 5>>\fP
317:
318: <3 3>
319:
320: \fB alt_fnd : <3 <3 4 5>>\fP
321:
322: T
323:
324: \fB )pfn alt_fnd\fP
325:
326: {alt_fnd ! or @ &eq @ distl }
327:
328: \fB distl : <3 <3 4 5>>\fP
329:
330: <<3 3> <3 4> <3 5>>
331:
332: \fB &eq @ distl : <3 <3 4 5>>\fP
333:
334: <T F F>
335:
336: \fB !or : <T F T>\fP
337:
338: T
339:
340: \fB !or : <F F F>\fP
341:
342: F
343:
344: \fB )delete alt_fnd\fP
345:
346: \fB )fns\fP
347:
348: .TS
349: l l l l l l l.
350: abs_val all_le alt_fact eq0 fact find ip
351: mm sort sub1 \& \& \& \&
352: .TE
353:
354: \fB alt_fnd : <3 <3 4 5>>\fP
355:
356: alt_fnd not defined
357:
358: ?
359: \fB {g g}\fP
360:
361: {g}
362: \fB g : 3\fP
363:
364: non-terminating
365:
366: ?
367:
368: [Return to top level]
369:
370: FP, v. 4.0 10/8/82
371: \fB [+,*] : <3 4>\fP
372:
373: <7 12>
374:
375: .(b
376: \fB [+,* : <3 4>\fP
377:
378: syntax error:
379:
380: [+,* \kx: <3 4>
381: \h'\nxu'^
382: .)b
383: \fB ip : <<3 4 5> <5 6 7>>\fP
384:
385: 74
386:
387: \fB )pfn ip\fP
388:
389: {ip !+ @ &* @ trans}
390:
391: \fB trans : <<3 4 5> <5 6 7>>\fP
392:
393: <<3 5> <4 6> <5 7>>
394:
395: \fB &* @ trans : <<3 4 5> <5 6 7>>\fP
396:
397: <15 24 35>
398:
399: \fB mm : <<<1 0> <0 1>> <<3 4> <5 6>>>\fP
400:
401: <<3 4> <5 6>>
402:
403: \fB )pfn mm\fP
404:
405: {mm &&ip @ &distl @ distr @[1,trans@2]}
406:
407: \fB [1,trans@2] : <<<1 0> <0 1>> <<3 4> <5 6>>>\fP
408:
409: <<<1 0> <0 1>> <<3 4> <5 6>>>
410:
411: \fB distr : <<<1 0> <0 1>> <<3 4> <5 6>>>\fP
412:
413: <<<1 0> <<3 4> <5 6>>> <<0 1> <<3 4> <5 6>>>>
414:
415: \fB &distl : <<<1 0> <<3 4> <5 6>>> <<0 1> <<3 4> <5 6>>>>\fP
416:
417: <<<<1 0> <3 4>> <<1 0> <5 6>>> <<<0 1> <3 4>> <<0 1> <5 6>>>>
418:
419: .(b
420: \fB &ip @ &dist & distr @ [1,trans @ 2] : <<<1 0> <0 1>> <<3 4> <5 6>>>\fP
421:
422: syntax error:
423:
424: [+,* \kx: <3 4>
425: \h'\nxu'^
426: &ip @ &distl \kx& distr @ [1,trans @ 2] : <<<1 0> <0 1>> <<3 4> <5 6>>>
427: \h'\nxu'^
428: .)b
429: \fB &ip @ &distl @ distr @ [1,trans@2] : <<<1 0> <0 1>> <<3 4> <5 6>>>\fP
430:
431: ?
432: .sp 2
433: .fi
434: .bp
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.