CSE 230: Principles of Programming Languages
An OBJ3 Survival Guide
OBJ3 is not a programming language as such (though it can be used as one), and
it may well be quite different from anything you have used before. In this
case, it will take some effort to get used to it, and you cannot expect your
experience to be very much like that of using C, Java, Pascal, or even ML and
Prolog; you will need to develop some slightly different skills.
- OBJ3 is an interpreter, which means you can use it interactively.
However, this is usually not a very good idea, because you are likely to make
typing errors. Hence it is better to use it more as if it were a compiler,
and input specs, reductions, etc. by reading a pre-prepared file into a
running OBJ3. You will then debug that file iteratively, by inspecting the
OBJ3 output, modifying the input, and running it again. It is most convenient
to do this using a powerful editor (such as emacs, though any editor with
comparable capabilities would be equally good), in which you can have one
buffer for the input file and another for the output file, with the latter
running in shell mode.
- A sufficiently powerful editor will also allow you to easily find a
character position in your input file, and to search the output file buffer.
The former is sometimes called for by OBJ3 error messages, and the latter can
be useful, for example, when a large output file is produced by a trace. A
sufficiently powerful editor also makes it easier to save output files. OBJ3
was actually designed to be used with a powerful editor having such
capabilities.
- OBJ3 is a term rewriting engine. Its main use is for specification and
verification, i.e., for theorem proving (though it is also useful in certain
programming situations, such as prototyping and small one-time applications).
This gives it a very different character from most programming languages. In
particular, every computation is a proof, because it is a sequence of valid
applications of an inference rule of equational logic. Many features of an
ordinary programming language are absent precisely because they would violate
this logical soundness.
- Because OBJ3 has user-definable mixfix subsorted syntax, it has an
extremely sophisticated parser for terms. Because it is impossible for a
parser of this kind to always provide very specific error messages when it
fails, you may have to be clever yourself sometimes.
- Because almost anything can be a lexical item, the parser requrires spaces
between lexical items; the only exceptions are certain "special characters",
which include
, ( ) [ ] { }
but not ".". Because many commands and
declarations end with a period, that period must therefore be preceeded by a
space, unless the previous character is a special character. (This is one of
the most common errors that OBJ3 beginners make.) Also, due to the special
role of the period, it is dangerous to use periods in user-defined operator
syntax.
- The remarks above about period are a special case of how lexical items,
spaces and special characters work in OBJ3. Thus "2+2" will be seen as a
single lexical item, which (presumably) is not defined; to get the usual parse
of this this, write "2 + 2", or because of the rules about special characters,
"(2)+(2)"; however, "2(+)2" will not work, because parentheses must enclose
well formed subterms. The other special characters cannot be used to delimit
subterms in this way, but they can still obviate spaces. For example, if
"_[_]" is a defined operator (with a suitably tight precedence), then "A[2]+
2" is ok, but not "A[2]+2"; similarly, "A[2]+(2 * 2)" is ok, but of course,
"[2 + 2]" is bad.
- If you fail to declare a variable (or mispell it, either in its
declaration or in its use), then your output will contain instances of the bad
item inside of _[ ]_ pairs, often along with other stuff. The same
will happen for operations that you either fail to declare or mispell.
- If you ask OBJ3 to do a nonterminating computation, you will get "Error:
Value stack overflow." along with some other stuff that you can ignore (it is
also possible to give OBJ3 a really huge computation that will produce the
same message, but beginners are unlikely to do this).
- Formal verification is difficult for humans, and at first can look very
strange; informal proofs never give so many low level details, for the very
good reason that they impede understanding; and as usual, things that are
"obvious" to people are often not at all obvious to a computer program. So
many difficulties with using OBJ3 to do proofs have nothing to do with OBJ3.
- If you want to use emacs, here are some hints: there are two versions, of
which xemacs (which is available on Suns
at UCSD) seems to be the best. To go to character position N using emacs,
first go to the top of the file (with [meta-x]<), then type [C-u]N[C-f]
(where N is some number, such as 329). To open a unix shell buffer, type
[meta-x]shell; this shell can be saved with [C-x][C-w]file (where "file" is
the file name) the first time (to create the file), and [C-x][C-s] thereafter.
Note that "[C-x]" means press control and x keys at the same time. You can
also get online psychiatric help, by typing [meta-x]doctor :-)
(Note: I'm not trying to get you to use emacs; if you can get Word or vi to do
the same tricks, more power to you!)
- The OBJ prompt is "OBJ>". If the file you want to run is "foo.obj"
then enter "in foo" at the OBJ prompt. If you see the prompt ">>" then
you have entered the Lisp debugger, which means that something has gone wrong
with OBJ; enter ":q" to get back to the OBJ prompt.
- In case your unix is a little rusty, here's one way to run OBJ3: first
enter
alias obj /net/cat/disk1/goguen/obj
either in a shell, or preferably in your .aliases file, so you never have to
type it again; then just enter "obj" at the shell prompt. (Enter "source
.aliases" to get it going the first time.)
I welcome your comments to improve this document for future students!
Of course, the OBJ3 Manual gives
more precise information on all these points (except the last), but often in a
less digestible form.
Maintained by Joseph Goguen
Last modified 20 March 1999