CA1274310A - System for animating program operation and displaying time-based relationships - Google Patents

System for animating program operation and displaying time-based relationships

Info

Publication number
CA1274310A
CA1274310A CA000538545A CA538545A CA1274310A CA 1274310 A CA1274310 A CA 1274310A CA 000538545 A CA000538545 A CA 000538545A CA 538545 A CA538545 A CA 538545A CA 1274310 A CA1274310 A CA 1274310A
Authority
CA
Canada
Prior art keywords
self
encoder
message
new
receiver
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Expired - Fee Related
Application number
CA000538545A
Other languages
French (fr)
Inventor
Robert A. Duisberg
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Tektronix Inc
Original Assignee
Tektronix Inc
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Tektronix Inc filed Critical Tektronix Inc
Application granted granted Critical
Publication of CA1274310A publication Critical patent/CA1274310A/en
Anticipated expiration legal-status Critical
Expired - Fee Related legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F3/00Input arrangements for transferring data to be processed into a form capable of being handled by the computer; Output arrangements for transferring data from processing unit to output unit, e.g. interface arrangements
    • G06F3/01Input arrangements or combined input and output arrangements for interaction between user and computer
    • G06F3/048Interaction techniques based on graphical user interfaces [GUI]
    • G06F3/0487Interaction techniques based on graphical user interfaces [GUI] using specific features provided by the input device, e.g. functions controlled by the rotation of a mouse with dual sensing arrangements, or of the nature of the input device, e.g. tap gestures based on pressure sensed by a digitiser
    • G06F3/0489Interaction techniques based on graphical user interfaces [GUI] using specific features provided by the input device, e.g. functions controlled by the rotation of a mouse with dual sensing arrangements, or of the nature of the input device, e.g. tap gestures based on pressure sensed by a digitiser using dedicated keyboard keys or combinations thereof
    • G06F3/04895Guidance during keyboard input operation, e.g. prompting
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F30/00Computer-aided design [CAD]
    • G06F30/20Design optimisation, verification or simulation
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F2111/00Details relating to CAD techniques
    • G06F2111/04Constraint-based CAD

Abstract

Abstract In a computerized simulation system, the behavior of a model comprising a group of interrelated objects in an object oriented programing environment is defined by a constraint network including temporal constraints, which the future behavior of the model must satisfy following triggering events. Following a triggering event, time stamped representations of messages are created and stored in a queue. The value of a time variable representing time is progressively incremented and the message indicated by each enqueued representation is sent to the model as the value of the time variable surpasses the value of the time stamp of the representation. The message representations and the value of their time stamps are created according to the requirements of the constraint network such that the messages cause the model to perform the appropriate actions at the appropriate times in order to satisfy the temporal constraints defined by the constraint network.

Description

~ ~7~3~

SYSTEM POR ANIMATING PROGRAM OPERATION AND
DISPIAYING TIME ~D REL~TICNSHIPS

BACKGROUND OF THE INVENTION
This inven~ion relates in qeneral to computer-based simulation systems and in particular to a system employing constraint satisfaction for temporizing a simulation.
Computer programs have long been used for simulating the behavior of a "real world"-apparatus or process and an "animation" is a simulation which includes a graphical display representing the behavior of the apparatus or process. A computer simulation of a bouncing ball might include an algorithm for computing data representing the ver-tical position of the ball as a function of time.
The data may then be used in a display.
In addition to simulating real world appearance of things, animation is a power~ul means for representing the inner workings of a process which in itself does not have a visual aspect. For example, data structures are often represented by t two dimensional diagrams because they are most easily apprehended in spatial, visual form rather than as a textual description or bits in a memory bank. By extension, understanding obscure algo-rithms operating on data structures could be assisted ~hrough simulation of dynamic motion in such diagrams and images.
Much of the appeal of animation is in being able to simulate the behavior of an experimental design to "see how it works." For instance, if an algorithm sorts bars by length, it is helpful to see the bars move about as they are sorted. How-ever, this appeal is dlminished if an animation is : :

~, . . . . . .............................. .

: . : , 3~

laborious to construct.
Experience has shown that about 80% of the code in computer-based animation merely implements animation graphics, even in an object oriented computer language like Smalltalk-80 ~hereinafter referred to as "Smalltalk") which offers a high level graphics interface. ("Smalltalk-80" is a registered trademark of - the Xerox Corporation and the Smalltalk computer language is described in the book SMALLTALK-80 The Lanquage and Its Implementation, by Adele Goldberg and David Robson, published in 1983.) Animation difficulties are further magnified if one insists an animation must be more than pictures on a screen, and that the pictures should create the illusion of things they represent for allowing a user to interact with them. For example, an animated spring desirably acts like a real one in that a user should be able to "push" it or "pull" it and observe the response.
This means the animation must be designed as a fully interactive interface and the user should be able to gain access to the code which drives the animation.
The requirements outlined above suggest the components for assembling an animation should be self-contained ob]ects simulating "things" they represent.The internal state of each object should be self-consistent, in keeping with the real-world laws governing the item being simulated, and the picture of the object should change state consistently, according to the rules of some representational scheme. One may think of an animation as the creation of an image whose state is "constrained" to bear some specified relation to the state of an object simulating a "thing".

. . . . . .

.
. ' ' .,- ' ,~ ~' . .
.
.. . . .: ~ ,.

This need for consistency of state and repre-sentation ~akes the use of a constraint language desirable to implement animation. Constraint languages allow the programmer to declare relations that a systen~ of objects must satisy; it is the job of constraint satisfaction algorithms to auto-matically find a way to satisfy those relation-shipso The declarative character is attractive sinc~ it tends to reduce the creation of an anima-tion to the writing of an executable specification, which one may expect to be simpler than writing out detailed graphics instructions in an imperative language.
One existing constraint oriented computer programming system, "ThingLab", is described in "ThingLab -- A Constraint-Oriented Simulation Laboratory", by ~. H. Borning, published July, 1979 by Xerox Corporation, in Xerox Palo Alto Research Center Report SSL-79-3, and in an article entitled "The Programming Langua~e Aspects of ThingLab, A
Constraint-Oriented Simulation Laboratory", also by A.H. Borning, published in ACM Transactions on Programm n~ Languages and Systems, October, 1981.
Constraints in ThingLab are implemented as objects ~5 that represent some relation as a predicate and contain a variety of methods as code fragments - which can be used to establish the relation under different circumstances, depending on what is known. For example, a constraint predicate that a = b ~ c would contain the expressions a <- b ~ c, b <- a - c and c <- a ~ b, any one of which may be used to satisfy the constraint. But depending upon what values are known or have just been changed, only one expression may be appropriate.
The goal of constraint satisfaceion techniques is :

~ 7L~3~0 to choose and order appropriate methods so that relati~ns throughout a network of constraints are reestablished following a change.
The act of programming in a constraint oriented system consists o~ Rpecifying, preferably in a graphical way, the interconnections am~ng objects containing code fragments embodying the functionality of the part. The job of the con-straint system then is to sort out and ordex those code fragments so that the composite shows the desired behavior of a coherent whole. One of ~he most attractive features of constraint languages is that they are fundamentally descriptive as opposed to imperative. The drudgery of hand-coding anima-tions is in having to give explicitly imperative commands for everything that is to happen and appear on the screen. It is easier to merely describe in general terms how things should appear and let the system generate the code that would make it so.
The animated, dynamic responses of a system ~- like ThingLab are user driven in response only to a - command to "satisfy all constraints with these values now". Constraints in ThingLab are "static"
- 25 rather than "temporal" in that they are satisfied in the same way for all time and are independent of time. There can be no history dependent specifica-tions because there is no history.
' SUMMARY OF THE INVENTION
According to the present invention, a con-straint system models time in order to provide meaningful and realistic animation. Time requires special treatment and cannvt simply be inserted as another variable in a constraint relation. Static .: .. .. - , : - . . : - : - ., :
.
', -~

-~ ~7~

constraints have the property of satisfying them-selves in multiple directions depending on computa-tional circumstances. If time were treated as a static constraint, time could be set forward sr backward erratically because of changes occurring to values dependent on time, unless time were given special treatment to insure its steady monotonic advance. Also there is a disjunction between the -~ inherently discrete frame-by-frame, time-slice - 10 character of computation, and the kinds o con-tinuum statements one would like to make in describing rates of change, eOg. V = dx/dt. One must consider how to provide a system to construct discrete approximations of continuous processes, and how to treat any err~rs in these approximations.
According to one aspect of the invention, a gxoup of interactive elements is simulated by utilizing a model embodied within an object oriented computer programming system and the temporal ~ehavior of the model is controlled by a further time management o~ject. The time manage-ment object is adapted to execute a procedure for incrementing a simulation "time" by adjusting the value of a variablP representing time, and main-tains an 'levent queue" for storing events, wherein an event comprises a representation of a message and a "time stamp" indicating a time at which the message is to be sent to the model. The time management object is further adapted to transmit any message represented by an event in the event queue to the model when time represented by the time varlable surpasses the time indicated by the time stamp associated with the message. Each such message sent to the model causes the model to carry out some procedure.

. ~ .
, :.
, . - , . . .
.

3~(~

The model is made to respond to a triggering message in a temporal fashion by storing one or more events in the event queue in respon~e to the triggering message. Each event stored in the event queue includes a time stamp indicating a future time at which a response message is t~ ~ sent to effect a particular response. As the ~i~e manage-ment object increments the time varia~le, the response messages described by the enguæ~ed events are sent in the order that th~ events ~ time stamped. Thus the model can carry ou~ ~n action or a sequence of actions in the future in ~esponse to a current triggering event.
According to another aspect of the ~resent invention, the behavior of the model i~ described according to a set of temporal constraints on the future behavior of the model (e.g., on $he assign ment of values to variables it controls) which are invoked in response to a triggering m~s age. When a triggering message is sent to the m~del f~r which no procedure has b~en compiled for satisfying tem-poral constraints, a response proced~r~ is com-piled for execution by the time management object which causes one or more events to be ~tored in the event queue. Each of these events in~ludes a time stamp indicating a future tim~ and a ~presentation of a temporal constraint satisfaction message to the model for causing the m~el to s~isfy the requirements of the tempor 1 constrai~ts triggered by the triggering message.
- Thereafter, as the time managemP~* object increments the simulation time, it tr~nsmits to the model a message described by an event in the event queue whenever the simulation time surpasses the time indicated by the tim~ stamp of the event, :, ~
:
. .
.' : , : '- .

1;2743~

thereby causing the model to carry out an ~ction in satisfaction of its temporal constraints.
- Thus the present invention not only temporizes the behavior o~ the model by providing the time S management object for controlling the actions of the model to be performed at a specified ~uture time, it also automatically determines what those actions will be in order to satisfy a set of temporal constraints on the behavior of the model.
It is accordingly an object of the present invention to provide a method for controlling the behavior of a model embodied in an object oriented computer programming system such that the model operates in satisfaction of a set of one or more temporal constraints.
The subject matter of the present invention is particularly pointed vut and distinctly claimed in the concluding portion of this specification.
However, both the organization and method of opera-
2~ tion of the invention, together with fuxther advan tages and objects thereof, will best be undexstood by reference to the following description taken in connection with accompanying drawings.

BRIEF DESCRIPTION OF THE DRAWINGS
FIGS. 1-17 depict displays on a computer graphics terminal illustrating the operation of the present invention.

DETAILED DESCRIPTION
The preferred embodiment of the present inven-tion is implemented as an improvement to the ThingLab constraint satisfaction programming system, which in turn is based on the Smal~talk prvgramming language. Accordingly, the basic prin - . , . ~ .

-- ' - , - ' ~ : . ' - ' : ~ :

. ~ ' ' '
3~

ciples of Smalltalk and ThingLab wi]l be briefly discussed in order to provide a foundation for the detailed description of the present invention.
Smalltalk is an object oriented computer pro-gramming language wherein computer software is organized into "objects" each comprising a block of program instructions describing various computer opPrations ("methods") to be performed in response to "messages" sent to the object. Such operations include, for example, the manipulation of variables and the transmission of messages to other objects.
The "state" of an object is defined in terms ffl the values of variables that it controls and t~e meth~ds associated with each object define its "behavior" in response to the messages it receives.
Thus one may "program" in the Smalltalk language by writing individual blocks of code each of which defines (or creates) an object.
The Smalltalk programming language can be used to facilitate the modeling of interactive systems in that each component of the system can be modeled with an object, the behavior of each component being simulated by the methods of the corresponding object and the interactions between components being simulated by the messages transmitted between objects. A user may also communicate with an object through its image on a computer terminal screen, utilizing a mouse to control a cursor on the screen to point to the object and buttons on the mouse or a keyboard to transmit messages to the object~ An object may also provide information to the user through its image on the screen, using data readouts or graphical changes to the object image. Although the object oriented environment of Smalltalk makes simulation development morm intui-.
' ' ~ ' , ' ': ', ' :
' ~7~3~

tive, Smalltalk programming may be considered as relatively difficult to learn~
ThingLab is a "higher level" programming language based on Smalltalk wherein a user may specify the hehavior of a system of interrelated objects by indicating "constraints" ~hat the state of each object must satisfy, rather than by directly encoding the methods which define or con-trol each object's behavior. Once the constraints are specified, ThingLab generates the necessary code for methods which cause the network to satisfy the constraints. In ThingLab, a constraint is itself implemented as an object "owned" by an object being constrained, the constraint object comprising a set of code fragments which can be used to establish various methods for satisfying the constraint. For example, an object might ~e required to control the values of three variables (a, b, and cl such that a = b ~ c. Accordingly, the associated constraint object would contain the expressions a <- b t C~ b ~- a - c, and c <- a - b, any one of which may be used to satisfy the constraint. But depending upon which values are known or have just been changed, only one of the three methods for satisfying the con-straint may be appropriate.
When a system of interrelated objects is specified in terms of a netwoxk of constraints, a change in state of any one ob~ect ~ay trigger changes in the states of other objects in oxder to satisfy the constraint network. ThingLab chooses and orders appropriate methods or each object so that relations throughout the network of con-straints are reestablished after a change to the constraint network. ~

: .~, , , ~ : .

. , ~, ~ .

.~ .

~L~7~

In ThingLab, the state of such a ~ystem of objects changes only when a constraint is changed or when the value of a variable i5 changed by some stim~lus event~ However, ~n object cann~t be "constrained" to behave in a temporal fashion by changing state at some ~uture time in response to some event which happens now; but rather can only be constrained to fully respond ~now" to an event that happens now~ Th~refore ThingLab is not suitable, for example, for modeling an RC network since the behavior of a capa~itor in such a network is necessarily temporal. When a voltage ~cross a capacitor changes abruptlyi the current through the capacitor changes not abruptly but smoothly over time a~ording to the constraint relation that I = C~dV/dt.
In accordance with the preferred embodiment of the present invention ThingLab i5 utilized as the basis of a programming ~ystem, hereina~ter referred to as ~Animus~. A Smalltalk li~ting implementing Animus withîn the ThingLab envir~nment is included as Appendix I to this application. Like ThingLab, Animus permits a user to describe systems of Smalltalk objects according to the static con-straints that they must ~a~isfy, but in addition thereto Animus also permits 8y6tem~ to be described in terms of "temporal constraints~ wherein objects are constrained to carry ou~ one or more actions in the future in response to a stimulus event ~ 30 occurring in the present.
-. The Animus system is well suited to creating .~ animated simulations of physical systems. Con-tinuous physical processes may be described by differential equations, as fox examplç the equa-tions of mvtion for a mechanical sy~tem~ ~nimus .
.:
~'. ' ~ ', ' , . . .
.

.' ' :- : ; ~ ' ' . :
- :
- : :-' .,., ~ . ~ .

~ ~ 27~3~LV

provides the Smalltalk class TimeDifferenti~l-Constraint which allows the user to specify such dif f erential equations as constraints on the system's behavior. tStandard Smalltalk typogra~
phical conventions are used throughout this appli-cation. Class names are capitali~ed and may be shown in bold face while instance variable names begin in lower case.) The mechanism contained in TimeDifferentialConstraint satisfies a constraint by automatically generating and executing a finite difference approximation to the behavior specified.
Thus, for example, in the definition of a class ~echanicalNode one may find the constraint that v = dx/dt. That is, the prototypical instance of Me~hanicalNode has an instance variable repre-senting a position whose value is constrained, as time advances, to be derived from the value o the instance variable for velocity. These constraints are "simple" because the response to satisfy them consists of a single event to adjust the object's state in the next instant, as contrasted with a more complex animation response such as sending an icon out on a trajectory of many step-wise time sequenced moves.

Typical Operation There will first be described a number of examples of how the present invention might be used, followed by a more in-depth discussion of implementation. Suppose we wished to demonstrate or investigate the behavior sf a capacitor dis-charging through a resistor. Referring to FIG. 1, - showing an "Animus Browser window" 10 displayed on the screen ~f a computer terminal, we woul~ begin by defining a new prototype class, selecting ` :

--, ' ' , . . :

.
, .~7~3 ~ 2 ~define new thing" from a m~nu that pops up with a mouse button click in a first pane 12 of window lOo A dialog window then appears and asks for the nam~
of the new prototype elass, to which we respond by using a keyboard to type in ~RCn7 The line ~RC"
will then appear in the first pane 12 a~ part o~ a list of prototypes. We ~elect "RC" using the ~ouse and begin to build a prototypical RC network by selecting Upicture~ in a second pane 14 listing formats, and ~insert~ in a third pane 16 listing operations. Operations of this general type are common to ThingLab.
Prototype constraint classes for electronic components are advantageously provided in a ~kitN
o~ ~uch classes provided within Animus and includes such things as capacitors, inductors, oscillo-~copes~ and signal generators, with ti~e dependent behavior built in~
A resistor prototype kit ~omponent, for example, incl`~des the necessary Smalltalk ~ode for : controlling the display o~ a representation o~ a :. resistor on the screen as well as code for ma~n-taining variables describing the st~te of the resi~
tor (~uch as its resistance, ~erminal voltages and current through the r0sistor) and code describing the behavior of a resistor in ~erms of constrain~s its variables must ~atisfy le~g. Ohm'Q law). The Ohm's law constraint (V ~ IR) describing the behavior of a resis~or is ~non-temporal~ in tha~ it ~oes not ~- 30 involve time: a resistor fully responds to a change - in one variable ~such as terminal voltage~ by instantaneously changing one or more other variables (such as current or another terminal ~oltage) in ~rder tha~ the constrain~ a~i~fied. The prior art ThingLab ~ystem ~nclude~ kit components such as . .
' :. , ' - ' ' ':

, ~ ~

resistors which have non-temporal constraints7 On the other hand, constraints defining a capacitor have a temporal a~pect because a capaci-tor behaves in a temporal fashion. The relation~
~hips between voltage, current, and charge variables which describe the state of a capaci~or are modeled by di~erential equations involving time and therefore a change in any of ~he~e variables must cause a time depenaent change in one or more of the other variable~ in order to ~atisfy the constraints which define the behavior of the capacitor. Thus, in addition to the necessary Small~alk code for ~ontrolling the display of a re~resentation of a capacitor on the screen, ~or maintaining variables d~cribing the ~tate of the capacitor and for describing non-temporal con-straints on the behavior o a kit ~omponent a~
provided for in ~he prior art ThingLab system, a proto~ype kit component such as a capacitor desirably also includes code describing ~he tem-poral constraints on the behavior of the ~apacitor.
This ~dditional code, beyond what is pre~ently included ~n Thin~ab kit components, is emb~died by the Animus system of the present in~ention by ~n instance of a ~i~eDifferentialCon~traint class (described ~n detail hereinbelow) which forms ~n additional part o each kit component representing an objec exhibiting ~emporal behavior.
To construct an ~C network from such kit ~om-- 30 ponents, we s01ect the object ~Capacitor" from a kit of previously constructed prototypes in ~ourth ~: pane 18. A flashing image of a capacitor 20 w~ll follow a ~ursor 21 in a di~play area 22 o~ wind~w 10 and allow us to locate the ~apacitor image 20 wherever desired in axea 22 by moving the ~uræor .

. . . . .
, :' . . , : '.
., . ~, .
. ' . ~ " ` '': , .' . ~

741;~3 1~

and clicking a mouse button. We then insert a resistor 24 into display area 22 in a similar fashion by selecting "Resistor" from pane lB. (The lists in panes 12, 16, and 18 are scrollable and only a portion of each list ~s displayed.) The endpoints of each lead of resistor 24 are con-sidered "sticky" and one will "merge" with A capa-citor lead to form a circuit node 25 when brought close to the capacitor lead.
FIG. 2 shows a latter stage in the construc-- tion of the RC prototype. Once the RC prototype has been assembled, it may be desirable to probe it with an oscilloscope 26 (another prototype object available in the kit) inserted into the RC proto-1~ type to view the voltage between a circuit node 25 and ground 29. The "beam" of the oscilloscope 26 is constrained so that its vertical displacement is proportional to the voltage difference between its leads, and so that its horizontal displacement o tracks the value of time.
To star the animation going, we simply select "go" in the third pane 16 in order to send messages to advance a "clock", an object in Animus which maintains a global variable called "time". The capacitor prototype 20, as the charge is discharged through resistor 24, constrains the current through it to equal the change in its charge with respect to time (i = dq/dt) which is provided with an initial condition charge ~which may be adjusted by the user as discussed hereinbelow)~ When the clock is sent a message to incxement time, constraint satisfaction requires that time may only be - advanced in consideration of the constraint that i = dq/dt in the capacitor. When a time incrementing message is sent, Animus compiles a new method to .
i - . - .
.
.
' ~ ~ t743~ C) i respond to this message which, in addition to incrementing time, enqueues an "event" in an "event queue" (discussed in detail hereinbelow). An event is a description of a message to be sent upon the next increment of time ("tick" of the clock) to adjust the charge on the capacitor 20. This change to the charge in turn triggers other constraints which define the behavior of the RC network.
Animus plans and compiles the necessary methods to implement this behavior based on the constraints triggered. These include methods to change the voltage on the capacitor (V = ~/C3, to change text displayed adjacent to the capacitor which indicates the charge on the capacitor 20, to move the beam on the oscilloscope 26, and to change the current through the resistor 24, along with text adjacent - to the resistor indicating the resistor current.
This planning and compilation phase takes about 30 seconds for the circuit of FIG. ~. After the methods are once compiled they may be executed - without recompilation thereafter, and once the animation begins to run, clock ticks come with a satisfying swiftness and the motion of the oscillo~
scope beam attains a reasonable degxee of smooth-ness. The resulting exponential decay seen on the oscilloscope 26 is not the result of any analytical ~- calculation of exponentials, ~ut occurs naturally as a result of finite-di~ference approximations embodied in the methods generated by the system to satisfy a specified TimeDifferentialConstraint associated with each time dependent element of the RC network.
The capacitor 20 is suitably provided in the "kit" with an initial charge. To reinitialize the charge, the user can edit the capacitox directly .. . .

- . ': ' , ~
.. , :
: , , : .
:

3~

and simply assign a new value to the charge, whereupon the animation may proceed. To perform the edit we select "edit" in the third pane 16, and in the fourth pane 18 we select the kind of object we want to edit, in this case "Capacitor." We then obtain a cursor moveable flashing image of a capa-citor in area 22 that will "stick" to any capacitor we select. Animus shows us the selection by dis-playing a box 30 around the selected element, as illustrated in FIG. 3. Clicking a mouse button on the selection now brings up a standard Smalltalk Inspector window 31 as shown in FIG. 4 in which values of the instance variables of the selection may be examined and edited. We select the text ~or the magnitude of the charge by selecting "charge"
in window 31, edit it, accept it, and close the window. We may then resume the RC system operation by selecting "go" in third pane 16.
The new initial charge on the capacitor changes the initial voltage across the capacitor so - that the exponential decay of that voltage, viewed by the oscilloscope 26 as capacitor 20 discharges through resistor 24 following the "go" command, begins at a voltage level which may be higher or 2S lower than the previous initial charge. The implementation of this software to hring about these results is hereinafter more fully describedc As another example, referring to FIG. 5, we may build an electrical oscillator by ~elec ing from the "kit" an inductor 33 and connecting it with a capacitor 32 and an oscilloscope 34 to build an LC circuit 36 in window 10. The "gain" and ~'sweep" o the scope 34 may be adjusted by editing the instance variables for the scope in the same way that the capacitoris initial charge was .

. . -.

~'~7~3~0 changed. Numbers printed beside the c~mponents are suitably constrained with each "tick" (i.e., incre-ment o~ time) to indicate the charge on the capaci-tor 32 and the current through the inductor 33 in arbitrary units. The inductor 33 behavior is des-cribed by a TimeDifferentialConstraint indicating that V = L*di/dt, where "L" is inductance, "V" is the voltage across the inductor and "i" is the current through the inductor. When the ~C circui~
36 is built and told to "go", temporal constraints for both the capacitor and the inductor must be satisfied. The method to increment time now enqueues two events-; one describing a message to adjust the charge on the capacitor 32 and another describing a message to adjust the current in the inductor 33. These messages trigger other con-straints so that a reasonable set of finite-- difference functions are effectively generated.
After the LC circuit 36 has operated for many time increments, the oscilIoscope 34 shows that the - voltage across capa~itor 32 varies in a smooth sinusoid.
; FIG. 6 shows an animation of a mechanical analog to the electrical oscillator of FIG. 5, comprising a mass 40 on a spring 42. A spring prototype containing a constraint modeling Hooke's - Law F = -k/x (where F indicates a vector force and X indicates a distance vector) i~ pxovided in the kit. Hoo~e's Law is expressed as a static con-straint between the spring's extension and the - force it contributes. The mass object 40, con-taining constraints expressing Newton's Law F = ma and the basic kinematic relations V - dx/dt and a = dv/dt, may be attached to the end of the ~ 35 spring, where these kinematics are described by .~
~"
' ~ - , ' ' ' " . ' : -~ ~7~3~

TimeDifferentialConstraints as above. When the system is told to "go" methods are compiled that solve the constraints directly in two dimensions.
If we graphically edit the mass's position by S selecting "move" in pane 16 and "MechanicalNode" in pane 18, and utilize the cursor 21 to push the mass, the system will continue to oscillate, but in a way that can account for the "push" from the cursor.
If the motion of the bouncing mass seems too - l0 jerky, we can adjust the granularity of the clock increment by selecting "tick size" in the third pane 16 as shown in FIG. 7. This brings up another prompt window 43 in which one can edit the size of the "dt" time increment. A smaller value for "dt"
tends to make the animation look smoother, though of course it runs more slowly in real time.
In FIG. 8 a "hand" object 41 from the kit (pane 18) may be inserted in the prototype which is constrained to drive the spring/weight system by moving the upper end 45 of the spring up and down at a fixed sinusoidal frequency. This enables observation of the transient behavior of the spring/weight system and also demonstrates resonance phenomena. The hand 41 introduces into the system a "scripting" TimeFunctionConstraint in which the value of a variable is determined by evaluating some function of time. That is, the hand prototype definition has an instance variable, "vertical~Offset," defined by a sine function, 3~ A*sine(wt).
When time is incremented, constrain~ satisfac-tion enqueues a message that assigns the value of the function at the current time into the con-strained variable, the vertical offset of the hand 41 from its initial position. Since the driving -' ~', . .

~7~3~

hand 41 is steadily adding "energy~ to the system, -- the oscillation amplitude would increase without bound in the absence of damping such as that due to friction, air resistance or spring inelasticity.
Such damping i~ conveniently modeled in the ~ass 40 itself as a slight modification to the constr~in~
determining the acceleration. A term ~ * v, i8 simply subtracted from the Yalue of acceleration, where v is a vector velocity, scaled by a damping ~oefficient f, yielding a fsrce component propor-tinnal ~o velocity and opposing the direction of motion.
The a~imation of discrete processes such as alqorithms poses a new set of problems. It is no longer so easy to describe temporal evolution usin~
equations, but rather one encoun~ers event-driven causes and effects. A principal means ~or describing resp~nses to even~s is provided by the mechanism of ~riggerCo~str~ints. A discrete proce s i8 described by its ~tracen~ the stream of events comprising it, and a TriggerConstr~int allows the animator to speci~y certain graphical responses to the occurrence of particular events.
FIG. 9 ~hows an Animus Browser window lO
displaying an animation ~"sorting") created to test an algorithm for 80rting nu~bers by ~agnitude. The animation consists of representing each number by a . bar of height proportional to the magnitude of~ the ~: number, bars being placed a graphical queue in the order that the numbers are arranged before the sort.
As the algorithm reorders the numbers, the animation graphically swaps the p~sitions of the bars in ~he queue to show how the sorting algorithm ~orts. To build a 60rting animation in Animus we select an item from the kit tpane l~l oalled a Sor Wueue which . ~
.

-. -. . :. .
' . .: ' ~ , -.
,: ' . - ~ , .
4~

causes a queue symbol 40 including a small rectangle 40a, indicating the start of the queue, and a dot 40b, indicating the end of the queue, to be placed in the display area 22 of window 10. We then graphically add elements (bars~ to be sorted, each an instance of Bar~agnitude (a kit item3 represented by a bar 41 in a queue 42 of such bars, each bar being inserted between the queue start symbol 40a and the queue end symbol 40b. The height of each bar may be changed utilizing cursor 44, the magnitude represented by each bar being constrained to be proportional to the bar's height. The bar width remains constant.
After bar elements have been added to the queue 42, the algorithm to be animated may be invoked, as shown in FIG. 10, by selecting "send message" in the third pane 16 and "SortQueue" in the fourth pane 18 of window 10, and by pointing with the cursor 44 to the queue to receive the message. The system ascertains what messages the queue can understand and presents the user with a rnenu 46 (as shown in FIG. 11) from which to choose - a sortins algorithm. We select a sorting algorithm "selectionSort" from menu 46 and the sort begins.
As the algorithm compares the heights of two bars 41a and 41b (or in actuality compares the value~ of two numbers constraine~ to correspond to the bar heights), the bars "flash" (alternate between black and white fill) as seen in stop-action in FIG. 12.
When the sorting algorithm decides that positions of two bars 41a, 41b are to be swapped, the bars are graphically moved past one another to exchange positions as shown in mid-swap in FIG. 13 . . ..................... : ~ . "
.' ~ . . . . .

~.;2 74~1 [3 The bars could be swapped instantaneously but it is more difficult for a viewer to comprehend the procedure than when the bars move smoothly past one another over a period of time. The movement is simulated by "stepping" each bar across the screen using steps small enough so that the viewer perceives continuous movement. The movement of the bars in the sorting animation is an example o converting a discrete process (such as a swap) into a stream of events (display steps) which happen over a period of time. This capability is provided by the TriggerConstraints mechanism.
Let us now consider how one might use the Animus system to construct an animation of a system - 15 problem comprising a producer and a consumer. The producer produces goods and transmits them to a distributor (monitor) which stores them in a ware house (buffer) until purchased by the consumer.
When the buffer is full, the monitor sends a "full"
signal to the producer which then stops production until the monitor sends a "not full" signal, indi-cating the buffer can accept more goods. The Animus "kit" provides prototypes for the consumer, the producer, and the monitor processes as well as for the buffer. Referring to FIG. 14, depicting an Animus Browser window 1~ showin~ a producer/consu-mer animation under development in area 22, the producer is represented by a block 50, the monitor is represented ~y a block 52, the consumer is represented by a block 54, and the buffer is repre-sented as a queue 60 similar to the queue of the previously discussed sorting example. An output lead 49 of the producer 50 is connected to an input lead 51 of the monitor 52 and an output lead 53 of the monitor is connected to an input lead 55 of the .

.
. .

43~
~2 consumer 54. An input/output lead 62 of the ~oni~
tor 52 is connected to the buffer 60. The lead connections define the paths of goods through the system and each lead is an instance varia~le ~uch as ~dataLead", similar to instances of ~uoberLead in ThingLab, which enables a user to indicate that the output of a producer 50 is ~o be sent to a monitor 52 by graphically interconnecting leads~
We provide the producer, monitor and consumer processes with their specialized behavior by inserting bits of algorithmi~ code into the prototype definitions. For example~ the monitor must handle the signaling embodied in the algorithm~ ~o it will need protocols and variables for handling ~he ~ignals, ~uch as notE~pty5ignal notEmptyCondition < true .
notFullSignal notFullCondition <- true Likewise the buf~er will need to ~ignal the ~onitox when it is full or not.
To build the Monitor-Producer-Consumer ~MPC) prototype animation we begin by inserting the Producer 50, Consumer 54 and Monitor 52 as shown in : FIG. 14. The leads stick when moved together by a cursor, their connection in thi~ ~ontext indicating data pathwaysO Having assembled the ~ructure of the MPC prototype, we start the action by ~ending nproduce" messages t~ the producer 50 as shown in FIG. 15, selecting "send message" in the third pane 16 of the browser and "Produ~er" in the fourth pane ~8. As we move the cursor into area 22 we obtain a .~

..
, . '. .., ' : .

~Z~743~(~

flashinq image 56 of the Producer 50 prototype which will stick to the producer instance we wish to address. Releasing the mouse button on the selected Producer causes the system to recompile all the methods for which responses are specified to be triggered, and then presents us, as shown in FIG. 16, with a menu 58 of messages which may be sent to the selected producer. In this case only the message "Produce" may be sent.
When we celect the "produce" message to be sent to the producer 50, two distinct but related things happen to the prsducer which provides a "datum", represented by a black dot 64 (as shown in FIG. 17) containing a letter indicating a product.
In FIG. 17 four "produce" messages have been sent.
Three products (A, B and C) have been stored in buffer 60 while a fourth product D, provided in response to the fourth "produce" message, is shown "en route" to the buffer 60. The Producer, consumer, monitor and buffer prototypes include constraints which require certain graphical events to occur when the Producer produces a datum, namely that the dot 64 representing the datum be displayed as "moving" from Producer 50 and into buffer 60.
Animus compiles methods for the MPC prototype which - ensure the constraints are satisfied when the Producer is sent a "produce" message. The movement of the dot 64 is an example of a temporal response occasioned by temporal constraints.
- 30 If the producer 50 is told to produce when the buffer is full, then the monitor 56 signals the producer 50 to wait. A graphical constraint is pro-vided in the producer such that when its "blockingCondition" is set, the producer displays itself video inverted. Then if the consumer consumes .

. ' ' ~ ' . , ' ,' .

2~

an element, the monitor 52 receives a "notFullSignal"
message from the buffer 60 and in turn wakes the ~ producer 50 which then resends its datum.
Implementation An operator utilizes Animus to create a model which simulates the behavior of a collection of interactive elements such as a process or an apparatus. The model is assembled from Smalltalk objects instantiated from preexisting prototypes in i0 the Animus kit wherein each prototype simulates a part of the process or apparatus~ Once the model is created, it may itself be used as a prototype in the kit for an element of a more complicated model. The temporal behavior of the model is con-trolled by a time management sbject thexeinafter referred to as the "anima"), an instance of a subclass of a new Smalltalk class Anima. The anima is adapted to execute a procedure for incrementing a simulation "time" by incrementing the value of a ~ariable representing time. The anima also main-tains an "event queue" for storing "events", wherein an "event" is a representation of a message, and a "time stamp" indicating a time at which the message is to be sent to the model. The anima is further adapted to transmit any message represented by an event in the event queue to objects o~ the model when the time represented by the time variable surpasses the time indicated by the time stamp associated with the message. Each - 30 such message sent to the model causes the model to carry out some procedure which satisfies con- -straints on its behavior.
` - In order to cause the model to behave in a temporal fashion in response to some ~riggering message, one or more events are stored in the - . , .. . , ,, ... - . . .
: ~
. .. . , . : .. :
' ' , ' ,: ".': "' ' . ' '.
-', ~
. .

~z~

event queue in response to the triggering message wherein each event includes a time stamp indicating a future time at which its message is to be sent to the model in order to effect a particul~r response.
As the time management object increments the time variable, the messages described by the events in the event queue are sent in the order that the events are time stamped. Thus the model carries out an action or a sequence of actions in the future in response to a current triggering Pvent.
In creating the model, temporal behavior of the model is described by temporal constraints on the behavior of its parts, the temporal constraint~
being described by instances of temporal constraint classes which are instantiated when the kit prototypes are instantiated and inserted into the model. The t~mporal con~traint classes include descripti~ns of triggering messages which invoke ~; constraints. When a triggering message is sent to the model for which no procedure has been compiled for satisfying temporal constraints triggered by the message, Animus compiles a response procedure for execution by the time management object (the anima) which causes one or more events to be stored in the event queue. Each of these events includes a time stamp indicating a future time and a ~- representation of a temporal constraint satisfaction message to the model for causing the model to satisfy the requirements of the temporal constraints triggered by the triggering message.
Thereafter, as the anima increments the simulation time, it transmits to the model any message described by any event in the event queue for which the simulation time surpasses the time indicated by the time stamp of the event, thereby . . ~

. .
': . ' , ~ , ' ~ ', , , ' ' ~ 2743~

causing the model to carry out actions in satisfaction of its temporal constraints. Thus Animus not only temporizes the behavior of the model by providing the anima for controlling the actions of the model to be performed at a specified future times, it also automatically determines what those actions will be in order to satisfy a set of temporal constraints on the behavior of the model and embodies those actions in the ~orm of time stamped events in an event queue.
In discussing the behavior of constraints, especially temporal ones, it is important to distinguish four distinct periods in time. The distinctions are impor~ant with respect to when objects and responses come into being, and when methods become defined. These times are used to structure the discussion of the behavior of constraints and they are:
Definition Time - The time at which the textual definition of a constraint becomes instantiated as an instance of a Constraint class and becomes incorporated into the prototype being de~ined.
- Compile Time - The time at which a message is sent to some node in the constrained structure which is not defined in the ~ethodDictionary for that object, but which is recognized as a method for which a response can be generated given the constraints. At this time a new method i8 compiled by the Animus system to respond to that message such that all constraints are satisfiedO
Run Time - The time at which the new method ~compiled at compile time) is executed. In the case of a temporal constraint this execution results in the creation of a response which can - , . . . .

- . '- ', :. ' ' : ' ' : ~ ' ' - : . . :
:. - , .: .
: .

only oc~ur in the future.
Future Time - The time at which a temporal response (created at run time) unfolds.
The irst three times are sufficient for describing the important events of a static constraint system. However, a static constraint is not concerned with the future behavior of the - system; it is concerned only with the current state of the system and says nothing about what states the system must assume in the future. In con~rast, a temporal constxaint is satisfied by the future behavior of a system and has no effect on its current state.
All time management protocols and controls for compiling temporal constraints are implemented as instance methods in the Smalltalk class Anima.
Anima, of whose presence the user is generally unaware, is in some sense the "soul" of the animation. The simulation time as well as the event queue are instance varia~les of, and are managed by, the anima. When the user defines a new prototype in the browser, such as the 'iCircuit"
prototype, Animus automatically defines a new class called CircuitAnima as a subclass of Anima into which methods for the response and temporal behavior of the particular circuit become compiled.
An anima that is an instance of this new subclass is automatically instantiated when the user constructs a new prototype~ and is initialized and assigned as the value of the instance variable ` "anima'l of that prototype when time ~irst advances.
An "eventl' is an instance of class Event and is a representation of a Smalltalk message along with a time stamp specifying a time at which that message will be ent. A message in Smalltalk .

~`
. ~ , .. :

semantics consist~ of a reference to an object designated the receiver, a symbol serving as a message ~selectorl', and an array ~ arguments.
When a message is fient to a receiver objectt the receiver determines from the seleetor what method it is to execute and makes use ~f information contained in the arguments o the message when executi.ng ~he ~ethod. The time stamp of ~n event serves to defer transmission of the me~sa~e until time has a value greater than the time stamp.
The ~event queue" is a variable ("eventQueue") com-prising a linked list o events in which ~nsertions and removals of events may be done efficiently.
Re~pon~ are represe~ted as prototypes whieh, upon the occurrence of a designated tri~ger event, axe realized as a stream of events, which are pl~ced in the event queueL Any instance o~ Ani~a responds to the message "tick: dt,~ by ~irst checking to find all events in the event queue with time-stamps less than the current value of time, 6ends off the messages represented by the events, and finally increments the v~lue of time by the value of dt.
Since enqueued events zlre explicitly time stamped, and management of all ~ve~ts and xesponses occur in one time-ordered queue, there is n~ need for synchroniza~ion primatives. ~n arbitrary degree of concurrency may be handled by the event queue, since any number of ~vents may be ~tamped to occur at the same time. In particular, by inter-leaving complex responses, ~uch as movement of ~any different icons across the screen, a series of single-step e~ents are specified to begin at speci-fic times with durations such that they overlap.
The constituent events are inserted ~ime-ordered in the queue and executed in that order~ thus inter . ~

:

~ 3~

leaved.
A temporal constraint is a relation that is required to hold between the existence of a stimulus event and a response in the form of a
5 stream of one or more new events. The statement of a temporal constraint must include a description of the stimulus event and some representation of the abstract response prototype from which the response stream of events can be instantiated at a particular time. The stimulus event may simply be a tick of the clock or it may be the receipt of some specified message by a particular object in the model.

Definition Time Temporal constraints are expressed locally in the components which are to exhibit the specified behavior, and these components are then combined (for instance by "merging" leads in the RC network example) so that the constraints interact in a netwoxk. Unlike ThingLab, where static constraints are satisfied more }ocally ~in the least co~mon ancestor of the affected parts), in Animus time is - considered global and time as well as the single eventQueue variable are manayed by the single instance of Anima which is contained in the ances-tor to all parts of the animated ~tr~cture. There-fore at the time of prototype initialization the animated structure must be traversed and all tem-pural constraints caused to migrate up to theanima, since the anima is the owner of the con-strained variable, time. This process is detailed hereinbelow. Any message that would increment time thus must consider the constraints on time and a new method must be compiled to respond to that : ' ' ' :' . -, ,. :.
' ' ' ' : '' ' :

message which in addition to incrementing time guarantees that the constraints are ~atisfied.
The textual definition of a static constraint, for example the Ohm's Law constraint for V - IR
S defining the Resistor prototype (or kit object~, appears as an instance creation and initiali~ation message to the constraint class as follows:
..
Constraint Owner:Resistor prototype rule: '(leadl node voltage lead2 node voltage) = (leadl current * resistance)' methods:
#(~leadl node set.voltage:
lead2 node voltage I ~leadl current *resistance)' 'lead2 node set.voltage:
leadl node voltage lleadl current *resistance)' 'leadl set.current:
(leadl node voltage-lead2 node voltage) resistance' 'resistance reference') The string argument designated as the "rule"
represents the relation or predicate that the static constraint is to maintain (i.e., that V = IR). The strings provided in the array of "methods:" are code fragments that the constraint might utilize to reestablish the rule in the event of a change. Typically a number of different - ~ethods are supplied to enable the constraint to be satisfied in different ways depending upon what variables are known. Here, the constraint is given the option to adjust the voltage at either lead, or to change the current through the resistor. The ,, ' ~ ' ." '`,. ~. -, ~ . . . -.
, .

~L~7~3~3 string 'resistance reference' indicates that the instance variable "resistance" is reference only, that is the constraint should not change the value of resistance to satisfy itself. However an outside reference to the resistance, for example if the user were to edit its value, would nonetheless cause the constraint to fire.
When the Resistor pr~totype (or kit object) d~finition is instantiated, the "owner:rule:methods"
message is sent to an instance of class Cvnstraint which responds by sending messages to an instance of Compiler which in turn parses the rule and method strings in the definition. The compiler returns an instance of a class ~ethodNode from which a parse tree representing each message string can be extracted. The intermediate representation used by the Smalltalk compiler is a tree of ParseNodes (of which ~ethodNode is a subclass) which (recursively) know how to emit byte codes.
The parse trees are then stored as initial values of instance variables in a new Constraint instance.
Finally, the class sees that this new Constraint instance is inserted into the class definition of the prototype Resistor.
The goal of temporal constraint satisfaction, in the case of a TimeDifferentialConstraint, is to generate a set of methods that embody a finit `~ difference approximation for a stated differential equation. One way to perform such an appxoximation is to consider the derivative value (for example - the current, i, in the capacitor's constraint relation i = dq/dt case) at the onset of each discrete time interval dt to be good for the duration of that interval. Then the new value for the differential variable (charge q) may be .. . .. : -................. : , - : . , . : .
- . . - , , . ~ .

., ' - . : : ' ~

~.~7~ lO

calculated for the beginning of the next interval, after which other values (such as the current) may be updated according to the constraints for static consistency. Relying on this method, the user need not specify a series of options in the constraint definition, but only the variables so constrained.
Thus the definition of a TimeDifferentialConstraint in the Capacitor prototype (i.e., kit object) appears simply as~
TimeDifferentialConstraint owner:Capacitor prototype timeDerivativeOf:'charge'equals:'leadl current' As for a static constraint definition this "owner:timeDerivativeOfoequals:" message calls on a compiler to return a parse tree, but the string to be parsed is o~ly implicit in the definition.
Additional string elements are added to the infor-mation given in thP definition so that the compiler returns a parse tree standing for the code fragment:

delta.charge: tl ¦delta¦
delta <~ leadl current * tl.
The value of the time increment tl is not known until run time and so is expected as a parameter.
This code fragment is incorporated into a new method created at compile time, as described hereinhelow.
In the new method, the local temporary variable "delta" is passed as an argument in another message to increment the charge~ This parse tree is inserted as a field in the new constraint instance in the new prototype class definition, but not directly as before, but rather packaged inside an -.

..
. ..

:

43~) object called a Response. An instance of class Response is an abstract representation of some possibly complex behavior to occur in the ~uture, and becomes realized at run time as a sequence of events to be stored in the event queue~

Compile Time At compile time a message that was not under-stood has been sent to a part of the structure.
The method defined in Smalltalk class Object for "doesnotUnderstand," which normally puts the user into a debugger, has been overridden in the Animus system so that it first checks whether the message selector was of a form (such as "delta.charge:"
above) for which the Animus system should try to compile a method from constraint information. If so, an instance of class ConstraintSatisfacti~n-Planner is created and told to collect together all constraints that might have to be satisfied or checked because of the potential change. Such a planner maintains a queue of methods contributed by affected constraints. The planner tries to find an ordering of these methods that will satisfy those constraints. The first step taken by the planner is to expand the message recursively to all parts of the receiver, so that a message affecting the whole structure, such as moving the entire object, - may be implemented by messages to the parts, ulti-mately moving each point comprising the object by the same amountO For example, if a quadrilatexal object consisting of four line segment objects were to receive the message "moveby:deltal' it would -expand this into four "moveby:" messages, vne to each line segment~ Each of the four messages to line segments would in turn be expanded to two -:~' , ~ ~7~3~

messages, one for each of the endpoint objects of the segment.
Next for each message in the planner, the path to the receiver is checked for any constraints that might no longer be satisfied, and these constraints are told to add their methcds to the planner. For example, if two resistors were connected to the same electrical node whose voltage is to chan~e, then the methods f~r each resistors Ohm's Law constraint must be added to the planner. When a constraint is told to add its messages to the planner queue it checks to see whether it has already done 50 via a different acces6 path to a merged object. The constraint also checks whether it "overlaps" the receiver of the message being planned for, that is, whether any of the constrained parts are going to be affected by the planned changes. The messages in the planner's queue are then processed to delete duplicates (arising because of merged parts being accesses via more than one path in the xecursive expansion) and, if possible, to find a one-pass ordering for - sending the messages in the queue ~o that changes can propagate through the system leaving all cvn-straints satisfied. Finally, a new method is com-piled into the receiver's class definition whose statements are the messages o the planner's queue in the appropriate order.
In the case of a temporal constraint the receiver of the initial message i~ the global entity "time", located in the anima, which is an implicit variable in all simulation objects. This means that at compile time, upon receipt of a message to time by "incrementby: dt," the anima must first gather together all the t-mporal :` :
- , . . . . .
. . .
.

. . .

~2~

constxaint~ that ~re defined in parts of the prototype object since time and the constraints on time are going to be globally managed by the anima.
The anima then sends itself a message to "compileResponseFor" the temporal constraints it has just gathered~ This means that the code fragment contained in the response of Pach temporal constraint becomes augmented and placed in context.
For example, if a capacitor i added to a circuit the ~nima compiles a response method derived from the last mentioned code shown which now reads:
del~a.thing.capacito~3.~harge:tl tdelta ¦ ' delta <~ thingcapacitor31eadlcurrent*tl~
thing capacitor3chargeprimitiveIncrement:delta.

Notice that this differs ~rom the earlier code fragment in that both the method selectors and the reference to ~he curren~ have had path names prepended to reflect the position of the specific : capacitor in a larger context. Also the calculated "delta" is now passed as an argument to "capacitor3chargeprimativeIncrement:~, a system compiled methsd insuring static constraint ~atisfaction in the circui~, ~o make things ~onsistent once the charge has been changed. It is ~ a method which has been compiled via the prior art - ~tatic constraint satisfaction mechanism of ThingLab, ~aking care of 6uch things a~ Adjus~ing the voltage across the capacitor to reflect the change in charge (C - q/V), propagating v~ltages along wires, ~nd ~inally adjustin~ the current ~n the circuit due to Oh~'s Law in the resistor. Upon the triggering of a temporal constrain~, messages -` ' '. ' , ~ '.; ~ .
, .
, 3~
3~

are connected in a queue in the satisfaction planner, and constraints similarly checked. Now the "overlaps:" check is trivial; one simply looks to see whether the receiver o the message is time.
A temporal constraint is also asked to place its methods into the planner, but instead of doing so directly, it compiles another methud which at run-time enqueues the response method to occur in the future. For example, the method "incrementby:" is de~ined in the anima's class as Incrementby: tl time primativeIncrement: tl thingEvents enqueues [Array with:
(Event new atTime: time value ~ tl receiver: self selector- ~delta.thing.capacitor3.charge:
arguments: (Array with: tl))).

Thus the change to the value of charge is enqueued to occur in the following instant. This effectively implements the finite di$ference approximation, the value of the current has been left untouched fox the duration of the time inter-val, and a new value of current is then derived from this first approximation to the new value of charge. This delay of the response for one clock tick breaks the circularity inherent in the state-ment i = dq/dt, wherein the charge is dependent on the current and vice versa, which would otherwise - force the constraint satisfier into costly relaxa-tion methods~ Other temporal constraints may entail more elaborate responses such as scripts or . "

3~C~

graphical trajectories involving the enqueuing of many events stretching out into the future, in contrast to the single event of this example.
Run Time .
At run time, static constraints are satisfied by simply running the compiled method generated at compile time. However, in the case of a temporal - constraint the method generated at compile time i5 itself a method to generate a set of new messages that will form constituent events o the run-time response to occur in the future. These new messages appear as time-stamped events which are placed into the event queue. That is, in our example, "time"
receives the message "incrementby:dl" given above.
This enqueues an event so that the anima executes the "delta.thing.capacitor3.charge" method at the next tick of the clock.

Future Time The future is represented by the event queue maintained by the anima. As previously mentioned, the eventQueue is an instance variable of anima comprising a linked list of time-stamped messages which will be sent when time catches up to the time-stamp.

Types of Temporal Constraints In some cases it is possible to describe temporal behavior in terms of real~valued functions of *ime or differential equations involving time.
In these cases the systems being simulated and animated are continuous processes and the problem for the system in satisfying the constraints i5 to generate a discrete approximation of the continuous specification. Alternatively~ the simulated .
-- -: ' . ~ ' "' . , ' .~

~ ~7~3~

process may be discrete, in which case the constraints and their satisfaction must conform to an event driven, cause-and-effect model. However, one may wish to represent evolution that is explicitly discrete with as much visual smoothness and continuity as possible, as for example in the previously discussed sort animation wherein discrete swaps of bar position in a queue were represented by apparently continuous movement o bars from one queue po~ition to another. In such case, intermediate ~raphical states for a thing being animated must be interpolated which in fact have nothing to do with any actual state of the thing itself.
Continuous Evolution Of the simpler kinds of temporal constraints are those that explicitly determine the states of objects as functions of times. An example is the constraining of the position of the hand 41 that drives the bouncing spring 42 of FIG. 8 to follow a sinusoidal functions of timP~ The definitioll of the constraint appears as TimeFunctionConstraint owner: Hand prototype timeVariable: 't' timeFunction: '(t * frequency) sin * amplitude' constrains: 'verticalOffse~'.

In this definition the variable 't' is actually just a place holding dummy variable, since there is no instance variable re~erxing to time in the Hand prototype itself. Later, at compile time this dummy variable is replaced by '1time" which is an instance variable of the automatically gene~rated ,: .
- : . . . . :, . ~ . . .
. -3~

subclass of Anima for the animation prototype into which the Hand is inserted. When this definition is filled in, the constraint which is installed into the Hand pxototype constructs a parse tree representing the code fragment:
delta.verticaloffset - ¦delta¦
delta <- (thing anima time * frequ~ncy) sin *
amplitude Finally at compile time, this fragment becomes recom?iled into the anima as before, in the form of another method that actually performs the assignment, while also satisfying any other constraints on the variable being assigne~ into.
Thus the method appears as follows~

delta.thing.hand3.verticalOffset ¦delta¦
delta <- (thing anima time * thing hand3 frequency) sin * thing hand3 amplitude.
~thing hand3verticalOffsetprimitiveSetTo: delta 2S With each tick of the clock this new method is - called, the specified function of time is evaluated, and the constrained variable is set to the result. -The situation is not quite so simple when continuous evolution is to be described by time-differential; constraintsr e.g., v = dx/dt. This - case presents some special problems arising from the fact that the continuous and exact analytical description must be mapped into an implementation - 35 of a finite difference approximationO Since digital . .

: . ., . . .. - . :.

- . - . . .

3~

- technology requires building a movie out of discxete frames, a continuous process ~ust be modeled discretely. Furthermore here is an inherent circularity in a statement such a~
v = dx/dt; it states that velocity depends upon posi~ion, but position also clearly depends upon velocity. According to a finlte difference approximation method, the old value o velocity would be con~idered to be valid for the duration ~f the incremental time interval, dt, in order to calculate the new position, and only after the approximate ne~ position is esta~ hed would the velocity be updated.
The implementation of Ti~eDif~er~ntialCon~traints effectively ~chieves this behavior. The c~ns~raint i5 triggered initially ~y any message that would increment the value of time in the global clock.
That is, a message to increment time i reint2r-pretted in view of the constraint, and a new method is compiled that increments time as well as enqu~s an event embodying the constraint's response. This event i~ the in~rementing of the v31ue of the differential ~i.e., dx) by the speci~ied amount - ~i.e., V~dt). But the event is enqueued to occur in the fol lowing instant, thereby generating the stan~
dard appr~ximation by ~onsidering the old value of the derivative as valid throughout the time i~terval.
One detai 1 appearing in the ~yntax of T~laeDifferen~ialCons~raint declarations is that one may not constrain expressions, but only ins~ance variables. Thus in the Inductor prototype, when one would like to expre~s ~he ~onstraint V/~ ~ diidt, one must create a new instance variable "delt~VoverL"
and write~

., , (3 TimeDifferentialConstraint owner: Inductor prototype timeDerivativeOf: 'current' equals: 'deltaVoverL'.

One must further constrain this new variable to the described expression thus:

Constraint ~wner: Inductor prototype rule: 'deltaVoverL =
(leadl node voltage - lead2 node voltage) / inductance' methods:
#('self set.deltaVoverL:
(leadl node voltage - lead2 node voltage) / inductance' 'leadl node voltage reference' 'lead2 node voltage reference' 'induc~ance reference').
. . ~
This simplifies the implementation of the constraint. Whereas static constraints may satisfy themselves by incorporating expressions in line into newly compiled run-time methods, a temporal constraint creates a run-time method which itself enqueues another method to be executed at a later ~ time, and this latter m thod can only refer to its -~ receiver and arguments, not expr~ssions~
Discrete Evolution The specification of responses to discrete ~ events is implemented by the class - TriggeredConstraint. The trigger event is a message with the specified selector sent to the owner of the constraint. The constraint owner's behavior upon receiving the trigger message takes the constraint into account by first enqueuing the -~ specified response events and then performing the ~ 35 primitive method associated with the message. This ':
: ~ ' - : - .. . :

. ~
:. .. - .............. .. - :
; ` ' -. . ~ ~ ' : . ~ ,, :: . ' . , . - , . .~' . : .

~7~3~3 technique allows particular instances of a class to have individualized responses to a given message, unlike the usual situation in Smalltalk where all instances of a class have the same behavior.
Each temporal constraint possesses a Response by which it satisfies itself. In a constraint for continuous evolution the response is relatiYely simple, involving the sending of a single message to perform an assignment. The response triggered by a TriggerConstraint is often more involved, entailing the enqueuing of many events, or starting up a procedure implementing an algorithm being animated. For example, a response that is an instance of class Flasher enqueues a series of events which alternately paint a region of the screen black and then white~ Flashing may be used, for example, to highlight some object the user should notice, like the elements of an array as they are being compared in a sort.
The technique used to insure the execution of responses takes advantage of the recompilation and relocation of methods at compile time to insert the code fragment given as the response into the newly compiled method. Thu~, the definition for a trigger constraint for making bars flash when they are compared in a sorting algorithm is:

TriggerConstraintowner: SortQueue prototype to~ st' trigger: #compare: with:
causes: I(Flasher with: (list at: al)) enqueueEvents.
(Flasher with: (list at: a2)) enqueueEvents'~

This code fragment in the trigger constraint causes the following method to be compiled into the ;
:~

: ~ ' .

:
.
. .
~, ' .
.

~.~ 74~1l ) anima class for the sorting animation:

thingsortQueue31ist.compare: tl with: t2 (Flasher with: thing sortQueue3 list at: tl)~
enqueueEvents.
(Flasher with: thing sortQueue3 list at: t2)~
nqueueEvents~
selftick: 1 ~thing sortQueue3 listcompare: tl with: t2.

This ~ethod is executed instead of the ~ri-ginal "compare: with:" method since all messages to the constrained object to invoke the original method have been recompiled, and rerouted to the - anima with the new extended selector substituted.
Notice that in the recompilation, the message "selftick: 1" has also been inserted by the com-piler so that the events that are enqueued for the response are immediately executed. This is neces-sary since, when control is given over to an exe-cuting algorithm, the browser no longer sends tick messages to the prototype, as was the case when we selected "go" in the spring/weight simulation.
Conceivably this problem could be solved by "animating the program counter," and using advances in the counter to send off tick messages. But object oriented languages such as Smalltalk typically do not have a program counter in the usual senseO Me sages are simply passed around.
The explicit insertion of tick messages by the system into the recompiled messages forces the animated responses to occur a~s they are needed in a temporal fashion~ ~
Another way to generate a response is to refer .'. , . . , ~7~31t~

directly to a Script to be enqueued, rather than creating a Trajectory or Flasher which then enqueues events. Most simply a script may be a stream of events, that is, time stamped messages.
Typically a script is accessed as a Stream that is opened onto a file. Instances of a script respond quite simply by placing their own sequence of events into the event queue at run time. In order to accomplish this the events are represented as SmallTalk parse trees at definition time in the same way that ~onstraint methods and response methods are represented. Then when the structure is built and the anima is initialized, the event messages are relocated to reflect the context.
The mechanism of TriggerConstraint allows for even more elaborate responses including initiation of an algorithm. A TriggerConstraint definition could contain code ~or the algorithm in the "causes:" field. Thus the selection sort algorithmic code appears in the definition of the SortQueue prototype as:

TriggerConstraint owner: SortQueue prototype to: 'list 'trigger: #selectionSort causes:' lleastl (1 to: listsize) do: [:i ¦ least <- i.
(i + 1 to: list size~
do: [:j ¦ (list compare: least with j) ifTrue:
[least <- j~]
~least = ij ifFalse: llist swap: i with: least]]'.

- This code is recompiled in the ~ame way as ;; other responses. The references to selectors such ` ~ 35 as "compare:with:" and "swap:with:" can be desig-- `~ .

~. .. ~ , . . . :
.
.~ : , ' ' ~ . , ' .

~7~3~
~s nated as triggers to be changed during compilation to refer to the new methods which also contain the - specified responses, as described in the next sec-tion. The algorithm is then typically invoked by sending a message to an instance owning the con-straint by pointing at the object using a "Kicker"
tool described hereinbelow. Conceptually the con-straint satisfies itself by enqueuing its expres-sions upon having been "kicked", but those expres sions must first be relocated into the particular context in a manner d~scribed below.
A problem may arise in building animations in which one part of the system wants to send a message to another part which is not a subpart of the first part. For example, in the aforementioned Producer-Consumer animation, when the Buffer has been told to enqueue or dequeue an element, it must indicate to the Monitor whether it is not ull or not empty. Thus the Buffer prototype contains the methods:

enqueue: element list add: element.
~dataLead ancestral: 'Monitor') notEmptySignal.
list size = maxSize ifTrue:
[(dataLead ancestral: 'Monitor') fullCondition]

- de~ueue (dataLead ancetral: 'Monitor') notFullSignal.
listsize = 1 ifTrue:
- [(dataLead ancestral: 'Monitor'J emptyCondition].
tlist removeFirst .~ .
The Producer prototype contains the followiny method:

.': . ', - - : ' ' , - ' . ~

.
- . . .
.

~:7~3~(~
~6 produce dataLead node ancestral: 'Monitor' send: 'enq:' with: currentDatum.
currentDatum ~- (currentDatum asInteger ~ 1) asCharacter . .
The receiver of the producer's production is intended to be the monitor itself, but graphically, we are only able to merge part of these objects, their dataLeads, to indicate this. Access to parts in ThingLab is strictly top-down via name paths, for example "MPC producerl dataLead node value."
There are no back-pointers from parts to their ancestors in the hierarchical structure. The "ancestral:send:with:" message allows us to send a message indirectly, again via the root where global responses are compiled so that constraint satisfaction is guaranteed.

Method Relocation Important to the implementation-of either kind of temporal constraint is the process of reinter-~; pretation of messages. New methods must be compiled in which actions are taken to satisfy the constraints (i.e., to enqueue the appropriate responses) while executing a received message. This is managed through a convention established in Thinglab that messages to a part in the structure are all sent :
through the root of the structure via a path con-sisting of part names, Furthermore i~ a method defined or used in a part is constrained (i~e~, is the trigger of TriggerConstraint) or affects con-~; strained parts, then a new method is compiled into the anima with a unique selector constructed ~y pre-fixing ~he path names to the original selec~or.

, ~''' . ' . ~: ` ' .' ' ' ~ . -, 3~

This convention of access via root and pathsis a very natural approach in Thinglab where user : request~ drive the changes in ~he constr3ined structure. Access by the user to the ~tructure i8 thr~ugh the browser having an instance variable pointing to the root object of the ~tructure. The constraint satisfaction mechanism depends on the passage of the ~essage down through the network, checking at each node whether the ~essage pathway overlaps the path to some constrained pa~t, ~nd thus whether tha~ constraint ~hould be add~d to the list of those whose ~tisfaction must be assured.
: In Animus more often me~sa~es causing change~
in the structure come from within the structure itself, from the execution o~ the algorithm being animated. A knowledgeable part o~ the ~tructure can only send ~ message directly to another part at the risk of subverting the constraint ~echani~m altogether. Constraint satisfaction can only be : 20 guaranteed if message pas~ing among parts of the s~ructure is done by ~ending messages to the root anima and ~rom ~here Vi3 a pa~h down another branch, which of course entails overhead~ Specifi-cally this means that not only must any method : 25 whose ~elector i8 a trigger be relocated; but any . method that uses a triggered method ti.e~, ends a message ~ith a selector ~o an object owning a :~ triggerConatraint Gn that selector~ must also be reloca~ed so that those ~alls on the ~riggered method can be routed through the ani~aO Fortun-ately the user need ~ee none of the relocat~d : methods and need only concern himself with the imple for~s of methods he may define local to .

.

: . .,. ,: . :

3~

components. Once the network of paths is esta blished upon construction of a new prototype obiect from kit components, the system takes care of interactions and relocations~
Suppose for example that one wishes to send a message to change the value of the current through a capacitor in the aforementioned RC circuit.
Access to the object representing the curren~ would be Yia the path nthing capacitorl leadl current".
Each path na~e is both the name of an instance variable and also the elector of an automatically ~enerated ~ccess function which ~imply returns the value of the named variable. Thus ~he path is in fact an executable message, or fieguence of messa~es, which will return the desired part.
~uring the process of relocation, aPter a component is inserted into a stru~ure ~uch as ~he capacitor into the RC circuit) the paths to its parts must be : extended to reflect its position in the structure.
Thus in ~onstraint methods defined local to the capacitor, there may be references to ~leadl ~urrent~, and all such referen~es will be ex~ended as above to ~thin~ capa~itorl leadl current~n Trigger selectors are similarly trea~ed upon relocation in that they are extended by the path names to the part where the trigger is definedO
HoweYer, the path names are no longer executable p~r se, but rather are joined together into a single long selector without spaces in order to provide a unique selector in the anima for that trigger~ The sy~tem then compiles a new method for that selector into the anima. For example, assume that one wishes to animate the swap of two elements in a li~t which is part of a laryer structure. To do ~o one would state a trigger constraint in the list objec~r .. . . . . .
..

' ~ .
.

a~

tri~gerin~ on ~he selector ~swap:with:~, defined in the ~tandard Smalltalk sy~tem in class SequPncea~leCollection. Note that there may be other lists in the object which may be not animated to avoid ~creen clutter. One does not wish to change the behavior of all lists, but only this paxticular list. If the path to the ready list is, for .xample9 ~thing ~im Xernell readyListl list," then a new method will be compiled into the anima with the ~elector "thingsimker~ellreadyLi~tllistswap:with:" which instantiates a pair of Trajectorie~, asks them to enqueue their events, and then performs the primative ~wap:wi~h: method on the list. This arrangement requires that any method sending th~
message "swap:with:" to this li~t must ~e relocated ~o that it employs the extended ~elec-tor in order to ensure ~onstraint ~atisfactionJ
This bit of book keeping is ~acilitated by a standard Smalltalk system utility that returns a list of ~essage selectors used by a method which can be checked at compile ti~e against a li~t of triggers.
Relocation functions ar~ provided by adding protocols to the classes u6ed by the Smalltalk compiler itself~ The compiler ~cans a source method as a string and crea~es a graph o~ parse tree nodes representing that method. Thus the compiler uses classes ~uch as A~ign~entNode, BlockNode, ~e~sageNode, and YariablQNode, all : subclasses of P~rseNode. Each of these cla ses -~ are proYided with methods as needed to respond to ~protocols ~uch as "relocatePaths: aPathPre~ix"
which typically will perform a local change ~o create a ~ew ~elector by concatenating . .

- . . ~ . .

~aPathPrefix" onto the original selector. The relocation message and path extension are then recursively passed down to descendant nodes in the parse tree, such ~s to arguments or subexpressions.
The processing is thus distributed among object~
which perform relati~ely simple local transforma-tions, and complexity is dealt with in the recur-- sive calls. Each node in this recursi~e calling BeqUenCe returns a new structur~ with the altera~
tions in place, and these returned structures are assembled into the new transformed ~ethodNodeO
.Once methods have been reloca~edt the selectors that have been d~signated triggers in TriggerConstra~nts require special treatment.
~ithout any special treatment, ~ message such as nlistswap: tl w~th: t2," would relocate into ~ome~
thing like "thing ~imKernell readyLi~tl lis~ ~wap:
tl with: t2~. In other words, the reference to the variable "list" is relocated but nothing i8 done to 2~ the selector. But since this ~el~ctor is t~ ~rigger a response, that response has recompiled into ~he anima under a new selector, such ~s ~thingsimkernellreadyLi6tllist.swap:with:" which does ~- the ~wap as well as ~nqueuing the required responses.
Thus during the process of relocation, all designated trigger selectors and the paths to the objects in which th~se selectors will trigger responses are maintained on a list. When these selectors are encountered~ they are replaced by new selectors generated by ~compressing" the path into the original ~elector ~o that the proper method, including the response, is executed. This Gompres--~ ion is accompli~hed in a manner similar ~o reloca tion, by adding ~ethods for the protoeol "compressTrigger~trigger~" to a number of compiler 1~7~3~13 ~rs~acsa~ classe~. Nere ~triggers~ ~ a Ii~t of selec~ors and as~ociated path~ to p;~rts ~here those ~e1ector~ are defined to be trigger~. ~hu~, oF
example, a ~ethodNode instance responds to ~hi~
pr~tocol by te~ting whether "triqgers~ include~ the E~elector of that ~et~Qd~ode instance. I 80 th~
method is redirected ~o ~he anima ti.e., ~he receivex i~ ~s~igned to be n~el~ and the ~elector i~ ext~nded by concatenati~ the pa~h ~o the def ining part to the selector. Then the WcompressTrigger:" ~e~aqe is recur~iv~ly ~ent tD
the argu~e~t~ to the ~ethod t~ ieh ~y be 2xpreso ~ions). If the ~ethodtNod~ lector i~ ~ot among the trigger~, then the ~elector i~ l~ft a8 i8, ~nd :- 15 the ~co~pre. sTrigger:" me~sag~ aply pas~ed to both ~he rece$ver expre~sion and the ~rgumen~
5~3 ~e~
In order tc~ su~arize ~nd clarify ~he sbvve discussi~n, it ~ill be useful to preserlt in full the rç!sults of msthod relocation fox the preYiou~ly di6cus~ed sorting ~x~mpl~ of FIGSo 9-~3. R~call that the ar~irDation f lashes th~ bar~ representing -- ~nagnitude~ upon comparifion ~nd then a~OV~8 the bar~ ~moothly and ~lmultanesusly to show swapsO
The algorithm~c ~ode cont~ined in ~he ~3cit~ collnponent ;ortQueue i8 ~oded ~n ~ ~traigh~forward ~nanner in Smal ltalk as fol lows:
. .
~elæt:tionSor~
least -~ tlto: li81: size~ do~
l~ast ~ iD
(i~l to~ t ~iz~) do: t~ li8~ comp~re: le~st wi~h: ~3 ~rue:

. ~ . - . ., , , , :, :
. ' ~' . '.
. :

1 le~t ~ j 1 1.
least ~ i if Fal~e: llist ~wap~ ith: least] 3 SIn ~ddition the $or~Qu~ue componQnt defines two trigger eonstraints.

. .
: ~ TriggerCon~raint owner s SortQueue prototype to ~ t ' trigger: ~cor~par~ ~ wî~h: cau~e~:
10' ~F~asher with ~list a~: al) ) enquet!e~ven~.
tFla~er with: ~list a~: ~2~ ) ~nque~e~Yeilts~
q~risgerConstraint ownero Sor~Q~eue proto~ype to~ 'li t' trigger: #swap: wit~l: cau~e~:
' ~Trajectory wit~: (li~t ~t: al) 15de~tination~ 'L at-a 2~ ~ ~nqueue~3Yent~
(Tr~jectory with: ~I ist at: a2) destination: ~liæ~ at: al) ~ enqueueEve~s~ ' When a g;orSQueue is in~erted ~ a part of a 20~tructure and the ~nim~ o that ~tructure i initializ~d, the~e will be defin~d ~n the ela~ of - ~ that ~ni~a the method:

thinq~orSQu~u~3 1~ . 4election5ar~
Itl ~2 t31 :~ ~1 to: thinq sortQu~ue3 li~t 8iZ~) : do: ~:t2 ¦
tl ~ t2 : tt2 ~ 1 to: thing ~ortQueue3 li~t 5ize) do~ 3i (~elf thing ~or~u~ue3 lis~compareO ~I wi~hs t3 i~rue: ltl ~ ~3J3 : tl ~ t~
if~al~:
35l~elf thingsortQueue31ist.~wap: ~2 ~i~h: tll~.

, . . . . .
.
. : . . .
:, . . :, :, .
, . .
-,' .' ' self tick: 1.
~nil Since this method is generated by the sy~tem and there is no corresponding ~ource code, the local va~iable~
tl, t2, etc. are generated in the decompil~tion o~ the compiled method. There are three significant differences to notice between this method and the ki~
component method. The first is the path exten~ion to all references to local instance variables, as indi-ca~ed for the variable ~list" in this example. ~ext, the designated trigger selectors have been extended by concatena~ing the path exte~sion t~ the original ~elec~
tor in the same way that khe "~electionSortN sele~tor it~el~ was changed. Finally an explicit tick message - has been inserted to insure that enqueued ~vents occur~
Furthermore the new method called by the method above will be defined in the anima so that they include the specified responses:
: 20 thingsor~Queue31ist.æwap~ hs ~2 ~Trajectory with~ (thing ~ortQueue3 list at: tl) destination: (thing sor~Queue3 list at: ~2) ) enqueueEvent~.
2~ (Trajectory with: (thing ~ort~ueue3 list a~: t2) destination: (thing sortQueue3 list at: tl~
enqueueEvent~0 selftick: 1 ~- ~thing soxtQ~eue3 list swap: ~ with: t2 thing~ortQueue31i~t.co~pares tl ~i~ t~
(Flasher with: ~thing sortQueue3 li~t at~ tl) enqueueEvents.
- (Flasher with: (thing ~ortQueue3 li~t at: t2) enqueueEvents.

. .
' , ~ . ' .
.

. ' . '.: , ' ~7~3~

~lftick : 1 ~thing sortQueue3 list compare: tl with: t2 Again notice that the system has inserted the "selftick:~ message ~o that the ~ewly enqueued events are ~xecuted forthwith.
. .
: Responses The specification and activation o~ a ~emporal constraint i~volves the r~alization of a responQe.
~ Responses in Animus ~re implemented by classes that -~ are subclasses of ~he abstract superclass Respo~e.
Ti~2Differenti~lConutraint~ which model continuum ~: processes cause instantiation of I~oedia~eRespo~es ~ 15 which are the clos~st thing to the instantaneous ; reactions of the continua being modeled.
TriqgerC~n~traints often cause more elaborate : responses such as instances of Flasher, vr ~raje~tory~ detailed hereinbelow. An inst~nce of class ~e~pon~e is an object that repre~en~s an :~ abstraction of the event sequence. The parti~ular sequence i5 g~nerated when ~he ~e~pon~e is realized by sending it the message "enqueueEvents,~
~ or ~ore generally "enqueue~ents~t: aShift with:
: 25 aStxetrh,~ where the parameters are temp~ral translation and scaling r~spe~ively. All ~: instances:of response classes understand t~ese ; . message~ and react ~y generatIng an ~vent tream :. and placing:i~ ~ime-ordered into the eventqueue.
` 30 The parameters ~aShift~ and ~aStretchU axe ~:
defaulted ~o ~ero and one resp~ctively ln the simpler message ~enqueueEvents,~ that ~s~the event stream is~o start immediately and to be of the ~tandard duration. Re p~nses can ~al80 be realized ~which are giYen o~her parameeer~ suoh as the obj-ct . . : ~
:
.: ; , 3~(~

~hose image i8 to be mo~ed. Maintaining descr~ p-tions of resporlses iD relatiYely 2bstract term~ in the~e cla ses, rather than concretely instanltiated, allow~ greater ~lexibility. For exa~nple a ~imple paramet~r ~ay determi~ae whet~er ~n icon ~ 'co mv~s ~long a trajec~ory in const~nt time, or Zlt ~ con-st~nt velocity.
FinallyD ~ TriggerCo~ r~in~ may be crea~ed without using ~he convenien~e oiE abs~ract Re~3po~:~e~
at ~11, but rather a "cau~e~ ield ~ay be fi~led wi~h a ~tring of arbitrary Small~c~lk expressions~
Thi~ ~s the means by whlch an arbitrary algorithm e~ay be specif ~ed, as ~ ~he 80rting ~xamples.

~
- ~ny animation ~y~em ~hould be able to periEorm a ~equence of a~ctions ~ccording to ~oe~e predefia3~d ~cript. A re~ponse of Cla8EI ~ ript i~ ini~ialized wi~h a pointer to a file containing ~n ~rr~y of ~trings whi~h can be compiled into ~es~ge~ to create new event~. Fo.r exampl~, in the pr~iously des~ribed Monitored Pr~ducer-Con~umer ani~atio~, one might li~e the produ~er ~nd con~umer to ~utono-~ou ly produce and con~u~e ~t rert~in ti~e~
according to 8cript8, rA~her than the u~er having to send individual ~es~age~ ~o initiate ea~h pro-duction and con~umption. Thu~ su~h a Producer proto~ype contains the con~traint:

TriggerConstraintown~r: Produ~er prototype to: 'self' trigger: #run~crip~
causes:'lScrip~ fro~File: ~Produc~rScript~
~nqueueEvent~To: 8~1' where the file ~ProducerScript~ contain~ ~trang~ like:

~, . .

~7~

vent n~w atTime~ 1 receiver~ ~elf ~elector: ~produce argument~
'~Yent new ~tTi~e: 4 receiYer: self ~elector: ~produce argument~
~h of ~hese event~ 8~ described in ~h~ file ~ust be re~o~piled and redirected ~o that ~t co~pile time ~he con~traint hold~ an ~xray of Smalltal~
parse tree~ representing ~s~aqes to ~8 xeceiYed by the ani~a o~ the ~onitored Producer-Consumer anima~ion7 Selectors ~thingproducer3.producen ~xe extended to reflect ~he con~exts, and the time stamp~ are ~h~f~ed relati~e to the ~urrent tl~ Notice th~ th~ events ~re rerouted through the ani~a ~ince : 15 that is ~here the graphical re pon~ ha~e ~een compilèd. That i-, ~he con~traint, ~riggerConstrain~ o~ner: Producer prototype toD 'self' trigger: ~produce cau e~ ' ~Traiectory with:
(~o~enge form: l~orm dotOfSizet 20) ~rame: ~frame coEn~r extent: 20Q203 ~ label: currentDatum) ;~ 25 dest~natlon:.d~taL2ad node) enqueu~vent~', ha~ led to the compila ivn into ~las~ ~PCAnima of the ~ethod, :
- 30 ~hingpr~ueer3.produce ; ~Traject~ry withs (~ozenge orm: !Form dotOfSize~ 20~
frame~ ~thing producer3 fr~me corn~r ~ :
. :

..

. ..
. .

.

7 ~

extent: 20@20) label: thing producer3 currentDatum) destination: thing producer3 dataLead node~
-~ enqueueEv~nts.
self tick: 1.
tthing producer3 produce.

. .
This ~ethod includes the desired graphical response.
To have sent the "produce" mess~ge directly to the Producer would effectively subv~rt the tempor31 constraint mechanism.

Sequences are used when the desired animated effect cannot be simply achieved by making an icon move across the screen~ but rath~r re~uires that the icon change ~hape, a~ f~r instance when an icon in the form of a human ~walk~ across ~he screen.
Like a Script, a Sequen~e is initialized with a pointer to a ~ile containing ln array of bitmap~ and at compile time thesc bit maps are s~ored into the con~raint whose response is the ~equence. Sinc~
the realiæation of a Sequence does no~ involve me~sage passing like ~r~pts, but only display of the bitmaps, thexe i~ no need at compile time for methods to be relocated.

: : Immedia~e Responses In a continuum process described by a time differential constraint, the changes ~o specified occur instantaneously, 2110wing one to w~ite an equation ~uch as i - dqJdt, which in the real world is ~rue at all in~initesimal instant~. In ~he digital world ~his must be model~d by a se~uence of a~signments and a flnite time granularity. Th-s ' . .
;, .

.
~ '. .

~ ~af3~

the satisfaction of a Ti~eDif~rentialCon~traint, - which will be a~sured at ~very increment of ~he clock, involve~ the instantiation of an I~ediateRespon~e. An in~ance of Io~ediate~e~pons~ enqueue~ a single event to ~au~e the change specified by the constraint~ ~uch as decrement~ng the charge on the capacitor by i~dt in the RC circ~it. Note that ~ince the increment to the ~harge calculated at time ~to"~ namely dq ~ i~dt, i~ assigned in the next in~tant, time ~- ~to ~ dtn, the es~ential feature of the approxi~ation ha~ been achi~vedt the ~deriv~tiYe~ ~alue ~eurrent) has be~n considered good for ~h~ duration of the time interval in order to get a first approximation to the new Yalue of ~he differential variahle, that char~e, a~ter which other values ~re adjusted according to the cons~raint~ for ~tatic con~is-tency. ~his serves to break the in~tantaneous circular dependency implied in the constraint equa-: 20 tion, that the charge depend~ upon the ~urxent which in ~urn depends upon the ch~rge.

The abstraction of the func~ion of ~ovinq icons across the ~creen is i~plemented by the clas~
~r~cctory. An instance of class Tra~2ctory i~
created by ~pecifyinq at l~e~s~ the ob~ect whose i~age i~ to be ~oved, ~nd where it i8 to m~ve.
Additional in~tance ~reation ~essag~s m~y also ~pecify how it is to Mo~e~ for example ~t con~tan~
elocity or ~long a curved path. But the default is that the icon will be ~oved in ~onstant t~e9 that is, in a cons~ant nu~ber of ~teps along a straight line betwe~n it~ original po~i~ion ~nd ~he ; 35 destination. ~r~e~toEie~ with a~ many as ~en . .. ~ , - :

., - : , 7 ~ 0 steps and as few as four have been tested. More steps create ~moother movements, but typically ~our ste~s ~eem adequate to provide the illusion of ~mooth motion, the eye seeming ~o do the interpola-tion on its own, with only the barest ~ugge~tion of intervening positions. The motivation for usiny fewer steps is that in some cases where a single triggered c~nstraint causes the instantiation of four ox five trajectories interleaved at the ~ame time, there is a noticeable delay while forty or ~ifty events are created, initialized and in~er~eB
time-ordered into the eventQueue.
A non-tri~ial feature o~ the behavior requir2d of trajectories is that they should not spoil ~he .15 display as they move a~ross i~ but should crea~e the illusion that an ic~n being moved ~lides over the display. This means that upon initialization, a trajectory must tore a picture of the background of the re~ion across whi~h it will travel and then~
at each step of the way, it must restore the portion of background upon which the icon had been sittingO

Flashers Class Flasher~ pr~vides anoth~r useful anima-tion response. ~ Pl~sher is instantiated by simply specifying the region of the ~reen, a reGta~gle, ~hat is ~o fla~h. ~n instance of ~lasher then respo~ds to th~ me~sage "e~queueEvents~ by ~reating and enqueuing a ser~es of events that will flash the region on the screen. In the previously des-- cribed sorting algorithm this respons~ i~ used to point out the bars whose height~ are being compared.

User ~nterfae~
~he user interfa~e to Animus is si~ilar to ~he ~ .

.

- ~

ThingLab lnter~ce with a f~w poæ~ible ~hanges zlnd additions. The Glasses Ani~u~E~r~3ser and u~ro~r~er~ieY are 6ubclasses s;f ThinglalblBro~r~er and Thi~lab~lrc~ser~ie~ respectlv~ly. The prin~ipal desirable difference consi~ts $n the addition of a number of ~ool~" wh~ch appe~r as ite~s in the khird pane o the browser. These tool~i described h~rein--below, pertaln to the ~an~ge~ent of ~i~ul~tion t~me,, edi~ing arld message $endinq to parts, and the addi-1:ion of element6 to i~dexed part~ . list~.
The ~ost fundarnenta~l addition t~ the 6et o browser tool~ i~ the cla~fi 113r~r ~hich ~8 activated 3by ~electing the ~tem ~gOn in the third pane of ~he browser. The ba~ic fun~tion of the driYer is to repeatedly ~end ~tick:dt" me~se~g~3 ~o the anima of tA~ ~elected prototype. It has pro~ren useful to add to DriYer capabiliti~s ~o recognize when ~ tic3c c the cloc)c ent2il8 1110 graphical change ~o that redrawing can be ~uppres~ed, s~gni-ficantly ~proving the re6ponse of ~om~ ~imula-ti~ns. Al~o it is u~eful to h~ve the ~Iriver ~heck for u3er input request~ at each tick- IDri~cr i8 a subcla~s of the ThingLab cla~ ~ool and inherit~
rom it the ba~ic ~chedulir~ protocs:~ls. ~h~n th~
- 25 browser i~ ~tarted UPD the selected 1rool execut~
the method:

~tar~Up
6~?1f fir~ti~ne ifFal~e: [~false].
1 el eachtiniel whileTrue.
î self l~sttime .

Thi~; ~ethod ~llow~ the ~elected tool ~o ~ine partis:ul~r prelud~, execution loop ~nd po~tlu~e function$. Irl response to the ~fireti~a~ me~s~ge, .

. .
"' ' ~ ', ' ' '' ' ~ ' " , .
-'. . ~' ~.' .. . .

.- ~ - . .

a Dri~er ~ends the ~ ge "~lection ani~a initiali~e." Thi~ will not ne~e3~arily e:au~e the anima to reinitialize and pe~orm the involYed method relocation for temporal constraints since the ani~na keep~ an inst~nce variable~
which i6 set true upon initi~liz~tion and r~se!t fal~e ~hen ~ny stxuctural ch~n~3es are Dnade ~hic:h ~ould Eeguire reco~pilatiQn o~E constraint ~e~hodsr Thi~ is ~o ~vo~d unnece~sary re~o~pil~tion every tim~ the ~imulation ~ re~tarted wh~n no ~tructural changes ha~r~ beerl made .
~he alethod ~ea~hti~e~ def in~d in ~ri~r~r E~end6 the ~election'~ anima the ~essage ~tick": ~election anima del'caTK. The ti~e incre~ent ~5 ~ 50 s~or~d as an in~tance va~riable in the~ anima so that th~
user may adju~ the Ngrasaul~rity~ of the a~ni~ation.
The input ~ or li,,e., ~he S~alltalk o~ject repre-~nting the mou~e and it~ ~tate) i~ then checked to ~e if the appropriate mou~e button i~ pre~ed, and if ~o ~ pop-up ~enu i~ pre~ented ~or ~Ihe ll~er to ~end a mes6age ~o the ~election.
General~ty requ~r~s that th~ ~enu and it~
actlons be def ined by the particul2ar ~hing being di ~playedl ~ince difiEerent u~er interac:tions ~re appropriat~ for different simulations. How~lrer, the ~elec~ced proto'cype ha~ been c:on6tructed graphi~a~ly ro~ kit ~omponen~, and the user ha~
had ~ei~h~r ~he ~e~ns nor ~he oppor~unity to define menux and their fun~tioJIs. The~e ~enus are prede-f in~d in the kit c~ponents. Al 1 that is known in advance abou~ a n~wly cre . ~ed ob~ec:t i8 that i~ is a subclass of ~i~u~0bj~¢t. ~rhu% the de~ired blchaYior i8 ae::hieved by def ini rag tlle protoeol ~get~enu~ in Ani~u~Ob~ect that querie~ its part~
and c:onstru~ts a ~R~nu aontai~ing item6 for inter~c~
' .

v tions with any component kit part that have ~uch interactive capabilities defi~ed in them.
Finally a Driver keeps a Boolean variable "picturesChanged" ~et by any response event that moves components around on the screen so that a picture buffer update and redisplay is needed.
Otherwise if nothing has happened to alter the picture ~ince the last tick, redrawing is omi~tedO
In some cases it is desirable to be able to directly set the absolute value of time, rather than to simply increment it. Thi~ is not generally possible for animations who~e state is generated incrementally, but rather only for those whose state is strictly det0rmined as a direct function of ~ime. The ~ystem provides the class ~etter, a subclass Qf class Tool which is activated when the user ~elezts ~settime~ in the third pane of the browser.
A Tic~er tool i5 selected via the item "tick : 20 ~ize" in the third pane of the browser and allows the user to adjus~ the granularity o.f the time in~rement that i~ sent with each new tick message . to the anima. Like the Setter this tool prompts the user for a new value in a pop-up window, and whatever the user accept~ in ~ha~ window i8 assigned as the new value ~f the time increment ~ used by the anima in ~tick:n me~sages.
: Algorithm animation applications typically - display data structures ~uch as lists~ ~r arrays, : 30 or in Smalltalk terminology, ~indexed part~.
: Smalltalk make.~ a fundamental distinc~ion between vbjects whose parts are na~ed instance variable~
and those whose parts are unnamed and accessible by index. The difference implies that when a user - 35 builds an objsct in Animus, he can either insert a .

. .
.

new part as a new named instance variable, or he --- may add elements to an already present ~ndexed structure such as a list~ It happens that proto-cols provided by ThingLab only allow access to named part via path names ~uch as ~circuik capacitor2 leadl node voltage." But what about a path like nos kernel pauseQueue2 list4 processPriority," where the ~4~ refers t~ the fourth indexed Pro~ess in the ~is~ managed by a : 10 PauseQueue in the OS kernel? Since in ThingLab, interpretation of a path to a part inv~lves the performing of the name as the selector of a message sent (the access functions to named parts already having been automatically compiled into prototypes) this involves ~he overridi~g in Animus of the rather fundamental Smalltalk protoool in ~las~
Object, "perform: aSelec~or with: arguments." Thi~
method (a primative) is provid~d with addi~ional - code ~should the prima~ive fail) to interpret a S~allInteger such as 4 as the name of a mes~age selector which returns the fourth indexed part.
The interface offers ac~e~s to indexed parts through class Stic~er (detailed in ~ppendix I~, a tool which one s21ects by choosing ~add" in the third pane of the browser. This tool allows ~he us~r for ~xample to graphically add ~lements to an array ~o be sortedO
:` A tool called a ~icker (detailed in Appendix ~ I) allows one to send a mes~age ~o an object on the - 30 ~creen, ~uch as to tell a particular array to ~or~
itself. The ~hoice of ~send message~ he third pane, like the ThingLab tool ~move~ flashes a~
image of the prototype of the thing to rec~i~e the message. The prototype image sticks ~o an instance on the screen of that type~ and the selected -,: .
, .

~4~

6~

instance thereupon relocates into the anima the methods of afiy triggered selectors. ~hese are the mess~es one is then allowed tQ send to that instance, and the user is ~ffered a pop-up menu from which he may select one of the messages. This mechanis~ underlies the starting up of the pre-viously described sorting example.
Class Pic~er ~detailed in Appendix I) provides the mode o interaction one expects from selecting "edit" in the third pane o~ the browser. Like the ~ic~er, 2ic~er shows the user a flashing image of the prot~type of the thing one wants to edit which sticks to an instance of that prototype. Thus having made the choice, Animus takes advantage of the general SmallTalk class In~pector, and simply opens ~p a system inspector on the instance chosen.
Thus accordin~ to the present inven~ion the temporal behavior of a mode1 embodied within an object oriented computer programming system is controlled by a ~ime managemen~ object which incre-ments a simulation time by adjusting the value of a variable representing ~ime and which maintains an eventqueue ~or s~oring ~ime ~tamped repre~entatior of messages to be sent to the model. The time management object is further adapted to transmit any message representation in the eventqueue to the model when the time represented by the time variable surpasses the time indicated by messages's time ~tan-p and the model ~s made to respond to a triggering eYent in a temporal fashion by ~toring : one or m~re time stamped message representations in the eventqueue so that as the time management o~ject incremen~s the time variable, the messages described by the ~Yents are sent in time ~tamp~d order.
'' . ' : ,'. ,:
. ; . ,:

.

3~1 ~5 ~urthermore, the temporal behavior of the - model is described according to a ~et of temporal constraint~ invoked in resp~nse to triggering messages. ~hen a triggering message is sent to the model for which no procedure has been compiled for ~atisfying temporal constraints triggered by the message, a response procedure is compiled and exe-cuted which stores the appropriate message repre-sentations in the eventqueue ~uch tha~ as the time management ob~ect increments the ~imulation time, it transmits the appropriate messages at the appro-priate time to cause the model to carry out proce- -dures in satisfaction of its temporal constraints.
Therefore ~he present invention not only te~porizes the behavior of ~he model through the use of the e~entqueue, it also ccmpiles methods for ~atisfying the temporal constraints on the behavior of the model~
While a preferred embodiment of the present invention has been illustrated ~nd described, it will be apparent to thos~ ~killed in the art that : many changes and modifications may b0 made wi~hout departing from the invention in it~ broader -: espects. The appended claims are ~hsrefore - ~5 intended to cover all SUCII changes and modifica-~ tions as fall within ~he true spiri~ and scope of :~ the invention.

~ 35 : ' '' ' .
:- , ., .
.-. , -'

Claims (16)

Claims
1. A method for controlling behavior of a model embodied as a group of interactive objects in an object oriented computer programming system the method comprising the steps of:
describing the behavior of said model according to a set of constraints on said behavior of said model, at least one of said constraints describing a temporal behavior of said model;
determining actions to be performed by said interactive objects and times at which said actions are to be performed according to said set of constraints; and generating events, each event comprising a representation of a message to be sent to said model, for causing said model to perform one of said actions, and a time stamp representing a time at which the message is to be sent.
2. The method according to claim 1 further comprising the steps of:
storing said events in an event queue;
incrementing a variable representing time;
and transmitting to said model a message represented by an event stored in said event queue when the value of time represented by said time variable surpasses the time indicated by the time stamp.
3. A method for controlling behavior of a model embodied as interactive objects in an object oriented computer programming system, the method comprising the steps of:

defining the behavior of said model in response to a triggering event by a network of constraints, including temporal constraints, on the state of said model following said triggering event;
creating and storing in a memory, representations of messages to be sent to said model and a time stamp associated with each message representation, each said message causing said model to perform an appropriate action at a time indicated by the associated time stamp to satisfy said network of constraints;
incrementing a variable representing time;
and transmitting each of said messages stored in memory to said model when time represented by said time variable surpasses time indicated by the time stamp associated with the message.
4. A method for simulating interactive elements utilizing a model embodied within an object oriented computer programming system wherein said model exhibits temporal behavior, the method comprising the steps of: .
instantiating a time management object for executing procedures embodying the temporal behavior of said model, including adjusting the value of a variable representing time and maintaining an event queue for storing events, wherein an event comprises a representation of a message and a time stamp indicating a time at which said message is to be sent, said time management object being adapted to send a message to said model when the time represented by said time variable surpasses the time indicated by the time stamp;
instantiating a temporal constraint object comprising a description of a triggering message for the model and a description of a temporal constraint on the behavior of the model in response to said triggering message; and compiling a response procedure to be executed by said time management object for storing a response event in said event queue, said response event comprising a time stamp indicating a future time and a representation of a temporal constraint satisfaction message to be sent to said model for causing said model to satisfy said temporal constraint.
5. The method according to claim 4 wherein said response procedure is compiled in response to said triggering message.
6. The method according to claim 4 further comprising the step of executing said response procedure whereby said time management object stores said response event in said event queue and then sends said temporal constraint satisfaction message to said model when said time represented by said time variable surpasses said future time.
7. The method according to claim 4 wherein said triggering me sage described by said temporal constraint object comprises a message sent to said model and wherein said temporal constraint is a relationship between objects comprising said model which said model must satisfy when the time repre-sented by said time variable is incremented by a predetermined amount.
8. The method according to claim 4 wherein said triggering message described by said temporal constraint object comprises a time incrementing message sent to said time management object for incre-menting time represented by said time variable.
9. The method according to claim 4 further comprising the step of displaying an image on a screen of a computer terminal, the appearance of said image being controlled according to the tem-poral behavior of said model.
10. A method for simulating a collection of interactive elements utilizing a model embodied within an object oriented computer programming system, wherein said model exhibits temporal behavior, the method comprising the steps of:
instantiating a time management object for executing procedures embodying the temporal behavior of said model, including adjusting the value of a time variable representing time and maintaining an event queue for storing events, wherein an event comprises a representation of a message and a time stamp indicating a time at which said message is to be sent, said time management object being adapted to send said message to said model when the time represented by said time variable surpasses the time indicated by said time stamp;
instantiating a temporal constraint object comprising a description of a triggering message and a description of a temporal constraint on the behavior of the model in response to said triggering message;
compiling a response procedure to be exe-cuted by said time management object for storing a response event in said event queue, said response event comprising a time stamp indicating a future time and a representation of a temporal constraint satisfaction message to said model for causing said model to satisfy said temporal constraint, said response procedure being compiled in response to said triggering message;
executing said response procedure whereby said time management object stores said response event in said event queue and then sends said temporal constraint satisfaction message to said model when said time represented by said time variable surpasses said future time; and displaying an image on a screen of a com-puter terminal, the appearance of said image being controlled according to the temporal behavior of said model.
11. A method for animating the operation of an algorithm utilizing a model embodied within an object oriented computer programming system, wherein said model exhibits temporal behavior, the method comprising the steps of:
instantiating a time management object for executing procedures embodying the temporal behavior of said model, including adjusting the value of a time variable representing time and maintaining an event queue for storing events, wherein an event comprises a representation of a message and a time stamp indicating a time at which said message is to be sent, said time management object being adapted to send said message to said model when the time represented by said time variable surpasses the time indicated by said time stamp;

instantiating a temporal constraint object comprising a description of a triggering message indicating performance of an action performed by said algorithm and a description of a temporal constraint on the behavior of said model in response to said triggering message; and compiling a response procedure to be exe-cuted by said time management object for storing a response event in said event queue, said response event comprising a time stamp indicating a future time and a representation of a temporal constraint satisfaction message to said model for causing said model to satisfy said temporal constraint.
12. The method according to claim 11 wherein said response procedure is compiled in response to said triggering message.
13. The method according to claim 11 further comprising the step of executing said response procedure whereby said time management object stores said response event in said event queue and then sends said temporal constraint satisfaction message to said model when said time represented by said time variable surpasses said future time.
14. The method according to claim 11 wherein said triggering message described by said temporal constraint object comprises a message sent to said model and wherein said temporal constraint is a relationship between objects comprising said model which said model must satisfy when the time repre-sented by said time variable is incremented by a predetermined amount.
15. The method according to claim 11 further comprising the step of displaying an image on a screen, the appearance of said image being controlled according to the temporal behavior of said model and representing said action performed by said algorithm.
16. A method for animating the operation of an algorithm utilizing a model embodied within an object oriented computer programming system, wherein said model exhibits temporal behavior, the method comprising the steps of:
instantiating a time management object for executing procedures embodying the temporal behavior of said model, including adjusting the value of a time variable representing time and maintaining an event queue for storing events, wherein an event comprises a representation of a message and a time stamp indicating a time at which said massage is to be sent, said time management object being adapted to send said message to said model when the time represented by said time variable surpasses the time indicated by said time stamp;
instantiating a temporal constraint object comprising a description of a triggering message indicating performance of an action performed by said algorithm and a description of a temporal constraint on the behavior of said model in response to said triggering message;
compiling a response procedure to be exe-cuted by said time management object for storing a response event in said event queue, said response event comprising a time stamp indicating a future time and a representation of a temporal constraint satisfaction message to said model for causing said model to satisfy said temporal constraint, said response procedure being compiled in response to said triggering message;
executing aid response procedure whereby aid time management object stores said response event in said event queue and then sends said temporal constraint satisfaction message to said model when said time represented by said time variable surpasses said future time; and displaying an image on a screen of a com-puter terminal, the appearance of said image being controlled according to the temporal behavior of said model and representing said action performed by said algorithm.

APPENDIX I

ANIMUS LISTING

Copyright (c) 1986, Tektronix, Inc.
All righes reserved.

Things put: Identity Dictionary new!

Smalltalk at: #Things put:IdentityDictionary new! Things put:IdentityDictionary new!
Smalltalk at: #ThingDefinitions put:IdentityDictionary new AccessPath Animus-compiling AccessPath extendedSelector: aSymbol "this is just like extendSelector but with a:on the end" extendedSelector:
¦wStrm?Strm¦
wStrm?StringnewWriteStream: 200.
?Strm?aSymbol readStream.
(?Strm upTo:$.)do:
[:c¦wStrm nextPut:c.].
(names copyFrom: 1 to: names size) do:
[:n¦wStrm nextPut: $.. wSTRm nextPutAll:n].
?Strm at End ifFalse: [wStrm nextPut: $.].
[?Strm atEnd] whileFalse:.[wStrm nextPut: ?Strm next].
wStrm nextPut: $:.
?wStrm contents asSymbol extendSelector: aSymbol extendSelector:
¦wStrm rStrm period¦
wStrm?String new WriteStream: 200.
?Strm?aSymbol readStream.
(period?aSymbol includes:$.) ifTrue:[(?Strm upPut:$.)do:
[:c¦wStrm nextPut:c.]].
(names copyFrom: 1 to: names size)do:
[:n¦period ifTrue:[wStrm nextPut: $.]. wStrm nextPutAll:n].
?Strm atEnd ifFalse: [wStrm nextPut:$.].
[?Strm atEnd] whileFalse: [wStrm nextPut:$.].
?wStrm contents asSymbol incrementLast incrementLast ¦strm¦
strm?String new WriteStream:200.
(names copyFrom: 1 to: names size-1)do:
[:n¦strm nextPutAll:n. strm space].
strm nextPutAll:'increment'.
strm nextPutAll: names last.
strm nextPut: $:.
?strm contents Animus-compiling AcessPath incrementSelector incrementSelector ¦strm¦
strm?StringnewWriteStream: 200.
strm nextPutAll:'delta'.
(names copyFrom: 1 to: names size-1)do:
[:n¦strm nextPutAll: n.strm nextPut:$.].
strm nextPutAll: names last.
strm nextPut: $:.
incrementSelector WithHead: aString incrementSelectorWithHead:
¦strm¦
strm?String newWriteStream: 200.
strm nextPutAll: aString.
(names copyFrom: 1 to: names size-1)do:
[:n¦strm nextPutAll: n.strm nextPut:$.].
strm nextPutAll:names last.
strm nextPut:$:.
?strm contents setLast setLast ¦strm¦
strm?String newWriteStream: 200.
(names copyFrom: I to: names size-1)do:
[:n¦strm nextPutAll: n. strm space].
strm nextPutAll:'set'.
strm nextPutAll:names last.
strm nextPut: $:.
?strm contents Animus-testing contains: other contains:
self isEmpty ifTrue:[?false].
?(self within:other) notNil or: [self tail contains: other]

ActionMenu Animus ActionMenu selectors selectors ?selectors AssignmentNode AssignmentNode Animus compressTrigger: triggers encoder:encoder compressTrigger:encoder:
?AssigmentNode new variable: variable value: (value compressTrigger:triggers encoder: encoder) from: encoder BlockNode Animus BlockNode add: aMessageNode add:
¦newStatements¦
newStatements?statements copyFrom: 1 to: statements size-1.
newStatements addLast:(ReturnNode new expr: aMessageNode).
"newStatements addLast: statements last."
statements?newStatements compressTrigger: triggers encoder: encoder compressTrigger ?BlockNode new arguments: (arguments collect: [:a¦acompressTrigger: triggers encoder: encoder])statements: (statements collect: [:$¦$ compressTrigger: triggers encoder: encoder]) returns: false from: encoder sourceEnd: 1 penultAdd: aMessageNode penultAdd:
¦newStatements¦
newStatements?statements copyFrom: 1 to: statements size-1.
newStatements addLast: aMessageNode.
newStatements addLast: statements last.
statements?newStatements preAdd: aMessageNode preAdd:
¦newStatements¦
newStatements?statements copyFrom: 1 to: statements size.
newStatements addFirst: aMessageNode.
statements?newStatements Boolean Boolean Animus Boolean isBoolean isBoolean ?true Collection Animus Collection compare: I with:] compare:with:
?(self at:i) value > (self at:j)value maxSize maxSize "Answer the largest basicSize which is valid for the receiver's class.
should answer infinity, but this is close enough."
?self class maxSize "for 16 bit 4404"
perform: aSymbol perform:
"send the receiver the unary massage indicated by the argument. The argument is the selector of the message. Invoke messageNotUnderstood: if the number of arguments expected by the selector is not zero.
"Modified for animus access to indexed parts:
(self isEmpty not and: [aSymbol class = SmallInteger]) ifTrue:[?self at: aSymbol].
"<primitive:83>"
?nil"self perform: aSymbol withArguments: (Array new:0)""old default"

Constraint Animus-testing ConstraintisTemporal IsTemporal ?false methodTrees method Trees ?method Trees ruleTree rule Tree ?ruleTree Encoder Encoder Animus Encoder nTempsIncrement mTempsIncrement nTemps?nTemps+1 scopeTable scopeTable ?scopeTable FieldDescription Animus FieldDescriptions isIndexed isIndexed "return true if I hold an indexable part - default is that I do not"
?false Form Animus Form form form ?self frame frame ?Rectangle origin: 0?0 extend: self extent from: aForm in: aRectangle "Create a virtual bit map from a user specified rectangular area in aForm. from:in:
Reallocates bitmap only if aRectangle = the receiver's extent."
(width=aRectangle width and: [height=aRectangle height]) ifFalse:[self extent: aRectangle extent].
self copyBits:(aRectangle origin extent: self extent) from: aForm at: 0?0 clippingBox: display boundingBox rule: Form over mask: Form black showsHistory ?true showsHistory Form class Form Class Form class Animus dotOFSize: diameter dotOfSize:
"Create a form which contains a round black dot."
¦radius form bite circle¦
radius ? diameter//2.
form ? self new extent: diameter@diameter offset: (0@0)-(radius@radius).
diameter <= 32 if True: "special case for speed"
[form black.
diameter <= 2 if True: [?form].
bite ? diameter//3.
form white: (0@0 extent: bite@1).
form white: (0@(diameter-1) extent: bite@1).
form white: (diameter-bite@0 extent: bite@1).
form white: (diameter-bite@ (diameter-1) extent: bite@1).
form white: (0@0 extent: 1@bite).
form white: (0@(diameter-bite) extent: 1@bite).
fonn white: (diameter-1@0 extent: 1@bite).
form white: (diameter-1@(diameter-bite) extent: 1@bite).
?form].
radius ? diameter-1//2. "so circle fits entirely"
(Circle new center: radius @ radius radius: radius) display On: form.
form convex Shape Fill: Form black. "fill the circle with black"
?form "(Form dotOfSize: 20) display At: Sensor cursor Point"
dotWith: a Character dotWith:
¦aForm¦
aForm ? self dotOfSize: 32.
aCharacter asSymbol asString asDisplayText displayOn: aForm at: B @ 8.
?aForm Integer Integer Animus asPath asPath ?AcccssPath new names: (Array with: self) MessageNode MessageNode MessageNode Animus compressTrigger: triggers encoder: encoder (triggers includes: selector key) ifTrue:
[?MessageNode new receiver: (encoder encode Variable: 'self') selector: (receiver asPath extendSelector: selector key) arguments: (arguments collect: [:a¦a compressTrigger: triggers encoder: encoder]) precedence: precedence from: encoder]
ifFalse: [?MessageNode new receiver: (receiver compressTrigger: triggers encoder: encoder) selector: selector key arguments: (arguments collect: [:a¦a compressTrigger: triggers encoder: encoder]) precedence: precedence from: encoder]
key ?self asPath applyTo: TheBrowser prototype anima key MessagePlan Animus MessagePlan code: encoder ¦sel¦
compileTimeOnly ifTrue: [?encoder encode Variable" 'nil'].
sel ? self selector.
?MessageNode new receiver: (receiver code: encoder) selector: sel arguments: (arguments collect:
[:a¦a class = String ifTrue: [encoder encodeVariable: a]
ifFalse: [encoder encodeLiteral: a]]}
precedence: sel precedence from: encoder MethodNode MethodNode MethodNode Animus compressTrigger: triggers encoder: passedEncoder compressTrigger:encoder: ?MethodNode new selector: selectorOrFalse arguments: arguments precedence: precedence temporaries: temporaries block. (block compressTrigger triggers encoder: passedEncoder) encoder: passedEncoder primitive: primitive relocate: aPathPrefix relocate:
?self selector (aPathPrefix extendSelector: self selector) arguments: arguments precedence: precedence temporaries: temporaries block: (block relocatePaths: aPathPrefix encoder: encoder) encoder encoder primitive: primitive relocatePaths: aPathPrefix encoder: anEncoder relocatePaths:encoder:
?self selector (aPathPrefix extendSelector: self selector) arguments: (arguments do: [:a¦a relocatePaths: aPathPrefix encoder: anEncoder]) precedence: precedence temporaries: (temporaries do: [:temp¦(encoder scopeTable includesKey: temp key) ifFalse: [encoder bindTemp: temp key]]) block: (block relocatePaths: aPathPrefix encoder: anEncoder) encoder. anEncoder primitive: primitive relocatePaths:part:encoder:
relocatePaths: aPathPrefix part: aPathSuffix encoder: anEncoder ?self selector: ((aPathPrefix concat; aPathSuffix) extendSelector: self selector) arguments: (arguments do: [:a¦a relocatePaths: aPathPrefix encoder: anEncoder]) precedence: precedence temporaries: (temporaries do: [:temp¦(encoder scopeTable includesKey: temp key) ifFalse: [encoder bindTemp: temp key]]) block: (block relocatePaths: aPathPrefix encoder: anEncoder) encoder: anEncoder primitive: primitive Object Animus constraints Object compileSmashCodeFor: sel fields: fields compileSmashCodeFor:fields:
"compile code to change the values of some of my parts.
other parts may need to be altered to satisfy constraints.
sel should be of the form smash.part1.subpart: part2.subpart.subsubpart: part3:
fields is a collection of arrays of my field properties corresponding to those subparts to be set"

Animus constraints Object ¦planner encoder args statements fs tempName arg changeMessage setSel setNode returnNode block methodNode¦
planner ? AnimusSatisfactionPlanner for: self message: sel.
encoder ? planner encoder.
args ? OrderedCollection new.
statements ? OrderedCollection new.
¦ to: fields size do:
[:i¦fs ? fields at: i.
tempName ? 't', i printString.
arg ? encoder bindTemp: tempName.
args add: arg.
"make a message that describes the change being made, tell the planner about it and add methods from affected constraints.

changeMessage ? MessagePlan new context: self receiver: (fs collect: [:f¦f name]) asPath constraint: nil owner: EmptyPath keywords: #('alter') arguments: #0 uniqueState: true referenceOnly: false compileTimeOnly: true.
planner add: changeMessage.
changeMessage addMethods: planner].
"delete duplicate messages"
planner delete Duplicates, "first add a set statement to to collection of statements setSel ? ('set', (sel copyFrom: 7 to: sel size)) asSymbol.
setNode ? MessageNode new receiver: (encoder encodeVariable: 'self') selector: setSel arguments: args precedence: setSel precedence from: encoder.
statements add. setNode.
statements addAll: (self buildPlan: planner).
returnNode ? ReturnNode new expr: (encoder encodeVariable: 'self').
statements add: returnNode.
block ? BlockNode new statements: statements returns: true.
methodNode ? MethodNode new selector: sel arguments: args precedence: sel precedence temporaries: #0 block: block encoder: encoder primitive: 0.
methodNode compileIn: self class makeMethodFor: message makeMethodFor:
"Compile a method for receiving message"
¦planner¦
planner ? AnimusSatisfactionPlanner for: self message: message keywords first asSymbol.
message arguments do: [:a¦planner encoder bindTemp: a).
self expand: message planner: planner.
"If there is only one message in the planner's queue, and if that Animus constraints Object message doesn't interact with any of my constraints or merges, then use a simple method."
(self testSimple: planner) ifTrue: [?self simpleMethod: message planner: planner].
"situation not simple - find all the relevant messages. Note that a copy of the planner is used because stuff is being added during the 'do:'"
planner copy do: [:m¦m addMethods: planner].
"delete duplicate messages"
planner deleteDuplicates.
"if there is only 1 message in the planner's queue, use a cheap method"
planner size = 1 if True: [?self oneMessageMethod: message planner: planner]
if False: [?self complexMethod: message planner: planner]

Animus editing ancestral: classNameString ancestral:
?(TheBrowser prototype instancePaths: (Compiler evaluate: classNameString)) first applyTo: TheBrowser prototype ancestral: classNameString send: selectorString ancestral:send:
¦pathToReceiver¦
pathToReceiver ? (TheBrowser prototype InstancePaths: (Compiler evaluate: classNameString)) first.
TheBrowser prototype anima perform: (('thing' asPath concat: pathToReceiver) extendSelector selectorString asSymbol) ancestral: classNameString send: selectorString with: argument ancestral:send:with:
¦pathToReceiver¦
pathToReceiver ? (TheBrowser prototype instancePaths: (Compiler evaluate: classNameString)) first.
TheBrowser prototype anima perform: (('thing' asPath concat: pathToReceiver) extendSelector: selectorString asSymbol) with: argument ancestralAnima ancestralAnima "looks for any object in the hierarchy which is an instance of a subclass of Anima"
?(TheBrowser prototype instanceAnimaPaths) first applyTo: TheBrowser prototype animusToolsFor: format animusToolsFor:
"return a vector of classes of editing tools"
format isPicture ifFalse: [?Array new].
?(Array with: Inserter with: Deleter with: Sticker), (Array with: Ticker with: Setter with: Driver with: Kicker), (Array with: Picker with: Mover with: TextEditor) doNothing doNothing ?self editor editor ?nil expand: message planner: planner expand:planner:
¦keyword¦
keyword ? message keywords at 1.

Animus editing Object keyword = 'moveby:' if True: [message receivingObject expandMove: message planner: planner. ?self].
keyword = 'scaleby:' if True: [message receivingObject expandMove: message planner: planner. ?self].
keyword = 'incrementby:' if True: [message receivingObject expandIncrement: message planner: planner. ?self].
keyword = 'setTo:' if True: [message receivingObject expandSetTo: message planner: planner. ?self].keyword = 'fixedLocation' if True: [message receivingObject expandFixedLocation: message planner: planner. ?self].
(keyword size > 12 and: [(keyword copyFrom: 1 to: 12) = 'moveInserter']) if True: [message receivingObject expandMoveAttacher: message planner: planner attachers: self inserters.
?self].
(keyword size > 15 and: [keyword copyFrom: 1 to: 15) = 'moveConstrainer']) if True: [message receivingObject expandMoveAttacher: message planner: planner attachers: self constainers. ?self].
planner add: message expandIncrement: message planner: planner expandIncrement:planner:
"send this message to each of my times ? m ?
m ? MessagePlan new context: message context receiver: (message receiver add: #time) constraint: message constraint owner: message owner keywords: message keywords arguments: message arguments uniqueState:
message uniqueState referenceOnly: message referenceOnly compileTimeOnly: message compileTimeOnly.
self time expand: m planner: planner the above code should actually only be for Anima. for all else:"
self expandMove: message planner: planner expandSetTo: message planner: planner expandSetTo:planner:
planner add: (MessagePlan new context message context receiver: message receiver constraint messageconstraint owner: messageowner keywords: #('primitiveSetTo:') arguments: message arguments uniqueState: message uniqueState referenceOnly: message referenceOnly compileTimeOnly: message compileTimeOnly) getTimeConstraintsOnPath: aPath getTimeConstraintsOnPath:
¦ constraintsWithPaths ¦
Transcript show: aPath printString.
constraintsWithPaths ? OrderedCollection new.
constraintsWithPaths addAllLast: ((self constraints select: [: c ¦ c is Temporal]) collect:
[: c ¦ c path: aPath]).
self parts with: self partNames do:
[: aPart: aName ¦ constraintsWithPaths addAllLast:
(aPart getTimeConstraintsOnPath: (aPath add: aName))].
?constraintsWithPaths Animus editing Object getTimeConstraintsOnPath:constraints:
getTimeConstraintsOnPath: aPath constraints: tConstraints ((Self constraints select [:c¦c is Temporal]) collect:[: c¦c copy path: aPath]) do: [: each ¦ tConstraints add: each.].
self parts with: self partNames do:
[: aPart: aName ¦ aPart getTimeConstraintsOnPath: (aPath add: aName) constraints: tConstraints.].
?tConstraints getTimeConstraintsOnPath: aPath index: index getTimeConstraintsOnPath:index:
¦ constraintsWithPaths idx ¦
constraintsWithPaths ? OrderedCollection new.
idx ? index.
constaintsWithPaths addAllLast ((self constraints select [: c¦c isTemporal]) collect:
[: c¦c path: aPath.
c animaIndex: idx.
idx ? idx + 1.
c]).
self parts with: self partNames do:
[:aPart : aName ¦ constraintsWithPaths addAllLast:
(aPart getTimeConstraintsOnPath: (aPath add: aName) index:
(constraintsWithPaths isEmpty ifFalse: [constrainsWithPaths last animaIndex + 1] ifTrue: [idx]))].
? constraintsWithPaths incrementby: delta incrementby:
self interpret 'incrementby:' with: delta instanceAnimaPaths instanceAnimaPaths "like instancePaths: except uses isKindOf: instead of isMemeberOf:"
"return a vector of paths to instances of class cl or its subclasses"
"First check if I'm an instance of cl.
Find a path to each of my parts which is an instance of cl.
InstancePathsDict is disabled for Animus since things don't tend to stay put."
¦ partsDict paths prefix subPaths strm subPart part¦
(self anima isKindOf: Anima) if True: [?'anima' asPath].
partsDict ? IdentityDictionary new.
self fieldDescriptions do: [: f¦f isPart ifTrue:
[subPaths ? (self perform: f name) instancePaths: Anima prefix ? f asPath.
part ? self instVarAt: f index.
subPaths do:
[:P¦
subPart ? p applyTo: part.
partsDict at: subPart put: (prefix concat: p)]]].
strm ? Array newWriteStream: 10.
partsDict do: [: x ¦ strm nextPut: x].
paths ? strm contents.
?paths Animus editing Object instancePaths:cl instancePaths:
"return a vector of paths to instances of class cl or its subclasses"
"First check if I'm an instance of cl.
Find a path to each of my parts which is an instance of cl.
InstancePathsDict is disabled for Animus since things don't tend to stay put."
¦ partsDict paths prefix subPaths strm subPart part ¦
(self isMemberOf: cl) ifTrue:[? Array with: EmptyPath].
partsDict ? IdentityDictionary new.
self fieldDescriptions do:[:f¦f isPart ifTrue:
[subPaths ?(self perform: f name) instancePaths: cl.
prefix ? f asPath.
part ? self instVarAt: f index.
subPaths do:
[:p¦
subPart ? p applyTo: part.
partsDict at: subPart put: (prefix concat:p)]]].
strm ? Array new WriteStream: 10.
partsDictdo:[:x¦ strm nextPut:x].
paths ? strm contents.
?paths instancePaths:cl instancePaths:
"like instancePaths: except uses isKindOf: instead of isMemeberOf:"
"return a vector of paths to instances of class cl or its subclasses"
"First check if I'm an instance of cl.
Find a path to each of my parts which is an instance of cl.
InstancePathsDict is disabled for Animus since things don't tend to stay put."
¦ partsDict paths prefix subPaths strm subPart part ¦
(self isKindOf:cl) ifTrue: [? Array with: EmptyPath].
partsDict ? IdentityDictionary new.
self fieldDescroptions do:[:f¦f isPart ifTrue:
[subPaths ? (self perform: f name) instancePaths: cl.
prefix ? f asPath.
part ? self instVarAt: f index.
subPaths do:
[:p¦
subpart ? p applyTo: part.
partsDict at: subPart put: (prefix concat: p)]]].
strm ? Array new WriteStream: 10.
partsDict do:(:x ¦ strm nextPut: x).
paths ? strm contents.
? paths offset: a Thing offset:
"default"
?0@0 Animus editing Object partNames partNames ?(self fieldDescriptions select [:f¦f isPart]) collect: [:g¦g name]
primitiveSetTo: dt primitiveSetTo:
self become: dt tick: delta tick:
TheBrowser prototype anima tick: delta Animus operations 14 aSymbol 14 "perform aSymbol,which is a unary selector name, as a binary function"
?self perform: aSymbol Animus testing isAnimusObject isAnimusObject ?false isBoolean isBoolean ?false OrderedCollection Animus OrderedCollection filledSize filledSize ?(self select [: each ¦ each value isNil not]) size firstIndex firstIndex ?firstIndex lastIndex lastIndex ?lastIndex lastIndex: integer lastIndex:
lastIndex ? integer lastindexOf: anElement lastIndexOf:
(1 to: self size) reverseDo: [:1¦ (self at: i) = anElement if True: [?i]].
?0 ParseNode ParseNode ParseNode Animus basicPrintString basicPrintString "Answer a String whose characters are a description of the receiver."
¦ aStream ¦
aStream ? WriteStream on: (String new: 16).
self printOn: aStream indent: 0.
?aStream contents compressTrigger: triggers encoder: encoder compressTrigger:encoder:
?self Path class Animus Path class with: aPoint with: anotherPoint with:with:
¦ newSelf ¦
newSelf ? self new.
newSelf add: aPoint.
newSelf add: anotherPoint.
?newSelf Pen Animus Pen showPicture: medium showPicture:
?self QueuedMethodDescription Animus QueuedMethodDescription canBeSentNext: queue ¦ path ¦ canBeSentNext: queuePoint "return true is I can be sent next"
"The following conditions must be true for me to be sent next:
my constraint uniquely determines the state of my receiver;
my receiver or one of its parts isn't already unalterable;
and all the objects that I reference are unalterable.

Animus OueuedMethodDescription (constraint isMemberOf: SetMembershipConstraint) ifTrue: [?true].
(constraint isMemberOf: TimeDifferentialConstraint) ifTrue: [?true].
(constraint isMemberOf: FunctionConstraint) ifTrue: [?true].
(constraint isMemberOf: TriggerConstraint) ifTrue: [?true].
uniqueState ifFalse: [?false].
(queue testForUnalterablePart: receiver) if True: [?false].
constraint = nil if True: [?true].
"If any of the objects that I reference may still change, return false"
constraint methodDescriptions do:
[: descr ¦ path ? owner concat: descr receiver.
path = receiver ifFalse:
["it's the one I alter"
(queue testIfUnalterable: path) if False:
[ "last chance! If this description is reference only, and there are no altering discriptions to it in the queue, it won't change."
(descr referenceOnly and: [(queue noAlteringMessagesTo: path)]) ifFalse: [?false]]]].
(constraint isKindOf: SetConstraint) itTrue: [(queue findConstraint constraint owner: owner) do:
[: descr ¦ descr = self if False:
[(queue testIfUnalterable: descr receiver) ifFalse: [?false]]]].
?true Rectangle Animus Rectangle frame frame ?self Rectangle class Animus Rectangle class bottomLeft: aPoint extent: anotherPoint bottomLeft:extent:
?self origin: aPoint x @ (aPoint y - anotherPoint y) extent: anotherPoint x @ (0 - anotherPoint y) Relaxer Relaxer Animus compiling Relaxer pickErrors: planner oldUnalterable: oldUnalterable pickErrors:oldUnalterable:
"Find the vectors of constraint owners, errors and tests.
Delete these messages from the queue.
Choose only one error and test per constraint"
¦ picked ¦
picked ? ConstraintSatisfactionPlanner for: context.
constraintOwners ? OrderedCollection new.
errors ? OrderedCollection new.
tests ? OrderedCollection new.
planner unalterable do:
[:path ¦ (oldUnalterable includes: path) ifFalse: [(planner findReceiver: path) do:
[:message ¦ planner remove: message.
(picked hasConstraint: message constraint owner: message owner) ifFalse:
["delete messages from this constraint to objects in oldUnalterable, since the errors for their constraint will be taken care of by the relaxer"
picked add: message.
constraintOwners add: message owner.
errors add: (self compileError: message encoder: planner encoder).
tests add: (self compileTest: message encodera: planner encoder).
(planner findConstraint: message constraint owner: message owner) do:
[:m ¦ (oldUnalterable includes: m receiver) ifTrue: [planner remove: m]]]]]].
constraintOwnerVecs add: constraintOwners asArray.
errorVecs add: errors asArray.
testVecs add: tests asArray SequenceableCollection Animus SequenceableCollection instancePaths: cl instancePaths:
"return a vector of paths to instances of class cl or its subclasses"
"First check if I'm an instance of cl. If not, then check in my dictionary of instance paths to see if there is an entry for cl. If that fails too, then find a path to each of my parts which is an instance of cl. If there is more than one path to that part put only one of them in the vector."
¦ instancePathsDict partsDict paths prefix subPaths strm subPart part ¦
(self isMemberOf: cl) iFTrue:[? Array with:EmptyPath].
partsDict ? IdentityDictionary new.
(I to: self size) do:[:indx ¦ subPaths ?(self at: indx) instancePaths: cl.
prefix ? indx asPath.
part ? self at: indx.
subPaths do:
[:p¦
subPart ? p applyTo: part.

Animus SequenceableCollection partsDict at: subPart put:(prefix concat:p)]].
strm ? Array new WriteStream: 10.
partsDict do: [:x¦strm nextPut: x].
paths ? strm contents.
?paths String Animus String selectorWithArgs selectorWithArgs ¦ strm string index ¦
(self last=$:) ifFalse: [?self] ifTrue:
[strm ? self readStream.
string ? Sring new WriteStream: 64.
index ? 1.
[strm atEnd] whileFalse:
[string nextPutAll: (strm up To:$:).
string nextPutAll:':a',index printSting.''.
index ? index +1].
?string contents]
"'swap: with:'selectorWithArgs"

ThingLabObject Animus ThingLabObject anima anima ?nil Tool Animus Tool willChangeStructure willChangeStructure "The structure of the selection is about to be changed. Make sure its a prototype"
selection anima isNil ifFalse: [selection anima deInitialize].
selection isPrototype ifFalse:
[self error: 'not a prototype'.

selection ? selection as Prototype.
editedView picturePane update.
editedView buffer update]

UndefinedObject UndefinedObject Animus UndefinedObject Animus asPath asPath ?EmptyPath do: aBlock do:
"do nothing"
?self set.value: ignored ?self set value value ?nil ThingLabBrowser subclass: #AnimusBrowser instanceVariableNames: 'anima ' classVariableNames: 'FieldDescriptions ' poolDictionaries: "
category: 'Animus-Views' AnimusBrowser prototypes AnimusBrowser defineNewThing defineNewThing ¦ nameString name animaClassName ¦
nameString ? FillinTheBlank request: 'Enter name of new thing' default: 'NameOfThing'.
nameString size=0 ifTrue: [?self].
nameString at: 1 put: (nameString at: 1) asUppercase.
name ? self makeClassName: nameSting.
animaClassName ? (nameString, 'Anima') asSymbol.
(Smalltalk includesKey: name) ifTrue: [?self notify: name,' is a name used elsewhere'].
self prototypeSuperclass subclass: name instanceVariableNames:"
classVariableNames: "
poolDictionaries: "
category: 'Prototypes'.
Anima subclass: animaClassName instanceVariableNames: "
classVariableNames: "
poolDictionaries: "
catagory: 'Animae'.
(Smalltalk at: name) prototype anima: (Smalltalk at: animaClassName) new.
"leave text editing mode, and update the selection pane"
prototypeClass ? name.
self changed: #prototypeClassList prototypes AnimusBrowser prototypeSuperclass ?AnimusObject prototypeSuperclass removeThing (self confirm: 'Do you really want to remove removeThing prototypeClass.'from the system?'ifFalse:[?self].
self browsedPrototype anima isNil ifFalse:[self browsedPrototype anima nilFields.
self browsedPrototype anima class removeFromSystem.
self browsedPrototype nilFields].
self browsedDictionary removeKey: prototypeClass ifAbsent: ?.
self browsedPrototype class removeFromSystem.
"update the selection pane"
prototypeClass?nil.
self changed:#prototypeClassList tool toolList toolList (prototype=nil or: [aspect=nil]) ifTrue: [?nil].
self showSelector=#showPicture: ifFalse: [?nil].
?prototype animusToolsFor:aspect access anima anima ?anima anima:anAnima anima?anAnima anima:

Driver Tool subclass:#Driver Driver instanceVariableNames.:
classVariableNames: 'PicturesChanged' poolDictionaries:"
category: 'Animus-Views' tool Protocol action ?'go' action performAction performAction Transcript show: selection anima tiime printString scheduling eachtime eachtime ¦menu message¦
selection anima tick: selection anima deltaT.
sensor redButtonPressed ifTrue:[menu?ActionMenu labels: 'FileOp PaneOp Remote MenuChange Auto Start/Stop' selectors:#('FileOp''PaneOp''Remote''MenuChange''Auto''Start/Stop').message?menu selectorAt: menu startUp.
TheBrowser prototype anima thing simKernel3 sendX: message toExchange: 'UTHX' sender: SimProcess prototype]
ifFalse:[selection parts first class = SimKernel ifTrue:[PicturesChanged isNil ifFalse:[self class resetPicturesChanged.
self updatePictures]]
ifFalse:[self updatePictures]].
"Transcript show: selection anima thing simKernel3 readyList list printString, selection anima thing simKernel3 pauseList list printString, selection anima thing simKernel3 signalList list pringString. Transcript show: selection anima thing simKernel3 deviceList printString."
?editedView containsPoint: Sensor cursorPoint firsttime firsttime selection anima initialize.
super fisttime ?true Driver class Driver class Driver class instanceVariableNames:"
access resetPicturesChanged resetPicturesChanged PicturesChanged?nil setPicturesChanged setPicturesChanged PicturesChanged?true Sticker Inserter subclass: #Sticker Sticker instanceVariableNames:"
classVariableNames:"
poolDictionaries:"
category:'Animus-Views' tool protocol action action ?'add' perform Action performAction ¦xOffset aList¦
aList?(selectionMerges first allButLast applyTo: selection) list.
aList add: carrier.
xOffset?(selectionMerges first allButLast applyTo:selection location x+10.
(1 to: aList size-1) do:[:i¦xOffset?xOffset+8+(aList at:i]frame width].
aList last set frame:(aList last frame TranslateBy:((xOffset-aList last frame origin x)?0)).
(selectionMerges first allButLast applyTo:selection)addPoint moveby:(carrier frame width +8?0).
(carrier isKindOf: SimProcess)ifTrue:[selection simKernel3 deviceList add: (Association key:carrier processName,'X'value: carrier device)].
self showBuffered Kicker Tool subclass:#Kicker Kicker instanceVariableNames:"
classVariableNames:'KickPictures' poolDictionaries:"
category:'Animus-Views' tool protocol action action ?'send message' oldFirsttime oldFirsttime ¦menu selector¦
selection anima initialize.
super firsttime.
menu?ActionMenu labels:(selection anima triggers inject:"into[:string:trigger[string, trigger first asString, (trigger=selection anima triggers last ifTrue: ["] ifFalse:[°
selectors:(selection anima triggers collect:[:trigger]trigger last extendSelector:trigger first]) selector?menu selectorAt menu startUp.
selection anima perform: selector.
Sensor cursorPoint:(editView super View subViews at:3) inset Display Box center.?false performAction ¦menu selector receiver Triggers args¦ performAction selectionMerges do:[:ra¦ m ? nil ifFalse:[selection anuima initialize receiverTriggers?selection anima triggers select:[:trigger¦trigger last contains: m].
menu?ActionMenu labels:(recieverTriggers inject"into:[:string:trigger¦string, trigger first asString.
(trigger=receiverTriggers last ifTrue: ["] ifFalse["
selectors:(receiverTriggers collect:[trigger¦trigger last extendSelecto4:trigger first]).
self showBuffered.
selector?menu selector At: menu startUp.
selector isKeyword ifTrue: [args?Compiler evaluate: (fillinTheBlank request: 'argArray?').
selection anima perform: selector with Arguments: args.
selection anima tick:1.
selection anima tick:1]
ifFalse:[selection anima perform:selector].
self showBuffered.
Sensor cursorPoint:(editedView superView subViews at:3)insetDisplayBoxcenter.]]

Kicker class Kicker class Kicker class instanceVariableNames: "

access resetPicturesChanged resetPicturesChanged KickPictures ? nil setPicturesChanged setPicturesChanged KickPictures ? true Picker Tool subclass: #Picker Picker instanceVarableNames: "
classVariableNames: "
poolDictionaries: "
category: 'Animus-Views' tool protocol action action ?'edit' performAction performAction (selectionMerges first applyTo: selection) inspect self showBuffered Setter Tool subclass: #Setter Setter instanceVariableNames: "
classVariableNames: "
poolDictionaries: "
category: 'Animus-Views' tool Protocol action action ?'set time' firsttime firsttime selection anima time set.value: (FillInTheBlank: request: 'Edit time value' initialAnswer: selection anima time value printString) asNumber.
Sensor cursorPoint: (editedView superView subViews at: 3) insetDisplayBox center.
?false Ticker Tool subc1ass: #Ticker Ticker instanceVariableNames: "
classVariableNames: "
poolDictionaries: "
category: 'Animus-Views' tool Protocol action action ?'tick size' firsttime firsttime selection anima deltaT: (FillInTheBlank request: 'Edit time increment, dt:' initialAnswer: selection anima deltaT printString) asNumber.
Sensor cursorPoint: (editedView superView subViews at: 3) insetDisplayBox center.
?false AnimusBrowserView ThingLabBrowserView subclass: #AnimusBrowserView #AnimusBrowserView instanceVariableNames: "
classVariableNames: "
poolDictionaries: "
category: 'Animus-Views' AnimusBrowserView class AnimusBrowserView class AnimusBrowserView class instanceVariableNames: "

Initialization open Create "AnimusBrowserView open"
¦ topView browser ¦
TheBrowser ? AnimusBrowser new.
topView ? self model: TheBrowser label: 'Animus Browser' minimumSize: 300 @ 200.
topView addSubView:
(ListViewWithBlock on: TheBrowser aspect: #prototypeClass printItems: true) in: (0@0 extent: 0.25@0.22) borderWidth: 1.
topView addSubView:
(ListViewWithBlock on: TheBrowser aspect: #aspect printBlock: [:x¦x name]) in: (0.25@0 extent: 0.25@0.22) borderWidth: 1.
topView addSubView:
(ListViewWithBlock on: TheBrowser aspect: #tool printBlock: [:x¦x new action]) in: (0.5@0 extent: 0.25@0.22) borderWidth: 1.
topView addSubView:
(ListViewWithBlock on: TheBrowser aspect: #filter printItems: true) in: (0.75@0 extent: 0.25@0.22) borderWidth: 1.
topView addSubView: .
(TextView on: TheBrowser aspect: #text change: #acceptText: from:
menu: #textMenu) in: (0@0.22 extent: 1@0.78) borderWidth: 1.
topView coutroller open Object variableSubclass: #Case instanceVariableNames: 'keyArray responseArray item currentEvent currentArray ' classVariableNames: 'FieldDescriptions' poolDictionaries:"
category: 'Animus Responses' Initialization Animus Browser View Class Case Initialization item: an Item item:
item ? an Item key Array: an Item key Array:
key Array ? an Item response Array: an Item response Array:
response Array ? an Item operations first first ? index ?
(key Array includes: item value) if True: [index ? (key Array index Of: item value)]
if False: [index ? response Array size].
current Array ? response Array at: index.
current Array is Empty if True: [?nil] if False: [?current Event ? current Array first]
next next (current Event current Array last) if True: [?nil].
?current Event ? current Array at: (current Array index Of: current Event) + 1 value value ? index ?
(key Array includes: item) if True: [index ? (key Array index Of: item)]
if False: [index ? response Array size].
?current Array ? response Array at: (index min: response Array size) printing print On: strm print On:
strm next PutAll: 'Case', item value print String, 'of', key Array print String ,' ', response Array print String .
Case class Case class Case class instance Variable Names: "

Case class Instance creation item: an Item of: key Array is: response Array item:of:is:
? new Guy ?
new Guy ? self new.
new Guy item: an Item.
new Guy key Array: key Array.
new Guy response Array: response Array.
?new Guy Event Queue Linked List variable Subclass: # Event Queue Event Queue instande VariableNames:"
class VariableNames:"
pool Dictionaries: "
category: 'Anus-Responses' tests check: a Time check:
?event Array?
event Array ? OrderedCollection new.
self is Emply if True: [?event Array].
[self first time Stamp ? a Time value]
while True: [event Array add Last self first.
self remove First.
self is Empty if True: [?event Array]].
?event Array enqueuling enqueue: an EventArray enqueue:
an EventArray do: [:an event ? self insert TimeOrdered: an Event]
enqueue Shifted: an EventArray euqueue Shifted:
? current Time an Event?
an EvenyArray is Nil if True: [?nil].
current Time ? The Browser prototype anima time value.
an EventArray do: [: an EventNode ? an Event ? Event new perform: an EventNode selector key with Arguments: (an EventNode arguments collect: [:each ? each key]) as Array.
self insert TimeOrdered: (an Event at Time: an Event time Stamp + current Time)]
insert TimeOrdered: an Event insert TimeOrdered:
? previous next ?
self is Empty if True: [?self add First: an event].
an Event time Stamp < self first time Stamp if True: [?self add First: an Event].
a Event time Stamp >= self last time Stamp if True: [?self add Last an Event].
next ? self first an Event time Stamp >= next time Stamp]
while True: previous ? next next ? next next Link ].
an Event next Link: next previous next Link an Event Event Link variable Subclass: #Event Event instance VariableNames: 'time Stamp receiver selector arguments' . .
class VariableNames: 'FieldDescriptions' pool Dictionaries: "
category: 'Animus-Responses' Event comment 'The receiver of an Event is an actual object pointer and the arguments are an array of such pointers. The seleclor is a symbol. This is contrasted to EventPrototypes (see their comment)' happening happen happen receiver perform: selector with Arguments: arguments happen: dt happen:
receiver perform: selector with: dt access at Time: an Integer atTime:
time Stamp ? an Integer at Time: ? receiver: r selector: s arguments: a at Time:receiver:selector:arguments:
time Stamp ? l.
receiver ? r.
seleclor ? s.
arguments ? a receiver: r selector: s arguments: a receiver:selector:arguments:
receiver ? r.
selector ? s.
arguments ? a time Stamp time Stamp ?time Stamp printing print On: a Stream print On:
a Stream next PutAll:'[', receiver print String,' ', selector print String, arguments print String,')', time Stamp print String Event class Event class Event class instance VariableNames: "

Initialization noop noop "a no-op event"
null null "return a no-op event"
?self new receiver: self selector: #noop arguments: #0 OSEvent Event variableSubclass: #OSEvent OSEvent instanceVariableNames: "
classVariableNames: "
poolDictionaries: "
category: 'Animus-Responses' happening happen happen ? returnValue ?
returnValue ? receiver perform: selector withArguments: arguments.
(receiver isKindOf: SimProcess) if True:
(returnValue isBoolean ifFalse: [returnValue ? false].
TheBrowser prototype anima thing simKernel3 setJump: returnValue]

Lozenge Object variableSubclass: #Lozenge Lozenge instanceVariableNames: 'frame form ' classVariableNames: 'FieldDescriptions' poolDictionaries: "
category: 'Animus-Responses' moving display display form displayAt: frame origin frameTranslateBy: delta frameTranslateBy:
?frame translateBy: delta access form form ?form form: aForm form:
form ? aForm frame frame ?frame frame: aRect frame:
?frame ? aRect Lozenge class Lozenge class Lozenge class instanceVariableNames: "

Instance creation form: form frame: rect label: string form:frame:label:
? newLozenge tempForm ?
newLozenge ? self new.
tempForm ? (form reverse) offset: 0@0.
((Paragraph withText: string asText style: (TextStyle default alignment: 2)) asForm) displayOn: tempForm medium at: (3@2) rule: Form over mask: Form black.
newLozenge form: tempForm reverse.
newLozenge frame: rect.
?newLozenge Instant creation Lozenge class fromFrame: rect fromFrame:
? newLozenge tempForm ?
newLozenge ? self new.
newLozenge form: (Form fromDisplay: (rect tanslateBy: TheBrowser dependents last insetDisplayBox origin)).
newLozenge frame: rect.
TheBrowser dependents last displayView.
?newLozenge ProcessSet Object variableSubclass: #ProcessSet ProcessSet instanceVariableNames: 'frame form processCollection ' classVariableNames: 'FieldDescriptions ' poolDictionaries: "
category: 'Animus-Responses' access form form ?form form: aForm form:
form ? aForm frame frame ?frame frame: aRect frame:
frame ? aRect processCollection processCollection ?processCollection processCollection: aCollection processCollection:
processCollection ? aCollection moving frameTranslateBy: delta frameTranslateBy:
processCollection do: [: each ? each set.frame: (each frame translateBy: delta)].
?frame translatleBy: delta ProcessSet class ProcessSet class ProcessSet class instanceVariableNames: "

Initialize frame: aRect frame:
?newSelf?
newSelf ? self new.
newSelf frame: aRect:
form: (Form fromDisplay: (aRect translateBy: theBrowser dependents last insetDisplayBox origin) rounded).
?newSelf Initialize ProcessSet class from: aProc to: another in: aList from:to:in:
¦newSelf¦
newSelf ? self new.
newSelf processCollection: (aList copyFrom: (aList indexOf: aProc) to: (aList indexOf: another)).
newSelf frame: (aProc frame merge: another frame).
newSelf form: (Form fromDisplay: (newSelf frame translateBy: TheBrowser dependents last insetDisplayBox origin) rounded).
?newSelf Response Object variable Subclass: #Response Response instance VariableNames: 'responseMethod' classVariableNames:"
poolDictionaries:"
category: 'Animus-Responses' access responseMethod responseMethod ?responseMethod responseMethod: aMethodNode responseMethod:
responseMethod?aMethodNode Response class Response class Response class instanceVariableNames:"
Instance creation with: aMethodTree with:
?self new responseMethod: aMethodTree ImmediateResponse Response variableSubclass:#ImmediateResponse ImmediateResponse instance VariableNames:"
classVariableNames:"
poolDictionaries:"
category: 'Animus-Responses' printing printOn: aStream printOn:
aStream nextPutAll: 'enqueue immediately'.
responseMethod printOn: aStream Script Response variableSubclass: #Script Script instance VariableNames: 'eventArray' classVariableNames:"
poolDictionaries:"
category: 'Animus-Response' access eventArray eventArray ?eventArray eventArray: array eventArray:
eventArray?array Script class Script class Script class instanceVariableNames:"
Instance creation with: response eventArray: messageNodeArray with:eventArray:
¦script¦
scrip?self with: response.
script eventArray: messageNodeArray.
?script TriggeredResponse Response variableSubclass: #TriggeredResponse TriggeredResponse instanceVariableNames:"
classVariableNames:"
poolDictionaries:"
category: 'Animus-Responses' printing printOn: aStream printOn:
aStream nextPutAll: 'triggered'.
responseMethod printOn: aStream Flasher TriggeredResponse variableSubclass: #Flasher Flasher instanceVariableNames: 'thing' classVariableNames:"
poolDictionaries:"
category: 'Animus-Responses' access thing: aThing thing: thing?aThing responding enqueueEvents equenueEvents ¦eventCollection¦
TheBrowser prototype anima thingEvents enqueue:
[eventCollection?OrderedCollection new.
(1 to: 2) do:[:i¦eventCollection add: (Event new atTime: TheBrowser prototype anima time value +(TheBrowser prototype anima deltaT/10*j) receiver: self selector:#showBlack:
arguments:#(nil)).
eventCollection add: (Event new atTime: TheBrowser prototype anima time value + 0.005 +(TheBrowser prototype anima deltT/10*i) receiver: self selector:#showWhite:
arguments:#(nil))].
eventCollection add: (Event new atTime: TheBrowser prototype anima time value + 0.6 receiver: TheBrowser dependents last selector: #displayViewOn:
arguments:(Array with: Display)).
eventCollection] value showBlack:ingnored showBlack:
Display fill: (thing frame translateBy: TheBrowser dependents last insetdisplaybox origin)mask: Form black.
(Delay forMilliseconds: 50)wait showWhite:ingnored showWhite:
¦frm¦
frm?thing frame translateBy: TheBrowser dependents last insetDisplaybox origin.
Display fill: frm mask: Form white.
Display border: frm width: 3.
(Delay forMiliseconds: 50)wait Flasher class Flasher class Flasher class instance Variable Names: "

Instance creation with: a Thing with:
?self new thing: a Thing Trajectory TriggeredResponse variableSubclass: #Trajectory Trajectory instance VariableNames: 'thing destination delta form background tempbackground'classVariableNames: "
poolDictionaries: "
category: 'Animus-Responses' access destination: aPoint destination:
destination ? aPoint thing: aThing thing:
thing ? athing responding enqueueEvents enqueueEvents ¦eventCollection¦
"2 timesRepeat:[ Displayflash: (0@0 corner: 800@800)].
Sensor waitButton.
Sensor redButtonPressed ifTrue:[self halt]."
TheBrowser prototype anima thingEvents enqueue:
(eventCollection ? OrderedCollection new.
eventCollection add: (Event new atTime: TheBrowser prototype anima time value receiver: self selector: #initialize:
arguments: #(nil)).
(1 to:8) do: [:i¦eventCollection add: (Event new atTime: TheBrowser prototype anima time value +(TheBrowser prototype anima deltaT/10*i) receiver: self selector: #step:
arguments: (Array with:i))].
eventCollection] value initialize:ignored initialize:
¦mergeRect¦
delta ? destination frame bottomLeft - thing frame bottomLeft/8Ø
form ? thing form.
tempbackgroung ? (thing clas=Lozenge) ifTrue: [Form fromDisplay: (thing frame translateBy: TheBrowser dependents last insetDisplayBox origin) rounded]
ifFalse: [(Form extent: form extent) white].
mergeRect ? ((thing frame merge: (destination frame origin + (destination offset: thing) extent: thing frame extent)) translateBy: TheBrowser dependents last insetDisplayBox origin) rounded.
background ? (Form fromDisplay: mergeRect).
tempbackground displayOn: background at:(thing frame origin + TheBrowser dependents last insetDisplayBox origin - mergeRect origin).
TheBrowser tool setPicturesChanged."

responding Trajectory 10 timesRepeat:[ Displayflash: mergeRect].
background displayAt: 300@200.
tempbackground displayAt: 300@300.
Sensor waitButton.
Sensor redButtonPressed ifTrue: [ self halt]"
step: index step:
tempbackground displayAt: thing frame origin + TheBrowser dependents last insetDisplayBox origin.
thing set.frame: (thing frameTranslateBy: delta).
form displayAt: thing frame origin + TheBrowser dependents last insetDisplayBox origin.
tempbackground ? (Form extent: form extent) from: background in:
((((delta x > 0 if True: [0] ifFalse: [background width - form width]) @
(delta y > 0 ifTrue: [0] ifFalse: [background height - form height])) + (index * delta)) extent: form extent)".
tempbackground displayAt: 300@300 + (0@ index * 80).
Sensor waitButton.
Sensor redButtonPressed ifTrue:[ self hair]"
Printing printOn: strm printOn:
strm nextPutAll; 'TrajFromTo: ', thing printString, destination printString Trajectory class Trajectory class Trajectory class instanceVariableNames:"
Instance creation with: aThing destination: anotherThing with:destination:
¦temp¦
temp ? self new thing: aThing.
temp destination anotherThing.
? temp ThingLabObject subclass: #AnimusObject instanceVariableNames: 'anima historyDescription' classVariableNames: 'FieldDescriptions' poolDictionaries: "
category: 'Animus-Objects' AnimusObject AnimusObject AnimusObject access anima anima ? anima anima: anAnima anima:
anima ? anAniama tests isAnimusObject isAnimusObject ?true AnimusObject class AnimusObject class AnimusObject class instanceVariableNames: "
file out fileOutAnimus AnimusObject ¦ sourceFile toInitialize meta ¦
"toInitialize is a collection of classes that need to have their prototypes initialized"
toInitialize ? OrderedCollection new.
"file out changes to existing classes (should all be in protocols that start with 'Animus')"
sourceFile ? FileStream newFileNamed: 'animus.st'.
sourceFile timeStamp.
sourceFile cr; nextPutAll: 'Smalltalk at: #Things put: IdentityDictionary new!';cr.
sourceFile cr; nextPutAll: 'Smalltalk at: #ThingDefinitions put: IdentityDictionary new!'; cr; cr.
"don't file out changes for prototype classes or classes in Animus categories"
Smalltalk allClassesDo:
[:class¦
('Animus*' match: class category)¦(#Prototypes = class category) ifFalse:
[(Array with: class with: class class) do: "Both class and meta:
[: each ¦ each organization categories do:
[:cat ¦('Animus*'match:cat) ifTrue: "File out Animus categories"
[each fileOutCategory: cat on: sourceFile moveSource: false toFile: 0.
"check if this class needs to have its prototype initialized:
each isMeta & (each includesSelector: #initializePrototype)ifTrue:
[toInitialize add: each]]]]]].
sourceFile cr. sourceFile cr.
"file out new Animus classes (should all be in categories that start with 'Anumus')"
(SystemOrganization categorises select: [:x¦'Animus*' match:x]) do:
[:cat ¦ sourceFile cr. sourceFile cr.
SystemOrganization fileOutCategory: cat onFile: sourceFile, sourceFile cr].
"add messages to initialize prototypes. Initializations of existing system classes are done first to avoid ording problems"
sourceFile cr. sourceFile cr.

file out AnimusObject class Smalltalk allClassesDo:
[:each¦meta ? each class.
(meta includesSelector: #initializePrototype) & (toInitialize includes: meta) not ifTrue: [toInitialize add: meta]].
toInitialize do:
[:c¦sourceFile nextPutAll:c soleInstance name,'initializePrototype!'.
sourceFile cr].
sourceFile close file in fileInBasics fileInBasics "AnimusObject fileInBasics"
(FileStream oldFileNamed: 'currentThings/ElectricalObject.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/ElectricalNode.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/ElectricalLead.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/TwoLeadedObject.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Resistor.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Wire.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Ground.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Meter.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Capacitor.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Scope.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Inductor.thing')fileIn.
fileInElectrical fileInElectrical "AnimusObject fileInElectrical"
(FileStream oldFileNamed: 'currentThings/ElectricalObject.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/ElectricalNode.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/ElectricalLead.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/TwoLeadedObject.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Resistor.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Wire.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Ground.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Meter.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Capacitor.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Scope.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Inductor.thing')fileIn.

fileInMechanical fileInMechanical "AnimusObject fileInMechanical"
(FileStream oldFileNamed: 'currentThings/MechanicalNode.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/MechanicalRod.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/TwoRodedObject.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Mass.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/Spring.thing')fileIn.

fileInOS fileInOS
"AnimusObject fileInOS"
(FileStream oldFileNamed: 'currentThings/'OSaux.st')fileIn.
(FileStream oldFileNamed: 'currentThings/ABaseQueue.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/APriorityQueue.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/APauseQueue.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/SimDevice.thing')fileIn.
(FileStream oldFileNamed: 'currentThings/SimProcess.thing')fileIn.

file in AnimusObject class (FileStream old FileNamed: 'currentThings/ProcAC.thing') fileIn.
(FileStream old FileNamed: 'currentThings/ProcMM.thing') fileIn.
(FileStream old FileNamed: 'currentThings/ProcFS.thing')fileIn.
(FileStream old FileNamed: 'currentThings/ProcUIH.thing')fileIn.
(FileStream old FileNamed: 'currentThings/ProcPP.thing') fileIn.
(FileStream old FileNamed: 'currentThings/ProcGA.thinf') fileIn.
(FileStream old FileNamed: 'currentThings/ProcHDW.thing') fileIn.
(FileStream old FileNamed: 'currentThings/SimKernel.thing') fileIn.

AMagnitude AnimusObject subclsss: #AMagnitude AMagnitude instanceVariableNames: 'value ' classVariableNames: 'FieldDescriptions InstancePathsDict Methods ' poolDictionaries; "
category: 'Animus-Objects' access value value ?value value: anInteger value:
value ? anInteger printing printOn: aStream printOn:
aStream nextPutAll: ' a Magnitude of ', value printString compiling expandIncrement: message planner: planner expandIncrement:planner:
planner add: (MessagePlan new context: message context receiver: message receiver constraint message constraint owner; message owner keywords: #('primitiveIncrement:') arguments: message arguments uniqueState: message uniqueState referenceOnly: message referenceOnly compileTimeOnly: message compileTimeOnly) primitiveIncrement: dt primitiveIncrement:
value ? value + dt primitivesetTo: dt primitivesetTo:
value ? value + di primitiveSetTo: dt primitiveSetTo:

AMagnitude class AMagnitude class AMagnitude class instanceVariableNames: "

Instance creation value: anInteger value:
?self new value: anInteger Anima AnimusObject subclass: #Anima Anima instanceVariableNames: 'thing deltaT time constraints thingEvents triggers encoder initilized ' classVariableNames: 'FieldDescriptions ' poolDictionaries: "
category: 'Animus-Objects' evolution expandIncrement: message planner: planner expandIncrement:planner:
"send this message to each of my times"
¦m¦
m ? MessagePlan new context: message context receiver: (message receiver add: #time) constraint: message constraint owner message owner keywords: message keywords arguments: message arguments uniqueState:
message uniqueState referenceOnly: message referenceOnly compileTimeOnly: message compileTimeOnly.
self time expand: m planner. planner expandSetTo: message planner: planner expandSetTo:planner:
"send this message to each of my times"
¦m¦
m ? MessagePlan new context: message contextreceiver: (message receiver add: #time) constraint: message constraint owner. message owner keywords: message keywords arguments: message arguments uniqueState:
message uniqueState referenceOnly: message referenceOnly compileTimeOnly: message compileTimeOnly.
self time expand: m planner. planner tick: dt tick:
¦ eventsToDo ¦
self incrementby: dt.
eventsToDo ? thingEvents check: time.
eventsToDo do: [:anEvent ¦ anEvent happen].

constraints compileResponsesFor: ¦Constraints compileResponsesFor:
¦ responseMethod moreMessage transform respEncoder triggerNames¦
¦Constraints do:
[:tc] Transcript show:,'compiling response for ',tc ruleTree printString, ' '. respEncoder ? Ic response responseMethod encoder.
respEncoder scopeTable associationsDo: [: assoc ¦ (encoder scopeTable includesKey: assoc key) if False: [encoder scopeTable add: assoc. encoder nTempsIncrement]].
"(1 to: tc response responseMethod arguments size) do:
[:i¦ (encoder scopeTable includesKey 't', iprintString) ifFalse: [encoderbindTemp: 'f', i printString]].
encoder scopeTable includesKey: 'delta') ifFalse: [encoder bindTemp: 'f,i triggerNames ? triggers collect: [: t¦ t first].
responseMethod ? tc relocateResponse: encoder triggers: triggerNames.
(triggerNames includes: tc trigger) if True: [responseMethod penultAdd: (self tickMessage)].
tc isPostlude if True: [responseMethod block preAdd: (tc basicMethod: encoder in: self]
ifFalse: [responseMethod block add: (tc basicMethod: encoder in: self)].
responseMethod compileIn: self class]

constraits Anima getTimeConstraints getTimeConstraints ¦Constraints¦
tConstraints ? OrderedCollection new.
thing getTimeConstraintsOnPath:
(AccessPath new names: (Array with; #thing)) constraints; tConstraints.
" ¦Constraints addAll last: (thing getTimeConstraintsOnPath:
(AccessPath new names: (Array with;#thing))).
" constraints ?¦Constraints.
tconstraints do: [:c¦ c is Triggered ifTrue: [triggers add;
(Array with: c trigger with: (c path concat: c ruleTree receiver asPath))]].
self compileResponsesFor:¦Constraints.
? tConstraints getTimeConstraintsOnPath: aPath getTimeConstraintsOnPath:
¦tConstraints¦.
tConstraints ? OrderedCollection new.
thing getTimeConstraintsOnPath:
((AccessPath new names: (Array with: #thing)) concat: aPath) constraints; tConstraints, constraints ? tConstraints.
tConstraints do: [:c ¦ c isTriggered ifTrue: [triggers add:
(array with: c trigger with: (c path concat: c ruleTree receiver asPath))]].
self compileResponsesFor: tConstraints.
?tConstraints tickMessage tickMessage ?MessageNode new receiver: (encoder encodeVariable: 'self') selector;#tick;
arguments: (array with: (encoder encodedLiteral: I)) precedence: #tick:precedence from:encoder initilization basicIniitialize basicInitialize "TheBrowswe anima initialize"
initialized isNil ifTrue: [Transcript show:' initializing', self printString,'; please be patient.
'.
self forgetConstraintMethods, thing ? TheBrowser Prototype.
triggers ? OrderedCollection new.
time ? AMagnitude value: 0.
thingEvents ? EventQueue new.
deltaT isNil ifTrue: [deltaT ?1].
encoder ? Encoder new init: self class context: nil notifying: self.
initalized ? false]
deInitialize deInitialize initialized ? nil initialization Anima forgetConstraintMethods forgetConstraintMethods Methods ? Dictionary new.
initialize initialize "TheBrowser anima initialize"
initialized isNil ifTrue: [Transcript show: ' initializing ', self printString, ': please be patient.
'.
self forgetConstraintMethods.
thing ? TheBrowser prototype.
triggers ? OrderedCollection new.
time ? AMagnitude value: 0.
thingEvents ? EventQueue new.
deltaT isNil ifTrue: [deltaT ? 1].
encoder ? Encoder new init: self class context: nil notifying: self.
self getTimeConstaints.
initialized ? true]
showing showPicture: medium showPicture:
"do nothing"
?self access constraints constraints ?constraints deltaT deltaT
?deltaT
deltaT: aNumber deltaT:
deltaT ? aNumber encoder encoder ?encoder merges merges ?Array new receiver receiver "need this for Compiler evaluate:in:"
?self recopy: dict recopy:
?self thing thing ?thing access Anima thingEvents thingEvents ?thingEvents time time ?time triggers triggers ?triggers ConstraintSatisfactionPlanner variableSubclass:#AnimusSatisfactionPlanner instanceVariableNames: 'message ' classVariableNames: "
poolDictionaries: "
category: 'Animus-Constraints' AnimusSatisfactionPlanner AnimusSatisfactionPlanner access message message ?message message: aMessage message:
message ? aMessage AnimusSatisfactionPlanner class AnimusSatisfactionPlanner class AnimlusSatisfactionPlanner class instanceVariableNames: "

Instance creation for: anObject message: aMessage for:message:
¦planner¦
planner ? super for: anObject planner message: aMessage.
?planner TemporalConstraint Constraint subclass: #TemporalConstraint TemporalConstraint instanceVariableNames: 'path response animaindex' classVariableNames: 'FieldDescriptions' poolDictionaries:"
category: 'Animus-Constraints' access animaIndex animaIndex ?animaIndex animaIndex: anIndex animaIndex:
animaIndex ? anIndex path path ?path path: aPath path:
path ? aPath response response ?response response: aResponsePrototype response:
response ? aResponsePrtotype trigger trigger ?nil compiling addMethods:context:owner:receiever:
addMethods: queue context: context owner: owner receiver: receiver "add my message to the queue"
¦queuedDescr eventQueueingMessage¦
(self overlaps: receiver) ifFa1se: ?nil].
"see if I have already been told to add messages to the queue"
(self shouldNotAddTo: queue owner: owner receiver: receiver) ifTrue: [?nil].
methodDescriptions with: methodTrees do: [:descr: method¦descr referenceOnly ifFalse:
["make a message plan with the corrcct context, receiver, owner."
queuedDescr ? QueuedMethodDescription new context: context receiver: path asPath constraint: self owner: owner compiling TemporalConstraint uniqueState: descr uniqueState referenceOnly: descr referenceOnly compileTimeOnly: descr compileTimeOnly constraintMethod: (self relocatedResponseEncoder: context encoder).
queue add: queuedDescr.
queuedDescr addMethods: queue]]
basicMethod: encoder in: anAnima basicMethod:in:
?encoder encodeVariable: 'nil' relocatedResponseEncoder: encoder relocatedReaponseEncoder:
¦sel¦
sel ? (self relocateResponseEncoder: encoder) selector.
?MessageNode new receiver. (encoder encodeVariable: 'self') selector: sel arguments: #0 precedence: sel precedence from: encoder relocateResponse: encoder triggers: triggers relocateResponse:triggers:
?self relocateResponseEncode: encoder relocateResponseEncoder: encoder relocateResponseEncoder:
?response: responseMethod copy relocatePaths: path encoder: encoder testing isPostlude isPostlude ?false isTemporal isTemporal ?true isTriggered isTriggered ?false shouldNotAddTo: queue owner: owner shouldNotAddTo:owner:
?(queue hasConstraint: self owner: owner) shouldNotAddTo: queue owner: owner receiver: receiver shouldNotAddTo:owner:receiver:
?(queue hasConstraint: self owner: owner) or: [(receiver firstName = #time) not]

TemporalConstraint class TemporalConstraint class TemporalConstraint class instanceVariableNames: "

initialization owner: owner rule: ruleString owner:rule:
self owner: owner rule: ruleString test: nil error: nil methods: #('self responding') response:
(ImmediateResponse with: (Compiler new parse: 'responding', ruleString in: owner class notifying: nil)) owner:rule:test:error:methods:response:
owner: owner rule: ruleString test: testString error: errorString methods: methodString response: resp ¦timeConstraint¦
timeConstraint ? self owner: owner rule: ruleString test: testString error: errorString methods: methodString.
timeConstraint response: resp.
?timeConstraint FunctionConstraint TemporalConstraint subclass: #FunctionConstraint FunctionConstraint instanceVariableNames: 'function' classVariableNames: "
poolDictionaries: "
calegory: 'Animus-Constraints' testing overlaps: otherPath overlaps:
?otherPath names first = #time "or: [ruleTree receiver asPath overlaps: otherPath]"

compiling addMethods:context:owner:receiver:
addMethods: queue context: context owner: owner receiver: receiver "add my messages to the queue"
¦queuedDescr eventQueueingMessage¦
(self overlaps: receiver) ifFalse: [?nil].
"see if I have already been told to add messages to the queue"
(queue hasConstraint: self owner: owner) ifTrue: [?nil].
methodDescriptions with: methodTrees do: [:descr:method¦descr referenceOnly ifFalse:
["make a message plan with the correct context, receiver, and owner."
queuedDescr ? QueuedMethodDescription new context: context receiver: receiver constraint: self owner: owner uniqueState: descr uniqueState referenceOnly: descr referenceOnly compileTimeOnly: descr compileTimeOnly constrainlMethod; (self makeEnqueuingMethodin; context).
queue add: queuedDescr.
queuedDescr addMethods: queue]]
basicMethod: encoder in: anAnima basicMethod:in ?(anAnima transform: (MessagePlan new context: anAnima receiver: (path concat: ruleTree receiver asPath) constraint nil owner: EmptyPath keywords: #('setTo:') arguments: #('delta') uniqueState: true referenceOnly:
false compileTimeOnly: false)) code: eneoder makeEnqueuingMethodIn: context makeEnqueuingMethodIn:
¦newEventNode incrementedTimeNode eventNode eventArrayNode selectorNode argArrayNode¦
(context encoder scopeTable includesKey: 'argl') ifTrue: [nil] ifFalse: [context encoder bindTemp: 'argl'].
newEventNode ? MessageNode new receiver: (context encoder encodeLiteral: Event) selector: #new nplllng Function Constraint arguments: #0 precedence: #new precedence from: context encoder.
incrementedTimeNode ? MessageNode new receiver ((AccessPath new names: #(time value)) code: context encoder) selector: #+
arguments: (Array with: (context encoder encodeVariable:'argl')) precedence: #+precedence from: context encoder.
selectorNode ? MessageNode new receiver:(context encoder encodeLiteral:(path concat:ruleTree receiver asPath)incrementSelector) selector: #asSymbol arguments: #0 precedence: #asSymbol precedence from: context encoder.
argArrayNode ? MessageNode new receiver (context encoder encodeLiteral:Array) selector: #with:
arguments: (Array with: (context encoder encodeVariable:'argl')) precedence: #with: precedence from: context encoder.
eventNode ? MessageNode new receiver newEventNode selector: #atTime: receiver: selector: arguments:
arguments: (Array with: incrementedTimeNode wiih: (context encoder encodeVariable:'self') with selectorNode with: argArrayNode) precedence: #atTime: receiver: selector: arguments: precedence from: context encoder.
eventArrayNode ? MessageNode new receiver: (context encoder encodeLiteral: Array) selector: #with:
arguments: (Array with: eventNode) precedence: #with: precedence from: context encoder.
?MessageNode new receiver: (context encoder encodeVariable:'thingEvents') selector #enqueue:
arguments:(Array with:eventArrayNode) precedence: #enqueue: precedence from: context encoder FunctionConstraint class FunctionConstraint clsss FunctionConstraint class instanceVariableNames:"

FunctionConstraint initilaization owner:owner to:partPathStringfunctionString: owner:to:function:
¦methodString constraint functionMethod ¦

functionMethod ? (Compiler new parse: partPathStringasincrementSelector,'ignored¦delta¦
delta ? TheBrowser prototype anima time value', functionString in:owner class notifying:nil).
methodString ? 'self respond'.
constraint ? self owner: owner rule:partPathString,'followsTimeFunction:#,functionString test:nil error: nil methods:(Array with: methodString)response:
(ImmediateResponse with: functionMethod).
?constraint TimeFunctionConstriant FunctionConstraint subclass:#TimeFunctionConstriant TimeFunctionConstriant instanceVariableNames:"
classVaiableNames:"
poolDictionaries:"
category:'Animus-Constraints' TimeFunctionConstriant TimeFunctionConstriant class TimeFunctionConstriant class instanceVariableNames:"
owner:owner to:partPathStringfunctionString: owner:to:function:
¦methodString constraint functionMethod ¦

functionMethod ? (Compiler new parse: partPathStringasincrementSelector,'ignored¦delta¦
delta ? TheBrowser prototype anima time value',functionString in:owner class notifying:nil).
methodString ? 'self respond'.
constraint ? self owner: owner rule:partPathString,'followsTimeFunction:#,functionString test:nil error: nil methods:(Array with: methodString)response:
(ImmediateResponse with: functionMethod).
?constraint ScrlptConstralnt TemporalConstraint subclass: #ScriptConstraint ScriptConstraint instance Variabie Names:'script' classVariableNames: "
poolDistionaries:"
category:'Animus-Constraints' testing overlaps: otherPath overlaps:
?ruleTree receiver asPath overlaps: otherPath printing printOn:strm printOn:
super printOn:strm.
script prinlOn: strm.
?strm contents compilling relocateResponseEncoder: encoder relocateResponseEncoder:
(path applyTo:TheBrowser prototype anima)set.script:(response eventArray collect:[:eventTree¦eventTree copy relocatePaths:path encoder:encoder]).
?esponse responseMethod copy relocatePaths:path encoder: encoder ScriptConstraint class ScriptConstraint class ScriptConstraint class instanceVariableNames:"

initiailzation owner: owner fromFile: fileName owner:fromFile:
¦response mehodString events constraint¦ -?self owner:ownerto:ownerscript:(Compiler evaluate:(FileStream fileNamed:fileName)contentsOfEntireFile) owner:ownerto:partPathString script:eventStringArray owner:to:script:
¦response methodString constraint events ¦
events ? (1 to:eventStringArray size)collect:[:i¦(Compiler new parse:'method',iprintString,' ',(eventStringArray at:i)in: owner class notifying: nil) block statements first].
methodString ? 'self respond'. "anima thingEvents enqueue:(self',triggerSelectorStringselectorWithArgs, constraint ? self owner: owner rule: 'self followsScript: #', eventStringArray printString test: nil error:nil methods:(Array with:methodString) response:
(Script with:

I???allzation ScriptConstraint class (Compiler new parse:'respond TheBrowser prototype anima thingEvents enqueueShifted:self script.
self set.script:nil' in:owner class notifying:nil)eventArray:events).
?constraint TimeDifferentialConstraint TemporalConstraint subclass: #TimeDifferentialConstraint TimeDifferentialConstraint instanceVariableNames:"
classVariableNames: 'FieldDescriptions' poolDictionaries:"
category: 'Animus-Constraints' compiling addMethods:context:owner:receiver:
addMethods: queue context: context owner: owner receiver: receiver "add my messages so the queue"
¦ queuedDescr eventQueueingMessage ¦
(self overlaps: receiver) ifFalse: [?nil].
"see if I have already been told to add messages to the queue"
(queue hasConstraint: self owner: owner) ifTrue: [?nil].
methodDescriptions with: methodTrees do: [:descr: method ¦ descr referenceOnly ifFalse:
["make a message plan with the correct context, receiver, and owner."
queuedDescr ? QueuedMethodDescription new context: context receiver: receiver constraint: self owner: owner uniqueState: descr uniqueState referenceOnly: descr referenceOnly compileTimeOnly: descr compileTimeOnly constaintMethod: (self makeEnqueingMethodIn: context).
queue add: queuedDescr.
queuedDescr addMethods: queue]]
basicMethod: encoder in: anAnima basicMethod:in:
?(anAnima transform: (MessagePlan new context: anAnima receiver. (path concat: ruleTree receiver asPath) constraint: nil owner. EmplyPath keywords: #('incrementby:') arguments:#('delta')uniqueState:true referenceOnly: false compileTimeOnly: false)) code:encoder makeEnqueuingMethodIn:context makeEnqueuingMethodIn:
¦newEventNode incrementedTimeNode eventNode eventArrayNode selectorNode argArrayNode¦
(context encoder scope Table includesKey: 'argl') ifTrue:[nil]ifFalse: [context encoder bindTemp: 'argl']
newEventNode ? MessageNode new receiver: (context encoder encodeLiteral: Event) selector: #new arguments: #O
precedence: #new precedence from: context encoder.
incrementedTimeNode ? MessageNode new receiver: ((AccessPath new names: #(time value)) code: context encoder) compiling TimeDifferentialConstraint selector: #+
arguments: (Array with: (context encoder encodeVariable: 'argl')) precedence: #+ precedence from: context encoder.
selectorNode ? MessageNode new receiver: (context encoder encodeLiteral:(path concat: ruleTree receiver asPath) incrementSelector) selector: #asSymbol arguments: #O
precedence: #asSymbol precedence from: context encoder.
argArrayNode ? MessageNode new receiver:(context encoder encodeLiteral: Array) selector:#with:
arguments: (Array with:(context encoder encodeVariable: 'argl')) precedence: #with:precedence from: context encoder.
eventNode ? MessageNode new receiver: newEventNode selector: #atTime:receiver:selector:arguments:
arguments: (Array with: incrementedTimeNode with:(context encoder encodeVariable:'self') with: selectorNode with: argArrayNode) precedence: #atTime:receiver:selector:arguments:precedence from: context encoder.
eventArrayNode ? MessageNode new receiver:(context encoder encodeLiteral: Array) selector:#with:
arguments: (Array with:eventNode) precedence: #with: precedence from: context encoder.
?MessageNode new receiver: (context encoder encodeVariable: 'thingEvents') selector: #enqueue:
arguments: (Array with: eventArrayNode) precedence: #enqueue: precedence from: context encoder relocateResponse: encoder triggers: triggers relocateResponse:triggers:
?self relocateResponseEncoder:encoder relocateResponse: encoder relocateResponseEncoder:
?response responseMethod copy relocatePaths: path encoder: encoder testing overlaps: otherPath overlaps:
otherPath firstName = #time ifTrue:[?true].
?false TimeDifferentialConstraint class TimeDifferentialConstraint class TimeDifferentialConstraint class inslanceVanableNames: "

initialization owner:rule:test:error:timeDerivativeOf:equals:
owner:owner rule: ruleString test: testString error: errorString timeDerivativeOf: differentialString equalsString ¦differentialMethod differenlialPath differentialMethodString¦
differentialPath?differentialString asPath.
differentialMethodString ? differentialPath incrementSelector, ' t1 ¦ delta ¦
delta ? ', equalsString, ' *t1'.
differentialMethod ? Compiler new parse: differentialMethodString in: owner class notifying: nil.
?self owner:owner rule:ruleString test: testString error: errorString methods: #('self responding') response:
(ImmediateResponse with: differentialMethod) owner:timeDerivativeOf:equals:
owner: owner timeDerivativeOf: differentialString equals: equalsString ?self owner:owner rule: ( differendalString, 'derivativeWRTtime: ', equalsString) test: nil error: nil timeDerivativeOf: differentialString equals: equalsString TriggerConstraint TemporalConstraint subclass: #TriggerConstraint TriggerConstraint instanceVariableNames: 'trigger postlude' classVariableNames: "
poolDictionaries: "
category: 'Animus-Constraints' testing isPostlude isPostlude ?postlude isTriggered isTriggered ?true overlaps: otherPath overlaps:
?ruleTree receiver asPath overlaps: otherPath shouldNotAddTo: queue owner: owner shouldNotAddTo:owner:
?((queue message = trigger) not) or:[(queue hasConstraint: self owner: owner) or:[((path extendedSelector: ruleTree arguments first key) = queue message) not]]
shouldNotAddTo: queue owner: owner receiver: receiver shouldNotAddTo:owner:receiver:
?((queue message = trigger) not) or:[(queue hasConstraint self owner:owner) or:[((path extendedSelector:ruleTree arguments first key)= queue message)not]]

compiling basicMethod: encoder in: anAnima basicMethod:in:
?MessageNode new receiver: ((path concat: ruleTree receiver asPath) code: encoder) selector: response responseMethod selector arguments: response responseMethod arguments precedence: response responseMethod selector precedence from: encoder makeEnqueuingMethodFrom: encoder makeEnqueuingMethodFrom:
¦newCollectionNode assignNode intervalNode fractionNode multiplyNode incrementedTimeNode selectorNode newEventNode eventNode addNode innerBlocknode doNode eventArrayNode outerBlockNode innerBlockNode constraintIndexNode respondentNode initialNode additionalNode¦
(encoder scopeTable includesKey: 't1') ifTrue: [nil] ifFalse: [encoder bindTemp't1']
(encoder scopeTable includesKey: 'eventCollection') ifTrue: [nil] if False: [encoder bindTemp:
'eventCollection'].
(encoder scopeTable includesKey: 'i') ifTrue: [nil] ifFalse: [encoder bindTemp: 'i'].
newCollectionNode ? MessageNode new receiver: (encoder encodeLiteral: OrderedCollection) selector: #new arguments: #O
precedenoe: #new precedence from: encoder.
assignNode ? AssignmentNode new variable: (encoder encodeVariable: 'eventCollection') compiling TriggerConstraint value: newCollectionNode from: encoder.
constraintIndexNode ? MessageNode new receiver: (encoder encodeVariable: 'constraints') selector #at:
arguments: (Array with: (encoder encodeLiteral: animaIndex)) precedence: #at: precedence from: encoder.
respondentNode ? MessageNode new receiver: constraintIndexNode selector: #response arguments: #0 precedence: #response precedence from: encoder.
intervalNode ? MessageNode new reeceiver: (encoder encodeLiteral: 1) selector: #to:
arguments: (Array with: (encoder encodeLiteral: 25)) precedence: #to: precedence from: encoder.
fractionNode ? MessageNode new receiver: (encoder encodeVariable: 'deltaT') selector: #/
arguments: (Array with: (encoder encodeLiteral: 26)) precedence: #/precedence from: encoder.
multiplyNode ? MessageNode new receiver: fractionNode selector: #*
arguments: (Array with: (encoder encodeVariable: 'i')) precedence: #* precedence from: encoder.
incrementedTimeNode ? MessageNode new receiver: ((AccessPath new names: #(time value)) code: encoder) selector: #+
arguments: (Array with: multiplyNode) precedence: #+ precedence from: encoder.
newEventNode ? MessageNode new receiver: (encoder encodeLiteral: Event) selector: #new arguments: #0 precedence: #new precedence from: encoder.
initialNode ? MessageNode new receiver: newEventNode selector: #atTime: receiver: selector: arguments:
arguments: (Array with: ((AccessPath new names: #(time value)) code: encoder) with: respondentNode with: (encoder encodeLiteral: #initialize:) with: (encoder encodeLiteral: #0)) precedence: #atTime: receiver: selector: arguments: precedence from: encoder.
additionalNode ? MessageNode new receiver: (encoder encodeVariable: 'eventCollection') compiling Trigger Constraint selector # add:
arguments: (Array with: initial Node) precedence: # add: precedence from: encoder.
event Node ? Message Node new receiver: new Event Node selector: # at Time: receiver selector: arguments:
arguments: (Array with: incremented Time Node with: respondent Node with: (encoder encode Literal: # step:) with: (encoder encode Literal: # O)) precedence: # at Time: receiver: selector: arguments: precedence from: encoder.
add Node ? Message Node new receive: (encoder encode Variable: 'event Collection') selector: # add:
arguments: (Array with: event Node ) precedence: # add: precedence from: encoder.
inner Block Node ? Block Node new arguments: (Array with: (encoder encode Variable: 'i')) statements: (Array with: add Node) returns: false from: encoder source End: 1.
do Node ? Message Node new receiver: interval Node selector: # do:
arguments: (Array with: inner Block Node) precedence: # do: precedence from: encoder.
outer Block Node ? Block Node new statements: (Array with: assign Node with: addinitial Node with: do Node with: (encoder encode Variable:
'event Collection')) returns: false.
event Array Node ? Message Node new receiver outer Block Node selector: # value arguments: # O
precedence: # value precedence from: encoder.
self half ? Message Node new receiver (encoder encode Variable: 'thing Events') selector: # enqueue:
arguments: (Array with: event Array Node) precedence: # enqueue: precedence from: encoder relocate Response: encoder triggers: triggers relocate Response: triggers:
? tree ?
tree ? response response Method copy relocate Paths: path part: rule Tree receiver as Path encoder: encoder.
?tree compress Trigger: triggers encoder: encoder Trigger Constraint printing print On: strm print On:
super print On: strm.
path print On: strm.
? strm contents access postiude: boolean postiude:
postiude ? boolean trigger trigger ?trigger trigger: a Symbol trigger:
trigger ? a Symbol Trigger Constraint class Trigger Constraint class Trigger Constraint class instance Varabie Names:"

Initialization owner: to: trigger: causes:
owner: ownr to: part Path String trigger: trigger Selector String causes: a Response String ? response method String response Method constraint ?I
response Method ? Compiler new parse: trigger Selector String selector With Args, a Response String in: owner class notifying: nil.
method String ? 'self respond'. "anima thing Events enqueue: (self', trigger Selector String selector With Args, ')'".
constraint ? self owner: owner rule: ( part Path String, 'triggers On: #'; trigger Selector String) test nil error: nil methods: (Array with: method String) response: (Triggered Response new response Method: response Method).
constraint trigger: trigger Selector String as Symbol.
constraint postiude: false.
?constraint owner: to: trigger: causes: postlude:
owner: owner to: part Path String trigger: trigger Selector String causes: a Response String postlude: boolean ?c?
c ? self owner: owner to: part Path String trigger: trigger Selector String causes: a Response String.
c postlude: boolean.
?c Algorithm Constraint Trigger Constraint subclass: #Algorithm Constraint Algorithm Constraint instance Variable Names:"
class Variable Names:"
pool Dictionaries:"
category: 'Animus-Constraints' compiling basic Method: encoder in: an Anima basic Method: in:
?encoder encode Variable: 'nil' Part Description subclass: # Indexed Part Description instance Varible Names: "
class Variable Names: "
pool Dictionaries: "
category: 'Animus-Fields' Indexed Part Description Indexed Part Description testing is Indexed is Indexed ?true Rectangle initialize Prototype Line Segment initialize Prototype Point initialize Prototype Text Thing initialize Prototype
CA000538545A 1986-07-25 1987-06-03 System for animating program operation and displaying time-based relationships Expired - Fee Related CA1274310A (en)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
US891,071 1986-07-25
US06/891,071 US4821220A (en) 1986-07-25 1986-07-25 System for animating program operation and displaying time-based relationships

Publications (1)

Publication Number Publication Date
CA1274310A true CA1274310A (en) 1990-09-18

Family

ID=25397562

Family Applications (1)

Application Number Title Priority Date Filing Date
CA000538545A Expired - Fee Related CA1274310A (en) 1986-07-25 1987-06-03 System for animating program operation and displaying time-based relationships

Country Status (4)

Country Link
US (1) US4821220A (en)
EP (1) EP0254438A3 (en)
JP (1) JPS6336354A (en)
CA (1) CA1274310A (en)

Families Citing this family (194)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JPS6441966A (en) * 1987-08-07 1989-02-14 Hitachi Ltd Method for displaying routing
JPH01108681A (en) * 1987-10-20 1989-04-25 Nec Corp Moving image specification input system
US4970664A (en) * 1988-06-10 1990-11-13 Kaiser Richard R Critical path analyzer with path context window
JP2522541B2 (en) * 1989-03-24 1996-08-07 三菱電機株式会社 Simulation device and simulation method
US5125091A (en) * 1989-06-08 1992-06-23 Hazox Corporation Object oriented control of real-time processing
US5247650A (en) * 1989-08-30 1993-09-21 Industrial Technology Institute System for combining originally software incompatible control, kinematic, and discrete event simulation systems into a single integrated simulation system
US5043920A (en) * 1989-09-20 1991-08-27 International Business Machines Corporation Multi-dimension visual analysis
US5161223A (en) * 1989-10-23 1992-11-03 International Business Machines Corporation Resumeable batch query for processing time consuming queries in an object oriented database management system
US5161225A (en) * 1989-10-23 1992-11-03 International Business Machines Corporation Persistent stream for processing time consuming and reusable queries in an object oriented database management system
US5313629A (en) * 1989-10-23 1994-05-17 International Business Machines Corporation Unit of work for preserving data integrity of a data-base by creating in memory a copy of all objects which are to be processed together
US5202981A (en) * 1989-10-23 1993-04-13 International Business Machines Corporation Process and apparatus for manipulating a boundless data stream in an object oriented programming system
JPH0833862B2 (en) * 1989-10-23 1996-03-29 インターナシヨナル・ビジネス・マシーンズ・コーポレーシヨン Object-oriented computer system
US5210700A (en) * 1990-02-20 1993-05-11 International Business Machines Corporation Automatic delay adjustment for static timing analysis
US5133073A (en) * 1990-05-29 1992-07-21 Wavetracer, Inc. Processor array of N-dimensions which is physically reconfigurable into N-1
US5157785A (en) * 1990-05-29 1992-10-20 Wavetracer, Inc. Process cell for an n-dimensional processor array having a single input element with 2n data inputs, memory, and full function arithmetic logic unit
US5239493A (en) * 1990-06-26 1993-08-24 Digital Equipment Corporation Method and apparatus for interpreting and organizing timing specification information
EP0463732A3 (en) * 1990-06-28 1992-10-14 International Business Machines Corporation Method and system for animating the execution of a computer program
DE69126666T2 (en) * 1990-09-17 1998-02-12 Cabletron Systems Inc NETWORK MANAGEMENT SYSTEM WITH MODEL-BASED INTELLIGENCE
US5265206A (en) * 1990-10-23 1993-11-23 International Business Machines Corporation System and method for implementing a messenger and object manager in an object oriented programming environment
US5335339A (en) * 1990-11-22 1994-08-02 Hitachi, Ltd. Equipment and method for interactive testing and simulating of a specification of a network system
US5307499A (en) * 1990-11-30 1994-04-26 Singapore Computer Systems Limited Interpretive object-oriented facility which can access pre-compiled classes
US5459868A (en) * 1990-11-30 1995-10-17 St Computer Systems & Services Interpretive object-oriented facility which can access pre-compiled classes
EP0490478A2 (en) * 1990-12-14 1992-06-17 Tektronix Inc. Automatic compilation of model equations into a gradient based analog simulator
US5276885A (en) * 1991-04-18 1994-01-04 Carnegie Group Single step mapping in topological order of the queued class and instance frames of a semantic network to a static working memory
US5402361A (en) * 1991-04-18 1995-03-28 X-Rite, Incorporated Apparatus for method for logging, storing, and redirection of process related non-densitometric data generated by color processing equipment for use by an off site host computer
US6484189B1 (en) 1991-04-26 2002-11-19 Amiga Development Llc Methods and apparatus for a multimedia authoring and presentation system
US5317732A (en) * 1991-04-26 1994-05-31 Commodore Electronics Limited System for relocating a multimedia presentation on a different platform by extracting a resource map in order to remap and relocate resources
US5574843A (en) * 1991-04-26 1996-11-12 Escom Ag Methods and apparatus providing for a presentation system for multimedia applications
GB9110336D0 (en) * 1991-05-13 1991-07-03 Young Arthur P Methods and computing equipment for real time application
JP2788820B2 (en) * 1991-08-30 1998-08-20 三菱電機株式会社 Simulation equipment
US5852449A (en) * 1992-01-27 1998-12-22 Scientific And Engineering Software Apparatus for and method of displaying running of modeled system designs
US5241675A (en) * 1992-04-09 1993-08-31 Bell Communications Research, Inc. Method for enforcing the serialization of global multidatabase transactions through committing only on consistent subtransaction serialization by the local database managers
EP0567699A1 (en) * 1992-04-30 1993-11-03 Hewlett-Packard Company Object based system
US5544295A (en) * 1992-05-27 1996-08-06 Apple Computer, Inc. Method and apparatus for indicating a change in status of an object and its disposition using animation
US5528261A (en) * 1992-06-09 1996-06-18 Apple Computer, Inc. Operating system software architecture and methods for supporting color processing
US5511196A (en) * 1992-11-17 1996-04-23 International Business Machines Corporation Method and system in a data processing system for the enhancement of relationships between reference objects in an object oriented environment and a data object outside an object oriented environment
US5991538A (en) * 1992-12-18 1999-11-23 Inprise Corporation System for generating and using programs in an object-oriented environment with a message dispatch architecture
US5434965A (en) * 1992-12-23 1995-07-18 Taligent, Inc. Balloon help system
US5550563A (en) * 1992-12-23 1996-08-27 Taligent, Inc. Interaction framework system
US5530864A (en) * 1992-12-23 1996-06-25 Taligent Command object system for an object-oriented software platform
WO1994015281A1 (en) * 1992-12-23 1994-07-07 Taligent, Inc. Atomic command system
DE69310187T2 (en) * 1992-12-23 1997-11-27 Taligent Inc OBJECT-ORIENTED FRAMEWORK SYSTEM
US5390325A (en) * 1992-12-23 1995-02-14 Taligent, Inc. Automated testing system
US5551055A (en) * 1992-12-23 1996-08-27 Taligent, Inc. System for providing locale dependent user interface for presenting control graphic which has different contents or same contents displayed in a predetermined order
US6259446B1 (en) 1992-12-23 2001-07-10 Object Technology Licensing Corporation Menu state system
US5315703A (en) * 1992-12-23 1994-05-24 Taligent, Inc. Object-oriented notification framework system
AU6081994A (en) * 1993-01-22 1994-08-15 Taligent, Inc. Flexible system
AU6019094A (en) * 1993-01-22 1994-08-15 Taligent, Inc. Business card system
US5428718A (en) * 1993-01-22 1995-06-27 Taligent, Inc. Tessellation system
US5394523A (en) * 1993-01-22 1995-02-28 Taligent, Inc. Polymorphic graphic device
CA2135522A1 (en) * 1993-01-22 1994-08-04 Object Technology Licensing Corporation Flexible network system
US5519862A (en) * 1993-02-26 1996-05-21 Taligent, Inc. Concurrent processing apparatus with incremental command objects
AU6161594A (en) 1993-02-26 1994-09-14 Taligent, Inc. Collaborative work system
US5369766A (en) * 1993-03-25 1994-11-29 Taligent, Inc. Object-oriented loader system with support for different load formats
CA2135517A1 (en) * 1993-03-25 1994-09-29 Patrick Delaney Ross Multi-level interrupt system
US5485373A (en) * 1993-03-25 1996-01-16 Taligent, Inc. Language-sensitive text searching system with modified Boyer-Moore process
EP0692114B1 (en) * 1993-03-31 2000-02-02 Object Technology Licensing Corp. Time-based script sequences
EP0692125B1 (en) * 1993-03-31 1999-10-27 Object Technology Licensing Corp. Costume objetcs
AU6390994A (en) * 1993-04-05 1994-10-24 Taligent, Inc. Font selection system
DE69400276T2 (en) * 1993-04-05 1997-02-13 Taligent Inc CHARACTER SET FOR TEXT INPUT
US5459865A (en) * 1993-04-05 1995-10-17 Taligent Inc. Runtime loader
AU6018694A (en) * 1993-04-26 1994-11-21 Taligent, Inc. Text transliteration system
US5432948A (en) * 1993-04-26 1995-07-11 Taligent, Inc. Object-oriented rule-based text input transliteration system
US5544302A (en) * 1993-06-03 1996-08-06 Taligent, Inc. Object-oriented framework for creating and using container objects with built-in properties
CN1113395A (en) * 1993-06-03 1995-12-13 塔里根特公司 Place object display system
JP3798015B2 (en) * 1993-06-03 2006-07-19 オブジェクト テクノロジー ライセンシング コーポレイション Place object system
US5524190A (en) * 1993-06-04 1996-06-04 Taligent, Inc. Command object logging system for restoring documents
US5471568A (en) * 1993-06-30 1995-11-28 Taligent, Inc. Object-oriented apparatus and method for scan line conversion of graphic edges
US5487145A (en) * 1993-07-09 1996-01-23 Taligent, Inc. Method and apparatus for compositing display items which minimizes locked drawing areas
US5379432A (en) 1993-07-19 1995-01-03 Taligent, Inc. Object-oriented interface for a procedural operating system
WO1995003574A1 (en) * 1993-07-19 1995-02-02 Taligent, Inc. Dynamic linking system
US5404529A (en) * 1993-07-19 1995-04-04 Taligent, Inc. Object-oriented interprocess communication system interface for a procedural operating system
US5473777A (en) * 1993-07-19 1995-12-05 Moeller; Christopher P. Wrapper for enabling an object otented application to maintain virtual memory using procedural function calls
US6684261B1 (en) * 1993-07-19 2004-01-27 Object Technology Licensing Corporation Object-oriented operating system
US5519867A (en) * 1993-07-19 1996-05-21 Taligent, Inc. Object-oriented multitasking system
US5455951A (en) * 1993-07-19 1995-10-03 Taligent, Inc. Method and apparatus for running an object-oriented program on a host computer with a procedural operating system
US5471675A (en) * 1993-07-27 1995-11-28 Taligent, Inc. Object oriented video framework system
EP0713594B1 (en) * 1993-07-27 1997-10-15 Taligent, Inc. Object-oriented rendering system
US5479589A (en) * 1993-08-04 1995-12-26 Taligent, Inc. Object-oriented system for selecting a graphic image on a display
US5396626A (en) * 1993-08-04 1995-03-07 Taligent, Inc. Object-oriented locator system
US5379430A (en) * 1993-08-04 1995-01-03 Taligent, Inc. Object-oriented system locator system
US5586236A (en) * 1993-08-11 1996-12-17 Object Technology Licensing Corp. Universal color look up table and method of generation
US5621434A (en) * 1993-08-11 1997-04-15 Object Technology Licensing Corp. Cursor manipulation system and method
US5566278A (en) * 1993-08-24 1996-10-15 Taligent, Inc. Object oriented printing system
US5481666A (en) * 1993-08-25 1996-01-02 Taligent, Inc. Object-oriented navigation system
US5500929A (en) * 1993-08-30 1996-03-19 Taligent, Inc. System for browsing a network resource book with tabs attached to pages
US5428744A (en) * 1993-08-30 1995-06-27 Taligent, Inc. Object-oriented system for building a graphic image on a display
US5390138A (en) * 1993-09-13 1995-02-14 Taligent, Inc. Object-oriented audio system
JP3770616B2 (en) * 1993-09-13 2006-04-26 オブジェクト テクノロジー ライセンシング コーポレイション Object-oriented video system
US5388264A (en) * 1993-09-13 1995-02-07 Taligent, Inc. Object oriented framework system for routing, editing, and synchronizing MIDI multimedia information using graphically represented connection object
AU6019994A (en) * 1993-09-13 1995-04-03 Taligent, Inc. Multimedia data routing system
US5511002A (en) * 1993-09-13 1996-04-23 Taligent, Inc. Multimedia player component object system
CA2153964A1 (en) * 1993-09-13 1995-03-23 Steven H. Milne Object-oriented audio record/playback system
US5583977A (en) * 1993-10-21 1996-12-10 Taligent, Inc. Object-oriented curve manipulation system
US5522025A (en) * 1993-10-25 1996-05-28 Taligent, Inc. Object-oriented window area display system
US5455854A (en) * 1993-10-26 1995-10-03 Taligent, Inc. Object-oriented telephony system
EP0712513B1 (en) * 1993-10-29 1997-06-04 Taligent, Inc. Graphic editor framework system
WO1995012866A1 (en) * 1993-11-02 1995-05-11 Taligent, Inc. Object-oriented graphic system
US5455952A (en) * 1993-11-03 1995-10-03 Cardinal Vision, Inc. Method of computing based on networks of dependent objects
US5428722A (en) * 1993-11-05 1995-06-27 Taligent, Inc. Object-oriented painter maker
US6040838A (en) * 1993-11-05 2000-03-21 Obejct Technology Licensing Corporation Graphic state processing
US5537526A (en) * 1993-11-12 1996-07-16 Taugent, Inc. Method and apparatus for processing a display document utilizing a system level document framework
WO1995015524A1 (en) * 1993-12-02 1995-06-08 Taligent, Inc. Method and apparatus for displaying hardware dependent graphics in an object-oriented operating system
US5548726A (en) * 1993-12-17 1996-08-20 Taligeni, Inc. System for activating new service in client server network by reconfiguring the multilayer network protocol stack dynamically within the server node
US5499343A (en) * 1993-12-17 1996-03-12 Taligent, Inc. Object-oriented networking system with dynamically configurable communication links
US5548723A (en) * 1993-12-17 1996-08-20 Taligent, Inc. Object-oriented network protocol configuration system utilizing a dynamically configurable protocol stack
AU6702594A (en) * 1993-12-17 1995-07-03 Taligent, Inc. Object-oriented distributed communications directory service
US5530799A (en) * 1993-12-17 1996-06-25 Taligent Inc. Rendering cache in an object oriented system
US5594921A (en) * 1993-12-17 1997-01-14 Object Technology Licensing Corp. Authentication of users with dynamically configurable protocol stack
US5515508A (en) * 1993-12-17 1996-05-07 Taligent, Inc. Client server system and method of operation including a dynamically configurable protocol stack
US5491800A (en) * 1993-12-20 1996-02-13 Taligent, Inc. Object-oriented remote procedure call networking system
US5371884A (en) * 1993-12-21 1994-12-06 Taligent, Inc. Processor fault recovery system
AU6814594A (en) * 1993-12-21 1995-07-10 Taligent, Inc. Automatic hardware configuration
US5566346A (en) * 1993-12-21 1996-10-15 Taligent, Inc. System for constructing hardware device interface software systems independent of operating systems including capability of installing and removing interrupt handlers
US5680624A (en) * 1993-12-21 1997-10-21 Object Licensing Corporation Object oriented interrupt system
US5548779A (en) * 1993-12-21 1996-08-20 Taligent System for providing system services for a device to a client using stack definition and stack description of a stack having top, intermediate, and bottom service objects
US5546595A (en) * 1993-12-21 1996-08-13 Taligent, Inc. Object-oriented system using objects representing hardware devices, physical connectors and connections between the physical connectors for configuring a computer
US5574915A (en) * 1993-12-21 1996-11-12 Taligent Object-oriented booting framework
WO1995017729A1 (en) * 1993-12-22 1995-06-29 Taligent, Inc. Input methods framework
US5524200A (en) * 1993-12-30 1996-06-04 Taligent, Inc. Object-oriented non-rectilinear viewing framework
WO1995018437A1 (en) * 1993-12-30 1995-07-06 Taligent, Inc. Object-oriented view coordinate space system
US5555368A (en) * 1993-12-30 1996-09-10 Taligent Object-oriented multi-tasking view framework
US5544301A (en) * 1993-12-30 1996-08-06 Taligent, Inc. Object-oriented view layout system
US5524199A (en) * 1993-12-30 1996-06-04 Taligent Object-oriented view system with background processing of update request
US5615326A (en) * 1993-12-30 1997-03-25 Taligent, Inc. Object-oriented viewing framework having view grouping
US5465362A (en) * 1993-12-30 1995-11-07 Taligent, Inc. Object-oriented view-system for displaying information in a windowing environment
WO1995018413A1 (en) * 1993-12-30 1995-07-06 Taligent, Inc. Object-oriented view hierarchy framework
US5832219A (en) * 1994-02-08 1998-11-03 Object Technology Licensing Corp. Distributed object networking service
US5475607A (en) * 1994-04-12 1995-12-12 International Business Machines Corporation Method of target generation for multilevel hierarchical circuit designs
US5680563A (en) * 1994-07-25 1997-10-21 Object Technology Licensing Corporation Object-oriented operating system enhancement for filtering items in a window
US5912666A (en) * 1994-08-23 1999-06-15 Object Technology Licensing Corp. Object-oriented global cursor tool
US5504892A (en) * 1994-09-08 1996-04-02 Taligent, Inc. Extensible object-oriented file system
US5803089A (en) * 1994-09-15 1998-09-08 Visualization Technology, Inc. Position tracking and imaging system for use in medical applications
US5519818A (en) * 1994-09-19 1996-05-21 Taligent, Inc. Object-oriented graphic picking system
US5592600A (en) * 1994-09-27 1997-01-07 International Business Machines Corporation Animated display showing execution of object-oriented programs
JPH10507853A (en) * 1994-10-25 1998-07-28 オブジェクト テクノロジー ライセンシング コーポレイション Object oriented system for servicing windows
US5613122A (en) * 1994-11-14 1997-03-18 Object Technology Licensing Corp. Object-oriented operating system
US5652884A (en) * 1994-11-14 1997-07-29 Object Technology Licensing Corp. Method and apparatus for dynamic update of an existing object in an object editor
US5630131A (en) * 1994-11-14 1997-05-13 Object Technology Licensing Corp. Method and apparatus for importing and exporting archive files for a graphical user interface
US5752245A (en) * 1994-12-09 1998-05-12 Object Technology Licensing Corporation Object-oriented system for configuration history management with a project workspace and project history database for draft identification
US5659735A (en) * 1994-12-09 1997-08-19 Object Technology Licensing Corp. Object-oriented system for program version and history database management system for various program components
US5553282A (en) * 1994-12-09 1996-09-03 Taligent, Inc. Software project history database and method of operation
US5650946A (en) 1995-01-06 1997-07-22 Xilinx, Inc. Logic simulator which can maintain, store and use historical event records
US5713045A (en) * 1995-06-29 1998-01-27 Object Technology Licensing Corporation System for processing user events with input device entity associated with event producer which further links communication from event consumer to the event producer
US6158045A (en) * 1995-11-13 2000-12-05 Object Technology Licensing Corporation Portable debugging services utilizing a client debugger object and a server debugger object with flexible addressing support
US5787245A (en) * 1995-11-13 1998-07-28 Object Technology Licensing Corporation Portable debugging service utilizing a client debugger object and a server debugger object
US5778230A (en) * 1995-11-13 1998-07-07 Object Technology Licensing Corp. Goal directed object-oriented debugging system
US5815653A (en) * 1995-11-13 1998-09-29 You; Lawrence L. Debugging system with portable debug environment-independent client and non-portable platform-specific server
US5812850A (en) * 1995-11-13 1998-09-22 Object Technology Licensing Corp. Object-oriented symbolic debugger using a compiler driven database and state modeling to control program execution
US5956479A (en) * 1995-11-13 1999-09-21 Object Technology Licensing Corporation Demand based generation of symbolic information
US6405263B1 (en) 1995-12-04 2002-06-11 International Business Machines Corporation Method and apparatus for subclassing system object model classes in dynamic languages
US5729765A (en) * 1995-12-07 1998-03-17 Samsung Electronics Co., Ltd. Method and apparatus for determining the status of a shared resource
US5790132A (en) * 1995-12-07 1998-08-04 Object Technology Licensing Corp. Image rendering system with extensible mechanism for providing visual user feedback when an image graphic is selected
US5822580A (en) * 1996-01-19 1998-10-13 Object Technology Licensing Corp. Object oriented programming based global registry system, method, and article of manufacture
EP0927406A4 (en) 1996-03-15 2002-05-02 Zapa Digital Arts Ltd Programmable computer graphic objects
US5875332A (en) * 1996-05-31 1999-02-23 International Business Machines Corporation Generating a common gateway interface adapter customized for a stored procedure
US5819068A (en) * 1996-05-31 1998-10-06 United Defense, Lp Temporally driven simulation engine
US5877768A (en) * 1996-06-19 1999-03-02 Object Technology Licensing Corp. Method and system using a sorting table to order 2D shapes and 2D projections of 3D shapes for rendering a composite drawing
GB9616184D0 (en) * 1996-08-01 1996-09-11 Philips Electronics Nv Virtual environment navigation
US5857093A (en) * 1996-09-20 1999-01-05 Allen-Bradley Company, Llc Cross-compiled simulation timing backannotation
GB9703016D0 (en) * 1997-02-07 1997-04-02 Cyberclass Limited Animation system and mehod
US5923867A (en) * 1997-07-31 1999-07-13 Adaptec, Inc. Object oriented simulation modeling
US6134594A (en) 1997-10-28 2000-10-17 Microsoft Corporation Multi-user, multiple tier distributed application architecture with single-user access control of middle tier objects
US6026237A (en) * 1997-11-03 2000-02-15 International Business Machines Corporation System and method for dynamic modification of class files
JPH11338680A (en) 1998-05-27 1999-12-10 Mitsubishi Electric Corp Simulation display system
US6442620B1 (en) 1998-08-17 2002-08-27 Microsoft Corporation Environment extensibility and automatic services for component applications using contexts, policies and activators
US6425017B1 (en) 1998-08-17 2002-07-23 Microsoft Corporation Queued method invocations on distributed component applications
US6748455B1 (en) 1999-02-23 2004-06-08 Microsoft Corporation Object connectivity through loosely coupled publish and subscribe events with filtering
US6829770B1 (en) 1999-02-23 2004-12-07 Microsoft Corporation Object connectivity through loosely coupled publish and subscribe events
US6920636B1 (en) * 1999-12-15 2005-07-19 Microsoft Corporation Queued component interface passing for results outflow from queued method invocations
US7057612B2 (en) * 2000-01-12 2006-06-06 Balfour Technologies Llc Method and system for a four-dimensional temporal visualization data browser
DE10195202T1 (en) * 2000-01-27 2003-04-30 Morphics Tech Inc Method and device for multi-branched signal processing
US6658652B1 (en) 2000-06-08 2003-12-02 International Business Machines Corporation Method and system for shadow heap memory leak detection and other heap analysis in an object-oriented environment during real-time trace processing
US6904594B1 (en) 2000-07-06 2005-06-07 International Business Machines Corporation Method and system for apportioning changes in metric variables in an symmetric multiprocessor (SMP) environment
US7389497B1 (en) 2000-07-06 2008-06-17 International Business Machines Corporation Method and system for tracing profiling information using per thread metric variables with reused kernel threads
US6735758B1 (en) 2000-07-06 2004-05-11 International Business Machines Corporation Method and system for SMP profiling using synchronized or nonsynchronized metric variables with support across multiple systems
US6662359B1 (en) 2000-07-20 2003-12-09 International Business Machines Corporation System and method for injecting hooks into Java classes to handle exception and finalization processing
US6742178B1 (en) 2000-07-20 2004-05-25 International Business Machines Corporation System and method for instrumenting application class files with correlation information to the instrumentation
US6968540B2 (en) * 2000-10-25 2005-11-22 Opnet Technologies Inc. Software instrumentation method and apparatus
US7062749B2 (en) * 2000-12-15 2006-06-13 Promenix, Inc. Measuring, monitoring and tracking enterprise communications and processes
AU2002329611A1 (en) * 2001-07-20 2003-03-03 Altaworks Corporation System and method for adaptive threshold determination for performance metrics
US7219034B2 (en) 2001-09-13 2007-05-15 Opnet Technologies, Inc. System and methods for display of time-series data distribution
US7401057B2 (en) 2002-12-10 2008-07-15 Asset Trust, Inc. Entity centric computer system
US7689994B2 (en) * 2004-01-28 2010-03-30 Microsoft Corporation System and method for specifying and executing temporal order events
US6898475B1 (en) * 2004-05-27 2005-05-24 Palo Alto Research Center Inc. System and method utilizing temporal constraints to coordinate multiple planning sessions
US8713025B2 (en) 2005-03-31 2014-04-29 Square Halt Solutions, Limited Liability Company Complete context search system
US7457789B2 (en) * 2005-08-17 2008-11-25 Tacton Systems Ab Configuration assistance for complex products
US20080154559A1 (en) * 2006-10-12 2008-06-26 Chethan Ram Method and system for variable scale time management for simulation environments
US8438539B2 (en) * 2008-04-11 2013-05-07 International Business Machines Corporation Using a menu slideshow framework for generating a custom menu-driven slideshow containing definable content
US20110185353A1 (en) * 2010-01-27 2011-07-28 Jack Matthew Mitigating Problems Arising From Incompatible Software
US8719196B2 (en) 2011-12-19 2014-05-06 Go Daddy Operating Company, LLC Methods for monitoring computer resources using a first and second matrix, and a feature relationship tree
US8600915B2 (en) 2011-12-19 2013-12-03 Go Daddy Operating Company, LLC Systems for monitoring computer resources
US10657180B2 (en) * 2015-11-04 2020-05-19 International Business Machines Corporation Building and reusing solution cache for constraint satisfaction problems
CN113468713A (en) * 2020-03-31 2021-10-01 顺丰科技有限公司 Service simulation method and device, computer equipment and storage medium

Family Cites Families (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US4604718A (en) * 1983-04-25 1986-08-05 Simulated Designs, Ltd. Computer simulation system
US4656603A (en) * 1984-03-01 1987-04-07 The Cadware Group, Ltd. Schematic diagram generating system using library of general purpose interactively selectable graphic primitives to create special applications icons
US4635208A (en) * 1985-01-18 1987-01-06 Hewlett-Packard Company Computer-aided design of systems

Also Published As

Publication number Publication date
EP0254438A2 (en) 1988-01-27
US4821220A (en) 1989-04-11
EP0254438A3 (en) 1989-10-25
JPS6336354A (en) 1988-02-17

Similar Documents

Publication Publication Date Title
CA1274310A (en) System for animating program operation and displaying time-based relationships
US7720662B1 (en) Visual representation of model execution results contributing to a failure condition in a model
US7809545B2 (en) System and method for using execution contexts in block diagram modeling
US7167817B2 (en) Automated approach to resolving artificial algebraic loops
US7313449B1 (en) Handshaking configuration mechanisms in graphical programming environments
US8667462B1 (en) Model and subsystem function signatures
US20020023110A1 (en) Document markup language and system and method for generating and displaying documents therein
Palanque et al. Synergistic modelling of tasks, users and systems using formal specification techniques
van der Aalst et al. Ex Spect 6.4 An Executable Specification Tool for Hierarchical Colored Petri Nets
US7412366B1 (en) Rate grouping during code generation for multi-rate models
Navarre et al. Structuring interactive systems specifications for executability and prototypability
JP2001502096A (en) Methods and systems for designing graphical user interfaces for electronic consumer devices
Courtney Modeling user interfaces in a functional language
CN107040818B (en) Layout analytic hierarchy process method and system for Android TV
Lakos Pragmatic inheritance issues for object Petri nets
Faucou et al. An ADL centric approach for the formal design of real-time systems
Abdelhabib et al. JAPROSIM: a Java framework for process interaction discrete event simulation
Okkonen et al. Sokrates-SA-A formal method for specifying real-time systems
Rathnam et al. Tools for building the human-computer interface of a decision support system
Witten et al. Jade: a distributed software prototyping environment
WO2007041901A1 (en) System and method for formal verification of statecharts
Arief A framework for supporting automatic simulation generation from design
Harrouet et al. Multiagent systems and virtual reality for interactive prototyping
Braubach et al. Tool-supported interpreter-based user interface architecture for ubiquitous computing
Hermanns Construction and verification of performance and reliability models

Legal Events

Date Code Title Description
MKLA Lapsed