Introducing OBJ [chapter]

Joseph A. Goguen, Timothy Winkler, José Meseguer, Kokichi Futatsugi, Jean-Pierre Jouannaud
2000 Advances in Formal Methods  
This is an introduction to the philosophy and use of OBJ, emphasizing its operational semantics, with aspects of its history and its logical semantics. Release 2 of OBJ3 is described in detail, with many examples. OBJ is a wide spectrum rst-order functional language that is rigorously based on (order sorted) equational logic and parameterized programming, supporting a declarative style that facilitates veri cation and allows OBJ to be used as a theorem prover. Order sorted algebra provides a
more » ... ion of subsort that rigorously supports multiple inheritance, exception handling and overloading. Parameterized programming gives powerful support for design, veri cation, reuse, and maintenance, using two kinds of module: objects to encapsulate executable code, and in particular to de ne abstract data types by initial algebra semantics; and (loose) theories to specify both syntactic and semantic properties of modules. Each kind of module can be parameterized, where actual parameters may be modules. For parameter instantiation, a view binds the formal entities in an interface theory to actual entities in a module, and also asserts that the target module satis es the semantic conditions of the interface theory. Module expressions allow complex combinations of already de ned modules, including sums, instantiations, and transformations; moreover, evaluating a module expression actually constructs the described software (sub)system from the given components. Default views can greatly reduce the e ort of instantiating modules, by allowing obvious correspondences to be left out. We argue that rst-order parameterized programming includes much of the power of higher-order programming, in a form that is often more convenient. Although OBJ executable code normally consists of equations that are interpreted as rewrite rules, OBJ3 objects can also encapsulate Lisp code, e.g., to provide e cient built-in data types, or to augment the system with new capabilities; we describe the syntax of this facility, and provide some examples. In addition, OBJ provides rewriting modulo associative, commutative and/or identity equations, as well as user-de nable evaluation strategies that allow lazy, eager, and mixed evaluation strategies on an operator-by-operator basis; memoization is also available on an operator-by-operator basis. In addition, OBJ3 supports the application of equations one at a time, either forwards or backwards; this is needed for equational theorem proving. Finally, OBJ provides user-de nable mix x syntax, which supports the notational conventions of particular application domains. 1 OBJ3 has been used for building FOOPS, an object oriented speci cation and programming system 74, 87], the Eqlog system 71, 72, 25] for equational logic (or relational) programming, OOZE 3], an object oriented speci cation language in uenced by Z 142], the 2OBJ metalogical framework theorem prover 81], and TOOR 130], a system for tracing requirements. OBJ has been used for many applications, including debugging algebraic speci cations 77], rapid prototyping 69], de ning programming languages in a way that directly yields an interpreter (see Appendix Section C.2, as well as 79] and some elegant work of Peter Mosses 120, 121]), specifying software systems (e.g., the GKS graphics kernel system 28], an Ada con guration manager 40], the MacIntosh QuickDraw program 126], and OBJ itself 20]), hardware speci cation, simulation, and veri cation (see 144] and Section 4.8), speci cation and veri cation of imperative programs 66], speci cation of user interface designs 60, 58], and theorem proving 53, 66, 59]; several of these were done under a UK government grant. OBJ has also been combined with Petri nets, thus allowing structured data in tokens 5], and was used to verify compilers for parallel programming languages in the esprit sponsored procos project 137, 138]. In addition, OBJ serves as a programming language for the massively parallel Rewrite Rule Machine, which executes rewrite rules directly 63, 152, 106, 75, 107, 2, 54, 1]; in fact, given equal silicon oorspace and development e ort, OBJ on such a machine could out-perform a conventional language on a conventional machine, because of the direct concurrent execution of rewrite rules. Some examples using OBJ3 for theorem proving and hardware veri cation from 51] and 59] are given in Appendix Section C.4. In 66], OBJ3 is used for teaching the semantics of imperative programming languages, and all the proofs in 66] are actually executable OBJ3 programs; see 109] for a more detailed discussion of the educational uses of OBJ. A Brief History of OBJ OBJ was designed in 1976 by Goguen 43], using \error algebras" to extend algebraic abstract data type theory with error handling and partial functions; this rst design also used ideas from Clear 8, 10] for parameterized modules, thus giving birth to parameterized programming. The rst implementations of OBJ were done from 1977 to 1979 at UCLA by Joseph Tardo and Joseph Goguen. OBJ0 45] was based on unsorted equational logic, while OBJT used error algebras plus an \image" construct for parameterization 148, 82]. David Plaisted implemented OBJ1, building on OBJT during 1982{83 at SRI, based on theoretical and design work carried out with Joseph Goguen and Jos e Meseguer; improvements of OBJ1 over OBJT included rewriting modulo associativity and/or commutativity, hash coded memo functions, the use of theories with loose semantics as well as objects with initial semantics, and new interactive features 77] which made the system more convenient for users. OBJ2 35, 36] was implemented using parts of OBJ1 during 1984-85 at SRI by Kokichi Futatsugi and Jean-Pierre Jouannaud, following a design in which Jos e Meseguer and Joseph Goguen also participated, based on order sorted algebra 44, 76, 62, 73, 141] rather than error algebra; also, OBJ2 provided Clear-like parameterized modules, theories, and views, although not in full generality. Another in uence on OBJ3's design and implementation was the HISP system 38, 39, 30] of Kokichi Futatsugi. OBJ3 was rst developed at SRI by Timothy Winkler, Jos e Meseguer, Joseph Goguen, Claude and H el ene Kirchner, and Aristide Megrelis; Release 2 was developed at SRI by Timothy Winkler, Patrick Lincoln, Jos e Meseguer, and Joseph Goguen, and later extended by Winkler and Goguen at the Programming Research Group of the Oxford University Computing Lab; version 2.04 includes further small bug xes made at Oxford. Although the syntax of OBJ3 is close to that of OBJ2, it has a di erent implementation based on a simpler approach to order sorted rewriting 101], and it also provides much more sophisticated parameterized programming. OBJ2 and OBJ3 can be seen as implementations of Clear 8, 10], where the chosen logic is order sorted equational logic. Other implementations of OBJ1 include UMIST-OBJ from the University of Manchester Institute of Science and Technology 20], Abstract Pascal from the University of Manchester 105], and MC-OBJ from the University of Milan 14]; the rst two are written in Pascal and the third in C. In addition, there is a Franz Lisp OBJ2 done at Washington State University 143]. UMIST-OBJ has been made available as a proprietary software product from Gerrard Software, under the name ObjEx. OBJ has been extended in many directions, including logic (or relational) programming (the Eqlog system 71, 72, 25]), object oriented programming (the FOOPS system 74, 87]), object oriented speci cation (OOZE 3]), requirements tracing (TOOR 130]), higher-order functional programming 97, 110], and LOTOS-style speci cation for communication protocols 127, 128]. Recent developments within the OBJ community include CafeOBJ, Maude, and CASL. CafeOBJ 26, 27] is being built at the Japan Institute of Science and Technology under the direction of Prof. Kokichi Futatsugi; it extends OBJ3 with hidden algebra 55, 80, 68, 67] for behavioral speci cation, and with rewriting logic 113, 114] for applications programming. Maude 112, 16] is being built at SRI International under the parse, or more precisely, a unique parse of least sort; it is intended that the parser give information about di culties that it encounters, including multiple parses of least sort. Warning: Due to the treatment of user-supplied operator precedence (see Section 2.4.3), the parser in Release 2 of OBJ3 may sometimes fail to nd a parse, even though an unambiguous parse exists. This can usually be repaired by adding parentheses. Let us now discuss operator syntax. The argument and value sorts of an operator are declared at the same time that its syntactic form is declared. There are two kinds of syntactic form declaration in OBJ. We call the rst kind the standard form, because it de nes the parenthesized-pre x-with-commas syntax that is standard in mathematics. For example, op push : Stack Int -> Stack . declares syntax for terms of the form push(X,Y) of sort Stack, where X has sort Stack and Y has sort Int. If the top operator of a term has standard syntactic form, then its arguments (i.e., its rst level subterms) must be separated by commas and be enclosed within a top level matching pair of parentheses, for the entire term to be well formed. OBJ3's syntax for a standard operator declaration is op hOpForm i : hSortList i -> hSort i . where hOpFormi is a nonempty string of characters, possibly consisting of multiple (blank-separated) tokens. Operators in standard form should not include the underbar character, \_" (some further syntactic requirements for hOpFormi are discussed below). Warning: An operator declaration must be terminated with a blank followed by a period 6 , and all of the sorts (and operators | see the discussion of id declarations below) used in it must have been previously declared. The second kind of OBJ syntax for operator declarations is called mix x form, and it allows declaring arbitrary mix x syntax. This kind of declaration uses place-holders, indicated by an underbar character, to indicate where arguments should appear; the rest of the operator form consists of the keywords associated with the operator. For example, the following is a pre x declaration for top as used in terms like top push(S,5): Similarly, the \out x" form of the singleton set formation operator, as in { 4 }, is declared by op f_g : Int -> Set . and the in x form for addition, as in 2 + 3, is given by op _+_ : Int Int -> Int . while a mix x declaration for conditional is 6 An exception is if the last character is a left bracket, \]", which will occur if there are attributes (see Section 2.4). 6 op if_then_else_fi : Bool Int Int -> Int . Between the : and the -> in an operator declaration comes the arity of the operator, and after the -> comes its value sort (sometimes called \co-arity"); the harity; value sorti pair is called the rank of the operator. The general syntax for mix x form operator declarations is op hOpForm i : hSortList i -> hSort i . where hOpFormi is a non-empty string of characters, possibly consisting of multiple (blank-separated) tokens, possibly including blanks and matching pairs of parentheses. Blanks in the form have no e ect when they are contiguous to an underbar. The following shows a form with a blank: op _is in_ : Int IntSet -> Bool . Warning: A mix x operator form should be neither entirely blank, nor consist of just one underbar. Also, it must contain exactly as many underbars as there are sorts in its arity. The entire hOpFormi of an operator can be enclosed in parentheses. This can be used to avoid syntactic ambiguity. For example, in the following declaration for division of rational numbers by non-zero rationals, op (_:_) : Rat NzNat -> Rat . failure to enclose the operator name in parentheses could cause the rst \:" to be erroneously treated as the delimiter for the hSortListi of the declaration. Such enclosing parentheses are not considered part of the hOpFormi, but rather provide a way to avoid this kind of syntactic ambiguity. The rule is that if the rst token encountered after the \op" in an operator declaration is a left parenthesis that is matched by a right parenthesis before the delimiting \:", then these parentheses are interpreted as delimiters, rather than as part of the hOpFormi. This does not preclude using parentheses as tokens in the syntax of an operator. However, the rst token in the syntax of an operator should never be a left parenthesis. For example, one can declare an \apply" operator in a data type of lambda expressions with the syntax op _(_) : Lambda Lambda -> Lambda . Constant declarations have no underbars and have empty arity. For example, op true : -> Bool .
doi:10.1007/978-1-4757-6541-0_1 fatcat:p43wswo5drag7fvuxwkkchq4ue