title: Toward Compiler Implementation Correctness Proofs

authors:
Laurian M. Chirica
David F. Martin

abstract: Aspect of the interaction between compiler theory and practice is addressed. Presented is a technique for the syntax-directed specification of compilers together with a method for proving the correctness of their parse-driven implementations. The subject matter is presented in an order-algebraic framework; while not strictly necessary, this approach imposes beneficial structure and modularity on the resulting specifications and implementation correctness proofs. Compilers are specified using an order-algebraic definition of attribute grammars. A practical class of compiler implementations is considered, consisting of those driven by LR( k ) or LL( k ) parsers which cause a sequence of translation routine activations to modify a suitably initialized collection of data structures (called a translation environment). The implementation correctness criterion consists of appropriately comparing, for each source program, the corresponding object program (contained in the final translation environment) produced by the compiler implementation to the object program dictated by the compiler specification. Provided that suitable intermediate assertions (called translation invariants ) are supplied, the program consisting of the (parse-induced) sequence of translation routine activations can be proven partially correct via standard inductive assertion methods.


venue: toplas

title: Parlog: Parallel Programming in Logic

authors:
Keith L. Clark
Steve Gregory

abstract: PARLOG is a logic programming language in the sense that nearly every definition and query can be read as a sentence of predicate logic. It differs from PROLOG in incorporating parallel modes of evaluation. For reasons of efficient implementation, it distinguishes and separates and-parallel and or-parallel evaluation. PARLOG relations are divided into two types: single-solution relations and all-solutions relations. A conjunction of single-solution relation calls can be evaluated in parallel with shared variables acting as communication channels for the passing of partial bindings. Only one solution to each call is computed, using committed choice nondeterminism. A conjunction of all-solutions relation calls is evaluated without communication of partial bindings, but all the solutions may be found by an or-parallel exploration of the different evaluation paths. A set constructor provides the main interface between single-solution relations and all-solutions relations. This paper is a tutorial introduction to PARLOG. It assumes familiarity with logic programming. Categories and Subject Descriptors: D.l.l [Programming Techniques]: Applicative (Functional)


title: Automatic Verification of Finite-State Concurrent Systems Using Temporal Logic Specifications

authors:
Edmund M. Clarke
E. Allen Emerson
A. Prasad Sistla

abstract: We give an efficient procedure for verifying that a finite-state concurrent system meets a specification expressed in a (propositional, branching-time) temporal logic. Our algorithm has complexity linear in both the size of the specification and the size of the global state graph for the concurrent system. We also show how this approach can be adapted to handle fairness. We argue that our technique can provide a practical alternative to manual proof construction or use of a mechanical theorem prover for verifying many finite-state concurrent systems. Experimental results show that state machines with several hundred states can be checked in a matter of seconds.


title: The Impact of Interprocedural Analysis and Optimization in the Rn Programming Environment

authors:
Keith D. Cooper
Ken Kennedy
Linda Torczon

abstract: In spite of substantial progress in the theory of interprocedural data flow analysis, few practical compiling systems can afford to apply it to produce more efficient object programs. To perform interprocedural analysis, a compiler needs not only the source code of the module being compiled, but also information about the side effects of every procedure in the program containing that module, even separately compiled procedures. In a conventional batch compiler system, the increase in compilation time required to gather this information would make the whole process impractical. In an integrated programming environment, however, other tools can cooperate with the compiler to compute the necessary interprocedural information incrementally . as the program is being developed, decreasing both the overall cost of the analysis and the cost of individual compilations. A central goal of the R n project at Rice University is to construct a prototype software development environment that is designed to build whole programs, rather than just individual modules. It employs interprocedural analysis and optimization to produce high-quality machine code for whole programs. This paper presents an overview of the methods used by the environment to accomplish this task and discusses the impact of these methods on the various environment components. The responsibilities of each component of the environment for the preparation and use of interprocedural information are presented in detail.


title: Proving Liveness for Networks of Communicating Finite State Machines

authors:
Mohamed G. Gouda
Chung-Kuo Chang

abstract: Consider a network of communicating finite state machines that exchange messages over unbounded FIFO channels. Each machine in the network can be defined by a directed graph whose nodes represent the machine states and whose edges represent its transitions. In general, for a node in one of the machines to be live (i.e., encountered infinitely often during the course of communication), each machine in the network should progress in some fair fashion. We define three graduated notions of fair progress (namely, node fairness, edge fairness, and network fairness), and on this basis we define three corresponding degrees of node liveness. We discuss techniques to verify that a given node is live under each of these fairness assumptions. These techniques can be automated; and they are effective even if the network under consideration has an infinite number of reachable states. We use our techniques to establish the liveness of some practical communication protocols; these include an unbounded start-stop protocol, an unbounded alternating bit protocol, and a simplified version of the CSMA/CD protocol for local area networks.


title: Proving Systolic Systems Correct

abstract: A language for describing communicating systems is described. It is sufficiently expressive to describe both the desired behavior of systems, their specifications , and their actual implementations in terms of simpler components. We say I satisfies S if 1 is a correct implementation of the specification S . We briefly discuss a semantic treatment of this notion of satisfaction, but the main emphasis of the paper is on a proof technique for proving statements of the form I satisfies S , based on syntactic transformations and induction. Two examples are given, both systolic systems from the literature.


title: Generating Editing Environments Based on Relations and Attributes

authors:
Susan Horwitz
Tim Teitelbaum

abstract: The ability to generate language-based editors depends on the existence of a powerful, language-independent model of editing. A model is proposed in which programs are represented as attributed abstract-syntax trees with an associated relational database. Relations can depend on the state of the attributed tree, and attributes can depend on the values in relations, provided there are no circular dependencies. The power and the limitations of relational operations are demonstrated with respect to the support of static-semantic checking, anomaly detection, an interrogation facility, and the ability to define alternative program displays. The advantages of the hybrid system over both the purely relational and purely attribute-based systems are presented, and new algorithms are given for query evaluation and incremental view updating motivated by the efficiency requirements of interactive editing under the defined model. A prototype implementation of an editor generator is described, and suggestions for future research are made.


title: Applicative Caching

authors:
Robert M. Keller
M. Ronan Sleep

abstract: The “referential transparency” principle of applicative language expressions stipulates that a single value exists for all occurrences of an expression in a given context (where a context is a set of bindings of variables to values). In principle, each such value therefore need to be computed only once. However, in applicative language systems supporting recursive programming or tasking notions, the bindings are not all precomputed and explicit. As a result, textual recognition of all multipleoccurrences is precluded, with the unfortunate consequence that such occurrences are recomputed. We elaborate upon the early notion of “memo function” for solving this problem. We suggest syntactic and semantic constructs providing programmer control for avoiding recomputation, which is incorporated into a “building-block” approach.


title: A Formal Approach to Undo Operations in Programming Languages

abstract: A framework is presented for adding a general Undo facility to programming languages. A discussion of relevant literature is provided to show that the idea of Undoing pervades several areas in computer science, and even other disciplines. A simple model of computation is introduced, and it is augmented with a minimal amount of additional structure needed for recovery and reversal. Two different interpretations of Undo are motivated with examples. Then, four primitives are defined in a language-independent manner; they are sufficient to support a wide range of Undo capability. Two of these primitives carry out state saving, and the others mirror the two versions of the Undo operation. Properties of and relationships between these primitives are explored, and there are some preliminary remarks on how one could implement a system based on this formalism. The main conclusion is that the notions of recovery and reversal of actions can become part of the programming process.


title: Axioms for Memory Access in Asynchronous Hardware Systems

abstract: The problem of concurrent accesses to registers by asynchronous components is considered. A set of axioms about the values in a register during concurrent accesses is proposed. It is shown that if these axioms are met by a register, then concurrent accesses to it may be viewed as nonconcurrent, thus making it possible to analyze asynchronous algorithms without elaborate timing analysis of operations. These axioms are shown, in a certain sense, to be the weakest. Motivation for this work came from analyzing low-level hardware components in a VLSI chip which concurrently accesses a flip-flop.


title: The PegaSys System: Pictures as Formal Documentation of Large Programs

authors:
Mark Moriconi
Dwight F. Hare

abstract: PegsSys is an experimental system in which a user formally describes how a program is put together by means of a hierarchically structured collection of pictures, called formal dependency diagrams (FDDs). Icons in an FDD denote a wide range of data and control dependencies among the relatively coarse-grained entities contained in large programs. Dependencies considered atomic with respect to one level in a hierarchy can be decomposed into a number of dependencies at a lower level. Each dependency can be a predefined primitive of the FDD language or it can be defined by a PegaSys user in terms of the primitives. A PegsSys user is given the illusion that logical formulas do not exist, even though PegaSys reasons about them internally. This involves (1) checking whether an FDD is meaningful syntactically, (2) determining whether hierarchical refinements of an FDD are methodologically sound, and (3) deciding whether an FDD hierarchy is logically consistent with the program that it is intended to describe. The techniques used to provide these capabilities are discussed along with the logical properties that enable PegaSys to maintain the user illusion.


title: Efficient Demand-Driven Evaluation - Part 2

authors:
Keshav Pingali
Arvind

abstract: In Part 1 of this paper [5], we presented a scheme whereby a compiler could propagate demands through programs in a powerful stream language L. A data-driven evaluation of the transformed program performed exactly the same computation as a demand-driven evaluation of the original program. In this paper we explore a different transformation, which trades the complexity of demand propagation for a bounded amount of extra computation on some data lines.


title: Clarification of "Feeding Inputs on Demand" in Efficient Demand-Driven Evaluation - Part 1


title: A Short Proof of a Conjecture of DeRemer and Pennello

abstract: In this paper we offer a short proof of the DeRemer-Pennello conjecture that if the LR(0) automaton for a grammar G contains a state p and a nonterminal A such that ( p , A ) is a nonterminal transition, ( p , A ) includes + ( p , A ) and Read ( p , A ) is not empty, then grammar G is not LR( k ) for any k .


title: The ML Approach to the Readable All-Purpose Language

abstract: The ideal computer language is seen as one that would be as readable as natural language, and so adaptable that it could serve as the only language a user need ever know. An approach to language design has emerged that shows promise of allowing one to come much closer to that ideal than might reasonably have been expected. Using this approach, a language referred to as ML has been developed, and has been implemented as a language-creation system in which user-defined procedures invoked at translation time translate the source to some object code. In this way the user can define both the syntax and the semantics of the source language. Both language and implementation are capable of further development. This paper describes the approach, the language, and the implementation and recommends areas for further work.


title: A Structural View of the Cedar Programming Environment

authors:
Daniel C. Swinehart
Polle T. Zellweger
Richard J. Beach
Robert Hagemann

abstract: This paper presents an overview of the Cedar programming environment, focusing on its overall structure—that is, the major components of Cedar and the way they are organized. Cedar supports the development of programs written in a single programming language, also called Cedar. Its primary purpose is to increase the productivity of programmers whose activities include experimental programming and the development of prototype software systems for a high-performance personal computer. The paper emphasizes the extent to which the Cedar language, with run-time support, has influenced the organization, flexibility, usefulness, and stability of the Cedar environment. It highlights the novel system features of Cedar, including automatic storage management of dynamically allocated typed values, a run-time type system that provides run-time access to Cedar data type definitions and allows interpretive manipulation of typed values, and a powerful device-independent imaging model that supports the user interface facilities. Using these discussions to set the context, the paper addresses the language and system features and the methodologies used to facilitate the integration of Cedar applications. A comparison of Cedar with other programming environments further identifies areas where Cedar excels and areas where work remains to be done.


title: Smart Recompilation

abstract: With current compiler technology, changing a single line in a large software system may trigger massive recompilations. If the change occurs in a file with shared declarations, all compilation units depending upon that file must be recompiled to assure consistency. However, many of those recompilations may be redundant, because the change may affect only a small fraction of the overall system. Smart recompilation is a method for reducing the set of modules that must be recompiled after a change. The method determines whether recompilation is necessary by isolating the differences among program modules and analyzing the effect of changes. The method is applicable to languages with and without overloading. A prototype demonstrates that the method is efficient and can be added with modest effort to existing compilers.


title: The Concept of a Supercompiler

abstract: A supercompiler is a program transformer of a certain type. It traces the possible generalized histories of computation by the original program, and compiles an equivalent program, reducing in the process the redundancy that could be present in the original program. The nature of the redundancy that can be eliminated by supercompilation may be various, e.g., some variables might have predefined values (as in partial evaluation), or the structure of control transfer could be made more efficient (as in lazy evaluation), or it could simply be the fact that the same variable is used more than once. The general principles of supercompilation are described and compared with the usual approach to program transformation as a stepwise application of a number of equivalence rules. It is argued that the language Refal serves the needs of supercompilation best. Refal is formally defined and compared with Prolog and other languages. Examples are given of the operation of a Refal supercompiler implemented at CCNY on an IBM/370.


title: Automatic Translation of Fortran Programs to Vector Form

authors:
Randy Allen
Ken Kennedy

abstract: The recent success of vector computers such as the Cray-1 and array processors such as those manufactured by Floating Point Systems has increased interest in making vector operations available to the FORTRAN programmer. The FORTRAN standards committee is currently considering a successor to FORTRAN 77, usually called FORTRAN 8x, that will permit the programmer to explicitly specify vector and array operations. Although FORTRAN 8x will make it convenient to specify explicit vector operations in new programs, it does little for existing code. In order to benefit from the power of vector hardware, existing programs will need to be rewritten in some language (presumably FORTRAN 8x) that permits the explicit specification of vector operations. One way to avoid a massive manual recoding effort is to provide a translator that discovers the parallelism implicit in a FORTRAN program and automatically rewrites that program in FORTRAN 8x. Such a translation from FORTRAN to FORTRAN 8x is not straightforward because FORTRAN DO loops are not always semantically equivalent to the corresponding FORTRAN 8x parallel operation. The semantic difference between these two constructs is precisely captured by the concept of dependence . A translation from FORTRAN to FORTRAN 8x preserves the semantics of the original program if it preserves the dependences in that program. The theoretical background is developed here for employing data dependence to convert FORTRAN programs to parallel form. Dependence is defined and characterized in terms of the conditions that give rise to it; accurate tests to determine dependence are presented; and transformations that use dependence to uncover additional parallelism are discussed.


title: A Generalized Iterative Construct and Its Semantics

abstract: A new programming language construct, called DOupon, subsumes Dijkstra's selective (IF) and iterative (DO) constructs. DOupon has a predicate transformer approximately equivalent in complexity to that for DO. In addition, it simplifies a wide variety of algorithms, in form as well as in discovery and proof. Several theorems are demonstrated that are useful for correctness proofs and for optimization and that are not applicable to DO or IF. The general usefulness of DOupon derives from a separation of the concerns of invariance, through iteration, from those of termination.


title: A Methodology for Synthesis of Recursive Functional Programs

abstract: John Backus introduced the Functional Programming (FP) system, the variable-free applicative system having reduction semantics. Backus has also introduced a unique expansion technique for reasoning about a class of recursive FP programs. As a natural outgrowth of this expansion technique, an FP program synthesis methodology is described in this paper. The methodology synthesizes recursive FP programs of the form f = p →, q ; E ( f . h ) from their preformulated case-by-case descriptions, which in turn come from given input-output example specifications. After explaining the methodology informally, formalization in the form of a definition and a synthesis theorem is introduced. A sufficient condition for the functional form E , for successful synthesis under the present methodology, is obtained structurally. Several illustrative examples of synthesis are also included.


title: A Data-Driven Model for a Subset of Logic Programming

authors:
Lubomir Bic
Craig A. Lee

abstract: There is a direct correspondence between semantic networks and a subset of logic programs, restricted only to binary predicates. The advantage of the latter is that it can describe not only the nodes and arcs comprising a semantic net, but also the data-retrieval operations applied to such nets. The main objective of this paper is to present a data-driven model of computation that permits this subset of logic programs to be executed on a highly parallel computer architecture. We demonstrate how logic programs may be converted into collections of data-flow graphs in which resolution is viewed as a process of finding matches between certain graph templates and portions of the data-flow graphs. This graph fitting process is carried out by messages propagating asynchronously through the data-flow graph; thus computation is entirely data driven, without the need for any centralized control and centralized memory. This permits a potentially large number of independent processing elements to cooperate in solving a given query.


title: On the Algebraic Definition of Programming Languages

authors:
Manfred Broy
Martin Wirsing
Peter Pepper

abstract: The algebraic specification of the semantics of programming languages is outlined. Particular emphasis is given to the problem of specifying least-fixed points by first-order conditional equations. To cover this issue, the theory of specifying partial heterogeneous algebras by abstract data types is slightly extended by a more general notion of homomorphism. In this framework the semantics of programming languages can be uniquely specified in a purely algebraic way, using particular models of a hierarchy of abstract types. This approach is demonstrated for a simple procedural programming language. Several increasingly complex versions of iterations are treated and analyzed with respect to their theoretical consequences. Finally, as a complementary algebraic technique, transformational semantics is explained and applied to our examples.


title: A Practical Method for LR and LL Syntactic Error Diagnosis

authors:
Michael G. Burke
Gerald A. Fisher

abstract: This paper presents a powerful, practical, and essentially language-independent syntactic error diagnosis and recovery method that is applicable within the frameworks of LR and LL parsing. The method generally issues accurate diagnoses even where multiple errors occur within close proximity, yet seldom issues spurious error messages. It employs a new technique, parse action deferral, that allows the most appropriate recovery in cases where this would ordinarily be precluded by late detection of the error. The method is practical in that it does not impose substantial space or time overhead on the parsing of correct programs, and in that its time efficiency in processing an error allows for its incorporation in a production compiler. The method is language independent, but it does allow for tuning with respect to particular languages and implementations through the setting of language-specific parameters.


title: The Geometry of Semaphore Programs

authors:
Scott D. Carson
Paul F. Reynolds Jr.

abstract: Synchronization errors in concurrent programs are notoriously difficult to find and correct. Deadlock, partial deadlock, and unsafeness are conditions that constitute such errors. A model of concurrent semaphore programs based on multidimensional, solid geometry is presented. While previously reported geometric models are restricted to two-process mutual exclusion problems, the model described here applies to a broader class of synchronization problems. The model is shown to be exact for systems composed of an arbitrary, yet fixed number of concurrent processes, each consisting of a straight line sequence of arbitrarily ordered semaphore operations.


title: The Multiway Rendezvous

abstract: The multiway rendezvous is a natural generalization of the rendezvous in which more than two processes may participate. The utility of the multiway rendezvous is illustrated by solutions to a variety of problems. To make their simplicity apparent, these solutions are written using a construct tailor-made to support the multiway rendezvous. The degree of support for multiway rendezvous applications by several well-known languages that support the two-way rendezvous is examined. Since such support for the multiway rendezvous is found to be inadequate, well-integrated extensions to these languages are considered that would help provide such support.


title: Parsing and Compiling Using Prolog

authors:
Jacques Cohen
Timothy J. Hickey

abstract: This paper presents the material needed for exposing the reader to the advantages of using Prolog as a language for describing succinctly most of the algorithms needed in prototyping and implementing compilers or producing tools that facilitate this task. The available published material on the subject describes one particular approach in implementing compilers using Prolog. It consists of coupling actions to recursive descent parsers to produce syntax-trees which are subsequently utilized in guiding the generation of assembly language code. Although this remains a worthwhile approach, there is a host of possibilities for Prolog usage in compiler construction. The primary aim of this paper is to demonstrate the use of Prolog in parsing and compiling. A second, but equally important, goal of this paper is to show that Prolog is a labor-saving tool in prototyping and implementing many non-numerical algorithms which arise in compiling, and whose description using Prolog is not available in the literature. The paper discusses the use of unification and nondeterminism in compiler writing as well as means to bypass these (costly) features when they are deemed unnecessary. Topics covered include bottom-up and top-down parsers, syntax-directed translation, grammar properties, parser generation, code generation, and optimizations. Newly proposed features that are useful in compiler construction are also discussed. A knowledge of Prolog is assumed.


title: Conversion from Data-Driven to Synchronous Execution in Loop Programs

authors:
Janice E. Cuny
Lawrence Snyder

abstract: Conversion algorithms are presented that would enable programmers to write programs in a high-level, data flow language and then run those programs on a synchronous machine. A model of interprocess communication systems is developed in which both data-driven and synchronous execution modes are represented. Balancing equations are used to characterize a subclass of parallel programs, called loop programs, for which conversions are possible. We show that all loop programs having the finite buffer property can be converted into synchronous mode. Finally two algorithms for the conversion of loop programs are presented and discussed.


title: Language Support for the Specification and Development of Composite Systems

abstract: When a complex system is to be realized as a combination of interacting components, development of those components should commence from a specification of the behavior required of the composite system. A separate specification should be used to describe the decomposition of that system into components. The first phase of implementation from a specification in this style is the derivation of the individual component behaviors implied by these specifications. The virtues of this approach to specification are expounded, and specification language features that are supportive of it are presented. It is shown how these are incorporated in the specification language Gist, which our group has developed. These issues are illustrated in a development of a controller for elevators serving passengers in a multistory building.


title: The Program Dependence Graph and Its Use in Optimization

authors:
Jeanne Ferrante
Karl J. Ottenstein
Joe D. Warren

abstract: In this paper we present an intermediate program representation, called the program dependence graph ( PDG ), that makes explicit both the data and control dependences for each operation in a program. Data dependences have been used to represent only the relevant data flow relationships of a program. Control dependences are introduced to analogously represent only the essential control flow relationships of a program. Control dependences are derived from the usual control flow graph. Many traditional optimizations operate more efficiently on the PDG. Since dependences in the PDG connect computationally related parts of the program, a single walk of these dependences is sufficient to perform many optimizations. The PDG allows transformations such as vectorization, that previously required special treatment of control dependence, to be performed in a manner that is uniform for both control and data dependences. Program transformations that require interaction of the two dependence types can also be easily handled with our representation. As an example, an incremental approach to modifying data dependences resulting from branch deletion or loop unrolling is introduced. The PDG supports incremental optimization, permitting transformations to be triggered by one another and applied only to affected dependences.


title: DIB - A Distributed Implementation of Backtracking

authors:
Raphael A. Finkel
Udi Manber

abstract: DIB is a general-purpose package that allows a wide range of applications such as recursive backtrack, branch and bound, and alpha-beta search to be implemented on a multicomputer. It is very easy to use. The application program needs to specify only the root of the recursion tree, the computation to be performed at each node, and how to generate children at each node. In addition, the application program may optionally specify how to synthesize values of tree nodes from their children's values and how to disseminate information (such as bounds) either globally or locally in the tree. DIB uses a distributed algorithm, transparent to the application programmer, that divides the problem into subproblems and dynamically allocates them to any number of (potentially nonhomogeneous) machines. This algorithm requires only minimal support from the distributed operating system. DIB can recover from failures of machines even if they are not detected. DIB currently runs on the Crystal multicomputer at the University of Wisconsin-Madison. Many applications have been implemented quite easily, including exhaustive traversal ( N queens, knight's tour, negamax tree evaluation), branch and bound (traveling salesman) and alpha-beta search (the game of NIM). Speedup is excellent for exhaustive traversal and quite good for branch and bound.


title: An Editor for Revision Control

authors:
Christopher W. Fraser
Eugene W. Myers

abstract: Programming environments support revision control in several guises. Explicitly, revision control software manages the trees of revisions that grow as software is modified. Implicitly, editors retain past versions by automatically saving backup copies and by allowing users to undo commands. This paper describes an editor that offers a uniform solution to these problems by never destroying the old version of the file being edited. It represents files using a generalization of AVL trees called “AVL dags,” which makes it affordable to automatically retain past versions of files. Automatic retention makes revision maintenance transparent to users. The editor also uses the same command language to edit both text and revision trees.


title: Embedding Continuations in Procedural Objects

authors:
Christopher T. Haynes
Daniel P. Friedman

abstract: Continuations, when available as first-class objects, provide a general control abstraction in programming languages. They liberate the programmer from specific control structures, increasing programming language extensibility. Such continuations may be extended by embedding them in procedural objects. This technique is first used to restore a fluid environment when a continuation object is invoked. We then consider techniques for constraining the power of continuations in the interest of security and efficiency. Domain mechanisms, which create dynamic barriers for enclosing control, are implemented using fluids. Domains are then used to implement an unwind-protect facility in the presence of first-class continuations. Finally, we present two mechanisms, wind-unwind and dynamic-wind, that generalize unwind-protect.


title: Data Descriptors: A Compile-Time Model of Data and Addressing

abstract: Data descriptors, which have evolved from Wilcox's value descriptors [16], are a notation for representing run-time data objects at compile time. One of the principal reasons for developing this notation was to aid in the rapid construction of code generators, especially for new microprocessors. Each data descriptor contains a base, a displacement, and a level of indirection. For example, a variable x lying at displacement 28 from base register B3 is represented by this data descriptor: @B3.28. The general form of a data descriptor is @ k b.d.i where k gives the number of levels of indirection, b is a base, d is a displacement, and I is an index. Data descriptors are convenient for representing addressing in Fortran (with static allocation and common blocks), in Pascal and Turing (with automatic allocation and stack frames), and in more general languages such as Euclid and PL/I. This generality of data descriptors allows code generation to be largely independent of the source language. Data descriptors are able to encode the addressing modes of typical computer architectures such as the IBM 360 and the PDP-11. This generality of data descriptors allows code generation to be largely machine independent. This paper gives a machine independent method of storage allocation that uses data descriptors. Techniques are given for local optimization of basic arithmetic and addressing code using data descriptors. Target machine dependencies are isolated so that the part of the code generator that handles high-level addressing (such as subscripting) is machine independent. The techniques described in this paper have proven effective in the rapid development of a number of production code generators.


title: IDL: Sharing Intermediate Representations

abstract: IDL (Interface Description Language) is a practical and useful tool for controlling the exchange of structured data between different components of a large system. IDL is a notation for describing collections of programs and the data structures through which they communicate. Using IDL, a designer gives abstract descriptions of data structures, together with representation specifications that specialize the abstract structures for particular programs. A tool, the IDL translator, generates readers and writers that map between concrete internal representations and abstract exchange representations.


title: Algorithmic Specifications: A Constructive Specification Method for Abstract Data Types

abstract: This paper presents a new specification method for abstract data types and a pertaining logic. The specification method proposed differs from the classical algebraic one by its constructive, yet abstract nature. Although it leads to a different style in specification, the method avoids some fundamental problems inherent in the algebraic specification method. The logic proposed is essentially a first-order logic for strict (partial) functions. It allows in particular the expression of the semantic conditions guaranteeing the consistency of a specification.


title: Retargetable Microcode Synthesis

authors:
Robert A. Mueller
Joseph Varghese

abstract: Most work on automating the translation of high-level microprogramming languages into microcode has dealt with lexical and syntactic analysis and the use of manually produced macro tables for code generation. We describe an approach to and some results on the formalization and automation of the more difficult problem of retargeting local code generation in a machine-independent, optimizing microcode synthesis system. Whereas this problem is similar in many ways to that of retargeting local code generation in high-level language compilers, there are some major differences that call for new approaches. The primary issues addressed in this paper are the representation of target microprogrammable machines, the intermediate representation of local microprogram function, and general algorithmic methods for deriving local microcode from target machine and microcode function specifications. Of particular interest are the use of formal semantics and data flow principles in achieving both a general and reasonably efficient solution. Examples of the modeling of a representative horizontal machine (the PUMA) and the generation of microcode for the PUMA machine model from our working implementation are presented.


title: Sublinear-Space Evaluation Algorithms for Attribute Grammars

authors:
Thomas W. Reps
Alan J. Demers

abstract: A major drawback of attribute-grammar-based systems is that they are profligate consumers of storage. This paper concerns new storage-management techniques that reduce the number of attribute values retained at any stage of attribute evaluation; it presents an algorithm for evaluating an n -attribute tree that never retains more than O (log n ) attribute values. This method is optimal, although it may require nonlinear time. A second algorithm, which never retains more than O (√ n ) attribute values, is also presented, both as an introduction to the O (log n ) method and because it works in linear time.


title: Efficient Algorithms for Automatic Construction and Compactification of Parsing Grammars

authors:
Daniel J. Rosenkrantz
Harry B. Hunt III

abstract: Several computational problems about grammars are studied. Efficient algorithms are presented for the problems of (1) determining, for a given semantic grammar, if there exists a related parsing grammar in some specified grammar class, and (2) finding such a related parsing grammar when one exists. The two grammars are to be related by mergers of nonterminals and/or terminals. Efficient algorithms are presented for most of the grammar classes used in compilers. We also study the problem of (3) determining which terminals of a grammar are good candidates for merger into common lexical tokens of the corresponding parsing grammar.


title: Soundness of Hoare's Logic: An Automated Proof Using LCF

abstract: This paper presents a natural deduction proof of Hoare's logic carried out by the Edinburgh LCF theorem prover. The emphasis is on the way Hoare's theory is presented to the LCF, which looks very much like an exposition of syntax and semantics to human readers; and on the programmable heuristics (tactics). We also discuss some problems and possible improvements to the LCF.


title: Graph Translation Schemes to Generate Compiler Parts

abstract: Graph translation schemes (GTSs) are a generalization of attribute grammars and of some ideas in Koster's language CDL2 They are specially designed to support a compiler writer in defining parts of the back-end of his compiler, but they can also be useful for the specification of the analysis pass of a compiler. GTSs combine elements of functional and of algorithmic specification techniques to allow iterative attribute evaluation and attributing of program graphs. GTSs consist of only a few syntactical elements. We present operational semantics and discuss improvements in the efficiency of the proposed implementation of GTSs.


title: Writing Larch Interface Language Specifications

abstract: Current research in specifications is emphasizing the practical use of formal specifications in program design. One way to encourage their use in practice is to provide specification languages that are accessible to both designers and programmers. With this goal in mind, the Larch family of formal specification languages has evolved to support a two-tiered approach to writing specifications. This approach separates the specification of state transformations and programming language dependencies from the specification of underlying abstractions. Thus, each member of the Larch family has a subset derived from a programming language and another subset independent of any programming languages. We call the former interface languages, and the latter the Larch Shared Language. This paper focuses on Larch interface language specifications. Through examples, we illustrate some salient features of Larch/CLU, a Larch interface language for the programming language CLU. We give an example of writing an interface specification following the two-tiered approach and discuss in detail issues involved in writing interface specifications and their interaction with their Shared Language components.


title: An Axiomatic Treatment of Exception Handling in an Expression-Oriented Language

authors:
Shaula Yemini
Daniel M. Berry

abstract: An axiomatic semantic definition is given of the replacement model of exception handling in an expression-oriented language. These semantics require only two new proof rules for the most general case. An example is given of a program fragment using this model of exception handling, and these rules are used to verify the consistency of the fragment and its specification.


title: An Overview of the SR Language and Implementation

authors:
Gregory R. Andrews
Ronald A. Olsson
Michael H. Coffin
Irving Elshoff
Kelvin D. Nilsen
Titus D. M. Purdin
Gregg M. Townsend

abstract: SR is a language for programming distributed systems ranging from operating systems to application programs. On the basis of our experience with the initial version, the language has evolved considerably. In this paper we describe the current version of SR and give an overview of its implementation. The main language constructs are still resources and operations. Resources encapsulate processes and variables that they share; operations provide the primary mechanism for process interaction. One way in which SR has changed is that both resources and processes are now created dynamically. Another change is that inheritance is supported. A third change is that the mechanisms for operation invocation—call and send—and operation implementation—proc and in—have been extended and integrated. Consequently, all of local and remote procedure call, rendezvous, dynamic process creation, asynchronous message passing, multicast, and semaphores are supported. We have found this flexibility to be very useful for distributed programming. Moreover, by basing SR on a small number of well-integrated concepts, the language has proved easy to learn and use, and it has a reasonably efficient implementation.


title: Distributed Cooperation with Action Systems

authors:
Ralph-Johan Back
Reino Kurki-Suonio

abstract: Action systems provide a method to program distributed systems that emphasizes the overall behavior of the system. System behavior is described in terms of the possible interactions (actions) that the processes can engage in, rather than in terms of the sequential code that the processes execute. The actions provide a symmetric communication mechanism that permits an arbitrary number of processes to be synchronized by a common handshake. This is a generalization of the usual approach, employed in languages like CSP and Ada, in which communication is asymmetric and restricted to involve only two processes. Two different execution models are given for action systems: a sequential one and a concurrent one. The sequential model is easier to use for reasoning, and is essentially equivalent to the guarded iteration statement by Dijkstra. It is well suited for reasoning about system properties in temporal logic, but requires a stronger fairness notion than it is reasonable to assume a distributed implementation will support. The concurrent execution model reflects the true concurrency that is present in a distributed execution, and corresponds to the way in which the system is actually implemented. An efficient distributed implementation of action systems on a local area network is described. The fairness assumptions of the concurrent model can be guaranteed in this implementation. The relationship between the two execution models is studied in detail in the paper. For systems that will be called fairly serializable, the two models are shown to be equivalent. Proof methods are given for verifying this property of action systems. It is shown that for fairly serializable systems, properties that hold for any concurrent execution of the system can be established by temporal proofs that are conducted entirely within the simpler sequential execution model.


title: On the (non-) Relationship between SLR(1) and NQLALR(1) Grammars

authors:
Manuel E. Bermudez
Karl M. Schimpf

abstract: A popular but “not-quite” correct technique for computing LALR(1) look-ahead sets has been formalized by DeRemer and Pennello and dubbed NQLALR(l). They also claim that the class of SLR(l) grammars is a subset of the class of NQLALR(1) grammars. We prove here that no such relationship exists between those two classes. We do so with a counterexample that, ironically, appeared in DeRemer and Pennello's own paper.


title: Abstract Interaction Tools: A Language for User Interface Management Systems

abstract: A language model is presented for the specification of User Interface Management Systems. The model, called the Abstract Interaction Tool (AIT) model, offers a tree-like hierarchy of interaction objects. Each object represents a subtree and can be considered as an abstract input device containing a syntax-like specification of the required input pattern. The hierarchy of specifications amounts to a system of syntactical productions with multiple control. Terminal nodes of the AIT tree represent the interface to the physical interaction devices. The AIT model features hierarchical output resource management. At the higher, more abstract, level the input-output is loosely coupled. At lower levels the coupling becomes increasingly tight. At the upper levels, AITs model the functions (what) required by the user, whereas at the lower levels the way to accomplish them (how) is stressed. The AIT model has modes for multithread and multiple-device user interaction. There are facilities for context-dependent prompting, echoing, feedback, error correction, and expertise levels. A special section in the AIT provides for links to application modules. As a model for general interactive systems, AITs can be applied to graphics, process control, dialogue, and real-time systems. AITs can also be used to define controlled production rules in knowledge-based systems. In addition the model can provide tools for the software engineering phases specification and prototyping.


title: System Semantics: Principles, Applications, and Implementation

abstract: Systems semantics extends the denotational semantics of programming languages to a semantics for the description of arbitrary systems, including objects that are not computations in any sense. By defining different meaning functions, the same formal description may be used to denote different system properties, such as structure, behavior, component cost, and performance aspects (e.g., timing). The definition of these semantic functions also provides guidance in language design, in particular for the match between language constructs and the system concepts to be expressed. Aiming at compositionality ensures useful properties for formal manipulation. In this fashion, the meaning functions can be made sufficiently simple to serve not only as a direct implementation on a machine but also as rules for reasoning about systems in a transformational manner. As the applications show, however, compositionality can be ensured only through careful consideration of the characteristics of the flow of information inside the system. Two classes of application are discussed: Unidirectional systems, in particular digital systems without feedback (combinational) and with feedback (sequential), and a certain class of analog systems. Nonunidirectional systems, in particular two-port analog networks. The emphasis will be on the functional style of description and on formal reasoning (theorem proving, derivation of properties). Implementation and rapid prototyping strategies in various system description environments are also briefly discussed. These would permit the concepts of system semantics to be explored without the need for a complete implementation.


title: Efficient Incremental LR Parsing for Syntax-Directed Editors

authors:
Pierpaolo Degano
Stefano Mannucci
Bruno Mojana

abstract: A technique for generating parsers which is an extension to LR techniques and is based on parsing table splitting, is presented. Then this technique is slightly extended to support incremental syntax analysis. Given a context-free grammar and a set “ IC ” of nonterminals devised to be incremental, a set of subtables is generated to drive the analysis of program fragments derivable from nonterminals in IC . The proposed technique generates parsing tables which are considerably smaller than the standard ones, even when incrementality is not exploited. Thus, these tables may be stored as arrays permitting faster access and accurate error handling. Furthermore, our tables are suitable for generating syntax-directed editors which provide a full analytic mode. The efficiency of the analytic component of a syntax-directed editor obtained in this way and its easy integration with the generative component stress the advantages of incremental program writing.


title: Constrained Expressions: Toward Broad Applicability of Analysis Methods for Distributed Software Systems

authors:
Laura K. Dillon
George S. Avrunin
Jack C. Wileden

abstract: It is extremely difficult to characterize the possible behaviors of a distributed software system through informal reasoning. Developers of distributed systems require tools that support formal reasoning about properties of the behaviors of their systems. These tools should be applicable to designs and other preimplementation descriptions of a system, as well as to completed programs. Furthermore, they should not limit a developer's choice of development languages. In this paper we present a basis for broadly applicable analysis methods for distributed software systems. The constrained expression formalism can be used with a wide variety of distributed system development notations to give a uniform closed-form representation of a system's behavior. A collection of formal analysis techniques can then be applied with this representation to establish properties of the system. Examples of these formal analysis techniques appear elsewhere. Here we illustrate the broad applicability of the constrained expression formalism by showing how constrained expression representations are obtained from descriptions of systems in three different notations: SDYMOL, CSP, and Petri nets. Features of these three notations span most of the significant alternatives for describing distributed software systems. Our examples thus offer persuasive evidence for the broad applicability of the constrained expression approach.


title: A Solution to a Problem with Morel and Renvoise's "Global Optimization by Suppression of Partial Redundancies"

authors:
Karl-Heinz Drechsler
Manfred P. Stadel

abstract: Morel and Renvoise have previously described a method for global optimization and code motion by suppression of partial redundancies [l]. Morel and Renvoise use data flow analysis to determine expression computations that should be inserted at the end of certain basic blocks and to determine redundant computations that can be eliminated. The execution of these techniques results in the movement of loop invariant expressions out of the loop. In addition to [l] Morel and Renvoise's techniques can also be applied to subexpressions of larger expressions. Then, however, in certain special cases these optimization techniques move expressions to places where some of its subexpressions are neither available nor moved together with the expression. In this paper we present a modification of Morel and Renvoise's algorithm that avoids the above described situations.


title: Simple, Efficient Asynchronous Parallel Algorithms for Maximization

authors:
Albert G. Greenberg
Boris D. Lubachevsky
Andrew M. Odlyzko

abstract: The problem of computing the maximum of n inputs on an asynchronous parallel computer is considered. In general, the inputs may arrive staggered in time, the number of processors available to the maximization algorithm may vary during its execution, and the number of inputs, n , may be initially unknown. Two simple, efficient algorithms to compute the maximum are presented. Each algorithm may be invoked asynchronously, as new inputs and processors arrive. Performance measures that account for the response times of the invocations are introduced, and the algorithms are analyzed under these measures.


title: A Mathematical Approach to Nondeterminism in Data Types

abstract: The theory of abstract data types is generalized to the case of nondeterministic operations (set-valuedfunctions). Since the nondeterminism of operations may be coupled, signatures are extended so that operations can have results in Cartesian products. Input/output behavior is used to characterize implementation of one model by another. It is described by means of accumulated arrows, which form a generalization of the term algebra. Morphisms of nondeterministic models are introduced. Both innovations prove to be powerful tools in the analysis of input/output behavior. Extraction equivalence and observable equivalence of values are investigated. Quotient models for such equivalence relations are constructed. The equivalence relations are compared with each other, with separation of values by means of experiments, and with the separation property that characterizes a terminal model. Examples are given to show that the four concepts are different. In deterministic models the concepts coincide.


title: An Ada Package for Dimensional Analysis

abstract: This paper illustrates the use of Ada's abstraction facilities—notably, operator overloading and type parameterization—to define an oft-requested feature: a way to attribute units of measure to variables and values. The definition given allows the programmer to specify units of measure for variables, constants, and parameters; checks uses of these entities for dimensional consistency; allows arithmetic between them, where legal; and provides scale conversions between commensurate units. It is not constrained to a particular system of measurement (such as the metric or English systems). Although the definition is in standard Ada and requires nothing special of the compiler, certain reasonable design choices in the compiler, discussed here at some length, can make its implementation particularly efficient.


title: Analysis of Functional Programs to Detect Run-Time Garbage Cells

authors:
Katsuro Inoue
Hiroyuki Seki
Hikaru Yagi

abstract: We propose a method for detecting the generation of garbage cells by analyzing a source text written in a functional programming language which uses ordinary linked lists to implement list-type values. For a subexpression such as F ( G ( . . . )) in a program where the function values of F and G are of list type, if a cell c is created during the computation of G and if c does not appear in a list-type value of F , then c becomes a garbage cell at the end of the computation of F . We discuss this problem on the basis of formal languages derived from the functional program text and show some sufficient conditions that predict the generation of garbage cells. Also, we give an efficient algorithm to detect at compile time the generation of garbage cells which are linearly linked. We have implemented these algorithms in an experimental LISP system. By executing several sample programs on the system, we conclude that our method is effective in detecting the generation of garbage cells.


title: Director Strings as Combinators

authors:
Richard Kennaway
M. Ronan Sleep

abstract: A simple calculus (the Director String Calculus-DSC) for expressing abstractions is introduced, which captures the essence of the “long reach” combinators introduced by Turner. We present abstraction rules that preserve the applicative structure of the original lambda term, and that cannot increase the number of subterms in the translation. A translated lambda term can be reduced according to the evaluation rules of DSC. If this terminates with a DSC normal form, this can be translated into a lambda term using rules presented below. We call this process of abstracting a lambda term, reducing to normal form in the space of DSC terms, and translating back to a lambda term an implementation . We show that our implementation of the lambda calculus is correct: For lambda terms with a normal form that contains no lambdas ( ground terms ), the implementation is shown to yield a lambda calculus normal form. For lambda terms whose normal forms represent functions, it is shown that the implementation yields lambda terms that are beta-convertible in zero or more steps to the normal form of the original lambda term. In this sense, our implementation involves weak reduction according to Hindley et al. [9].


title: Efficient Synchronization on Multiprocessors with Shared Memory

authors:
Clyde P. Kruskal
Larry Rudolph
Marc Snir

abstract: A new formalism is given for read-modify-write (RMW) synchronization operations. This formalism is used to extend the memory reference combining mechanism introduced in the NYU Ultracomputer, to arbitrary RMW operations. A formal correctness proof of this combining mechanism is given. General requirements for the practicality of combining are discussed. Combining is shown to be practical for many useful memory access operations. This includes memory updates of the form mem _ val := mem _ val op val , where op need not be associative, and a variety of synchronization primitives. The computation involved is shown to be closely related to parallel prefix evaluation.


title: Control Predicates are Better than Dummy Variables for Reasoning about Program Control

abstract: When explicit control predicates rather than dummy variables are used, the Owicki-Gries method for proving safety properties of concurrent programs can be strengthened, making it easier to construct the required program annotations.


title: Determining the Extent of Lookahead in Syntactic Error Repair

authors:
Jon Mauney
Charles N. Fischer

abstract: Many syntactic error repair strategies examine several additional symbols of input to guide the choice of a repair; a problem is determining how many symbols to examine. The goal of gathering all relevant information is discussed and shown to be impractical; instead we can gather all information relevant to choosing among a set of “minimal repairs.” We show that finding symbols with the property “Moderate Phrase-Level Uniqueness” is sufficient to establish that all information relevant to these minimal repairs has been seen. Empirical results on the occurrence of such symbols in Pascal are presented.


title: ACE: An Automatic Complexity Evaluator

abstract: There has been a great deal of research done on the evaluation of the complexity of particular algorithms; little effort, however, has been devoted to the mechanization of this evaluation. The ACE (Automatic Complexity Evaluator) system is able to analyze reasonably large programs, like sorting programs, in a fully mechanical way. A time-complexity function is derived from the initial functional program. This function is transformed into its nonrecursive equivalent according to MacCarthy's recursion induction principle, using a predefined library of recursive definitions. As the complexity is not a decidable property, this transformation will not be possible in all cases. The richer the predefined library is, the more likely the system is to succeed. The operations performed by ACE are described and the use of the system is illustrated with the analysis of a sorting algorithm. Related works and further improvements are discussed in the conclusion.


title: Abstract Types Have Existential Type

authors:
John C. Mitchell
Gordon D. Plotkin

abstract: Abstract data type declarations appear in typed programming languages like Ada, Alphard, CLU and ML. This form of declaration binds a list of identifiers to a type with associated operations, a composite “value” we call a data algebra . We use a second-order typed lambda calculus SOL to show how data algebras may be given types, passed as parameters, and returned as results of function calls. In the process, we discuss the semantics of abstract data type declarations and review a connection between typed programming languages and constructive logic.


title: The Specification Statement

abstract: Dijkstra's programming language is extended by specification statements , which specify parts of a program “yet to be developed.” A weakest precondition semantics is given for these statements so that the extended language has a meaning as precise as the original. The goal is to improve the development of programs, making it closer to manipulations within a single calculus. The extension does this by providing one semantic framework for specifications and programs alike: Developments begin with a program (a single specification statement) and end with a program (in the executable language). And the notion of refinement or satisfaction , which normally relates a specification to its possible implementations, is automatically generalized to act between specifications and between programs as well. A surprising consequence of the extension is the appearance of miracles : program fragments that do not satisfy Dijkstra's Law of the Excluded Miracle . Uses for them are suggested.


title: A Note on the Drinking Philosophers Problem

authors:
Sandra L. Murphy
A. Udaya Shankar


title: Fairness in Parallel Programs: The Transformational Approach

authors:
Ernst-Rüdiger Olderog
Krzysztof R. Apt

abstract: Program transformations are proposed as a means of providing fair parallelism semantics for parallel programs with shared variables. The transformations are developed in two steps. First, abstract schedulers that implement the various fairness policies are introduced. These schedulers use random assignments z := ? to represent the unbounded nondeterminism induced by fairness. Concrete schedulers are derived by suitably refining the ?. The transformations are then obtained by embedding the abstract schedulers into the parallel programs. This embedding is proved correct on the basis of a simple transition semantics. Since the parallel structure of the original program is preserved, the transformations also provide a basis for syntax-directed proofs of total correctness under the fairness assumption. These proofs make use of infinite ordinals.


title: Specification and Verification of Liveness Properties of Cyclic, Concurrent Processes

authors:
Joylyn Reed
Raymond T. Yeh

abstract: A technique is described for software specification and verification of concurrent, distributed systems. The complete specification of a program is given in terms of a hierarchical structure of module specifications. Module external specifications are abstract; module internal specifications are descriptions of internal implementations, either in terms of submodules or actual code. The verification that an implementation satisfies its specification is language independent for the former and language dependent for the latter. Distinguishing the liveness properites provided by a module and the liveness properties required by a module (from its comodules) allows the specification and verification of a given module to be independent from the specification and verification of its comodules.


title: Incremental Data-Flow Analysis

authors:
Barbara G. Ryder
Marvin C. Paull

abstract: An incremental update algorithm modifies the solution of a problem that has been changed, rather than re-solving the entire problem. ACINCF and ACINCB are incremental update algorithms for forward and backward data-flow analysis, respectively, based on our equations model of Allen-Cocke interval analysis. In addition, we have studied their performance on a “nontoy” structured programming language L. Given a set of localized program changes in a program written in L, we identify a priori the nodes in its flow graph whose corresponding data-flow equations may be affected by the changes. We characterize these possibly affected nodes by their corresponding program structures and their relation to the original change sites, and do so without actually performing the incremental updates . Our results can be refined to characterize the reduced equations possibly affected if structured loop exit mechanisms are used, either singly or together, thereby relating richness of programming language usage to the ease of incremental updating.


title: Smarter Recompilation

authors:
Robert W. Schwanke
Gail E. Kaiser

abstract: Tichy's Smart Recompilation method can be made smarter by permitting benign type inconsistencies between separately compiled modules. This enhanced method helps the programmer to make far-reaching changes in small, manageable steps.


title: Efficient and Correct Execution of Parallel Programs that Share Memory

authors:
Dennis E. Shasha
Marc Snir

abstract: In this paper we consider an optimization problem that arises in the execution of parallel programs on shared-memory multiple-instruction-stream, multiple-data-stream (MIMD) computers. A program on such machines consists of many sequential program segments, each executed by a single processor. These segments interact as they access shared variables. Access to memory is asynchronous, and memory accesses are not necessarily executed in the order they were issued. An execution is correct if it is sequentially consistent: It should seem as if all the instructions were executed sequentially, in an order obtained by interleaving the instruction streams of the processors. Sequential consistency can be enforced by delaying each access to shared memory until the previous access of the same processor has terminated. For performance reasons, however, we want to allow several accesses by the same processor to proceed concurrently. Our analysis finds a minimal set of delays that enforces sequential consistency. The analysis extends to interprocessor synchronization constraints and to code where blocks of operations have to execute atomically. We use a conflict graph similar to that used to schedule transactions in distributed databases. Our graph incorporates the order on operations given by the program text, enabling us to do without locks even when database conflict graphs would suggest that locks are necessary. Our work has implications for the design of multiprocessors; it offers new compiler optimization techniques for parallel languages that support shared variables.


title: Tichy's Response to R. W. Schwanke and G. E. Kaiser's "Smarter Recompilation"

abstract: Schwanke and Kaiser's extension of smart recompilation is an intriguing idea. Their mechanism aims at delaying recompilation work by permitting “harmless” compilation inconsistencies to remain after changes. Full consistency can be reestablished at a later time, after the change has been tested in a subpart of the system. If the change was inadequate, then no needless compilation work was performed. This strategy is used frequently in practice, by exploiting loopholes in system generation tools. Schwanke and Kaiser's mechanism is novel in that it makes this practice safe. The compiler is aware of the inconsistencies, and will not overlook dangerous ones. Furthermore, it can help reestablish full consistency once a change is deemed acceptable. Smarter recompilation defines a harmless inconsistency as follows. If a declaration is changed, this action is treated as introducing a new version of the declaration. The coexistence of both the old and new versions in the same configuration is a harmless inconsistency as long as the uses of the two versions do not conflict. The system must be separable into two partitions, one that uses the old version and the other the new one, such that the interface between the two depends on neither. Since the inconsistent declarations do not cross the interface, the two partitions may even communicate with each other. Of course, inconsistencies not captured by the type system cannot be treated in this way. Schwanke and Kaiser's note leaves a few minor questions unanswered. For instance, a new or changed declaration might cause a redeclaration or overloading error that can only be detected by recompilation. Is this potential problem left undetected until full consistency is desired, or is it checked immediately? If a declaration is deleted that is still in use, is the deletion treated as an error or as a delayed deletion that will take effect after the last use disappears? If the old and new versions of a procedure operate on the same data structure, is it always desirable to let both versions coexist, or can the programmer indicate that the old version should be eliminated before the next program execution? Perhaps a future paper about an implementation will clarify these points. Smarter recompilation also opens the door for more powerful programming tools. For example, since the mechanism maintains cross-reference information, a tool like Masterscope [1] could be built relatively easily. The tool would have the advantage that cross-reference information is immediately available once a module has been compiled. Only little additional data would be needed to classify the uses of symbols. The information could also be exploited by a Maintainer's Assistant. This program helps with reestablishing consistency after changes by suggesting corrections of the affected program parts. For example, it could attempt to make call sites of changed procedures consistent with their headers, update operations on changed record fields, or perform some simple program transformations in response to data structure changes.


title: Type Extensions

abstract: Software systems represent a hierarchy of modules. Client modules contain sets of procedures that extend the capabilities of imported modules. This concept of extension is here applied to data types. Extended types are related to their ancestor in terms of a hierarchy. Variables of an extended type are compatible with variables of the ancestor type. This scheme is expressed by three language constructs only: the declaration of extended record types, the type test, and the type guard. The facility of extended types, which closely resembles the class concept, is defined in rigorous and concise terms, and an efficient implementation is presented.


title: Code Generation Using Tree Matching and Dynamic Programming

authors:
Alfred V. Aho
Mahadevan Ganapathi
Steven W. K. Tjiang

abstract: Compiler-component generators, such as lexical analyzer generators and parser generators, have long been used to facilitate the construction of compilers. A tree-manipulation language called twig has been developed to help construct efficient code generators. Twig transforms a tree-translation scheme into a code generator that combines a fast top-down tree-pattern matching algorithm with dynamic programming. Twig has been used to specify and construct code generators for several experimental compilers targeted for different machines.


title: Efficient Implementation of Lattice Operations

authors:
Hassan Aït-Kaci
Robert S. Boyer
Patrick Lincoln
Roger Nasr

abstract: Lattice operations such as greatest lower bound (GLB), least upper bound (LUB), and relative complementation (BUTNOT) are becoming more and more important in programming languages supporting object inheritance. We present a general technique for the efficient implementation of such operations based on an encoding method. The effect of the encoding is to plunge the given ordering into a boolean lattice of binary words, leading to an almost constant time complexity of the lattice operations. A first method is described based on a transitive closure approach. Then a more space-efficient method minimizing code-word length is described. Finally a powerful grouping technique called modulation is presented, which drastically reduces code space while keeping all three lattice operations highly efficient. This technique takes into account idiosyncrasies of the topology of the poset being encoded that are quite likely to occur in practice. All methods are formally justified. We see this work as an original contribution towards using semantic (vz., in this case, taxonomic) information in the engineering pragmatics of storage and retrieval of (vz., partially or quasi-ordered) information.


title: Verifying Temporal Properties without Temporal Logic

authors:
Bowen Alpern
Fred B. Schneider

abstract: An approach to proving temporal properties of concurrent programs that does not use temporal logic as an inference system is presented. The approach is based on using Buchi automata to specify properties. To show that a program satisfies a given property, proof obligations are derived from the Buchi automata specifying that property. These obligations are discharged by devising suitable invariant assertions and variant functions for the program. The approach is shown to be sound and relatively complete. A mutual exclusion protocol illustrates its application.


title: On Lamport's Interprocessor Communication Model

abstract: Leslie Lamport presented a set of axioms in 1979 that capture the essential properties of the temporal relationships between complex and perhaps unspecified activities within any system, and proceeded to use this axiom system to prove the correctness of sophisticated algorithms for reliable communication and mutual exclusion in systems without shared memory. As a step toward a more complete metatheory of Lamport's axiom system, this paper determines the extent to which that system differs from systems based on “atomic,” or indivisible, actions. Theorem 1 shows that only very weak conditions need be satisfied in addition to the given axioms to guarantee the existence of an atomic “model,” while Proposition 1 gives sufficient conditions under which any such model must be a “faithful” representation. Finally, Theorem 2 restates a result of Lamport showing exactly when a system can be thought of as made up of a set of atomic events that can be totally ordered temporally. A new constructive proof is offered for this result.


title: I-Structures: Data Structures for Parallel Computing

authors:
Arvind
Rishiyur S. Nikhil
Keshav Pingali

abstract: It is difficult to achieve elegance, efficiency, and parallelism simultaneously in functional programs that manipulate large data structures. We demonstrate this through careful analysis of program examples using three common functional data-structuring approaches-lists using Cons, arrays using Update (both fine-grained operators), and arrays using make-array (a “bulk” operator). We then present I-structure as an alternative and show elegant, efficient, and parallel solutions for the program examples in Id, a language with I-structures. The parallelism in Id is made precise by means of an operational semantics for Id as a parallel reduction system. I-structures make the language nonfunctional, but do not lose determinacy. Finally, we show that even in the context of purely functional languages, I-structures are invaluable for implementing functional data abstractions.


title: Synchronization of Asynchronous Processes in CSP

abstract: Many concurrent programming languages including CSP and Ada use synchronous message-passing to define communication between a pair of asynchronous processes. Suggested primitives like the generalized alternative command for CSP and the symmetric select statement for Ada allow a process to nondeterministically select one of several communication statements for execution. The communication statement may be either an input or an output statement. We propose a simple algorithm to implement the generalized alternative command and show that it uses fewer messages than existing algorithms.


title: Concurrency in Heavily Loaded Neighborhood-Constrained Systems

authors:
Valmir Carneiro Barbosa
Eli Gafni

abstract: Let G be a connected undirected graph in which each node corresponds to a process and two nodes are connected by an edge if the corresponding processes share a resource. We consider distributed computations in which processes are constantly demanding all of their resources in order to operate, and in which neighboring processes may not operate concurrently. We advocate that such a system is general enough for representing a large class of resource-sharing systems under heavy load. We employ a distributed scheduling mechanism based on acyclic orientations of G and investigate the amount of concurrency that it provides. We show that this concurrency is given by a number akin to G 's chromatic and multichromatic numbers, and that, among scheduling schemes which require neighbors in G to alternate in their turns to operate, ours is the one that potentially provides the greatest concurrency. However, we also show that the decision problem corresponding to optimizing concurrency is NP -complete.


title: Scheduling Expressions on a Pipelined Processor with a Maximal Delay of One Cycle

authors:
David Bernstein
Izidor Gertner

abstract: Consider a pipelined machine that can issue instructions every machine cycle. Sometimes, an instruction that uses the result of the instruction preceding it in a pipe must be delayed to ensure that a program computes a right value. We assume that issuing of such instructions is delayed by at most one machine cycle. For such a machine model, given an unbounded number of machine registers and memory locations, an algorithm to find a shortest schedule of the given expression is presented and analyzed. The proposed algorithm is a modification of Coffman-Graham's algorithm [7], which provides an optimal solution to the problem of scheduling tasks on two parallel processors.


title: Efficient Implementation of the First-Fit Strategy for Dynamic Storage Allocation

abstract: We describe an algorithm that efficiently implements the first-fit strategy for dynamic storage allocation. The algorithm imposes a storage overhead of only one word per allocated block (plus a few percent of the total space used for dynamic storage), and the time required to allocate or free a block is O (log W ), where W is the maximum number of words allocated dynamically. The algorithm is faster than many commonly used algorithms, especially when many small blocks are allocated, and has good worst-case behavior. It is relatively easy to implement and could be used internally by an operating system or to provide run-time support for high-level languages such as Pascal and Ada. A Pascal implementation is given in the Appendix.


title: Uniform Self-Stabilizing Rings

authors:
James E. Burns
Jan K. Pachl

abstract: A self-stabilizing system has the property that, no matter how it is perturbed, it eventually returns to a legitimate configuration. Dijkstra originally introduced the self-stabilization problem and gave several solutions for a ring of processors in his 1974 Communications of the ACM paper. His solutions use a distinguished processor in the ring, which effectively acts as a controlling element to drive the system toward stability. Dijkstra has observed that a distinguished processor is essential if the number of processors in the ring is composite. We show, by presenting a protocol and proving its correctness, that there is a self-stabilizing system with no distinguished processor if the size of the ring is prime. The basic protocol uses Θ ( n 2 ) states in each processor when n is the size of the ring. We modify the basic protocol to obtain one that uses Θ ( n 2 /ln n ) states.


title: Efficient High-Level Iteration with Accumulators

abstract: Accumulators are proposed as a new type of high-level iteration construct for imperative languages. Accumulators are user-programmed mechanisms for successively combining a sequence of values into a single result value. The accumulated result can either be a simple numeric value such as the sum of a series or a data structure such as a list. Accumulators naturally complement constructs that allow iteration through user-programmed sequences of values such as the iterators of CLU and the generators of Alphard. A practical design for high-level iteration is illustrated by way of an extension to Modula-2 called Modula Plus. The extension incorporates both a redesigned mechanism for iterators as well as the accumulator design. Several applications are illustrated including both numeric and data structure accumulation. It is shown that the design supports efficient iteration both because it is amenable to implementation via in-line coding and because it allows high-level iteration concepts to be implemented as encapsulations of efficient low-level manipulations.


title: ECCS and LIPS: Two Languages for OSI Systems Specification and Verification

authors:
Vincenza Carchiolo
Antonella Di Stefano
Alberto Faro
Giuseppe Pappalardo

abstract: An issue of current interest in the Open Systems Interconnection (OSI) field is the choice of a language well suited to specification and verification. For this purpose, two languages based on Milner's communication calculi are proposed, respectively intended for the specification of asynchronous and synchronous OSI systems. A formal verification method, relying upon the algebraic foundations of the two languages, is introduced and illustrated by means of examples based on nontrivial protocols and services.


title: Static Inference of Modes and Data Dependencies in Logic Programs

abstract: Mode and data dependency analyses find many applications in the generation of efficient executable code for logic programs. For example, mode information can be used to generate specialized unification instructions where permissible, to detect determinacy and functionality of programs, generate index structures more intelligently, reduce the amount of runtime tests in systems that support goal suspension, and in the integration of logic and functional languages. Data dependency information can be used for various source-level optimizing transformations, to improve backtracking behavior and to parallelize logic programs. This paper describes and proves correct an algorithm for the static inference of modes and data dependencies in a program. The algorithm is shown to be quite efficient for programs commonly encountered in practice.


title: Functional Computations in Logic Programs

authors:
Saumya K. Debray
David Scott Warren

abstract: Although the ability to simulate nondeterminism and to compute multiple solutions for a single query is a powerful and attractive feature of logic programming languages, it is expensive in both time and space. Since programs in such languages are very often functional, that is, they do not produce more than one distinct solution for a single input, this overhead is especially undesirable. This paper describes how programs may be analyzed statically to determine which literals and predicates are functional, and how the program may then be optimized using this information. Our notion of “functionality” subsumes the notion of “determinacy” that has been considered by various researchers. Our algorithm is less reliant on language features such as the cut, and thus extends more easily to parallel execution strategies, than others that have been proposed.


title: Distributed FIFO Allocation of Identical Resources Using Small Shared Space

authors:
Michael J. Fischer
Nancy A. Lynch
James E. Burns
Allan Borodin

abstract: We present a simple and efficient algorithm for the FIFO allocation of k identical resources among asynchronous processes that communicate via shared memory. The algorithm simulates a shared queue but uses exponentially fewer shared memory values, resulting in practical savings of time and space as well as program complexity. The algorithm is robust against process failure through unannounced stopping, making it attractive also for use in an environment of processes of widely differing speeds. In addition to its practical advantages, we show that for fixed k , the shared space complexity of the algorithm as a function of the number N of processes is optimal to within a constant factor.


title: Integrating Noninterfering Versions of Programs

authors:
Susan Horwitz
Jan F. Prins
Thomas W. Reps

abstract: The need to integrate several versions of a program into a common one arises frequently, but it is a tedious and time consuming task to integrate programs by hand. To date, the only available tools for assisting with program integration are variants of text-based differential file comparators; these are of limited utility because one has no guarantees about how the program that is the product of an integration behaves compared to the programs that were integrated. This paper concerns the design of a semantics-based tool for automatically integrating program versions. The main contribution of the paper is an algorithm that takes as input three programs A , B , and Base , where A and B are two variants of Base . Whenever the changes made to Base to create A and B do not “interfere” (in a sense defined in the paper), the algorithm produces a program M that integrates A and B . The algorithm is predicated on the assumption that differences in the behavior of the variant programs from that of Base , rather than differences in the text , are significant and must be preserved in M . Although it is undecidable whether a program modification actually leads to such a difference, it is possible to determine a safe approximation by comparing each of the variants with Base . To determine this information, the integration algorithm employs a program representation that is similar (although not identical) to the dependence graphs that have been used previously in vectorizing and parallelizing compilers. The algorithm also makes use of the notion of a program slice to find just those statements of a program that determine the values of potentially affected variables. The program-integration problem has not been formalized previously. It should be noted, however, that the integration problem examined here is a greatly simplified one; in particular, we assume that expressions contain only scalar variables and constants, and that the only statements used in programs are assignment statements, conditional statements, and while-loops.


title: Incremental Dynamic Semantics for Language-Based Programming Environments

abstract: Attribute grammars are a formal notation for expressing the static semantics of programming languages—those properties that can be derived from inspection of the program text. Attribute grammars have become popular as a mechanism for generating language-based programming environments that incrementally perform symbol resolution, type checking, code generation, and derivation of other static semantic properties as the program is modified. However, attribute grammars are not suitable for expressing dynamic semantics—those properties that reflect the history of program execution and/or user interactions with the programming environment. This paper presents action equations , an extension of attribute grammars suitable for specifying the static and the dynamic semantics of programming languages. It describes how action equations can be used to generate language-based programming environments that incrementally derive static and dynamic properties as the user modifies and debugs th e program.


title: Designing Families of Data Types Using Exemplars

abstract: Designing data types in isolation is fundamentally different from designing them for integration into communities of data types, especially when inheritance is a fundamental issue. Moreover, we can distinguish between the design of families—integrated types that are variations of each other—and more general communities where totally different but cohesive collections of types support specific applications (e.g., a compiler). We are concerned with the design of integrated families of data types as opposed to individual data types; that is, on the issues that arise when the focus is intermediate between the design of individual data types and more general communities of data types. We argue that design at this level is not adequately served by systems providing only class-based inheritance hierarchies and that systems which additionally provide a coupled subtype specification hierarchy are still not adequate. We propose a system that provides an unlimited number of uncoupled specification hi erarchies and illustrate it with three: a subtype hierarchy, a specialization/generalization hierarchy, and a like hierarchy. We also resurrect a relatively unknown Smalltalk design methodology that we call programming-by-exemplars and argue that it is an important addition to a designer's grab bag of techniques. The methodology is used to show that the subtype hierarchy must be decoupled from the inheritance hierarchy, something that other researchers have also suggested. However, we do so in the context of exemplar-based systems to additionally show that they can already support the extensions required without modification and that they lead to a better separation between users and implementers, since classes and exemplars can be related in more flexible ways. We also suggest that class-based systems need the notion of private types if they are to surmount their current limitations. Our points are made in the guise of designing a family of List data types. Among these is a new variety of lists that have never been previously published: prefix-sharing lists. We also argue that there is a need for familial classes to serve as an intermediary between users and the members of a family.


title: Row Replacement Algorithms for Screen Editors

authors:
Eugene W. Myers
Webb Miller

abstract: Interactive screen editors repeatedly determine terminal command sequences to update a screen row. Computing an optimal command sequence differs from the traditional sequence comparison problem in that there is a cost for moving the cursor over unedited characters and the cost of an n -character command is not always the cost of n one-character commands. For example, on an ANSI-standard terminal, it takes nine bytes to insert one character, ten to insert two, eleven to insert three, and so on. This paper presents an O ( MN ) dynamic programming algorithm for row replacement where an n -character command costs α n + β for constants α and β. M is the length of the original row and N is the length of its replacement. Also given is an O ( Cost × ( M + N )) “greedy” algorithm for optimal row replacement. Here Cost is the optimal cost (in bytes) of the replacement, so the algorithm is fast when the require d update is small. Though the algorithm is rather complicated, it is fast enough to be useful in practice.


title: A Generalization of Dijkstra's Calculus

abstract: Dijsktra's calculus of guarded commands can be generalized and simplified by dropping the law of the excluded miracle. This paper gives a self-contained account of the generalized calculus from first principles through the semantics of recursion. The treatment of recursion uses the fixpoint method from denotational semantics. The paper relies only on the algebraic properties of predicates; individual states are not mentioned (except for motivation). To achieve this, we apply the correspondence between programs and predicates that underlies predicative programming. The paper is written from the axiomatic semantic point of view, but its contents can be described from the denotational semantic point of view roughly as follows: The Plotkin-Apt correspondence between wp semantics and the Smyth powerdomain is extended to a correspondence between the full wp/wlp semantics and the Plotkin powerdomain extended with the empty set.


title: A Denotational Semantics for Prolog

authors:
Tim Nicholson
Norman Y. Foo

abstract: A denotational semantics is presented for the language Pro.og. Metapredicates are not considered. Conventional control sequencing is assumed for Prolog's execution. The semantics is nonstandard, and goal continuations are used to explicate the sequencing.


title: On the Productivity of Recursive List Definitions

abstract: Several related notions of the productivity are presented for functional languages with lazy evaluation. The notion of productivity captures the idea of computability, of progress of infinite-list programs. If an infinite-list program is productive , then every element of the list can be computed in finite “time.” These notions are used to study recursive list definitions, that is, lists defined by l where l = fl . Sufficient conditions are given in terms of the function f that either guarantee the productivity of the list or its unproductivity. Furthermore, a calculus is developed that can be used in verifying that lists defined by l where l = f I are productive. The power and the usefulness of our theory are demonstrated by several nontrivial examples. Several observations are given in conclusion.


title: Some Comments on ''A Solution to a Problem with Morel and Renvoise's 'Global Optimization by Suppression of Partial Redundancies'

abstract: Abstract: Drechsler and Stadel presented a solution to a problem with Morel and Renvoise's “Global Optimization by Suppression of Partial Redundancies.” We cite some earlier generalizations of Morel and Renvoise's algorithm that solve the same problem, and we comment on their applicability.


title: A Simple Interprocedural Register Allocation Algorithm and Its Effectiveness for Lisp

authors:
Peter Steenkiste
John L. Hennessy

abstract: Register allocation is an important optimization in many compilers, but with per-procedure register allocation, it is often not possible to make good use of a large register set. Procedure calls limit the improvement from global register allocation, since they force variables allocated to registers to be saved and restored. This limitation is more pronounced in LISP programs due to the higher frequency of procedure calls. An interprocedural register allocation algorithm is developed by simplifying a version of interprocedural graph coloring. The simplification corresponds to a bottom-up coloring of the interference graph. The scheme is evaluated using a number of LISP programs. The evaluation considers the scheme's limitations and compares these “software register windows” against the hardware register windows used in the Berkeley RISC and SPUR processors.


title: Type Representation of Objects by Functions

abstract: A systematic representation of objects grouped into types by constructions similar to the composition of sets in mathematics is proposed. The representation is by lambda expressions, which supports the representation of objects from function spaces. The representation is related to a rather conventional language of type descriptions in a way that is believed to be new. Ordinary control-expressions (i.e.,case- and let-expressions) are derived from the proposed representation.


title: Local Atomicity Properties: Modular Concurrency Control for Abstract Data Types

abstract: Atomic actions (or transactions) are useful for coping with concurrency and failures. One way of ensuring atomicity of actions is to implement applications in terms ofatomic data types: abstract data types whose objects ensure serializability and recoverability of actions using them. Many atomic types can be implemented to provide high levels of concurrency by taking advantage of algebraic properties of the type's operations, for example, that certain operations commute. In this paper we analyze the level of concurrency permitted by an atomic type. We introduce several local constraints on individual objects that suffice to ensure global atomicity of actions; we call these constraintslocal atomicity properties. We present three local atomicity properties, each of which isoptimal: no strictly weaker local constraint on objects suffices to ensure global atomicity for actions. Thus, the local atomicity properties define precise limits on the amount of concurrency that can be permitted by an atomic type.