Annotation of researchv10dc/vol2/anim/anim.ms, revision 1.1.1.1

1.1       root        1: .so ../ADM/mac
                      2: .XX anim 451 "A System for Algorithm Animation"
                      3: .EQ
                      4: delim @@
                      5: .EN
                      6: .nr dP 1
                      7: .nr dV 1
                      8: .nr dT 8       \" tab stops this far apart in .P1/.P2
                      9: .nr NH .5v     \" adds extra space before NH or SH heading
                     10: .nr ds .5i     \" default indent for programs
                     11: .hy 14         \" set hyphenation: 2=not last lines; 4= no -xx; 8=no xx-
                     12: .\"
                     13: .de IN \" assumes called as .INCLUDE filename
                     14: .sy compile \\$2.t
                     15: .so \\$2.o
                     16: ..
                     17: .de ge \" assumes .ge called as .get
                     18: .sy trget \\n(.$ \\$2 '\\$3' '\\$4' '\\$5' >junk.\\n($$
                     19: .so junk.\\n($$
                     20: .sy rm junk.\\n($$
                     21: ..
                     22: .de ru \" assumes .ru called as .run
                     23: .sy \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 >junk1.\\n($$
                     24: .get junk1.\\n($$
                     25: .sy rm junk1.\\n($$
                     26: ..
                     27: .TL
                     28: A System for Algorithm Animation
                     29: .br
                     30: Tutorial and User Manual
                     31: .AU
                     32: Jon L. Bentley
                     33: Brian W. Kernighan
                     34: .AI
                     35: .MH
                     36: .AB
                     37: A program or an algorithm can be animated by a movie
                     38: that graphically represents its dynamic execution.
                     39: For instance, a memory allocator might be animated by lines that
                     40: appear when memory is allocated and disappear when it is freed;
                     41: a sort might be animated by a randomly scrambled
                     42: sequence of lines being permuted into order.
                     43: Such animations are useful for debugging programs, for developing
                     44: new programs, and for communicating information about how programs work.
                     45: This paper describes a basic system for algorithm animation:
                     46: the output is crude, but the system is easy to use;
                     47: novice users can animate a program in a couple of hours.
                     48: The system currently produces movies on Teletype 5620 terminals
                     49: and workstations that support the X window system, and also renders movies into
                     50: ``stills'' that can be included in
                     51: .I troff
                     52: documents.
                     53: This paper is a user manual and a tutorial introduction
                     54: to algorithm animation using the system.
                     55: .AE
                     56: .NH
                     57: Introduction
                     58: .PP
                     59: Dynamic displays are better than static displays for
                     60: giving insight into the behavior of dynamic systems.
                     61: The pictures in Figure 1, for instance, illustrate four
                     62: equal-mass bodies moving in the plane
                     63: under Newtonian attraction.
                     64: .KF
                     65: .INCLUDE stars
                     66: .sp
                     67: .ce
                     68: \f3Figure 1:\fP  Bodies moving under Newtonian attraction
                     69: .KE
                     70: Time marches across the pictures left to right,
                     71: at roughly equal intervals.
                     72: Each column, called a
                     73: .I snapshot ,
                     74: depicts three
                     75: .I views
                     76: of the bodies.
                     77: The top view gives the current position as a dot; the tail formed
                     78: by the last few positions hints at the velocity and the acceleration.
                     79: The middle view renders the path of each body as a line.
                     80: The bottom view depicts the history of velocities by dots
                     81: recorded at equal time intervals:
                     82: low velocities give close dots and
                     83: high velocities leave the dots far apart.
                     84: .PP
                     85: The first snapshot shows the bodies starting slowly, far apart.
                     86: In the second snapshot they have recently experienced a
                     87: high-velocity encounter near the center.
                     88: In the third snapshot the bodies are again far apart,
                     89: moving slowly toward another encounter in the fourth snapshot.
                     90: In the fifth snapshot the large time-step of our simulation program
                     91: violates conservation of energy and sends the bodies racing away
                     92: from each other.
                     93: .PP
                     94: This paper describes the animation system that produced those pictures.
                     95: A sixty-line C simulation program was augmented with eight
                     96: .I printf
                     97: statements to generate a
                     98: .I script
                     99: file describing the paths of the four bodies in the three views.
                    100: That file was processed by a program named
                    101: .I stills
                    102: to produce the pictures above, using
                    103: .I pic
                    104: and
                    105: .I troff ;
                    106: we were able to control what frames were displayed, in what size and form.
                    107: A program named
                    108: .I movie
                    109: displays the same data on a Teletype 5620 terminal or an X workstation;
                    110: the viewer can control the speed of display,
                    111: proceed forward or backward through time,
                    112: and change the screen layout to emphasize certain views.
                    113: Those components can be depicted as:
                    114: .PS
                    115: boxht = .25; boxwid = .6
                    116: ellipseht = .25; ellipsewid = .6
                    117: lineht = .1; linewid = .4
                    118: down
                    119: box "generator"
                    120: line down
                    121: A: ellipse "script"
                    122: line from A.se right down
                    123: box "stills"
                    124: line down
                    125: box invis "pic | troff | ..."
                    126: line from A.sw left down
                    127: box "movie"
                    128: line down
                    129: box invis "5620, X, ..."
                    130: .PE
                    131: .PP
                    132: Several systems have been developed for algorithm animation
                    133: |reference(sedgewick brown ieee).
                    134: Most of those systems produce animations of very high quality;
                    135: unfortunately, they are expensive in both programmer time and CPU time.
                    136: Our system is at the opposite end of the spectrum:
                    137: its output is primitive, but the system is easy to use;
                    138: a new user can animate a simple program
                    139: in an hour or two by adding a few lines of code.
                    140: Although our system was designed primarily with program animation
                    141: in mind, the gravitational example shows that it can be useful
                    142: in other domains as well.
                    143: .PP
                    144: Section 2 introduces the system by animating a sorting algorithm.
                    145: Sections 3 through 5 describe the three primary components of
                    146: the system:
                    147: script
                    148: files,
                    149: .I movie ,
                    150: and
                    151: .I stills .
                    152: Section 6 describes the animation of several larger programs,
                    153: and Section 7 discusses a few everyday matters about using the system.
                    154: .NH
                    155: A Simple Example \(em Sorting
                    156: .PP
                    157: Insertion sort is the method most card players use.
                    158: As each card is dealt, it is inserted into
                    159: its proper place among the existing cards.
                    160: To sort the array @X[1..N]@, insertion sort maintains the
                    161: sorted subset in @X[1..I]@ and increases @I@ from 2 to @N@.
                    162: The subarray @X[1..1]@ is sorted by definition.
                    163: The first phase of the algorithm sifts @X[2]@ down
                    164: so that @X[1..2]@ is sorted, the second phase sifts
                    165: @X[3]@ down so that @X[1..3]@ is sorted, and so on.
                    166: .PP
                    167: Here is an implementation of insertion sort in
                    168: .I awk |reference(awk book):
                    169: .P1
                    170: .get is.awk
                    171: .P2
                    172: The first
                    173: .CW for
                    174: statement sprinkles
                    175: .CW x[1..n]
                    176: with random integers in the range @1..25@, and the second and third
                    177: .CW for
                    178: statements perform the insertion sort.
                    179: The function
                    180: .CW swap
                    181: exchanges array elements;
                    182: .CW show
                    183: prints the current state of the array.
                    184: .PP
                    185: If we run this program with
                    186: .CW n
                    187: set to 7, we get this static display
                    188: of sorting a 7-element array of random integers:
                    189: .P1
                    190: .run sh is.awk 7
                    191: .P2
                    192: .PP
                    193: The animation system provides an alternative:
                    194: by adding a few more
                    195: .CW print
                    196: statements to the program, we can produce input for the animation system,
                    197: thus providing a dynamic display
                    198: of the sorting process.
                    199: Furthermore, we can use graphics as well as text,
                    200: to give a more visual presentation of the algorithm.
                    201: .PP
                    202: For this example, we decided to present two
                    203: views.
                    204: The top view simply shows the numbers in the array as they are sorted;
                    205: it is essentially the same as the textual output above,
                    206: except that we have added a vertical bar:
                    207: elements to the left of the bar are in order.
                    208: The bottom view is graphical: the value of each element is represented
                    209: by the length of the corresponding vertical line.
                    210: .PP
                    211: These six snapshots
                    212: show the state after each phase of the sorting algorithm:
                    213: .sy make.sorts
                    214: .INCLUDE is3
                    215: .PP
                    216: Although the two views represent the same information,
                    217: they are useful for different tasks.
                    218: The textual nature of the top view is easier for novices to follow,
                    219: and the complete information is handy for debugging small examples.
                    220: The more visual bottom view is better for displaying large sorts.
                    221: .sp 1
                    222: .LP
                    223: .I "The Program."
                    224: .PP
                    225: Here is the complete
                    226: .I awk
                    227: program
                    228: .CW is.gen
                    229: that generated the animation depicted above.
                    230: .P1
                    231: .get is.gen
                    232: .P2
                    233: It is very similar to the first version,
                    234: but we have added the functions
                    235: .CW less
                    236: to make comparisons and
                    237: .CW draw
                    238: to display elements,
                    239: as well as several
                    240: .CW print
                    241: statements.
                    242: In addition to performing their sorting functions,
                    243: .CW less
                    244: and
                    245: .CW swap
                    246: record their actions by printing output
                    247: into a script file that will serve as input to
                    248: .I movie
                    249: and
                    250: .I stills .
                    251: This animation uses four commands:
                    252: .CW line ,
                    253: .CW text ,
                    254: .CW view
                    255: and
                    256: .CW click .
                    257: .PP
                    258: A line from @( x sub 1 , y sub 1 )@ to @( x sub 2 , y sub 2 )@ is
                    259: drawn by a command of the form
                    260: .P1
                    261: @optional_label:@ line @x sub 1@ @y sub 1@ @x sub 2@ @y sub 2@
                    262: .P2
                    263: (Throughout this paper, literals are shown in
                    264: .CW typewriter
                    265: font and categories are in @italics@.)
                    266: The coordinates of the line can lie in any range;
                    267: later programs will scale them appropriately.
                    268: The label on a line is optional.
                    269: When a labeled object is drawn
                    270: the object that previously had that label is erased.
                    271: Thus for all lines that have the same label,
                    272: the act of drawing one line erases its predecessor.
                    273: (There is also an explicit
                    274: .CW erase
                    275: command.)
                    276: .PP
                    277: Text is produced at @( x , y )@ by a command of the form
                    278: .P1
                    279: @optional_label:@ text @x@ @y@ @anything@ @at@ @all@
                    280: .P2
                    281: As with lines, labels are permitted;
                    282: re-use of a label erases whatever object previously had that label.
                    283: For example, the vertical bar is always printed with the label
                    284: .CW bar ,
                    285: so each bar erases the previous one.
                    286: .PP
                    287: The
                    288: .CW view
                    289: command is used to place output in a particular view.
                    290: There are two views here,
                    291: .CW text
                    292: and
                    293: .CW geom :
                    294: .P1
                    295: view text
                    296: view geom
                    297: .P2
                    298: The
                    299: .CW draw
                    300: function draws text in the
                    301: .CW text
                    302: view
                    303: and lines in the
                    304: .CW geom
                    305: view, relying on implicit erasure to remove the previous object
                    306: before creating a new one.
                    307: Different views are independent, so a label like
                    308: .CW a1
                    309: can be used in several views without interference.
                    310: .PP
                    311: Interesting events are marked by the
                    312: .CW click
                    313: command:
                    314: .P1
                    315: click swap
                    316: click comp
                    317: click phase
                    318: .P2
                    319: .I Stills
                    320: and
                    321: .I movie
                    322: can refer to each click with this mechanism,
                    323: as we will see in more detail shortly.
                    324: .PP
                    325: Labels, view names and click names are arbitrary
                    326: and unrelated to one another.
                    327: .sp 1
                    328: .LP
                    329: .I "The Script File."
                    330: .PP
                    331: Executing the command
                    332: .P1
                    333: is.gen 3 >is1.s
                    334: .P2
                    335: produces the script file
                    336: .CW is1.s
                    337: containing a sort of three elements.
                    338: The basename
                    339: .CW is1
                    340: is for ``insertion sort 1''; the suffix
                    341: .CW .s
                    342: identifies it as a script file and is required by the animation system.
                    343: Here is
                    344: .CW is1.s ,
                    345: printed in two columns to save space:
                    346: .P1
                    347: .ps 8
                    348: .vs 8
                    349: .ta 3i
                    350: .run 2col is1.s
                    351: .P2
                    352: .sp
                    353: .PP
                    354: Here is a picture of all clicks in the script file
                    355: .CW is1.s ,
                    356: produced by
                    357: .I stills .
                    358: .INCLUDE is1
                    359: As before, time goes from left to right.
                    360: Both views of the current state are depicted in a snapshot at each
                    361: .CW click ;
                    362: the label below each frame tells the name and number of the click.
                    363: This detailed picture illustrates the animation system;
                    364: here is a sparser picture that illustrates insertion sort
                    365: on a 14-element array:
                    366: .INCLUDE is2
                    367: .sp 1
                    368: .LP
                    369: .I "Making Stills."
                    370: .PP
                    371: The last picture was included in this document by this
                    372: .I stills
                    373: description:
                    374: .P1
                    375: .get is2.t
                    376: .P2
                    377: The description is delimited by the lines
                    378: .CW "\&.begin stills"
                    379: and
                    380: .CW \&.end
                    381: (which correspond, for instance, to
                    382: .CW \&.EQ
                    383: and
                    384: .CW \&.EN
                    385: in
                    386: .CW eqn
                    387: or
                    388: .CW \&.TS
                    389: and
                    390: .CW \&.TE
                    391: in
                    392: .CW tbl ).
                    393: Text following the sharp character
                    394: .CW #
                    395: is a comment to be ignored.
                    396: The
                    397: .CW view
                    398: statements specify the empty string as the title for both
                    399: views of the data.
                    400: The
                    401: .CW print
                    402: statement displays snapshots at the requested
                    403: .CW click s
                    404: of
                    405: .CW phase .
                    406: .PP
                    407: The last four statements are parameter assignments of the form
                    408: .P1
                    409: @parameter_name@   @value@
                    410: .P2
                    411: Assignment to the
                    412: .CW file
                    413: parameter names the script file to be displayed.
                    414: The next two assignments set the height and width of frames,
                    415: and the final statement causes
                    416: .CW medium
                    417: text (the default text size) to be set
                    418: five points smaller than the current
                    419: .I troff
                    420: point size.
                    421: .sp 1
                    422: .LP
                    423: .I "Viewing A Movie."
                    424: .PP
                    425: To watch a movie on the 5620,
                    426: make a window of suitable size and shape
                    427: and in it type the command
                    428: .P1
                    429: is.gen 20 | movie
                    430: .P2
                    431: If you want to access the script later, type instead
                    432: .P1
                    433: is.gen 20 >is.s
                    434: movie is.s
                    435: .P2
                    436: After a pause to run
                    437: .CW is.gen
                    438: (about 15 seconds on a VAX\(tm-750 in this case), the 5620 down-loading procedure
                    439: will begin;
                    440: after that (another 30 seconds), the data for the movie itself will
                    441: begin to appear.
                    442: When this is finished (also about 30 seconds),
                    443: a message about the number of bytes
                    444: sent (about 9500) appears in the upper left corner.
                    445: .PP
                    446: At this point, the mouse buttons can be used to
                    447: redisplay the movie.
                    448: Button 3 is the main control.
                    449: It has 9 menu items:
                    450: .P1
                    451: again
                    452: faster 1
                    453: slower 1
                    454: 1 step
                    455: backward
                    456: fatter 1
                    457: thinner 1
                    458: or mode
                    459: new file
                    460: Quit?
                    461: .P2
                    462: To play the movie again,
                    463: select
                    464: .CW again .
                    465: (This movie takes about 6 seconds at full speed.)
                    466: You can stop it at any point by pushing any button;
                    467: a further push of button 1 continues it.
                    468: To slow the display, select 
                    469: .CW slower ;
                    470: each selection halves the speed by increasing
                    471: a wait interval by a factor of two.
                    472: After three selections the menu reads
                    473: .P1
                    474: again
                    475: faster 8
                    476: slower 8
                    477: \&...
                    478: .P2
                    479: Try selecting
                    480: .CW again
                    481: to see the sort once at this speed, then select
                    482: .CW faster
                    483: three times to get back to full speed.
                    484: .PP
                    485: The items labeled
                    486: .CW fatter
                    487: and
                    488: .CW thinner
                    489: control the thickness of lines in an analogous manner.
                    490: Selecting
                    491: .CW fatter
                    492: several times results in obese lines;
                    493: you may return things to normal with
                    494: .CW thinner .
                    495: .PP
                    496: Three menu items control binary mode settings:
                    497: .CW 1
                    498: .CW step
                    499: or
                    500: .CW run ;
                    501: .CW backward
                    502: or
                    503: .CW forward ;
                    504: and
                    505: .CW or
                    506: .CW mode
                    507: or
                    508: .CW xor
                    509: .CW mode .
                    510: For each, the label indicates the next state,
                    511: not the current state.
                    512: .PP
                    513: Normally the movie is played from beginning to end without pause.
                    514: The menu item labeled
                    515: .CW 1
                    516: .CW step
                    517: puts it into a mode where it displays only one ``step''
                    518: each time button 1 is pushed.
                    519: This allows you to inspect the sort a frame at a time.
                    520: This item changes to
                    521: .CW run
                    522: when
                    523: .CW 1
                    524: .CW step
                    525: has been selected
                    526: so you can revert to continuous action.
                    527: .PP
                    528: The
                    529: .CW backward
                    530: item causes the steps to be taken in reverse order (time runs backwards);
                    531: the menu item changes to
                    532: .CW forward
                    533: when selected.
                    534: After the sort ends, select
                    535: .CW backward
                    536: and
                    537: .CW again
                    538: and watch the array scramble itself before your very eyes.
                    539: Judicious use of 
                    540: .CW 1
                    541: .CW step
                    542: and
                    543: .CW backward
                    544: and
                    545: .CW forward
                    546: make it easy to examine a few snapshots in detail.
                    547: .PP
                    548: Normally items are displayed in ``exclusive OR'' mode,
                    549: which means that a bit drawn over a previous one erases it.
                    550: If you are drawing numerous objects in a crowded area,
                    551: this can lead to unintended erasures.
                    552: The
                    553: .CW or
                    554: .CW mode
                    555: item switches to ``inclusive OR'' for drawing objects,
                    556: and erases objects by clearing.
                    557: Some movies are far better in one mode than the other.
                    558: .PP
                    559: The
                    560: .CW new
                    561: .CW file
                    562: item allows one to view a new movie without having to reload the
                    563: .I movie
                    564: program into the 5620.
                    565: We'll see how it works in Section 4.
                    566: .PP
                    567: The
                    568: .CW Quit?
                    569: menu item is the way to exit.
                    570: If selected, it displays a skull and crossbones
                    571: to warn that its effect is irreversible.
                    572: Pushing button 3 again exits;
                    573: a different button avoids quitting.
                    574: .PP
                    575: Button 2 contains menu items to control the size and shape
                    576: of the views on the screen and to control the meaning of a
                    577: ``step'' in 1-step mode.
                    578: For this sorting movie, button 2 looks like:
                    579: .P1
                    580: view text
                    581: view geom
                    582: click comp
                    583: click swap
                    584: click phase
                    585: .P2
                    586: When a view is selected, you can sweep a rectangle
                    587: in which that view is to be displayed;
                    588: the use is exactly like the
                    589: .CW New
                    590: menu item in
                    591: .I mux .
                    592: You can arrange the views any way you like;
                    593: try deleting the textual view by sweeping its rectangle out of the window.
                    594: .PP
                    595: When a
                    596: .CW click
                    597: is selected, 1-stepping proceeds to the next
                    598: occurrence of that click.
                    599: So, for example, to see swaps one at a time,
                    600: select
                    601: .CW click
                    602: .CW swap
                    603: on button 2 then select
                    604: .CW 1
                    605: .CW step
                    606: on button 3.
                    607: Each hit of button 1 will pause at the next
                    608: .CW click
                    609: .CW swap
                    610: statement in the script file, in either
                    611: .CW forward
                    612: and
                    613: .CW backward
                    614: mode.
                    615: .PP
                    616: Multiple clicks may be selected.
                    617: Selecting both
                    618: .CW click
                    619: .CW comp
                    620: and
                    621: .CW click
                    622: .CW swap
                    623: will cause a pause after every comparison and every swap.
                    624: Selected clicks are marked with an asterisk in the menu;
                    625: selecting a click that already has an asterisk
                    626: removes the asterisk and turns off the click.
                    627: .PP
                    628: In
                    629: .CW run
                    630: mode, the movie runs at full speed until it encounters a selected click,
                    631: then pauses for a time proportional to the selected speed.
                    632: Selecting no clicks is equivalent to having selected an implicit
                    633: click that occurs after each geometric object
                    634: (text, line, circle, rectangle)
                    635: is drawn or erased,
                    636: so animations run faster when some clicks are turned on (with
                    637: .CW click
                    638: .CW phase
                    639: selected, for instance, the sorting movie runs nearly twice as fast).
                    640: .sp 1
                    641: .LP
                    642: .I "Summary."
                    643: .PP
                    644: This exercise illustrates the capabilities
                    645: and limitations of our animation system.
                    646: The output of
                    647: .I movie
                    648: is a crude but useful animation.
                    649: The output of
                    650: .I stills
                    651: is handy for more detailed study and for presentation in documents
                    652: (we would like to include a movie in this document, for instance,
                    653: but paper is easier to distribute than videotape).
                    654: A sophisticated animation system might require 500 lines of
                    655: code to produce beautiful animations of insertion sort.
                    656: Our output is unpolished by comparison, but it is adequate
                    657: for many purposes and requires just a few dozen lines.
                    658: .PP
                    659: If our system is so crude, why bother using it?
                    660: Why not animate an algorithm simply by drawing geometric objects
                    661: on the output device you happen to be using?
                    662: Some of the answer lies in extra services like these:
                    663: .IP
                    664: .I "Device Independence."
                    665: A script file can be rendered as a movie on a 5620 or an X11 workstation;
                    666: the system is designed to make it easy to port to additional
                    667: output devices.
                    668: The same script file can be incorporated into a document by
                    669: .I stills .
                    670: .IP
                    671: .I "Names."
                    672: Labels allow geometric objects to be erased;
                    673: implicit erasure by re-using a label avoids
                    674: much of the tedium of bookkeeping.
                    675: Click names mark key events;
                    676: they can be used to group related events.
                    677: .IP
                    678: .I "Independent Views."
                    679: Different simultaneous views of a process
                    680: are crucial for animating algorithms.
                    681: In our system, a single statement moves from one view to another.
                    682: Within a view, the user need not be
                    683: concerned about the range of coordinates;
                    684: the system scales automatically.
                    685: Labels in different views are independent.
                    686: .IP
                    687: .I "Viewer Control."
                    688: Both
                    689: .I movie
                    690: and
                    691: .I stills
                    692: allow the viewer to select which views will be displayed
                    693: and which clicks will be recognized.
                    694: Additionally,
                    695: .I movie
                    696: allows the viewer to go forward or backward, in single
                    697: steps or running at a selected speed.
                    698: .IP
                    699: .I "An Interface To The World."
                    700: Although writing to files takes more computer time than using the
                    701: geometric primitives provided by a specific output device,
                    702: we will soon see how those files allow complicated tasks
                    703: to be easily composed out of simple software tools.
                    704: .LP
                    705: Our system does not support interactive animations, however:
                    706: once the script has been generated,
                    707: there's no way to change it
                    708: except to generate it again.
                    709: .NH
                    710: The Script Language
                    711: .PP
                    712: This section is a more complete description of the
                    713: script language in which animations are described.
                    714: A script file is processed by the heretofore unmentioned program
                    715: .I develop ;
                    716: errors in script files are reported by that program.
                    717: The output of
                    718: .I develop
                    719: feeds
                    720: .I stills
                    721: and
                    722: .I movie :
                    723: .PS
                    724: boxht = .25; boxwid = .6
                    725: ellipseht = .25; ellipsewid = .6
                    726: lineht = .1; linewid = .4
                    727: down
                    728: box "generator"
                    729: line down
                    730: ellipse "fname.s"
                    731: line down
                    732: box "develop"
                    733: line down
                    734: A: ellipse "fname.i"
                    735: B: box "stills" with .w at A.e + (.2, -.4)
                    736: line down
                    737: box invis "pic | troff | ..."
                    738: C: box "movie" with .e at A.w - (.2, .4)
                    739: line down
                    740: box invis "5620, X, ..."
                    741: line from A.se to B.nw
                    742: line from A.sw to C.ne
                    743: up
                    744: line up from B.n
                    745: ellipse "docfile"
                    746: .PE
                    747: The command
                    748: .CW develop
                    749: .CW fname.s
                    750: produces the
                    751: .I intermediate
                    752: file
                    753: .CW fname.i
                    754: from the script file
                    755: .CW fname.s ,
                    756: unless
                    757: .CW fname.i
                    758: already exists and is newer than
                    759: the corresponding script file.
                    760: Fortunately, most users need not be concerned with intermediate files and the
                    761: .I develop
                    762: program; both
                    763: .I movie
                    764: and
                    765: .I stills
                    766: call
                    767: .I develop
                    768: implicitly.
                    769: Appendix I defines the format of an intermediate file.
                    770: .PP
                    771: The script language provides
                    772: commands to draw geometric objects
                    773: and commands that control the pictures.
                    774: A line whose first non-blank character is
                    775: .CW #
                    776: is a comment;
                    777: comments may not appear on the line after other commands.
                    778: Blank lines are ignored.
                    779: .sp 1
                    780: .LP
                    781: .I "Geometric Commands" :
                    782: .CW text ,
                    783: .CW line ,
                    784: .CW box ,
                    785: .CW circle .
                    786: .PP
                    787: Geometric commands describe text, lines, rectangles, or circles.
                    788: They share the common form
                    789: .P1
                    790: @optional_label:@ @command@  @options@  @x@ @y@  @additional@ @parts@
                    791: .P2
                    792: If a label is present, it names the object and will implicitly
                    793: erase any existing object with the same name in the same view.
                    794: The options are a (possibly null) list of names,
                    795: terminated by the next numeric field.
                    796: .PP
                    797: Text is placed at a position by the command
                    798: .P1
                    799: @optional_label:@ text  @options@  @x@ @y@  @string@
                    800: .P2
                    801: The available options are
                    802: .P1
                    803: [center]  ljust  rjust  above  below
                    804: small  [medium]  big  bigbig
                    805: .P2
                    806: At most one option may be selected from each line;
                    807: if none is selected, the option in brackets is used.
                    808: The first line describes text position, and
                    809: the second line describes text size.
                    810: The text string may be quoted.
                    811: If there is no leading quote, then the string starts at the first
                    812: non-blank character and continues until the end of the line.
                    813: If there is a leading quote, subsequent leading white space is kept
                    814: and any trailing quote at the end of the line is removed;
                    815: intermediate quotes are kept.
                    816: Some strings, including
                    817: (but not necessarily limited to)
                    818: .CW bullet ,
                    819: .CW dot ,
                    820: .CW circle ,
                    821: and
                    822: .CW times ,
                    823: are recognized by later processors.
                    824: .PP
                    825: A line is drawn by
                    826: .P1
                    827: @optional_label:@ line  @options@  @x sub 1@ @y sub 1@ @x sub 2@ @y sub 2@
                    828: .P2
                    829: The available options are
                    830: .P1
                    831: [-]  ->  <-  <->
                    832: [solid]  fat  fatfat  dotted  dashed
                    833: .P2
                    834: The first line of options describe whether the line should
                    835: be drawn with arrowheads; the default is without arrowheads.
                    836: The option
                    837: .CW <-
                    838: puts an arrowhead at the @( x sub 1 , y sub 1 )@ end of the line,
                    839: .CW ->
                    840: puts an arrowhead at the other end,
                    841: and
                    842: .CW <->
                    843: puts them at both ends.
                    844: The second line of options describes the body of the line.
                    845: .PP
                    846: A rectangle is drawn by
                    847: .P1
                    848: @optional_label:@ box  @options@  @xmin@ @ymin@ @xmax@ @ymax@
                    849: .P2
                    850: The only options are
                    851: .P1
                    852: [nofill]  fill
                    853: .P2
                    854: Under the default
                    855: .CW nofill
                    856: only the border of the box is drawn;
                    857: a
                    858: .CW fill ed
                    859: box has a solid interior as well.
                    860: .PP
                    861: A circle is drawn by
                    862: .P1
                    863: @optional_label:@ circle  @options@  @x@ @y@  @radius@
                    864: .P2
                    865: The radius is measured in the @x@ dimension.
                    866: Circles will look right only if @x@ and @y@ are in about the same range.
                    867: As with rectangles, the options are
                    868: .P1
                    869: [nofill]  fill
                    870: .P2
                    871: .sp 1
                    872: .LP
                    873: .I "Control Commands" :
                    874: .CW view ,
                    875: .CW click ,
                    876: .CW erase ,
                    877: .CW clear .
                    878: .PP
                    879: The current view is set by the statement
                    880: .P1
                    881: view  @name@
                    882: .P2
                    883: If there are no view statements in the script file,
                    884: .I develop
                    885: generates a single implicit view named
                    886: .CW def.view .
                    887: If geometric objects appear before the first view statement,
                    888: they go in that view and a warning message is generated.
                    889: .PP
                    890: A click is named by
                    891: .P1
                    892: click  @optional_name@
                    893: .P2
                    894: If no name is present, then the name
                    895: .CW def.click
                    896: is implicitly supplied.
                    897: .PP
                    898: A labeled geometric object can be explicitly erased by the command
                    899: .P1
                    900: erase  @label@
                    901: .P2
                    902: .I develop
                    903: prints a warning
                    904: if the object was never defined or has already been erased.
                    905: The various views have distinct name spaces;
                    906: the same label may be applied to two unrelated objects in two different views.
                    907: All objects in the current view can be erased by the statement
                    908: .P1
                    909: clear
                    910: .P2
                    911: .PP
                    912: None of these commands may have labels.
                    913: .sp 1
                    914: .LP
                    915: .I "Summary."
                    916: .PP
                    917: The script language contains the following commands;
                    918: options are indented on a subsequent line, with defaults in brackets:
                    919: .P1
                    920: # comment
                    921: @optional_label:@ line  @options@  @x sub 1@ @y sub 1@ @x sub 2@ @y sub 2@
                    922:        [-]  ->  <-  <->
                    923:        [solid]  fat  fatfat  dotted  dashed
                    924: @optional_label:@ text  @options@  @x@ @y@  @string@
                    925:        [center]  ljust  rjust  above  below
                    926:        small  [medium]  big  bigbig
                    927: @optional_label:@ box  @options@  @xmin@ @ymin@ @xmax@ @ymax@
                    928:        [nofill]  fill
                    929: @optional_label:@ circle  @options@  @x@ @y@  @radius@
                    930:        [nofill]  fill
                    931: view  @name@
                    932: click  @optional_name@
                    933: erase  @label@
                    934: clear
                    935: .P2
                    936: .PP
                    937: The shell command
                    938: .CW develop
                    939: .CW fname.s
                    940: makes the intermediate file
                    941: .CW fname.i
                    942: from the script file
                    943: .CW fname.s ,
                    944: if
                    945: .CW fname.i
                    946: is out of date.
                    947: The purpose of the intermediate file is to trade
                    948: increased space (for storing the intermediate file) for
                    949: reduced run time (a script file is developed just once, not
                    950: each time it is used).
                    951: The
                    952: .I movie
                    953: and
                    954: .I stills
                    955: shell scripts could be rewritten to pipe their inputs through
                    956: .I fdevelop ,
                    957: a filter form of
                    958: .I develop .
                    959: The
                    960: .I fdevelop
                    961: program can handle script files with at most 20,000 lines;
                    962: the argument 
                    963: .CW -l\f2n\fP
                    964: changes the upper bound to
                    965: .I n
                    966: instead.
                    967: It can similarly handle at most 10,000 pieces of geometry
                    968: active at any time;
                    969: the argument 
                    970: .CW -s\f2n\fP
                    971: (for ``slots'') changes that upper bound.
                    972: Error messages tell when these bounds need to be increased.
                    973: After any
                    974: .CW -l
                    975: and
                    976: .CW -s
                    977: arguments,
                    978: .I fdevelop
                    979: can have an optional file name.
                    980: If there is a name, that is the input file; otherwise,
                    981: the standard input is used.
                    982: The output is written on
                    983: the standard output.
                    984: .NH
                    985: The Movie Program
                    986: .PP
                    987: Movie production, as with most 5620 programs,
                    988: uses a host process and a terminal process.
                    989: The host sends the intermediate file produced by
                    990: .I develop
                    991: in a compact form to the terminal,
                    992: which stores it in a form suited
                    993: for forward or backward display.
                    994: As the file is shipped, the line number in
                    995: the intermediate file is displayed in the
                    996: upper-left corner of the window every 100 lines.
                    997: Afterwards, the total number of bytes
                    998: stored is displayed in that location.
                    999: The terminal process allocates 80,000 bytes
                   1000: (typically 5-10,000 objects)
                   1001: for the picture;
                   1002: the argument 
                   1003: .CW -m\f2n\fP
                   1004: sets the allocation to
                   1005: .I n
                   1006: instead.
                   1007: .PP
                   1008: The button 3 menu was sketched in Section 2.
                   1009: In general, drawing can be interrupted at any point by
                   1010: pushing any button, then resumed by pushing button 1.
                   1011: .PP
                   1012: Four menu items control two variables:
                   1013: .P1
                   1014: faster [speed]
                   1015: slower [speed]
                   1016: .P2
                   1017: decrease (halve) and increase (double) the pause at selected clicks, and
                   1018: .P1
                   1019: thinner [line width]
                   1020: fatter [line width]
                   1021: .P2
                   1022: alter the width of lines.
                   1023: (If the line thickness is @n@, then
                   1024: .CW solid
                   1025: lines are @2n - 1@ bits wide;
                   1026: .CW fat
                   1027: and
                   1028: .CW fatfat
                   1029: lines are larger.)
                   1030: Three menu items control binary attributes:
                   1031: .P1
                   1032: backward    forward
                   1033: or mode     xor mode
                   1034: 1 step      run
                   1035: .P2
                   1036: The mode displayed on the menu is the next state, not the current one.
                   1037: If the program is currently in
                   1038: .CW or
                   1039: .CW mode ,
                   1040: for instance, then
                   1041: .CW xor
                   1042: .CW mode
                   1043: is displayed.
                   1044: .PP
                   1045: The
                   1046: .CW new
                   1047: .CW file
                   1048: item allows one to view a new movie without downloading the
                   1049: .I movie
                   1050: program again.
                   1051: After selecting that item,
                   1052: text in the upper left of the window asks for the name of the intermediate
                   1053: file to be processed.
                   1054: The
                   1055: .I movie
                   1056: program does not call
                   1057: .I develop
                   1058: to make the intermediate
                   1059: .CW .i ) (
                   1060: file from the script
                   1061: .CW .s ) (
                   1062: file;
                   1063: that is the responsibility of the user,
                   1064: typically in a separate window.
                   1065: .PP
                   1066: Button 2 lists views and clicks.
                   1067: Selecting a view results in an icon for sweeping a rectangle,
                   1068: as in
                   1069: .I mux .
                   1070: Views may be positioned anywhere;
                   1071: portions positioned outside the window will not be shown.
                   1072: Initially, views have a 5 percent margin at each edge;
                   1073: this margin is zero for views that have been reshaped.
                   1074: If the window itself is reshaped, all views revert to
                   1075: the default position and margin.
                   1076: .PP
                   1077: Normally, in 1-step mode, the display pauses after each
                   1078: primitive object (line, text, etc.) has been drawn or erased.
                   1079: If any clicks are defined and turned on by button 2, however,
                   1080: then the display pauses only at those points.
                   1081: Any number of clicks may be turned on.
                   1082: Clicks that are turned on are marked with an asterisk;
                   1083: they may be turned off by selecting them again.
                   1084: .PP
                   1085: As it is for the 5620, so it is for X workstations,
                   1086: although the exigencies of the X window system
                   1087: have forced us to curtail some features.
                   1088: To keep the code relatively portable,
                   1089: there are again two processes, so
                   1090: the window in which one starts the animation clones another
                   1091: window of uncontrolled size, shape and position
                   1092: where the animation itself occurs.
                   1093: .PP
                   1094: The current terminal programs support
                   1095: many, but not all, text size and line mode options.
                   1096: .PP
                   1097: If
                   1098: .I movie
                   1099: has a single argument, it must be either a
                   1100: .CW .s
                   1101: or
                   1102: .CW .i
                   1103: file;
                   1104: .I movie
                   1105: .I develop s
                   1106: a
                   1107: .CW .s
                   1108: file.
                   1109: If it has no arguments, then it will pipe
                   1110: the standard input
                   1111: through
                   1112: .I fdevelop ;
                   1113: no intermediate file is created.
                   1114: For more exotic situations, use
                   1115: .I fmovie :
                   1116: with no arguments, it projects the intermediate file
                   1117: from the standard input;
                   1118: with a single argument, it projects that intermediate file.
                   1119: .NH
                   1120: The Stills Language
                   1121: .PP
                   1122: The
                   1123: .I stills
                   1124: program is a typical
                   1125: .I troff
                   1126: preprocessor.
                   1127: Portions of its input bracketed by
                   1128: .CW .begin
                   1129: .CW stills
                   1130: and
                   1131: .CW .end
                   1132: are translated into
                   1133: .I pic
                   1134: commands, and the rest of the input is passed through untouched.
                   1135: A paper containing
                   1136: .I stills
                   1137: input is typically compiled by a command like
                   1138: .P1
                   1139: stills paper | pic | troff >paper.out
                   1140: .P2
                   1141: .PP
                   1142: There are three classes of statements in a
                   1143: .I stills
                   1144: description:
                   1145: .CW print ,
                   1146: .CW view ,
                   1147: and parameter assignments.
                   1148: Only two statements are mandatory in a particular description:
                   1149: an assignment to the
                   1150: .CW file
                   1151: parameter and a
                   1152: .CW print
                   1153: statement.
                   1154: Text following the sharp symbol
                   1155: .CW #
                   1156: is discarded as a comment; blank lines are ignored.
                   1157: .PP
                   1158: There may be any number of
                   1159: .CW print
                   1160: statements of any combination of the following forms:
                   1161: .P1
                   1162: print all
                   1163: print final
                   1164: print @clickname@ all
                   1165: print @clickname@ @number@ @number@ @number@ ...
                   1166: .P2
                   1167: The first statement causes a snapshot to be drawn at each
                   1168: .CW click
                   1169: statement in the script file; the second draws one at the end of the file.
                   1170: The third form prints all
                   1171: .CW click s
                   1172: of the designated name, and the fourth prints only the clicks enumerated
                   1173: in the list of numbers.
                   1174: .PP
                   1175: View statements select which views are to be printed in snapshots
                   1176: and assign titles to views.
                   1177: .P1
                   1178: view  @name@  @optional@ @title@
                   1179: .P2
                   1180: The views appear in the order they are named,
                   1181: either top-to-bottom if time goes
                   1182: .CW across
                   1183: the page or left-to-right if time goes
                   1184: .CW down
                   1185: the page.
                   1186: If there are no
                   1187: .CW view
                   1188: statements, each snapshot depicts all views in the script.
                   1189: If the title is enclosed in quote marks, they are stripped and
                   1190: leading space is kept.
                   1191: If no title is given for a particular view, the view name
                   1192: itself is used as a title;
                   1193: thus an empty title is needed to turn off printing.
                   1194: .PP
                   1195: Parameters can be set by assignment statements of the form
                   1196: .P1
                   1197: @parameter_name@  @value@
                   1198: .P2
                   1199: All parameters are reset to their default values at each
                   1200: .CW .begin
                   1201: .I stills
                   1202: statement.
                   1203: Numeric values may be of the form
                   1204: .CW n ,
                   1205: .CW +n ,
                   1206: .CW -n ,
                   1207: or absent (zero default).
                   1208: .IP
                   1209: .I Filename 
                   1210: parameter:
                   1211: .CW file .
                   1212: The script file is named by assigning to the
                   1213: .CW file
                   1214: parameter with a statement of the form
                   1215: .CW file
                   1216: .CW basename.s .
                   1217: The
                   1218: .I stills
                   1219: program
                   1220: .I develop s
                   1221: that script file and then reads
                   1222: .CW basename.i .
                   1223: .IP
                   1224: .I "Text sizes" :
                   1225: .CW "small medium big bigbig" .
                   1226: The assignment
                   1227: .CW small
                   1228: .CW -2
                   1229: causes text with the
                   1230: .CW small
                   1231: option to be printed two point sizes smaller than the current
                   1232: .I troff
                   1233: point size.
                   1234: Assigning
                   1235: .CW "+5"
                   1236: or
                   1237: .CW "5"
                   1238: to
                   1239: .CW "bigbig"
                   1240: increases the point size by 5 for
                   1241: .CW bigbig
                   1242: text.
                   1243: All changes are relative; there is no way to set
                   1244: absolute point size.
                   1245: .IP
                   1246: .I "Line widths" :
                   1247: .CW "solid fat fatfat" .
                   1248: Relative size changes for line widths, exactly as for text sizes.
                   1249: .IP
                   1250: .I "Direction" :
                   1251: .CW "across down" .
                   1252: By default, snapshots proceed across the page in time.
                   1253: The assignment
                   1254: .CW down
                   1255: .CW 5
                   1256: causes time to proceed down the page for 5 snapshots before
                   1257: starting a new column;
                   1258: .CW down
                   1259: .CW 0
                   1260: or
                   1261: .CW "down"
                   1262: yields as many snapshots as will fit on an 8-inch page.
                   1263: The assignment
                   1264: .CW across
                   1265: .CW 7
                   1266: gives 7 snapshots in a row before starting a new row;
                   1267: .CW across
                   1268: .CW 0
                   1269: or
                   1270: .CW across
                   1271: adapts to a 6-inch width.
                   1272: .IP
                   1273: .I "Frame parameters" :
                   1274: .CW "frameht framewid margin" .
                   1275: The height and width of frames are given in inches; defaults are 1.5.
                   1276: The margin of a frame is the white space surrounding the data;
                   1277: the default is 0.05, or a five percent border.
                   1278: .IP
                   1279: .I "Optional parts" :
                   1280: .CW "frames times" .
                   1281: Frames are the solid borders around pictures;
                   1282: times are the click name and number that triggered a snapshot.
                   1283: Both have the default value
                   1284: .CW vis
                   1285: and are shown; they may be suppressed by assigning them the value
                   1286: .CW invis .
                   1287: .PP
                   1288: In summary,
                   1289: .I stills
                   1290: input consists of these commands:
                   1291: .P1
                   1292: print all
                   1293: print final
                   1294: print @clickname@ all
                   1295: print @clickname@ @number@ @number@ @number@ ...
                   1296: view  @name@  @optional@ @title@
                   1297: @parameter_name@  @value@
                   1298: .P2
                   1299: .LP
                   1300: At least one
                   1301: .CW print
                   1302: statement and a
                   1303: .CW file
                   1304: assignment are mandatory;
                   1305: other statements are optional.
                   1306: The parameter names in the right column may appear on the left side of a
                   1307: name/value assignment:
                   1308: .P1
                   1309: .ta 1.1i
                   1310: \f2Filename\fP file
                   1311: \f2Text sizes\fP       small medium big bigbig
                   1312: \f2Line widths\fP      solid fat fatfat
                   1313: \f2Direction\fP        across down
                   1314: \f2Frame parameters\fP frameht framewid margin
                   1315: \f2Optional parts\fP   frames times
                   1316: .P2
                   1317: .........
                   1318: .NH
                   1319: Larger Animations
                   1320: .PP
                   1321: The examples in this section illustrate algorithms on several
                   1322: classes of data structures, including arrays, trees and graphs.
                   1323: The graphical style is simple; this is easy for the animator and
                   1324: effective for the viewer.
                   1325: The programs in this section are not presented as paradigms of
                   1326: good programming style; rather, they show how succinct programs
                   1327: can yield useful animations.
                   1328: .PP
                   1329: In the paper cited earlier, Brown and Sedgewick employ
                   1330: several conceptual levels in animating an algorithm.
                   1331: .IP
                   1332: .I Execution.
                   1333: At one extreme is the program to be animated,
                   1334: executing on the data of interest.
                   1335: .IP
                   1336: .I "History of ``Interesting Events.''
                   1337: What events in a computation should be depicted in the animation?
                   1338: The simple animation of insertion sort in Section 2 used augmented
                   1339: .CW less
                   1340: and
                   1341: .CW swap
                   1342: routines to capture two primitives of most sorting programs:
                   1343: comparisons and data movements.
                   1344: It also explicitly recorded information associated with the
                   1345: interesting event of finishing a phase.
                   1346: .IP
                   1347: .I "Geometric interpretation of events.
                   1348: One must next decide how to represent
                   1349: the interesting events pictorially.
                   1350: An array of integers, for instance, might be represented by
                   1351: a sequence of numbers, a scatterplot of bullets, or a sequence
                   1352: of vertical bars.
                   1353: .IP
                   1354: .I "Rendering on a device.
                   1355: In our system, this is the job of
                   1356: .I movie
                   1357: and
                   1358: .I stills .
                   1359: .LP
                   1360: The sample program
                   1361: .CW is.gen
                   1362: identified interesting events and gave them
                   1363: a geometric interpretation in separate procedures
                   1364: within a single program.
                   1365: Alternatively, it may be more convenient
                   1366: to implement the various tasks as a pipeline of two programs:
                   1367: a generator program writes interesting events that
                   1368: are given a geometric interpretation by a program that writes
                   1369: a script file.
                   1370: .PP
                   1371: One usually prints a
                   1372: .CW click
                   1373: statement immediately after the event it marks.
                   1374: Sometimes, though, one draws additional objects to
                   1375: highlight the event, which are erased immediately after the
                   1376: .CW click .
                   1377: In that case, one uses a sequence like
                   1378: .P1
                   1379: @draw@ @event@ @E@
                   1380: @highlight@ @E@
                   1381: click E
                   1382: @remove@ @highlights@
                   1383: .P2
                   1384: .sp 1
                   1385: .LP
                   1386: .I "Sorting, Again."
                   1387: .PP
                   1388: We will return to the subject of
                   1389: sorting with a more interesting animation:
                   1390: a race of insertion sort versus quicksort.
                   1391: We will use the same insertion sort we saw earlier,
                   1392: and a quicksort described in Section 10.2 of |reference(programming pearls).
                   1393: The two sorting routines and their supporting functions
                   1394: are contained in this
                   1395: .I awk
                   1396: program:
                   1397: .P1
                   1398: .get race.gen
                   1399: .P2
                   1400: Quicksort is called as
                   1401: .CW "qsort(l,u)"
                   1402: to sort the subarray
                   1403: .CW x[l..u] .
                   1404: The function
                   1405: .CW draw
                   1406: represents the numbers to be sorted as vertical lines.
                   1407: The
                   1408: .CW BEGIN
                   1409: block sets
                   1410: .CW n ,
                   1411: initializes the array,
                   1412: draws the initial representation,
                   1413: and then calls a sort routine.
                   1414: As it stands, the code depicts a 50-element quicksort.
                   1415: .PP
                   1416: Some algorithm animation systems present races of programs
                   1417: by implementing a simple form of time slicing.
                   1418: To create a race in our system, we first ran the program into the file
                   1419: .CW qs.s .
                   1420: We then changed the final line in the
                   1421: .CW BEGIN
                   1422: section to call
                   1423: .CW isort ,
                   1424: and ran that into the file
                   1425: .CW is.s .
                   1426: Finally, we merged the two scripts into one with this
                   1427: .I awk
                   1428: program:
                   1429: .P1
                   1430: .get race.splice
                   1431: .P2
                   1432: The loop copies the script of insertion sort until it encounters a
                   1433: .CW click
                   1434: .CW comp
                   1435: statement; it then copies quicksort until it encounters the corresponding
                   1436: .CW click ,
                   1437: at which points it prints the
                   1438: .CW click
                   1439: statement.
                   1440: The variables
                   1441: .CW s1
                   1442: and
                   1443: .CW s2
                   1444: store the status of the most recent
                   1445: .CW getline s
                   1446: of the two files; the status is one if a record was found and
                   1447: zero if an end-of-file was encountered.
                   1448: When one file is exhausted, the remainder of the other is copied.
                   1449: (A production splicer should
                   1450: have a more graceful interface for naming the files and views.)
                   1451: .PP
                   1452: The resulting script file is an execution of the
                   1453: sorts in two parallel views, synchronized by comparisons:
                   1454: .INCLUDE race
                   1455: As before, insertion sort sifts each element into place in turn.
                   1456: This picture only hints at the operation of quicksort;
                   1457: insight into that algorithm requires the identification
                   1458: of interesting events beyond comparisons and swaps.
                   1459: Quicksort finishes after 240 comparisons, while insertion
                   1460: sort takes almost three times as long.
                   1461: For completeness, here is the
                   1462: .I stills
                   1463: input that produced the picture:
                   1464: .P1
                   1465: .get race.t
                   1466: .P2
                   1467: .sp 1
                   1468: .LP
                   1469: .I "Trees."
                   1470: .PP
                   1471: Here are pictures of a (nonbalanced) binary search tree after inserting
                   1472: 5, 10, 15 and 20 random integers in the range 0..999:
                   1473: .INCLUDE bst
                   1474: In the last two frames, the labels for node 3
                   1475: and 13 are squeezed too close together.
                   1476: The script was generated by this
                   1477: .I awk
                   1478: program:
                   1479: .P1
                   1480: .get bst.gen
                   1481: .P2
                   1482: The animation code consists of just three lines in the
                   1483: .CW insert
                   1484: procedure.
                   1485: .PP
                   1486: The pictures give insight into random binary search trees
                   1487: in spite of being rather ugly.
                   1488: The trees have two distinct failings: the depiction of
                   1489: individual nodes, and the layout of the entire tree.
                   1490: .PP
                   1491: A node is represented by its numeric value;
                   1492: each node is connected to its parent.
                   1493: If the shape of the tree is more important than
                   1494: the values it contains, one can delete the values entirely.
                   1495: We will shortly see a tree with more graceful edges.
                   1496: .PP
                   1497: The other aesthetic issue is the layout of the tree.
                   1498: The @y@-value is the depth of the node in the tree,
                   1499: which is a very robust choice
                   1500: (one could also use the time at which the node was inserted).
                   1501: The @x@-value in this example is simply the randomly generated value itself;
                   1502: there are many alternative choices.
                   1503: One could instead use the number of the node in an inorder traversal,
                   1504: which involves a multiple-pass algorithm:
                   1505: the tree is first built, then traversed and numbered, and the
                   1506: insertions are then reported with knowledge of the numbers.
                   1507: For this representation, it is crucial to separate the
                   1508: interesting events from their geometric representation;
                   1509: it is convenient to calculate these in two filters in a pipeline.
                   1510: .PP
                   1511: This animation of heapsort uses an alternative representation of trees.
                   1512: It was generated by a 50-line
                   1513: .I awk
                   1514: program.
                   1515: .INCLUDE heap
                   1516: Each snapshot shows the result of a
                   1517: .CW sift
                   1518: operation.
                   1519: The first four
                   1520: .CW sift s
                   1521: build the heap; subsequent
                   1522: .CW sift s
                   1523: maintain the unsorted elements as a heap.
                   1524: Arrows point from lesser elements to greater elements.
                   1525: .PP
                   1526: A node in the heap is represented by its value;
                   1527: lines between nodes have a single arrowhead and
                   1528: are chopped by twenty percent at each end.
                   1529: The root of the heap is at @(1/2,~-1)@,
                   1530: its two children are at @(1/4,~-2)@ and @(3/4, ~-2)@, their four
                   1531: children are at @(1/8,~-3)@, @(3/8,~-3)@, @(5/8,~-3)@, @(7/8,~-3)@, etc.
                   1532: .PP
                   1533: Other tree layouts proved useful in animating
                   1534: two algorithms dealing with parse trees.
                   1535: In both cases, a node's @x@-value was the minimum of the
                   1536: @x@-values among the node's descendants (equivalently,
                   1537: the @x@-value of its leftmost child); all edges were therefore
                   1538: either vertical or slanting down to the right.
                   1539: A random sentence generator built the tree left-to-right and top-down;
                   1540: just as in the binary search tree,
                   1541: the height of a node was one less than its parent.
                   1542: A parser built the tree in postorder and bottom-up:
                   1543: the height of a node was one greater than the
                   1544: maximum of the heights of its children.
                   1545: .sp 1
                   1546: .LP
                   1547: .I "A Graph Algorithm."
                   1548: .PP
                   1549: Prim's algorithm for computing the minimum spanning tree (MST)
                   1550: of a graph starts with a fragment consisting of a single vertex.
                   1551: It increases the fragment by adding the nearest vertex until all
                   1552: vertices are in the fragment, at which point it is the MST
                   1553: of the entire graph.
                   1554: This picture shows Prim's algorithm on the complete
                   1555: graph induced by a set of 50 planar points;
                   1556: the weight of an edge between two points is
                   1557: defined to be their Euclidean distance.
                   1558: .INCLUDE mst2
                   1559: The snapshots are taken every ten stages.
                   1560: .PP
                   1561: The obvious implementation of Prim's algorithm on an @N@-point
                   1562: set requires time proportional to @N sup 3@.
                   1563: Dijkstra discovered an elegant implementation of the algorithm
                   1564: with running time proportional to @N sup 2@:
                   1565: every point not in the fragment keeps a pointer
                   1566: to its nearest neighbor in the fragment.
                   1567: Here is Dijkstra's implementation on a ten-node planar graph:
                   1568: .INCLUDE mst1
                   1569: In this animation, nodes in the fragment are bullets, nodes
                   1570: not in the fragment are crosses, edges in the MST are
                   1571: .CW fat
                   1572: lines, and the nearest neighbors are pointed to by arrows.
                   1573: .PP
                   1574: These two sequences illustrate two
                   1575: styles of drawing graphs with our system.
                   1576: Dots and lines are sufficient for simple algorithms,
                   1577: while various symbols and line options can depict subtle processes.
                   1578: .PP
                   1579: The geometric nature of the above graphs made them easy to lay out.
                   1580: Laying out a general graph is very hard.
                   1581: If the graphs in your applications are specialized (such as trees),
                   1582: you might exploit that structure to compute an effective layout.
                   1583: A graph of @N@ vertices can be easily represented
                   1584: by an @N times N@ matrix in which the @i,j@-th element
                   1585: represents the edge from vertex @i@ to vertex @j@;
                   1586: that is useful for insight into some graph algorithms.
                   1587: If you have access to a program that produces good layouts of general graphs,
                   1588: you might use that program to compute positions of vertices,
                   1589: and then feed those into our system.
                   1590: .sp 1
                   1591: .LP
                   1592: .I "A Memory Allocator."
                   1593: .PP
                   1594: The
                   1595: .I develop
                   1596: program uses the
                   1597: .I malloc
                   1598: memory allocator for several of its data structures.
                   1599: We augmented
                   1600: .I develop 's
                   1601: calls to the allocator with data gathering
                   1602: routines to produce an animation;
                   1603: here is the final snapshot.
                   1604: .KF
                   1605: .INCLUDE malloc
                   1606: .KE
                   1607: The left frame is the arena of storage from which memory is allocated.
                   1608: Memory blocks are represented by lines,
                   1609: low addresses are at the bottom of the picture, and
                   1610: the picture is 1024 bytes wide.
                   1611: The right frame is a histogram of the sizes of memory currently
                   1612: allocated; there is a dot for each element, a vertical bar every ten
                   1613: positions to help counting, and the maximum value is in the lower right corner.
                   1614: .PP
                   1615: This snapshot was taken at the end of execution of
                   1616: .I fdevelop .
                   1617: The histogram shows two large blocks
                   1618: of 20,000 and 40,000 bytes, 96 blocks of size 16, and 96
                   1619: slightly larger blocks (the blocks of size 16 are symbol table records;
                   1620: each points to an allocated string).
                   1621: The arena shows the two huge pieces (the larger is higher)
                   1622: and a gap above the smaller (memory allocated by
                   1623: procedures that didn't call our augmented
                   1624: .I malloc ).
                   1625: The remainder of the arena is allocated efficiently.
                   1626: .PP
                   1627: A movie like this helped us find a bug in
                   1628: .I fdevelop :
                   1629: an early version allocated the symbol table nodes but did not
                   1630: .I free
                   1631: them.
                   1632: This problem manifested itself in an overloaded arena and a huge
                   1633: spike in the histogram at size 16.
                   1634: .PP
                   1635: The
                   1636: .I fdevelop
                   1637: program interacts with the storage allocator only through
                   1638: the two routines
                   1639: .I emalloc
                   1640: and
                   1641: .I efree .
                   1642: We animated the storage allocator by modifying those routines:
                   1643: .P1
                   1644: .get malloc.c
                   1645: .P2
                   1646: They write on the named file output lines of two types:
                   1647: .P1
                   1648: m @address@ @length@
                   1649: f @address@
                   1650: .P2
                   1651: The first line denotes that a
                   1652: .I malloc
                   1653: of the given length returned the given address;
                   1654: the second marks a
                   1655: .I free .
                   1656: .PP
                   1657: The resulting history file contains the interesting events;
                   1658: they are given a geometric interpretation by a subsequent program.
                   1659: Here is a simple program that generates only the arena view
                   1660: from the script file:
                   1661: .P1
                   1662: .get malloc.awk
                   1663: .P2
                   1664: The
                   1665: .CW BEGIN
                   1666: block initializes variables,
                   1667: the actions for
                   1668: .CW m
                   1669: lines draw memory, and those for
                   1670: .CW f
                   1671: lines erase memory.
                   1672: The variable
                   1673: .CW s
                   1674: is the starting byte of a block;
                   1675: .CW e
                   1676: is the ending block.
                   1677: The variables
                   1678: .CW sx
                   1679: and
                   1680: .CW sy
                   1681: are the @x@ and @y@ positions of the starting byte, and
                   1682: similarly for
                   1683: .CW ex
                   1684: and
                   1685: .CW ey .
                   1686: If the block fits on one line, then only a single line fragment
                   1687: need be drawn; otherwise, fragments of three types are needed.
                   1688: .PP
                   1689: The complete program for generating scripts
                   1690: from history files is 56 lines of
                   1691: .I awk .
                   1692: To ease tracing the action in the arena, it marks a
                   1693: .I malloc
                   1694: with an
                   1695: .CW x
                   1696: and a
                   1697: .I free
                   1698: with an
                   1699: .CW o .
                   1700: The histogram view is embellished with bars and the maximum value.
                   1701: There is room for further elaborations;
                   1702: one might, for instance, want to put either or both of
                   1703: the axes of the histogram on logarithmic scales.
                   1704: .sp 1
                   1705: .LP
                   1706: .I "Dynamic Statistical Displays."
                   1707: .PP
                   1708: Rick Becker constructed this display of air pollution
                   1709: in the Northeast United States:
                   1710: .INCLUDE ozone
                   1711: The data was gathered hourly on
                   1712: a single summer day in the early 1970's.
                   1713: The radius of each circle is proportional to the ozone
                   1714: reading (a common measurement of air pollution)
                   1715: at one of 32 stations in New Jersey,
                   1716: New York, Connecticut, and Massachusetts.
                   1717: The radius of the clock denotes the maximum ozone level prescribed
                   1718: by the Environmental Protection Agency;
                   1719: its hour hand goes from 7:00 AM to midnight.
                   1720: .PP
                   1721: This display shows how New York City's
                   1722: air pollution is blown to the northeast.
                   1723: Becker and his colleagues prepared a similar movie in the
                   1724: early 1970's using the technology of the day;
                   1725: it required several weeks of programming time, then
                   1726: a weekend with a movie camera to make the final film.
                   1727: He built this display from the same data in a couple of hours,
                   1728: then prepared a video tape of the
                   1729: resulting movie in under thirty minutes.
                   1730: The original movie was a bit nicer (it drew the background
                   1731: map and the circles in two different colors),
                   1732: but the new movie is just as useful, and provides stills for free.
                   1733: ......
                   1734: .NH
                   1735: Living With The System
                   1736: .PP
                   1737: The system that we have described is the
                   1738: bare bones of an animation environment.
                   1739: We have found that the most fruitful way of enhancing the
                   1740: environment is not by modifying the primary programs,
                   1741: but rather by using small filters that interact with the
                   1742: various files in the system.
                   1743: .PP
                   1744: We showed earlier, for instance, a race of two sorting algorithms.
                   1745: While other animation systems implement races with
                   1746: a general mechanism for time sharing,
                   1747: we did the job with a small
                   1748: .I awk
                   1749: program that merges two files.
                   1750: Our system does not have a facility for counting clicks;
                   1751: rather, we use filters such as
                   1752: .P1
                   1753: grep 'click comps' | wc
                   1754: .P2
                   1755: to see how many comparisons were made.
                   1756: We will even admit to using text editors to make minor changes
                   1757: to both script and intermediate files.
                   1758: .PP
                   1759: We have built several useful filters in addition to
                   1760: .I merge .
                   1761: The program
                   1762: .I view.clicks
                   1763: prints a summary of the views and clicks used in a script file;
                   1764: it is helpful as one is preparing a
                   1765: .I stills
                   1766: file.
                   1767: Its implementation uses the intermediate file described
                   1768: in Appendix I:
                   1769: .P1
                   1770: .get view.clicks
                   1771: .P2
                   1772: The first step of the shell script is to develop the script file;
                   1773: the subsequent
                   1774: .I awk
                   1775: program then reads the resulting intermediate file.
                   1776: The first pattern/action pair prints for each view its
                   1777: name and the @x@ and @y@ ranges in the script file.
                   1778: The second pair builds a string of all clicks from the
                   1779: define click statements, and the third pair prints that
                   1780: string and exits at the first non-define statement.
                   1781: .PP
                   1782: The program
                   1783: .I show.clicks
                   1784: takes a script file as input;
                   1785: its output is a new script file containing all information in
                   1786: the input and, in addition, a new view named
                   1787: .CW click.count
                   1788: in which the various clicks are counted.
                   1789: This is useful for preparing
                   1790: .I stills
                   1791: files and for debugging.
                   1792: Its input is a script file,
                   1793: either named explicitly or as the standard input.
                   1794: Here is the code:
                   1795: .P1
                   1796: .get show.clicks
                   1797: .P2
                   1798: The second pattern/action pair stores the name of the current view,
                   1799: and the fourth action copies each line onto the output file.
                   1800: The first pattern/action pair supplies a default view name, if needed.
                   1801: .PP
                   1802: The work is done when the third pattern recognizes a
                   1803: .CW click
                   1804: statement.
                   1805: The
                   1806: .CW if
                   1807: statement puts the click name in
                   1808: .CW cname ,
                   1809: and the
                   1810: .CW print
                   1811: statement switches to the new view.
                   1812: The second
                   1813: .CW if
                   1814: statement is executed when a new
                   1815: .CW click
                   1816: statement is seen; it assigns it a number and prints out the
                   1817: click name, once and for all.
                   1818: The two following statements rewrite the appropriate count
                   1819: and place a bullet next to it.
                   1820: The final statement returns to the current view.
                   1821: .PP
                   1822: One can use the ideas in
                   1823: .I show.clicks
                   1824: to process lines in the script file of the form
                   1825: .P1
                   1826: @name@ = @value@
                   1827: .P2
                   1828: The output script file has a new view named
                   1829: .CW variables ;
                   1830: it contains the name of each variable mentioned and its current value.
                   1831: .PP
                   1832: Larger filters have also proven useful.
                   1833: For instance, we built a set of tools to render animations
                   1834: of three-dimensional lines and text
                   1835: (circles and rectangles were not supported).
                   1836: The primary program translated a three-dimensional script into a
                   1837: standard script that contained two two-dimensional views for
                   1838: each three-dimensional view; the resulting
                   1839: .I movie
                   1840: and
                   1841: .I stills
                   1842: were suitable for viewing with standard stereo viewers.
                   1843: Support programs included a filter for rotating a view
                   1844: around a given line.
                   1845: .PP
                   1846: The
                   1847: .I movie
                   1848: and
                   1849: .I develop
                   1850: programs are in fact simple shell scripts that call filter
                   1851: versions named
                   1852: .I fmovie
                   1853: and
                   1854: .I fdevelop .
                   1855: You may find it convenient to rewrite those shell scripts for
                   1856: your environment.
                   1857: .SH
                   1858: Acknowledgements
                   1859: .PP
                   1860: We are deeply indebted to Howard Trickey;
                   1861: he gave us invaluable advice for getting a minimal
                   1862: animation facility working in the Sun environment,
                   1863: then finished the job properly.
                   1864: He subsequently made it all work under the X window system.
                   1865: Andrew Hume and Jane Elliott made possible
                   1866: our first experiments with animation.
                   1867: Our early users, Rick Becker and Chris Van Wyk,
                   1868: gave us bug reports and suggestions for improvements.
                   1869: Eric Grosse, John Linderman, Doug McIlroy,
                   1870: Steve Mahaney, Howard Trickey, and Chris Van Wyk
                   1871: made helpful comments on this paper.
                   1872: .SH
                   1873: References
                   1874: .LP
                   1875: |reference_placement
                   1876: .sp 100
                   1877: .BP
                   1878: .SH
                   1879: Appendix I \(em Intermediate Files
                   1880: .PP
                   1881: This appendix defines the intermediate files produced by
                   1882: .I develop .
                   1883: The files are easier to process than the corresponding script files.
                   1884: For instance,
                   1885: names are converted to small integers,
                   1886: floating point numbers are scaled to integers in 0..9999,
                   1887: and commands are abbreviated to single letters.
                   1888: .PP
                   1889: A line whose first non-blank character is
                   1890: .CW #
                   1891: is a comment.
                   1892: .PP
                   1893: An intermediate file begins with define statements
                   1894: that give the names of the views and the clicks:
                   1895: .P1
                   1896: d v @vnum@ @viewname@ @minx@ @miny@ @maxx@ @maxy@
                   1897: d c @cnum@ @clickname@
                   1898: d p @any@ @text@
                   1899: d p e
                   1900: .P2
                   1901: Fields are separated by tab characters.
                   1902: Both views and clicks are numbered 0, 1, 2, ....
                   1903: The four final numbers on a view line tell the
                   1904: range of the coordinates in the original script file.
                   1905: A line that begins with
                   1906: .CW "d p"
                   1907: is a ``pragma''; both
                   1908: .I movie
                   1909: and
                   1910: .I stills
                   1911: currently ignore all such lines.
                   1912: The defines appear at the front of the file in
                   1913: the order views, clicks, pragmas, then
                   1914: the ``end of defines'' pragma
                   1915: .CW "d p e" .
                   1916: .PP
                   1917: The geometric commands for lines, boxes, circles and text
                   1918: are mapped to the following:
                   1919: .P1
                   1920: g @slotnum@ l @vnum@ @opts@ @x sub 1@ @y sub 1@ @x sub 2@ @y sub 2@
                   1921: g @slotnum@ b @vnum@ @opts@ @x sub 1@ @y sub 1@ @x sub 2@ @y sub 2@
                   1922: g @slotnum@ c @vnum@ @opts@ @x@ @y@ @rad@
                   1923: g @slotnum@ t @vnum@ @opts@ @x@ @y@ @text@ @string@
                   1924: .P2
                   1925: Objects that are never erased have slot number 0;
                   1926: other objects are placed in ``slots'' that can hold at most one object.
                   1927: The third field is the type of geometric object;
                   1928: the fourth field is the view number.
                   1929: All @x@ and @y@ values are normalized to integers in the range 0..9999.
                   1930: There is a single separating tab before the (unquoted) text string.
                   1931: Options are given as a string of characters,
                   1932: whose length and interpretation are summarized as:
                   1933: .P1
                   1934: .ps -2
                   1935: .vs -3
                   1936: OBJECT POS     NAME    ABBREV
                   1937: text   1       center  c
                   1938:                ljust   l
                   1939:                rjust   r
                   1940:                above   a
                   1941:                below   b
                   1942:        2       medium  m
                   1943:                small   s
                   1944:                big     b
                   1945:                bigbig  B
                   1946: line   1       solid   s
                   1947:                fat     f
                   1948:                fatfat  F
                   1949:                dotted  o
                   1950:                dashed  a
                   1951:        2       -       -
                   1952:                ->      >
                   1953:                <-      <
                   1954:                <->     x
                   1955: box    1       nofill  n
                   1956:                fill    f
                   1957: circle 1       nofill  n
                   1958:                fill    f
                   1959: .vs +3
                   1960: .ps +2
                   1961: .P2
                   1962: For instance, the options for a text string are described
                   1963: by two characters giving its position and its size;
                   1964: .CW small
                   1965: .CW center
                   1966: text has the option string
                   1967: .CW cs .
                   1968: Further options may be added at the right end of the string;
                   1969: subsequent programs should ignore letters they don't expect.
                   1970: .PP
                   1971: A click statement is represented as
                   1972: .P1
                   1973: c @cnum@
                   1974: .P2
                   1975: .PP
                   1976: An erase statement is translated into
                   1977: .P1
                   1978: e @line@ @repeated@ @here@, @except@ e @italic "for"@ @leading@ g
                   1979: .P2
                   1980: A processor may choose to implement this statement using
                   1981: either the geometric description or the slot number.
                   1982: .PP
                   1983: A
                   1984: .CW clear
                   1985: statement (which erases all objects in a view)
                   1986: is translated into a pair of starting and ending ``blank''
                   1987: commands that bracket a sequence of erase statements:
                   1988: .P1
                   1989: b s @vnum@
                   1990: b e @vnum@
                   1991: .P2
                   1992: The erase statements together clear the view.
                   1993: A processor may choose to implement the
                   1994: .CW clear
                   1995: either by ignoring the
                   1996: .CW b
                   1997: commands and letting the erase statements
                   1998: take their course or by explicitly processing the start
                   1999: command and then ignoring
                   2000: .CW e
                   2001: commands until encountering the
                   2002: .CW "b e"
                   2003: line.
                   2004: .PP
                   2005: As an example, running
                   2006: .CW develop
                   2007: on this trivial script file
                   2008: .P1
                   2009: line 1 2 3 4
                   2010: text small above 5 6 "Hello, world."
                   2011: click stage
                   2012: clear
                   2013: .P2
                   2014: produces this intermediate file:
                   2015: .P1
                   2016: d      v       0       def.view        1       2       5       6
                   2017: d      c       0       stage
                   2018: d      p       e
                   2019: g      1       l       0       s-      0       0       4999    4999
                   2020: g      2       t       0       as      9999    9999    Hello, world.
                   2021: c      0
                   2022: b      s       0
                   2023: e      1       l       0       s-      0       0       4999    4999
                   2024: e      2       t       0       as      9999    9999    Hello, world.
                   2025: b      e       0
                   2026: .P2
                   2027: .PP
                   2028: Here is a summary of the commands in the intermediate language:
                   2029: .P1
                   2030: # @comment@
                   2031: b s @vnum@
                   2032: b e @vnum@
                   2033: c @cnum@
                   2034: d v @vnum@ @viewname@ @minx@ @miny@ @maxx@ @maxy@
                   2035: d c @cnum@ @clickname@
                   2036: d p @any@ @text@
                   2037: d p e
                   2038: e @line@ @repeated@ @here@, @except@ e @italic "for"@ @leading@ g
                   2039: g @slotnum@ l @vnum@ @opts@ @x sub 1@ @y sub 1@ @x sub 2@ @y sub 2@
                   2040: g @slotnum@ b @vnum@ @opts@ @x sub 1@ @y sub 1@ @x sub 2@ @y sub 2@
                   2041: g @slotnum@ c @vnum@ @opts@ @x@ @y@ @rad@
                   2042: g @slotnum@ t @vnum@ @opts@ @x@ @y@ @text@ @string@
                   2043: .P2

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.