Persistence in Algebraic Specifications
Total Page:16
File Type:pdf, Size:1020Kb
Persistence in Algebraic Specifications Freek Wiedijk Persistence in Algebraic Specifications Persistence in Algebraic Specifications Academisch Proefschrift ter verkrijging van de graad van doctor aan de Universiteit van Amsterdam, op gezag van de Rector Magnificus prof. dr. P.W.M. de Meijer, in het openbaar te verdedigen in de Aula der Universiteit (Oude Lutherse Kerk, ingang Singel 411, hoek Spui), op donderdag 12 december 1991 te 12.00 uur door Frederik Wiedijk geboren te Haarlem Promotores: prof. dr. P. Klint & prof. dr. J.A. Bergstra Faculteit Wiskunde en Informatica Het hier beschreven onderzoek werd mede mogelijk gemaakt door steun van de Ne- derlandse organisatie voor Wetenschappelijk Onderzoek (voorheen de nederlandse organisatie voor Zuiver-Wetenschappelijk Onderzoek) binnen project nummer 612- 317-013 getiteld Executeerbaar maken van algebraïsche specificaties. voor Jan Truijens Contents Contents Acknowledgements 1 Introduction 1 1.1 Motivation and general overview 2 1.2 Examples of erroneous specifications 13 1.3 Background and related work 22 2. Theory 25 2.1 Basic notions 27 2.1.1. Equational specifications 28 2.1.2 Term rewriting systems 29 2.2 Termination 30 2.2.1 Weak and strong termination 33 2.2.2 Path orderings 34 2.2.3 Decidability 40 2.3 Confluence 41 2.3.1 Weak and strong confluence 42 2.3.2 Overlapping 44 2.3.3 Decidability 45 2.4 Reduction strategies 46 2.5 Persistence 48 2.5.1 Weak and strong persistence 52 2.5.2 Term approximations and bases 54 2.5.3 Normal form analysis 56 2.5.4 Decidability 60 2.6 Primitive recursive algebras 62 3 Perspect 65 3.1 Language definition 65 3.1.1 Syntax 65 3.1.2 Elimination of abbreviations 68 3.1.3 Declarations and typing 70 3.1.4 Semantics 72 3.1.5 Restrictions on the specification 74 3.1.6 Five levels of Perspect 76 3.2 Properties 79 3.2.1 Decidability 79 3.2.2 Executability 80 3.2.3 Persistence 80 3.2.4 Expressiveness 81 3.2.5 Compositionality 81 3.3 Examples 83 3.3.1 Natural numbers and integers 85 3.3.2 Rational numbers 91 3.3.3 Primitive recursive functions 103 3.3.4 Stacks 108 3.3.5 Arrays 112 3.3.6 Text and pictures 117 3.3.7 Small text editor 123 3.4 Checker 128 3.4.1 Operation 128 3.4.2 Program 131 3.4.3 Deviation from the formal definition 134 4 Compilation 139 4.1 Prolog 139 4.1.1 Compilation scheme 140 4.1.2 Comparison with other schemes 145 4.1.3 Example 148 4.2 Modula-2 155 4.2.1 Compilation scheme 156 4.2.2 Example 163 5 Conclusion 171 Appendices 175 I Perspect syntax diagrams 175 II Error messages from the Perspect system 177 III Definition modules of the Perspect checker 181 References 187 Samenvatting (Summary in dutch) 193 Acknowledgements My greatest debt is to Paul Klint, my promotor. I admire his excellent taste, and I con- sider it a great honor that he allowed me to work under his supervision. I want to thank Jan Bergstra, my second promotor, for interesting and stimulating discussions. His ability to transform himself into an expert, whatever the subject may be, never ceases to amaze me. My friend Jesse de Does has been a great support from the start. Despite his un- familiarity with the field of algebraic specifications, he is one of the few people who read all my work and understood it, in spite of my hermetic style. I am indebted to him for numerous corrections. My roommate and friend Sjouke Mauw has been a great help on many occasions. He has always showed great interest in my work, and never failed to point out where my texts were less than clear. Of all people working near me I feel closest intellectually to my friend Hans Mulder. He is a mathematician as well as a real hacker. He has often shown me where to look for excitement. His knowledge of computer science, in particular its folklore, is unsur- passed. I finally would like to express my thanks to the following people, who made the four years that I worked at the University of Amsterdam an unforgettable experience. They are: Pum Walters, Jos Vrancken, Chris Verhoef, Gert Veltink, John Tromp, Leen Torenvliet, Dolf Starreveld, Joost Schraag, Piet Rodenburg, Karst Koymans, Wilco Koorn, Jan Willem Klop, Jan Hellings, Jan Heering, Linda van der Gaag, Peter van Emde Boas, Madelon Drolsbach, Casper Dik, Felix Croes, Richard Carels, Maarten Carels, Jacob Brunekreef, Jeroen Brouwer, Wiet Bouma, Jurjen Bos, Chris Borton and Jos Baeten. The picture on the cover shows two views on the one missing configuration (3L 2FB 3F) in Sol LeWitt’s All three-part variations on three different kind of cubes, an ink drawing from 1960 that I saw on the exhibition of LeWitt’s work held in the Stedelijk Museum in Amsterdam in 1984. The mottos in front of the chapters are taken from various articles and letters received from Usenet. Chapter 1 Introduction If it’s not correct, it’s worthless. I would even agree that if it does not have rigorous definitions, it’s worthless. This thesis investigates some aspects of the notion of persistence in the context of modular initial algebra specifications. A specification is called persistent when the sets of elements of the specified datatypes do not depend on the module in which they are referred to (for the precise definition of persistence, refer to section 2.5.1.2). The three main goals of this study are: • To argue that verification of the persistence of an algebraic specification can en- hance our confidence in the correctness of that specification, and to give an ap- proach for verifying a form of persistence automatically. • To show that a specification can be implemented using logic programming in such a way that the implementation consists of the natural definition of the semantics of that specification. • To show that a persistent specification can be implemented in a modular pro- cedural programming language in such a way that the modularity of the implemen- tation corresponds to the modularity of the specification. This thesis, then, consists of four parts. • Chapter 1 contains an introduction that motivates the use of modular initial algebra specifications and the study of persistence. • Chapter 2 gives a formal treatment of the theory of initial algebra specifications and techniques that can be used to verify the persistence of those specifications. • Chapter 3 gives a concrete framework for checking persistence in the form of the specification language Perspect. A number of examples in this language are pre- sented. • Chapter 4 shows that persistent specifications can be cleanly integrated with both a logic programming language and a modular procedural programming language. Algorithms for compiling Perspect specifications to both Prolog and Modula-2 programs are described. Two specification languages will be used for the expression of algebraic specifications. The first one is ASF, which is an acronym for ‘Algebraic Specification Formalism’. It was developed in Amsterdam as part of the specification language for the GIPE pro- ject. For the definition of ASF, see chapter 1 of [Bergstra, Heering, Klint, 1989]. The 2 Introduction second specification language that is used is Perspect, a dialect of ASF, which is the specification language introduced in this thesis. It will be the subject of chapter 3. 1.1. Motivation and general overview In this thesis we study the theory of initial algebra specifications. Specification lan- guages that use initial algebra semantics have both the characteristics of a formal spec- ification language as well as those of a programming language. This dualistic nature of a language that uses initial algebra semantics is both its weakness and its strength. 1.1.1. Simplicity of semantics. The main advantage of a language that uses initial algebra semantics, an advantage it shares with most other formal specification languages, is its clean semantics. Programming languages on the contrary, are almost always ridden with special cases in the definition of their semantics, and often contain aspects that are left unspecified or refer to system dependent parameters. Unfortunately this departure from an abstract model behind the semantics of the language is necessary when one defines a programming language: even the most formal of programming languages has to give some description of what should happen when there is, for instance, not enough storage in the computer to run the program. A specification language, of course, need not bother with such problems. For a rather extreme example of the undefinedness and system dependency of texts in conventional programming languages, consider the following program in the C programming language [Kernighan, Ritchie, 1988]. #include <stdio.h> int main() { long l; int i; short s; char c; i = 65537; l = i * i; for (s = 0; s < l; s++) ; c = 255; if (c == -1) (void) puts("0"); else (void) puts("1"); return 0; } Motivation and general overview 3 This text is a valid C program. However, when someone tries to compile this program and subsequently tries to run it, there are (at least) five possibilities: (i) The compiler refuses to compile the program. (ii) The program compiles, but crashes when it is run. (iii) The program compiles and does not crash, but will not terminate. (iv) The program compiles, does not crash, and terminates after printing ‘0’. (v) The program compiles, does not crash, and terminates after printing ‘1’. Furthermore, for all five cases, the compiler and runtime system can justify why they behave like they do. It all depends on how many bits there are in the various kinds of integer (which is a system dependency of the compiler), and what happens on integer overflow (which is an undefined aspect in the C programming language).