SOS 2007 Preliminary Proceedings of the 4th Workshop on Structural Operational Semantics Wrocław, Poland, 9th July 2007
Editors: Rob van Glabbeek and Matthew Hennessy Contents
Preface ...... 1
Pawe lSobocinski´ (Invited Speaker) A well-behaved LTS for the Pi-calculus (abstract) ...... 3
Traian Serbanuta, Grigore Rosu & Jose Meseguer A Rewriting Logic Approach to Operational Semantics (extended abstract) 10
Patrick Cousot & Radhia Cousot Bi-inductive Structural Semantics ...... 25
David Frutos Escrig & Carlos Gregorio Rodrguez Simulations up-to and Canonical Preorders (extended abstract) ...... 40
Harald Fecher & Heiko Schmidt Process Algebra Having Inherent Choice: Revised Semantics for Concurrent Systems ...... 55
Astrid Kiehn An operational semantics for shared messaging communication ...... 70
Iain Phillips & Irek Ulidowski Reversibility and models for concurrency ...... 85
MohammadReza Mousavi & Michel Reniers A Congruence Rule Format with Universal Quantification ...... 100
Jesper Bengtson & Joachim Parrow A completeness proof for bisimulation in the pi-calculus using Isabelle . . . . 115
Front cover design: Anna Tito SOS 2007 Preliminary Version
Preface
This volume contains the preliminary proceedings of SOS 2007, the Fourth Work- shop on Structural Operational Semantics, held on the 9th of July 2007 in Wroc law, Poland, as a affiliated workshop of LICS 2007, the Twenty-Second Annual IEEE Symposium on Logic in Computer Science, and ICALP 2007, the 34th International Colloquium on Automata, Languages and Programming. Structural operational semantics (SOS) provides a framework for giving opera- tional semantics to programming and specification languages. A growing number of programming languages from commercial and academic spheres have been given us- able semantic descriptions by means of structural operational semantics. Because of its intuitive appeal and flexibility, structural operational semantics has found consid- erable application in the study of the semantics of concurrent processes. Moreover, it is becoming a viable alternative to denotational semantics in the static analysis of programs, and in proving compiler correctness. Recently, structural operational semantics has been successfully applied as a formal tool to establish results that hold for classes of process description languages. This has allowed for the generalisation of well-known results in the field of process algebra, and for the development of a meta-theory for process calculi based on the realization that many of the results in this field only depend upon general semantic properties of language constructs. The SOS workshop series aims at being a forum for researchers, students and practitioners interested in new developments, and directions for future investigation, in the field of structural operational semantics. One of the specific goals of the series is to establish synergies between the concurrency and programming language communities working on the theory and practice of SOS. It also aims at widening the knowledge of SOS among postgraduate students and young researchers worldwide. The first SOS workshop took place on the 30th of August 2004 in London (UK) as a satellite event of CONCUR 2004, the Fifteenth International Conference on Concurrency Theory, and marked the publication of two special volumes (60–61) of the Journal of Logic and Algebraic Programming devoted to SOS; the proceedings appeared as ENTCS volume 128, issue 1. The second SOS workshop took place on the 10th of July 2005 in Lisbon (Portugal) as a satellite event of ICALP 2005, the The 32nd International Colloquium on Automata, Languages and Programming; its proceedings appeared as ENTCS volume 156, issue 1, and a special issue of The- This is a preliminary version. The final version will be published in Electronic Notes in Theoretical Computer Science oretical Computer Science based on selected papers appeared in 2007. The third SOS Workshop occurred on the 26th of August 2006 in Bonn as a satellite workshop of CONCUR 2006, the Seventeenth International Conference on Concurrency The- ory, and its proceedings appeared as ENTCS volume 175, issue 1. A special issue of Information and Computation on Structural Operational Semantics inspired by SOS 2006 is in preparation.
Programme committee:
• Luca Aceto (Aalborg, DK; Reykjav´ık, IS)
• Rocco De Nicola (Florence, IT)
• Rob van Glabbeek (NICTA, AU, co-chair)
• Reiko Heckel (Leicester, UK)
• Matthew Hennessy (Sussex, UK, co-chair)
• Bartek Klin (Warsaw, PL)
• Ugo Montanari (Pisa, IT)
• MohammadReza Mousavi (Eindhoven, NL)
• Prakash Panangaden (Montreal, CA)
• Grigore Rosu (Urbana-Champaign IL, USA)
• Simone Tini (Insubria, I)
• Shoji Yuen (Nagoya, JP) The submitted papers were carefully refereed by the programme committee and by several outside referees, whose help is gratefully acknowledged.
Invited speaker: Pawel Sobocinski (Southampton, UK) will address SOS 2007 on A well-behaved LTS for the Pi-calculus.
Publication: The final versions of the papers in these preliminary proceedings will be published in ENTCS, Electronic Notes in Theoretical Computer Science. ENTCS is published electronically through the facilities of Elsevier Science B.V. and under its auspices. We are grateful to ENTCS for their continuing support, and in particular to Mike Mislove, Managing Editor of the series.
Organisation: We are grateful to Marcin Bie´nkowski for taking care of the local organisation, and for mediating in the printing of these preliminary proceedings. Support from National ICT Australia and the University of Sussex is also gratefully acknowledged.
Rob van Glabbeek (National ICT Australia) Matthew Hennessy (University of Sussex)
2 SOS 2007 Preliminary Version
A well-behaved LTS for the Pi-calculus (Abstract)
Pawe lSoboci´nski1
ecs, University of Southampton, UK
The Pi-calculus [2,10] is one of the most well-known and widely-studied process calculi – roughly, it extends the binary synchronisations along a channel/name, familiar from ccs, with the ability to pass names as arguments. Thus, the input prefix becomes a binder and the synchronisation itself results in a substitution of the communicated name for the bound variable. The Pi-calculus inherits another binder from ccs – the restriction operator. The ability to pass names as part of a synchronous communication means that it behaves rather differently in this setting - in particular, the scope of a restriction, static in ccs, becomes dynamic essentially because restricted names can be communicated along public channels. Additionally, it behaves somewhat like a global generator of new-names - since α-conversion ensures that whichever concrete name is chosen for a restricted name, it is different from all other names in the term – in fact, the global nature of new names is also enforced in the definition of bisimulation as we shall recall below. See also [12]. The (reduction) semantics of the Pi-calculus is very similar to that of css, in fact, in the sum-free fragment we can express it essentially as the axiom
a!b.P k a?x.Q → P k Q[b/x] (1) closed under evaluation contexts: parallel composition and restriction – reduction is not allowed under prefix. The reduction semantics naturally leads to a contextually defined equivalence: the barbed congruence. While canonical, contextually defined equivalences are difficult to reason about directly and for this reason it is helpful to define another “semantics”: the so-called early labelled transition system (lts). The labels of the transition system aim at classifying the possible interactions with the environment. Early congruence coincides with barbed congruence, but the lts
1 Research partially supported by EPSRC grant EP/D066565/1. This is a preliminary version. The final version will be published in Electronic Notes in Theoretical Computer Science P. Sobocinski´ is much easier to use because of the power of coinduction.
a!b a?b (In) (Out) P −−→ P ′ Q −−→ Q′ a?b a!b (Comm) a?xP −−→ P [b/x] a!bP −−→ P τ P kQ −→ P ′kQ′
a!b a!(b) P P a6=b a?b −−→ ′ P −−−→ P ′ Q −−→ Q′ b/∈fn(Q) (Open) (Close) a!(b) τ P kQ −→ νb(P ′kQ′) νbP −−−→P ′ α α P −→ P ′ bn(α)∩fn(Q)=∅ P −→ P ′ b/∈n(α) (Par) α α (Res) P kQ −→ P ′kQ νbP −→ νbP ′
The so-called early lts, presented above for the finite, sum-free fragment without match or mismatch, is widely known and can be presented and used by humans in a fairly simple way provided that a number of conventions is followed – we shall discuss these in more detail below. In order to save space we omitted the symmetric versions of (Comm), (Close) and (Par); one normally works with an abstract syntax in which k is associative and commutative – such an equivalence relation on syntax is usually referred to as structural congruence. It is worth mentioning that rules (Open) and (Close) perform two roles: scope extrusion and generation of new name observable (the bound output label a!(b)). The side-conditions on the derivation rules deserve some further consideration. The requirements on (Res) and (Open) are fairly obvious and inherited from ccs – they ensure that ν behaves like ccs restriction in that one cannot communicate on a restricted channel from outside its scope. The conditions required of (Close) and (Par) merit more attention – in particular they make sure that the (Open)/(Close) mechanism for scope extrusion functions correctly. Indeed, consider the process P = (νb a!b) k b?x where the scope of the restriction encompasses only the left component. If the side-condition on (LPar) was lifted one a!(b) would be able to derive the label P −−−→ b?x. But, using (Close), one would then τ be able to derive P k a?y −→ νb b?x with the result that the freely occurring b in right component of P would have become incorrectly bound after the interaction. The side condition on (Close) exists for similar reasons. Even with the side-conditions, the definition of bisimulation has to be altered. In a!(b) particular, in the bisimulation game played on (P,Q), if P challenges with P −−−→ P ′ then Q must respond if and only if b∈ / fn(Q). Technically this is due to the side condition in the (Par) rule: consider the processes
νb a!b and (νb a!b) k νcc!b which are clearly equivalent; the second component of the second process has no observable behaviour – but clearly the first process can perform a a!(b) action while the second cannot. Intuitively, this phenomenon demonstrates ν’s global behaviour as a fresh name generator – whichever name is present in the system, the fresh name observed (witnessed by the bound output label) will be different. Sangiorgi and Walker [11, Convention 1.4.10] argue that all such problems can be solved by making sure that “... the bound names of any process or actions under 4 P. Sobocinski´ consideration are chosen to be different from the names free in any other entities under consideration ...”. This is certainly true, but the convention is arguably a strong one and, conventions aside, the definition of bisimulation has been tampered with. It has also been noticed by a number of authors that conventions which are fine for humans are non-trivial to implement when using proof-assistants or theorem-provers. There have been several works [1, 6, 4] which aim at formalising these conventions, roughly the idea is to index the processes with the set of names which can appear within and consider bisimulation as a name-indexed relation. See [5] for an overview and a comparison of the approaches. As outlined above, the lts can be considered as a tool for reasoning about a contextually defined equivalence on the reduction semantics; following this line of reasoning raises a natural question as to whether the lts can be derived in some systematic way from the reduction semantics; research in this direction was com- menced by Leifer and Milner [8] and continued by Klin, Sassone and the author [7]. In Leifer and Milner’s work, the labels of the resulting transition system are cer- c[−] tain contexts c[−] of the language. Roughly, for a closed term t, t −−→ t′ when c[−] allows t to reduce to t′ in one step, ie c[t] → t′ and c[−] is the minimal such context, in other words it doesn’t contain any redundant information in order for the reduction to occur. The minimality condition is expressed categorically; if the underlying category of terms and contexts satisfies certain assumptions then bisim- ilarity (defined in the usual way) on the lts is a congruence. One of the limitations of the framework is that the underlying reduction system is required to consist of ground rules, which practically rules out calculi such as ccs and Pi because the reduction rules contain parameters – eg P and Q in (1). A generalisation of the theory which aims at overcoming this problem was studied in [7] – reduction rules are open terms, and given another open term, one can compute both a minimal context and a minimal parameter which allows reduction. While work in progress, in a ccs-like setting a possible label would be of the form
−1ka?x−2 ha!bP,−1i −−−−−−→ P k−1 where the context forms an (unsubstantiated) part of the term and the labels are able to modify the context. Another feature is that the information in the labels is restricted by what can be observed in one reduction step – this rules out Pi labels which also contain the name being transmitted. We can use some of the intuitions gained from the work described in the para- graph above to develop a new lts for the Pi-calculus. To do this we expand the calculus with a typed meta-syntax for holes and contexts, the idea is that such con- texts can form a part of a term after interaction. The meta-syntax is a simply-typed lambda calculus, with β-reduction forming a part of the structural congruence. We start with an untyped syntax on which we give type rules, starting with two base types; a name type N and a process type P. Types in this setting are included only to make the meta-syntax formal, they certainly have less structure than usual Pi-calculus type systems based on channel types. Differently from the classical presentation, we treat ν as a standard binder which binds variables of name 5 P. Sobocinski´ type. We assume a countable supply of variables of each type. In all these choices, our presentation more similar to Engberg and Nielsen’s eccs [2,3], the “precursor” to the Pi-calculus. Actually, all the basic ingredients of the theory (scope extrusion, fresh name generation) were already present in the aforementioned work; the main novelty of the Pi-calculus was the collapse of the syntactic classes of variables and names. It can be argued that the resulting simplicity is deceptive. We use the syntactic convention of a, b for name constants, k, l for terms of name type, x,y for variables (including name variables), P,Q for terms of process type, X,Y for variables of function type. Type contexts are finite maps from variables to types. We shall consider only typed terms.
Types
σ ::= N | P | σ → σ
Syntax
M ::= x | a | 0 | M k M | M!MM | M?xM | νxM | λx : σ.M | M(M)
Type rules
(:Name) (:Zero) Γ⊢a:N Γ⊢0:P Γ⊢M:P Γ⊢M ′:P Γ⊢M:P Γ⊢k:N Γ⊢l:N (:Par) (:OutPref) Γ⊢MkM ′:P Γ⊢k!l.M:P Γ,x:N ⊢M:P Γ,x:N ⊢M:P Γ⊢k:N (:Nu) (:InPref) Γ⊢νxM:P Γ⊢k?x.M:P
Γ(x)=σ Γ,x:σ⊢M:σ′ Γ⊢M1:σ→σ′ Γ⊢M2:σ (:Var) (:λ) (:App) Γ⊢x:σ Γ⊢λx:σ.M:σ→σ′ Γ⊢M1(M2):σ′
We give a brief outline of the part of the lts concerned with communication and scope extrusion below. The lts is defined structurally. Because we operate in a typed setting, the states of the lts are pairs of typed context and term. We denote such pairs syntactically as hΓ | V i where Γ is a type context and V is a term. The interplay between the type context and the term is explained by a type preservation result, described following an intuitive account of the transitions. The labels in the fragment are the usual ccs labels. The intuitive idea is that a process offering an output on a channel k can perform the interaction with a context, and evolve into a process consisting of its continuation in parallel with the interacting context, which has been passed the communicated name. This context is explicitly described in the resulting state as a lambda abstraction which binds a variable of type I = N → P (cf (Out)). On the other hand, a process offering an input on a channel k can perform the communication with the context and obtain some name – the result is a lambda abstraction which binds a variable of type N (cf (In)). A process with a capability to input on k in parallel composition 6 P. Sobocinski´ with a process which has a capability to output on the said channel can perform the synchronisation without the need for an external context – the abstractions are combined via an application (cf (Tau)). There is a technical similarity to the presentation of the late semantics using abstractions and concretions [9]; see the (Comm) rule below. Notice, however, that we do not say anything about the actual nature of the name transmitted in the labels.
LTS - Communication fragment
(In) (Out) k? k! hΓ | k?xP i −→ hΓ | λx:N .P i hΓ | k!lP i −→ hΓ | λX:I .P kX(l)i k? k! hΓ | P i −→ hΓ | Ui hΓ | P i −→ hΓ | T i (kIn) (kOut) k? k! hΓ | P kQi −→ hΓ | λx:N .U(x)kQi hΓ | P kQi −→ hΓ | λX:I .T (X)kQi k? k! hΓ,y:N | P i −→ hΓ,y:N | Ui (k6=y) hΓ,y:N | P i −→ hΓ,y:N | T i (k6=y) (νIn) (νOut) k? k! hΓ | νyP i −→ hΓ | λx:N .νyU(x)i hΓ | νyP i −→ hΓ | λX:I .νyT (X)i k! k? hΓ | P i −→ hΓ | T i hΓ | Qi −→ hΓ | Ui τ (Tau) hΓ | P kQi −→ hΓ | T (U)i τ τ hΓ | P i −→ hΓ | P ′i hΓ,y:N | P i −→ hΓ,y:N | P ′i τ (kTau) τ (νTau) hΓ | P kQi −→ hΓ | P ′kQi hΓ | νyP i −→ hΓ | νyP ′i
In the rules (kIn) and (νIn), the variable x in the right hand side of the result is chosen fresh for U. Similarly, in (kOut) and (νOut) the variable X is chosen fresh for T . The lts has a regular structure – there is one axiom for each kind of label - (In), (Out) and (Tau) for input, output and τ respectively. Further, there is precisely one rule for each syntactic constructor and each kind of label. We give a brief example in order to demonstrate how scope-extrusion is handled by the above rules. First observe that we can derive the following transition:
(Out) a! hx:N | a!x.P i −→ hx:N | λX:I .P kX(x)i (νOut) a! I I h∅ | νxa!x.P i −→ h∅ | λX: .νx(λX′: .P kX′(x))Xi but λX : I .νx(λX′ : I .P k X′(x))X ≡ λX : I .νx(P k X(x)), and so, using (Tau) we obtain the correct extrusion of scope:
(In) a? a! h∅ | a?y.Qi −→ h∅ | λy.Qi h∅ | νxa!x.P i −→ h∅ | λX:I .νx(P kX(x))i τ (Tau) h∅ | a?y.Qkνx.a!x.P i −→ h∅ | νx.(P k(λy.Q)(x))i since νx.(P k (λy.Q)(x)) ≡ νx(P k Q[x/y]). One can prove a type preservation result about the lts – in particular demon- strating that the result of applying the (Tau) rule is typeable. Indeed, suppose that Γ ⊢ P : P. Then the following hold: 7 P. Sobocinski´
k? • if hΓ | P i −→ hΓ | Ui then Γ ⊢ U : N → P; k! • if hΓ | P i −→ hΓ | T i then Γ ⊢ T : I → P; τ ′ • if hΓ | P i −→ hΓ | P ′i then Γ ⊢ P : P.
The lts presented above is only a fragment and bisimilarity does not give a satisfactory equivalence; it is presented here only to give a basic idea of the tech- niques involved. In particular, there is no observation of the identity of the name communicated (input, output, or fresh output). The full lts contains extra labels and derivation rules which take care of such observables by suitably evaluating λ- abstracted terms, yielding the standard early equivalence. The two functions (scope extrusion and fresh name generation) of the ν operator are thus dealt with sepa- rately. Intuitively, transitions which arise out of process terms, as presented here, represent the part of the interaction which is controlled by the process; transitions out of lambda-abstracted terms, omitted in this presentation, represent the part con- trolled by the context. The full lts does not require complicated side-conditions, variable conventions and the resulting equivalence is obtained using ordinary bisim- ulation indexed by type contexts. The reader will notice that in fact the lts resembles closely that for ccs – in particular one could give a complete lts for that calculus in a similar style (without passing the name to the context in the result of (Out) and without awaiting a name in the result of (In)). This demonstrates one feature and a design principle associated with the lts – modularity. The idea is that the semantics for different features of a calculus should be given by standard lts modules which fit together in a largely orthogonal way: the Pi-calculus extends ccs with extra features and thus it shouldn’t be surprising that the synchronous communication feature of Pi is handled with a ccs-like subsystem. Contrast this situation with the standard lts in which communication is more complicated - there are two different kinds of output labels (free and bound) and two different axioms for τ. While presentations such as [1] reduce this difference, it may prove that the technique advocated in this paper generalises well to other calculi – eg higher order Pi-calculus or the ambient calculus.
References
[1] G. L. Cattani and P. Sewell. Models for name-passing processes: interleaving and causal. Information and Computation, 190:136–178, 2004. [2] U. Engberg and M. Nielsen. A calculus of communicating systems with label passing. Technical Report DAIMI PB-208, University of Aarhus, May 1986. [3] U. Engberg and M. Nielsen. A calculus of communicating systems with label passing - ten years after. In Proof, Language, and Interaction; Essays in Honour of Robin Milner, pages 599–622. MIT Press, 2000. [4] G. U. Ferrari, U. Montanari, and M. Pistore. Minimising transition systems for name passing calculi: a co-algebraic formulation. In FoSSaCS ’02, pages 129–158, 2002. [5] M. P. Fiore and S. Staton. Comparing operational models of name-passing process calculi. Information and Computation, 204(4):435–678, 2006.
[6] M. P. Fiore and D. Turi. Semantics of name and value passing. In LiCS ’01, pages 93–104, 2001.
[7] B. Klin, V. Sassone, and P. Soboci´nski. Labels from reductions: towards a general theory. In Algebra and Coalgebra in Computer Science, Calco ’05, volume 3629 of LNCS, pages 30–50. Springer, 2005. 8 P. Sobocinski´
[8] J. Leifer and R. Milner. Deriving bisimulation congruences for reactive systems. In International Conference on Concurrency Theory Concur ’00, volume 1877 of LNCS, pages 243–258. Springer, 2000.
[9] R. Milner. Communicating and Mobile Systems: the Pi-calculus. Cambridge University Press, 1999.
[10] R. Milner, J. Parrow, and D. Walker. A calculus of mobile processes, ii. Information and Computation, 100(1):41–77, 1992.
[11] D. Sangiorgi and D. Walker. The π-calculus: a Theory of Mobile Processes. Cambridge University Press, 2001.
[12] L. Wischik. Old names for Nu. In Dagstuhl Seminar 04241, 2004.
9 SOS 2007 Preliminary Version
A Rewriting Logic Approach to Operational Semantics – Extended Abstract
Traian Florin S¸erb˘anut¸˘a, Grigore Ro¸su, Jos´eMeseguer
Department of Computer Science, University of Illinois at Urbana-Champaign. {tserban2,grosu,meseguer}@cs.uiuc.edu
Abstract This paper shows how rewriting logic semantics (RLS) can be used as a computational logic framework for operational semantic definitions of programming languages. Several operational semantics styles are ad- dressed: big-step and small-step structural operational semantics (SOS), modular SOS, reduction semantics with evaluation contexts, and continuation-based semantics. Each of these language definitional styles can be faithfully captured as an RLS theory, in the sense that there is a one-to-one correspondence between computational steps in the original language definition and computational steps in the corresponding RLS theory. A major goal of this paper is to show that RLS does not force or pre-impose any given language definitional style, and that its flexibility and ease of use makes RLS an appealing framework for exploring new definitional styles.
1 Introduction
This paper is part of the rewriting logic semantics (RLS) project (see [25,26] and the references there). The broad goal of the project is to develop a tool-supported computational logic framework for modular programming language design, seman- tics, formal analysis and implementation, based on rewriting logic [22]. Any logical framework worth its salt should be evaluated in terms of its expressiveness and flexibility. Therefore, a very pertinent question is: how does RLS express other approaches to operational semantics? In particular, how well can it express various approaches in the SOS tradition? The goal of this paper is to answer these ques- tions. Partial answers, giving detailed comparisons with specific approaches have appeared elsewhere. For example, [21] and [43] provide comparisons with standard SOS [34]; and [23] compares RLS with both standard SOS and Mosses’ modular structural operational semantics (MSOS) [31]. However, no comprehensive compar- ison encompassing most approaches in the SOS tradition has been given to date. To make our ideas more concrete, in this paper we use a simple programming lan- guage, show how it is expressed in each different definitional style, and how that
1 Supported in part by NSF grants CCF-0234524, CCF-0448501, CNS-0509321, and CNS-05-24516; and by ONR Grant N00014-02-1-0715. This is a preliminary version. The final version will be published in Electronic Notes in Theoretical Computer Science S¸erbanut¸˘ a,˘ Ros¸u, Meseguer style is captured as a rewrite theory in the RLS framework. We furthermore give correctness theorems showing the faithfulness of the RLS representation for each style. Even though we exemplify the ideas with a simple language for concreteness’ sake, the process of representing each definitional style in RLS is completely gen- eral and automatable, and in some cases like MSOS has already been automated [6]. The range of styles covered includes: big-step (or natural) SOS semantics; small- step SOS semantics; MSOS semantics; context-sensitive reduction semantics; and continuation-based semantics. Any logical framework for operational semantics of programming languages has to meet strong challenges. We list below some of them and sketch how they are met in RLS; for a more thorough discussion see [38]. • Handling of SOS Definitions. As illustrated in Sections 4, 5, and 6, both big- step and small-step SOS, and also MSOS definitions can be expressed as rewrite theories in RLS; see also [21,43,23]. • Handling of context-sensitive reduction. In Section 7 we sketch a general method to express in RLS semantic definitions based on evaluation contexts (e.g., [47]). • Handling higher-order syntax. Higher-order syntax admits first-order representa- tions, e.g., [1,2,40]. Using CINNI [40], all this can be done keeping essentially the original higher-order syntax. • Handling continuations. Continuations [12,35] are traditionally understood as higher-order functions. In Section 8 we present an alternative view of continua- tions that is intrinsically first-order. • Handling concurrency. One of the strongest points of rewriting logic is precisely that it is a logical framework for concurrency. Unlike standard SOS, which forces an interleaving semantics, true concurrency is directly supported. • Expressiveness and flexibility. RLS does not force on the user any particular definitional style. This is illustrated in this paper by showing how quite different definitional styles can all be faithfully and naturally captured in RLS. • Mathematical and operational semantics. Rewriting logic has both a compu- tational proof theory and an initial model semantics, which provides inductive reasoning principles to prove properties. Therefore RLS programming language definitions have both an operational rewriting semantics, and a mathematical ini- tial model semantics. • Performance Issues. High-performance systems supporting rewriting can be used to directly execute RLS semantic definitions as interpreters. In Section 9 we present encouraging experimental performance results for our example language using various systems and different definitional styles. Besides the good features mentioned above, another advantage of RLS is the availability of generic tools for: (i) syntax; (ii) execution (already mentioned); and (iii) formal analysis. For example, languages such as ASF+SDF [41] and Maude [7] support user-definable syntax. There is a wealth of theorem proving and model checking tools for rewriting/equational-based specifications, which can be used di- rectly to prove properties about language definitions. The fact that these formal analysis tools are generic, should not fool one into thinking that they must be in-
11 S¸erbanut¸˘ a,˘ Ros¸u, Meseguer efficient. For example, the LTL model checkers obtained for free in Maude from the RLS definitions of Java and the JVM compare favorably in performance with state-of-the-art Java model checkers [11]. Another advantage of RLS is what we call the “abstraction dial,” which can be used to reach a good balance between abstraction and computational observability in semantic definitions. The point is which computational granularity is appropriate. A small-step semantics opts for very fine-grained computations. But this is not nec- essarily the only or the best option for all purposes. The fact that an RLS theory’s axioms include both equations and rewrite rules provides the useful “abstraction dial,” because rewriting takes place modulo the equations. That is, computations performed by equations are abstracted out and become invisible. This has many advantages, as explained in [25]. For example, in Sections 4 and 5, we use equations to define the semantic infrastructure (stores, etc.) of SOS definitions; in Section 7 equations are also used to hide the extraction and application of evaluation contexts, which are “meta-level” operations, carrying no computational meaning; in Section 8, equations are also used to decompose the evaluation tasks into their correspond- ing subtasks; finally, in Section 6, equations of associativity and commutativity are used to achievemodularity of language definitions. 2 Rewriting Logic
Rewriting logic [22] is a computational logic that can be efficiently implemented and that has good properties as a general and flexible logical and semantic framework, in which a wide range of logics and models of computation can be faithfully repre- sented [21]. In particular, for programming language semantics it provides the RLS framework, of which we here only emphasize the operational semantics aspects. Two key points are: (i) how rewriting logic combines equational logic and term rewriting; and (ii) what the intuitive meaning of a rewrite theory is. A rewrite theory is a triple R = (Σ,E,R) with Σ a signature, E a set of (conditional) Σ-equations, and R a set of Σ-rewrite rules, with conditions involving both equations and rewrites. ′ ′ That is, a rule in R can have the general form (∀X) t −→ t if (Vi ui = ui) ∧ ′ (Vj wj −→ wj). Alternatively, such a rule could be displayed with an inference- ′ ′ (V ui = u ) ∧ (V wj −→ w ) rule-like notation as i i j j . t −→ t′ Therefore, the logic’s atomic sentences are equations and rewrite rules. Equa- tional theories and traditional term rewriting systems then appear as special cases. An equational theory (Σ, E) can be represented as the rewrite theory (Σ, E, ∅); and a rewriting system (Σ, R) can be represented as the rewrite theory (Σ, ∅, R). Of course, if the equations of an equational theory (Σ, E) are confluent, there is −→ −→ another useful representation, namely, as the rewrite theory (Σ, ∅, E ), where E are the rewrite rules obtained by orienting the equations E as rules. This representation is at the basis of much work in term rewriting, but by implicitly suggesting that rewrite rules are just an efficient technique for equational reasoning it can blind us to the fact that rewrite rules can have a more general non-equational semantics. This is the raison d’ˆetre of rewriting logic. In rewriting logic a theory R = (Σ,E,R) ax- iomatizes a concurrent system, whose states are elements of the algebraic data type (Σ, E), that is, E-equivalence classes of ground Σ-terms, and whose atomic transi- 12 S¸erbanut¸˘ a,˘ Ros¸u, Meseguer tions are specified by the rules R. The inference system of rewriting logic allows us to derive as proofs all the concurrent computations of the system axiomatized by R: concurrent computation and rewriting logic deduction coincide. There are many systems that either specifically implement term rewriting effi- ciently, so-called as rewrite engines, or support term rewriting as part of a more complex functionality. Any of these systems can be used as an underlying platform for execution and analysis of programming languages defined using the techniques proposed in this paper. Without attempting to be exhaustive, we here only men- tion (alphabetically) some engines that we are more familiar with, noting that many functional languages and theorem provers provide support for term rewriting as well: ASF+SDF [41], CafeOBJ [10], Elan [4], Maude [7], OBJ [16], and Stratego [44]. Some of these engines can achieve remarkable speeds on today’s machines, in the order of tens of millions of rewrite steps per second.
3 A Simple Imperative Language
To illustrate the various operational semantics, we have chosen a small imperative language having arithmetic and boolean expressions with side effects (increment expression), short-circuited boolean operations, assignment, conditional, while loop, sequential composition, blocks and halt. Here is its syntax: AExp ::= Var|# Int|AExp + AExp|AExp - AExp|AExp * AExp|AExp / AExp| ++ Var BExp ::= # Bool|AExp <= AExp|AExp >= AExp|AExp == AExp|BExp and BExp| not BExp Stmt ::= skip |Var := AExp|Stmt ; Stmt| if BExp then Stmt else Stmt| while BExp Stmt Pgm ::= Stmt . AExp The result of running a program is the evaluation of AExp in the state after executing Stmt. This BNF syntax is entirely equivalent to an algebraic order-sorted signature having one (mixfix) operation definition per production, terminals giving the name of the operation and non-terminals the arity. For example, the production for if- then-else can be seen as an algebraic operation if then else : BExp × Stmt × Stmt → Stmt. We will use the following conventions for variables throughout the remaining of the paper: X ∈ Var, A ∈ AExp, B ∈ BExp, St ∈ Stmt, P ∈ Pgm, I ∈ Int, T ∈ Bool = {true, false}, S ∈ Store, any of them primed or indexed. The next sections will use this simple language and will present definitions in various operational semantics styles (big step, small step SOS, MSOS, reduction using evaluation contexts, and continuation-based), as well as the corresponding RLS representation of each definition. We will also characterize the relation between the RLS representations and their corresponding definitional style counterparts, pointing out some strengths and weaknesses for each style. The reader is referred to [19,34,31,47] for details on the described operational semantics styles. We assume equational definitions for basic operations on booleans and integers, and assume that any other theory defined from here on includes them. One of the reasons why we wrapped booleans and integers in the syntax (using “#”) is precisely to distinguish them from the corresponding values, and thus to prevent the “builtin” equations from reducing expressions like 3 + 5 directly in the syntax. We wish to have full control over the computational granularity of the language, since we aim for the same computational granularity of each different style. Unlike in various operational semantics, which usually abstract stores as func- 13 S¸erbanut¸˘ a,˘ Ros¸u, Meseguer tions, in rewriting logic we explicitly define the store as an abstract datatype: a store is a set of bindings from variables to values, together with two operations on them, one for retrieving a value, another for setting a value. Well-formed stores correspond to partially defined functions. Having this abstraction in place, we can regard them as functions for all practical purposes from now on. We let s ≃ σ denote that well-formed state s corresponds to partial function σ.
4 Big-Step Operational Semantics
Introduced as natural semantics in [19], also named relational semantics in [28], or evaluation semantics, big-step semantics is “the most denotational” of the op- erational semantics. One can view big-step definitions as definitions of functions interpreting each language construct in an appropriate domain. Big step semantics can be easily represented within rewriting logic. For example, consider the big-step rule defining the while loop: ′ ′ hB, σi ⇓ hfalse, σ i hB, σi ⇓ htrue, σ1i, hSt, σ1i ⇓ hσ2i, hwhile B St, σ2i ⇓ hσ i hwhile B St, σi ⇓ hσ′i hwhile B St, σi ⇓ hσ′i This rule can be automatically translated into the rewrite rules: hwhile B St,Si → hS′i if hB,Si → hfalse,S′i ′ ′ hwhile B St,Si → hS i if hB,Si → htrue,S1i ∧ hSt,S1i → hS2i ∧ hwhile B St,S2i → hS i To give a rewriting logic theory for the big-step semantics, one needs to first de- fine the various configuration constructs, which are assumed by default in BigStep, as corresponding operations extending the signature. Then one can define the cor- responding rewrite theory RBigStep entirely automatically. Due to the one-to-one correspondence between big-step rules in BigStep and rewrite rules in RBigStep, it is easy to prove by induction on the length of derivations the following result: Proposition 4.1 For any p ∈ Pgm and i ∈ Int, the following are equivalent: 1 (i) BigStep ⊢ hpi ⇓ hii; and (ii) RBigStep ⊢ hpi→ hii.
The only apparent difference between BigStep and RBigStep is the different no- tational conventions they use. However, as the above result shows, there is a one- to-one correspondence also between their corresponding “computations” (or exe- cutions, or derivations). Therefore, RBigStep actually is the big-step operational semantics BigStep, not an “encoding” of it. Strengths. Big-step semantics allows straightforward recursive definition when the language is deterministic. It can be easily and efficiently interpreted in any recursive, functional or logical framework. It is useful for defining type systems. Weaknesses. Due to its monolithic, single-step evaluation, it is hard to debug or trace big-step semantic definitions. If the program is wrong, no information is given about where the failure occurred. It may be hard or impossible to model concurrent features. It is not modular, e.g., to add side effects to expressions, one must redefine the rules to allow expressions to evaluate to pairs (value-store). It is inconvenient (and non-modular) to define complex control statements; consider, for example, adding halt to the above definition – one needs to add a special “halting signal” configuration and rules to propagate it. 14 S¸erbanut¸˘ a,˘ Ros¸u, Meseguer
5 Small-Step Operational Semantics
Introduced by Plotkin in [34], also called transition semantics or reduction seman- tics, small-step semantics captures the notion of one computational step. One inherent technicality involved in capturing small-step operational semantics as a rewrite theory in a one-to-one notational and computational correspondence is that the rewriting relation is by definition transitive, while the small-step relation is not transitive (its transitive closure is defined a posteriori). Therefore, we need to devise a mechanism to “inhibit” rewriting logic’s transitive and uncontrolled application of rules. An elegant way to achieve this is to view a small step as a modifier of the current configuration. Specifically, we consider “·” to be a modifier on the config- uration which performs a “small-step” of computation; in other words, we assume an operation · : Config → Config. Then, a small-step semantic rule, e.g. the one for defining while, · hwhile B St, σi → hif B then (St; while B St) else skip, σi is translated, again automatically, into a rewriting logic rule, e.g.,
·hwhile B St,Si → hif B then (St; while B St) else skip,Si As for big-step semantics, the rewriting under context deduction rule for rewrit- ing logic is again inapplicable, since all rules act at the top, on configurations. However, in SmallStep it is not the case that all right hand sides are normal forms (this actually is the specificity of small-step semantics). The “·” operator intro- duced in RSmallStep prevents the unrestricted application of transitivity, and can be regarded as a token given to a configuration to allow it to change to the next step. We use transitivity at the end (rules for smallstep) to obtain the transitive closure of the small-step relation by specifically giving tokens to the configuration until it reaches a normal form. Again, there is a direct correspondence between SOS-style rules and rewriting rules, leading to the following result, which can also be proved by induction on the length of derivations:
Proposition 5.1 For any p ∈ Pgm and i ∈ Int, SmallStep ⊢ hp, ⊥i →∗ hskip.i, σi for some state σ iff RSmallStep ⊢ eval(p) → i.
Strengths. Small-step operational semantics precisely defines the notion of one computational step. It stops at errors, pointing them out. It is easy to trace and debug. It gives interleaving semantics for concurrency. Weaknesses. Each small step does the same amount of computation as a big step in finding the next redex. It does not give a “true concurrency” semantics, that is, one has to chose a certain interleaving (no two rules can be applied at the same time), mainly because reduction is forced to occur only at the top. It is still hard to deal with complex control – for example, consider adding halt to this language. One cannot simply do it as for other ordinary statements: instead, one has to add a corner case (additional rule) to each statement to propagate the halt. Moreover, by propagating the “halt signal” through all the statements and expressions, one fails to capture the intended computation granularity of halt: it should just terminate the execution in one step! 15 S¸erbanut¸˘ a,˘ Ros¸u, Meseguer
6 MSOS Semantics
MSOS [31] was introduced to deal with the non-modularity issues of SOS. The solution proposed in MSOS involves moving the non-syntactic state components to the arrow labels, plus a discipline of only selecting needed attributes from states. u A transition in MSOS is of the form P −→ P ′, where P and P ′ are program ex- pressions and u is a label describing the structure of the state both before and after the transition. If u is missing, then the state is assumed to stay unchanged. Specifi- cally, u is a record containing fields denoting the semantic components. Modularity is achieved by the record comprehension notation “. . .” which indicates that more fields could follow but that they are not of interest for this transition. Fields of a label can fall in one of the following categories: read-only, read-write and write-only. Read-only fields are only inspected by the rule, but not modified. Read-write fields come in pairs, having the same field name, except that the “write” field name is primed. They are used for transitions modifying existing state fields. Write-only fields are used to record things not analyzable during the execution of the program, such as the output or the trace. Their names are always primed and they have a free monoid semantics – everything written on then is added at the end. Since the part of the state not involved in a certain rule is hidden through the “. . .” notation, language extensions can be made modularly. Consider, e.g., adding halt to the language. What needs to be done is to add another read-write record field, say halt?, along with the possible values halted(i), to signal that the program halted with value i, and false, as the default value, along with a construct stuck to block the execution of the program. To represent MSOS in rewriting logic, we here follow the methodology in [23]. Using the fact that labels describe changes from their source state to their des- tination state, one can move the labels back into the configurations. That is, a transition P −→u P ′ is modeled as a rewrite step ·hP, uprei → hP ′, uposti, where upre and upost are records describing the state before and after the transition. Note again the use of the “·” operator to emulate small steps by restricting transitivity. State records can be specified equationally as wrapping (using a constructor “{ }”) a set of fields built from fields as constructors, using an associative and commutative concatenation operation “ , ”. Fields are built from state attributes; e.g., the store can be embedded into a field by a constructor “σ : ”. Records upre and upost are computed from u as follows. For unobservable transitions, upre = upost. Read-only fields of u are added to both upre and upost. Read-write fields of u are translated by putting the read part in upre and the (now unprimed) write part in upost. Notice that the “. . .” notation gets replaced by a generic field-set variable W . For example, the rules for assignment in MSOS style,
S A −→ A′ unobs{σ = σ0,...} {σ=σ0,σ =σ0[I/X],...} S ′ X:=A −→ X:=A′ X:=I −−−−−−−−−−−−−−−−→ skip are translated into the following rewrite rules (R, R′ stand for records and W stands for the remaining of a record):
·hX:=A, Ri → hX:=A′, R′i if ·hA, Ri → hA′, R′i
·hX:=I, {σ : S0,W }i → hskip, {σ : S0[X ← I],W }i Write-only fields i′ = v of u are translated as follows: i : L, with L a fresh new 16 S¸erbanut¸˘ a,˘ Ros¸u, Meseguer variable, is added to upre, and i : Lv is added to upost. When dealing with observable transitions, both state records meta-variables and . . . operations are represented in upre by some variables, while in upost by others. Modularity is preserved by this translation. What indeed makes MSOS defini- tions modular is the record comprehension mechanism. A similar comprehension mechanism is achieved in rewriting logic by using sets of fields and matching modulo associativity and commutativity. That is, the extensibility provided by the “. . .” record notation in MSOS is here captured by associative and commutative matching on the W variable, which allows new fields to be added. The relation between MSOS and RMSOS definitions assumes that MSOS defini- tions are in a certain normal form [23] and is made precise by the following theorem, strongly relating MSOS and modular rewriting semantics. Theorem 6.1 [23] For each normalized MSOS definition, there is a strong bisim- ulation between its transition system and the transition system associated to its translation in rewriting logic. This translation is the basis for the Maude-MSOS tool [6], which was used to define and analyze complex language definitions. Strengths. As it is a framework on top of any operational semantics, it inher- its the strengths of the semantic for which it is used; moreover, it adds to those strengths the important new feature of modularity. Weaknesses. Control is still not explicit in MSOS, making combinations of control-dependent features (e.g., call/cc) harder to specify [31, page 223]. 7 Reduction Semantics with Evaluation Contexts
Introduced in [47], also called context reduction, the evaluation contexts style im- proves over small-step definitional style in two ways: (i) it gives a more compact semantics to context-sensitive reduction, by using parsing to find the next redex rather than small-step rules; and (ii) it provides the possibility of also modifying the context in which a reduction occurs, making it much easier to deal with control- intensive features. For example, defining halt is done now using only one rule, C[halt I] → I, preserving the desired computational granularity.
C ::= [] | hC,Si I1 + I2 → (I1 +Int I2) | skip.C | C.A hP, σi[X:=I] → hP, σ[I/X]i[skip] | X:=C | I + C | C + A while B St → if B then (St; while B St) else skip E → E′ C[halt I] → hIi C[E] → C[E′] C[skip.I] → hIi
·(C[R]) → C[R′] if ·(R) → R′ ·(Cfg) → c2s(C[R]) if ·(s2c(Cfg)) → C[R]
·(I1 + I2) → (I1 + I2) Int eval(P )= reduction(hP, ∅i) ·(hP,Si[X:=I]) → hP,S[X ← I]i[skip] reduction(Cfg)= reduction(·(Cfg’)) ·(while B St) → if B then (St; while B St) else skip reduction(hIi) = I ·(C[halt I]) → hIi[[]] Table 1: CxtRed-like rules and their corresponding rewriting logic variants An important part of a context reduction semantics is the definition of evaluation contexts, which is typically done by means of a context-free grammar. A context is a program with a “hole”, the hole being a placeholder where the next computational 17 S¸erbanut¸˘ a,˘ Ros¸u, Meseguer step takes place. If C is such a context and E is some expression whose type fits into the type of the hole of C, then C[E] is the program formed by replacing the hole of C by E. The characteristic reduction step underlying context reduction is “C[E] → C[E′] when E → E′,” capturing the fact that reductions are allowed to take place only in appropriate evaluation contexts. Table 1 presents a definition of selected evaluation contexts and some context reduction semantics rules together with their representation within rewriting logic. By making the evaluation context explicit and changeable, context reduction is, in our view, a significant improvement over small-step SOS. In particular, one can now define control-intensive statements like halt modularly and at the desired level of computational granularity. Even though the definition gives one the feeling that evaluation contexts and their instantiation come “for free”, the application of the “rewrite in context” rule presented above can be expensive in practice. This is because one needs either to parse/search the entire configuration to put it in the form C[E] for some appropriate C satisfying the grammar of evaluation contexts, or to maintain enough information in some special data-structures to perform the split C[E] using only local information and updates. Direct implementations of context reduction such as PLT-Redex cannot avoid paying a significant performance penalty, as the performance numbers in Section 9 show 2 . Context reduction is trickier to faithfully capture as a rewrite theory, since rewriting logic, by its locality, always applies a rule in the context, without ac- tually having the capability of changing the given context. In order to have an algebraic representation of contexts we extend the signature by adding a constant [], representing the hole, for each syntactic category. The operation s2c, has an ef- fect similar to what one achieves by parsing in context reduction, in the sense that given a piece of syntax it yields C[R]. In our rewriting logic definition, C[R] is not a parsing convention, but rather a constructor conveniently representing the pair (context C, redex R). The operation c2s, is defined as a morphism on the syntax, but we get (from the defining equations) the guarantee that it will be applied only to “well-formed” contexts (i.e., contexts containing only one hole). The rewrite theory RCxtRed is obtained by adding the rewrite rules in Table 1 to the equations of s2c and c2s. The RCxtRed definition is a faithful representation of context reduction semantics. Also, since parsing issues are abstracted away using equations, the computational granularity is the same, yielding a one-to-one corre- spondence between the computations performed by the context reduction semantics rules and those performed by the rewriting rules. Theorem 7.1 If s ≃ σ 3 , the following hold: (i) hp,σi parses in CxtRed as hc, σi[r] iff RCxtRed ⊢ s2c(hp,si) = hc, si[r]; (ii) RCxtRed ⊢ c2s(c[r]) = c[r/[]] for any valid ′ ′ context c and appropriate redex r; (iii) CxtRed ⊢ hp,σi → hp ,σ i iff RCxtRed ⊢ 1 ′ ′ ′ ′ 1 ·(hp,si) → hp ,s i and s ≃ σ ; (iv) CxtRed ⊢ hp,σi → hii iff RCxtRed ⊢ ·(hp,si) → ∗ hii; (v) CxtRed ⊢ hp, ⊥i → hii iff RCxtRed ⊢ eval(p) → i. Strengths. Context reduction semantics distinguishes small-step rules into com- putational rules and rules needed to find the redex (the latter are transformed into
2 Refocusing [9] proposed automatically generating abstract machines for overcoming this problem. 3 We let s ≃ σ denote the fact that equationally defined state s represents the store σ. 18 S¸erbanut¸˘ a,˘ Ros¸u, Meseguer grammar rules generating the allowable contexts). This makes definitions more com- pact. It improves over small step semantics by allowing the context to be changed by execution rules. It can deal easily with control-intensive features. Weaknesses. It still only allows “interleaving semantics” for concurrency. Al- though context-sensitive rewriting might seem to be easily implementable by rewrit- ing, in fact all current implementations of context reduction work by transforming context grammar definitions into traversal functions, thus being as (in)efficient as the small-step implementations (one has to perform an amount of work linear in the size of the program for each computational step).
8 A Continuation-Based Semantics The idea of continuation-based interpreters for programming languages and their relation to abstract machines has been well studied (see, for example, [12]). In this section we propose a rewriting logic semantics based on a structure that provides a first-order representation of continuations; this is the only reason why we call this structure a “continuation”; but notice that it can just as well be regarded as a post-order representation of the abstract syntax tree of the program, so one needs no prior knowledge of continuations [12] in order to understand this section. We will show the equivalence of this theory to the context reduction semantics theory. Based on the desired order of evaluation, the program is sequentialized by trans- forming it into a list of tasks to be performed in order. This is done once and for all at the beginning, the benefit being that at any subsequent moment in time we know precisely where the next redex is: at the top of the tasks list. The top level configuration is constructed by an operator “ ” putting together the store (wrapped by a constructor store) and the continuation (wrapped by k). Also, syntax is added for the continuation items. The continuation is defined as a list of tasks, where the list constructor “ y ” is associative, having as identity a constant “nothing”. We also use lists of values and continuations, each having an associative list append constructor “ , ” with identity “.”. We use variables K and V to denote continuations and values, respectively; also, we use Kl and Vl for lists of continuations and values, respectively. We call the list of tasks a continuation because it resembles the idea of continuations as higher-order functions. However, our continuation is a pure first order flattening of the program. For example aexp(A1 + A2) = (aexp(A1), aexp(A2)) y + precisely encodes the order of evaluation: first A1, then A2, then sum the values. Also, stmt(while B St) = bexp(B) y while(bexp(B), stmt(St)) says that the loop is dependent on the value of B for its evaluation. pgm, stmt, bexp, aexp are used to flatten the program to a continuation, taking into account the order of evaluation 4 . The most important benefit of this transformation is that of gaining locality. Now one needs to specify from the context only what is needed to perform the computation. This gives the possibility of achieving “true concurrency”, since rules which do not act on the same parts of the context can be applied in parallel. We here only discuss the sequential variant of our continuation-based semantics, because our language is sequential. In
4 The effect of these functions is somehow similar to what one would obtain in a higher order world by means of CPS transformations [46] or conversions to monadic normal form [30]. 19 S¸erbanut¸˘ a,˘ Ros¸u, Meseguer
[36] we show how the same technique can be used, with no additional effort, to define concurrent languages: as expected, one continuation structure is generated for each concurrent thread or process. Then rewrite rules can apply “truly concurrently” at the tops of continuations. Table 2 presents some rewrite rules from the continuation- based definition of our language. aexp(A1 + A2) = (aexp(A1), aexp(A2)) y + k((I1,I2) y + y K) → k(I1 +Int I2 y K) stmt(X := A)= aexp(A) y write(X) k(I y write(X) y K) store(Store) → k(K) store(Store[X ← I]) stmt(while B St)= bexp(B) y while(bexp(B), stmt(St)) k(false y while(K1,K2) y K) → k(K) k(true y while(K1,K2) y K) → k(K2 y K1 y while(K1,K2) y K) stmt(halt A)= aexp(A) y halt k(I y halt y K) → k(I) pgm(St.A)= stmt(St) y aexp(A) hP i = result(k(pgm(P )) store(empty)) result(k(I) store(Store)) = I using the (equationally defined) mechanism for evaluating lists of expressions: k((V l,Ke,Kel) y K)= k(Ke y (V l, nothing,Kel) y K) Note. Because in rewriting engines equations are also executed by rewriting, one would need to split the rule for evaluating expressions into two rules: k((V l,Ke,Kel) y K)= k(Ke y (V l, nothing,Kel) y K) k(V y (V l, nothing,Kel) y K)= k((V l,V,Kel) y K)
Table 2: Rewriting logic theory RK (continuation-based definition of the language) There exists a close connection between definitions of languages using reduction semantics with evaluation contexts and the style promoted in this section: ′ ′ Theorem 8.1 Suppose s ≃ σ. Then: (i) If CxtRed ⊢ hp,σi → hp ,σ i then RK ⊢ k(pgm(p)) store(s) →≤1 k(pgm(p′)) store(s′) and s′ ≃ σ′, where →≤1=→0 ∪ →1; ′ ′ ′ ′ (ii) If RK ⊢ k(pgm(p)) store(s) → k(k ) store(s ) then there exists p and σ such ∗ ′ ′ ′ ′ ′ ′ that CxtRed ⊢ hp,σi→ hp ,σ i, RK ⊢ k(pgm(p )) = k(k ) and s ≃ σ ; ∗ (iii) CxtRed ⊢ hp, ⊥i → i iff RK ⊢ hpi→ i for any p ∈ Pgm and i ∈ Int. Strengths. No need to search for a redex anymore, since the redex is always at the top. It is more efficient than direct implementations of evaluation contexts or small-step SOS. Also, it greatly reduces the need for conditional rules/equations; conditional rules/equations might involve inherently inefficient reachability analysis to check the conditions and are harder to deal with in parallel environments. An important “strength” specific to the rewriting logic approach is that reductions can now apply wherever they match, in a context-insensitive way. Additionally, continuation-based definitions in the RLS style above are very modular (particularly due to the use of matching modulo associativity and commutativity). Weaknesses. The program is now flattened in the continuation; several new operations (continuation constants) need to be introduced, which “replace” the corresponding original language constructs. 9 Experiments
RLS specifications can be turned into interpreters for the specified language. To analyze the efficiency of this approach, we wrote the RLS definitions above in two rewrite engines, namely ASF+SDF 1.5 (a compiler) and Maude 2.2 (a fast inter- preter with good tool support), and in several programming languages with built-in support for matching, namely Haskell, Ocaml and Prolog. For each definitional style tested (except small-step SOS), we have included for comparison interpreters 20 S¸erbanut¸˘ a,˘ Ros¸u, Meseguer in Scheme, adapting definitions from [13], chapter 3.9 (evaluation semantics) and 7.3 (continuation based semantics) and a PLT-Redex definition given as example in the installation package (for context reduction). Since RLS representation of MSOS re- lies intensively on matching modulo associativity and commutativity, which is only supported by Maude, we performed no experiments for it. One tested program consists of 15 nested loops, each of 2 iterations. The other program verifies Collatz’ conjecture up to 300. The following table gives for each definitional style the running time of the various interpreters (first column – nested loops; second column – Collatz). Times are expressed in seconds. A limit of 700mb was set on memory usage; “-” found in a table cell means the memory limit was reached; an empty cell means the combination was not attempted. For Haskell we used the ghc compiler. For Ocaml we used the ocamlcopt compiler. For Prolog we compiled the programs using gprolog. For Scheme we used the PLT-Scheme interpreter. Tests were done on a Pentium 4@2GHz with 1GB RAM, running Linux.
Language Bigstep SmallStep Reduction Continuations ASF+SDF 1.7 265.1 11.9 769.6 88.7 891.3 2.5 344.7 Haskell 0.3 32.1 3.2 167.4 5.8 157.2 0.6 41.1 Maude 3.8 184.5 63.4 >1000 552.1 >1000 8.4 483.9 Ocaml 0.5 10.2 1.0 21.0 1.8 11.0 0.5 10.9 Prolog 1.6 - 7.0 - 9.4 - 3.0 - Scheme 3.8 122.3 - - 5.9 323.6 Table 3: Experiments (times in seconds) Prolog yields pretty fast interpreters. However, for backtracking reasons, it needs to maintain the stack of all predicates tried on the current path, thus the amount of memory grows with the number of computational steps. The style promoted in [13] seems to also take into account efficiency. The only drawback is the fact that it looks more like an interpreter of a big-step definition, the representational distance to the big-step definition being much bigger than in interpreters based on RLS. The PLT-Redex implementation of context reduction ran out of memory for the presented inputs (for 9 nested loops it finished in 198 seconds). The rewriting logic implementations seem to be quite efficient in terms of speed and memory us- age, while keeping a minimal representational distance to the operational semantics definitions. In particular, RLS definitions interpreted in Maude are comparable in terms of efficiency with the interpreters in Scheme, while having the advantage of being formal definitions.
10 Related Work
There is much related work on frameworks for defining programming languages. Without trying to be exhaustive, we mention some of them. Algebraic denotational semantics. This approach, (see [17,42] for two recent books), is a special case of RLS, namely, the case in which the rewrite theory RL defining language L is an equational theory. While algebraic semantics shares a number of advantages with RLS, its main limitation is that it is not well-suited for concurrent language definitions. Other RLS work. RLS is a collective international project. Through the efforts of various researchers, there is by now a substantial body of work demonstrating the 21 S¸erbanut¸˘ a,˘ Ros¸u, Meseguer usefulness of this approach. A first snapshot of the RLS project was given in [26], and a second in [25]. This paper can be viewed as third snapshot focusing on the variety of definitional styles supported. A substantial body of experience in giving programming language definitions, and using those definitions both for execution and for analysis purposes has already been gathered; an up-to-date list of references on RLS can be found in the companion tech report [38]. Higher-order approaches. The most classic higher-order approach, although not exactly operational, is denotational semantics [37]. Denotational semantics has some similarities with its first-order algebraic cousin mentioned above, since both are based on semantic equations. Two differences are: (i) the use of first- order equations in the algebraic case versus the higher-order ones in traditional denotational semantics; and (ii) the kinds of models used in each case. A related class of higher-order approaches uses higher-order functional languages or higher- order theorem provers to give operational semantics to programming languages. Without trying to be complete, we can mention, for example, the use of Scheme in [13], the use of ML in [33], and the use of Common LISP within the ACL2 prover in [20]. There is also a body of work on using monads [29,45] to implement language interpreters in higher-order functional languages; the monadic approach has better modularity characteristics than standard SOS. A third class of higher- order approaches are based on the use of higher-order abstract syntax (HOAS) and higher-order logical frameworks, such as LF or λ-Prolog [32], to encode languages as logical systems. For recent work in this direction see [27] and references there. Other approaches. Going back to the Centaur project [5,8], logic programming has been used as a framework for SOS definitions. Note that λ-Prolog [32] belongs both in this category and in the higher-order one. Abstract State Machine (ASM) [18] can encode any computation and have a rigorous semantics, so any program- ming language can be defined as an ASM and thus implicitly be given a semantics. Both big- and small-step ASM semantics have been investigated. The semantics of various programming languages, including, for example, Java [39], has been given using ASMs. The Chemical Abstract Machine [3] avoids some of the limitations of SOS in defining concurrent programming languages and was introduced in the same journal volume as Rewriting Logic; as shown in [22], any chemical abstract machine definition is a rewrite logic theory. Tile logic [14] also supports definitions of concurrent languages and has been compared to and translated into rewriting logic [24,15]. 11 Conclusions
We have tried to show how RLS can be used as a logical framework for operational semantics definitions of programming languages. By showing how it can faithfully capture big-step and small-step SOS, MSOS, context reduction, and continuation- based semantics, we hope to have illustrated what might be called its ecumenical character: flexible support for a wide range of definitional styles, without forcing or pre-imposing any given style. We think that this flexibility makes RLS useful as a way of exploring new definitional styles. For highly-concurrent languages, such as mobile languages, or for languages involving concurrency, real-time and/or probabilities, a centralized approach forcing an interleaving semantics is unnatural. 22 S¸erbanut¸˘ a,˘ Ros¸u, Meseguer
We have, of course, refrained from putting forward any specific suggestions in this regard. But we think that new definitional styles are worth investigating; and hope that RLS in general, and this paper in particular, will stimulate such investigations.
References
[1] Abadi, M., L. Cardelli, P.-L. Curien and J.-J. L´evy, Explicit Substitutions, in: Proc. POPL’90 (1990), pp. 31–46.
[2] Benaissa, Z.-E.-A., D. Briaud, P. Lescanne and J. Rouyer-Degli, lambda-nu, a calculus of explicit substitutions which preserves strong normalisation., J. Funct. Program. 6 (1996), pp. 699–722.
[3] Berry, G. and G. Boudol, The chemical abstract machine, Theoretical Computer Science 96 (1992), pp. 217–248.
[4] Borovansk´y, P., H. Cirstea, H. Dubois, C. Kirchner, H. Kirchner, P.-E. Moreau, C. Ringeissen and M. Vittek, “ELAN V 3.4 User Manual,” LORIA, Nancy (France), fourth edition (2000).
[5] Borras, P., D. Cl´ement, T. Despeyroux, J. Incerpi, G. Kahn, B. Lang and V. Pascual, Centaur: The system., in: Software Development Environments (SDE), 1988, pp. 14–24.
[6] Chalub, F. and C. Braga, Maude MSOS tool, in: G. Denker and C. Talcott, editors, 6th International Workshop on Rewriting Logic and its Applications (WRLA’06), Electronic Notes in Theoretical Computer Science (to appear).
[7] Clavel, M., F. Dur´an, S. Eker, P. Lincoln, N. Mart´ı-Oliet, J. Meseguer and J. F. Quesada, Maude: specification and programming in rewriting logic., Theor. Comput. Sci. 285 (2002), pp. 187–243.
[8] Cl´ement, D., J. Despeyroux, L. Hascoet and G. Kahn, Natural semantics on the computer, in: K. Fuchi and M. Nivat, editors, Proceedings, France-Japan AI and CS Symposium, ICOT, 1986 pp. 49–89, also, Information Processing Society of Japan, Technical Memorandum PL-86-6.
[9] Danvy, O. and L. R. Nielsen, Refocusing in reduction semantics, Technical Report BRICS RS-04-26, University of Aarhus (2004).
[10] Diaconescu, R. and K. Futatsugi, “CafeOBJ Report. The Language, Proof Techniques, and Methodologies for Object-Oriented Algebraic Specification,” AMAST Series in Computing 6, World Scientific, 1998.
[11] Farzan, A., F. Cheng, J. Meseguer and G. Ro¸su, Formal analysis of Java programs in JavaFAN, in Proc. CAV’04, Springer LNCS, 2004.
[12] Felleisen, M. and D. P. Friedman, Control operators, the secd-machine, and the lambda-calculus, in: 3rd Working Conference on the Formal Description of Programming Concepts, Ebberup, Denmark, 1986, pp. 193–219.
[13] Friedman, D. P., M. Wand and C. T. Haynes, “Essentials of Programming Languages,” The MIT Press, Cambridge, MA, 2001, 2nd edition.
[14] Gadducci, F. and U. Montanari, The tile model, in: G. Plotkin, C. Stirling and M. Tofte, editors, Proof, Language and Interaction: Essays in Honour of Robin Milner, MIT, 2000 Also, TR-96-27, C.S. Dept., Univ. of Pisa, 1996.
[15] Gadducci, F. and U. Montanari, Comparing logics for rewriting: Rewriting logic, action calculi and tile logic, Theoret. Comput. Sci. 285 (2002), pp. 319–358.
[16] Goguen, J., T. Winkler, J. Meseguer, K. Futatsugi and J.-P. Jouannaud, Introducing OBJ, in: J. Goguen, editor, Applications of Algebraic Specification using OBJ, Cambridge, 1993 .
[17] Goguen, J. A. and G. Malcolm, “Algebraic Semantics of Imperative Programs,” MIT Press, 1996.
[18] Gurevich, Y., Evolving algebras 1993: Lipari Guide, in: E. B¨orger, editor, Specification and Validation Methods, Oxford University Press, 1994 pp. 9–37.
[19] Kahn, G., Natural semantics., in: F.-J. Brandenburg, G. Vidal-Naquet and M. Wirsing, editors, STACS, Lecture Notes in Computer Science 247 (1987), pp. 22–39.
[20] Kaufmann, M., P. Manolios and J. S. Moore, “Computer-Aided Reasoning: ACL2 Case Studies,” Kluwer Academic Press, 2000.
[21] Mart´ı-Oliet, N. and J. Meseguer, Rewriting logic as a logical and semantic framework, in: D. Gabbay and F. Guenthner, editors, Handbook of Philosophical Logic, 2nd. Edition, Kluwer Academic Publishers, 2002 pp. 1–87, first published as SRI Tech. Report SRI-CSL-93-05, August 1993. 23 S¸erbanut¸˘ a,˘ Ros¸u, Meseguer
[22] Meseguer, J., Conditional rewriting logic as a unified model of concurrency, Theoretical Computer Science 96 (1992), pp. 73–155.
[23] Meseguer, J. and C. Braga, Modular rewriting semantics of programming languages, in Proc. AMAST’04, Springer LNCS 3116, 364–378, 2004. [24] Meseguer, J. and U. Montanari, Mapping tile logic into rewriting logic, in: F. Parisi-Presicce, editor, Proceedings of WADT’97, 12th Workshop on Recent Trends in Algebraic Development Techniques, LNCS 1376 (1998), pp. 62–91.
[25] Meseguer, J. and G. Ro¸su, The rewriting logic semantics project, Theoretical Computer Science to appear (2006).
[26] Meseguer, J. and G. Rosu, Rewriting logic semantics: From language specifications to formal analysis tools., in: D. A. Basin and M. Rusinowitch, editors, IJCAR, Lecture Notes in Computer Science 3097 (2004), pp. 1–44.
[27] Miller, D., Representing and reasoning with operational semantics., in: U. Furbach and N. Shankar, editors, IJCAR, Lecture Notes in Computer Science 4130 (2006), pp. 4–20.
[28] Milner, R., M. Tofte, R. Harper and D. MacQueen, “The Definition of Standard ML (Revised),” MIT Press, 1997. [29] Moggi, E., An abstract view of programming languages, Technical Report ECS-LFCS-90-113, Edinburgh University, Department of Computer Science (1989).
[30] Moggi, E., Notions of computation and monads, Inf. Comput. 93 (1991), pp. 55–92.
[31] Mosses, P. D., Modular structural operational semantics, J. Log. Algebr. Program. 60–61 (2004), pp. 195–228. [32] Nadathur, G. and D. Miller, An overview of λProlog, in: K. Bowen and R. Kowalski, editors, Fifth Int. Joint Conf. and Symp. on Logic Programming (1988), pp. 810–827.
[33] Pierce, B., “Types and Programming Languages,” MIT Press, 2002.
[34] Plotkin, G. D., A structural approach to operational semantics., J. Log. Algebr. Program. 60-61 (2004), pp. 17–139, original version: University of Aarhus Technical Report DAIMI FN-19, 1981. [35] Reynolds, J. C., The Discoveries of Continuations, LISP and Symbolic Computation 6 (1993), pp. 233– 247. [36] Ro¸su, G., K: a Rewrite-based Framework for Modular Language Design, Semantics, Analysis and Implementation, Technical Report UIUCDCS-R-2005-2672, Department of Computer Science, University of Illinois at Urbana-Champaign (2005).
[37] Scott, D., Outline of a mathematical theory of computation, in: Proceedings, Fourth Annual Princeton Conference on Information Sciences and Systems, Princeton University, 1970 pp. 169–176, also appeared as Technical Monograph PRG 2, Oxford University, Programming Research Group. [38] S¸erb˘anut¸˘a, T. F., G. Ro¸su and J. Meseguer, A rewriting logic approach to operational semantics, Technical Report UIUCDCS-R-2007-2820, University of Illinois, Department of COmputer Science (2007).
[39] St¨ark, R. F., J. Schmid and E. B¨orger, “Java and the Java Virtual Machine: Definition, Verification, Validation,” Springer, 2001. [40] Stehr, M.-O., CINNI - a generic calculus of explicit substitutions and its application to lambda-, sigma- and pi-calculi (2000), proc. 3rd. Intl. Workshop on Rewriting Logic and its Applications.
[41] van den Brand, M., J. Heering, P. Klint and P. A. Olivier, Compiling language definitions: the asf+sdf compiler., ACM Trans. Program. Lang. Syst. 24 (2002), pp. 334–368.
[42] van Deursen, A., J. Heering and P. Klint, “Language Prototyping: An Algebraic Specification Approach,” World Scientific, 1996. [43] Verdejo, A. and N. Mart´ı-Oliet, Executable structural operational semantics in maude., J. Log. Algebr. Program. 67 (2006), pp. 226–293.
[44] Visser, E., Program transformation with Stratego/XT: Rules, strategies, tools, and systems in Stratego/XT 0.9., in: C. Lengauer, D. S. Batory, C. Consel and M. Odersky, editors, Domain-Specific Program Generation, Lecture Notes in Computer Science 3016 (2003), pp. 216–238.
[45] Wadler, P., The essence of functional programming., in: POPL, 1992, pp. 1–14.
[46] Wand, M., Continuation-based program transformation strategies., J. ACM 27 (1980), pp. 164–180.
[47] Wright, A. K. and M. Felleisen, A syntactic approach to type soundness, Inf. Comput. 115 (1994), pp. 38–94.
24 SOS 2007 Preliminary Version
Bi-inductive Structural Semantics (Extended Abstract)
Patrick Cousot1
Département d’informatique, École normale supérieure, 45 rue d’Ulm, 75230 Paris cedex 05, France Radhia Cousot2
CNRS & École polytechnique, 91128 Palaiseau cedex, France
Abstract We propose a simple order-theoretic generalization of set-theoretic inductive definitions. This general- ization covers inductive, co-inductive and bi-inductive definitions and is preserved by abstraction. This allows the structural operational semantics to describe simultaneously the finite/terminating and in- finite/diverging behaviors of programs. This is illustrated on the structural bifinitary small/big-step trace/relational/operational semantics of the call-by-value λ-calculus.
Keywords: fixpoint definition, inductive definition, co-inductive definition, bi-inductive definition, structural operational semantics, SOS, trace semantics, relational semantics, small-step semantics, big-step semantics, divergence semantics, abstraction.
1 Introduction
The connection between the use of fixpoints in denotational semantics [17]andthe use of rule-based inductive definitions in axiomatic semantics [10]andstructural operational semantics (SOS) [19,20,21] can be made by a generalization of inductive definitions [1] to include co-inductive definitions [8]. It is then possible to generalize natural semantics describing finite input/output behaviors [12]soastoalsoinclude infinite behaviors [7]. This is necessary since the definition of the infinite behaviors cannot be derived from the finite big-step SOS behaviors.
Example 1.1 Let us consider the choice operator E1 E2 where the evaluation of | E1 either terminates (returning the value a, written E1 = a) or does not termi- ⇒ nate (written E1 = ). Similarly, the big-step semantics of E2 is E2 = b for a ⇒⊥ ⇒ 1 Piatsr cuek.Co so.tr@ n f , www.di.ens.fr/˜cousot/ 2 Road.hhiuafCln.siout@poqytc e e r, www.polytechnique.edu/Radhia.Cousot/ This is a preliminary version. The final version will be published in Electronic Notes in Theoretical Computer Science P. Cousot & R. Cousot
terminating evaluation returning b or E2 = for non-termination. Let us consider ⇒⊥ several possible semantics for the choice operator:
• Nondeterministic: an internal choice is made initially to evaluate E1 or to evaluate E2;
• Parallel: evaluate E1 and E2 concurrently, with an unspecified scheduling, and return the first available result a or b;
• Mixed left-to-right: evaluate E1 and then either return its result a or evaluate E2 and return its result b;
• Mixed right-to-left: evaluate E2 and then either return its result b or evaluate E1 and return its result a;
• Eager: evaluate both E1 and E2 and return either results if both terminate. The corresponding finite big-step behaviors, as described in natural semantics [12], are all defined as follows:
a b = aab = b. | ⇒ | ⇒ But for the case = , the infinite behaviors are all different: ⊥|⊥ ⇒⊥ Non-deter- Parallel Mixed left- Mixed right- Eager ministic to-right to-left b = b b = b b = b ⊥| ⇒ ⊥| ⇒ ⊥| ⇒ b = b = b = b = ⊥| ⇒⊥ ⊥| ⇒⊥ ⊥| ⇒⊥ ⊥| ⇒⊥ a = a a = a a = a |⊥ ⇒ |⊥ ⇒ |⊥ ⇒ a = a = a = a = |⊥ ⇒⊥ |⊥ ⇒⊥ |⊥ ⇒⊥ |⊥ ⇒⊥ Since the natural semantics defines the finite behaviors but not the diverging behav- iors, an interpretation of the big-step evaluation rules as Horn clauses implemented in Prolog [2,9] will have its diverging behaviors determined by the implementation (e.g. Prolog interpreter with left-to-right evaluation). 2 The paper develops and illustrates the use of "bi-inductive" definitions in opera- tional semantics which enable both finitary and infinitary behaviors to be described simultaneously [7,8]. The general methodology consists in extending Hilbert proof systems [1]byre- placing the powerset ℘(U), of the universe U by a partial order , .Beyond ⊆ D the classical inductive definitions ℘(U), , this extension includes the co-inductive ⊆ definitions ℘(U), and bi-inductive definitions mixing inductive and co-inductive ⊇ definitions [7,8]. This extension also copes with compositional structural definitions as found in denotational semantics or SOS. This is illustrated by definitions of the semantics of the call-by-value λ-calculus. We introduce an original big-step trace semantics that gives operational meaning to both convergent and divergent behaviors of programs. The compositional struc- tural definition mixes induction for finite behaviors and co-induction for infinite behaviors while avoiding duplication of rules between the two cases. This big-step 26 P. Cousot & R. Cousot trace semantics excludes erroneous behaviors that go wrong. The other semantics are then systematically derived by abstraction. The big-step trace semantics is first abstracted to a relational semantics and then to the standard big-step or natural semantics. These abstraction are sound and complete in that the big-step trace and relational semantics describe the same converging or diverging behaviors while the big-step trace and natural semantics describe the same finite behaviors. The big-step trace semantics is then abstracted into a small-step semantics, by collecting transitions along traces. This abstraction is sound but incomplete in that the traces generated by the small-step semantics describes convergent, divergent, but also erroneous behaviors of programs. This shows that trace-based operational semantics can be much more informative that small-step operational semantics.
2 Bi-inductive structural definitions and their abstrac- tion
2.1 Structural order-theoretic inductive definitions We introduce different forms of structural order-theoretic inductive definitions and prove their equivalence. We formalize the syntax of a language L as a binary relation on L to be ≺ understood as the “strict syntactic subcomponent” relation on L. L, is therefore ≺ a well-founded set, is irreflexive (inducing the reflexive 4), and has finite left ≺ ≺ images L : L N ( S is the cardinality of set S, N is the set ∀ ∈ |{ ∈ | ≺ }| ∈ | | of natural numbers). Hence we can write ::= 1,...,n for the tuple of elements = 1,...,n such that 1,...,n = L . { } { ∈ | ≺ } For≺ example, for the language L of lambda terms a, b, ... ::=x λ x . a ab,we | | can define a λ x . a, a aband b abso ab::= a, b. In case no structural i.e. ≺ ≺ ≺ syntax-directed reasoning is needed, L canbechosenasasingletonand as false. ≺ For each “syntactic component” L, we consider a semantic domain , , ∈ D , which is assumed to be a directed complete partial order (dcpo). ⊥ For each “syntactic component” L, we consider variables X, Y, . . . ranging ∈ over the semantic domain . We drop the subscript when the corresponding D semantic domain is clear from the context (e.g. the semantic domain is the same for all “syntactic components” i.e. L : = ). ∀ ∈ D D For each “syntactic component” L,weletΔ be indexed sequences (totally ∈ ordered sets). We write xi when considering the sequence xi,i Δ i Δ ∈ ∈ Δ S of elements of a set ∈S as a vector of S. i Δ → ∈ i For each element i Δ of the sequence, we consider transformers F ∈ ∈D × 1 ... n where n = L and 1,...,n = L D ×D −→ D i |{ ∈ | ≺ }| { } { ∈ | ≺ . When n =0,wehaveF . } ∈D −→ D The transformers are assumed to be -monotone in their first parameter, that is i Δ, 1,...,n , X, Y ,X1 1 ,...,Xn n : X Y = i∀ ∈ ≺i ∈D ∈D ∈D ⇒ F (X, X1,...,Xn) F (Y,X1,...,Xn). For each “syntactic component” L,thejoin g (Δ ) is ∈ ∈ −→ D −→ D assumed to be componentwise -monotone ( Xi,i Δ : Yi,i Δ :( i ∀ ∈ ∀ ∈ ∀ ∈ 27 P. Cousot & R. Cousot
Δ : Xi Yi)= ( Xi) ( Yi)). The join operator is used to gather ⇒ i Δ i Δ ∈ ∈ g( X )= X alternatives in formal definitions. For brevity, we write i i, leaving i Δ i Δ ∈ ∈ implicit the fact that the Xi should be considered in the total order given by the sequence Δ. Most often, the order of presentation of these alternatives in the formal definition is not significant. In this case, Δ is just a set and the join may often be defined in term of a binary join g ( ) , which is assumed to be associative, ∈ D ×D −→ D commutative, and -monotone, as g( Xi) , Xi. The binary join may be i Δ i Δ ∈ ∈ different form the least upper bound (lub) of the semantic domain . D A fixpoint definition has the form