Electronic Notes in Theoretical Computer Science 36 (2000)

URL: http://www.elsevier.nl/locate/entcs/volume36.html 23 pages

Parameterized Theories and Views in Full Maude 2.0*

Francisco Durán a and José Meseguer b

a ETSII, Universidad de Málaga, Spain b SRI International, Menlo Park, California, USA

Abstract

Parameterized specification and programming is a key modularity and reusability technique crucial for managing the complexity of large specifications and programs. In the search for ever more powerful parameterized module composition operations, languages in the Clear/OBJ tradition, including OBJ3, CafeOBJ, and Maude, have used categorical constructions involving three key notions: (i) modules, which are theories with an initial or, more generally, free extension semantics; (ii) theories, with a loose semantics; and (iii) views, which are theory interpretations used to instantiate parameter theories, and to assert formal properties. It has for long been understood that the full generality and power of a module algebra based on these notions requires parameterized theories and views, not just parameterized modules. However, at present, none of the above-mentioned language implementations supports parameterized modules and views. This paper explains and illustrates with examples the language design of Full Maude 2.0, a new module algebra for Maude currently under development in which modules, theories, and views can all be parameterized. We also summarize the underlying categorical semantics, based on the notion of structured modules with freeness constraints, and explain the reflective design of the Full Maude 2.0 implementation.

1 Introduction

Parameterized specification and programming is a key modularity and reusability technique crucial for managing the complexity of large specifications and programs. Some of the key intuitions can be traced back to Strachey's notions of parametric polymorphism [28], that, beginning with Reynolds [26], has influenced a vast body of work in higher-order programming and higher-order type theory.

* Supported by DARPA through Rome Laboratories Contract F30602-97-C-0312 and NASA Contract NAS2-98073, by Office of Naval Research Contract N00014-99-C-0198, and by National Science Foundation Grants CCR-9900334.

©2000 Published by Elsevier Science B. V.

However, the notion of parameterized specification and programming is by no means restricted to higher-order logics. As proposed by Burstall and Goguen in their work on Clear [5] and on institutions [21], parameterized specifications can be defined in any logic satisfying very general and simple assumptions; and they can likewise be given a simple categorical semantics in this general setting by means of colimits. These ideas have influenced much subsequent work, not only in algebraic specification, but also in software refinement and program synthesis [27], and in module interconnection languages [19,29].

In algebraic specification and equational programming the Clear viewpoint has been particularly well understood and exploited, influencing many algebraic specification languages such as, for example, ACT ONE [17] and CASL [10] (see the surveys [3,18] for many other references). In particular, Clear-like module algebras have been vigorously pursued and developed in the OBJ family of languages, especially in the OBJ3 [22], CafeOBJ [11] and Maude [14,12] designs and implementations. Common to languages in this family is the use of three key ingredients in the module algebra:

• modules, which are theories with an initial or—in the parameterized case— free extension semantics;

• theories, with a loose semantics, that can be used to specify the parameters of modules and to state formal assertions; and

• views, which are theory interpretations used to instantiate parameter theories, refine specifications, and assert formal properties.

It has for long been understood that the full generality and power of a module algebra based on these primitives requires parameterized theories and views, not just parameterized modules [22,20]. In this way, a considerably greater degree of genericity, modularity, and reusability can be achieved for specifications and proofs. However, at present none of the above-mentioned implementations—nor any other algebraic language implementation we are aware of, except perhaps for some partial prototype efforts—supports parameterized modules and views. In our view, the reasons for this omission are both practical and theoretical:

• practically, a conventional module algebra implementation requires several man-years, and obviously even longer with parameterized theories and views;

• theoretically, parameterized theories and views can be best understood in a full-fledged institution of structured theories, that has only recently been developed [16].

This paper presents our language design of the Full Maude 2.0 module algebra currently under development, that will extend Full Maude 1.0 [14,12] with parameterized theories and views.

• At the theoretical level, our language design uses the institution of struc-

tured theories with freeness constrains S (C(I)) over a given institution I [16].

• The implementation will use Maude reflection to specify parameterized theories and views in a natural extension of the Full Maude 1.0 executable specification. Besides being a formal specification about which we can prove formal properties, this has also the important practical advantage of reducing the module algebra implementation effort from man-years to man-months.

We can illustrate these notions with a simple example generalizing a similar one in [22], namely a parameterized view ITER-IS-HOM[X :: MONOID] from an appropriate instance of a theory HOM[X :: MONOID, Y : : MONOID], specifying a monoid homomorphism, to a generic iteration module ITER[X :: MONOID].

fth MONOID is sort M . op e : -> M .

op _*_ : M M -> M [assoc id: e] . endfth

view MONOID from TRIV to MONOID is

sort Elt to M . endv

fmod ITER[X :: MONOID] is protecting LIST[MONOID][X] . op iter : List[MONOID][X] -> M.X . var A : M.X . var L : List[MONOID][X] . eq iter(nil) = e . eq iter(A L) = A * iter(L) . endfm

fth HOM[X :: MONOID, Y :: MONOID] is op h : M.X -> M.Y . vars A B : M.X . eq h(e) = e .

eq h(A * B) = h(A) * h(B) . endth

view ListAsMonoid[X :: MONOID] from MONOID to LIST[MONOID][X] is

sort M to List[MONOID][X] . endv

view ITER-IS-HOM[X :: MONOID]

from HOM[ListAsMonoid[MONOID], MONOID][X, X] to ITER[X] is

The ITER-IS-HOM view allows us to realize that any iteration is a spe-

cial case of a monoid homomorphism. Therefore, if we are able to prove any property about the parameterized functional theory HOM in general, or about HOM[ListAsMonoid[MONOID], MONOID][A, A] for some actual parameter A, and assuming a proof that the parameterized view is correct, we will then have also such a property for ITER in general, or for ITER[A].

The paper is organized as follows. In Section 2 we summarize the relevant concepts of Full Maude 1.0 that this work extends. Our language design for parameterized theories and views is then presented and illustrated with examples in Sections 3, 4, and 5. Section 6 summarizes the categorical semantics of the module algebra, based on the notion of structured theories with freeness constraints of [16], that generalize the theories with freeness constraints in [21] and provide a natural conceptual unification of the notions of parameterized module and parameterized theory. We also explain the reflective design of the Full Maude 2.0 module algebra as an executable Maude specification extending that of Full Maude 1.0 in Section 7, and conclude with a discussion of future work in Section 8.

2 Parameterized Programming in Full Maude 1.0

In Full Maude 1.0, like in OBJ3 [22], CafeOBJ [11], and other algebraic specification languages, theories are used to declare the interface requirements of parameterized modules, that is, the semantic properties that must be satisfied by the actual parameter modules used in an instantiation. As for modules, Full Maude 1.0 supports three different types of theories: functional, system, and object-oriented theories. Their internal logical structure is the same as that of their module counterparts. All of them can have declarations of sorts, subsort relations, operators, variables, membership axioms, and equations, and can import other theories or modules. System theories can have rules as well, and object-oriented theories can in addition have declarations of classes, subclass relations, and messages. However, in Full Maude 1.0, theories and views cannot be parameterized.

As functional modules, functional theories are membership equational logic theories, but they do not need to be Church-Rosser; they have a loose interpretation, in the sense that any algebra satisfying the equations and membership axioms in the theory is an acceptable model. System theories and object-oriented theories have a similar loose interpretation. While the semantics of an unparameterized module is the initial algebra specified by its theory, the semantics of a parameterized module is the free functor associated to the inclusion of the parameter theory into the body of the parameterized module [25]. If the parameterized module has several parameter theories, we should form their colimit, and consider instead the inclusion of such a colimit into the body. For example, a parameterized list module LIST[X :: TRIV] forms lists of models of the trivial parameter theory TRIV with one sort Elt, whose models are sets of elements, and its semantics is the free functor sending each set

to the algebra of lists of elements in the set. All this is entirely similar to the semantics of "objects" and theories in OBJ [22].

The including importation of a theory into another theory keeps its loose semantics. However, if the imported theory contains a module, which therefore must be interpreted with an initial semantics,1 then that initial semantics is maintained by the importation. For example, in the definition of the POSET theory of partially ordered sets below, the declaration protecting BOOL ensures that the initial semantics of the functional module for the Booleans is preserved, which is in fact a crucial requirement. This requirement is then preserved by the theory TOSET of totally ordered sets when POSET is included in it. In fact, we are dealing with a structure in which part of it, not only the top theory, has a loose semantics, while other parts may contain modules with an initial (or, more generally, free) semantics. The kind of semantics of a module or theory is determined by the keyword used in its definition and by the importation mode.

fth POSET is

protecting BOOL . sort Elt .

op _<_ : Elt Elt -> Bool . vars X Y Z : Elt . eq X < X = false .

ceq X < Z = true if X < Y and Y < Z . endfth

fth TOSET is

including POSET . vars X Y : Elt .

eq X < Y or Y < X or X == Y = true . endfth

In Full Maude 1.0 modules can be parameterized by one or more unparam-eterized theories, each of which is labeled, so that one can refer to the different parameters even when the same theory appears several times. The general form for the interface of a parameterized module is [X1 :: T1, ... , Xn :: Tn], where X1,..., Xn are the labels, and T1,...,Tn are the names of the parameter theories. In this, we follow the parameter labeling convention of OBJ3.

However, in Maude—unlike OBJ3—sorts are not systematically qualified by their module name. Instead, we assume that all views are named, and that these names are the ones used in the qualification of the sorts in a module. Specifically, any sort S declared in the body of a module M [X1 :: T1, ... ,Xn :: Tn] can be written in the form S [X1, ... ,Xn]. When the module is instantiated with views V1, ..., Vn, then the corresponding instantiated sort becomes S [V1, ... , Vn]. A notion similar to our parameter-

1 In Full Maude 1.0, the importation of a module into a theory is supported only in protecting mode.

ized sorts has been used in languages like Larch [23], LPG [2], and CASL [10]. However, none of these approaches qualifies sorts in a systematic way as we do.

Thus, a module to define sets can be defined as follows.

fmod SET[X :: TRIV] is sorts Set[X] NeSet[X] . subsorts Elt.X < NeSet[X] < Set[X] . op mt : -> Set[X] .

op__: Set[X] Set[X] -> Set[X] [assoc comm id: mt] .

op__: NeSet[X] NeSet[X] -> NeSet[X] [assoc comm id: mt] .

op _in_ : Elt.X Set[X] -> Bool .

vars EE' : Elt.X . var S : Set[X] . eq E E = E .

eq E in E' S = E == E' or E in S . eq E in mt = false . endfm

This convention for naming the sorts of a parameterized module avoids lengthy qualifications by module expressions and many unintended collisions of sort names, thus making sort names simple and renaming practically unnecessary when importing different instances of the same parameterized module.

3 Parameterized Theories and Views

This section presents the design of the parameterized theory and view declarations that will be supported in the Full Maude 2.0 version currently under development.

Suppose modules LIST[X :: TRIV] and SET[X :: TRIV], specifying, respectively, lists and sets, and suppose that we need the data type of lists of sets of natural numbers. Typically, we first instantiate the module SET with a view, say Nat, from TRIV to the module NAT mapping the sort Elt to the sort Nat, thus getting the module SET[Nat] of sets of natural numbers. Then, we instantiate the module specifying lists with a view, say NatSet, from TRIV to SET[Nat], obtaining the module LIST[NatSet]. But, what if we need now the data type of lists of sets of booleans? Should we repeat the whole process again? One possibility is defining a combined module SET-LIST[X :: TRIV]. But what if we later want stacks of sets instead of lists of sets?

We can greatly improve the reusability of specifications by using parameterized views. Let us consider the following parameterized view Set from TRIV to SET, which maps the sort Elt to the sort Set[X].

view Set[X :: TRIV] from TRIV to SET[X] is

sort Elt to Set[X] . endv

With this kind of views we can keep the parameter part of the target module still as a parameter. We can now have lists of sets, stacks of sets, and so on, for any instance of TRIV, by instantiating the appropriate parameterized module with the appropriate view. For example, given the view Nat above, we can have the module LIST[Set[Nat]] of lists of sets of natural numbers, or lists of sets of booleans with LIST[Set[Bool]], given a view Bool from TRIV to the built-in module BOOL. Similarly, we can have STACK[Set[Nat]] or STACK[Set[Bool]]. We can also link the parameter of a module like LIST[Set[X]] to the parameter of the module in which it is being included. That is, we can, for example, declare a module of the form

fmod FOO[X :: TRIV] is

protecting LIST[Set[X]] . endfm

Instantiating the module FOO with a view V to another module or theory results in a module with name FOO[V], which includes the module LIST[Set[V]]. Note that we still follow the Full Maude 1.0 conventions for module interfaces and for sort names. The only difference is that now, instead of having simple view names, we must consider names of views which are parameterized.

The use of parameterized views in the instantiation of parameterized modules allows very reusable specifications. However, reusability can still be further improved by the combined use of parameterized views and parameterized theories. Indeed, modules, theories, and views can now all be parameterized by parameterized theories. That is, the general form for the interface of a parameterized module is still M [X1 :: T1, ... , Xn :: Tn], where X1,..., Xn are the labels, and T1,...,Tn are the names of the parameter theories, but now each of the Tj, for i =1... n, can follow this very same pattern. For example, we can have a module MAP[F :: FUN[X :: TRIV, Y : : TRIV]] extending a given function between two parameter sets to a function between the corresponding sets of lists of elements.

Note that, by naming with explicit labels each of the theories in the structured parameters, we can specify which part of the structured parameter is shared. This mechanism is illustrated in Figures 1 and 2, where we depict the parameterized modules M[X1 :: T1 [X2 :: T2], X3 :: T3 [X4 :: T2]], and M' [X1 :: T1 [X2 :: T2], X3 :: T3 [X2 :: T2]], respectively. Although both parameters in the theory M[X1 :: T1 [X2 :: T2], X3 :: T3 [X4 :: T2]] of Figure 1 include the theory T2, it is not shared, since we use different labels for each of the two occurrences of T2. On the other hand, the structure of module M' [X1 :: T1 [X2 :: T2], X3 :: T3 [X2 :: T2 ]] includes only one copy of the theory T2, since it appears with the same label in its two occurrences.

This idea is quite close to that of renaming part of the structure of the parameters [14] to be able to share part of their structure, which also appears in CafeOBJ [11]. In CafeOBJ one can distinguish between so-called "share" and "non-share" cases, stating the kind of sharing that one wants for the

Xi :: Ti [X2 :: T2] + X3 :: T3 [X4 :: T2]

Xi :: Ti[X2 :: T2] X3 :: T3[X4 :: T2]

X2 :: T2 X4 :: T2

Fig. 1. Structure of module M[X1 :: T1 [X2 :: T2], X3 :: T3 [X4 :: T2]].

Xi :: Ti [X2 :: T2] + X3 :: T3 [X2 :: T2]

Xi :: Ti[X2 :: T2] X3 :: T3[X2 :: T2]

X2 :: T2

Fig. 2. Structure of module M' [Xi :: Ti [X2 :: T2], X3 :: T3 [X2 :: T2]].

parameters. In the "non-share" case it is still possible to explicitly share some submodule in the structure of the parameter.

Note also that the parameters of the sorts in modules parameterized by parameterized theories have to be qualified accordingly. For example, the sorts declared in the parameterized module M[X1 :: T1 [X2 :: T2], X3 :: T3 [X4 :: T2]] will be of the form S[X1 [X2], X3 [X4]], while the sorts declared in the module M' [Xi :: Ti [X2 :: T2], X3 :: T3 [X2 :: T2]] will be of the form S[Xi [X2], X3 [X2]].

The requirements explained above for modules and theories apply also to parameterized views, which have the form V [X1 :: T1, ... , Xn :: Tn], where X1,...,Xn are the labels, and T1,...,Tn are the names of the parameter theories, each of which can be a parameterized theory with the pattern explained above. As unparameterized views, parameterized views define a morphism between a theory, which can be parameterized or not, and a module or theory, which can also be parameterized. However, the interface of the parameterized view must coincide with the interface of the target theory or module, up to a change in the order in which the parameters appear, and the parameters of the source theory must be a subset of the parameters of the target theory or module. More precisely, given a view V [X :: P"] from a theory T [Y] to a module or theory T' [X], it must be the case that each parameter Yi :: Pi of the source theory is a labeled subtheory of some Xj :: P', where by a labeled

V[x :: P>]

Colim (P)c-^ Colim (P1 )

-T'[W]

Colim (W ) Fig. 3. View instantiation.

Colim (Q)

Set[Nat]

SET[Nat]

Fig. 4. The Set[Nat] view instantiation.

subtheory of a given labeled theory we mean a labeled theory appearing in its nested structure, including itself. For example, the labeled subtheories of X :: T[Y :: T'[Z :: T"]] are itself, Y :: T'[Z :: T"],and Z :: T". We can for instance have parameterized views such as the following ones.

view V[X1 :: T1[X2 :: T2]] from T[X2] to T'[X1[X2]] is ... endv view V[X1 :: T1, X2 :: T2] from T[X2] to T'[X1, X2] is ... endv

view V[X1 :: T1, X2 :: T2] from T[X1, X2] to T'[X2, X1] is ... endv

Given the parameterized view V[X :: I3'] from T [Y] to T' [X], and given views W1 : Pi ^ Q1,...,Wra : P^ ^ Qn, we can define the instantiation V[W1,..., Wn] of the parameterized view V by the views W1,...,Wn as the composition of the view V and of the pushout of Colim (W) along the inclusion of Colim(P') into T' depicted in the diagram of Figure 3, where Colim(P), Colim(P'), and Colim(Q) denote the colimits of P, P', and Q, respectively, and where Colim(W) denotes the induced morphism between Colim(P') and Colim(Q). Thus, for example, the view instantiation Set[Nat] in the module expression LIST[Set[Nat]] above can be depicted as shown in Figure 4.

4 Composed and Lifted Views

Instantiation of parameterized views is not enough. In order to be able to have access to all the potential of parameterized views we must be able to express explicitly the composition of views, which we denote with a semicolon. Furthermore, we should also be able to denote views that occur at different levels in the structure of the theories involved, which we call lifted views.

MODULE{F} V-AS-M MODULE-^MODULE[F]-^VECTOR-SP

-FIELD

Fig. 5. Views F and V-AS-M.

Let us consider, for example, the theory MODULE[X :: RING] of modules 2 over a ring. We can define a view from MODULE[X :: RING] to the theory VECTOR-SP[X :: FIELD] of vector spaces over a field by first defining a view F from RING to FIELD,

view F from RING to FIELD is

sort Elt to Elt . endv

and then defining a parameterized view V-AS-M[X MODULE[F][X] to VECTOR-SP[X].

FIELD] from the theory

view V-AS-M[X :: FIELD] from MODULE[F][X] to VECTOR-SP[X] is sort Elt to Elt . sort Elt.X to Elt.X . endv

Note that, by instantiating the theory MODULE[X :: RING] with F, we get the parameterized theory MODULE[F][X :: FIELD]. The different views involved are depicted in Figure 5. A specification of the theories can be found in Appendix A.

In Figure 5, we have used the notation MODULE{F} to refer to the pushout of F along the inclusion of the theory RING into MODULE. We call MODULE{F} the lifting of F (to MODULE,), since it is just the result of combining F with the identity morphism for MODULE, that is, we extend F in order to obtain the morphism at the right level. More precisely, given a parameterized module or theory M[X1 :: T1, ... ,Xn :: Tn ], and given views V1 : T1 ^ K1,..., Vn : Tn ^ Kn, with Ki modules or theories (or more generally, views for some labeled subtheories, see below), for i = 1. ..n, then M{V1; ... ,Vn}, called the lifting of V1, ... ,Vn to M, denotes the theory map given by the following pushout.

M{V1)...,V„} M-^M[Vi, ... ,Vj

Colim (T) ■

Colim (V )

Colim (K)

2 Note that the word "module" here refers to the usual algebraic structure generalizing vector spaces, and not to the structuring unit with initial or free semantics of the Maude language.

T{T1{V2,V3}} T-" T[Ti[V2,Vs]]

p.o. Tl{V2,V3}

"Ti [V2 ,V3]

Colim(T2'Ta) coäm(V2,V3)' Colim(K2'K3) Fig. 6. Views Ti{V2,V3} and T{T1{V2,V3}}.

TENSOR"

MODULE'

MODULE{F}

TENSOR[MODULE{F}] MODULE[F]-

■TENSOR[MODULE{F} ; V-AS-M]

V-AS-M

-VECTOR-SP

■FIELD-=-" FIELD

Fig. 7. Instantiation of TENSOR.

As said above, there can be lifted views for any of the labeled subthe-ories of a given theory. For example, let us consider a theory with name T[Xi :: Ti [X2 :: T2, X3 :: T3]] and views V2 : T2 ^ K2 and V3 : T3 ^ K3, i.e., views on the labeled subtheories X2 :: T2 and X3 :: T3. We can lift the views V2 and V3 to the level of T1 as T1{V2,V3}, or to the level of T as T{T1{V2 ,V3}}. These views are depicted in Figure 6. Note that, as above, we denote by Colim(T2, T3) the colimit of theories T2 and T3 and by Colim(K2, K3) the colimit of K2 and K3, and that we denote as Colim(V2, V3) the induced morphism between Colim(T2,T3) and Colim(K2, K3).

We can now instantiate a module parameterized by MODULE[X :: RING], e.g., the tensor algebra construction TENSOR[Y :: MODULE[X :: RING]], with a view from MODULE[X :: RING] to VECTOR-SP[X :: FIELD] to specialize the same construction to vector spaces. As depicted in Figure 7, for such an instantiation we can use the composition of the above views MODULE{F} and V-AS-M, which we denote by MODULE{F} ; V-AS-M. By instantiating the module TENSOR[Y :: MODULE[X :: RING]] with the composed view MODULE{F} ; V-AS-M we obtain TENSOR[MODULE{F} ; V-AS-M][Y :: VECTOR-SP[X :: FIELD]], which specializes to vector spaces the tensor algebra construction. We can then encapsulate this specialized construction in a module definition such as the following.

fmod TENSOR-VSPACE[Y :: VECTOR-SPACE[X :: FIELD]] protecting TENSOR[MODULE{F} ; V-AS-M][Y[X]] .

Note that the module TENSOR[MODULE{F} ; V-AS-M] is equivalent to the module TENSOR[MODULE{F}][V-AS-M], as can be easily inferred from the diagram in Figure 7.

5 Some Parameterized Theory and View Examples

In this section we present two additional examples illustrating some of the possibilities of the use of parameterized modules, theories, and views. The first example is a parameterized module specifying partial functions, and the second example illustrates how the use of parameterized theories and views can help to improve the reusability of some algorithms on data types. Despite their simplicity, they may help the reader in gaining an intuitive idea of the power of these mechanisms.

5.1 A Specification of Partial Functions

A very simple way of specifying (finite) partial functions is to see a partial function as a set of input-result pairs. Of course, for such a set to represent a function there cannot be two pairs associating different results to the same input value. We show below how this property can be specified by means of appropriate axioms in membership equational logic [25,4]. The partiality of a function can be specified by defining a default value to be used as the result for the input elements for which the function is not defined.

First, we define the parameterized functional module DEFAULT[X :: TRIV] in which we declare a sort Default[X] which is a supersort of the sort Elt of the parameter theory and a constant null of sort Default[X].

fmod DEFAULT[X :: TRIV] is sort Default[X] . subsort Elt.X < Default[X] . op null : -> Default[X] . endfm

We can then specify sets of pairs by instantiating the SET module of Section 2 with a parameterized view from TRIV to the module TUPLE(2) defining pairs of elements [12]. The appropriate parameterized view can be defined as follows.

view Tuple[X :: TRIV, Y :: TRIV] from TRIV to TUPLE(2)[X, Y] is

sort Elt to Tuple[X, Y] . endv

We are now ready to give the specification of partial functions. The sets representing the domain and codomain of the function are given by TRIV parameters, and then the set of tuples is provided by the module expression SET[Tuple[X, Y]] with sorts Set[Tuple[X, Y]] and NeSet[Tuple[X, Y]]. We define functions dom and im returning, respectively, the domain and image of a set of pairs, which are useful for checking whether there are two pairs

in a set of pairs with the same input value. With these declarations we can define the sort PFun[X, Y] as a subsort of Set[Tuple[X, Y]], by adding the appropriate membership axioms specifying those sets that satisfy the required property. Finally, we define operators _[_] and _[_->_] to evaluate a function at a particular element, and to add or redefine an input-result pair, respectively.

fmod PFUN[X :: TRIV, Y :: TRIV] is pr SET[Tuple[X, Y]] . pr SET[X] + SET[Y] . pr DEFAULT[Y] . sort PFun[X, Y] .

subsorts Tuple[X, Y] < PFun[X, Y] < Set[Tuple[X, Y]] .

var A : Elt.X . vars B C : Elt.Y . var F : PFun[X, Y] . var S : Set[Tuple[X, Y]] .

op dom : Set[Tuple[X, Y]] -> Set[X] eq dom(mt) = mt . eq dom(< A ; B > S) = A dom(S) .

op im : Set[Tuple[X, Y]] -> Set[Y] eq im(mt) = mt . eq im(< A ; B > S) = B im(S) .

mb mt : PFun[X, Y] . cmb < A ; B > F : PFun[X, Y] if not(A in dom(F)) . op _[_] : PFun[X, Y] Elt.X -> Default[Y] . op _[_->_] : PFun[X, Y] Elt.X Elt.Y -> PFun[X, Y] . eq (< A ; B > F)[ A ] = B . ceq F [ A ] = null if not(A in dom(F)) . eq(<A ;B>F)[A->C] = <A; C>F . ceq F [ A -> C ] =<A ; C > F if not(A in dom(F)) . endfm

Now, we can instantiate the PFUN module with, for example, the view Nat below, in order to get the finite partial functions from natural numbers to natural numbers by means of the module expression PFUN[Nat, Nat].

view Nat from TRIV to NAT is

sort Elt to Nat . endv

5.2 A Data Structure as Parameter

There are situations in which one needs to specify a certain data type requiring a data structure to store elements of some type, but so that it is irrelevant

*** domain

*** image

what particular type of structure is used. In many languages we are forced from the very beginning to choose such a data structure, which is in most cases some simple data structure such as a list or set, and in fact any of the choices will do for the main specification. However, if at some point in our specification we need to change the chosen data structure, it can be quite difficult, especially if we have fallen into the temptation of using any of the particularities of the chosen data structure, such as being associative in the case of lists, or associative and commutative in the case of sets.

The use of parameterized theories opens up the possibility of taking a more generic approach. Let us consider the following parameterized theory I-STRUCTURE, specifying any structure with a minimum set of requirements, for example, having two operators, one for generating an empty structure, and another for inserting a new element in a structure.

th I-STRUCTURE[X :: TRIV] is sorts NeStruct[X] Struct[X] . subsort NeStruct[X] < Struct[X] . op empty : -> Struct[X] .

op insert : Elt.X Struct[X] -> NeStruct[X] . endth

We can now specify any application which needs a generic data structure having those operations by parameterizing it with respect to the I-STRUCTURE theory.

A more interesting kind of data structure may be one specified by the theory STRUCTURE below, in which we have additional operations for inspecting and extracting elements from the structure. A structure like this may be useful, for example, for defining generic searching or traversing functions on trees or graphs. We can specify a generic search operation so that, depending on the particular structure we use to store the "live nodes," we get one kind of search or another. For example, instantiating it with a module STACK of stacks with operations push, pop, and top we get a depth-first search, while instantiating it with a module QUEUE of queues with functions put, remove, and get we get a breadth-first search. More interesting traversals can be obtained by using more sophisticated structures such as, for example, a heap or a priority queue.

th STRUCTURE[X :: TRIV] is inc I-STRUCTURE[X] .

op extract : NeStruct[X] -> Struct[X] . op inspect : NeStruct[X] -> Elt.X . endth

Let us specify a simple search algorithm on binary trees, and let us consider for that the following specification of binary trees with constructors empty for empty trees, and _[_]_ for forming a tree out of its left and right subtrees and an element at its root.

fmod BIN-TREE[X :: TRIV] is sorts BinTree[X] . op empty : -> BinTree[X] [ctor] .

op _[_]_ : BinTree[X] Elt.X BinTree[X] -> BinTree[X] [ctor] . endfm

In order to search for an element in a binary tree using a structure as the one specified by the theory STRUCTURE, we need a structure of such trees, so that we can proceed by storing each of the subtrees of the original tree in it. That is, instead of storing in the structure the "live nodes," we proceed by inserting the subtrees which have such live nodes as roots. Depending on the order in which such subtrees are stored and retrieved, we get one type of traversal or another. Thus, we first define a theory of structures of trees as follows.

view BinTree[X :: TRIV] from TRIV to BIN-TREE[X] is

sort Elt to BinTree[X] . endv

fth STRUCT-OF-TREES[X :: TRIV] is

inc STRUCTURE[BinTree[X]] . endfth

We are now ready to specify the search function in the BIN-TREE-SEARCH module below. This module is parameterized with respect to a structure of trees of elements in a given set. To simplify the specification, our search function takes an element and a tree, and checks whether the element is in the tree or not. It starts by introducing the complete tree in the structure of trees, and calling a function with the same name with such a structure of trees. This function checks whether the tree returned by the inspect function has the searched element at its root or not. In case it does not, the search function is called with its subtrees introduced in the structure of trees.

fmod BIN-TREE-SEARCH[X :: STRUCT-OF-TREES[Y :: TRIV]] is op search : Elt.Y BinTree[Y] -> Bool . op searchSt : Elt.Y Struct[BinTree[Y]].X -> Bool . op searchAux : Elt.Y BinTree[Y] Struct[BinTree[Y]].X -> Bool .

vars EE' : Elt.Y .

vars T T' : BinTree[Y] .

var S : Struct[BinTree[Y]].Y .

eq search(E, T) = searchSt(E, insert(T, empty)) . eq searchSt(E, empty) = false . ceq searchSt(E, T)

= searchAux(E, inspect(T), extract(T)) if T =/= empty . eq searchAux(E, T[E']T', S) = if E == E'

then true

else searchSt(E, insert(T', insert(T, S))) fi .

eq searchAux(E, empty, S) = searchSt(E, S) . endfm

Finally, let us define a depth-first search by instantiating the module BIN-TREE-SEARCH with the following module STACK of stacks, so that the generic structure of trees becomes a stack of trees.

fmod STACK[X :: TRIV] is

sorts Stack[X] NeStack[X] . op empty : -> Stack[X] [ctor] . op push : Elt.X Stack[X] -> NeStack[X] [ctor] . op pop : NeStack[X] -> Stack[X] . op top : NeStack[X] -> Elt.X . var E : Elt.X . var S : Stack[S] . eq pop(push(E, S)) = S . eq top(push(E, S)) = E . endfm

view StackAsStruct[X :: TRIV]

from STRUCT-OF-TREES[X] to STACK[BinTree[X]] is sort Struct[BinTree[X]] to Stack[BinTree[X]] . sort NeStruct[BinTree[X]] to NeStack[BinTree[X]] . op empty to empty . op insert to push . op extract to pop . op inspect to top . endv

fmod BIN-TREE-DEPTH-FIRST-SEARCH[X :: TRIV] is

protecting BIN-TREE-SEARCH[StackAsStruct[X]] . endfm

6 The Semantics of Parameterized Theories and Views

We summarize in this section how our work on structured theories and free-ness constraints on such theories [16] provides a categorical semantics for the parameterized theories, views, and modules of Full Maude 2.0. The semantics of the notions of parameterized theory and parameterized view is given by the general notion of structured theory introduced in [16], where we study structured theories and their composition. Such a notion is introduced as a way of considering structured theories as first-class citizens, so that the structure of each theory is preserved when theories are combined. There are very good theoretical and practical reasons for considering theory-building operations

whose results are structured theories, including the following: (i) the semantics associated to a structured module essentially depends on its structure, as it is the case when we associate to the inclusion of a parameter theory into the body of a parameterized specification a freeness constraint [21], requiring that the models of the body are free extensions of the models of the parameter; (ii) refining a software design can be best understood as refining structured theories [27]; (iii) dealing with structured theories can improve the simplicity and efficiency of module operations [14,12]; (iv) it can also improve the under-standability of design documentation; and (last but not least) (v) structured theories provide the right semantic framework to understand the notions of parameterized module, parameterized theory, and parameterized view.

In [16], a logic-independent categorical semantics is given to structured theories. As in Clear [5] and SPECWARE [27], the categorical notion of diagram is used for giving semantics to structured theories. In particular, the institution S(I) of structured theories over a given institution I is defined in [16], and several key results about the cocompleteness of its categories of signatures and theories are given. One of these results states that, if the category of signatures of I has colimits, then the categories of signatures and theories of S(I) both have colimits, making then possible extending the proposal of Goguen and Burstall [5] of taking colimits of theories as a systematic way of "putting theories together" to structured theories, that is, allowing us to use colimits of structured theories as a systematic way of putting structured theories together.

One of the key motivations for making structured theories a direct object of study is dealing with freeness constraints. They are crucial for the notion of parameterized module, in which the model of the parameterized module's body should be a free extension of the model of the parameter theory. In many specification languages, including Maude, this leads to a distinction between theories, with loose semantics, and modules, with initial or, more generally, free extension semantics. Both theories and modules can be parameterized, but in the case of parameterized modules, a freeness constraint between models of the parameter and models of the body is enforced.

Intuitively, freeness constraints are associated to particular theory maps appearing in the diagram of a structured theory, as illustrated in Figures 1-2, where the maps with freeness constraints are represented by Using this idea, the general construction by Goguen and Burstall [21] associating to an institution I another institution C (I) of theories with freeness constraints can be used to add such constraints to structured theories. The institution of structured theories with freeness constraints is then given by S(C(I)). Therefore, structured I-theories with freeness constraints unify the notions of theory (with loose semantics) and module (with initial or free extension semantics). That is, both theories and modules are unified in the more general notion of structured specification with freeness constraints, whose semantics explicitly depends on their structure. This more general notion serves as a

kind of conceptual unification of the notion of module (with initial or freeness constraints) and of theory (with loose semantics) and provides the underlying semantics for the notions of parameterized theory and parameterized module proposed in Section 3. We call a structured theory with freeness constraints a module if it has a freeness constraint at the top level, and we call it a theory if freeness constraints only appear at lower levels in the structure. Similarly, parameterized views, as well as lifted views and composed views, are particular morphisms between such structured specifications with freeness constraints.

We end this section with a technical qualification regarding freeness constraints in membership equational logic [25,4]. Due to the presence of kinds, in which new error terms can easily be added by new operators, the notions of protecting extension and of persistent theory inclusion are in practice too restrictive. The right notions are those of protected sorts (see [4, Section 8]) and of persistence at the sort level (see [4, Definition 71]). Therefore, for membership equational logic the C(I) construction should be relaxed to a similar construction in which the freeness constraints are imposed only at the level of sorts.

7 The Implementation

The theoretical foundations described in Section 6 are the basis for the Full Maude 2.0 module algebra, in which structured theories are first-class citizens, and module operations result in other structured theories [14,12].

Using the fact that rewriting logic is reflective [9,6], the entire module algebra is both specified and executed within the logic of Maude [12,15]. In general, theories, structured theories, theory maps, and so on are metalevel entities not available at the object level of a logic. However, since rewriting logic is reflective, all these entities can be represented within the logic itself. In particular, the universal theory U of rewriting logic has a sort Module whose terms are representations T of rewriting logic theories T. Maude's module algebra is then a rewrite theory FULL-MAUDE extending the universal theory U with new sorts such as StrTheory, View, and so on, and such that all module operations are definable within the logic by reflection. That is, in FULL-MAUDE all metalevel entities such as theories, structured theories, views, and module expressions are reified at the object level of the logic. Furthermore, the formal specification of the module operations is executable, so that FULL-MAUDE is part of the Maude distribution and is used in practice to execute the module composition operations.

It has already been demonstrated that Maude's module algebra can be easily extended [12,13,8]. We are currently working on the extension of Full Maude 1.0 in different ways, that will result in Full Maude 2.0, the version of Full Maude that will be distributed as part of the Maude 2.0 release [7]. Full Maude 2.0 will use parameterized theories and parameterized views in its full generality, following the design and semantics presented in this paper.

8 Concluding Remarks

Parameterized theories and views add substantial new generality to module algebra operations in the Clear/OBJ style. We have presented and illustrated with examples the key concepts and constructs of the Full Maude 2.0 module algebra currently under development, in which modules, theories, and views can all be parameterized. We have also discussed the underlying categorical semantics based on the institution of structured theories with freeness constraints; and we have explained the reflective design of the Full Maude 2.0 implementation.

In the upcoming months Full Maude 2.0 will be completed and will be integrated with the rest of the Maude 2.0 version. Much work remains ahead up to and beyond the release of Full Maude 2.0. We are investigating nota-tional conventions for views that can greatly reduce the need for explicit view definitions. We also would like to define and implement new module operations such as, for example, the object-oriented module operations described in [24]. The research on polytypic functions described in [8] should be more fully supported using the new capabilities of Full Maude 2.0. Proof techniques for parameterized modules, theories and views require more work, extending the Maude proof tools already available in the unparameterized case, and taking advantage of recent advances in metareasoning for Maude specifications [1], and in membership equational logic proof techniques [4]. Finally, the present work on Full Maude should be generalized to a generic module algebra written in Maude, which could be instantiated to endow many other logics with similar module operations.

Acknowledgments

We are very thankful to Narciso Marti-Oliet for his collaboration in the development of this work, for his careful reading of several versions of the paper, and for his many helpful suggestions for improvement. We are also greatful to Joseph Goguen for his constructive criticism and comments on these ideas.

References

[1] D. Basin, M. Clavel, and J. Meseguer. Reflective metalogical frameworks. In Proceedings of Workshop on Logical Frameworks and Meta-languages, LFM'99, 1999. Available at http://www.cs.bell-labs.com/~felty/LFM99/.

[2] D. Bert and R. Echahed. Design and implementation of a generic, logic and functional programming language. In B. Robinet and R. Wilhelm, editors, Proceedings of European Symposium on Programming ESOP'86, volume 213 of Lecture Notes in Computer Science, pages 119-132. Springer-Verlag, 1986.

[3] M. Bidoit, H.-J. Kreowski, P. Lescanne, F. Orejas, and D. Sannella, editors.

Algebraic System Specification and Development. A Survey and Annotated Bibliography, volume 501 of Lecture Notes in Computer Science. SpringerVerlag, 1991.

[4] A. Bouhoula, J.-P. Jouannaud, and J. Meseguer. Specification and proof in membership equational logic. Theoretical Computer Science, 236(1):35-132, 2000.

[5] R. Burstall and J. Goguen. The semantics of Clear, a specification language. In D. Bj0rner, editor, Proceedings of the 1979 Copenhagen Winter School on Abstract Software Specification, volume 86 of Lecture Notes in Computer Science, pages 292-332. Springer-Verlag, 1980.

[6] M. Clavel. Reflection in General Logics and in Rewriting Logic with Applications to the Maude Language. PhD thesis, Universidad de Navarra, 1998.

[7] M. Clavel, F. Durân, S. Eker, P. Lincoln, N. Marti-Oliet, J. Meseguer, and J. Quesada. Towards Maude 2.0. In K. Futatsugi, editor, Proceedings of Third International Workshop on Rewriting Logic and its Applications, volume 36 of Electronic Notes in Theoretical Computer Science. Elsevier, 2000. This volume.

[8] M. Clavel, F. Duran, and N. Marti-Oliet. Polytypic programming in Maude. In K. Futatsugi, editor, Proceedings of Third International Workshop on Rewriting Logic and its Applications, volume 36 of Electronic Notes in Theoretical Computer Science. Elsevier, 2000. This volume.

[9] M. Clavel and J. Meseguer. Reflection and strategies in rewriting logic. In J. Meseguer, editor, Proceedings of 1st International Workshop on Rewriting Logic and its Applications, volume 4 of Electronic Notes in Theoretical Computer Science. Elsevier, 1996. Available at http://www.elsevier.nl/ locate/entcs/volume4.html.

[10] CoFI Task Group on Language Design. CASL—The common algebraic specification language, version 1.0. Available at http://www.brics.dk/ Projects/CoFI, October 1998.

[11] R. Diaconescu and K. Futatsugi. CafeOBJ Report. AMAST Series. World Scientific, 1998.

[12] F. Duran. A Reflective Module Algebra with Applications to the Maude Language. PhD thesis, Universidad de Malaga, June 1999.

[13] F. Duran. The extensibility of Maude's module algebra. In T. Rus, editor, Proceedings of 8th International Conference on Algebraic Methodology and Software Technology (AMAST '2000), volume 1816 of Lecture Notes in Computer Science, pages 422-437. Springer-Verlag, 2000.

[14] F. Duran and J. Meseguer. An extensible module algebra for Maude. In C. Kirchner and H. Kirchner, editors, Proceedings of 2nd International Workshop on Rewriting Logic and its Applications, volume 15 of Electronic Notes in Theoretical Computer Science. Elsevier, 1998. Available at http: //www.elsevier.nl/locate/entcs/volume15.html.

[15] F. Duran and J. Meseguer. The Maude specification of Full Maude. Manuscript, SRI International. Available at http://maude.csl.sri.com, February 1999.

[16] F. Duran and J. Meseguer. Structured theories and institutions. In M. Hofmann, G. Rosolini, and D. Pavlovic, editors, Proceedings of 8th Conference on Category Theory and Computer Science (CTCS'99), volume 29 of Electronic Notes in Theoretical Computer Science, pages 71-90. Elsevier, 1999. Available at http://www.elsevier.nl/locate/entcs/volume29.html.

[17] H. Ehrig and B. Mahr. Fundamentals of Algebraic Specification 1. Equations and Initial Semantics. Springer-Verlag, 1985.

[18] M. Gogolla and M. Cerioli. What is an Abstract Data Type after all? In E. Astesiano, G. Reggio, and A. Tarlecki, editors, Recent Trends in Data Type Specification, volume 906 of Lecture Notes in Computer Science, pages 499-523. Springer Verlag, 1995.

[19] J. Goguen. Reusing and interconnecting software components. Computer, 19(2):16-28, February 1986.

[20] J. Goguen. Types as theories. In G. Reed, A. Roscoe, and R. Wachter, editors, Topology and Category Theory in Computer Science, pages 357-390. Oxford University Press, 1991.

[21] J. Goguen and R. Burstall. Institutions: Abstract model theory for specification and programming. Journal of the Association for Computing Machinery, 39(1):95-146, 1992.

[22] J. Goguen, T. Winkler, J. Meseguer, K. Futatsugi, and J.-P. Jouannaud. Introducing OBJ. In J. Goguen and G. Malcolm, editors, Software Engineering with OBJ: Algebraic Specification in Action. Kluwer, 2000.

[23] J. Guttag and J. Horning, editors. Larch: Languages and Tools for Formal Specification. Texts and Monographs in Computer Science. Springer-Verlag, 1993.

[24] J. Meseguer. A logical theory of concurrent objects and its realization in the Maude language. In G. Agha, P. Wegner, and A. Yonezawa, editors, Research Directions in Object-Based Concurrency, pages 314-390. The MIT Press, 1993.

[25] J. Meseguer. Membership algebra as a semantic framework for equational specification. In F. Parisi-Presicce, editor, Recent Trends in Algebraic Development Techniques, volume 1376 of Lecture Notes in Computer Science, pages 18-61. Springer-Verlag, 1998.

[26] J. Reynolds. Towards a theory of type structure. In B. Robinet, editor, Programming Symposium, volume 19 of Lecture Notes in Computer Science, pages 408-425. Springer-Verlag, 1974.

[27] Y. Srinivas and R. Jiillig. SPECWARE: Formal support for composing software. In B. Moeller, editor, Proceedings of Conference on Mathematics of Program Construction, volume 947 of Lecture Notes in Computer Science, pages 399422. Springer-Verlag, 1995.

[28] C. Strachey. Fundamental concepts in programming languages. Higher-Order and Symbolic Computation, 13:11-49, 2000.

[29] W. Tracz. Formal specification of parameterized programs in LILEANNA. Manuscript, Version 7.0, 1993.

A The Theory of Vector Spaces and Other Theories

The theory of commutative monoids can be defined in a way entirely similar to that of the MONOID theory of Section 1. Now, the binary _+_ operator is declared associative, commutative, and with 0 as its identity element.

fth +MONOID is including TRIV . op 0 : -> Elt .

op _+_ : Elt Elt -> Elt [assoc comm id: 0] . endfth

A commutative group can be expressed as a commutative monoid with an inverse operator -_.

fth +GROUP is

including +MONOID . op -_ : Elt -> Elt . var X : Elt . eq X + -(X) =0 . endfth

The theory of rings can be expressed as follows.

fth RING is

including +GROUP .

including +MONOID * (op _+_ to _*_, op 0 to 1) . vars X Y Z : Elt .

eq X * (Y + Z) = (X * Y) + (X * Z) . endfth

Next, we define the theory of domains.

fth DOMAIN is

including RING . protecting BOOL . sort NzElt . subsort NzElt < Elt .

op _*_ : NzElt NzElt -> NzElt [assoc comm id: 1] .

op nz : Elt -> Bool .

var X : Elt .

mb 1 : NzElt .

eq nz(1) = true .

eq nz(0) = false .

ceq X = 0 if nz(X) = false .

DURAN AND MESEGUER

endfth

The theory of fields can now be defined as follows.

fth FIELD is

including DOMAIN . op inv : NzElt -> NzElt . var X : NzElt . eq X * inv(X) = 1 .

endfth

The theory of modules is parameterized by a theory RING, and includes the theory +GROUP and some additional equations as follows.

fth MODULE[R :: RING] is including +GROUP .

op __ : Elt.R Elt -> Elt .

vars A B : Elt.R . vars X Y : Elt . eq (0).Elt.R X = 0 . eq 1 X = X .

eq (A * B) X = A (B X) . eq (A + B) X = (A X) + (B X) . eq A (X + Y) = (A X) + (A Y) . eq A 0 = 0 .

The theory of vector spaces over a field can now be specified as the theory of modules over a field, which is obtained by instantiating the MODULE theory above with a view from RING to FIELD.

view Field from RING to FIELD is sort Elt to Elt .

fth VECTOR-SP[F :: FIELD] is including MODULE[Field][F] .

endfth