Electronic Notes in Theoretical Computer Science 44 No. 3 (2003) URL: http://www.elsevier.nl/locate/entcs/volume44.html 43 pages
Refinement and Development of Programs from Relational Specifications Wolfram Kahl 1 Department of Computing and Software, McMaster University Hamilton, Ontario, Canada L8S 4K1
Abstract These tutorial notes present an overview of specification and refinement concepts and methods that are based on relations.
1
Introduction
At a suitable level of abstraction, the functional requirements on a software program can be considered as specifying which inputs a program has to be able to handle, and for each input, which outputs it may acceptably produce for it. These requirements or specifications can be formalised as relations relating inputs with outputs. Specifications have two uses: On the one hand, a specification is the starting point for the design and implementation process; on the other hand it is the basis for verification and testing of the final product. Both of these uses can profit from a relational approach, since a program, too, establishes a relation between the input space and the output space. For verification, a satisfaction relation between program relations and specification relations needs to be established, and for testing, relational tools can help to organise the input space. For the design and implementation process, the original specification can be subjected to a process of stepwise refinement, producing a sequence of relational specifications the last of which directly represents a program, and this program is then correct by derivation. These notes attempt a general introduction into relational specification and refinement concepts, and present a selection of program derivation calculi based on these. 1
Email:
[email protected]. Part of this work was completed during the author’s appointment at Universit¨ at der Bundeswehr M¨ unchen.
c 2003 Published by Elsevier Science B. V.
51
Kahl
In the next section we discuss the spectrum of languages used to handle relations and present the language we are going to use for the rest of the paper, together with some useful vocabulary. Section 3 starts from the motivational basis for different concepts of satisfaction of specifications and shows how such satisfaction concepts induce corresponding refinement concepts. Most of these refinement concepts find their application in some approach to relational refinement; the following sections present prominent approaches: •
Section 4 presents the Bird-Meertens-Backhouse calculus with its emphasis on elegant derivation of recursive algorithms using datatypes identified by relators.
•
In Sect. 5, after a very quick overview of important parts of the specification notation Z, we adapt Z by making the state transition relations encoded by Z operation schemas explicit; this allows us to use operation schemas as a concise notation for concrete relations in the next section.
•
The demonic calculus of relations has been introduced by many researchers in similar ways; in Sect. 6 we present it in the pure relation-algebraic style and make its close relation with refinement in Z explicit.
•
The fork-algebraic programming calculus presents a different way to connect predicate-logic specifications with relation algebraic program derivations, which we shortly sketch in Sect. 7.
•
While the previous sections all treat variants of so-called program refinement, Sect. 8 introduces data refinement just to the extent that some connections to program refinement can be established.
For much of the material presented here, more background can be found in e.g. in different chapters of [11]; we provide additional references to the related literature in the individual sections.
2
Languages of Relations
For denoting relations and arguing about relations in the context of program refinement and derivation, we need languages that •
provide means to express concrete relations that serve as specifications or program building blocks,
•
allow to build component-free relational expressions with a structure that is accessible to algebraic transformations, and
•
allow to express the rules of a relational calculus that justifies these transformations.
Frequently, relations are introduced from the set-theoretic point of view, where a relation is a subset of a Cartesian product of two sets. From this, the relational operations can be defined, and their properties shown. In such settings, element-wise arguments still remain possible, and there is a real
52
Kahl
danger that derivations become less reusable if they are conducted on a lower level of abstraction than necessary. The opposite approach is to start from the signature and properties of the operations — this is the approach of relation algebras. In the realm of functions instead of relations, the corresponding approach is category theory, and it is nowadays quite usual to consider relation algebras as special kinds of categories. Concrete relations, that is, subsets of Cartesian products, are then just one particular instance of relation algebras, and results obtained on an abstract relation algebraic level become very reusable, just like category theoretic results are reusable across a wide spectrum of applications in mathematics and computer science. Therefore, for high-level reasoning about relations, a component-free, relation algebraic approach is most natural and desirable. An early proponent of such a purely relation algebraic approach to program development is M¨oller [47]; the disadvantage of this purity is that the frequently necessary reference to concrete relations and properties can become quite awkward. To avoid such awkwardness, some systematic way to interface relationalgebraic arguments with concrete relations is needed. Although in the sequel, the language of a certain kind of algebra of relations will be used predominantly, from Sect. 5 on we experiment with a notationally “light-weight” approach to integrate concrete relations denoted by Z operation schemas. For a set of notations that allow to carefully elaborate all conceptual distinctions between the concrete and abstract views see [38]. Algebras of relations come in several flavours: •
Homogeneous relation algebras consider relations on a single universe, so for example intersection or composition are defined for arbitrary binary relations.
•
Heterogeneous relation algebras consider every relation as having associated with it a source and a target. Then, for every application of union and intersection, all arguments need to be relations with equal source and target, and for a composition R ;S , the target of R needs to be equal to the source of S .
For most applications in the context of software, the heterogeneous approach is preferable, mostly for the same reasons that also support static typing in programming languages. Even in the literature on heterogeneous relation algebras, however, there are still quite different approaches for selecting the source and target entities of relations: •
The view of a heterogeneous relation algebra as a partial algebra [58,62] does not mention these entities at all, but resorts to side conditions along the lines of “where the following compositions are defined . . .”.
53
Kahl •
Freyd and Scedrov’s definition of allegories [25, 2.11] uses source and target operations that yield identity relations. Like the previous approach, this gives rise to a single-sorted language of relations.
•
Modern views of abstract heterogeneous relation algebras (see e.g. [61]) use the language of category theory (see e.g. [5] for an accessible introduction) and mention objects that occur as source and target of relations — this gives rise to a two-sorted language. 2
•
Relational languages that are embedded in typed set theories (like Z, see Sect. 5 below) use types (usually special sets) as source and target of relations.
We use a definition in the style of [61]: Definition 2.1 In a heterogeneous relation algebra, there are objects A, B, . . . and relations R, S , . . ., and the following operations are provided: • Every relation R has a source object source(R) and a target object target(R). For two objects A and B, we let A ↔ B denote the set of all relations with source object A and target object B. Therefore, a relation R : A ↔ B has source A and target B. •
The set A ↔ B of all relations between A and B is a complete Boolean lattice with inclusion ⊆, union ∪, intersection ∩, universal relation A,B , and empty relation A,B . The complement of R : A ↔ B is written R. (We usually omit the indices and write just and .)
•
The composition R ;S of two relations R and S is defined iff target(R) = source(S ), and then it is an element of source(R) ↔ target(S ). The composition operation is associative.
•
For every object A there is an identity relation A , and for every relation R we have source(R) ;R = R and R ;target(R) = R. (Where the object is clear from the context, we frequently omit the index and just write .)
•
The converse of R : A ↔ B is R : B ↔ A, and for all objects A, B, and C, and for all relations R : A ↔ B, P : A ↔ C, and Q : C ↔ B, the Dedekind rule holds:
R ∩ P ;Q ⊆ (P ∩ R ;Q );(Q ∩ P ;R) The standard models for the axioms of heterogeneous relation algebra consider some collection of sets as objects, and for two sets A and B, the relations between them are essentially the subsets of the Cartesian product A × B, also called concrete relations. 2
Category theory mostly uses the word “domain” where we use “source”, and “codomain” where we use “target”. Since for relations, the word “domain” continues to be used in its traditional meaning of “domain of definition”, we stick with “source” and “target”.
54
Kahl
For concrete relations R : A ↔ B and S : B ↔ C, the composition can be defined via a translation into an existential quantification: for all x : A and z : C we have (x , z ) ∈ (R ;S )
∃ y : B • (x , y) ∈ R ∧ (y, z ) ∈ S .
iff
The effect that predicate-logic quantifications are reduced to algebraic operations is the main advantage of using relation algebraic calculations over arguments on the level of predicate logics. Besides the operations from the above definitions, we will also use the following non-primitive purely relation-algebraic operations: •
For every object A, we let PId A denote the set of partial identities on A, i.e. the set of relations contained in A . Partial identities are sometimes also called “coreflexives” [25] or “monotypes” [1,20]; their importance can be understood from the fact that in relation algebras where objects are sets, partial identities are one way to identify subsets of objects. For a partial identity p, we let p ∼ denote the negation of p as a partial identity, that is, p ∼ := ∩ p.
•
Many useful properties of relations have simple relation-algebraic formulations. In particular, a relation R : A ↔ B is called univalent, or a function, iff R;R ⊆ B , total iff A ⊆ R;R, and a mapping iff it is univalent and total. Dually, R is called injective iff R ;R ⊆ A , surjective iff B ⊆ R;R, and bijective iff it is injective and surjective. We use some of the arrows of the Z notation: A →
B is the set of univalent relations (partial functions) from A to B; in the same way, → is used for mappings (total functions), and → for bijective mappings.
•
For every relation R : A ↔ B, we define domR to be that partial identity from PId A which corresponds to the domain (of definition) of R:
domR := A ∩ R;R ; analogously, ranR : PId B corresponds to the range of R, with
ranR := B ∩ R ;R . •
we use / as the left residual operator, and \ for the right residual ; these are the residuations arising from composition in the following way (with R, X : A ↔ B; S , Y : B ↔ C, and Q : A ↔ C): R ;Y ⊆ Q
⇔ Y ⊆ R\Q ,
or, equivalently,
R\Q = R;Q ;
X ;S ⊆ Q
⇔ X ⊆ Q/S ,
or, equivalently,
Q/S = Q ;S .
55
Kahl
For concrete relations Q : A ↔ C; R : A ↔ B, and S : B ↔ C between sets, the residuals translate into universal quantifications — for all x : A; y : B and z : C we have: (y, z ) ∈ (R\Q)
iff
∀ x : A • (x , y) ∈ R ⇒ (x , z ) ∈ Q ;
(x , y) ∈ (Q/S )
iff
∀ z : C • (y, z ) ∈ S ⇒ (x , z ) ∈ Q .
The importance of residuals in software development was emphasised already in [34,33], where the left residual is called weakest prespecification (and denoted in a different way). •
For a homogeneous relation R : A ↔ A, we denote its reflexive and transitive closure by R ∗ . Relation-algebraically, this is the meet of all relations X : A ↔ A that are both reflexive (A ⊆ X ) and transitive (X ;X ⊆ X ) and contain R, i.e., R ⊆ X . This meet exists since A ↔ A is a complete lattice.
Our introduction of relation algebras of concrete relations above was, in fact, quite sloppy: since in a heterogeneous relation algebra there needs to be a way to determine source and target for arbitrary relations, we cannot directly use concrete relations, since then we would not be able to determine, e.g., the source of the empty set understood as empty concrete relation — there is an empty relation between any two sets. In the heterogeneous relation algebra of concrete relations between sets, a relation is therefore a concrete relation together with the information which sets are its source and its target. Nevertheless, this relation algebra is frequently called the “heterogeneous relation algebra of sets and concrete relations” — this sloppiness seems to be usual where category theoretic formulations are used. We now make this precise: Definition 2.2 We let Rel denote the heterogeneous relation algebra that has sets as objects, and for two sets A and B, the set of relations between A and B is the set containing the triple (A, R, B) for every subset R of A × B. The relation algebra contained in the specification notation Z (see Sect. 5) differs from Rel in that not all sets, but only certain sets, known as types, are provided as objects — we denote this relation algebra as Zed . In order to reduce notational ballast, we usually just write R instead of (A, R, B) and assume that A and B are clear from the context. This approach is an informal variant of the typing system of Z; there, type inference spares users the burden of having to provide type annotations for all relations (or expressions), but a specification is only legal if for every relation R only one type annotation R : A ↔ B can be inferred.
56
Kahl
3
Relational Refinement Concepts
Specifications are usually loose, i.e., not monomorphic; rather, a single specification S usually allows many different implementations that all satisfy the specification S . Refining a specification S means providing another specification S such that every implementation that satisfies S also satisfies S . Under these circumstances, S is called a refinement of S . Therefore, a refinement concept requires •
a concept of specification, formalised as a set S of specifications;
•
a concept of implementations, frequently called programs, formalised as a set P of programs, and
•
a concept of satisfaction of a specification by an implementation, formalised as a relation S : P ↔ S between programs and specifications.
With this context, the above definition of refinement can be formalised in a relation-algebraic way: Definition 3.1 Given a satisfaction relation S : P ↔ S, the refinement relation induced by S is the relation S\S, which is an element of S ↔ S. Properties of the right residual imply reflexivity ⊆ S\S and transitivity (S\S);(S\S) ⊆ S\S of this refinement relation, so we have: Lemma 3.2 Every refinement relation that is induced by a satisfaction relation is a preorder. Frequently, satisfaction is not defined directly as a relation between programs and specifications, but rather as a relation between meanings of programs and meanings of specifications. Since specifications and programs usually are syntactic constructs, the move to their meaning as mathematical objects eases formal argumentation. One special (but frequent) case is that the same mathematical objects are used as meanings of both specifications and programs; in many practical cases this lets the satisfaction relation and the refinement relation coincide: Theorem 3.3 If the set of meanings of programs and the set of meanings of specifications coincide, and if the satisfaction relation is a preorder on that set, then the refinement relation is equal to the satisfaction relation. PROOF: Let S denote the satisfaction relation. If S is reflexive and transitive, then properties of the right residual prove equality of the refinement relation S \S with S : S \S ⊆ \S = S ⊆ S \(S ;S ) = S \S This result helps to understand the frequent lack of distinction between satisfaction and refinement, and even between specifications and (nondeterministic) programs in the refinement literature.
57
Kahl
Refinement can be applied to whole programs, or to single modules (typically abstract datatypes, or state transition systems). For program refinement, we consider the meaning of a program to be its input/output behaviour, considered as a relation. The program specification expresses requirements on this input/output behaviour, and can also be expressed as a relation. Therefore, program refinement relates two relations of the same type. For data refinement, one considers an abstract datatype, i.e., a datatype with operations (or a state space with transitions), and an implementation will consist of some concrete datatype with concrete operations. So here we have two tuples of relations (one relation for every operation or state transition) that “act” on different types, the first on the abstract datatype (or state space), and the second on the concrete datatype resp. state space. Data refinement relates these two tuples employing abstraction relations from the concrete to the abstract spaces. In the sequel we shall consider only program refinement; we shall talk about data refinement only shortly as the topic of Sect. 8. Programs are expressed in some programming language and denote some meaning. In the relational approach, this meaning is a relation, reflecting, in the simplest case, the relation between inputs provided to the program and outputs produced by the program in reaction to these inputs. In the general case, calls to file systems and other operation system services also have to be considered as outputs, and reactions of the operating system to these calls have to be considered as inputs. Mechanisms for this are familiar in denotational semantics, and mostly can be explained from the more general point of view where one considers a program as inducing a state transition of a part of the “real world”. Then, the meaning of the program is a relation between states. Instead of a relation, in many approaches to denotational semantics, a program is assigned a function from inputs to outputs. Since functions are special cases of relations, these approaches can still be used within the relational setting. However, using relations has several advantages: •
A simple, “built-in” treatment of partial operations is available.
•
Since specifications denote relations, as discussed below, a program can be considered as a special case of a specification.
Frequently, a third advantage is put forward: •
If nondeterminism is built into the language, that can easily be accommodated.
However, nondeterminism and loose specifications are two quite different affairs, as will be discussed below. As an example for mapping programs to relations instead of to functions, we sketch a standard relational semantics for a simple programming language
58
Kahl
fragment. We denote the relational meaning of program P by [[ P ]], and this is a relation on the states of the machine executing the program. The relational meaning of a Boolean condition b is denoted by [[ b ]]c ; this is a partial identity on the same states. Since we do not want to get into the details of expression semantics here, we sketch the semantics of assignment only informally: For an assignment x := e, the semantics will be a relation that relates state s with state s if and only if s differs from s at most in the value assigned to the variable x, and the value assigned to x in s results from evaluating the expression e in the original state s. For control structures, we have the following relational semantics: [[ skip ]]
=
[[ R; S ]]
= [[ R ]];[[ S ]]
; [[ if b then R else S fi ]] = [[ b ]]c;[[ R ]] ∪ [[ b ]]∼ c [[ S ]]
[[ while b do R od ]]
= ([[ b ]]c;[[ R ]])∗;[[ b ]]∼ c
For deterministic programs, if we have R = [[ P ]], then this means: i) For every input in the domain of R, every execution of P terminates. ii) For every input outside the domain of R, no execution of P terminates. iii) R associates with every input precisely those outputs that can be obtained by terminating executions of P . For non-deterministic programs, we still have ii) and iii), but instead of i) we only have: i’) For every input in the domain of R, there exists at least one terminating execution of P . For conditions b, the condition semantics [[ b ]]c directly represents the set of states where b evaluates to True, and it is assumed that in all other states, b evaluates to False, so this approach is not appropriate for languages where it is possible that the evaluation of a boolean condition does not terminate. For the sake of simplicity we stick with this restriction; it is in fact not hard to design a different kind of semantics for boolean conditions and adapt the semantics of if -statements and while-loops accordingly. For most purposes, i’) is far too week, so simple relational semantics only really makes sense for deterministic programs. For non-deterministic programs, the semantics needs to express the possibility that for some inputs, both termination and nontermination are possible, while for other inputs the program always terminates. Therefore, more complex mathematical objects need to be used. Among the possibilities are the following:
59
Kahl •
Instead of relations on the set of legal states, use relations from legal states to a “lifted” state set containing all legal states and in addition one “illegal state” standing for nontermination.
•
Parnas’ LD-relations, see below.
•
In an attempt to provide maximum generality, Winter [68] considers a programming language that features three different nondeterministic choice operators, and defines the semantics of a program essentially as a pair of relations between sets of non-empty subsets of lifted domains. In a certain way, this can be considered as encompassing the other two approaches.
For the time being, let us restrict ourselves to an understanding of program semantics that includes i). One way to deal with specification semantics is to express specifications in a language that comprises the programming language as a sub-language; the correspondingly extended semantics then turns specifications into generalised programs. It can also be seen as turning programs into specialised specifications. With that background, the question for the meaning of the statement of “R refines S ” for two relational specifications R and S is then frequently expressed as a statement about programs. For example, de Roever explains the meaning of “R refines S ” in the following way [13]: “Using R, no possible observation shows that we are not using S .” Reformulated as a definition of satisfaction of a specification S by a program P , we could say: “No possible observation of P shows that it is not satisfying S .” But all this only leaves us with another question: What are “possible observations”? •
Any result delivered by R for some input obviously is a possible observation.
•
Can we observe nontermination of R for some input? One might argue that in some cases we can, in particular where run-time errors are treated as semantically equivalent to nontermination.
•
Can we observe behaviour of R for all possible inputs, or only for inputs for which S is defined? The former assumes that we can test R on its own; the latter reflects the fact that S may only be defined for possible inputs, and undefined for inputs that are known to be impossible, for example for reasons of the run-time environment. (Parnas and Madey [54] present a clean way to formalise the latter point of view by making the constraints imposed by the environment explicit in a second relation.)
60
Kahl
Different answers to these questions first of all determine different satisfaction concepts, and then by way of Def. 3.1 also different refinement concepts. We now show how different concepts of satisfaction of relational specifications result from different views about what constitutes specified behaviour and what constitutes an observable deviation from the specified behaviour. Let us assume P and S are relations between inputs and outputs, where P is considered as (the meaning of) a program, and S is considered as (the meaning of) a specification. We now describe four different interpretations of the statement “P satisfies S ”: Partial correctness: for every input for which P is defined, all results delivered by P for this input are explicitly allowed by S . This implies that if S is not defined for some input, then P also must not be defined there. This is simply inclusion of relations, denoted by P ⊆S . It can be explained as reflecting two assumptions: Non-definedness of a specification for some input specifies that this input is illegal and should be treated as an error: no output should be produced for it. • Only outputs can be observed; nontermination cannot be observed. This implies that termination cannot be specified; in the inclusion sense, the empty relation satisfies every specification. •
Reduction of nondeterminism: P is defined exactly where S is defined, and has only results allowed by S : S ; ∩ P ⊆ S
and
P ; = S ;
In this paper, we denote this by P S . (Note that this symbol is frequently used for other purposes.) This can be understood as reflecting the assumptions that both outputs and nontermination are observable: • If a specification is not defined for some input, then it specifies nontermination for that input, and producing an output is not allowed. • If a specification is defined for some input, then nontermination is not allowed, and only the specified outputs are allowed. Total correctness: P is defined at least where S is defined, and there, P has only results allowed by S : S ; ∩ P ⊆ S
and
61
P ; ⊇ S ;
Kahl
With our choice of symbol for this satisfaction concept we follow a large part of the literature: P S . Here we have the assumption that nontermination can be observed, but not specified: • If a specification is defined for some input, then nontermination is not allowed, and only the specified outputs are allowed, as for . • If a specification is not defined for some input, then it imposes no constraint on the behaviour for that input: both nontermination and producing arbitrary output satisfy that aspect of the specification. Domain extension: where S is defined, P behaves exactly as S : S ; ∩ P = S This is the converse of the prerestriction ordering introduced in [49] (see also [21]); therefore we denote it as P S . We are using this as an auxiliary concept. If we were to seriously consider it as a satisfaction concept, then it would reflect the following assumptions: • Nontermination cannot be specified. • Incapability to produce a certain output is observable. Since these satisfaction concepts all are orderings, Theorem 3.3 shows that they coincide with the respective refinement concepts. An interesting fact is that these refinement (and satisfaction) concepts can be expressed in very similar shapes: R⊆S
is equivalent to:
S ; ∩ R ⊆ S
and R ; ⊆ S ;
RS
is equivalent to:
S ; ∩ R ⊆ S
and R ; = S ;
RS
is equivalent to:
S ; ∩ R ⊆ S
and R ; ⊇ S ;
RS
is equivalent to:
S ; ∩ R = S
and R
⊇S
There are useful relations between these variants: •
Domain extension is conjunction of containment and refinement for total correctness [21]: RS
is equivalent to:
S ⊆R
and R S
This is obvious from the above. Reformulated on the level of relations between relations, this reads: ( )=( ⊇ )∩( )
62
Kahl •
Reduction of nondeterminism commutes with domain extension: ( );( ) = ( );( )
•
This combination of domain extension and reduction of nondeterminism is in fact just refinement “” for total correctness: ∗ ( ) = ( );( ) = ( ) ∪ ( ) Therefore, all reductions of nondeterminism and all domain extensions are refinements for total correctness, and every refinement for total correctness can be understood as a sequence of steps that each are either a reduction of nondeterminism or a domain extension.
The four refinement concepts presented above share the characteristic that the meanings of specifications and programs both are simple relations from inputs to outputs. We have seen that the different refinement concepts were able to impose different kinds of constraints on implementations, but also that some desirable conjunctions of constraints could not be expressed in a single satisfaction concept — this is a consequence of the simplicity of the semantics. One approach that obtains in a higher expressivity of program descriptions in exchange for a slightly more complicated representation is that of Parnas’ LD-relations (limited-domain relations) [52,53], also introduced by Nipkow without a special name in the context of data refinement in [50]. With LDrelations, an appropriate generalisation of the relational program semantics of above yields the semantics of a program as consisting of a relation R from inputs to outputs and in addition a subset c of the domain of definition of that relation, called competence set, with the following meaning: •
the relation R associates every input with precisely those outputs that can be obtained via some terminating execution;
•
for every input in the competence set, execution is guaranteed to terminate;
•
for every input outside the competence set, nontermination is possible.
LD-relations can also be used as specifications — with the interpretation that for inputs outside the competence set, nontermination is allowed, and termination is only allowed if its result is explicitly permitted by the relation: A program P = (RP , cP ) satisfies a specification S = (RS , cS ) iff cS ⊆ cP and RP ⊆ RS . This reflects the assumptions that not only terminating in some result state is observable and specifiable, but that nontermination, too, is observable and specifiable. It is easy to see that outside the competence set, this satisfaction concept corresponds to inclusion, and inside the competence set, to reduction of nondeterminism. In addition, it corresponds to total correctness everywhere except on that part of the domain of RS that lies outside the competence set cS . Therefore, ⊆ and can be regained as special cases of LD-relation refinement.
63
Kahl
4
Relational Datatypes and Generic Programming
The Bird-Meertens approach [9,45] to calculational program derivation, emphasising algebraic, component-free calculations, originally concentrated on functional specifications and programs, pushing higher-order functions and generic approaches to deal with initial algebraic datatypes. However, under many circumstances functional specifications were recognised as not fully appropriate, since for example in some optimisation problems, there might not be a unique optimum, and an algorithm that just delivers any optimum should be considered as satisfying the specification. Therefore, a shift towards the use of relational specifications and program derivations via relation-algebraic calculations has taken place. The very influential draft book [1] by Backhouse and his colleagues established a “A Relational Theory of Datatypes” centred around the concept of relators that had originally been introduced in [42]. A nice summary is [20], which contains a more detailed exposition of the material skimmed over in this section; a difference in the style of formalisation is that we “make the typing more explicit” by using our setting of heterogeneous relation algebras. The textbook “Algebra of Programming” by Bird and de Moor [10] constitutes a further culmination of that trend towards considering the derivation of functional programs in a relational framework. It employs a relational approach, using the framework of categories and allegories [25], and uses relational calculus for algorithm derivation in fields like optimisation problems, dynamic programming, and greedy algorithms. For matters of style, one can find therein an encouragement to avoid the relational complement, “since the number of rules in the relational calculus becomes quite unmanageable when boolean negation is considered”. The concept of refinement employed in the Bird-Meertens approach is sometimes reduction of non-determinism , and otherwise inclusion ⊆. An important ingredient of this approach is that it abstracts away from specific datatype constructions and therefore allows arguments that are independent from the choice of datatype constructions. It therefore forms an important foundation of generic programming (see, e.g., [3]); the extension to relations brings more flexibility in specification and program derivation. The basis of abstraction from specific datatype constructions is provided by the category-theoretic concept of functor and its extension to the concept of relator. Since our arguments are all within the context of a single category or allegory or heterogeneous relation algebra, we restrict ourselves to endofunctors, even if we follow common usage in this field and just use the word “functor”. Definition 4.1 (Relators) In the context of a heterogeneous relation algebra, a total function F mapping objects to objects and relations to relations is a functor iff it enjoys the following properties:
64
Kahl •
F preserves source and target:
F (source(R)) = source(F (R)) F (target(R)) = target(F (R)) F (A ) = F (A)
•
F preserves identities:
•
F distributes over composition:
F (R ;S ) = F (R);F (S )
A functor F is a relator iff it satisfies two additional laws: •
F distributes over converse:
F (R) = (F (R))
•
F is monotonic:
R ⊆ S ⇒ F (R) ⊆ F (S )
Most important datatype constructions are relators: •
One of the most pervasive datatype constructions is the direct (or Cartesian) product construction; this gives rise to the binary product relator ×. For two objects A and B, their direct product is denoted A × B. Associated with such a product are two surjective projection mappings πA,B : A × B ↔ A and ρA,B : A × B ↔ B. The following properties of the projections are used to characterise direct products in general relation algebras (let π = πA,B and ρ = ρA,B ):
π ;π = domA,B
ρ ;ρ = ranA,B
π ;ρ = A,B
π;π ∩ ρ;ρ = A×B
(For non-empty sets, domA,B = A and ranA,B = B .) For more information about direct products in relation algebras see for example [7,15]. The projections can be used to define the relation part of the product relator: For two relations R : A ↔ C and S : B ↔ D, their direct product R × S is a relation in (A × B) ↔ (C × D) and can be defined in the following way: R × S := πA,B ;R;πC,D ∩ ρA,B ;s ;ρC,D •
Behind the use of alternatives in datatype constructions is the sum relator that associates with two objects A and B their direct sum A + B; for sets, this is the disjoint union.
•
The simplest relators are the identical relator Id that is the identity function on objects and relations, and constant relators that map every object to some constant object, and every relation to the identity relation on that constant object. An important constant relator is which maps every object to a “singleton object”, also denoted . With sets, the object is some singleton set; where it is necessary to explicitly determine this set, a usual choice is := {⊥}.
•
Recursive datatype relators like those for lists and trees are defined via initial algebras, to be introduced now.
For a functor F and an object (set) A, a mapping (total and univalent relation)
65
Kahl
from F (A) to A is called an F -algebra over the carrier A. An F -algebra homomorphism from a : F (A) → A to b : F (B) → B is a mapping f : A → B with a ;f = F (b);b. An initial F -algebra i is an F -algebra for which there are F -algebra homomorphisms from i to all F -algebras. For example, if F (X ) = + A × X for some set A, then the initial algebra for F is the natural isomorphism from F (seq A) to seq(A), where seq A denotes the set of finite lists with elements taken from A. In general, initial algebras correspond to recursive datatypes, and by using functors or relators as parameters in developments, it is now possible to argue in general over common patterns of recursive algorithms connected with recursive datatypes, without committing to any specific relator. Let F be a relator, and α : F (T ) → T be its initial algebra. Assuming two relations Q : A ↔ F (A) and R : F (B) ↔ B, the following recursive program scheme instances are defined: •
the catamorphism, also called fold, or primitive recursion 3 : ([R]) : T ↔ B with X = ([R]) ⇔ X = α ;F (X );R ;
•
the anamorphism (or unfold): (Q)! : A ↔ T with X = (Q)!
•
X = Q ;F (X );α ;
⇔
the hylomorphism: (Q)!;([R]) : A ↔ B is the least solution of the hyloequation X = Q ;F (X );R In this composition of two recursive programs, the relator F defines the intermediate data structure.
Program derivation using relators strives to implement a given relational specification S : A ↔ B, and proceeds in the following way: •
Determine a relator F and relations Q : A ↔ F (A) and R : F (B) ↔ B such that Q ;F (S );R ⊆ S ,
•
where Q is F -reductive, see below;
Then the hylo-equation X = Q ;F (X );R has the (unique) solution (X = (Q)!;([R])) . From implementations for Q and R, this solution immediately produces an implementation for S .
•
While Q and R are not directly implementable, iterate the implementation process for them.
3
This generalised kind of primitive recursion uses elements of arbitrary recursive data type instead of just natural numbers.
66
Kahl
The following examples show how problem-solving strategies determine intermediate data structures, i.e., relators: •
repetition: F (X ) = A + X
•
divide-and-conquer (as in merge sort, for example): F (X ) = A+(X ×X )
•
list or stack: F (X ) = + (A × X )
•
non-empty list or stack: F (X ) = A + (A × X )
The reductivity property used above is a generalisation of well-foundedness; a relation is Id-reductive precisely if it well-founded. The general definition involves residuals: A relation Q : A ↔ F (A) is F -reductive iff for all partial identities X ⊆ A , X = ( ;F (X ))/Q ∩ A
⇒
X = A .
Reductivity of Q enforces termination of (Q)! considered as a program, and thus totality of (Q)!;([R]) as a relation. This section, although it could present only a very condensed sampling, hopefully has given the reader a first idea of the mathematical elegance and power of the algebraic tools and theorems of the Bird-Meertens-Backhouse approach to calculational program derivation using relations and relators. The textbook [10] and more recent applications like [12] show that this field is currently moving from what was almost a “fine art” to a practically useful program derivation method. In our opinion, one of the main obstacles to its more wide-spread adoption is the lack of support systems that encapsulate all this mathematical knowledge and assist the user in its application.
5
Z Operation Schemas as Relations
Although some purely relation-algebraic approaches to relational specification could be considered as being close to abstract specification techniques like that of algebraic datatypes, most relational approaches to software specification are, by virtue of their use of concrete relations, in general closer to the modeloriented specification methods. There are several formal model-oriented specification methods; the most well-known are the following: VDM, the Vienna Definition Method [40], places particular emphasis on being a method for correct software development from specifications; for its semantics it uses a logics of partial functions, and specifications are presented as combinations of pre- and postconditions. Z was developed as a systematic mathematical notation for capturing requirements and writing specifications. An important structuring tool is its schema notation, which leads to specifications with a relational semantics.
67
Kahl
B, developed by Abrial [2] after his work on Z, centres around an “abstract machine notation” for specifications in all stages of the software development process, and uses a predicate transformer semantics. It is a “wide-spectrum” notation that includes an executable subset; the B-method supports the whole development process. Among these, the one that most naturally supports a component-free and relational style of specification and argument is Z. We now present Z in some detail for several reasons. On the one hand, many building blocks of specifications are more or less involved concrete relations; since Z provides a mature, well-defined mathematical notation containing useful tools for the definition of concrete relations, it comes in handy for this purpose. On the other hand, refinement as traditionally handled in Z is very closely related to relation-algebraic refinement using the refinement relation , although this close relation seems not to have been made explicit so far. Therefore, we explain this in more detail in Sect. 6 and argue that both approaches can profit from this connection. The traditional reference for Z is [64]. The recent Z standardisation process [36] brought with it several changes, simplifications and additions, see [65]. For the purposes of these notes, the only item where these differences are important is that we employ the binding notation from the standard. Z is essentially a standardised mathematical notation, based on a typed variant of ZF set theory, that has been designed as a model-oriented specification language. Z features a simple decidable type system where opaque application-dependent types and, usually, the set Z of integers serve as base types; types with more structure are obtained via the powerset operator P and Cartesian products, and as schema types (which correspond to the record types of many programming languages). In this type system, relations are subsets of Cartesian products, and enjoy no special treatment. The “mathematical toolkit” of Z, a kind of standard library, includes the following notations relevant for relations: •
set operations that also can be used on relations, like intersection ∩ and union ∪ ,
•
relational operators: ∼ for converse and o9 for composition (neither of these two will be used in these notes; we stick with the relation-algebraic notation introduced in Def. 2.1);
•
Peirce algebra operators, that is, operators that connect relations and subsets of their source and target sets: · For a Z relation R : A ↔ B, dom R denotes the domain of definition as a subset of A: dom R = {x : A | (∃ y : B • (x , y) ∈ R)} = {p : R • first p} Therefore, for a Z relation R, we regain the partial-identity representation
68
Kahl
(defined in Sect. 2 and written in a sans-serif font) of the domain in the following way: domR = {x : dom R • (x , x )} . · Analogously, ran R is the range of R. · There are domain- and range-restriction and -subtraction operators , − , , − . · The relational image R(| S |) of a set S under a relation R can be considered as a simple abbreviation using a domain restriction: R(| S |) = ran (S R) The most important specification-specific feature of Z is that it provides the so-called schema notation: a state schema defines a state space via state components and an invariant connecting these components; an operation schema is used to specify an operation of some system by relating states before the operation (and possible inputs) with states after the operation (and possible outputs). Schemas can be written directly using the schema notation, or can be constructed using the operators of the schema calculus. The standard notation for schemas uses the so-called “schema boxes” as graphical structuring elements; the following is a simple state schema: State x, y : N y ≤x The same schema definition can also be written in an in-line notation: State == [x , y : N | y ≤ x ] This schema definition introduces a state space State where each element is a binding containing two components x and y that have to satisfy the invariant y ≤ x . Examples for such bindings are the following: { &| x == 0, y == 0 |', &| x == 1, y == 0 |', &| x == 1, y == 1 |', &| x == 2, y == 0 |', &| x == 2, y == 1 |', &| x == 2, y == 2 |', . . .} Since in Z, the set N of the natural numbers is not a type itself, but only an element of the type P Z, the declaration x , y : N is an abbreviation of the type declaration x , y : Z together with the predicate x ∈ N ∧ y ∈ N, which should really be considered as part of the schema’s invariant. Making this explicit is called schema normalisation; a normalised schema has only types in its declarations. The above State schema normalises to the following (employing the convention that separate lines of the invariant are connected by conjunction unless another operator is provided):
69
Kahl
State x, y : Z x ∈N∧y ∈N y ≤x A normalised schema without invariant is a schema type; the schema type associated with our State schema therefore is [x : Z; y : Z]. Formally, the above schema definition introduces State as an identifier bound to that subset of this schema type that contains precisely those elements for which the invariant y ≤ x holds. The schema calculus provides a set of operators for schemas that allow to construct component-free schema expressions. Those schema operators that we are going to use will to be explained in more detail below; here just a short overview (note that some of these operators have the same shapes as certain logical and relational operators, but are nevertheless considered as distinct): •
Schema conjunction ∧ is essentially intersection of binding sets.
•
Schema disjunction ∨ is essentially union of binding sets.
•
Schema negation ¬ is complement of binding sets (within the respective types).
•
Hiding is projection to sub-schema-types.
•
Renaming transforms binding sets by replacing (some) component names with others.
•
Schema decoration, e.g. suffixing a schema name with , transforms binding sets by decorating all component names in all bindings (this is a special case of renaming).
•
Schema composition o9 is sequential composition of operation schemas operating on the same states, see below.
•
Piping >> is sequential composition of operation schemas operating on different parts of a global state, connecting the outputs of the first operand to the inputs of the second.
Schemas can also serve as predicates or replace “schema text” in declarations. The operations are more intuitively reflected in the invariants of schemas that are equivalent to the corresponding schema expressions; let us start with the following two schemas: S1 x, y : N
S2 y, z : Z
y ≤x
z =2∗y
Notice that y has different declarations in the two schemas; this is allowed since both are compatible, i.e., in the same type.
70
Kahl
The proper way to obtain explicit schemas representing the result of “logical” schema operators is to normalise the operands, merge the declarations, and then apply the operator to the invariants. Afterwards, it may be possible to undo some normalisation in order to arrive at a more compact result. In our example, this is possible only for schema conjunction: ¬ S1
=
S1 ∧ S2
=
x, y : Z x +∈ N
=
y +∈ N
∧
z =2∗y
∨
y >x
x, y : N z :Z y ≤x
S1 ∨ S2
∨
x , y, z : Z (x ∈ N ∧ y ∈ N ∧ y ≤ x )
∨
z =2∗y
(Schema negation is rarely useful by itself, and schema disjunction is mostly used between schemas where common components have equal declarations.) Schema Decoration is a more technical operation: it acts on the names of all schema components, replacing them with the appropriately decorated variants. For the State schema defined above, we obtain: State
=
x , y : N y ≤ x
Usually, decoration with is used to denote the “after” state in operation schemas. There is a convention that produces a basic operation schema from a state schema via prefixing the state schema’s name with “∆”; the schema ∆State == State ∧ State is used to specify that an operation should start in a state satisfying State, and should also end in such a state. Expansion yields:
∆State
=
x , x , y, y : N y ≤x y ≤ x
Operation schemas usually specify operations by including additional constraints, e.g.:
71
Kahl
Op ∆State x − x ≤ y − y This operation is possible in states that satisfy its precondition, denoted pre Op, and defined by the following schema expression: pre Op
:⇔
∃ State • Op
This just formalises the fact that the precondition of Op is a formula describing all those State bindings for which a State binding exists such that Op is satisfied. Operation schemas can also include components with a “?” decoration, which are intended as inputs to the operation, and components with a “!” decoration, which are intended as outputs of the operation. In the following, the discussion will, for the sake of simplicity, be restricted to operation schemas without inputs and outputs, which we call simple operation schemas. According to the standard Z semantics of schemas, every operation schema denotes a set of bindings in which the state components occur both with and without the decoration. The intuitive meaning of a simple operation schema, however, is a relation on the state type involved, i.e., the schema type containing only the undecorated components. This is also made clear by the (informative) Annex E of the Z Standard [66]: “Each operation is described as a relation between states.” Consider the following simple operation schema: Op ∆State x − x ≤ y − y This denotes a subset of the schema type [x : Z; y : Z; x : Z; y : Z], as follows: Op = { . . . , &| x == 1, y == 0, x == 5, y == 4 |', &| x == 1, y == 0, x == 5, y == 5 |', . . .} By regrouping every the bindings into a pair of two-element bindings, we see that Op induces a relation on the schema type [x : Z; y : Z]; from now on, we denote this relation as [[ Op ]]. Even though this meta-operator [[ ]] has an overloaded type that cannot be expressed in Z, for every schema Op, the induced relation [[ Op ]] can easily be defined in Z, using the binding constructor
72
Kahl
θ and the possibility to use a schema (in this case: Op) as a macro in different contexts, here in set comprehension: [[ Op ]] : [x : N; y : N] ↔ [x : N; y : N] [[ Op ]] = {Op | (θState, θState )} Therefore, for the schema Op as defined above we have: [[ Op ]] = { . . . , &| x == 1, y == 0 |', &| x == 5, y == 4 |' , &| x == 1, y == 0 |', &| x == 5, y == 5 |' , . . .} We now use the notation [[ ]] only for denoting such binary relations induced by operation schemas; these binary relations are of course just isomorphic rearrangements of the standard meaning of operation schemas. Unfortunately, the Z notation does not provide any predefined notation for access to this relational interpretation of operation schemas. Keeping in mind the typing via invariant-free schema types, it is obvious that the schema operations on operation schemas over the same state space directly translate into the corresponding relational operations: [[ Op1 ∧ Op2 ]] = [[ Op1 ]] ∩ [[ Op2 ]] [[ Op1 ∨ Op2 ]] = [[ Op1 ]] ∪ [[ Op2 ]] [[ ¬ Op1 ]] = [[ Op1 ]] [[ Op1 o9 Op2 ]] = [[ Op1 ]];[[ Op2 ]] In addition, precisely the states in dom[[ Op1 ]] satisfy the precondition pre Op1, which can be expressed in Z using the binding construction θ: ∀ State • (pre Op1
⇔
θState ∈ dom[[ Op1 ]])
Since operation schemas are intended to be used as specifications of operations, we have to clarify which satisfaction concept underlies this use. Although this is not defined by the Z Standard, there is general agreement about this in the Z literature. In general, let us consider a simple operation schema: Op ∆State Pred Then the operation schema Op specifies
73
Kahl •
an operation on State
•
that for every state θState fulfilling the precondition pre Op
•
produces a state θState such that the predicate Pred (typically involving components of both of θState and θState ) holds.
We may translate the precondition pre Op as defined by the Z standard into a partial identity just like conditions in programs, and we obtain: [[ pre Op ]]c = [[ ∃ State • Op ]]c = dom[[ Op ]] Since nothing is specified for states that do not fulfil the precondition pre Op, this satisfaction concept obviously is precisely total correctness, or .
6
The Demonic Calculus of Relations
In this section we only recall the definitions and a few properties of the demonic operators as given in [19]; for more background see also e.g. [63,4,8,24,41]. The name “demonic” stems from an understanding of non-univalent specifications as nondeterministic programs. With that understanding, operations on specifications, like disjunction, or sequential compositions, are understood as operations on nondeterministic programs. Therefore, the semantics of these operations has to reflect “demonic nondeterminism” where some malevolent “demon” always makes choices in such a way that program execution will not terminate, if that is at all possible. The more appropriate way to explain these operators is to view them as operators on specifications: Then, the compound specification does not specify termination in cases for which via some component specification termination is not specified. For consistency with the literature, we use the “demonic names” throughout, but rather than referring to demons and nondeterministic programs in our explanations, we consistently use the specification point of view — as mentioned in Sect. 3, we are essentially dealing only with specifications for deterministic programs anyway. For illustrating the demonic operators, the literature mostly uses concrete relations written as sets of pairs, or some ad-hoc binding notation together with set comprehensions. Since the already established schema notation not only includes standardised ways to express relations between binding sets, but also allows to use schema expressions as macros, thus providing powerful abbreviation mechanisms, we shall use schema expressions as our preferred way to express concrete relations between binding spaces. To make the notation less cumbersome, from now on we consider every simple operation schema expression Op as directly denoting the induced relation [[ Op ]], thus making available not only schema operations on such schemas, but also relation-algebraic operations. The consideration of demonic operation on Z schemas has the additional advantage that the demonic operators make the arguments involved in schema
74
Kahl
calculus refinements much more explicit and obvious than the traditional approach using conventional schema calculus operations and totality arguments. In some way, this can be seen as a continuation of the integration of Z into the refinement calculus as proposed in [43]. Let us recapitulate the refinement concept for total correctness: A relation R : A ↔ B refines another relation S : A ↔ B, written R S , iff R ∩ S ; ⊆ S
and
S ; ⊆ R ; .
If R and S are operation schemas, then corresponding schema calculus formulae for specifying refinement are: ∀ R • (pre S ⇒ S )
∀ S • pre R .
and
Let us make the implications of this definition explicit again: •
R has to terminate where S is defined.
•
R can have less non-determinism than S .
•
Partialities in S allow non-termination of R.
•
Where non-termination is allowed, any result is allowed.
An example using concrete relations on Z: {(0, 2), (1, 2)} {(1, 2), (1, 3)} Using operation schemas over the state space [x : Z], this translates into the following: x, x : Z x ∈ {0, 1} ∧ x = 2
x, x : Z x = 1 ∧ x ∈ {2, 3}
The relation is a partial ordering and induces a join semi-lattice [16]. The top element of that semi-lattice is — every relation is a refinement of the “no constraint” specification. The sub-lattice between and is the Boolean lattice of vectors (a vector is a relation v with v ; = v , another representation of a subset of the source object). These vectors only specify termination on the subset they identify, and nothing else; in particular, specifies just totality, i.e., termination everywhere. Below therefore is the ideal of total relations, and the minima are mappings, that is, total and univalent relations. As pointed out by John Pfaltz, the refinement ordering is dual to the closure lattice ordering [55] with respect to the closure operator which maps a relation X : A ↔ B to X ;B,B , the “most non-deterministic” relation with the same domain — in that context, the definition of would be given as a single inclusion chain, equivalent to the conventional condition above: R ∩ S ; ⊆ S ⊆ R ; .
75
Kahl
In [41], we introduced the following auxiliary operation that proves very useful in the context of the demonic calculus of relations: Definition 6.1 For R : A ↔ B, we define its totalisation R • : A ↔ B: R • := R ∪ R ; = R ; → R. If R is an operation schema, then its totalisation is the schema (pre R) ⇒ R. Obviously, R • is always total, and if R total, then R • = R. Furthermore, we have R ⊆ R • R, so R • is a domain extension of R, i.e., R • R. Totalisation is refinement-monotonic: If R S , then R • S • , and, since refinement of total relations is inclusion, R • ⊆ S • . Totalisation can be used for an alternative way to define refinement, which, even though totalisation is not a closure operator, still follows the same pattern as the closure ordering: RS
iff
S ∩ R• ⊆ R ⊆ S • .
As another, very practical form of checking a refinement R S we therefore may use even the combination of the two conditions R ⊆ S • and S ; ⊆ R ;. The least upper bound of two relations R and S with respect to , denoted by R S and called the demonic join, is R S = (R ∪ S ) ∩ R ; ∩ S ; . The demonic join can be understood using the following intuition: P satisfies R S iff for every input, every behaviour of P for this input satisfies R or satisfies S . The following are explicit expressions for calculation demonic joins relationalgebraically and in the schema calculus:
R S = (R ∪ S ) ∩ R ; ∩ S ;
=
R∨S pre R ∧ pre S
As an example join of operation schemas, consider the following where the preconditions overlap just on 1 and 2:
x, x : Z x ≥1 x = x ∗ 2
x, x : Z
=
x ≤2 x = x + 1
76
x, x : Z 1≤x ≤2 x = x ∗ 2 ∨ x = x + 1
Kahl
The greatest lower bound of relations R and S with respect to is denoted by R S and called the demonic meet; such a greatest lower bound exists if and only if R and S are compatible, i.e., the intersection of the domains of R and S is contained in the domain of the intersection of R and S : R; ∩ S ; ⊆ (R ∩ S ); . If R and S are compatible, then the demonic meet can be expressed in different ways; the first is the traditional presentation, and the presentations using totalisation add different points of view towards the understanding of the demonic meet (we use the venturi tube “” to relate two expressions X Y with the meaning that if X is defined, then Y is defined and equal to X , and analogously X Y meaning that if X is defined, then Y is defined and refined by X ): R S (R ∩ S ) ∪ (R ∩ S ;) ∪ (R ; ∩ S ) = (R ∩ S • ) ∪ (R • ∩ S ) = (R ∪ S ) ∩ (R • ∩ S • ) The demonic meet can be understood using the following intuition: P satisfies R S if for every input, every behaviour of P for this input satisfies R and satisfies S . If the domain of two relations is equal, i.e., R ; = S ; (in particular, if R and S are total), then refinement is equivalent to inclusion: R S iff R ⊆ S , and demonic join and meet reduce to conventional join and meet: R S = R ∪ S , and R S = R ∩ S (if the demonic meet is defined). Totalisation, besides allowing shorter and more nicely symmetric presentations of demonic meets, can itself be defined via a demonic meet: R • = R . The demonic meet R S translates most easily into Z from the shape (R ∪ S ) ∩ (R • ∩ S • ), yielding the following schema: R∨S pre R ⇒ R pre S ⇒ S In the following example, the demonic meet is total, producing a slightly simpler shape: x, x : Z x ≥1 x ≤ x ∗ 2
x, x : Z x ≤2 x ≥ x + 1
77
=
x, x : Z x ≥ 1 ⇒ x ≤ x ∗ 2 x ≤ 2 ⇒ x ≥ x + 1
Kahl
Assuming that R and S are compatible, we have special shapes for the demonic meet if the domains of R and S are either equal or disjoint; in the schema calculus these are just schema conjunction and disjunction: • If
∀ State • pre R ⇔ pre S , then: R S = R ∧ S
• If ¬ ∃ State • pre R ∧ pre S , then: R S = R ∨ S Since many uses of schema conjunction and disjunction in practical specifications fall into these categories, this shows that demonic meet already is ubiquitous in schema calculus, although in the guises of restricted uses of schema conjunction and disjunction. Properties of demonic join and meet: R (S T ) (R S ) (R T ) R (S T ) (R S ) (R T ) Definition 6.2 For two relations R : A ↔ B and S : B ↔ C, the demonic composition of R and S is
B; S : B →
C | R R ∧ S S • R ;S } . R ✷ S := {R : A → (If PId B contains at least two elements, we could use total functions instead of partial functions. Since total functions are minimal wrt. , this also might seem more appropriate at first view. However, we still prefer to use partial functions since these are more accurate representations of programs in this context: deterministic, but not necessarily total.) Frequently, the fact that R ✷ S = R ;S ∩ R ;S ; is used as definition of demonic composition. If R and S are operation schemas over State, then R ✷ S is the following schema: R o9 S ∀ State | (θState → θState ) ∈ R • (pre S ) (We assign to and the same binding power as to ∪ and ∩, and to ✷ the same as ;.) Demonic composition is associative and has as identity and as zero; it distributes over and sub-distributes over existing demonic meets, and reduces to the usual composition in two particular cases: If R is univalent, or if S is total, then R ✷ S = R;S .
78
Kahl
The operators , and ✷ are order-preserving in their two arguments; hence, refining an argument yields a refined result. In the case of the demonic meet, however, one must be careful, since refining an argument may lead to an undefined expression. Totalisation also interacts in a useful way with demonic composition: For relations R : A ↔ B and S : B ↔ C we have: •
(R ✷ S )• = (R ;S )• ∪ R;S • .
•
If R is a mapping, then (R ;S )• = R;S • .
•
If S is total and surjective, then (R ;S )• = R •;S .
If F is a surjective mapping and the respective meets exist, then •
(R ✷ F S ) ✷ F R S ✷ F ,
•
F ✷ (F ✷ R S ) (R ∩ F ;S • ) ∪ (R • ∩ F ✷ S ), and
•
if S is total, then even F ✷ (F ✷ R S ) = R F ✷ S .
In analogy with the relational residuals, there also are demonic residuals. Consider three relations Q : A ↔ C; R : A ↔ B, and S : B ↔ C. The demonic left residual 4 Q S is the -greatest solution (in X ) for X ✷ S Q — this exists if Q ; ⊆ (Q/S );S ; , and:
Q S Q/S ∩ ;S . The demonic right residual R Q is the -greatest solution for R ✷ X Q — this exists if Q ; ⊆ R ; and ⊆ (R\Q • );, and: R Q R\Q • ∩ R ;Q ; .
There are many useful algebraic properties of the demonic residuals, see, e.g., [19]. In some cases, there are significant simplifications, for example the following: if Q ;S ;S ⊆ Q, then Q S is defined iff Q ; ⊆ Q ;S ;, and Q S Q ;S . Demonic residuals are useful in the situation where a specification can be refined by a sequential composition, and for one of the operands of that sequential composition a specification is already known. The analogous residuation with respect to demonic meet has two important fields of application: •
It enables an analogous approach to parallel composition, represented via a particular demonic meet, namely the demonic product presented below;
•
it allows to calculate precise specifications for the adaptation of reused components that do not (fully) meet the desired specification.
The demonic implication R S is the loosest specification that, together with 4
originally introduced as “conjugate kernel” in [18]
79
Kahl
R, still enforces S ; formally, it is defined by X R S
⇔
X RS
for all X : A ↔ B.
The demonic implication R S exists iff R S exists, and then (using Boolean implication P → Q = P ∪ Q defined as usual): R S (R • → S • ) ∩ ((R ∩ S • ); ∪ (R ; ∩ S ;)) = ((R ∪ S ) ∩ (R ∩ S • );) ∪ (R ; ∩ S ) •
= (R ∩ S • ) ∪ (S ∩ R ;) The general version of demonic implication presented here has been defined in [41]; a slightly restricted variant (for the case of S R only) had been presented in [46] under the name “refinement difference”; it is used there for introducing refinement distance, which now can be defined in the following way: R ⊗ S := (R S ) (S R) This refinement distance is useful in the component reuse context, see [44]. The demonic product of relations has been introduced in [41] based on the fact that for every direct product with projections π and ρ in a heterogeneous relation algebra, the demonic meet P ✷ π Q ✷ ρ always exists, and the following holds (for the sake of readability, from now on we omit the indices for π and ρ): (P ✷ π Q ✷ ρ ) ✷ (π ✷ R ρ ✷ S ) P ✷ R Q ✷ S . Replacing standard relation-algebraic operators in the definition of the direct product of relations with demonic operators, we obtain: Definition 6.3 The demonic product P Q of two relations P and Q is defined as follows: P Q := π ✷ P ✷ π ρ ✷ Q ✷ ρ It is easy to check that the demonic product can be calculated via the following equalities: P Q = (P × Q • ) ∪ (P • × Q) = (P × Q) ∪ (P × Q ;) ∪ (P ; × Q) The fact that the following is only a refinement, but not an equality, implies that this is an “unsharp product”, and is “not functorial”: (P Q) ✷ (R S ) (P ✷ R) (Q ✷ S ) From the specification point of view this reflects the fact that sequentialisation is a non-trivial refinement step. For the case where a specification P : A × C ↔ B × D and a potential component R : A ↔ B are given, [41] provides an explicit condition for the
80
Kahl
existence of a relation S : C ↔ D such that RS P , and in case of existence, also an explicit formulation for the -maximal specification S . In addition, a sufficient criterion for the possibility of parallel decomposition of some relation is given: Theorem 6.4 Given some relation P : A × C ↔ B × D. If the demonic residuals P1 = π (P ;π) and P2 = ρ (P ;ρ) exist (which is equivalent to ⊆ (π\(P ;π)• ); and ⊆ (ρ\(P ;ρ)• );), and if P = P ;π;π ∩ P ;ρ;ρ, then P has the demonic product decomposition P1 P2 P . A set of methods and theorems supporting program derivation and program adaptation from relational specifications and using the demonic calculus of relations has been assembled under the name of program construction by parts by Frappier [21], see also [22,23]. In the centre of interest is the refinement of relational specifications organised mostly as demonic meets of simpler specifications — since demonic meets can be understood as conjunction of constraints, a component specification can be seen as specifying a particular aspect of the final product. We have seen above that certain demonic meets can be translated into relational join, or schema disjunction — such meets can directly be represented in a program as case analyses. In general, refinement of demonic meets can, to some extent, proceed as refinement of the components, but since that can lead to undefined meets, one needs to proceed carefully. Another way to refine demonic meets is to reorganise them; for this purpose, rules like the following may be used: P1 ✷ P2 Q1 ✷ Q2 (P1 Q1 ) ✷ (P2 Q2 ) (P1 P2 ) (Q1 Q2 ) (P1 Q1 ) (P2 Q2 ) Again it is possible to arrive at undefined meets using these rules. However, in all these cases we have the nice property that if the final refinement is defined, then all the intermediate steps are defined, too, so it is not necessary to check definedness at each step. Yet another approach is to “guess” parts, and then calculate specifications for the remaining components from these, for example using demonic residuals. As a short example of program derivation in the demonic calculus of relations we reformulate the loop derivation example from [19] using the Z schema language for concrete relations. For better integration with the relationalgebraic operations, we shall exclusively use the official in-line presentation of Z schemas, and we consider operation schemas as directly denoting relations. The basis for this derivation is the following theorem (reformulated from [19, Thm. 11.2.4]):
81
Kahl
Theorem 6.5 Given a relation R : A ↔ A, the following three conditions are equivalent: i) R ; ⊆ R ;(R • ∩ ); , ii) there is a c ⊆ A with c ∼ ⊆ R • ∩ and R ; ⊆ R ;c ∼;, iii) there are c ⊆ A and B : A ↔ A such that R is refined by the -greatest fixed point of the function L with L(X ) = c ∼ c ✷ B ✷ X . In the context of iii), the following additional properties are known about B and c: • B (T T ) T , where T := c ; R ; c ∼ , • R ; ⊆ I(c ✷ B ). Here, I( ) associates with a relation R : A ↔ A its initial part [58,62], with: I(R) = {X : A ↔ A | R \X = X } I(R) is always a vector; for concrete relations it designates the set of vertices in the graph R from which no infinite R-paths begin. Note that T T is always defined. Also, ii) implies existence of B as in iii), so for application of this theorem, the easiest route frequently consists of first identifying an appropriate c, and then refining (T T ) T to obtain a B that satisfies the termination property R ; ⊆ I(c ✷ B ). As an example loop calculation, we consider a state space made set up as a state schema containing three integer variables: State
==
[l , m, n : Z]
and a specification R : State ↔ State stating that one of these variables should be multiplied with the power of the other two, presented as an operation schema: R
==
[∆State | n ≥ 0 ∧ l = l × m n ]
(Note that the final values m and n are not specified.) For obtaining the maximal c ∼ with c ∼ ⊆ R • we have to determine circumstances that ensure l = l in the context of R, where l = l × m n : R • ∩ = (R ∪ [∆State | n < 0]) ∩ ΞState = [ΞState | l = 0 ∨ m = 1 ∨ n ≤ 0] (The schema expression ΞState stands, by Z convention, for State .) One possible choice is now c := [ΞState | n > 0], with c ∼ = [ΞState | n ≤ 0]. Then R; ⊆ R ;c ∼; holds, and we can calculate T : T = c ;R ;c ∼ = [ R | n > 0 ∧ n ≤ 0 ]
82
Kahl
In this case, T is difunctional (i.e., T ;T ;T ⊆ T ), which implies T T = T ;T . The latter obviously contains the following invariant:
P == [ ∆State | l × m n = l × m n ] Using P as an abbreviation, we have T T = T ;T = [ P | n > 0 ∧ n > 0 ]
and can start the refinement for B : (T T ) T = (T T ) [ R | n > 0 ∧ n ≤ 0 ] (T T ) [ R | n > 0 ∧ n = 0 ] = [ P | n > 0 ∧ n > 0 ] [ P | n > 0 ∧ n = 0 ]
above, arithmetic
= [ P | n > 0 ∧ n ≥ 0 ]
equal domains
[ P | n > 0 ∧ n > n ≥ 0 ]
reduction of nondet.
By choosing this last relation as value of B , we are using the well-foundedness of < on the natural numbers to ensure progressive finiteness of c ✷ B , and therewith the condition R ; ⊆ I(c ✷ B ). Since this B is not univalent, it still can be refined in many different ways. One refinement to a univalent relation is achieved by ensuring n = n − 1; this give rise to the following program: do n > 0 → l := l × m; n := n − 1 od. The example presented here is intended on the one hand to provide a first impression of the kind of theorems and mathematical devices available in the program derivation approach of the demonic calculus of relations. On the other hand, our unconventional integration of Z operation schemas into the relation-algebraic notation hopefully opens up a method of easy integration of a powerful, concise and systematic notation for concrete relations inside arguments geared towards the use of the component-free relation-algebraic manipulations.
7
The Fork-Algebraic Programming Calculus
It is well-known that relation algebras in which all direct products exist (which can also be considered as certain kinds of complete tabular allegories) are equivalent to relation algebras of concrete sets and relations. In such settings,
83
Kahl
the expressivity of the relation-algebraic language comprises the expressivity of first-order predicate logic. 5 This fact has been most consciously exploited within the approach of using fork algebras as a programming calculus [29]. Fork algebras are one presentation of relation algebras that are provided with all direct products; fork algebras are usually presented as homogeneous relation algebras. Berghammer et al. show [7] the equivalence between the different presentations. There are translation procedures from predicate logic to such relation algebras, see [67], and the fact that predicate logical reasoning can be completely replaced by relation-algebraic, resp. fork-algebraic, reasoning, enables an approach that uses first-order logic as a specification language, but for program derivation reverts to the relation-algebraic level. There is extensive literature that presents fork algebras as basis for a calculus for program derivation [30,6,29,26,27]. This calculus presents an approach to the formulation of strategies for program derivation that is more general and less technically involved than the hylomorphisms of the Bird-Meertens approach, more geared towards a heuristic approach and less to elegant special cases where the clear structures of the Bird-Meertens approach shine. Interestingly, in fork-algebraic programming calculus only equational program derivation seems to have been considered — refinement happens only at the linguistic level, but semantically, refinement is replaced by equality. To give just a short taste of this calculus, note that strategies like Recomposition are considered as predicates over relations. For a specification P : A ↔ B, a relation Split : A ↔ (C1 × · · · × Ck ) for decomposing the inputs, a relation Join : (D1 × · · · × Dk ) ↔ B for recombining the output, and sub-problem specifications Qi : Ci ↔ Di for i ∈ {1, . . . , k }, the following formula over relations characterises the strategy of recomposition: Recomposition(P , Split, Q1 , . . . , Qk , Join) ⇔ P = Split ;(Q1 × · · · × Qk );Join By joining the strategy of Recomposition with another strategy Trivialisation that covers simple cases of problem P with P0 and otherwise leaves a more constrained problem Q, a formalisation of the divide-and-conquer strategy is obtained: D&C(P , P0 , Split, Q1 , . . . , Qk , Join) ⇔ ∃ Q • Trivialisation(P , P0 , Q) ∧ Recomposition(Q, Split, Q1 , . . . , Qk , Join) , where the original specification term P may appear inside some of the terms Q1 , . . . , Qk , but not in the term P0 . Iterating relation-algebraic calculations and the application of strategies like these, the final result of the program derivation process is a relational 5
Operators like infinite joins or transitive closure help to attain second-order expressivity.
84
Kahl
expression T that can be interpreted as (or transliterated into) a program, and for which the equation P = T has been shown by the derivation process. Since this manner of presenting program derivation strategies does not really depend on the specifics of the fork-algebraic treatment of relations, its merits lie more in providing a discipline to present such strategies on a firm theoretic foundation and with a slight inclination to a more logic-oriented language. (In fact, in comparison with the original approach we already took liberties here in transferring the approach into a heterogeneous setting.)
8
Data Refinement
Fundamental work on data refinement was presented by Hoare [32] and Jones [39]. A first relation-algebraic formulation of the simulations involved was put forwared by Hoare et al. in [31,35]; at the same time, Nipkow presented a more general simulation concept for LD-relations (without using that name) [50]. In a simple view of data refinement, an abstract datatype is defined most importantly by an abstract state space A and specifications Si : A ↔ A for operations on A. (For the sake of brevity, we omit initialisation and finalisation from our considerations.) An implementation is defined by a concrete state space C and concrete operations Ci : C ↔ C. For being able to relate an implementation to its specification, an abstraction relation is required; this is usually oriented from concrete states to abstract states, resulting in the following setup: S ✲ A
A α
✻
α
✻
R ✲ C
C
The most useful satisfaction concept in this context, L-simulation, has been named after the shape of the inclusion’s left-hand side in this diagram [13]:
α ;R ⊆ S ;α
With reversed direction of the abstraction relation, i.e., in terms of α, this is also called downwards-simulation, introduced in this shape in [31]. If the abstraction relation α is a mapping, then this is one of the equivalent ways to express that α is a homomorphism [62, Def. 7.1.1] from R to S , another equivalent formulation in this case is: R;α ⊆ α;S
85
Kahl
If α is not a mapping, however, then this is not equivalent to L-simulation; but it is used in the complementary concept of upwards simulation. A third equivalent shape of the homomorphism condition (for the case where α is a mapping) is R ⊆ α;S ;α . The resulting isomorphism concept demands that α is bijective and
R = α;S ;α ; this has been introduced already by Russell as what seems to be the first concept of defining some kind of “similarity” of relations via abstraction relations [57]. 6 In order to relate the satisfaction relation of L-simulation to those for program refinement, it is instructive to consider trivial abstraction, that is, the case where abstract and concrete states coincide and the abstraction relation is the identity on states: There, L-simulation reduces to inclusion, i.e., partial correctness: R⊆S As mentioned in Sect. 3, one way of dealing with the possibility of nontermination is to use a special “non-value” ⊥ as “result” of non-terminating computations. This approach is used in the context of Z, see for example the thorough introduction in [69, Chapts. 16ff.]. Let A⊥ denote the “lifting” of set A by adding an element ⊥, assuming ⊥∈ + A. In this context a different concept of totalisation of relations is used: • For a relation R : A ↔ B, the “totalised form” R : A⊥ ↔ B ⊥ is defined as •
⊥ ⊥ R := R ∪ ((A − dom R) × B )
This yields a pointed relation, i.e., a relation with the following properties: •
•
R is total
•
(⊥, ⊥) ∈ R
•
if (x , ⊥) ∈ R , then (x , y) ∈ R for all y ∈ B ⊥ .
•
•
•
These pointed relations are the images of a semi-lattice homomorphism from the demonic semi-lattice ordering (A ↔ B, ) to the standard relational lattice ✷ ordering (A⊥ ↔ B ⊥ , ⊆): Using the “unpointing” operation , defined by •
(R )✷ = R, we have: 6
I am grateful to Ridha Khedri for pointing this out to me. Russell’s “likeness” concept does in fact go back to [56].
86
Kahl
•
•
R⊆S •
•
•
•
(R ∪ S )✷ (R ∩ S )✷ • •
(R;S )✷
⇔
RS
=
RS
RS
=
R ✷S
Additional power in comparison with the demonic calculus is obtained through the fact that not only the total pointed relations are considered in this context, but also “lifted relations” for which the totality requirement is dropped; a lifting operation is provided, too (consider α : C ↔ A): ◦
α := α ∪ ({⊥} × A⊥ ) Now, the correspondence with the demonic calculus is less direct — we have, Q of unpointing: using a total variant Q ✷ = (dom(Q {⊥})) − • ◦
(R;α)✷ = R;α
and
◦ •
(α;S )✷ = α ✷ S
If α is total, then we even have • ◦
•
R;α = (R;α)
and
◦ •
•
α;S = (α ✷ S ) .
This allows us to investigate the central conditions for forwards and backwards simulation, see [69, p. 246f.]. For total abstraction relations α : C ↔ A and total representation relations β : A ↔ C, these are equivalent to simpler conditions in the demonic calculus of relations: • ◦
◦ •
◦ •
• ◦
R;α ⊆ α;S
⇔
R ;α α ✷ S
β ;R ⊆ S ;β
⇔
β ✷ R S ;β
This shows on the one hand the close relationship between data refinement as presented using pointed relations and the demonic approach, but on the other hand it also shows again that with slightly more complicated mathematical objects more expressivity can be gained — here it is the possibility of illegal implementation states and non-implemented abstract states (in the case of LD-relations it was the ability to model the possibility that for one input, both non-termination and termination were possible).
9
Conclusion
The common goal of all the approaches introduced in this overview is to provide a systematic method for deriving programs from relational specifications,
87
Kahl
using relational calculations. The most important common feature is the emphasis on component-free reasoning, wielding the powerful semantics of relational algebras via simple syntactic transformations. Another common issue is the necessity to interface with presentation of concrete relations — the most common approaches here use some kind of predicate logic or set theory. We have seen that the differences between the presented methods are not only in the notations used, or in the preferred fields of application, but already in the answers to the basic question what satisfaction of a specification by an implementation means, and therefore also what refinement means. By understanding the different points of view that justify the different refinement concepts, it also becomes clear that these different approaches are not really competing, but rather complementary. In the recent years, fostered by Gunther Schmidt’s “RelMiCS” initiative 7 , the field of researchers interested in Relational Methods in Computer Science already has made significant progress towards forming a research community interested in establishing bridges between different approaches, so further “interoperability” can be expected in the future. Another aspect for which we need to fix our hopes in the future is computer support for program derivation in relational calculi. Since the enormous amount of mathematical knowledge in this area will not easily be available to active developers interested in applying formal program derivation techniques, there need to be tools that put this knowledge at the fingertips of these developers, so that they can leverage their thorough understanding of their problem domain together with some basic understanding of the available mathematics to employ cutting-edge results in real-world developments.
References [1] Aarts, C., R. C. Backhouse, P. Hoogendijk, E. Voermans and J. van der Woude, A relational theory of datatypes, Working document (1992), 387 pp., available at http://www.cs.nott.ac.uk/˜rcb/MPC/book.ps.gz. [2] Abrial, J.-R., “The B-Book: Assigning Programs to Meanings,” Cambridge University Press, 1996. [3] Backhouse, R., P. Jansson, J. Jeuring and L. Meertens, Generic programming. an introduction, in: S. D. Swierstra, P. R. Henriques and J. N. Oliveira, editors, Advanced functional programming: Third International School, AFP ’98, Braga, Portugal, September 12–19, 1998: revised lectures, LNCS 1608 (1999), pp. 28– 117. [4] Backhouse, R. C. and J. van der Woude, Demonic operators and monotype factors, Mathematical Structures in Computer Science 3 (1993), pp. 417–433. 7
See [11,28,37,51,17,14] and http://ist.unibw-muenchen.de/relmics/.
88
Kahl
[5] Barr, M. and C. Wells, “Category Theory for Computing Science,” Prentice Hall International Series in Computer Science, Prentice Hall, 1990. [6] Baum, G. A., M. F. Frias, A. M. Haeberer and P. Mart´ınez L´ opez, From specifications to programs: A fork–algebraic approach to bridge the gap, in: Proceedings of Mathematical Foundations of Computer Science 1996 (MFCS ’96),Cracow, Poland, LNCS 1113 (1996), pp. 180–191. [7] Berghammer, R., A. M. Haeberer, G. Schmidt and P. A. S. Veloso, Comparing two different approaches to products in abstract relation algebra, in: M. Nivat, C. Rattray, T. Rus and G. Scollo, editors, AMAST ’93, Workshops in Computing (1994), pp. 167–176. [8] Berghammer, R. and H. Zierer, Relational algebraic semantics of deterministic and nondeterministic programs, Theoretical Computer Science 43 (1986), pp. 123–147. [9] Bird, R. S., Lectures on constructive functional programming, in: M. Broy, editor, Constructive Methods in Computing Science, NATO ASI Ser. F 55, Springer, 1989 pp. 151–216. [10] Bird, R. S. and O. de Moor, “Algebra of Programming,” International Series in Computer Science 100, Prentice Hall, 1997. [11] Brink, C., W. Kahl and G. Schmidt, editors, “Relational Methods in Computer Science,” Advances in Computing Science, Springer, Wien, New York, 1997. [12] de Moor, O. and J. Gibbons, Bridging the algorithm gap: A lineartime functional program for paragraph formatting, Science of Computer Programming 35 (1999). [13] de Roever, W.-P. and K. Engelhardt, “Data Refinement: Model-Oriented Proof Methods and their Comparison,” Cambridge Tracts Theoret. Comput. Sci. 47, Cambridge Univ. Press, 1998. [14] de Swart, H., editor, “Proc. RelMiCS 6, International Workshop on Relational Methods in Computer Science, Oisterwijk near Tilburg, Netherlands, 16–21 October 2001,” LNCS 2561, Springer, 2002. [15] Desharnais, J., Monomorphic characterization of n-ary direct products, Information Sciences 119 (1999), pp. 275–288. [16] Desharnais, J., N. Belkhiter, S. Ben Mohamed Sghaier, F. Tchier, A. Jaoua, A. Mili and N. Zaguia, Embedding a demonic semilattice in a relation algebra, Theoretical Computer Science 149 (1995), pp. 333–360. [17] Desharnais, J., M. Frappier, A. Jaoua and W. MacCaull, Relational methods in computer science, special issue devoted to RelMiCS 5 in Valcartier, Qu´ebec, January 2000, Information Sciences 139 (2001), pp. 165–307. [18] Desharnais, J., A. Jaoua, F. Mili, N. Boudriga and A. Mili, A relational division operator: The conjugate kernel, Theoretical Computer Science 114 (1993), pp. 247–272.
89
Kahl
[19] Desharnais, J., A. Mili and T. T. Nguyen, Refinement and demonic semantics, in: Brink et al. [11] pp. 166–183. [20] Doornbos, H., N. van Gasteren and R. Backhouse, Programs and datatypes, in: Brink et al. [11] pp. 150–165. [21] Frappier, M., “A Relational Basis for Program Construction by Parts,” Ph.D. thesis, University of Ottawa, Computer Science Department, 150 Louis Pasteur, Ottawa, ON, K1N 6N5, Canada (1995). [22] Frappier, M., A. Mili and J. Desharnais, Program construction by parts, in: B. M¨oller, editor, MCP ’95, LNCS 947 (1995), pp. 257–281. [23] Frappier, M., A. Mili and J. Desharnais, A relational calculus for program construction by parts, Science of Computer Programming 26 (1996), pp. 237– 254. [24] Frappier, M., A. Mili and J. Desharnais, Unifying program construction and modification, Logic Journal of the IGPL 6 (1998), pp. 317–340. [25] Freyd, P. J. and A. Scedrov, “Categories, Allegories,” North-Holland Mathematical Library 39, North-Holland, Amsterdam, 1990, xviii+296 pp. [26] Frias, M. F., G. A. Baum and A. M. Haeberer, Fork algebras in algebra, logic and computer science, Fund. Inform. 32 (1997), pp. 1–25. [27] Frias, M. F., G. A. Baum and A. M. Haeberer, Representability and program construction within fork algebras, Logic Journal of the IGPL 6 (1998), pp. 227– 257. [28] Haeberer, A. and M. Frias, Relational methods in computer science, special issue devoted to RelMiCS 2 in Paraty, July 1995, Journal of the IGPL 6 (1998). [29] Haeberer, A., M. Frias, G. Baum and P. Veloso, Fork algebras, in: Brink et al. [11] pp. 54–69. [30] Haeberer, A. M., G. A. Baum and G. Schmidt, On the smooth calculation of relational recursive expressions out of first-order non-constructive specifications involving quantifiers, in: D. Bjørner, M. Broy and I. Pottosin, editors, Formal Methods in Programming and Their Applications, Proc. Internat. Conf. Novosibirsk, June 28–July 3, 1993, LNCS 735 (1994), pp. 403–420. [31] He, J., C. A. R. Hoare and J. W. Sanders, Data refinement refined, in: B. Robinet and R. Wilhelm, editors, ESOP 86, European Symposium on Programming, LNCS 213 (1986), pp. 187–196. [32] Hoare, C. A. R., Proof of correctness of data representations, Acta Informatica 1 (1972), pp. 271–281. [33] Hoare, C. A. R., I. J. Hayes, J. He, C. C. Morgan, A. W. Roscoe, J. W. Sanders, I. H. Sørensen, J. M. Spivey and B. A. Sufrin, Laws of programming, Comm. ACM 30 (1987), pp. 672–686, corrigenda in 30, 9, p. 770.
90
Kahl
[34] Hoare, C. A. R. and J. He, The weakest prespecification, Fund. Inform. 4 (1986), pp. 51–54, 217–252. [35] Hoare, C. A. R., J. He and J. W. Sanders, Prespecification in data refinement, Inform. Process. Lett. 25 (1987), pp. 71–76. [36] ISO/IEC 13568:2002, Information technology — Z formal specification notation — syntax, type system and semantics, international Standard. [37] Jaoua, A. and G. Schmidt, Relational methods in computer science, special issue devoted to RelMiCS 3 in Hammamet, January 1997, Information Sciences 119 (1999), pp. 131–314. [38] Jipsen, P., C. Brink and G. Schmidt, Background material, in: Brink et al. [11] pp. 1–21. [39] Jones, C. B., “Software Development: A Rigorous Approach,” Prentice-Hall, 1980. [40] Jones, C. B., “Systematic Software Development Using VDM,” Prentice-Hall International Series in Computer Science, Prentice-Hall, 1986. [41] Kahl, W., Parallel composition and decomposition of specifications, Information Sciences 139 (2001), pp. 197–220. [42] Kawahara, Y., Notes on the universality of relational functors, Mem. Fac. Sci. Kyushu Univ. Ser. A 27 (1973), pp. 275–289. [43] King, S., Z and the refinement calculus, in: D. Bjørner, C. Hoare and H. Langmaack, editors, VDM ’90: VDM and Z — Formal Methods in Software Development, LNCS 428 (1990), pp. 164–188. [44] Labed Jilani, L., J. Desharnais and A. Mili, Defining and applying measures of distance between specifications, IEEE Transactions on Software Engineering 27 (2001), pp. 673–703. [45] Meertens, L., Algorithmics: Towards programming as a mathematical activity, in: J. W. de Bakker, M. Hazewinkel and J. K. Lenstra, editors, Proc. CWI Symposium on Mathematics and Computer Science (1986), pp. 289–334. [46] Mili, R., J. Desharnais, M. Frappier and A. Mili, Semantic distance between specifications, Theoretical Computer Science 247 (2000), pp. 257–276. [47] M¨ oller, B., Relations as program development language, in: B. M¨ oller, editor, Constructing Programs From Specifications, IFIP WG 2.1 (1991), pp. 319–371. [48] Moore, G. H., editor, “Bertrand Russell: Toward the “Principles of Mathematics”,” The Collected Papers of Bertrand Russell 3, Routledge, 1993. [49] Nelson, G., A generalization of Dijkstra’s calculus, ACM Transactions on Programming Languages and Systems (TOPLAS) 11 (1989), pp. 517–561. [50] Nipkow, T., Non-deterministic data types: Models and implementations, Acta Informatica 22 (1986), pp. 629–661.
91
Kahl
[51] Orlowska, E. and A. Szalas, editors, “Relational Methods for Computer Science Applications,” Heidelberg, 2001. [52] Parnas, D. L., A generalized control structure and its formal definition, Comm. ACM 26 (1983), pp. 572–581. [53] Parnas, D. L., Mathematical descriptions and specification of software, in: B. Pehrson and I. Simon, editors, 13th World Computer Congress 94, Vol. 1: Technology and Foundations, IFIP Transactions A-51 (1994), pp. 354–359. [54] Parnas, D. L. and J. Madey, Functional documentation for computer systems engineering (version 2), Science of Computer Programming 25 (1995), pp. 41– 61, also CRL Reports 237 and 309, McMaster Univ., Communications Research Laboratory and TRIO (Telecommunications Research Inst. of Ontario), Sept. 1991, pp.14. [55] Pfaltz, J. L., Closure lattices, Discrete Mathematics 154 (1996), pp. 217–236. [56] Russell, B., Th´eorie g´en´erale des s´eries bien-ordonn´ees, Rivista di Matematica VIII (1902), pp. 12–43, English as Paper 12: General Theory of Well-Ordered Series in [48]. [57] Russell, B., “Introduction to Mathematical Philosophy,” Routledge, 1919, reprinted 1998. [58] Schmidt, G., Programme als partielle Graphen, Habil. Thesis, Fachbereich Mathematik der Technischen Univ. M¨ unchen, Bericht 7813 (1977), English as [59,60]. [59] Schmidt, G., Programs as partial graphs I: Flow equivalence and correctness, Theoretical Computer Science 15 (1981), pp. 1–25. [60] Schmidt, G., Programs as partial graphs II: Recursion, Theoretical Computer Science 15 (1981), pp. 159–179. [61] Schmidt, G., C. Hattensperger and M. Winter, Heterogeneous relation algebra, in: Brink et al. [11] pp. 39–53. [62] Schmidt, G. and T. Str¨ ohlein, “Relations and Graphs, Discrete Mathematics for Computer Scientists,” EATCS-Monographs on Theoretical Computer Science, Springer, 1993. [63] Sekerinski, E., A calculus for predicative programming, in: R. S. Bird, C. C. Morgan and J. C. P. Woodcock, editors, MCP ’92, LNCS 669 (1992), pp. 302– 322. [64] Spivey, J. M., “The Z Notation: A Reference Manual,” Prentice Hall International Series in Computer Science, Prentice-Hall, 1989, out of print; available via URL: http://spivey.oriel.ox.ac.uk/˜mike/zrm/. [65] Toyn, I., Innovations in the notation of Standard Z, in: J. P. Bowen, A. Fett and M. G. Hinchey, editors, ZUM’98, The Z Formal Specification Notation, LNCS 1493 (1998), pp. 193–213.
92
Kahl
[66] Toyn, I., editor, “Z Notation, Final Committee Draft, CD 13568.2,” Developed by members of the Z Standards Panel, BSI Panel IST/5/-/19/2 (Z Notation), ISO Panel JTC1/SC22/WG19 (Rapporteur Group for Z), Project number JTC1.22.45, 1999, current version: Consensus Working Draft 2.7, October 12, 2001. URL: http://web.comlab.ox.ac.uk/oucl/research/groups/zstandards/index.html. [67] Veloso, P. A. S. and A. M. Haeberer, A finitary relational algebra for classical first-order logic, Bull. Polish Acad. Sci. Math., Sect. on Logic 20 (1991), pp. 52– 62. [68] Winter, M., “Strukturtheorie heterogener Relationenalgebren mit Anwendung auf Nichtdeterminismus in Programmiersprachen,” Ph.D. thesis, Fakult¨ at f¨ ur Informatik, Universit¨ at der Bundeswehr M¨ unchen (1998). [69] Woodcock, J. and J. Davies, “Using Z: Specification, Refinement, and Proof,” Prentice-Hall International Series in Computer Science, Prentice-Hall, 1996.
93