RFC 5

Decode Encode Language (DEL)

๐Ÿ“… published June 1969, from ietf

DEL ๐Ÿ’–

:DEL, 02/06/69 1010:58 JFR ; .DSN=1; .LSP=0; ['=] AND NOT SP ; ['?]; dual transmission?

Okay bestie, the title block is giving old-school ARPANET. โœจ It's an RFC from the Network Working Group, and the number printed in the corner is 4691. The author is Jeff Rulifson, and the date is June 2, 1969. The header doesn't list a category, and it doesn't say this one obsoletes or updates anything, so I'm not adding that. ๐Ÿฆ‹


Abstract ๐ŸŒธ

Okay so the Decode-Encode Language (DEL) is a machine-independent language built for two specific network jobs. ๐Ÿ’…

  • It accepts input codes from interactive consoles, gives immediate feedback, and packs the results into message packets for network transmission.
  • It accepts message packets from another computer, unpacks them, builds trees of display information, and sends other information to the user at their interactive station.

This is a working document for evolving the DEL language. Comments go to Jeff Rulifson at SRI. ๐Ÿงš


Forward ๐ŸŽ€

The initial ARPA network working group met at SRI on October 25-26, 1968. Everyone was basically agreed beforehand that running interactive programs across the network was going to be the first problem they had to face. ๐Ÿ‘‘

This group already agreed on the underlying ideas behind a DEL-like approach. They set some terminology, expectations for DEL programs, and lists of proposed semantic capabilities. Attendees were Andrews, Baray, Carr, Crocker, Rulifson, and Stoughton. ๐Ÿซถ

A second round of meetings happened in a more piecemeal way. Crocker met with Rulifson at SRI on November 18, 1968, and that resulted in formal co-routines being added. Stoughton met with Rulifson at SRI on December 12, 1968. They decided to meet again as a group, probably at UTAH, in late January 1969. ๐ŸŒˆ

The first public release of this paper was at the BBN NET meeting in Cambridge on February 13, 1969. ๐Ÿ’œ


NET Standard Translators โœจ

NST is the NST library: the set of programs needed to mesh efficiently with the code compiled at user sites from the DEL programs it receives. The NST-DEL approach to NET interactive system communication is meant to work across a broad spectrum. ๐ŸŒ

The lowest level of NST-DEL usage is direct transmission to the server-host. The information is in the same format user programs would receive at the user-host. ๐Ÿ“

  • In this mode, the NST defaults to inaction. The DEL program doesn't receive universal hardware representation input. It gets input the normal way for the user-host.
  • The DEL 1 program becomes merely a message builder and sender. ๐Ÿ’…

A more intermediate use of NST-DEL is to have echo tables for a TTY at the user-host. ๐Ÿฆ‹

  • In this mode, the DEL program runs a full duplex TTY for the user.
  • It echoes characters, translates them to the character set of the server-host, packs the translated characters into messages, and on appropriate break characters sends the messages.
  • When messages come from the server-host, the DEL program translates them to the user-host character set and prints them on the user's TTY. ๐ŸŒธ

A more ambitious task for DEL is running large, display-oriented systems from remote consoles over the NET. ๐Ÿ”ฅ

Large interactive systems usually offer a lot of feedback to the user. The unusual nature of that feedback makes it impossible to model with an echo table, so a user program has to be activated in a TSS every time a button state changes. ๐Ÿ™ˆ

  • That puts an unnecessarily large load on a TSS. If the system is run through the NET, it could easily load two systems.
  • To avoid this double overloading of the TSS, a DEL program runs on the user-host. It handles all the immediate feedback, kind of like a complicated echo table. At appropriate button pushes, a message goes to the server-host and display updates come back. โœจ

One of the more difficult, and often neglected, problems is effectively simulating one nonstandard console on another nonstandard console. ๐Ÿ˜ญ

We try to solve this with the co-routine structure of DEL programs. For complicated interactive systems, part of the DEL programs will be built by the server-host programmers. Interfaces between this program and the input stream can easily be inserted by programmers at the user-host site. ๐Ÿงš


Universal Hardware Representation ๐ŸŒˆ

To minimize the number of translators needed to map any facility's user codes to any other facility, there's a universal hardware representation. ๐Ÿ’–

It's basically a way of talking, in general terms, about all the hardware devices at all the interactive display stations in the initial network. ๐ŸŽ€

For example, a display is thought of as a square. The midpoint has coordinates (0.0), and the range is -1 to 1 on both axes. A point can now be specified to any accuracy, no matter the particular number or density of raster points on a display. โญ

The representation is discussed in the semantic explanations that come with the formal description of DEL. ๐Ÿซถ


Introduction to the Network Standard Translator (NST) ๐Ÿฆ‹

Suppose a user at a remote site, say Utah, is entered in the AHI system and wants to run NLS. ๐ŸŒธ

The first step is to enter NLS the normal way. At that point, the Utah system requests a symbolic program from NLS. ๐Ÿ’…

  • This program is written in DEL. It's called the NLS Remote Encode Program (REP).
  • It accepts input in the Universal Hardware Representation and translates it into a form NLS can use.
  • It may pack characters in a buffer, and it can also do some local feedback. ๐Ÿ‘‘

When the program is first received at Utah, it's compiled and loaded to run alongside a standard library. ๐Ÿ”ฅ

All input from the Utah console first goes to the NLS NEP. It gets processed, parsed, blocked, translated, and so on. When NEP receives a character that's appropriate to its state, it may finally initiate transfers to the 940. ๐Ÿ“

The bits transferred are in a form acceptable to the 940. They may also be in a standard form, so the NLSW doesn't need to tell apart Utah from other NET users. ๐ŸŒˆ


Advantages of NST ๐Ÿ’œ

After each node has implemented the library part of the NST, it only needs to write one program per subsystem: the symbolic file it sends to each user. That file maps the NET hardware representation into the node's own special bit formats. โœจ

  • This is the minimum programming you can expect if the console is used to its fullest extent. ๐Ÿงš
  • Since the NST that runs the encode translation is coded at the user site, it can take full advantage of hardware at its consoles. It can also add or remove hardware features without needing new or different translation tables from the host. ๐Ÿ’–
  • Local users also stay up to date on any changes in the system offered at the host site. As new features get added, the host programmers change the symbolic encode program. When that new program is compiled and used at the user site, the new features are automatically included. ๐ŸŽ€

The advantages of having the encode translation programs transferred symbolically should be obvious. ๐Ÿฆ‹

  • Each site can translate any way it sees fit, so machine code for each site can be produced to fit that site. Faster run times and greater code density will be the result. ๐ŸŒธ
  • Extra symbolic programs, coded at the user site, can also be easily interfaced between the user's monitor system and the DEL program from the host machine. This should ease the problem of console extension (for example, accommodating unusual keys and buttons) without losing the flexibility needed for man-machine interaction. ๐Ÿ‘‘

It's expected that when there's matching hardware, the symbolic programs will take that into account and avoid any unnecessary computing. This is immediately possible through the code translation constructs of DEL. It may someday be possible through program composition (when Crocker tells us how??) ๐Ÿ˜ญ


AHI NLS - User Console Communication - An Example ๐ŸŒˆ

Block Diagram ๐Ÿ”ฅ

The right side of the picture represents functions done at the user's main computer. The left side represents those done at the host computer. ๐Ÿซถ

  • Each label in the picture corresponds to a statement with the same name.
  • There are four trails associated with this picture. The first links (in a forward direction) the labels concerned only with network information. The second links the total information flow (again in a forward direction). The last two are equivalent to the first two but in a backward direction. They may be set with pointers t1 through t4 respectively. ๐Ÿงš
[">tif:] OR I" >nif"]; ["<tif:] OR ["<nif"];

User-to-Host Transmission ๐Ÿ’…

Keyboard is the set of input devices at the user's console. Input bits, after drifting through levels of monitor and interrupt handlers, eventually come to the encode translator. [>nif(encode)] ๐ŸŽ€

Encode maps the semi-raw input bits into an input stream in a form suited to the serving-host subsystem that will process the input. [>nif(hrt)<nif(keyboard)] ๐Ÿ’–

  • The Encode program was supplied by the server-host subsystem when the subsystem was first requested. It's sent to the user machine in symbolic form and compiled at the user machine into code particularly suited to that machine.
  • It may pack to break characters, map multiple characters to single characters and vice versa, do character translation, and give immediate feedback to the user. โœจ

1 dm Immediate feedback from the encode translator first goes to local display management, where it's mapped from the NET standard to the local display hardware. ๐ŸŒธ

  • A wide range of echo output may come from the encode translator. Simple character echoes would be a minimum, while command and machine-state feedback will be common. ๐Ÿฆ‹
  • It's reasonable to expect control and feedback functions that aren't even done at the server-host user stations to be done in local display control. For example, people with high-speed displays may want to selectively clear curves on a Culler display, which is impossible on a storage tube. ๐ŸŒˆ

Output from the encode translator for the server-host goes to the invisible IMP. It's broken into appropriate sizes, labeled by the encode translator, and then goes to the NET-to-host translator. ๐Ÿ“

  • Output from the user may be more than online input. It may be larger items, like computer-generated data, or files generated and used exclusively at the server-host site but stored at the user-host site.
  • Information of this kind may avoid translation if it's already in server-host format. Or it may undergo yet another kind of translation if it's a block of data. ๐Ÿ‘‘

hrp It finally gets to the host, and then has to go through the host reception program. This program maps and reorders the standard transmission-style packets of bits sent by the encode programs into messages acceptable to the host. It may well be part of the host machine's monitor. [>tif(net mode)<nif(code)] ๐Ÿ’œ

HOST-TO-USER TRANSMISSION โœจ

decode ๐ŸŽ€

Okay bestie, output from the server-host goes through decode first. It's a translation map that's kinda like the encode map, except maybe even more complicated ๐Ÿ’€ [>nif(urt)>tif(imp ctrl)<tif(net mode)]

This map at least formats display output into a simplified logical-entity output stream. The meaningful pieces can then be handled in different ways at the user site ๐Ÿ’…

The Decode program is sent to the host machine at the same time the Encode program is sent to the user machine. It starts out in symbolic form and gets compiled for efficient running at the host machine ๐Ÿงš

Lines of characters should be logically identified, so that different line widths can be handled at the user site ๐Ÿ“

Some form of logical line identification also has to happen. Say a straight line is going across the display. You should send that fact, instead of a series of 500 short vectors ๐Ÿฆ‹

As things firm up, more and more complicated structural display info (in the manner of LEAP) should be sent and accommodated at user sites. That way the responsibility for real-time display manipulation can shift closer to the user ๐Ÿ‘‘

imp ctrl

The server-host may also want to send control info to IMPs. The host decoder handles the formatting for that ๐Ÿซถ [>tif(urt) <tif(decode)]

The other control info that the host decoder supplies is message break up and identification. That's what lets proper assembly and sorting happen at the user site ๐Ÿงฉ

From the host decoder, info goes to the invisible IMP and directly to the NET-to-user translator. The only thing done to the messages is that they may be shuffled ๐Ÿ”€

urt

The user reception translator accepts messages from the user-site IMP 1 and fixes them up for user-site display โœจ [>nif(d ctrl)>tif(prgm ctrl)<tif(imp ctrl)<nif(decode)]

The minimal action is reordering the message pieces ๐ŸŒธ

dctrl

For display output, though, more needs to be done ๐Ÿ˜ญ The NET logical display info has to be put into the format of the user site. Display control is the one who does this job. Since it coordinates between (encode) and (decode), it can offer display management features that are local to the user site ๐Ÿ’– [>nif(display)<nif(urt)]

prgmctrl

Another action is the selective translation and routing of info to particular user-site subsystems ๐Ÿš€ [>tif(dctrl)<tif(urt)]

For example, blocks of floating-point info may get converted to user-style words and sent, in block form, to a subsystem for processing or storage ๐Ÿ”ข

The styles and translation of this info may well be a compact binary format that's suitable for quick translation, rather than a print-image-oriented format ๐Ÿ’œ

(display)

(display) is the output to the user ๐Ÿ–ฅ๏ธ [<nif(d ctrl)]


USER-TO-HOST INDIRECT TRANSMISSION ๐Ÿฆ‹

(net mode)

This is the mode where a remote user can link to a node indirectly, through another node ๐ŸŒˆ [<nif(decode)<tif(hrt)]


DEL SYNTAX ๐Ÿ’…

NOTES FOR NLS USERS

All statements in this branch that aren't part of the compiler must end with a period ๐Ÿซถ

To compile the DEL compiler, start by setting this pattern for the content analyzer:

( (symbol for up arrow)P1
SE(P1) <-"-;).

The pointer "del" is on the first character of the pattern. Next, jump to the first statement of the compiler. The pointer "c" is on this statement. Then output the compiler to the file ( '/A-DEL' ). The pointer "f" is on the name of the file for the compiler output -

PROGRAMS ๐ŸŽ€

SYNTAX

-meta file (k=100.m=300,n=20,s=900)

file = mesdecl $declaration $procedure "FINISH";

procedure =

  procname (

     (

        type "FUNCTION" /

        "PROCEDURE" ) .id (type .id / -empty)) /

     "CO-ROUTINE") ' /

  $declaration labeledst $(labeledst ';) "endp.";

labeledst = ((left arrow symbol).id ': / .empty) statement;

type = "INTEGER" / "REAL" ;

procname = .id;

Functions are differentiated from procedures so compilers can produce better code and run time checks ๐Ÿง 

Functions return values ๐Ÿ’ซ

Procedures do not return values ๐Ÿ™…โ€โ™€๏ธ

Co-routines don't have names or arguments. Their initial invocation points are given the pipe declaration ๐Ÿงš

It is not clear just how global declarations are to be?? ๐Ÿ’€


DECLARATIONS ๐ŸŒธ

SYNTAX

declaration = numbertype / structuredtype / label / lcl2uhr /
uhr2rmt / pipetype;

numbertype = : ("REAL" / "INTEGER") ("CONSTANT" conlist /
varlist);

conlist =

   .id '(left arrow symbol)constant

   $('. .id '(left arrow symbol)constant);

varlist =

   .id ('(left arrow symbol)constant / .empty)

   $('. .id('(left arrow symbol)constant / .empty));

idlist = .id $('. .id);

structuredtype = (tree" / "pointer" / "buffer" ) idlist;

label = "LABEL1" idlist;

pipetype = PIPE" pairedids $(', pairedids);

pairedids = .id .id;

procname = .id;

integerv = .id;

pipename = .id;

labelv = .id;

Variables declared to be constant may be put in read-only memory at run time ๐Ÿ”’

The label declaration declares cells that may contain the machine addresses of labels in the program as their values. This is not the B5500 label declaration ๐Ÿท๏ธ

In the pipe declaration, the first .ID of each pair is the name of the pipe, and the second is the initial starting point for the pipe ๐Ÿšฐ


ARITHMETIC ๐Ÿงฎ

SYNTAX

exp = "IF" conjunct "THEN" exp "ELSE" exp;

sum = term (

   '+ sum /

   '- sum /

   -empty);

term = factor (

   '* term /

   '/ term /

   '(up arrow symbol) term /

   .empty);

factor = '- factor / bitop;

bitop = compliment (

   '/' bitop /

   '/'\ bitop /

   '& bitop / (

   .empty);

compliment = "--" primary / primary;

(symbol for up arrow) means mod, and /\ means exclusive or ๐Ÿ”ฅ

Notice that the unary minus is allowable and gets parsed, so you can write x*-y ๐Ÿ’…

Since there's no standard convention with bitwise operators, they all have the same precedence, so parentheses must be used for grouping ๐Ÿ™ˆ

Compliment is the l's compliment ๐ŸŒˆ

It is assumed that all arithmetic and bit operations take place in the mode and style of the machine running the code. Anyone who takes advantage of word lengths, two's compliment arithmetic, etc. will eventually have problems. ๐Ÿ’€


PRIMARY ๐ŸŽ€

SYNTAX

primary =

   constant /

   builtin /

   variable / (

   block /

   '( exp ');

variable = .id (

   '(symbol for left arrow) exp /

   '( block ') /

   .empty);

constant =  integer / real / string;

builtin =

   mesinfo /

   cortnin /

   ("MIN" / "MAX") exp $('. exp) '/ ;

Parenthesized expressions may be a series of expressions. The value of a series is the value of the last one executed at run time ๐Ÿงพ

Subroutines may have one call by name argument ๐Ÿ“ž

Expressions may be mixed. Strings are a big problem? Rulifson also wants to get rid of real numbers!! ๐Ÿ˜ญ


CONJUNCTIVE EXPRESSION ๐Ÿ’œ

SYNTAX

conjunct = disjunct ("AND" conjunct / .empty);

disjunct = negation ("OR" negation / .empty);

negation = "NOT" relation / relation;

relation =

   '( conjunct ') /

   sum (

     "<=" sum /

     ">=" sum /

     '< sum /

     '> sum /

     '= sum /

     '" sum /

     .empty);

The conjunct construct is rigged so that a conjunct which isn't a sum doesn't need to have a value. It can be evaluated using jumps in the code ๐Ÿฆ˜ Reference to the conjunct is only made in places where a logical decision is called for (like if and while statements) ๐Ÿค“

We hope most compilers will be smart enough to skip unnecessary evaluations at run time ๐Ÿง  So a conjunct whose left part is false, or a disjunct whose left part is true, doesn't need to have its right part evaluated โœจ


ARITHMETIC EXPRESSION ๐ŸŒท

SYNTAX

statement = conditional / unconditional;

unconditional = loopst / cases / cibtrikst / uist / treest /
block / null / exp;

conditional = "IF" conjunct "THEN" unconditional (

   "ELSE" conditional /

   .empty);

block = "begin" exp $('; exp) "end";

An expression may be a statement ๐Ÿ™Œ In conditional statements the else part is optional, while in expressions it's mandatory. This is a side effect of the way the left parts of the syntax rules are ordered ๐Ÿซ 


SEMI-TREE MANIPULATION AND TESTING ๐ŸŒณ

SYNTAX

treest = setpntr / insertpntr / deletepntr;

setpntr = "set" "pointer" pntrname "to" pntrexp;

pntrexp = direction pntrexp / pntrname;

insertpntr = "insert" pntrexp "as"

   (("left" / "right") "brother") /

   (("first" / "last: ) "daughter") "of" pntrexp;

direction =

   "up" /

   "down" /

   "forward" /

   "backward: /

   "head" /

   "tail";

plantree = "replace" pntrname "with" pntrexp;

deletepntr = "delete: pntrname;

tree = '( tree1 ') ;

tree1 = nodename $nodename ;

nodename = terminal / '( tree1 ');

terminal = treename / buffername / point ername;

treename = id;

treedecl = "pointer" .id / "tree" .id;

Extra parentheses in tree building result in linear subcategorization, just like in LISP ๐ŸŽ€


FLOW AND CONTROL ๐Ÿฆ‹

controlst = gost / subst / loopstr / casest;

GO TO STATEMENTS

gost = "GO" "TO" (labelv / .id);

   assignlabel = "ASSIGN" .id "TO" labelv;

SUBROUTINES

subst = callst / returnst / cortnout;

   callst = "CALL" procname (exp / .emptyu);

   returnst = "RETURN" (exp / .empty);

   cortnout = "STUFF" exp "IN" pipename;

cortnin = "FETCH" pipename;

FETCH is a builtin function whose value is computed by invoking the named co-routine ๐Ÿ“ฌ

LOOP STATEMENTS ๐Ÿ”

SYNTAX

loopst = whilest / untilst / forst;

whilest = "WHILE" conjunct "DO" statement;

untilst = "UNTIL" conjunct "DO" statement;

forst = "FOR" integerv '- exp ("BY" exp / .empty) "TO" exp

"DO" statements;

The value of while and until statements is defined to be false and true (or 0 and non-zero) respectively ๐ŸŽฏ

For statements evaluate their initial exp, the by part, and the to part once, at initialization time. The running index of a for statement can't be changed within the loop. It can only be read ๐Ÿ‘€ If some compilers can take advantage of this (say, by putting it in a register), all the better ๐Ÿƒโ€โ™€๏ธ The increment and the to bound are both rounded to integers during initialization ๐Ÿ”ข

CASE STATEMENTS ๐ŸŽ€

SYNTAX

casest = ithcasest / condcasest;

ithcasest = "ITHCASE" exp "OF" "BEGIN" statement $(';
statement) "END";

condcasest = "CASE" exp "OF" "BEGIN" condcs $('; condcs)
"OTHERWISE" statement "END";


condcs = conjunct ': statement;

The value of a case statement is the value of the last case executed ๐ŸŒŸ


EXTRA STATEMENTS ๐Ÿงš

null = "NULL";

I/O STATEMENTS โœจ

okay so this is where the I/O statements come in, and they're giving very organized energy ๐Ÿ’…

iost = messagest / dspyst ;

MESSAGES ๐Ÿ’Œ

SYNTAX

bestie, the message statements have a whole grammar. I'm keeping every line exactly as it is ๐Ÿซถ

messagest = buildmes / demand;

  buildmest = startmes / appendmes / sendmes;

    startmes = "start" "message";

    appendmes = "append" "message" "byute" exp;

    sendmes = "send" "message";


  demandmes = "demand" "Message";

mesinfo =

  "get" "message" "byte"

  "message1" "length" /

  "message" empty: '?;

mesdecl = "message" "bytes" "are" ,byn "bits" long" '..

DISPLAY BUFFERS ๐Ÿ–ผ๏ธ

SYNTAX

display buffers have their own grammar and it's so pretty ๐ŸŒธ all copied exactly:

dspyst = startbuffer / bufappend / estab;

startbuffer - "start" "buffer";

bufappend = "append" bufstuff $('& bufstuff);

bufstuff = :

  "parameters" dspyparm $('. dspyparm) /

  "character" exp /

  "string"1 strilng /

  "vector" ("from" exp ':exp / .empty) "to" exp '. exp /

  "position" (onoff / .empty) "beam" "to" exp '= exp/

  curve" ;

dspyparm F :

  "intensity" "to" exp /

  "character" "width" "to" exp /

  "blink" onoff /

 "italics" onff;

onoff = "on" / "off";

estab = "establish" buffername;

LOGICAL SCREEN ๐Ÿฆ‹

okay so the screen is taken to be a square โœจ and the coordinates are normalized from -1 to +1 on both axes. so everything lives inside that little box, it's so neat ๐Ÿ“

there's a position register attached to the screen, called PREG ๐Ÿงš. it's a triple <x.y.r> where x and y specify a point on the screen, and r is a rotation in radians, counter clockwise, from the x-axis. main character energy for the rotation ๐Ÿ”„

the intensity, called INTENSITY, is a real number in the range from 0 to 1 ๐Ÿ’œ. 0 is black, 1 is as light as your display can go, and numbers in between specify the relative log of the intensity difference. literally so pretty โœจ

character frame size. ๐ŸŽ€

blink bit. ๐Ÿ’€

BUFFER BUILDING ๐Ÿงฑ

the terminal nodes of semi-trees are either semi-tree names or display buffers ๐ŸŒˆ. a display buffer is a series of logical entities, called bufstuff. bufstuff is the building block, lowkey iconic.

when the buffer is initilized, it is empty ๐Ÿซง. if no parameters are initially appended, then those in effect at the end of the display of the last node in the semi-tree will be in effect for the display of this node. so it carries the vibe forward, it's giving continuity ๐Ÿ’–

as the buffer is built, the logical entities get added to it โœจ. when it is established as a buffername, the buffer is closed, and further appends are prohibited ๐Ÿ”’. it is only after a buffername has been established that it may be used in a tree building statement. not before, bestie, no shortcuts ๐Ÿ™ˆ

LOGICAL INPUT DEVICES ๐ŸŽฎ

  • Wand ๐Ÿช„
  • Joy Stick ๐Ÿ•น๏ธ
  • Keyboard โŒจ๏ธ
  • Buttons ๐Ÿ”˜
  • Light Pens โœ๏ธ
  • Mice ๐Ÿญ

AUDIO OUTPUT DEVICES ๐Ÿ”Š

.end


SAMPLE PROGRAMS ๐ŸŒŸ

Program to run display and keyboard as tty. ๐Ÿ’ป

to run NLS, it's a whole program and it's so iconic ๐Ÿ‘‘

input part

display part

   DEMAND MESSAGE;

   While LENGTH " O DO

      ITHCASE GETBYTE OF Begin

      ITHCASE GETBYTE OF %file area uipdate% BEGIN

         %literal area%

         %message area%

         %name area%

         %bug%

         %sequence specs%

         %filter specs%

         %format specs%

         %command feedback line%

         %filer area%

         %date time%

         %echo register%

     BEGIN %DEL control%

DISTRIBUTION LIST ๐Ÿ“ฌ

the people behind this, all copied exactly, because they deserve the credit ๐Ÿซถ

Steve Carr
   Department of Computer Science
   University of Utah
   Salt Lake City, Utah  84112
   Phone 801-322-7211 X8224

Steve Crocker

   Boelter Hall
   University of California
   Los Angeles, California
   Phone 213-825-4864

Jeff Rulifson

   Stanford Research Institute
   333 Ravenswood
   Menlo Park, California  94035
   Phone 415-326-6200 X4116

Ron Stoughton

   Computer Research Laboratory
   University of California
   Santa Barbara, California  93106
   Phone 805-961-3221

Mehmet Baray

   Corey Hall
   University of California
   Berkeley, California  94720
   Phone 415-843-2621
๐Ÿ“ฆ where this page comes from