highlight the code, and execute. The calendar from Windows will appear on the screen. In the preceding code, MSWindowsAPI is an external name space defined in the interface code, WinExec is a function defined in the Microsoft Windows Software Development Kit (SDK; Microsoft, 1990), parameters define the types of the input needed for "WinExec," and returns define the type of the output required for this function. Actually activating the calendar is accomplished by passing a string naming the executable file (i.e., calendar.exe) and an argument denoting how the new window is to be shown on the screen (e.g., normal, iconified, etc.). One can use this interface to start any Windows application; furthermore, links between running applications and Smalltalk can be created. The reader is encouraged to experiment with the examples given in the system. One problem is that the SDK documentation will be required in order to be able to determine the available functions and their parameters.

## 12.4 Applications Using the External Environment

### Introduction

The preceding descriptions have indicated that it is possible to tailor the ST-80 environment for communication with the environment outside the computing system. This section examines a number of examples that describe when and how one might want to create applications that access the environment.

One of the simpler concepts that emerges from understanding the capabilities of the ST-80 environment is the idea of building control panels for controlling devices connected, either directly or indirectly, to a computer system. For example, the capabilities described in detail in Chapter 8 which permit building of a wide variety of interface functions such as gauges, lists, buttons, and so forth are ideal for the creation of control panels that can replace hardware control panels. In addition to replacement, the creation of new concepts for control and monitoring is simple to consider because all the tools needed to build and experiment with new styles of panels are at hand. For example, one might consider the creation of control panels that permit controlling and organizing the activity of multiple cooperative instruments. By using such a control panel, a single human operator might be able to operate a much larger number of machines than by using traditional hardware control methods. Furthermore, it is certainly conceivable that dynamically configurable control panels could be implemented that would adapt to the environment. An example of building a control panel is given in an upcoming section.

Next, the kinds of interface activities that might be appropriate for the hardware discussed in the previous section of this chapter will be examined.
## Interface Applications

*The Use of Serial and Parallel Connections.* Serial and parallel I/O ports are the most widely used means of communicating with a variety of devices. Often, serial and parallel communication is interchangeable. For example, printers frequently can be connected to either type of port, and within the operating system, output can ordinarily be redirected from one port to another. Various styles of communicating with printers exist. For example, some printers, such as the Apple LaserWriter, communicate in a language called PostScript (Holzgang, 1988) which is interpreted internally by the printer prior to producing an image on the printer. PostScript is a page description language that employs ASCII character representation to describe (albeit rather cryptically) how to print a page. In contrast, some other laser printers (e.g., Hewlett-Packard printers) use a raster scan technique for sending bitmaps to the printer, in which each dot is described. The raster scan technique is directly analogous to the form or Depth1Image display mechanism of ST-80, in which each bit of an image is assigned a 1 or 0 to indicate whether a white or black pixel should be displayed. Another text (Pinson and Wiener, 1988) gives a good example of how to interface a raster scan printer to Smalltalk.

Several communication and instrumentation examples are presented next.

*Serial Control.* Consider the scenario shown in Figure 12.10 in which a robot is controlled by a program written in ST-80. The application is the automated observation of parts on a manufacturing line. A camera mounted on the robot arm acquires video images and returns the images to the computer. Control of the robot is needed to adjust the height of the camera to be able to inspect different types of parts that might be run on the line. In the figure, only two cables are shown connected from the serial and video cards in a computer to the robot, although there might well be additional cables for controlling the flow of parts on the line shown. Internal to the robot is a small interpreter that can digest serial commands sent over the cable. Commands might be of the type "UP," "DOWN," "LEFT," "RESET," and so on, which can be readily created and stored in dictionaries in the application program. Both the robot and the belt could be controlled serially, based on video information returned to the computer, for detecting, for example, errors in the physical fabrication of a board. Shown on the right side of the diagram is a conceptualization of how the window containing a control panel might look for an application of this type. A selectionInListView could be created which would permit the user to choose various options. The video picture that the camera sees, perhaps including the highlighting of problem areas, might be shown in a view. Finally, a dialog box
<figure><img src="image_154.png" /><figcaption>**Figure 12.10** Controlling a Robotic Parts Inspector.</figcaption></figure>

(textCollector) could be displayed in which advice could be presented to the operator of the system.

**Serial Communications.** Smalltalk-80 provides the capability for connecting to serial ports on any of the supported hardware. Table 12.3 displays how a serial I/O port can be opened for three different hardware platforms. Once an identification for the opened port is obtained from the operating system (termed "handle," i.e., a name to call the port by), various options for the serial port, such as speed and number of bits, can be set. More information and examples about these options can be found using the Smalltalk browser.

In Release 4 of ST-80, the ObjectKit \ Smalltalk Advanced Programming software supplied by ParcPlace systems provides classes **SunTerminal** and **VT100Terminal** that permit displaying text collected from the serial I/O port. An example of a VT100 terminal window is shown in Figure 12.11. The functionality of this terminal window is virtually identical to the functionality provided by standard serial communications packages. Hence, it is questionable
<caption>**Table 12.3** Examples of Serial Port Usage in ST-80
(Note: These classes need to be filed in for Objectworks \ Smalltalk Release 4.)</caption>

**Opening a Port**

*   handle := UnixRealTtyAccessor open: '/ dev / ttya'.
*   handle := DosTtyAccessor open: 'COM1:'.
*   handle := MacTtyAccessor open: 'modem'.

**Setting Serial Options**

options := DosTtyOptions new.
options bits: 8;
    speed: 9600;
    stopBits: 1;
    parity: nil.
handle setOptions: options.

See OS* classes in the ST-80 browser for examples.

whether this facility will serve a useful purpose when other communications
packages are available. However, if an application required embedding a
terminal window as part of multiple views in a window, the classes provided
would indeed by useful. One might enhance the communications facility of
ST-80 to use multiple textCollector views that could sort electronic mail as it is
received, for example, into different categories, such as "urgent," "read later,"
or "junk mail." This capability would be straightforward to implement by
reading incoming text and routing the mail messages to dictionaries associated
with different textCollector views. Another variation on this same concept

<figure><img src="image_155.png" /><figcaption>Figure 12.11 A Terminal Window in ST-80.</figcaption></figure>
<figure><img src="image_156.png" /><figcaption>**Figure 12.12** Communications Concepts for Group Work Example. (S = serial).</figcaption></figure>

would be to facilitate groups of individuals working together. For example, multiple views in a terminal window could be created such that there might be different views of messages sorted from different members of a team collaborating on a project. A framework for an example of this kind of idea is outlined in Figure 12.12 in which individuals representing different kinds of functionality in a manufacturing organization are all connected via a network. Individual workstations (i.e., PCs, Mac, etc.) could be connected using serial connections to a wide-area net, perhaps implemented using fiber-optics communications media. Creating a multiperson communications facility for a group such as the one shown should be a fairly straightforward exercise of extending the MVC triad
<figure><img src="image_157.png" /><figcaption>Figure 12.13 Laboratory Control of Instruments.</figcaption></figure>

that implements a terminal window. Each workstation might display multiple views of text commentary by individual team members, or the sorting concept mentioned previously might be used to organize the work of the team into a browser that lists the messages by category.

*Direct Control of Instruments.* Another interface application is the connection of measurement instrumentation to the ST-80 environment, for the purpose of controlling and communicating with instruments. Figure 12.13 presents the conceptualization of how an instrumentation control system might be configured for conducting an experiment on testing the characteristics of a simple electronic circuit. A laboratory bench preparation could contain a breadboard of electronic components with input and output signal connections. The input could be driven by a programmable signal generator, with the signal level monitored by a voltmeter and the output of the system monitored by an oscilloscope, which could relay information about the contents of the signal measured back to the computer. All instruments could be synchronized via the
<table><caption>**Table 12.4** Controlling a Digital Voltmeter with IEEE-488 Commands</caption><thead><tr><th>Command Category</th><th>Command List<br>Function</th><th>ASCII Code</th></tr></thead><tbody><tr><td rowspan="4">Function step</td><td>Set meter to measure dc</td><td>F1</td></tr><tr><td>Set meter to measure ac</td><td>F2</td></tr><tr><td>dc amps</td><td>F3</td></tr><tr><td>ac amps</td><td>F4</td></tr><tr><td rowspan="5">Range selection</td><td>AutoRanging</td><td>R1</td></tr><tr><td>100 mV, 0.1 A</td><td>R2</td></tr><tr><td>1 V, 1 A</td><td>R3</td></tr><tr><td>10 V, 10 A</td><td>R4</td></tr><tr><td>100 V</td><td>R5</td></tr><tr><td rowspan="2">Triggering</td><td>Internal trigger</td><td>T1</td></tr><tr><td>External trigger</td><td>T2</td></tr><tr><td rowspan="2">Autozero</td><td>Zeros the instrument on</td><td>Z0</td></tr><tr><td>Zeros the instrument off</td><td>Z1</td></tr><tr><td colspan="3"><strong>Example Command String</strong><br>"F1R2T1Z0"</td></tr></tbody></table>

posting of control messages on the IEEE-488 bus (see the following examples). As in the previous example, a multiview control panel could be created which would permit control of laboratory experiments and summarization and plotting of results in a view.

Table 12.4 presents information about how to control an example instrument—a digital voltmeter. Control is via the transmission of a series of ASCII codes over the IEEE 488 bus. At the top of the table is a set of sample commands similar to those found in physical digital voltmeters that use the IEEE-488 bus. The commands are mnemonic; that is, they provide a terse rendition of a command in English by using the first letter of that command followed by a digit. Shown at the bottom of the table is a sample string that sets the voltmeter to measure dc voltage in the 100-mV range, using the internal trigger and with autozero turned on.

A computer can access the IEEE-488 bus by (1) simply sending serial strings from a standard serial port to a hardware device that converts serially coded information into the IEEE-488 format or (2) by directly driving an IEEE-488 interface board directly plugged into the computer. Several relatively complex factors need to be understood about how to accomplish direct program-to-hardware communication with a physical board. To explicate how to construct such an interface, a simple example will be given for a D/A converter,
<caption>**Table 12.5** Controlling a D/A Using a C-Language Interface</caption>

```c
#define DA 0×2EC
#define COMMAND 0×2ED
/* Interface code as in Table 12.3 */
main ()
{
    outp(COMMAND, 0×f); /* setup board */
    outp(COMMAND, 0×1); /* clear errors */
    outp(COMMAND, 0×8); /* write D/A immediate */
    outp (DA, 0×0); /* specify channel 0 */
    outp(DA, 0×100); /* output a value */
}
/* Interface code */
```

one of the most straightforward I/O devices that can be explained. Interfaces to more complicated devices will proceed in the same manner, although with added complexity.

*Direct I/O Port Connection Methods.* Table 12.5 presents an example of interfacing a digital to analog converter to the ST-80 system. The virtue of explaining the interfacing of a D/A converter is that it is conceptually and actually easy to understand the code needed to drive the converter using C, even if one does not understand the C language. The C code shown in the table follows the same format as the general interfacing example methodology discussed previously in Section 12.3. The first line of Table 12.5 defines DA as a physical address: 2EC₁₆; the preceding 0x simply indicates that the number should be interpreted by the C compiler as hexadecimal. In C-language compilers, there are typically mnemonics such as "inp" or "inport" and "outp" or "outport" that are compiled to assembly level code commands that address the I/O ports in DOS machines. In the example, "outp" is used to put a particular number into an I/O port. In other machines, for example, those that use Motorola cpu's, direct memory addresses are normally accessed rather than the ports to control I/O cards. In this case, a C structure can be created which represents the memory locations to be accessed and values put into these locations to control the I/O card.

A digital to analog converter converts a numerical value into an analog voltage, which is made available on a cable to the external world. To operate a typical D/A converter, two registers are employed: the command register (here named COMMAND) and the data register (designated as DA, in this example). Operation proceeds by sending a setup command, a clear errors
<figure><img src="image_158.png" /><figcaption>**Figure 12.14** A Control Panel for an Analog to Digital Converter.</figcaption></figure>

command, a command about what to do, the channel number, and finally the
data.

In the example, the first argument to outp is an address, as indicated
in the earlier definitions in this code fragment, and the second argument is code
sent to the board for control purposes or data. The port commands on a PC can
be used for accessing any of the machine ports. Because peripheral devices are
usually connected to port or directly to a memory location, it is straightforward
to address ports or addresses in C programs interfaced to Smalltalk.

Code to interface I/O devices to Smalltalk can be written in the
manner described in the last few paragraphs. However, it is essential to
determine if the manufacturer supplies the needed information about the
characteristics of the card.

*Creating a Control Panel Example.* As an example of creating a control panel in ST-80, Figure 12.14 displays a control panel for an analog to digital (A/D) converter. The example was created using the ViewBuilder program described
in Chapter 8. The design begins with defining the external functions of the A/D that need to be accessed in order to use the A/D board. Six main functions in this example were identified: setting the sampling rate, controlling the external trigger, selecting a channel, designating a file in which to store data, initiating inspection of acquired data, and running the system. The six items are actuated by pressing any of the six buttons shown in the figure. Recalling from the description in Chapter 8 that a button press executes code in a code block, one can add calls to primitives written in C which actually carry the functionality written on the buttons in the control panel.

## 12.5 The Wrapper Concept<fnref n="2" />

The concept of a "wrapper" comes from the commonsense usage of the term in the context of software. Many software packages are difficult to understand and use; hence, it would be useful to "wrap" these packages with a layer that would assist the user in using such systems and would assist in interpreting the output of a package. The ST-80 environment, particularly the graphics interface mechanisms of the MVC, permits the creation of interfaces that are more user friendly than the typical interface constructed for engineering software packages. Indeed, during the last few decades, many large and complex software packages for use in engineering have been created in a variety of computer languages with little regard for portability of reusability. For example, there are many quite expensive software packages for engineering modeling in a variety of the subfields of engineering that could benefit by having a "friendly" wrapper. Although such wrappings are becoming more commonplace with the increased use of window environments for PC and workstation environments, it is frequently difficult to understand how one might create custom wrapping for existing programs. Some scenarios for creation of simple wrappers are described next in the context of the MVC tools studied in this text.

Figure 12.15 diagrammatically illustrates the wrapper idea. Imagine that one has a large simulation package, as indicated at the top of the figure. Surrounding the package are interface functions that interpret both the input and output of the package through conversion routines that interface to a standard ST-80 window. The interface in the window might contain buttons for control, lists for selecting options, and a view in which results can be displayed.

<footnote n="2">²The wrapper concepts presented in this section differ from the wrapper concepts presented in Chapter 8. The class *Wrapper* in ST-80 provides different view functionality; here wrapper refers to surrounding or enclosing an application.</footnote>
<figure><img src="image_159.png" /><figcaption>Figure 12.15 The Wrapper Concept.</figcaption></figure>

Figure 12.16 shows an actual implementation of a wrapper (Bourne et al., 1989) that uses two views. The view in front is an ST-80 image created from information returned from a simulator and the view in the background is the actual wrapper view. Although part of this view is occluded, it is easily describable. First, there are four selectionInListViews across the top of the window in which different alternatives are available for operating the simulation system that is wrapped. At the bottom of the view are two textViews. On the left, prepackaged listings of commands that are available for driving a simulator can be viewed. On the right, occluded in this example, is a blank textView to which operational commands can be cut and pasted. Once the user creates a
<figure><img src="image_160.png" /><figcaption>Figure 12.16 A View of a Wrapper Implementation.</figcaption></figure>

command file, by analogy to the command files shown in the left view, the command listing can then be executed. The virtue of this scheme is that the user can find by browsing a set of command lines analogous to his or her current needs and tailor the listing selected simply by copying and pasting to a new view that is simultaneously observable with the original command lines.

The particular implementation shown in Figure 12.16 is reprinted from an application in which a large digital circuit simulator (LASAR; Teradyne, 1988) was wrapped. In this case, ST-80 was used to create the interface and the actual simulator code ran on a physically separated machine (Bourne et al., 1989). UNIX versions of ST-80 provide the capabilities for linking across multiple machines, hence, it was simple to create an interface on one machine and have the simulation run on another. ST-80 provides access to the UNIX facilities for "socketing," that is, creating pluggable communications channels across multiple machines. Unfortunately, the DOS and Macintosh versions of ST-80 do not currently have this capability.
## 12.6 Object-Oriented Database Management

Some ideas about supporting groups of individuals working together using computer-supported communications media have been mentioned previously. This type of distributed work environment introduces the problem that there must be some central repository for information that can be accessed by multiple individuals. This issue is well known for management of large information systems that require central data storage for access by a large number of users. Examples include stock market information access, airline reservation systems, and library information retrieval. Some common methods of storing information in databases include both relational databases (i.e., in tabular record-oriented representations) and hierarchical databases. Problems with traditional database management systems include limitations in available representational structures and stylized query mechanisms for retrieval of information. Also, there are typically "impedance" mismatches (i.e., the nonmatching of one program to another) between a database management system and an application program. The idea behind object-oriented database management systems (OODBMS) is to provide the capability for storing objects, no matter how large or how complex, in order to reduce application development time and increase modeling power. An example of an OODBMS is the Gemstone system. Gemstone (Maier and Stein, 1987) is an object-oriented database management system that capitalizes on the Smalltalk model, providing excellent facilities for sharing data among multiple users. Gemstone, written in C, provides Smalltalk and other interfaces access to shared data manipulation facilities. For a comprehensive look at this relatively new field of object-oriented databases, the reader is referred to Kim and Lochovsky (1989).

The addition of an object-oriented database management system to Smalltalk application programs can significantly enhance the capabilities of Smalltalk because Smalltalk was originally designed to be a personal computational environment on a single workstation. Objects created in Smalltalk are not persistent (i.e., they are not always there, e.g., the objects do not remain accessible when one exits the image) and are difficult to share among users except by the rudimentary means of sharing ASCII files of objects. The versions of Smalltalk-80 from Version 2.5 on have a binary object storage system (BOSS) for storing objects on files in a more parsimonious fashion than writing text files. This mechanism implements a form of persistent objects, but is not as sophisticated as the capabilities of Gemstone which provides multiple-user access to a database management system, including transaction and concurrency control (i.e., provides the capability for multiple users to share and update commonly shared objects).

An OODBMS can provide the capability of sharing information among various users without the need to capture a complete copy of objects in
<figure><img src="image_161.png" /><figcaption>**Figure 12.17** Group Work with an Object-Oriented Database Management System.</figcaption></figure>

each user's image or disk. Figure 12.17 conceptualizes how a group of individuals might work together on a network, sharing information resources on an OODBMS. In this scenario, each team member could be provided with the inter-team-member communication facilities described earlier in this chapter, coupled with the ability to view and manipulate persistent objects in a shared OODBMS, as shown on the right side of Figure 12.17.

## 12.7 Summary

The primary conclusion to be drawn from this chapter is that the Smalltalk-80 environment can be readily interfaced to the world outside the computer. This finding extends well beyond ST-80 in the sense that the interfacing concepts discussed are general in terms of language interfacing and application creation mechanisms. In previous chapters, the excellent graphics and user tools, including debuggers, of ST-80 have been extolled as providing mechanisms for the user to permit creating rapid prototypes of various types in engineering. In this chapter, areas that are difficult to approach using ST-80 alone have been examined—areas in which preexisting and well-defined classes
do not always exist. Because engineering often needs interfaces to the real world, methods for providing such interfaces have been surveyed and found to be relatively easy to create. The combination of an integrated programming environment with interfaces to the external world and to other computer languages offers a strong problem-solving system that should find excellent utility in many areas in engineering.

## References

Bourne, John R., J. Cantwell, A. J. Brodersen, B. Antao, A. Koussis and Y.-C. Huang, (1989). Intelligent Hypertutoring in Engineering. *Academic Computing*, September, 18-47.

Dittrich, K. R. (Ed.) (1988). *Advances in Object-Oriented Database Systems*. Lecture Notes in Computer Science. Springer-Verlag, New York.

Gates, S. C. (1989). *Laboratory Automation Using the IBM PC*. Prentice-Hall, Englewood Cliffs, NJ.

*High-C Compiler Manual* (1989). Meta Ware Incorporated, Santa Cruz, CA.

Holzgang, D. A. (1988). *Understanding PostScript*. Sybex, Inc., Alameda, CA.

Kim, W., and F. H. Lochovsky (Eds.) (1989). *Object-Oriented Concepts, Databases, and Applications*. Addison-Wesley, Reading, MA.

Maier, D., and J. Stein (1987). Development and Implementation of an Object-Oriented DBMS. In *Research Directions in Object-Oriented Programming*, B. Shriver and P. Wegner (Eds.), pages 355-392. MIT Press, Cambridge, MA.

Microsoft Windows Software Development Kit (1990). Reference Manuals, Microsoft Corporation, Redmond, WA.

*Objectworks\Smalltalk User's Guide*, Release 4 (1991). ParcPlace Systems, Mountain View, CA.

Pinson, Lewis J., and Richard S. Wiener (1988). *An Introduction to Object-Oriented Programming and Smalltalk*. Addison-Wesley, Reading, MA.

Teradyne Corporation (1988). *LASAR Version 6 Software Users Guide*. Boston, MA.

## Exercises

12.1 For the computers that you have access to, determine which peripherals are available and study how these peripherals operate with the facilities of the operating system that you are using.
12.2 Browse the ST-80 system. Study carefully the serial interface. Connect a serial cable from your computer to a "dumb" terminal or another computer using a communications program and see if you can send characters from one system to the other using the examples given in the serial interface class.

12.3 Project: Implement an A/D and D/A interface to ST-80.

12.4 Project: Implement an IEEE 488 interface to ST-80.

12.5 Study the manual provided in ST-80 on interfacing C to Smalltalk and write a brief explanatory report.

12.6 Undertake a survey of object-oriented database management systems. Contact manufacturers and compare and contrast the capabilities of the various systems you find.
# Building an Application: Concepts in Rapid Prototyping

## 13.1 Introduction

Many of the concepts and methodologies described throughout this text are tied together in a single prototypical application presented in this chapter. The ideas and the concrete programming tools discussed in earlier chapters are used here to create an example of a working digital circuit simulator. Because the focus of the chapter is on rapid prototyping, no attempt is made to present a completed and well-refined example; instead, the skeletal framework of the application is developed and code presented that can serve as a basis for continued development. Classes and code for the digital circuit model, developed in Chapter 3 using the application/class organization method (ACOM) modeling method, and the view building methods discussed in Chapter 8 are used to create a prototypical view of a digital circuit simulator. The purposes of the chapter are (1) to discuss general analytical and design methods, (2) to apply the concepts described to a digital circuit design problem, and (3) to show how the design can be implemented. More code is exhibited in this chapter than in prior chapters due to the need to describe the operation of the complete example. Coding methodologies are explained in detail because the techniques used are generally useful in many different kinds of rapid prototyping applications.

What is rapid prototyping? A prototype is defined as "An original type, form or instance that serves as a model on which later stages are based or judged" (Morris, 1981). As a model, a prototype can be thought of as a skeletal framework which can be expanded or modified to serve various needs. The addition of the term "rapid" to the beginning of the phrase connotes the ability to put together a model of an application rapidly. Hence, rapid prototyping has
come to mean the rapid fabrication of a working model of an application which
can be used to demonstrate a concept. Rapid prototypes are useful for explain-
ing what could be done if a prototype would be developed into a complete
product or for simply experimenting with concepts to determine the utility of an
idea. Rather than spend detailed design and implementation time, the rapid
prototyping methodology permits trying out many different ideas without the
high cost of detailed design and implementation.

13.2 The Digital Circuit Simulator Problem

Digital circuits, as described in Chapter 3, operate on digital signals, using 0 and 1 logic levels for signals. Collections of digital circuits, such as *and* gates, *or* gates, and invertors (i.e., *not* gates) can be connected to form logic circuits that implement a wide variety of devices such as adders, counters, and even digital computers. A digital circuit simulator is a program that can mimic the behavior of actual digital logic gates wired together and tested by applying a signal to the input of the combination of gates. A simple example used at several points throughout the text is the half-adder, a simple digital logic circuit composed of two *and* gates, one *or* gate, and one *not* gate. When physically wiring a circuit together on a workbench, students learning electronics can observe the behavior of the circuit combinations that they create. A viable alternative to physically wiring a circuit, applying input signals, and observing the output is to use a digital circuit simulator which permits the simulation of a physical system in software. A circuit simulator can provide close to the same educational experience as physically wiring the circuit, if the simulator has sufficient capabilities. At worst, a simulator might have only the capability of logically verifying what the output of a circuit should be given a particular input value or values. At best, the truly sophisticated simulator would contain many more components and instruments than those found on a typical physical workbench. The user would operate in a near-real-world simulated environment with the capability of rapidly connecting various combinations of circuits and observing circuit operation. With many types of simulated circuits available and the capability of abstracting the behavior of collections of components [see, e.g., van der Meulen (1989)], a circuit simulator becomes a potentially powerful design tool with which new electronic designs can be implemented and tested without the need for ever fabricating an actual circuit until the design is complete. Once a circuit is designed and debugged using such software-based simulation methodologies, actual physical devices can be created using the designs obtained from the simulation. Indeed, a circuit simulator, when devel-
oped fully, can be considered to be a productivity tool for design, as well as a learning tool for students.

As discussed in Chapter 3, a digital circuit simulator should permit connecting digital circuit components such as *and*, *or*, *not*, and other gates together with simulated wires. Using the ACOM methods, a description of various gates and wires was given in Chapter 3 and ultimately implemented and illustrated in Chapter 10. Neither in the class descriptions given in Chapter 3 nor in the discussion of constraints in Chapter 10 was any graphical means of display implemented. In the digital circuit simulation implementation in Chapter 3, the user could view the output signal values of a wired circuit on the system transcript. Later, in Chapter 10, inspector views were used to examine signals in a constraint network. The purpose of these implementations was to illustrate some basic properties of object-oriented programming, including inheritance, and to introduce the ACOM method. Although the few classes created permitted verifying the operation of simple logic circuits, the implementation technique required the user to build and name each object and wire in a workspace, including specification of the wiring of the individual components. Moreover, although one could inspect variables in this simulation, it was difficult to secure an overall global appraisal of the operation of the entire circuit.

To create a graphics-oriented circuit simulation system, the models described in Chapters 3 and 10 should be linked to a view in which graphical representations of circuit elements can be displayed and the circuit animated by displaying the signals propagating through the simulated circuit elements. Furthermore, a graphics builder interface should be added that would permit a user to construct a simulated system using only the point-and-click metaphor. The goal of this chapter is to show how to create a prototype of a digital circuit simulation system that has both circuit building and animation capabilities.

Basic conceptualization methods for creation of the prototype are examined next followed by a detailed description of the implementation code. The code builds directly on the code described in previous chapters. Although not complete, the code presented furnishes a sufficient framework to permit a serious student to develop a more complex example within a short time period. This chapter will conclude with a discussion of ideas about different directions in which the prototype could be developed.

### 13.3 Maxims for Rapid Prototyping

This section introduces some ideas about rapid prototyping, incorporating and reviewing concepts already covered that are germane. The maxims
given are almost commonsense knowledge and fit well with the conceptualiza-
tion of rapid prototyping as an analysis phase followed by design and implemen-
tation. The maxims given in the following discussion are divided into the four
areas: analysis, design, implementation, and incremental refinement.

The Analysis Phase

At the outset of the analysis phase of creating a rapid prototype, an
assessment of the design intent should be made (i.e., the teleology, as discussed
in Chapter 2). This assessment is a kind of requirements analysis, but not
extremely detailed. Particularly important at this point is determining what the
functionality of the system being created should be, in concept. An especially
useful mental (and paper-and-pencil) operation is to attempt to sketch out what
the behavior of the prototype should be; that is, how does a user interact with
the system and what does the system do while the user is engaged with the
system? At this point in creating a prototype, the chief notion is to try to link
your idea about a new system with what the system should do when it is
completed. Given the background on implementation paradigms presented
earlier in the text, it is useful to think in terms that ultimately can be
implemented. For example, if there are multiple functions to be carried out
which might be activated by pressing buttons, buttons should be included in a
prototype to activate the different designed functionalities.

A second important analysis requirement is to consider deeply how
the system should appear to the user and how the user should operate the
system. A useful construct here is the use of *storyboards*, that is, a series of
sketches that illustrate how a system would work, if constructed. It is very useful
to produce a set of storyboards that show each possible view that the user would
see, including switches, menus, and lists and how they might work.

A third analytical requirement is the consideration of the kinds of
knowledge and data representations required for the prototype. Knowledge and
data may fit easily recognized objects with which the designer is familiar, such as
dictionaries or ordered collections. At this stage, the designer may recognize
other requirements, such as the need for reasoning or representation of a rich
set of semantic constructs. Recognizing such representational needs would lead
to the conclusion that rule systems and semantic nets would be needed in the
prototype. In general, however, rather than resorting to complex representa-
tional structures for a prototype, simpler style representations are preferable
simply from the debugging and understandability position. Once a system
operates properly in the prototype, more complex representational schemes can
be substituted as desired.
## The Design Phase

Once concepts have been formed by analyzing the requirements for the system, the design phase commences with specification of the actual components of the application. First, a model that will represent the required knowledge and data should be specified. This step is identical to the ACOM method outlined in Chapter 3. The model should be tested using the simple evaluation techniques of creating code in a workspace and exercising the code to see that it performs the intended function (e.g., such as testing digital circuit operation as was done in a workspace in Chapter 10).

For all objects in the model, a specification of the instance and class variables needed should be determined. Application-wide variables should be identified early; that is, are there class variables that need to be identified that will require access by all objects in the system? In many cases, only instance variables will be needed; only occasionally are class variables needed that are accessible to all instances of the class.

For organizational purposes, opening an application is normally accomplished by using a class method or instance method, often called "open" in the application view or model. Inside the "open" method, linkages are made between the model, view, and controller to permit subsequent communication among these three major parts of an application. Typically, the application class is given a descriptive name and stored in a named category created using the class browser.

The remaining design steps are the specification of the characteristics of the view and controller. Either the **Controller** or the **ControllerWithMenu** class can be normally used in a prototype because this class provides most of the control functionality needed. The class **Controller** is provided with the creation of any **View** subclass. The design of the view requires additional thought, however. In particular, the placement and type of views in the window should be designed. This step essentially matches the requirements described in the storyboards by specifying the actual view types and placement. As outlined in Chapter 8, it is useful to employ a tool such as ViewBuilder (Jiang and Bourne, 1991) to create a view and controller that can be interfaced to the model.

## The Implementation Phase

To implement a design, the use of ViewBuilder is a good place to start. Graphically prototyping the view and controller components with this tool permits rapidly creating the skeletal view framework. Without ViewBuilder, the user should write an "open" method that follows the same schema shown in Chapter 8 for creating a window and adding views in a container. In fact, the
examples shown in Chapter 8 can be followed directly. The most reasonable scheme is to create a view in a window first, then open the window and determine that the view placement is reasonable. If you do not use View-Builder, special care must be given to defining the placement and the extent of each view.

Once the view is built and the controller implemented (normally by doing nothing special and simply allowing the default controller to be used), the application model can be added to the views by sending the message *model: aModel* to the views that require a model. After linking in the model, debugging and incremental refinement of the application can commence. Debugging is accomplished by trying to run the application and activating the various buttons, list selections, and gauges used to control the application. Any errors found while running the application will result in a debugger window popping up. The debugger window (see Chapter 6) will highlight the message send that caused an error. Frequently, it is necessary to move down the message send stack (i.e., move to the previous item in the message sends listed in the list at the top of the debugger view). The usual problem is that an object is being sent a message that it does not understand. One can correct the problem in the debugger and continue or restart the application.

## Incremental Refinement Phase

The incremental refinement phase of the implementation is probably the most interesting because new features rapidly appear in the prototype. Starting with a working simple prototype generated as described previously, small refinements can be made one by one and tried out. New features can be added to buttons in the view, and different styles of menus or icons can be experimented with and/or modified.

## 13.4 The Digital Circuit System: Teleological and Functional Assessment

### Teleology of the Simulator

The specific example designed and implemented in this chapter should permit a user to select digital components from a list or set of buttons and place the icons representing the components on a viewable graphics context. As each component is placed, the wires connected to the component should be specified. Once all components and wires are connected, the user should be able to set the signals on the input and observe the signal flow through the connected
gates. To demonstrate this design intent, a half-adder circuit consisting of two *and* gates, one *or* gate, one *invertor*, and six wires will be constructed.

## Functionality of the Simulator

Described next are the various components of the constituent elements of the digital circuit simulation which, when combined, are a description of the functionality of the system. The functional items are listed as in a specification.

### Creating Components

To create a component, the user should press a button with the name of the component. After pressing the button, an image representing the component follows the cursor until the user clicks any mouse button, depositing the image with the component icon on the view graphics context.

### Creating Wires

After completing specification of each component, a pop-up list should appear from which the user selects the wires to be connected to the component in the order: (input1 input2 out) for the **TwoInputGate** class and (input output) for one input gates such as invertors. This design prespecifies an arbitrary number of wires that can be used for connecting components in a circuit.

## Visually Connecting Components

The capability for displaying the wires should be included in the design. Drawing of wires should include the capability for ensuring that the wires are exactly vertical or horizontal when the user draws wires in approximately vertical or horizontal directions.

## Setting the Inputs

To demonstrate the feasibility of the prototype, buttons should be included that permit setting combinations of the input signal so that the behavior of the simulation can be verified. For the half-adder example to be
constructed, there are two inputs; hence, each input should be able to be set to either 0 or 1. For ease of construction, the wires on which signals can be set are specified to be wires A and B in the pop-up wire list.

## Animation

The progression of signals through the circuit should be viewable when setting the input signals.

## Encapsulation

Each component should contain information about connections to wires and behavior when activated. This behavior should include how to display itself and how to propagate information to connected wires.

## 13.5 DCS Architectural Organization

Figure 13.1 displays the architecture of the prototype. The three standard MVC elements are present; the initial conceptualization of the contents of each are given next. Throughout the next sections, specific reference to parts of the code presented in Table 13.4 are given; the reader can benefit from a simultaneous reading of the following information and examining the code. This operation will probably take several readings.

The parts of the design to be considered in detail are as follows.

### Model Design

The model for this application is very simple, consisting of ordered collections of gates and wires. The wire collection is initialized for the wires "1" through "10," so that the wires can be referenced by their position in the collection. Pop-up menus refer to the collection by using the letters "A" through "J." Hence, wires at: 1 is the wire "A," wires at: 2 is the wire "B," and so on.
<figure><img src="image_162.png" /><figcaption>**Figure 13.1** Architecture of the Digital Circuit Simulation System.</figcaption></figure>

## View Design

The view requires the most design. Ten button views are specified that completely control the application and one view defined in which the circuit can be graphically built.

## Controller Design

The controller is specified by default (i.e., **Controller**) via the default controller in the class **View**, although a controller with a menu could be used to permit the adding of pop-up menus for additional functionality at some later time. By simply specifying the view class as a subclass of **View**, the default controller is supplied. For the example given, the **ControllerWithMenu** would work equally well. To reduce the volume of the code shown, controller classes are not displayed.
Auxiliary Images

Five auxiliary images are used in the system. Three of these images are used for icons (AndImage, NotImage, and OrImage) and the remaining two (BlackImage and WhiteImage) are used respectively to show a black token on an icon when a signal appears at the component and to erase the black token. All images were created using a host drawing package and imported into ST-80 using code such as *AndImage* := *Image fromUser*. Each small image is pointed to by a global variable in the Smalltalk dictionary. An alternative methodology is to read the images from files using the binary object storage system of ST-80. Another alternative is to use black-and-white forms created by the bit editor in Version 2.5 and earlier systems and to read the forms from a file.

13.6 Organizing the Information to Store

The Model

Components

The digital circuit objects described in Chapter 3 exhibited no behavior other than forwarding their input states to their output. The behaviors of the *and*, *or*, and *not* gates presented here have been changed to add the additional capability of displaying their behavior on the view's graphics context. A more proper way to add this behavior would be to create a subclass of each component that contains the modified methods. For example, a subclass of **And** could be **AndWithAnimation** which would contain a new constraint block. In addition to the constraint modification, a variable "location" was added to each constraint to indicate the location of any particular gate in the window. Also added was a variable to keep track of the graphicsContext of the view.

The behavior of each component used in this animated example has been changed to permit display of a black image in the icon for that component. The original code for an *and* gate was, as described in Chapter 3:

constraint := [ :input1 :input2 | (input1 & input2) ifTrue: [1] ifFalse: [0]].

Thus, any *and* gate with this constraint will return a 1 when both its inputs are 1 and 0 otherwise. To change the behavior of this constraint to provide an animated view of the operation of the constraint, one can simply add a few new
statements inside this block, as follows:

constraint := 
    [ :input1 :input2 :aGraphicsContext :location | 
        (input1 = 1) & (input2 = 1) ifTrue: 
            [ BlackImage displayOn: aGraphicsContext at: (location + 5@10). 
              (Delay forSeconds: 1) wait. 
            WhiteImage displayOn: aGraphicsContext at: (location + 5@10). ] 
        ifFalse: [ 0 ] ] .

The changes to the code within this block are to add three statements: (1) to display an image of a black dot, (2) wait a short while, and (3) display another image with a white dot. The images were cut from the host drawing package and imported into ST-80 using Image fromUser. The white image is sized to cover the black dot. The action of the constraint is, when sent a signal, to blink the black dot on the icon of the gate. The location at which the dot appears, for illustration, is offset from the location passed to the block, which in this example is the top left of where the icon should be displayed. The offset was arbitrarily chosen to be 5 pixels in the x direction and 10 pixels in the y direction so that the dot would appear inside the image of the andGate.

Figure 13.2 displays the knowledge organization of the instance variables in the model. The knowledge organization for the gates (i.e., the *and*, *or*, and *not* gates in this example) remains similar to the organization used in Chapter 3. In the model, the instance variable "gates" holds an ordered

<figure><img src="image_163.png" /><figcaption>**Figure 13.2** Knowledge Organization in the Digital Circuit Simulation System.</figcaption></figure>
collection of gate objects. Each gate object is one of the gates defined when the user places a gate image on the screen. The instance variable "wires" in the model contains a collection of all the wires that are defined. Each wire defined contains the wire input, outputs, value, and a collection of points defining the path of the wire. To make naming wires simple for this example, all wire names are predefined so that each wire can be related to a popUpMenu with the wire names that the user can employ when wiring the system.

## The View

### Wire Manipulation

Figure 13.3 displays a rather nondescriptive picture of a few wires. There is a point to be made, however, that requires examination of this figure. The **GraphicsContext** method *displayLineFrom: to:* will draw from any point on a graphicsContext to any other point. Simply having the points follow the cursor is insufficient however, because it is quite difficult to draw straight lines using only the mouse. It is instructive to try drawing a straight line, as in the example given in Figure 7.4 to verify this problem. Lines in digital circuits are conventionally drawn either vertically or horizontally. To create this example, two possibilities for drawing algorithms were considered: (1) given the end points of a wire, create the wires automatically or (2) permit the user to create and route the wires by continued choosing of points using the mouse button. The latter method was chosen to avoid the complexities of wire routing and to demonstrate the use of a graphics primitive interacting with the mouse.

The protocols in **VCircuitSimView** dealing with wire manipulation contain a number of interesting methods. The method *addwire* is called from

<figure><img src="image_164.png" /><figcaption>**Figure 13.3** Drawing Wires.</figcaption></figure>
the opening view, activated by pressing the button with the same name. The main code in this method is a loop that checks to see if the user has clicked the mouse button twice: `checkForDoubleClick`. When this is not true, the dependent block is executed continuously showing a cursor and adding a line to the drawing when the user clicks a button. The method `straightenLines` is used to ensure that each line, prior to drawing, is either vertical or horizontal, if the mouse is within 10 pixels either vertically or horizontally from the previous point. This technique for drawing permits both horizontal lines, vertical lines, angled lines, and multisegmented lines to be drawn, as displayed in Figure 13.3, by simply clicking on the first and successive points and double clicking on the last point. Hence, when complete, a wire is simply an ordered collection of points that can be stored in one of the wires in the model. To facilitate storing of a wire, upon completion of drawing each wire, the user is asked to select which wire has been placed from those available in the array of wires in the model.

All locations stored for icons and for wires in these examples are specified as offsets from the top left corner of the circuitView defined in the opening method of the view. Note that the graphicsContext of the view must be used to draw on. The reason for specifying component offset from the view corner is that all components should be drawn at the same relative spot on the view no matter where the window is opened on the display. Because icon and wire locations relative to the top left of the view are stored in the model, redisplaying the icons and wires is simple whenever the window is moved or resized.

## Images

Table 13.1 displays the names of the auxiliary images used in the DCS example. Each image was created using a drawing package on the host platform and exported to ST-80 using the message `fromUser` sent to class **Image**. For Version 2.5 of ST-80, an alternative technique to create these images would be

<table><caption>**Table 13.1** Auxiliary Images Used in the Digital Circuit Simulator Example</caption><thead><tr><td>Image Name</td><td>Explanation</td></tr></thead><tbody><tr><td>AndImage</td><td>Icon for an <b>And</b> gate</td></tr><tr><td>OrImage</td><td>Icon for an <b>Or</b> gate</td></tr><tr><td>NotImage</td><td>Icon for an <b>Inverter</b></td></tr><tr><td>BlackImage</td><td>A black spot used for animation</td></tr><tr><td>WhitelImage</td><td>A white spot to erase a black spot</td></tr></tbody></table>
<figure><img src="image_165.png" /><figcaption>Figure 13.4 A Bit Editor View of the AND Gate Icon (Version 2.5).</figcaption></figure>

to create forms in Version 2.5 using the form and bit editor. Figure 13.4 shows an enlarged picture of an *and* form created. The resolution shown will vary depending on the platform. In this case, a 640 by 480 pixel screen was employed, thus resulting in the fairly coarse bitmap shown. Contrast the form created with the form shown in the form editor displayed in Figure 13.5. As indicated earlier in the text, form and bit editors have been removed from

<figure><img src="image_166.png" /><figcaption>Figure 13.5 An AndGate in a Form Editor (Version 2.5).</figcaption></figure>
Release 4. Hence, users familiar with bit and form editors need to use other methods for creating images. Fortunately, however, the sophistication of commercial drawing packages far surpasses the primitive bit and form editors. Hence, the user is really much better off employing commercial drawing packages and clip art for creating images to use in ST-80-based Release 4 applications.

## 13.7 Building the View

### Determining the View Components

The view for the digital circuit simulator example utilizes only buttons to evoke actions and a view for drawing the circuit. The functionality shown is for demonstration purposes and can be changed quite easily to accommodate additional functionality. The simulator was built several times in several different ways. First, in one version, ViewBuilder was used to implement the view. Figure 13.6 shows the screen view of ViewBuilder with the CircuitInterface constructed. As described in Chapter 8, the method of operation of the ViewBuilder is to first use the create button to size a new view followed by adding other views from the pop-up menu. As shown in this version done in Version 2.5, nine buttons were added to the window. The three buttons at the top left of the window are intended to implement adding a component: *not*, *or*, and *and*. The next two buttons deal with adding and removing wires and the final four buttons are associated with operation of the system created. These last four buttons are completely specific to the half-adder example selected to demonstrate the operation of the system.

To demonstrate how the simulator operates, the standard half-adder circuit is shown in the example views that follow. The four buttons added in the view permit setting the two inputs to 0 or 1, thus allowing the viewing of the operation of the circuit. Other circuit configurations would require a different input technique; for example, one would want to be able to attach a signal to any desired input rather than use the specificity shown here.

The design of the view is remarkably simple, associating each desired functionality with a button. Each button activates a block of code that calls a method associated with implementing the functionality of the named button. Note also that, in addition to the buttons, a view is specified on which to draw the components and wires.

Even without the use of ViewBuilder, the creation of the view is straightforward, that is, creating and adding buttons and other views to a window. By following the code shown in this chapter, a circuit interface that operates the same as the one shown can be constructed without the View-
<figure><img src="image_167.png" /><figcaption>Figure 13.6 The ViewBuilder Interface for the Digital Circuit Simulator. This screen dump is from Version 2.5; the screen dump for Release 4 appears essentially identical.</figcaption></figure>
<figure><img src="image_168.png" /><figcaption>Figure 13.7 The Completed Digital Circuit Interface View (Release 4 screen dump).</figcaption></figure>

Builder by simply creating the needed classes and typing in the code into the browser.

Figure 13.7 displays the completed view, showing the placement of the buttons. The right 85 percent of the view is the area reserved for drawing the circuit. As shown here, the half-adder is drawn, consisting of four gates and six wires. This particular view was created using Release 4; note the slight difference between the way the window outline appears in this example and the other examples written in Version 2.5.

Implementation of the Digital Circuit Simulator

The complete implementation of the DCS is shown in Table 13.4. The major components created are as follows.

1. The opening method, in `VCircuitSimView`, with which one launches the DCS using

`VCircuitSimView new open.`
A window is created for the application using

window := ScheduledWindow new.

window minimumSize: 300@200.

window label: 'Circuit Interface'.

The value shown as an argument to `minimumSize` was specified arbitrarily. Once the window is opened, the size can be easily changed.

2. Each view is then added to the window by adding views into aContainer, an instance of **CompositePart**. For example, a circuitView was created by simply sending *new* to **View**. Then, this view was placed in aContainer with the following code:

aContainer add: circuitView borderedIn: (0.15@0.0 extent: 0.85@1.0).

where the extent specifies that circuitView will take the right 85 percent of the window.

For the buttons, all are added in the same way:

button1 := LabeledBooleanView new.

button1 beTrigger.

“make a new booleanview”

“make it a button that”

“activates when released”

button1 controller beTriggerOnUp.

button1 beVisual: 'Add And' asComposedText.

button1 model: ((PluggableAdaptor on: self)

getBlock: [:myself|false]

“define its label”

“self refers to this view”

“nothing is done to change”

“the button”

putBlock: [:myself :value | self moveAnd]

“when the button is pressed,”

“send moveAnd”

updateBlock:

[:myself :value :parameter|false].

aContainer add: button1 borderedIn: (0@0 extent: 0.15@0.10).

In the code shown in Table 13.4, ten buttons are created rather than the nine described in the ViewBuilder implementation. The tenth button was implemented to show how to refresh the screen. Each button has an extent specified; in the preceding example code, the button begins in the top left of the window and extends 15 percent in the x direction and 10 percent in the y direction. Adding many buttons to the code by replicating the code is not a big chore because of the cut-and-paste capabilities that exist in the system browser.
Whenever a window is moved, the views shown need to be updated to redisplay themselves. The buttons contain code for update; `displayOn:` is sent to `circuitView` for redisplay. Also, for illustration, the last button `Refresh` was added to show how the display can be manually updated. Whenever the `Refresh` button is pressed, the `displayOn:` aGraphicsContext method in `VCircuitSimView` is called; the same refreshing of the screen occurs automatically by resizing the view. In the `displayOn:` method, all the objects on the screen are redisplayed using the information contained in the objects displayed. For example, all the icons contain the image to display and the location, relative to the window's top left corner, at which the icon is to be displayed. The only information needed is the graphicsContext on which to display, which is passed via the argument to the method `displayOn:`. Because wires are stored simply as a collection of wirePoints in each wire, redrawing the wires simply requires passing wirePoints to the `displayLineFrom/to:` method of GraphicsContext.

An alternative technique for updating the view is to provide a *self changed* message in the model after any changes are made to information stored in the model. The *self changed* method causes an *update* message to be sent to the view which, in turn, ultimately results in a *displayOn: anArgument* method in the view being sent. This linkage works best for selectively redisplaying only parts of the view that have been changed. Specification of the part of the view that is to be redisplayed may be indicated in the *self changed: anAspect* message, where the *anAspect* argument is passed via the *update* method to the view. In the view, different parts of the view can be selectively updated according to the value of *anAspect*.

## 13.8 Interfacing to the Model

The model remains relatively separate from the view in this implementation of the digital circuit simulator. Some information has been added to the model, such as the changes in the model for supporting animation and the data about the location of the gate and the graphicsContext. One task of the view is to interface with the user and to extract information about the contents of the model while the user is graphically building the circuit. When adding an *and* gate, the code shown in Table 13.2 is activated (for the purposes of this discussion, each line is numbered for further reference).

In Table 13.2, the first action in the method named `moveAnd` is to make the cursor blank (line 1) and have the *and* image follow the cursor as long as there is no button pressed. When any button is pressed, the image is displayed at the cursor location on the graphicsContext and that location is stored in the local variable `locationOfImage`. In line 7, `gateHolder`, the second local variable, is assigned a new *and* gate which is initialized. Next, in lines 8
<table><caption>**Table 13.2** Code for Creating an AND gate</caption><tr><td>1</td><td>Cursor blank showWhile: [AndImage</td></tr><tr><td>2</td><td>follow: [circuitView controller sensor mousePoint]</td></tr><tr><td>3</td><td>while: [circuitView controller sensor noButtonPressed]</td></tr><tr><td>4</td><td>on: circuitView graphicsContext.</td></tr><tr><td>5</td><td>AndImage displayOn: circuitView graphicsContext at:</td></tr><tr><td>6</td><td>(locationOfImage := circuitView controller sensor mousePoint).</td></tr><tr><td>7</td><td>gateHolder := AndGate new init.</td></tr><tr><td>8</td><td>gateHolder</td></tr><tr><td>9</td><td>input1: (self getWireFrom: circuitModel)</td></tr><tr><td>10</td><td>input2: (self getWireFrom: circuitModel)</td></tr><tr><td>11</td><td>output: (self getWireFrom: circuitModel).</td></tr><tr><td>12</td><td>gateHolder storeLocation: locationOfImage.</td></tr><tr><td>13</td><td>gateHolder storeGraphicsContext: circuitView graphicsContext.</td></tr><tr><td>14</td><td>circuitModel gates add: gateHolder</td></tr></table>

through 11, the new *and* gate is wired by permitting the user to connect to the inputs and output of the gate in the same style as in Chapter 3, except using menus. Finally, the location of the gate is stored in the *and* instance and the *and* gate added to the collection of gates contained in the model (line 14). Thus, the model contains all the needed information about each gate, that is, its behavior (created during *init* in line 7), its connections (lines 8 through 11), and where it should be shown to the user (line 12).

The remaining interfaces to the model are basically accomplished in the same way: the *or* and *not* gates have the same construction and the wire operations collect wire points and place collections of wire points in the model. The signal operations simply set the values of the signal on the inputs of the circuit in the model. In this example, *input1* and *input2* are assigned to the first two wires created. When signals are set on the wires, the values propagate through the constraint blocks in the model until reaching a wire for which there is no connection. At this point, the symbol for the wire and its value are printed on the transcript.

Hence, the conclusion about interfacing the view to the model for building a simulated circuit is that the view simply is an interface to the user, passing information to the model. There are a few complexities for determining the locations of objects to store and their relationships to each other. When examining the code in Table 13.4, note how the locations of the icons, wires, and the view itself are determined by sending *circuitView controller sensor mousePoint* to obtain the location of the mouse on the screen. The point to be made here is that by sending *controller* to *circuitView* one gets the controller for *circuitView* and then retrieves the sensor for that controller. This method enables accessing the location of the cursor with respect to the view specified.
## 13.9 Operating the Simulator

Operation of the simulator is as follows. The user first opens a new `circuitView` (e.g., by using the message quoted in the open message to `VCircuitSimView`) and presses one of the gate creation buttons. The icon representing that gate will appear and follow the movement of the cursor. However, the cursor is blanked so that the icon will appear to be dragged along as the user moves the mouse. Once a mouse button is clicked, the icon is deposited on the view's graphics context and a menu appears that allows the user to select in sequence the names of the wires that connect to the inputs and output of the gate placed (see the example in Figure 13.8). Each gate can be placed this way and each wire can be drawn on the view's `graphicsContext` by selecting "Add Wire" and single-clicking the mouse for drawing the wire until a double click occurs. After the wire is placed, the user is asked for the name of the wire from the menu of wires, in just the same way as asked for wire names when the gate was placed.

To operate the system, the user can press one of the signal-setting buttons which will place the indicated value on input wires A and B. Note the contrived nature of this example which uses a designated wire name. It would,

<figure><img src="image_169.png" /><figcaption>Figure 13.8 Selecting the Wires for a Gate.</figcaption></figure>
<table><caption>Table 13.3 Classes and Protocols of the Digital Circuit Simulator</caption><tbody><tr><td colspan="2"><strong>VCircuitSim View</strong></td></tr><tr><td>display</td><td>"redraw the view components"</td></tr><tr><td>displayOn:</td><td></td></tr><tr><td>wire manipulation</td><td></td></tr><tr><td>addWire</td><td>"store wire in the model"</td></tr><tr><td>checkForDoubleClick</td><td>"two clicks in same location"</td></tr><tr><td>drawWire</td><td>"draw the wire"</td></tr><tr><td>getWireFrom: aModel</td><td>"retrieve wire from the model"</td></tr><tr><td>getWirePositionInWireArray</td><td>"wire location in array"</td></tr><tr><td>showCursor</td><td>"display the cursor"</td></tr><tr><td>straightenLines</td><td>"ensure vertical / horizontal lines"</td></tr><tr><td>button control</td><td></td></tr><tr><td>moveAnd</td><td>"add an And gate"</td></tr><tr><td>moveOr</td><td>"add an Or gate"</td></tr><tr><td>moveNot</td><td>"add a Not gate"</td></tr><tr><td>set the inputs</td><td>"four different values for input"</td></tr><tr><td>instance creation</td><td></td></tr><tr><td>open</td><td>"open the application"</td></tr><tr><td colspan="2"><strong>VCircuitSim</strong></td></tr><tr><td>access</td><td></td></tr><tr><td>gates</td><td>"return the gates"</td></tr><tr><td>wires</td><td>"return the wires"</td></tr><tr><td>init</td><td>"initialize the gates and the wire"</td></tr></tbody></table>

of course, be more general to ask the user which wire to place the signal on. Once the input signal is placed, the model propagates values throughout the circuit; in each constraint, the BlackImage and WhiteImage images are displayed inside each icon in which a signal is changed to "1." Given the delay included in the constraint block in each icon, the view appears as a series of black dots rippling through the circuit. Furthermore, the output signals are printed in the system transcript in almost the same way as in Chapter 3.

There are many other configurations that could be employed to demonstrate signal propagation. The technique used here is simply illustrative and the reader is encouraged to experiment with other representational methodologies.

## 13.10 The Digital Circuit Simulator Code

Table 13.3 displays the classes and the protocols used in the digital circuit simulator example. Table 13.4 displays the code for the digital circuit simulator example, and Table 13.5 presents the changed implementations of the
<caption>Table 13.4 Digital Circuit Simulator Code</caption>

```
Object variableSubclass: #VCircuitSim
    instanceVariableNames: 'gates wires'
    classVariableNames:"
    poolDictionaries:"
    category: 'Circuit View example'
```
<table><caption>**Table 13.4 Continued**</caption><thead><tr><th colspan="2">VCircuitSimView methodsFor: button control</th></tr></thead><tbody><tr><td><strong>addWire</strong></td><td>"Add a wire to the circuitView"<br><pre>|currentWire targetWire tmp|<br>currentWire := OrderedCollection new.<br>firstCursorPosition := 0@0.<br>secondCursorPosition := nil.<br>[self checkForDoubleClick]<br>whileFalse:<br>  [self showCursor; drawWire.<br>    currentWire add: secondCursorPosition]<br>targetWire := circuitModel wires at: (tmp := self getWirePositionInWireArray).<br>circuitModel wires at: tmp put: (targetWire storeWire: currentWire)</pre></td></tr><tr><td><strong>moveAnd</strong></td><td>"Add an AndGate to the circuitView"<br><pre>|locationOfImage gateHolder|<br>Cursor blank showWhile: [AndImage "show the AndImage until a mouse button is pressed"<br>  follow: [circuitView controller sensor mousePoint]<br>  while: [circuitView controller sensor noButtonPressed]<br>  on: circuitView graphicsContext].<br>AndImage displayOn: circuitView graphicsContext at: (locationOfImage := circuitView<br>  controller sensor mousePoint).<br>gateHolder := AndGate new init. "now get the wires connected to the gate"<br>gateHolder<br>  input1: (self getWireFrom: circuitModel) "get the wires sequentially"<br>  input2: (self getWireFrom: circuitModel) "first the two inputs"<br>  output: (self getWireFrom: circuitModel). "then the output"<br>gateHolder storeLocation: locationOfImage.<br>gateHolder storeGraphicsContext: circuitView graphicsContext.<br>circuitModel gates add: gateHolder. "store the gate in the model"</pre></td></tr><tr><td><strong>moveNot</strong></td><td>"Add a notGate to the simulation"<br><pre>|locationOfImage gateHolder|<br>Cursor blank showWhile: [NotImage<br>  follow: [circuitView controller sensor mousePoint]<br>  while: [circuitView controller sensor noButtonPressed]<br>  on: circuitView graphicsContext].<br>NotImage displayOn: circuitView graphicsContext at: (locationOfImage := circuitView<br>  controller sensor mousePoint).<br>gateHolder := NotGate new init.<br>gateHolder input: (self getWireFrom: circuitModel)<br>  output: (self getWireFrom: circuitModel).<br>gateHolder storeLocation: locationOfImage.</pre></td></tr></tbody></table>
<table><caption>**Table 13.4 Continued**</caption><thead><tr><th></th><th></th></tr></thead><tbody><tr><td>gateHolder</td><td>storeGraphicsContext: circuitView graphicsContext.</td></tr><tr><td>circuitModel gates add:</td><td>gateHolder. "store the gate in the model"</td></tr><tr><td>moveOr</td><td>"add an OrGate to the Simulation"</td></tr><tr><td>locationOfImage gateHolder</td><td>Cursor blank showWhile: [OrImage follow: [circuitView controller sensor mousePoint] while: [circuitView controller sensor noButtonPressed] on: circuitView graphicsContext].</td></tr><tr><td>OrImage displayOn: circuitView graphicsContext at:</td><td>(locationOfImage := circuitView controller sensor mousePoint).</td></tr><tr><td>gateHolder := OrGate new init.</td><td>gateHolder input1: (self getWireFrom: circuitModel) input2: (self getWireFrom: circuitModel) output: (self getWireFrom: circuitModel).</td></tr><tr><td>gateHolder storeLocation:</td><td>locationOfImage.</td></tr><tr><td>gateHolder storeGraphicsContext:</td><td>circuitView graphicsContext.</td></tr><tr><td>circuitModel gates add:</td><td>gateHolder</td></tr><tr><td>removeWire</td><td>Transcript show: 'Wire removal is not implemented in this example'</td></tr><tr><td>setInput1To0</td><td>"This and other setInput... messages explicitly set the two input wires to a value Used for demonstration purposes"</td></tr><tr><td>circuitModel gates first inputWire1 set:</td><td>0</td></tr><tr><td>setInput1To1</td><td>circuitModel gates first inputWire1 set: 1.</td></tr><tr><td>setInput2To0</td><td>circuitModel gates first inputWire2 set: 0.</td></tr><tr><td>setInput2To1</td><td>circuitModel gates first inputWire2 set: 1.</td></tr><tr><td>VCircuitSimView methodsFor:</td><td>Instance creation</td></tr><tr><td>open</td><td>"VCircuitSimView new open"</td></tr><tr><td>aContainer</td><td>button1 window button4 button2 button3 button5 button6 button7 button8 button9 button10</td></tr><tr><td>circuitModel</td><td>:= VCircuitSim new init. "define the model"</td></tr><tr><td>window</td><td>:= ScheduledWindow new. "define the window"</td></tr><tr><td>window minimumSize:</td><td>300@200. "the minimum size of the window"</td></tr><tr><td>window label:</td><td>'Circuit Interface'. "and its label"</td></tr><tr><td>aContainer</td><td>:= CompositePart new. "define a container to put the parts of the view in"</td></tr><tr><td>circuitView</td><td>:= self. "circuitView is the name of the specific instance of this simulation"</td></tr></tbody></table>
<table><caption>**Table 13.4 Continued**</caption><tr><td>circuitView model: circuitModel.</td><td>"view and its model is circuitModel"</td></tr><tr><td>aContainer add: circuitView borderedIn: (0.15@0.0 extent: 0.85@1.0).</td><td></td></tr><tr><td>button1 := LabeledBooleanView new.</td><td>"All the buttons below are the same, each has a different label"</td></tr><tr><td>button1 beTrigger.</td><td>"Each button activates a method in the circuitView"</td></tr><tr><td>button1 controller beTriggerOnUp.</td><td></td></tr><tr><td>button1 beVisual: 'Add And' asComposedText.</td><td></td></tr><tr><td>button1 model: ((PluggableAdaptor on: self)</td><td></td></tr><tr><td>  getBlock: [:myself|false]</td><td></td></tr><tr><td>  putBlock: [:myself :value|self moveAnd] "send moveAnd to this view instance, when pressed"</td><td></td></tr><tr><td>  updateBlock: [:myself :value :parameter|false].</td><td></td></tr><tr><td>aContainer add: button1 borderedIn: (0@0 extent: 0.15@0.1).</td><td></td></tr><tr><td>button2 := LabeledBooleanView new.</td><td></td></tr><tr><td>button2 beTrigger.</td><td></td></tr><tr><td>button2 controller beTriggerOnUp.</td><td></td></tr><tr><td>button2 beVisual: 'Add Or' asComposedText.</td><td></td></tr><tr><td>button2 model: ((PluggableAdaptor on: self)</td><td></td></tr><tr><td>  getBlock: [:myself|false]</td><td></td></tr><tr><td>  putBlock: [:myself :value|self moveOr]</td><td></td></tr><tr><td>  updateBlock: [:myself :value :parameter|false].</td><td></td></tr><tr><td>aContainer add: button2 borderedIn: (0@0.1 extent: 0.15@0.1).</td><td></td></tr><tr><td>button3 := LabeledBooleanView new.</td><td></td></tr><tr><td>button3 beTrigger.</td><td></td></tr><tr><td>button3 controller beTriggerOnUp.</td><td></td></tr><tr><td>button3 beVisual: 'Add Not' asComposedText.</td><td></td></tr><tr><td>button3 model: ((PluggableAdaptor on: self)</td><td></td></tr><tr><td>  getBlock: [:myself|false]</td><td></td></tr><tr><td>  putBlock: [:myself :value|self moveNot]</td><td></td></tr><tr><td>  updateBlock: [:myself :value :parameter|false].</td><td></td></tr><tr><td>aContainer add: button3 borderedIn: (0@0.2 extent: 0.15@0.1).</td><td></td></tr><tr><td>button4 := LabeledBooleanView new.</td><td></td></tr><tr><td>button4 beTrigger.</td><td></td></tr><tr><td>button4 controller beTriggerOnUp.</td><td></td></tr><tr><td>button4 beVisual: 'Add Wire' asComposedText.</td><td></td></tr><tr><td>button4 model: ((PluggableAdaptor on: self)</td><td></td></tr><tr><td>  getBlock: [:myself|false]</td><td></td></tr><tr><td>  putBlock: [:myself :value|self addWire]</td><td></td></tr><tr><td>  updateBlock: [:myself :value :parameter|false].</td><td></td></tr><tr><td>aContainer add: button4 borderedIn: (0@0.3 extent: 0.15@0.1).</td><td></td></tr><tr><td>button5 := LabeledBooleanView new.</td><td></td></tr><tr><td>button5 beTrigger.</td><td></td></tr><tr><td>button5 controller beTriggerOnUp.</td><td></td></tr><tr><td>button5 beVisual: 'Remove wire' asComposedText.</td><td></td></tr><tr><td>button5 model: ((PluggableAdaptor on: self)</td><td></td></tr><tr><td>  getBlock: [:myself|false]</td><td></td></tr><tr><td>  putBlock: [:myself :value|false]</td><td></td></tr><tr><td>  updateBlock: [:myself :value :parameter|false].</td><td></td></tr><tr><td>aContainer add: button5 borderedIn: (0@0.4 extent: 0.15@0.1).</td><td></td></tr><tr><td>Button6: = LabeledBooleanView new.</td><td></td></tr><tr><td>button6 beTrigger.</td><td></td></tr><tr><td>button6 controller beTriggerOnUp.</td><td></td></tr><tr><td>button6 beVisual: 'Input 1 = 0' asComposedText.</td><td></td></tr><tr><td>button6 model: ((PluggableAdaptor on: self)</td><td></td></tr><tr><td>  getBlock: [:myself|false]</td><td></td></tr></table>
<caption>**Table 13.4 Continued**</caption>

```kotlin
putBlock: [:myself:value self setInput1To0]
updateBlock: [:myself :value :parameter|false]).
aContainer add: button6 borderedIn: (0@0.5 extent: 0.15@0.1).
button7 = LabeledBooleanView new.
button7 beTrigger.
button7 controller beTriggerOnUp.
button7 beVisual: 'Input 1 = 1' asComposedText.
button7 model: ((PluggableAdaptor on: self)
  getBlock: [:myself|false]
  putBlock: [:myself :value self setInput1To1]
  updateBlock: [:myself :value :parameter|false]).
aContainer add: button7 borderedIn: (0@0.6 extent: 0.15@0.1).
button8 = LabeledBooleanView new.
button8 beTrigger.
button8 controller beTriggerOnUp.
button8 beVisual: 'Input2 = 1' asComposedText.
button8 model: ((PluggableAdaptor on: self)
  getBlock: [:myself|false]
  putBlock: [:myself :value self setInput2To1]
  updateBlock: [:myself :value :parameter|false]).
aContainer add: button8 borderedIn: (0@0.7 extent: 0.15@0.1).
button9 = LabeledBooleanView new.
button9 beTrigger.
button9 controller beTriggerOnUp.
button9 beVisual: 'Input2 = 0' asComposedText.
button9 model: ((PluggableAdaptor on: self)
  getBlock: [:myself|false]
  putBlock: [:myself :value self setInput2To0]
  updateBlock: [:myself :value :parameter|false]).
aContainer add: button9 borderedIn: (0@0.8 extent: 0.15@0.1).
button10 = LabeledBooleanView new.
button10 beTrigger.
button10 controller beTriggerOnUp.
button10 beVisual: 'Refresh' asComposedText.
button10 model: ((PluggableAdaptor on: self)
  getBlock: [:myself|false]
  putBlock: [:myself :value self displayOn: circuitView graphicsContext]
  updateBlock: [:myself :value :parameter|false]).
aContainer add: button10 borderedIn: (0@0.9 extent: 0.15@0.1).
window component: aContainer.
window open
```

### VCircuitSimView class
instanceVariableNames:"

VCircuitSimView class methodsFor: icon creation

### example

1. create an icon using a drawing package

2. Use image fromUser to acquire image from screen

3. Store in the System Dictionary; for example, AndImage = Image fromUser.
<table><caption>**Table 13.5** Code for the Gates in the Digital Circuit Simulator Example</caption><thead><tr><th>Gate</th><th>Methods</th></tr></thead><tbody><tr><td>Object subclass: #Gate</td><td>instanceVariableNames: 'graphicsContext icon locationOfImage'<br>classVariableNames: ''<br>poolDictionaries: ''<br>category: 'digital-demo'</td></tr><tr><td>Gate is an abstract superClass that contains information about the location of the icon of the gate, graphicsContext and the location of the image. It serves as the superclass of TwoInputGate and OneInputGate.</td><td></td></tr><tr><td>Gate methodsFor: access</td><td></td></tr><tr><td>getGraphicsContext</td><td>^ graphicsContext</td></tr><tr><td>getIcon</td><td>^ icon</td></tr><tr><td>-location</td><td>^ locationOfImage</td></tr><tr><td>storeGraphicsContext: aGraphicsContext</td><td>graphicsContext := aGraphicsContext</td></tr><tr><td>storeLocation: aLocation</td><td>locationOfImage := aLocation</td></tr><tr><td>Gate subclass: #OneInputGate</td><td>InstanceVariableNames: 'InputWire outputWires constraint delay'<br>classVariableNames: ''<br>poolDictionaries: ''<br>category: 'digital-demo'</td></tr><tr><td>OneInputGate is an abstract class used for all one input and one output gates.</td><td></td></tr><tr><td>OneInputGate methodsFor: action</td><td></td></tr><tr><td>propagate</td><td>|constraintOutputValue|<br>constraintOutputValue := constraint<br>value: inputWire value<br>value: graphicsContext<br>value: locationOfImage.<br>outputWires do: [:aWire|aWire set: constraintOutputValue]</td></tr><tr><td>OneInputGate methodsFor: initialize</td><td></td></tr><tr><td>init</td><td>delay := 0.<br>outputWires := OrderedCollection new.</td></tr><tr><td>Input: aWire1 output: aWire2</td><td>inputWire := aWire1.<br>outputWires add: aWire2.<br>inputWire outputConnection: self.<br>aWire2 inputConnection: self.</td></tr></tbody></table>
<table><caption>**Table 13.5 Continued**</caption><tr><td>OneInputGate subclass:</td><td>#NotGate</td></tr><tr><td>InstanceVariableNames:</td><td>"</td></tr><tr><td>classVariableNames:</td><td>"</td></tr><tr><td>poolDictionaries:</td><td>"</td></tr><tr><td>category:</td><td>'digital-demo'</td></tr><tr><td colspan="2">NotGate inverts the signal entering the gate.</td></tr><tr><td colspan="2">NotGate methodsFor: initialize</td></tr><tr><td>Init</td><td>super init.<br/>constraint := [:input :aGraphicsContext :location | input = 1<br/>ifTrue: [0]<br/>ifFalse:<br/>[BlackImage displayOn: aGraphicsContext at: location + (5@10).<br/>(Delay forSeconds: 1) wait.<br/>WhiteImage displayOn: aGraphicsContext at: location + (5@10).<br/>1]].<br/>icon := NotImage</td></tr><tr><td>Gate subclass:</td><td>#TwoInputGate</td></tr><tr><td>InstanceVariableNames:</td><td>'InputWire1 inputWire2 outputWires constraint delay'</td></tr><tr><td>classVariableNames:</td><td>"</td></tr><tr><td>poolDictionaries:</td><td>"</td></tr><tr><td>category:</td><td>'digital-demo'</td></tr></table>

TwoInputGate is an abstract class used for implementing all two input and one output classes.

**TwoInputGate methodsFor: Initialize**

**Init**

delay := 0.
outputWires := OrderedCollection new.

**Input1: aWire1 Input2: aWire2 output: aWire3**
inputWire1 := aWire1.
inputWire2 := aWire2.
outputWires add: aWire3.
inputWire1 outputConnection: self.
inputWire2 outputConnection: self.
aWire3 inputConnection: self.

**TwoInputGate methodsFor: action**

**propagate**

| constraintOutputValue anArray |
|:---------------------------------|
| anArray := Array new: 4.        |
| anArray at: 1 put: inputWire1 value. |
| anArray at: 2 put: inputWire2 value. |
| anArray at: 3 put: graphicsContext. |
| anArray at: 4 put: locationOfImage.
**Table 13.5 Continued**

`constraintOutputValue` := `constraint` `valueWithArguments`: `anArray`.

`outputWires` do: `[:aWire|aWire` set: `constraintOutputValue`]

**TwoInputGate methodsFor: access**

**constraint**

`^constraint`

**InputWire1**

`^inputWire1`

**InputWire2**

`^inputWire2`

**TwoInputGate subclass: #AndGate**

`instanceVariableNames:`

`classVariableNames:`

`poolDictionaries:`

`category: 'digital-demo'`

This Class implements 'AND' behavior; that is, whenever both signals are present on the input, the signal is high on the output, otherwise the output is low.

**AndGate methodsFor: Initialize**

**Init**

“initialize the constraint block”

super init.

`constraint` := `[:input1 :input2 :aGraphicsContext :location | input1 = 1 & (input2 = 1)`

`ifTrue: "display a dot, wait, and white it out"`

`[BlackImage displayOn: aGraphicsContext at: location + (5@10).`

`(Delay forSeconds: 1) wait.`

`Whit Image displayOn: aGraphicsContext at: location + (5@10).`

`1]`

`ifFalse: [0]]`

`icon := AndImage`

**TwoInputGate subclass: #OrGate**

`instanceVariableNames:`

`classVariableNames:`

`poolDictionaries:`

`category: 'digital-demo'`

The behavior of OrGate is that whenever an input signal is high, so is the output signal.

**OrGate methodsFor: Initialize**

**Init**

super init.

`constraint` := `[:input1 :input2 :aGraphicsContext :location | input1 = 1 | (input2 = 1)`

`ifTrue:`

`[BlackImage displayOn: aGraphicsContext at: location + (5@10).`

`(Delay forSeconds: 1) wait.`
<caption>**Table 13.5 Continued**</caption>

```kts
Whitelimage displayOn: aGraphicsContext at: location + (5@10).
1]
ifFalse: [0].
icon := Orlimage

Object subclass: #Wire
    InstanceVariableNames: 'InputConnection outputConnections value name
                             pointsDescribingWire'
    classVariableNames:"
    poolDictionaries:"
    category: 'digital-demo'

Wires are used to connect digital components.

Wire methodsFor: access

getWirePoints
    ^ pointsDescribingWire

InputConnection: aGate
    inputConnection := aGate.

name
    ^ name

name: aName
    name := aName

outputConnection: aGate
    "multiple gates can be added to the output of a wire"
    outputConnections add: aGate

set: aValue
    value := aValue.
    outputConnections empty
    ifTrue:
        [Transcript show: self name printString. "print my name"
         Transcript show: self value printString. "print my value"
         Transcript cr.]
    ifFalse: [outputConnections do: [:eachGate|eachGate propagate]]
        "propagate value to each gate I am connected to"

storeWire: aWire
    pointsDescribingWire := aWire.

value
    ^ value

Wire methodsFor: initialize

init
    value := 0. "initialize the wire to hold a zero value"
    outputConnections := OrderedCollection new. "each wire connects to multiple sites"
```
gate classes that were given in Chapters 3 and 10. The reader is encouraged to create a mental organization of the code, according to the class/protocol representation of Table 13.3, then read the code starting with the *open* method of `VCircuitSimView`, and then code and demonstrate the application.

## 13.11 Additions to the DCS Application

The example described in this chapter could benefit from many improvements, some of which are suggested in the exercises. For example, consider the problem of drawing the wires. The technique selected requires the user to draw wires using the mouse. The linkages between gates are made using the wires specified when placing a gate on the circuitView. Wires are selected from predefined wires created during system startup and stored in a collection. To continue to follow this model, a dynamic extension of the collection should be made to include the automatic addition of wires as needed. Another modification would be to click on a gate and select the terminal of the gate that the mouse cursor is closest to for association with a wire. As the system operates in the example, the name of the wire needs to be remembered, an obviously problematic requirement. A second but more complex technique for drawing wires could be to create wires algorithmically, requiring no user interaction. If it is known, for example, that wire A is connected to the inputs of the *and* and *or* gates of the half-adder, then a routing algorithm should be able to determine where to draw the line showing the connection. Various algorithms are easy to understand but harder to implement. For example, between any two points, a rule might be "draw a line such that it is never closer to any gate icon than x pixels, it is always vertical or horizontal, maintains equidistance between any two gates (except when other lines are there), and takes the shortest distance possible." One can image a series of rules of this sort that could create wires from point to point.

A simple addition to the simulator would be the changing of the gate images. Simply replacing the icons with more realistic icons would improve the look of the simulation. Furthermore, the ability to rotate icons by 90 degrees would help, as would the capability of snapping wires to the proper location. On this latter point, each icon could have a set of connection points defined; in the *and* gate case, there would be three, two inputs and one output. For each of these connection points, an area around the point could be defined, for example 5 or 10 pixels. When placing a wire, if the point selected was within the 5- or 10-pixel area, the wire could be attached to that point; otherwise the connection would be disallowed.

Hierarchical viewing of circuit elements, as discussed briefly in Chapter 10 (see Figure 10.6), would be another useful addition to the simulation. For example, when a user moves the cursor inside an icon and brings up a menu
with a mouse click, one option could be "expand." Selection of this option would zoom a window on top of the current circuit which would show the contents of the circuit represented by the icon. Similarly, a menu could be available for whole circuits which would collapse the circuit to an icon and show it as part of a larger circuit. This type of whole-part expansion and collapsing is ideal for viewing a circuit in more or less detail.

## 13.12 Summary

This chapter has presented a complete example of how to create a rapid prototype of a digital circuit simulation system. Building on a model that uses constraint propagation to simulate the way a digital circuit operates, the primary addition in this chapter was the demonstration of how view components can be easily added to display visual models. The conclusion is that it is straightforward to implement a view that permits the observation of the working of a model. Given the components that have been described in some detail in earlier parts of the text, there are a wide variety of standard components such as pop-up menus, lists, buttons, and so on that make the job of rapid prototyping easy. Rather than create new kinds of representations to show objects visually, it is easier to simply use what is available.

A key concept in the rapid prototyping notion is the idea of creating a framework for the problem and then incrementally modifying the working prototype. As has been discussed above, there are many alternative ways of creating a digital circuit simulator with many attendant issues to resolve such as how to place components and place wires. These issues are hard to resolve a priori. It is indeed useful to be able to create a prototype rapidly and see how the concepts work and how the system should evolve into something perhaps more suitable. This capacity for continual evolution of a system is antithetical to top-down design, in which complete specifications for software are written prior to actually coding a system. However antithetical it may be, the fact remains that rapid prototyping is a boon to creativity, permits trying out ideas quickly and easily, and, in the long run, likely results in better and more thoroughly considered software products.

## References

* Jiang, Zhihe, and John Bourne (1991). A Visual Programming Environment for Building Smalltalk-80 Views. *Journal of Object-Oriented Programming*, May.

* Morris, William (Ed.) (1981). *The American Heritage Dictionary of the English Language*. Houghton Mifflin, Boston, MA.
van der Meulen, Pieter S. (1989). Development of an Interactive Simulator in Smalltalk. *Journal of Object-Oriented Programming*, Vol. 1, No. 5, January/February, 28–51.

Exercises

13.1 Four maxims for rapid prototyping are presented: the analysis phase, the design phase, the implementation phase, and the incremental refinement phase. Describe the steps associated with each phase.

13.2 Implement the digital circuit simulator, as presented in this chapter. Discuss any problems that you had while creating the implementation.

13.3 As mentioned in this chapter, a wire routing algorithm might work well as an alternative to the user-directed wire placement methodology described. Specify a few wire routing rules and indicate how the algorithms that you propose might be implemented.

13.4 In the example given in this chapter, you may have noticed that the "remove wire" switch does not actually remove a wire. Describe how you would implement (1) the removal of a single wire and (2) all the wires.

13.5 Note that there is no technique in the example given in this chapter for moving an icon once it is placed on the circuitView. One method is to erase the image at the specified location (perhaps by restoring the background that was behind the image) and then to have the icon follow the cursor. One can imagine defining the rectangular coordinates for each icon placed on the view's graphics context and storing this information in a dictionary. Then, whenever the cursor is within a rectangle and the mouse button is pressed, the designated icon would be erased and reattached to the cursor. See if you can implement this solution or a similar solution.

13.6 Attaching wires to a gate can be accomplished using the method described previously to locate the pins of the gate around certain points on the image. Discuss how to do this operation and propose a way of implementing wire attachment in this fashion.

13.7 In the current implementation, the value of the output wire is displayed on the system transcript. Add an icon, such as a light bulb, which will change color (e.g., from white to black) as the signal to which the icon is attached changes from 0 to 1.
<figure><img src="image_170.png" /></figure>
# Engineering Simulation Methodologies and Simulation Frameworks

## 14.1 Introduction

A framework is defined as "A structure for supporting, defining, or enclosing something." (Morris, 1981) or alternatively as "a frame or structure composed of parts fitted and joined together" (Webster's, 1989). For software, frameworks are shells, environments, or simply programs that support the integration of various pieces of software into a package that assists in problem solving or system operation. Widely used software packages, such as Microsoft Windows (1987), which organize the capabilities of an operating system for improved communication with the user, can be thought of as frameworks. More commonly, the term *framework* is employed to designate a set of software that is integrated to support a special type of application such as design, viz., design frameworks, which typically contain some type of simulation capabilities.

Simulation, as discussed at several points during earlier chapters, is the mimicking of the way that an actual physical system works, that is, the behavioral manifestations of a functional specification. Engineering simulation deals with the simulation of designed artifacts—those things that have been designed for use in our world. Hence, an engineering simulation provides the capability of replicating how something would work if it were fabricated. Indeed, this is the concept behind computer-aided engineering (CAE). Rather than create physical working prototypes of a system being designed, testing, and refining the prototypes, it is more parsimonious to simulate a system, pinpoint and correct design flaws, and fully test a system prior to ever creating a hardware implementation of a design. As an example, there are a number of design frameworks for computer-aided engineering in electronics. Frameworks built by such companies as Daisy System Corporation, Mentor Graphics Corp
ration, and Valid Logic (Ohr, 1990) are widely used. These frameworks are bundled packages of software that integrate software for schematic entry, netlist generation (i.e., the structure of circuit connectivity), simulation, printed circuit board layout, ASIC (application-specific integrated circuits) layout, and test programs. Such systems give an engineer or engineering team the complete capability of creating a design for an electronic circuit, simulating the circuit, producing the specifications for fabricating the circuit, and rigorously testing the product. Such frameworks are large, complex, and have normally been quite expensive.

At a simpler level, one can attempt to understand the concept of frameworks for organizing the simulation aspects of design. In much the same way that one can integrate generic software packages for solving electronic design problems, one can also consider general frameworks, which contain no domain knowledge, that permit the building of simulations for use in different engineering domains. In this chapter, the different types of simulation that are currently used will be considered and related to object-oriented thinking and implementation strategies. Examples of two kinds of existing simulation frameworks will be given, as well as an example in manufacturing.

In contrast to the previous chapter, this chapter contains a limited amount of code. Instead, concepts are discussed and pointers to the code are given. Because the text has a strong Smalltalk-80 orientation for implementation, Section 14.5 presents a discussion of a simulation framework in ST-80 code that can be secured from the ParcPlace Systems bulletin board.

## 14.2 The Kinds of Simulation

Simulation is used for many activities in engineering. Several examples are given in Table 14.1 that show a range of simulation activities across a broad spectrum of application areas. For example, in manufacturing, simulation is used for constructing a model of a manufacturing process. Once the model suitably mimics a real or planned system, various parameters can be varied to determine the influence on behavior of the simulation. An often-used example [see, e.g., Pinson and Wiener (1988) and Goldberg and Robson (1983)] simulates the arrival of customers at a bank. The purpose of the simulation is to assist in designing the characteristics of the bank, for example, how many tellers should be hired, how many customer queues should be allocated, and so on, for different probabilistic distributions of customers entering the bank at different times.

In almost any conceivable area, simulation methodologies can be used to predict behaviors for designed artifacts. The topics listed in Table 14.1 are by no means exhaustive—they are simply a few examples to show the range of
<table><caption>**Table 14.1 Example Uses for Simulation**</caption><thead><tr><td>Area</td><td>Examples</td></tr></thead><tbody><tr><td>Manufacturing</td><td>Warehouse modeling, printed circuit board manufacturing, rolling mill modeling, chemical plant models</td></tr><tr><td>Service sector</td><td>Goods distribution systems, mail delivery, medical staffing, planning, food service modeling, banking</td></tr><tr><td>Computers</td><td>Information packet distribution, memory modeling, communications network models</td></tr><tr><td>Civil engineering</td><td>Traffic control, hydrology, structural models</td></tr><tr><td>Military</td><td>Battle simulation, command, control</td></tr><tr><td>Aerospace</td><td>Flight simulation, airplane aerodynamics</td></tr></tbody></table>

possibilities. Of course, the difficulty with simulation is knowing how close to reality the simulation will be. Obviously, it would be disastrous to simulate a bridge and not be able to believe that the simulated results that dictate how the bridge would be built are close to being accurate. The fidelity of the simulation (i.e., how close the simulation gives answers close to reality) is a critical issue in determining what type of simulation to use.

There are many different styles and methodologies for producing simulation systems. Perhaps the most easily recognizable groups are (1) the traditional engineering simulation methodologies [see, e.g., Bratley, Fox, and Schrage (1987)] which predominantly employ discrete-event simulation and (2) qualitative simulation methodologies which have gained recent prominence due to research in artificial intelligence [see, e.g., Bobrow (1985)]. The differences, advantages, and disadvantages of these two major subdivisions in simulation methodology will be explained in this section.

Four terms relating to simulation need to be identified: *discrete*, *continuous*, *qualitative*, and *quantitative*. Discrete and continuous refer to time: (1) discrete time, such as fixed increments of time or tagged instances of events that occur at a particular time, and (2) continuous time, in which time varies without interruption. Quantitative and qualitative refer to what variables represent. Quantitative refers to the capability of explicitly associating a variable with a specific quantity, for example, $x = 5$, or an enumeration of specific values, for example, $x = \{5, 6, 7, 8, 9, 10\}$. In contrast, qualitative refers to associating a quality with a variable, for example: (1) the variable is not changing, (2) the variable is increasing, or (3) the variable is decreasing, with no specific numeri-
<table><caption>**Table 14.2** Variable, Time, and Constraint Attributes of Qualitative and Quantitative Models</caption><tr><td><strong>Quantitative Models</strong></td><td>Variables: Numeric<br>Time: Discrete or continuous<br>Constraints: Linear or nonlinear</td></tr><tr><td><strong>Qualitative Models</strong></td><td>Variables: Symbolic, numerical landmarks<br>Time: Symbolic<br>Constraints: Symbolic, functional relationships</td></tr></table>

cal association. Often symbols such as {0, +, -} are associated with these latter qualities to symbolically represent change.

Table 14.2 summarizes the attributes of quantitative and qualitative models with respect to variable, time, and constraint dimensions. Quantitative models employ mainly numeric variables, whereas qualitative models employ a combination of symbolic and numeric variables. In qualitative modeling, symbolic values represented as symbols or strings can be coupled to numeric values used as critical numeric “landmarks” for constraining ranges or specific values. Time is represented in quantitative models in either a discrete or continuous fashion. Discrete representations often do not use formal mathematics, whereas continuous representations are typically cast into a set of mathematical equations, algebraic or differential. For qualitative models, time can be represented symbolically with no numerical quantities involved. Finally, for the constraint dimension in modeling, various constraints are activated as information is processed by a simulation. In quantitative models, constraints (i.e., the expressible relationships between entities) are normally linear equations; yet, nonlinear relationships could serve equally well. For qualitative simulation, constraints become symbolic functional relationships. For example, a symbolic functional relationship might be expressed verbally as: “if there are two inputs, and both show an increase, then propagate an increase to the output.” In object-oriented representations, constraints could be simply implemented in methods operating on symbolic values stored in object instance variables, in much the same way as quantitative relationships are implemented in the digital circuit constraints given in the examples in Chapters 3 and 10.

## Alternatives for Representing Time

There are a number of choices for representing time. One familiar technique is the use of differential equations that permit mathematical representation of system behavior related directly to continuous time. Although equation-based closed-form mathematical descriptions are appealing and com-
plete, discrete representations are more attractive for computer simulation. Hence, discrete time (i.e., representing time as a series of exact discrete steps) has become the dominant means for simulating time-oriented systems. Most discrete-time representations use either a fixed-interval time representation or event-related timing. In the first case, fixed-interval-time models simply move a simulation clock from one time to the next; if an event is associated with a certain time, then it is activated. As a concrete example, imagine that events should occur in a simulation at times 5, 10, and 20 seconds after the start of the simulation. An internal clock could be set to tick and, after the requisite elapsed times, events (perhaps displaying an activity on the screen) would occur. Of course, time could be either real time or time that is either faster or slower than real time. In the second case, discrete-event simulation, events are tagged with a time at which they should occur and placed on a queue ordered by time. After starting the simulation, events are removed one by one from the head of the queue and activated. The activation of each new event may cause other events to be stored on the queue, each tagged with a specific time relative to the current time. The event activation process may continue indefinitely if the queue never becomes empty or will terminate when events on the queue are depleted.

Both fixed-interval-time simulation and event-driven simulation are widely used. Contrasting the two methods does not reveal clear superiority for either method, although event-driven simulation has some inherent advantages. For example, representation of events that are temporally distant (i.e., there is a long time between events) is simpler with event-driven simulation because time tags are the only information that is required to track time. Fixed-interval simulation also contains events that are time tagged; however, the requirement of permitting a clock to "tick" from one event to the next means that a suitable time compression must be found to permit observation of temporally distant events. Hence, watching a system simulated by fixed-interval simulation becomes difficult if there are events that are separated by both long and short times.

Chapter 13 described a form of fixed-interval-time simulation, in which delays were added to constraints. In the example given in that chapter, signals propagated through constraints, waiting an appropriate amount of time at each node. No system clock was involved, however; yet, the effect was precisely the same as if each constraint in each of the nodes had been triggered by a clock.

Table 14.3 shows several examples of continuous and discrete simulation systems. Examples listed under discrete-event simulations are often called "counter" simulations because of their relationship to the model of a customer approaching a counter for service, obtaining service, and leaving. All of these actions are discrete events and can be readily modeled using discrete-event
<table><caption>**Table 14.3** Examples of Discrete and Continuous Simulations</caption><thead><tr><th colspan="2">Discrete-Event Simulations</th></tr><tr><th>Example</th><th>Components</th></tr></thead><tbody><tr><td>Traffic control</td><td>Events: lights changing<br>Entities: vehicles</td></tr><tr><td>Commodity transport</td><td>Events: commodity transactions<br>Entities: trucks and trains</td></tr><tr><td>Aircraft control</td><td>Events: aircraft queue handling, positions<br>Entities: aircraft</td></tr><tr><td>Operating system</td><td>Events: switching processes<br>Entities: users</td></tr><tr><td>Bank simulation</td><td>Events: transactions<br>Entities: customers, bank tellers</td></tr></tbody></table>

**Continuous Simulations**

<table><thead><tr><th>Example Simulation</th><th>Implementation</th></tr></thead><tbody><tr><td>Simple mechanical and<br>electrical simulations (e.g.,<br>flush toilet or analog circuit)</td><td>Constraints using equations</td></tr><tr><td>Continuous flow<br>(e.g., through pipes)</td><td>Constraints / equations</td></tr><tr><td>Stresses on mechanical systems<br>or structures</td><td>Differential equations</td></tr><tr><td>Analog computers</td><td>Physical analog components</td></tr><tr><td>Models of human expertise</td><td>Rule-based systems</td></tr></tbody></table>

simulation. The first three continuous simulations shown in Table 14.3 are equation-based examples. Also shown are two other continuous simulations worth mentioning. First, analog computers physically implement continuous simulation. Analog computers are built from analog electronics hardware; hence, when changes are made in a simulation implemented in an analog computer, the results are immediately observable. Finally, rule systems can conceptually be thought of as organizing models of human expertise; when an observation is made, the inference should be made immediately. Thus, rule systems may be thought of as being continuous.

As a final note, the distinctions between discrete and continuous are often a matter of granularity. For example, as a homely example, putting sugar on cereal is a continuous type of action. Yet, when viewed very closely, discrete individual grains of sugar are being distributed at distinct points in time. A continuous model of the more global view might be implemented with an equation that relates the amount of sugar distributed to the time, and a discrete
model of the microscopic view would link distinct times to the distribution of each grain of sugar.

## Alternatives for Representing Quantities and Qualities in Simulation Systems

The word *quantitative* is defined as "Expressed or capable of expression as a quantity," and *qualitative* is defined as "Of, pertaining to, or concerning quality or qualities" (Morris, 1981). Quantities are describable in terms of variables that hold numeric values, whereas qualities are describable in symbolic terms. Traditional engineering simulation has represented quantities using several types of simulation methods. Table 14.4 lists the two leading classes of simulation methodologies and several simulation languages that have been useful for quantitative simulation. The most prevalent type of simulation is discrete-event simulation; listed in the table are five major types of discrete-event simulation: event scheduling, activity scanning, the three-phase approach, process interaction, and transaction flow (Pidd, 1988; Derrick et al., 1989). Event scheduling deals with the description of a system in terms of events that may occur and event routines that run when the state of a system changes. Activity scanning examines the interactions between entities in a system. The three-phase approach modifies the event scheduling model by segmenting system activities into three phases: a time scan, bookkeeping, and execution of condition-related events. The process interaction method tries to identify processes in a simulation as the main entities of interest, and the transaction flow method models time and state relationships in terms of the arrangement and interaction of transactions. There are a number of other discrete-event simulation methods [Derrick et al. (1989) identifies six more] that are somewhat less popular.

<table><caption>**Table 14.4** Examples of Types of Quantitative Simulation Systems and Languages</caption><tr><td>Discrete-event simulation</td><td>Event scheduling<br>Activity scanning<br>Three-phase approach<br>Process interaction<br>Transaction flow</td></tr><tr><td>Classical modeling</td><td>Optimization theory<br>Constraint programming<br>Bond graphs</td></tr><tr><td>Simulation languages</td><td>GPSS<br>SIMSCRIPT<br>GASP<br>SimKit</td></tr></table>
Classical modeling techniques, as displayed in Table 14.4, such as optimization theory, constraint programming, and bond graphs are other tools frequently used in simulation. Constraint programming issues have already been examined in some detail in Chapters 10 and 13. Many simulation languages produced during the last few decades permit a user to construct simulations by using the language syntax. The oldest simulation language is probably GPSS (General-Purpose Simulation System) which was introduced by IBM some three decades ago. GPSS is an ad hoc language that originally introduced the transaction model of simulation. More recent versions of GPSS have added graphical construction and animation (Cox, 1985). Simula (Birtwistle et al., 1973) is an early object-oriented simulation language. Simscript (Markowitz et al., 1963) utilizes English-like statements to permit modeling, and GASP (Pritsker and Kiviat, 1969) is a collection of Fortran subroutines for modeling. SimKit (Drummond and Stelzner, 1989) is an object-oriented modeling system that is part of the KEE (Knowledge Engineering Environment) package produced by Intellicorp.

The lesson to be learned from these few paragraphs about traditional simulation is that simulation is, by modern computer standards, an old field. Starting with the development of systems based on quantitative methods implemented with Fortran, the field has moved toward refining the initial concepts over several decades. Recently, however, traditional research in simulation has become aware of work on qualitative methods that has arisen in the field of artificial intelligence, and vice versa.

Qualitative simulation has evolved almost as a separate entity with little input from traditional simulation research. Starting from theories proposed by Hayes (1979), qualitative simulation has grown to be a viable interest area within the field of artificial intelligence. The basic idea is that one can replace detailed mathematical descriptions of quantitative relationships with symbolic representations that describe qualitatively interrelationships between entities. For the most part, work on qualitative simulation has been on theoretical constructs; however, as shown in Table 14.5, various investigators have applied their theories to practical problems. Consider the examples given in Table 14.5. Application examples range from the modeling of valves to topics in electrical and electronic circuits to even a description of the behavior of

<table><caption>**Table 14.5** Examples in Qualitative Simulation Systems</caption><tr><td>Valves</td><td>de Kleer and Brown (1985)</td></tr><tr><td>Analog circuits</td><td>de Kleer (1985)</td></tr><tr><td>MOS circuits</td><td>Williams (1985)</td></tr><tr><td>Electrical heating</td><td>Farquhar and Kuipers (1987)</td></tr><tr><td>Projectiles</td><td>Kuipers (1986)</td></tr></table>
projectiles. The commonality that can be observed in these examples is that the domains are typically ones that can be usefully modeled using differential or algebraic equations. Hence, one might question the utility for qualitative modeling. Several reasons have been advanced for employing qualitative modeling. Fishwick (1989) observes that there are indeed few cases in which qualitative simulation might make sense to use in preference to quantitative simulation. These cases are: (1) modeling human cognition, (2) cases in which quantitative models require excessive computation, and (3) tutoring systems. In the first case, it makes sense to utilize symbolic representations because there are few quantitative methods in cognitive science. The second and third cases are linked; qualitative models can produce a sense of how a system being simulated works, even though precision is lacking. Visualization of how a system operates is of paramount importance for tutoring systems because it is essential to produce simulations that rapidly give observable results to a student using a simulation. It would be totally unacceptable, for example, to require a student to wait long periods of time to observe a change on the computer screen. Of course, if the mathematical relationships between the entities utilized to model a system are sufficiently simple and/or computationally efficient, then quantitative models would be perfectly adequate for implementing models used in tutoring systems.

The thrust of these discussions is the view that qualitative modeling and quantitative modeling attempt to achieve the same goal, that is, providing a behavioral representation of something in the real world. Quantitative discrete methods have been used for this purpose for a long time, and the study of qualitative symbolic methods has only commenced during the last decade. Presumably, the trade-offs between the methodologies and the utility of the capabilities of the different paradigms will gradually become better understood.

## The Relationship between Traditional and AI-Based Simulation

Only during the last few years has there been any recognition that it would be useful to merge concepts in artificial intelligence with simulation methodologies. The central concept driving a merger of these formerly separate fields is that the addition of some form of intelligence will make simulation systems much more powerful. Capable of making decisions and interpreting the results of manipulation of simulation parameters, AI-based simulations will likely become widely used during the upcoming decade. Table 14.6 shows some of the efforts in this direction that have been made during the last years. CASM (computer-aided simulation modeling) (Balmer and Paul, 1986) applied expert systems technology to simulation for the purposes of problem formulation and simulation model development. SimKit (Drummond and Stelzner, 1989) is a set of software tools that permit building domain-independent discrete-event simu-
<table><caption>**Table 14.6 Artificial Intelligence Systems and Simulation**</caption><thead><tr><td>System Name</td><td>Capabilities</td></tr></thead><tbody><tr><td>CASM</td><td>Expert system for problem formulation and simulation model development</td></tr><tr><td>SimKit</td><td>Modeling kit for KEE</td></tr><tr><td>KBSim</td><td>Reasoning in simulation</td></tr><tr><td>Molgen</td><td>Rule-driven simulator for genetics</td></tr></tbody></table>

lation systems. Object-oriented in the sense that KEE (Kehler and Clemenson, 1984) frame structures are used in SimKit, this package permits graphical building of simulation systems.

KBSim (knowledge-based simulation) (Rothenberg, 1989) is a system that assists in reasoning in simulation, including inference and explanation. There are a variety of examples of AI-based simulation. One of the most impressive is the Molgen project (Meyers and Friedland, 1984) which uses a knowledge base of rules about regulatory genetics and facts to attempt to make deductions about specific growth behaviors in genetics.

The common theme in the use of AI methodologies in simulation is to add some level of intelligence to simulation. In work accomplished until the early 1990s, most activity has consisted of encoding human problem-solving knowledge in the form of rules that can be used to assist the user in (1) planning and putting together a simulation and (2) interpreting the results of a simulation.

## The Importance of Object-Oriented Methodologies in Simulation

The review of the state of the art of simulation methodologies given in this section permits the making of several assertions about why object-oriented methodologies are useful in simulation. First, most simulation is concerned with models of real-world entities and their interactions. The structures and behaviors of these objects are readily modeled by object-based techniques, as has been shown throughout the text. Second, objects provide a parsimonious representation for real-world objects by permitting specialization and inheritance. Thus, libraries of general simulation objects could exist which would facilitate building of new simulations simply by specializing existing objects in the library. For example, if a pipe existed in a library of simulation objects, a rusty pipe could be used in a simulation simply by specializing the existing class for pipe. This type of capability does not normally exist in traditional simulation packages.
<table><caption>**Table 14.7 Examples of ST-80 Simulation Applications**</caption><thead><tr><td>Name</td><td>Application</td></tr></thead><tbody><tr><td>INSIST</td><td>VLSI design</td></tr><tr><td>SIMFLEX</td><td>Flexible manufacturing</td></tr><tr><td>GREGG</td><td>Military graves registration</td></tr><tr><td>SIMBIOS</td><td>Continuous models</td></tr></tbody></table>

Although the use of object-oriented methods in simulation is a relatively new field, there are already a number of examples that have been created during the recent past. Table 14.7 summarizes some of these systems (Haden, 1990). The four systems shown in the table are Smalltalk-based (INSIST, van der Meulen, 1989; SIMFLEX, Vujosevic, Antao, and Bourne, 1990; GREGG, Helfman, Ralston, and Suckling, 1987; SIMBIOS, Guasch and Luker, 1990). Haden (1990) in a review of the literature found that approximately half of the 25 AI-based simulation systems reviewed were written in Smalltalk. The remaining systems were other object-oriented languages such as C++, Flavors, Ada, and Simula.

The next sections of this chapter will move away from the relatively abstract concepts presented previously and give some concrete examples of how to create simulation systems using object-oriented techniques. Also, more attention will be given to Smalltalk-80 implementations.

### 14.3 Multiple Independent Processes

Smalltalk-80 provides the capability for managing multiple independent processes with its virtual machine and virtual image. In essence, the virtual machine and virtual image permit the spawning of multiple processes as if one were able to use multiple physical machines to execute multiple processes. However, the Smalltalk-80 programmer needs to know virtually nothing about the implementation mechanism of the virtual machine and virtual image in order to make use of their capabilities. For simulation, the capability of having multiple independent processes running contemporaneously is significant. For example, consider the implementation of the counter simulations discussed earlier in this chapter in which there are two types of actors in a simulation: customers and servers. In these types of simulations, each type of actor can be made into an independent process and can operate in the simulation much like they do in the real world, that is, waiting on each other for service. The object-oriented communications paradigm works well in this type of simulation
<table><caption>Table 14.8 Some Features of Multiple Independent Processes in Smalltalk-80</caption><thead><tr><td>Feature</td><td>Description</td></tr></thead><tbody><tr><td>Process support</td><td>Supports multiple processes that can have priorities and are managed by the virtual image</td></tr><tr><td>Scheduling</td><td>Processes may be scheduled, activated, and terminated</td></tr><tr><td>Semaphores</td><td>Support synchronization of processes</td></tr><tr><td>Shared queues</td><td>Class SharedQueue provides safe communication between objects</td></tr><tr><td>Delays</td><td>Class Delay provides real-time delays</td></tr></tbody></table>

in which customers and servers send each other messages to communicate and start transactions.

Table 14.8 shows some of the important features of multiple independent processes that are implemented in ST-80. Processes are simply sequences of actions that are performed to carry out tasks. The ST-80 system permits multiple tasks to run contemporaneously (i.e., at about the same time). Although simultaneous parallelism of tasks is the objective, each process receives a slice of time to run. Also, some tasks can be given a higher priority than other tasks, as specified by the user. A simple experiment to test how multiple processes run in ST-80 can be conducted by the casual user by constructing the following code in a workspace and executing the code.

X := 0.
MyProcess := [[true] whileTrue:
    [|context| context := ScheduledControllers activeController view graphicsContext.
    context displayString:
        (X printString) at: 100@150.
    context displayImage: EraseIt<fnref n="1" /> at: 50@100.
    X := X + 1.
    Processor yield]

] forkAt: 4.

"a global variable"
"MyProcess is global"
"show the number"
"erase it"
"increment the number"
"make sure that higher"
"priority processes"
"are seen"
"start this independent"
"process at level 4"

<footnote n="1">¹EraseIt is a global variable that holds a blank image.</footnote>
This code should display a continuously increasing number on the workspace. If you move the cursor, you should still be able to type code in the workspace. Try typing

MyProcess terminate.

and executing this code. The continuously increasing numbers should cease to increment. In this test code fragment, the following points are relevant. First, one can send a message *fork* or *forkAt*: a Priority to a block of code and it will run independently. The code in this test block runs again and again, never terminating on its own, because `[true] whileTrue: [...]` is always true. Fortunately, the process is identified with a name: "MyProcess," which can be sent the message *terminate* to cause the process to stop running. Other messages such as *suspend* and *resume* are also available. Priorities range from 8 (high) to 2 (low). The normal user interaction priority is 4. By including in the block, the code "Processor yield," we ensure that other processes with the same priority can gain control. In the preceding example, the number contained in the global variable "X" is displayed on the workspace. To continue to be able to see each number in turn, this example erases a small area on the workspace by displaying a blank image over the area on which the numbers are displayed. Note that the "EraseIt" image can be captured easily by simply assigning *EraseIt* to *Image fromUser* and grabbing a blank area of the screen.

An interesting experiment that can be attempted is to duplicate the code given previously with different process names and with different locations to display numbers on the workspace. By doing this multiple times and forking multiple processes, it can be easily observed that adding more and more processes slows down the time given to each process. By declaring "X" as a global variable in the preceding example and in each subsequent process that is forked, multiple processes referring to "X" will each increment this same variable and display it.

The remaining features of multiple independent processes in ST-80 include classes for scheduling, semaphores (essentially flags—one-bit pieces of information) which permit synchronization of processes, shared queues, and a class called **Delay** which has already been used in Chapter 13. The class **Delay** will be used in the examples that follow to implement delays in a simulation.

## 14.4 Probability Distributions

A strong capability that is available for ST-80 is a set of classes for implementing probability distributions. In simulating randomly interacting multiple processes, it is essential to be able to characterize the behavior of the
<table><caption>**Table 14.9** Probability Distributions Implemented in ST-80</caption><thead><tr><td>Class Name</td><td>Possible Use</td></tr></thead><tbody><tr><td>Bernoulli</td><td>Determining whether an event occurs</td></tr><tr><td>Geometric</td><td>Determining how long until the next event</td></tr><tr><td>Poisson</td><td>Determining how many events occur in an interval</td></tr><tr><td>Exponential</td><td>For Poisson-distributed events, determining the time until the next event</td></tr><tr><td>Uniform</td><td>Picking equally likely events</td></tr><tr><td>Gamma</td><td>Determining how long until the Nth event occurs</td></tr><tr><td>Normal</td><td>Describing a process with a central tendency (mean) and a standard deviation</td></tr></tbody></table>

process statistically. The classes, contained in a `fileIn \utils \stats.st`,<fnref n="2" /> provide a rich set of distributions which can be employed by the user with little additional thought. Table 14.9 lists the types of distributions that are available in the ST-80 `fileIn \utils \stats.st`. A detailed discussion of these classes are found in Goldberg and Robson (1983).

An example of the use of probability distributions in simulation is straightforward. Imagine a counter-style simulation, for example, the bank simulation discussed previously. Customers arrive randomly according to a mean and a standard deviation. As indicated in Table 14.9, the Normal (also known as Gaussian) distribution would be suitable for modeling customer arrival. A specific example might be creating a new instance of a **Normal** class, for example:

$$aNormalDistribution := \text{Normal mean: 10 deviation: 1.}$$

The meaning of this distribution could be that, on the average, a customer arrives every 10 minutes with a deviation of plus or minus 1 minute. Practically, the use of the distribution instance would be to sample the distribution when a new number is needed, for example, to record the arrival of new customers appearing at the entrance to the bank on the screen. To secure a number, the instance of the distribution is sent the message *next* which, when repeatedly sent, results in this example, in a sequence of numbers such as: 10.34, 9.45, 8.56, 11.09, 12.34, 10.52, 10.98....

<footnote n="2">²Found on the ParcBench Bulletin Board of ParcPlace Systems.</footnote>
## 14.5 A Simple Framework for Discrete-Event Simulation

To explain discrete-event simulation, the example of the digital circuit simulator that has been used throughout this text (Chapters 3, 10, and 13) will be recast into a discrete-event-simulation framework. The intention is to explain how discrete-event simulation could be used to solve the same problem that has already been solved in a slightly different way and to compare the methodologies.

Consider the diagram presented in Figure 14.1 which portrays a discrete-event model for a digital circuit simulator consisting of a collection of gates and wires. This system is driven by procedures contained in wire objects which post their procedures on an agenda implemented as a queue. Whenever a wire receives a signal, it posts the procedures to be activated on the event queue at the time at which the event is supposed to occur. This idea is especially useful for posting events at some future time. For example, a signal arrives at an electronic gate and is delayed because of the inherent electrical characteristics of the gate for some fixed time. To simulate this situation, the class **Delay** was used in the simulation given in Chapter 13. In the discrete-event-simulation situation, the amount of time to be delayed is added to the current simulation time and posted to the event queue so that the procedures attached to the wire are run at the appropriate later time. This capability is especially important in simulating large systems of objects, many of which spawn delayed events at varying future times.

<figure><img src="image_171.png" /><figcaption>Figure 14.1 Discrete-Event Model for Digital Circuit Simulation.</figcaption></figure>
The model shown in Figure 14.1 attempts to graphically explicate the description given previously. At the top of the figure, a wireCollection is shown which contains all the wires in a circuit simulation. Each wire contains a set of procedures, labeled $P_A(1)$, $P_A(2)$, and so forth, where the subscript indicates the wire with which the procedure is associated. The agenda, also known as the event queue, contains associations of procedures and times. The diagram indicates that the procedures are posted in the event queue at the appropriate time, where times are sequentially ordered. Implementation should be by sorted collection, sorting on the time so that as new events are added to the queue, sorting will create the correct time ordering. Finally, any procedure can send a message to another wire, reinitiating the entire sequence of events, resulting in the effective propagation of events through the simulated system.

## 14.6 A Discrete-Event-Simulation Framework

*Simulation.st* is an example file that is available in Smalltalk-80. Goldberg and Robson (1983) in their seminal text on Smalltalk provide a detailed explanation of this code. This section gives an overview of the simulation framework contained in *simulation.st*. Readers without ST-80 can skip this section and those interested in the details of the code are referred to the Goldberg and Robson text. The rationale for this brief presentation is to make students who are interested in simulation aware of this existing framework.

Figure 14.2 presents this author's interpretation of the operation of the code provided in *simulation.st*. Shown at the top of the figure is an object that is used to organize a simulation. This object, class **Simulation**, contains four instance variables: resources, eventQueue, currentTime, and processCount. Resources is a set that contains objects that specify the amounts of various resources in the simulation. EventQueue, a sortedCollection, contains the delayed events of the simulation. CurrentTime is used to maintain the current simulation time, and processCount keeps track of the number of processes spawned. The eventQueue shown in the center of the figure displays a number of delayed events ordered by time. Each delayed event is a simulation object whose execution is delayed until a time specified in the object and sorted on the queue. Implemented as multiple independent processes, the delayed events utilize ST-80's capability of suspending a process and the capability of resuming a process using a semaphore (signal).

Figure 14.3 shows the class hierarchy created to implement the discrete-event-simulation framework. The major subclasses of **Object** created are **Resource**, **Simulation**, **SimulationObject**, and **DelayedEvent**. **Resource** is subclassed with **ResourceProvider** and **ResourceCoordinator** which provide classes that contain resources and implement capabilities for coordinating resources.
<figure><img src="image_172.png" /><figcaption>**Figure 14.2** Simulation Framework Interpretation of 'simulation.st' code in Smalltalk-80.</figcaption></figure>

The major interesting aspect of this simulation framework is the implementation of the simulation as a discrete-event simulation using multiple independent processes (implemented as blocks of code) which are scheduled on an event queue sorted by time. This idea is essentially the same as the digital circuit discrete-event simulation discussed in the previous section except that, in this case, blocks of code are stored on the queue to be executed. In this case,

<figure><img src="image_173.png" /><figcaption>**Figure 14.3** Class Hierarchy of Simulation Framework. [From Goldberg and Robson (1983).]</figcaption></figure>
<figure><img src="image_174.png" /><figcaption>Figure 14.4 Petri Net for Electronic Printed Circuit Board (PCB) Manufacturing.</figcaption></figure>

processes to be run are suspended, waiting to run until a signal is received from the simulation object that directs the sequential execution of delayed events posted on the event queue.

## 14.7 Simulation Using Petri Nets

Petri nets, first investigated by C. Petri (Petri, 1962), have been widely used during the last few decades for simulation (Peterson, 1981). Petri nets provide an alternative representation to the discrete-event queue-based systems discussed in the previous sections of this chapter. Petri nets provide an easy-to-understand technique for representing many kinds of systems and are easily implemented in the object-oriented style. Figure 14.4 presents a simple example of a Petri net. This figure is a Petri net that models a portion of an electronic printed circuit board (PCB) assembly system. The operation of this part of the assembly process is to fill a board with components and then solder the components on the board. Examining the figure reveals some unfamiliar symbols: (1) a vertical bar with arrows entering and exiting are termed transitions and (2) circles are termed conditions or places. The inputs to a transition are preconditions and the outputs from the transition are postconditions; that is, the transition behaves much like a rule: when preconditions are true, then the postconditions are triggered. The Petri net concept propagates tokens between places in the net, moving tokens between places according to the firing of the transitions. In the example, the first transition is “PCB Arrives,” resulting in a token being placed in the place called “Board Waiting.” The second transition has as input, “Board Waiting” and “Parts Available.” When there are tokens in both of this transition’s input places, then the transition can fire and produce a token to be placed in the output place “Board Stuffed.” Following the flow of tokens through the example shows that the next activity “Wave Soldering” will
<figure><img src="image_175.png" /><figcaption>**Figure 14.5** Object Hierarchy for Petri Net Implementation. Underlined classes are new.</figcaption></figure>

occur when the wave solder machine is ready to be used. The output of the
system is the board with components soldered on it.

The example given is typical of the kinds of graphs created using Petri nets. Most nets, however, are quite complex, yet visually useful for organizing the operation of entities such as machine shops, computer hardware, and software. Petri nets have been shown to be useful, as well, for organizing knowledge about commonplace activities such as the flow of information in a legal system, building a house, and so on (Peterson, 1981). Most applications capitalize on the capability of Petri nets to model parallel activities. Parallel applications can be easily understood by considering the PCB example. Suppose multiple assembly lines were simulated using the same schema as employed for the single line given previously. It is easy to visualize multiple places and transitions that would model the multiple parallel activities of the multiple assembly lines. Tokens could propagate asynchronously through the parallel systems and information on the operation of each line could be maintained separately or as composite data.

Figure 14.5 displays a class hierarchy for implementing a Petri net simulator. The major classes displayed are: **PTNetView**, a subclass of **View**; the **PTNetController**, a subclass of **Controller**; **PTNet**, the organizing model for the system; **PTNode**, the description of the nodes in the network; and **Connections**, a subclass of **Spline**<fnref n="3" /> used for drawing connections between the nodes on the graph. The code for this application consists of a fileOut of about 50K charac-

<footnote n="3">³Note that class Spline does not exist in Release 4; displayPolyline: could be used in a Release 4 implementation.</footnote>
<figure><img src="image_176.png" /><figcaption>**Figure 14.6** A Flexible Manufacturing Line. [With permission; Dehner (1990).]</figcaption></figure>

ters and is available to interested parties as indicated in the Appendix. The use of this ST-80 implementation in a manufacturing example will be discussed next.

## 14.8 Building an Example Simulation for Manufacturing

This section describes the use of Petri nets for implementing a printed circuit board manufacturing line. Figure 14.6 (Dehner, 1990a), a simplification of Figure 7.17 in which the concept was discussed in the context of user interface design, displays a view from above a manufacturing line. Empty boards enter on the top left and progress through various stations around the U until exiting as a completed product at the bottom left. At each station, a single type of operation occurs, for example, moving from DIP (dual in-line package) insert to axial insert, and so forth. At each station, an operator supervises the operation of machines that insert components, wave solder the components to the board, inspect the boards, and test the boards. The squares marked K are so-called Kanban squares or temporary storage areas for the partially finished product at each stage of the manufacturing process (Dehner, 1990b). As a set of boards is completed and tested, the product is moved from one Kanban square to another, "pulling" the product through the manufacturing process.

Petri nets can be used to simulate this manufacturing process. Figure 14.7 shows the use of the Petri net simulator discussed in the previous section of this chapter. Icons for the transitions are changed to rectangles which contain
<figure><img src="image_177.png" /><figcaption>Figure 14.7 The Petri Net Simulator for Flexible Manufacturing: Building the Simulation.</figcaption></figure>
<figure><img src="image_178.png" /><figcaption>Figure 14.8 The Petri Net Simulator: Running the Simulation.</figcaption></figure>
the name of the operation occurring at the transition. The places remain displayed as circles. Note the inclusion of a transition between each of the Kanban squares. The purpose of this transition is to permit transfer of a token from one square to the next (e.g., K1 to K2) when a predetermined number of items is present on the first square. Relating this statement to the example, each station would process a number of boards (e.g., 10 or 20) prior to permitting the forwarding of the batch to the next station.

Shown on the simulation view is the yellowButtonMenu which permits operation of the simulation. Operations for adding and removing nodes and links, adding tokens to nodes, defining the capacity of nodes, selecting the probability distributions associated with a transition, and other operations are accessible from this hierarchical menu (Jiang, Bourne, and Brodersen, 1990). Actually running the simulation results in the view presented in Figure 14.8 which animates the simulation. The hatched squares above each node show the number of tokens that are in a node (place) at any given time. Each transition reverses color (i.e., white to black) when the transition fires. Hence, one can watch the simulation work as the tokens flow throughout the simulation. Simultaneously, in a transcript window at the top right of the view, a textual set of information that describes the actions of the simulation is displayed.

## 14.9 Summary

The three major simulation methodologies described in this and previous chapters are: (1) analog constraints, (2) fixed-interval time simulation, and (3) discrete-event simulation. Analog constraints (e.g., the digital circuit simulator without delays) and equations implement instantaneous propagation of relationships. Adding time as a factor can be handled in different ways: by delays and by queues. Furthermore, relationships, time, and variables can be described both quantitatively and qualitatively. Thus, at this point, one must ask how one can decide what type of simulation is most useful for which types of situations. The answers are not easy—but here are a few observations that may be useful.

First, if a simulation system is already available for a specific purpose that will solve a problem, it should be used. Second, if the problem one is dealing with is analog in nature, use of the constraint methodology is very appealing because constraints permit visualization of analog interrelationships. Third, for discrete systems modeling, one has many choices among the myriad of digital simulation systems already created that use fixed-interval discrete simulation or event-driven simulation. Both of the latter techniques will yield the same approximate results; neither appears inherently superior except in
cases in which events are widely distributed in time. In this case, event-driven simulations appear to be more useful.

This chapter has examined a number of issues and alternatives for using various types of simulation methods and has indicated that object-oriented methodologies are a useful vehicle for implementing simulation systems. In several cases, in which entities in the real world are modeled, object-oriented techniques are obviously superior due to the one-to-one mapping between objects and simulated entities. The rapid prototyping capability of ST-80 permits building simulation systems based on the various models described. With the attendant graphical capabilities of the system, ST-80 is an appropriate tool for building simulation systems.

## References

Balmer, D. W., and R. J. Paul (1986). CASM—The Right Environment for Simulation. *Journal of the Operational Research Society*, Vol. 37, 443–452.

Birtwistle, G., O.-J. Dahl, B. Myhrlaug, and K. Hygaard (1973). *Simula Begin*. Petrocelli/Charter, New York.

Bobrow, D. G. (Ed.) (1985). *Qualitative Reasoning about Physical Systems*. MIT Press, Cambridge, MA.

Bratley, Paul, B. L. Fox, and L. E. Schrage (1987). *A Guide to Simulation*, 2nd ed. Springer-Verlag, New York.

Cox, S. and A. Cox (1985). GPSS/PC: A User Oriented Simulation System. In *Modeling and Simulation on Microcomputers*, R. G. Lavery (Ed.). Society for Computer Simulation, San Diego, CA, pp. 48–50.

Dehner, G. (1990a). Literature Review, Personal Communication.

Dehner, G. (1990b). Personal Communication.

de Kleer, J. (1985). How Circuits Work. In *Qualitative Reasoning about Physical Systems*, D. G. Bobrow (Ed.). MIT Press, Cambridge, MA.

de Kleer, J., and J. S. Brown (1985). A Qualitative Physics Based on Confluences. In *Qualitative Reasoning about Physical Systems*, D. G. Bobrow (Ed.). MIT Press, Cambridge, MA.

Derrick, E. J., O. Balci, and R. E. Nance, (1989). A Comparison of Selected Conceptual Frameworks for Simulation Modeling. *Proceedings of the 1989 Winter Simulation Conference*. Dec. 1989, pp. 711–718.

Drummond, Brian, and Marilyn Stelzner (1989). SimKit: A Model-Building Simulation Toolkit. In *AI Tools and Techniques*, M. H. Richer (Ed.), pages 241–259. Ablex Publishing, Norwood, NJ.

Farquhar, Adam, and B. Kuipers (1987). QSIM: A Tool for Qualitative Simulation. University of Texas Internal Memorandum.
Fishwick, Paul A. (1989). *Qualitative Methodology in Simulation Model Engineering*. *Simulation*, March, pp. 95-101.

Goldberg, Adele, and D. Robson (1983). *Smalltalk-80, The Language and Its Implementation*. Addison-Wesley, Reading, MA.

Guasch, Antoni, and Paul A. Luker (1990). *SIMBIOS: Simulation Based on Icons and Objects*. *Proceedings of the SCS Multiconference on Object Oriented Simulation*. January, 61-67.

Haden, Gerald L. (1990). The Virtual Engineering Laboratory: A Framework for Intelligent Computer-Aided Simulation, Analysis and Design. A Review of Relevant Literature, Area Paper, Vanderbilt University, Nashville.

Hayes, P. (1979). The Naive Physics Manifesto. In *Expert Systems in the Microelectronic Age*, D. Michie (Ed.). Edinburgh University Press, Edinburgh.

Helfman, R. A., M. H. Ralston, and J. R. Suckling (1987). Object-Oriented Simulation for the U.S. Army Graves Registration Service. In *Proceedings of the 1987 Winter Simulation Conference*. 860-869.

Jiang, Z., J. R. Bourne, and A. J. Brodersen (1990). A Petri-Net-Based Simulation System. Internal Working Paper, Center for Intelligent Systems, Vanderbilt University, Nashville.

Kehler, T. P., and G. D. Clemenson (1984). An Application Development System for Expert Systems. *System Software*, Vol. 3, No. 1, January, 212-224.

Kuipers, Benjamin (1986). *Qualitative Simulation*. *Artificial Intelligence*, Vol. 29, 289-338.

Markowitz, H. M., B. Hausner, and H. W. Karr (1963). *Simscript: A Simulation Programming Language*. RAND Corporation RM-3310-pr, Prentice-Hall, Englewood Cliffs, NJ.

Meyers, S., and P. Friedland (1984). Knowledge-Based Simulation of Genetic Regulation in Bacteriophage Lambda. *Nucleic Acids Research*, Vol. 12, No. 1, 1-9.

Microsoft Windows, Version 3.0 (1990). Microsoft Corporation, Redmond, WA.

Morris, William (Ed.) (1981). *The American Heritage Dictionary of the English Language*. Houghton Mifflin, Boston, MA.

ObjectWorks \ Smalltalk-80, Release 4, (1991) ParcPlace Systems, Mountain View, CA.

Ohr, Stephan A. (1990). *CAE: A Survey of Standards, Trends, and Tools*. Wiley, New York.

Peterson, James L. (1981). *Petri Net Theory and the Modeling of Systems*. Prentice-Hall, Englewood Cliffs, NJ.
Petri, C. (1962). *Kommunikation mit Automaten*. PhD dissertation, University of Bonn, Bonn, West Germany. In German.

Pidd, M. (1988). *Computer Simulation in Management Science*, 2nd Ed. Wiley, New York.

Pinson, L. J., and R. S. Wiener (1988). *An Introduction to Object-Oriented Programming and Smalltalk*. Addison-Wesley, Reading, MA.

Pritsker, A. A. B., and P. Kiviat (1969). *Simulation with GASP II: A FORTRAN-Based Simulation Language*. Prentice-Hall, Englewood Cliffs, NJ.

Rothenberg, Jeff (1989). *Tutorial: Artificial Intelligence and Simulation*. *Proceedings of the 1989 Winter Simulation Conference*, December, 33-39.

van der Meulen, Pieter S. (1989). Development of an Interactive Simulator in Smalltalk. *Journal of Object-Oriented Programming*, Vol. 1, No. 5, January/February, 28-51.

Vujosevic, Ranko, B. Antao, and J. R. Bourne (1990). *Object-Oriented Hierarchical Modelling and Simulation of Flexible Manufacturing Systems*. *Proceedings of the SCS Multiconference on Object-Oriented Simulation*. January, 87-92.

Webster's *Unabridged Dictionary of the English Language* (1989). Dilithium Press.

Williams, Brian C. (1985). *Qualitative Analysis of MOS Circuits*. In *Qualitative Reasoning about Physical Systems*, D. G. Bobrow, (Ed.). MIT Press, Cambridge, MA.

## Exercises

14.1 Implement the multiple-process experiment described in this chapter. Create several processes of the type specified and determine how many processes need to be started in order to slow down your machine. Next insert a (*Delay forSeconds: 1)* *wait* statement in the continuously executed block. You should see a distinct difference in the behavior of your multiple processes.

14.2 Consider the items given in Table 14.1. Now make up your own list of examples. Indicate for each what style simulation is best and why, in your opinion.

14.3 Give two examples of the terms quantitative and qualitative to demonstrate that you understand the difference between the two terms.
14.4 Describe the differences between classical modeling and discrete-event modeling methods.

14.5 Try out the probability distribution class of ST-80.<fnref n="4" /> Plot a Gaussian curve with a mean of 10 and a standard deviation of 1. Secure points as indicated in the example in this chapter for this distribution and plot them on the same graph. Do the points appear valid for the distribution given?

14.6 Investigate the Smalltalk classes for scheduling multiple processes. Normally, if a method opens a scheduled window, any code in the method following the opening of the window is not executed. This prevents a block of code from opening several windows at once. Describe a technique using multiple scheduled processes which would allow a single method or block of code to open several ScheduledWindows. [Hint: Help on this question can be secured from Goldberg and Robson (1983).]

14.7 Petri nets provide a very general simulation model. Using the concept, draw a Petri net for a process that you understand (e.g., a car wash or multiple serving lines in a cafeteria).

<footnote n="4">⁴Found on the ParcBench Bulletin Board of ParcPlace Systems.</footnote>
<figure><img src="image_179.png" /></figure>
# Conclusions

## 15.1 Review

In this text, object-oriented methodologies have been studied with a special emphasis on engineering analysis and design. The presentation has been segmented into three parts: (1) an introduction to object-oriented methods, (2) an examination of languages and tools, and, finally, (3) a sequence of engineering-related topics, including several examples. The text has concentrated on explaining how to use object-oriented techniques in engineering; consequently, all examples given have a relationship to engineering. In part, the reason for this concentration is the strong belief that object-oriented techniques will become a favorite methodology for facilitating computer-based engineering problem solving during the 1990s. This concluding chapter will examine trends and issues and attempt to provide a prognosis for the future of object-oriented methodologies.

## 15.2 Prognosis for Object-Oriented Methodologies

Object-oriented programming methodologies may ultimately be viewed as a turning point in programming or, alternatively, as only one of the major evolutionary changes in programming paradigms during the last part of the 20th century. Due to the very long time required to make assessments of the influence of programming paradigms, it may be well into the 21st century before a realistic assessment can take place. However, from the viewpoint of the beginning of the last decade of the 20th century, a prognosis can be given, arguing from the facts that are now known.
First, object-oriented methods appear exceptionally useful for breaking out of the procedural paradigm which has been taught for the last 30 years and more. Procedural coding (i.e., coding of how to do something) enforces thinking about programming in a sequential manner, that is, in a "do this, do that" format. This style is perfectly adequate for small programs and even acceptable for very large programs if one is careful to create well-structured designs in which to work. Yet, when complexity becomes high, some type of information hiding without loss of understandability is needed. The encapsulation capability of object-oriented methods is useful for reducing complexity because objects are specified as behavioral entities with which one can communicate only by sending messages. The user is not required to know what goes on inside an object, so long as an object carries out the desired task specified when a message is sent to it. In contrast, in nonobject-based languages, code is usually openly observable, thus increasing the complexity with which persons trying to understand code must deal. Of course, some complexity in traditional programming is reduced by the liberal use of function calls and subroutines. Nevertheless, hiding the entire internal structure of an object and communicating only via messages is a powerful conceptual tool that makes programming much more similar to the way humans interact and make transactions in the real world. This last characteristic should ultimately make object-oriented methods much more acceptable to future generations of programmers who can directly relate to the inherent familiarity and conceptual understandability of the methodology.

### 15.3 Object-Oriented Methods in Engineering

As emphasized in this book, object-oriented programming methodologies are thought to be inherently useful for problem solving in engineering. Many, if not most, engineering problems can be described conceptually in terms of objects interacting with each other. Various examples in the engineering domains have been presented; however, it is difficult to say with certainty that object-oriented techniques are a cross-engineering panacea for all problem solving. There are, after all, many algorithmic techniques, such as finite-element analysis, which are unlikely to ever become object-oriented in the near or long term. Yet, even such techniques might become part of object-oriented problem-solving packages at some point.

The real world and transactions in the real world are easily represented using the object-oriented paradigm. Engineering as a discipline deals with problem solving in the world. Hence, the use of object-oriented methods is, almost by definition, well suited for engineering. The prognosis for the use of object-oriented methods in engineering is that object-oriented solutions to problems will become gradually more used during the 1990s. As more tools for
implementing object systems become widely available and as the understanding of the methodology grows, a broad following for the paradigm should be in place by the end of the century.

## 15.4 The Importance of Environments

Although there are many arguments about which object-oriented language is "best," the argument is fairly empty because the constructs on which all the object-oriented languages are based are similar, as outlined in Chapter 2. A better argument is about environments. Robust environments provide the tools needed to make programming simple and understandable. Highly efficient languages are of little use if they are difficult to use and understand. Hence, as discussed at several points in the text, the position taken here is that an environment to support any programming facility is essential to secure any degree of productivity. To date, the best example of a robust environment for object-oriented programming is Objectworks \ Smalltalk which is used as an example throughout the text. The typical argument about languages is "my language is better than your language because my language executes faster." It is indeed surprising that this type of argument persists because it is fairly obvious that the really critical aspect of a language and environment is how efficiently and effectively one can produce the desired result —not just how fast a particular language runs! The quest for efficiency, effectiveness, and understanding revolves around the creation of more and more robust environments which ease the programmer's and engineer's route to a completed product with less difficulty, more insight, and a feeling that the program development environment assists rather than hinders in development.

## 15.5 Reusability and Productivity

There are critical and unresolved issues in reusability and productivity which should be examined as this book comes to a close. Reusability has been portrayed as a critical element for enhancing productivity. Indeed, this conjecture is almost certainly true because it is always easier to use a piece of working code rather than writing new code from scratch. Because inheritance properties of object-oriented systems make it particularly easy to reuse classes that have already been built, it is nearly axiomatic that the reusability of classes is essential to the proper conduct of object-oriented programming. Indeed, in the examples given throughout the text, the classes created are subclasses of the many classes that already exist in the ST-80 environment. However, there is a significant difficulty that must be addressed—that of rights to code created. In
traditional programming, source code is compiled and executable code delivered to the end user. For most software products, it is essential that the code and the "look and feel" of the systems created be different from any other to protect one's legal rights. Hence, code production usually starts from scratch—a lengthy and time-consuming process that is completely anathema to our goals of reusability for productivity enhancement. Given the current widespread legalistic view of the world, any company producing a new product based on object-oriented methods might well need to produce all new code rather than subclass code that exists elsewhere, produced, for example, by another company. The producers of environments such as ST-80 and ST/V have come to grips with this problem by selling run-time licenses at a low cost. Yet, to encourage real increases in national productivity in object-oriented methodologies, there should be an open exchange of classes written. Perhaps by working together rather than in competition, richer, broader, and more productive solutions to problems can be achieved.

## 15.6 The Reduction of Complexity and Improvement in Rapid Prototyping

The attributes of object-oriented programming—encapsulation, polymorphism, inheritance, and abstraction—make it possible to reduce the complexity of programmatic solutions to problems. Abstraction is especially important as a way of thinking because the efficient reuse of class hierarchies requires acceptance and understanding of conceptualizations. Novice object-oriented programmers often simply subclass **Object** to create a new object. More advanced object-oriented programmers look carefully for (or remember) classes that can be subclassed which will give them more of the needed functionality than simply creating a subclass of **Object**. Hence, understanding the abstract characteristics of a class library and how to make use of the representation and behavioral characteristics of these classes can be a true productivity enhancer. With regard to encapsulation, discussed briefly before, the idea of hiding the internal code of an object is essential. For the most part, one should not need to understand the internal functionality of an object. One needs only to know what will be the behavior of the object when it is sent various messages that activate methods in its protocol. This idea is also a productivity enhancer in the sense that the implementer of a new application does not need to understand any of the encapsulated code that is used (i.e., the inherited class behaviors), only the way the object presents itself to the outside. Polymorphism is the final construct that enhances productivity. By permitting different objects to respond to the same message, polymorphism reduces conceptual complexity and enhances understandability.
## 15.7 Graphics and Visualization

Smalltalk-80 provides excellent graphics and visualization tools. As the original leading environment that employed a rich graphics interface, Smalltalk stimulated the creation of many similar environments such as the Macintosh user interface, Microsoft Windows, and others. Almost without question, the ability to rapidly display graphics and to be able to easily create direct-manipulation interfaces promotes understanding and ease of use of any computer system. The concept of browsing, as formalized in the visually presented classBrowser of Smalltalk, for example, opens code to easy inspection, thereby increasing understandability. Throughout the text, numerous examples of direct-manipulation interfaces have been given in various different engineering fields which illustrate the utility of using graphics-based direct-manipulation interfaces to build engineering applications.

## 15.8 Language and Environment Trends

As discussed previously, arguments about which language is "better" frequently center around the speed of the code produced by the compiler of a language, rather than which language promotes productivity. The reason that arguments of this sort are pinned to speed rather than usability, understandability, and productivity is probably historical rather than based on reason. Indeed, for many years, languages have been gauged in terms of speed; now, however, because computer speeds have increased significantly while costs have plummeted, it is time to refocus on the real use for programming, that is, solving problems! Given such a refocus, it is essential to consider what attributes of languages and environments will likely come to the forefront in the future. If programming is to assist the large number of individuals solving problems, the programming paradigms used should be simple and easily understood and, even more importantly, the environments in which languages are embedded should be completely supportive and nonthreatening to the average user. The present high level of skill needed and the detailed study of programming languages required should completely disappear. The object-oriented paradigm and the environmental qualities manifested in ST-80, when extended and developed, should ultimately fulfill these requirements.

During the upcoming years, a general prediction is that more programming will be conducted using object-oriented methodologies. The current trend seems to be toward adapting standard languages to the paradigm rather than learning "new" languages such as Smalltalk. It may be immaterial which language ultimately becomes a "frontrunner" in the language wars—the paradigm remains the same in all. Once learned, the cognitive methodologies
can be readily transferred between languages. There are interim dangers, however. The adding of object-oriented capabilities to traditional languages does not encourage a paradigm shift, that is, forcing a user to think in an object-oriented style. Hence, it may be difficult to teach the object-oriented methodology to individuals trained in coding procedural code. Students who do not have a long history of procedural coding are able to learn object-oriented methods quickly and fairly easily. Even more impressive is that high school and junior high students can very rapidly understand the tenets of object-oriented methods and write code. This information would tend to point toward introducing more object-oriented methodologies courses in undergraduate engineering education and in high schools where students can learn new programming habits during their formative years.

Another prediction is the growth of environments to facilitate programming. Such environments are partially already in place as discussed in detail in this text. ST-80 certainly has one of the strongest environmental capabilities of any system today.

With regard to the future of ST-80 and other current leading object-oriented languages (e.g., C++, CLOS, etc.), the prediction is that the features and capabilities of the various language contenders will ultimately look more and more alike. This prediction has the potential for becoming true because the target goal for all languages/environments should be the same, that is, facilitating the creation of applications that solve problems! Given that the methods assist in solving problems, all tools should ultimately have similar characteristics.

## 15.9 Near and Long-Term Trends for Object-Oriented Methodologies

Although it is always difficult to predict future developments in any field, there are several conjectures about possible trends for object-oriented methodologies that will be examined next.

Currently, the creation of applications in the style discussed in this text requires the careful consideration of model characteristics, choosing a controller or controllers, and the building of views. A likely trend may well be the continued appearance of systems that assist the user in creating applications. One rudimentary system of this type—ViewBuilder—has been shown to be of great utility in creating views in the examples given in earlier chapters in this text. Extensions of this concept seem likely, probably in the form of systems that assist in building views with extensive capabilities, such as animation, or in organizing and understanding how to specialize class hierarchies.

Knowledge acquisition mechanisms for extending and organizing class hierarchies seem like plausible tools to be added to environments. Imagine
describing a problem, perhaps even in natural language, and receiving prompts about which classes are useful for producing the application or even receiving a skeletal outline of the class organization needed for creating the application. These types of ideas about almost automated programming may be more feasible in an object-oriented environment than in other currently existing paradigms. Program understanding systems for object-oriented methodologies may eventually become widespread. For example, systems that analyze classes used in creating an application and make recommendations about how the application could be improved or reorganized would have considerable utility for application developers. The existence of large, well-formed class libraries makes it possible to believe in the feasibility of creating such object-oriented program understanding and assistant systems.

If object-oriented programming methodologies reach their expected potential, the future should see greatly expanded class libraries that are widely shared and sold. In fact, a subindustry that sells knowledge in the form of class libraries is not a too-far-fetched notion. During the upcoming years, the problem of legal rights for knowledge stored in class libraries will surely be solved in some way. The most likely directions are (1) the licensing of object-hierarchies and (2) the creation of freely shared object libraries.

## 15.10 Concluding Statement

This text has presented the case for the importance of employing object-oriented methodologies for engineering analysis and design. Various concrete and prospective examples have been given. For examples that have not been created, but only outlines given, the intention has been to show the plausibility of the use of object-based techniques throughout the engineering discipline. It is hoped that the material presented will assist both engineering students and practitioners in understanding the role of object-oriented methodologies in engineering analysis and design.

### Exercises

15.1 Prepare a position paper about what you think is the potential for object-oriented methodologies.

15.2 Review the object-oriented languages and environments currently in existence. Determine if these languages and environments show characteristics that are similar to or different from those discussed in this text.
15.3 Trace the development of object-oriented languages and environments during the 1990s.

15.4 Review tools for object-oriented programming assistance that have been created and compare them with the original set of tools delivered with Smalltalk-80. Have these tools changed significantly?

15.5 Determine if any knowledge acquisition and program understanding tools exist for object-oriented systems.

15.6 Catalog object-oriented class libraries that are currently in existence, both for Smalltalk-80 and for other object-oriented languages. How do these libraries augment and extend the libraries described in this text?
# Appendix

The appendix lists additional materials that are available from both the author and the publisher.

I. The Instructor's manual for the text is available from the publishers by writing:

Richard D. Irwin, Inc.
1818 Ridge Road
Homewood, IL 60430-9986
Faculty Service telephone number: 800-323-4560

and requesting the manual. Available also with the manual are either a DOS 5 1/4" floppy disk or a Macintosh disk (3 1/2") that contains the ST-80 code referred to in the text. These materials are available to purchasers of the textbook. Contact the publishers at the preceding address for information about availability and shipping and handling charges.

The contents of the Instructor's Manual are as follows:

A. *Getting Started*. This section of the manual describes alternatives for acquiring and setting up a laboratory for teaching the material in this course.

B. *Planning the Course Structure*. An outline of a course structure is given, including initial handouts, an example exam, and a syllabus that includes the amount of time to be spent on each topic.

C. *Hints, Help, and Information about Using Each Chapter*. A chapter-by-chapter discussion of how each chapter can be presented is
given. Included are the complete solutions for the exercises at the end of each chapter.

### D. Code Printouts:

1. `canvas.st`, Version 2.5

2. `canvas.st`, Release 4

3. `ViewBuilder`, Version 2.5

4. `ViewBuilder`, Release 4

### E. MAC or DOS Disks.
Either DOS or Macintosh disks are available with the following code:

1. `canvas.st` (Version 2.5) and `canvas4.st` (Release 4)

2. `ViewBuilder` classes (both Version 2.5 and Release 4)

3. The simple inference engine (Chapter 11)

4. The CLIPS interface class (Chapter 12)

5. The Petri net example (Chapter 14)

6. The digital circuit simulator (Chapter 10) (Version 2.5 and Release 4 Versions)

7. The Network Representation Language (NRL; Chapter 11) (Version 2.5 and Release 4 Versions)

8. `gauges.st` (Release 4). Gauges derived from the work by Adams (1987). Distributed with permission of Knowledge Systems Corporation.

9. `charts40.st`: A collection of useful chart builders in Release 4.

## II. Copies of enlarged figures are available that are suitable for making overhead transparencies that can be used for lectures.

## III. A version of this text written using only examples in Smalltalk-80, Version 2.5, is available from the author for the cost of duplication and a handling fee. Write: J. Bourne, Box 1570, Station B, Vanderbilt University, Nashville, TN 37235.

### Reference

Adams, S. (1987) *Pluggable Gauges*. Knowledge Systems Corporation, Cary, NC.
Index

Abstract classes, examples of, 246

Abstraction, 245-246

definition of, 19, 24

contrast with generalization, 24

ACOM (see Application/class organization method)

ACOM cards, 52

application organizer card, 53

example, 62

class organizer card, 53

example, 63

class organizer extension card, 54

method description card, 55

example, 66

transferring ACOM example to browser, 129

use in DCS example, 260-261

Active values, 30, 33

Actor, 92, 94

A/D (see Analog to digital converter)

Ada, 88, 91

Adams, Sam, 169, 193, 194, 418n

Advice-giving system, 37-43

architecture, 40-43

AI (see Artificial intelligence)

Algol, 88

Algorithms:

black box, 285

coupling to, 251

definition of, 285

Alternate realities kit, 166-167

American Standard Code for Information Interchange (ASCII), 318

Amplifier, 49

Analog to digital converter (see Laboratory instrumentation)

Analog to digital/digital to analog conversion, 321

Analysis, definition of, 45

general concept, 46

maxims, 56-59

process, 46-51

Analyst, 14, 251

Analytical thinking, 45

AndGate, 60-61

Animation, 147-148

using follow:while:on:, 147

APL, 88, 89

Application, spreadsheet, 138

Application/class organization method (ACOM), 51-56

Application-specific integrated circuits, 382

Applications, engineering:

biomedical 241-245

build-it-yourself method, 179-181

chemical, 235-236

civil, 233-235

creating using ST-80 Environment, 125-130

electrical, 236

environmental, 241

examples of interfacing to the external environment, 329-338

mechanical, 236-237

Pluggable View method for creating, 181, 199

tools for Building, 175-215

ViewBuilder methodology, 181, 203-213

ARK (see Alternate realities kit)

Array, 73

ART, 307

Artificial intelligence (AI), 283

ASCII (see American Standard Code for Information Interchange)

ASIC (see Application-specific integrated circuits)

AT & T, 14

Augusta Ada, Countess of Lovelace, 91

Automatic view building methods (see Applications, ViewBuilder methodology)

Backus, John, 87

Backward chaining, 304-306

Backward compatibility (V.2.5), 148
**Bag**, 74

Bank example, 382

Behavior, 47-48

Binary object storage system (BOSS), 341

Binding:

definition of, 88n

dynamic, definition of, 88n

static, definition of, 88n

Black box, 285

Blocks, use of, 263

**BorderedWrapper**, 179

BOSS (see Binary object storage system)

Browser:

creating a new application with, 125

screen dump, 118

tool, 117

Browsing, term defined, 117

Buttons:

four types, examples of, 162

types of, 114

C, 88, 90

interfacing to, 249, 327-328

C++, 15, 73, 91, 92

CAD (see Computer-aided design)

Capturing images (see Image fromUser), 199

CASM, 389

**Car**, 26

Causality, 33-35

examples, 33-35

half-adder, 34

hot water heater, 34-35

Changed, 72, 177

Changes, 129

condenseChanges, 129

**Character**, 117

Clascal, 89

Class:

definition of, 20

hierarchy V.2.5, 149

hierarchy, Release 4, 116

how to create, 126

library, 116-117

CLIPS, 306, 324

interfacing to, 325-326

CLOS (see Common Lisp object system)

**CodeView**, 187

**Collection**, 117

Color, use of, 145-147

**ColorValue**, 145

Command interpretation distance, 133

Command line interfaces, DOS, UNIX, 135

Common Lisp object system (CLOS), 14, 93

CommonLisp, 89

Communications (computer), 317-322

Compiler:

High-C, 327

MPW C, 327

**CompositePart**, 155

Computer language [see Languages]

Computer peripherals, 316-322

Computer-aided design, 7-9

Computer-aided engineering (CAE), 381

example of tool, 7-8

Computing environment, 109

Conclusions, about object-oriented
methodologies, 409-416

Concurrent recommended reading, 15

Constraint, definition of, 255

Constraint methods, 255-281

concepts, 255-257

Fahrenheit to Centigrade converter,
255-256

local propagation, 257

relaxation methods, 257

Constraint systems, general advice, 279-280

Constraints:

implementation of, 263

in the digital circuit simulator, 354-355

Controller:

design of, 78

objects in, 39-40

Controller maxims, 80

Coupled systems, 249

architecture, 251-253

CP/M, 109

CRC (class-responsibility-collaborator) cards,
51

Cursor icons, 113

Custom interfaces (see Views)

CYC, 285

Daisy System Corporation, 381

DataBase management, object-oriented,
341-342

DCS (see Digital circuit simulator)

Debugger, 123

Debugging:

debugging ST-80 Code, 127

example of, 128

"subscript out of bounds," 128

DEC, 94

Declarative information, definition of, 6

**Delay**, 265, 269, 279, 392, 393, 395

Delays, implementation of, 265

Dependents, 72, 176

Design:

conceptual, 69

implementation, 69

Design scenario example:

for digital circuits, 80

interface methodologies, 81

Desktop, 110

Dictionary, used for representation, 75

**Dictionary**, 74, 79

Digital circuit simulator (DCS):

additions to, 377-378

animation, 352

building the view, 359-360

code, 367-376

creating components, 351

creating wires, 351

encapsulation, 352

example analysis of, 59
example of, 260-273

functionality, 351

images, 357

implementation, 361-363

knowledge organization, 355

operating, 365-366

setting inputs, 351

teleology, 350

visually connecting components, 351

wire, 356

wiring and testing, 269-273

**DigitalCircuitSimulation**, 46, 61

Digitaltalk, 14

Discrete-event model, 395

Disks with code examples, 417

DisplayDemo, example, 199

**DisplayDemo**

Displaying objects, V.2.5, 149-154

animation, 154

forms, 150-151

paths, 152

pen, 152

Displaying pictures (see PictureView example)

displayLineFrom/to, 148

**DisplayObject**, 117

displayPolyLine:at, 145

DOS, 109

Draw-80, 14

Drawing package, 14

**DrawingController**, 195

DrawingView, example, 196-198

**DrawingView**, 195

**EdgeWidgetWrapper**, 179

Edit-compile-debug loop, 104

Eiffel, 92, 94

Encapsulation, definition of, 19, 25

Engineering:

aerospace, 223

agricultural, 223

biomedical, 222

chemical, 222

civil, 222

computer, 222

definition of, 219

education, 223

electrical, 222

environmental, 222

fields, 221

intuition, 220

manufacturing, 223

materials, 223

mechanical, 222

nature of, 4

problem solving framework, 5-6

science and design, 220

Engineering knowledge:

control, 225

definition of, 283-284

domain knowledge, 224

engineering reasoning, 224

laws, algorithms and methodologies, 224

modeling and simulation, 225

models, algorithms, rules, 285-287

presentation and visualization, 225

representing, 283-313

Engineering problem solving system, 4

Error holders, for DOS, UNIX and Mac, 323

External device interfacing, 323

FFT (Fast Fourier transform), 9, 10, 49, 176, 285

File list, 124-125

**FillInTheBlank**, 189

Flavors, 89

programming example, 93

fork, 393

Forms (V.2.5), 190-191

Fortran, 87

Forward chaining, 303-304

ST-80 code, 304-306

Fourier transform (see also FFT), 220

Frame representation, 30

C, 31

history, 289

Lisp, 31

methodology, 290-293

Pascal, 31

Smalltalk, 31

Framework, definition of, 381

fromUser, 192

Fuji, 14, 94

Full-adder, 68

Function, 47-48

definition of, 6

GASP, 388

**GDMI** (*see* Graphics direct manipulation interface)

Gemstone, 341

GemStone, 14

Generalization, 25

GPSS, 388

Graphics contexts, 144, 191

Graphics direct-manipulation interface (GDMI), 139

concrete representations of, 141

evaluation gap, 140

execution gap, 140

Graphics objects, displaying, table of, 145

Graphics user interface and direct-manipulation interface:

definition of, 136

difference between, 137

GREGG, 291

Group work, 333, 342

GUI (see Graphics user interface)

Half-adder, example of, 273

Hierarchical design example, 262

Hierarchical menu, 82

Hierarchical representation (see Knowledge, hierarchical representation)
HP/Apollo, 94

Humble, 14

Hypercard, 84

Hypertext/Hypermedia, 296-300, 310

IBM, 87

Icon:

black image, 366

definition, 9n

dragging, 363-364

white image, 366

Icons, 162-163

building and using, 192

IEEE-488 bus, 11

bus control, example of, 335

digital voltmeter commands, 335

protocol, 321

serial to 488 conversion, 322

Image from User, 199

Images, 119

bit, 119-120

example editor (V2.5), 121-122

experiments with, 146-148

form, 119-120

hierarchy, 191

Inference (see also Rule/production systems),
249-250

Inheritance, 49

definition of, 19, 25

INSIST, 391

Inspectors, 79

using, 198

Instantiation, definition of, 20

Instructor's Manual, 417

Instrumentation interface, example of, 10-11

Interface design, general issues, 159

InterLisp, 104

Interviews, 73, 92

IO Accessor, 323-324

I/O port connections, 336

KBSim, 390

KEE, 307, 309, 388, 390

Keyboard access, 165

Knowledge (see also Engineering knowledge):

acquisition, 308

browsing, 301

captured in tutorial system, 302

chunking, 301

hierarchical representation, 292

organization, 220

representation, 223-226

representing:

procedural and declarative, 288-290

frames in objects, 293-294

types of,

design, 287

simulation, 287

Knowledge organization, 220

Knowledge Systems Corporation, 14, 193

Laboratory instrumentation:

control of, 334

control of A/D, 337

control of D/A, 336

Language (computer) prospectus:

familiarity, 99

graphics issues, 100

learning curve, 102

memory issues, 100

performance issues, 100

portability issues, 101

reusability, 103

task suitability, 99

training issues, 102

user interface issues, 101

Languages:

object-oriented, 87-107

examples, 92

issue summary, 104

procedural, 87

LANs and WANs (local and wide area
networks), 320

LASAR, 340

LaserWriter, Apple, 330

Launcher, 114

LauncherView, 156, 192, 193

Learning systems, 309

Lisp, 88, 89

ListView, 155

Logic, 289

LOGO, 90

LOOPS, 104

MacApp, 70, 72

MacOS, 109

MACSYMA, 259

Magic (see ARK)

Magnitude, 117

Mentor graphics, 381

Menus:

context sensitive, 113

dialogues, 188-189

hierarchical, 161, 190

list, 161

pop-up, 188-189

pull-down, 161

examples of, 160

Message, 24

Method, 24

how to create, 127

Microsoft windows, 112, 328-329

Microsoft software development kit (SDK), 329

Model:

alternative representations, 73

design, 73-76

maxims, 79-80

objects in, 38-39

Model-view-controller, 70-73, 175-181

conceptual framework, 176

controllers, 178

models, 177

views, 178
Modeling (see Simulation)
Models, declarative, 284
  mathematical, 285
  mental, 36, 286
  quantitative, 286
Molgen, 390
Mouse (see also Pointing devices), 113
  buttons, 113
Mousing, learning, 165
MovingObject, 26
MSWindowsInterface, 328
Multics, 109
Multiple independent processes, 391–393
  example of, 392
Multiple inheritance, 27
MVC (see Model-view-controller):
  example view using colors, 195
New product introduction, Petri net example, 278
NewWave, 136
NotGate, 60–61
NRL, 296
  hierarchy, 297
Object, 117
Object, state definition, 50
  behavior 50–51
  general definitions 19, 23
  identification, 48–49
Object-oriented analysis, 45–68
Object-oriented analysis and design,
  introduction to, 3
Object-oriented design, 69–84
Object-oriented engineering, definition of, 3
Objective-C, 14, 91
Objectkit \ Smalltalk, 112, 331
Objects, as a representation paradigm, 290
Objectworks \ Smalltalk (see also Smalltalk, and ST-80), 90
  tutorial, 15
  user's guide, 15, 70, 98, 327
open, 180
Open Desktop, 136
Open method, 180, 183
OpenOn method, 180, 182–184
Operate menu, examples, 157
Operating system:
  definition of, 13
  environment, 109
  IO Classes, 324
OPS5, 306
OrderedCollection, 73, 79
OrGate, 60–61
OS/MVS, 109
OS/2, 109, 136
OS/360, 109
Pagemaker, 82
Paint, 145
Palettes, 147

Parallel interfaces, 320
ParcBench (ParcPlace Systems Bulletin Board), 382, 394n
ParcPlace Systems, 94
Pascal, 88, 89
Pascal, object, 89
Pen (Pen), 149, 152
Pert, 14
Petri net, 14
  use for simulation, 397
  example, 276–279
PictureView example, 201–202
Pluggable gauges, 14, 169, 247
PluggableAdaptor, 186
Pointing devices:
  joysticks, 137
  light pen, 137
  mouse, 137
  new modalities, 138
  tablets, 137
  touchpads, 137
  trackballs, 137
  virtual scenes, 138
Polymorphism:
  definition of, 19, 25
  example of, 28
Pooled dictionary, 126
Pop-up menu, 82, 114
PostScript, 330
Predication, 30
Primitives, 249, 325, 327
Printed circuit board simulation, 397
Probability distributions, 393–394
  types supported in ST-80, 394
Problem solving:
  algorithmic, 219
  concept formation, 226
  constraint satisfaction, 229
  fabrication of result, 230
  heuristic, 219
  problem decomposition, 228
  process diagram, 227
  prototype design, 228
  refinement, 229
  review, 228
  simulation, 229
  steps in, 227
Procedural systems, 289
Procedures, interfacing to, 324
Productivity Products International (see
  Stepstone Co.)
Prolog, 90
Protocol, 24
Pull-down menu, 82
Rapid prototyping:
  analysis phase, 348
  definition of, 345
  design phase, 349
  digital circuit simulator, 346–379
  example, 345–379
  implementation phase, 349
incremental refinement phase, 350
maxims, 347-350

Real World and objects, 315-344
- classes for accessing, 323
- concepts, 315

Representation hierarchy, 25

Representing objects:
- behavior representation, 32
- how to, 28-33
- structural representation, 29

ResourceCoordination, 59

Reusability, 245, 246-247

Reusable classes, examples of, 247

Ritchie, Dennis, 91

RMG user interface, 169

Robot, 330

Rule/production systems, 286, 289, 303-308, 386

Running ST-80 code, 127

Scheduledcontrollers, example, 146

ScheduledWindow, 156, 179, 182

Schneiderman, Ben, 136

Screen interpretation distance, 133

Scripts, 289
- implementing, 294

ScrollingView, 156

SDK (see Microsoft Software Development Kit)

Self changed (see Changed)

self changed, 72

Semantic, definition of, 289

Semantic network, 74, 289
- example, 29
- implementing, 295

SequenceableCollection, 73

Serial interfaces, 318

Serial port:
- DOS utilization, 332
- example of use, 330
- Unix utilization, 332

Serpent, 70n, 72

Set, 74

SharedQueue, 392

Signal analysis, example of, 9-10

SIMBIOS, 391

SimFlex, 391

SimKit, 388, 389

Simscript, 388

Simula, 89, 90, 388

Simulation:
- and AI, 389
- and object-oriented methodologies, 390
- continuous, 383-384
  - examples of, 386
- contrast with modeling, 36
- coupling to, 251
- definition of, 381
- discrete, 383-384
- discrete-event, examples of, 386
- engineering, 381-407
- event-driven, 385
- example uses, 383

example of manufacturing cell, 170

fixed-interval-time, 385

flexible manufacturing, 398-403
framework, 397

hierarchy, 397

object-oriented, 12

qualitative, 383-384
- definition of, 387
- types of, 308

quantitative, 383-384
- definition of, 387
- types of, 387

traffic planning, 13, 22
using Petri nets, 397

Simulation.st, 396

SKETCHPAD, 257

Smalltalk:
- class hierarchy (Release 4), 114
- common display objects, 141, 142
- interfacing to C, 327-328
- interfacing to Microsoft windows, 328

Smalltalk/V, 12, 14, 91, 94
comparison with ST-80, 213

Smalltalk environment, 95, 109-131
characteristics, 114
- classes, 103
- components of (Release 4), 110
- Release 4, 112

saving, 129
screen dump, 111
Version 2.5, 112

Smalltalk language:
- blocks, 98, 263
- constructions, 96
- global dictionary, 96
- iteration, 98
- literals, 96
- messages, 97
- origins, 12
- revisions, 112
- syntax, 95-98

Smith, R., 166, 173

Sockets, 340

Software engineering, waterfall model, 284

SortedCollection, 73

ST-80 (see Smalltalk, and Objectworks)

startUp, 79

Stats.st, 394

Steamer, 257
- example of, 260

Stepstone Co., 14, 92

Storyboards, 248, 348

Stream, 117

Stroustrup, B., 92

Structure, 47-48
- definition of, 6

SUN, 94

SunTerminal, 331

Sutherland, Ivan, 257

Symbolics Lisp Machine, 93

System creation:
- design frameworks, 232
- inference, 232
knowledge organization, 232
refinement, 232

Tangled hierarchies (see also Multiple inheritance), 292

Tektronix, 94
Teleology, 47-48

Teradyne, 340
Terminal interfaces, 331, 332

TextCollector, global, 164

TextCollectorView, 187

Text editor, 118

TextEditor, 163-164
ThingLab, 257

example, 259

Time, representing, 35, 384-385

TK!Solver, 257

Tools for object-oriented engineering, 12-14

Traditional application building,
coupling to, 246-253

Traffic simulation, example of, 13, 233-235

Tutorial system, a digital circuit simulator,
273-276

TwoInputGate, 61
Typed:

definition of, 88n

strongly, definition of, 88n

weakly, definition of, 88n

UNIX, 90, 109
Untyped, definition of, 88n

Update, 79, 177

update:, 257

User interface software, 138-139

User interfaces:
contents, 136

definition of, 133

design, 133-173

graphics, 135

primitive, 134-135

Valid logic, 381

VCircuitSimView, 127

Video interface, 169, 171

View:
compiler, 77-78
design of, 76-78
library, 77
maxims, 80
objects in, 40-41
operations,

basic view types, 156
displaying, 158

View, 117

View builder interface, 77

ViewBuilder (see Applications, engineering:
ViewBuilder methodology)

View framework, examples, 181-183

Views:
Bar gauge, 194
Buttons and switches, 186-187
capabilities of the ST-80 user interface, 166
creating, 183-184
custom interfaces, 166
literalism and magic, 166
room metaphor, 168
graphically tailoring, 165
loader, 190
selection-in-list, 184-185
transcripts and text editors, 187

Virtual machine, 36

Visual component hierarchy, 144
CompositePart, 143
DependentPart, 143
DialogView, 143
EdgeWidget, 143
Image, 143
View, 143
VisualComponent, 143
VisualPart, 143

Visual display methods, 143-148

VMS, 109

VT100Terminal, 331

Whole-part hierarchies, 30-32
example, 32

Widget, 143

Windows and views, concepts, 154

Wire, 60-61
example code, 266-268

Workspace:
system, 123
use, 129

Wrapper:
example, 340
software, 338-340

Wrapper, 143, 144

X-Windows, 72, 136

Xerox, 12, 14, 94
Images have been losslessly embedded. Information about the original file can be found in PDF attachments. Some stats (more in the
PDF attachments):

```json
{
    "filename": "T2JqZWN0LU9yaWVudGVkIEVuZ2luZWVyaW5nXzQwMDUzNTUwLnppcA==",
    "filename_decoded": "Object-Oriented Engineering_40053550.zip",
    ">Main_size": 36280176,
    "md5": "3ed4b5bd557291640e2e05030f08d867",
    "header_md5": "79fcb5ce3e56a8557bf6b1f9d5154e5b",
    "sha1": "595a2d8edc43c035bf81a77c9e4a999496286644",
    "sha256": "400cd2db8b5efcc1b7d9e9b49d9fa009cd5c6cfcc3d5b7e37f19761e6e0bb95d",
    "crc32": 2168942133,
    "zip_password": "52gv",
    "uncompressed_size": 39985322,
    "pdg_dir_name": "Object-Oriented Engineering_40053550",
    "pdg_main_pages_found": 425,
    "pdg_main_pages_max": 425,
    "total_pages": 441,
    "total pixels": 2573598721,
    "pdf_generation_missing_pages": false
}
```