semantics of programming languages course notessemantics of programming languages course notes for...

97
University of Leicester SEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science

Upload: others

Post on 25-Feb-2021

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

University of Leicester

SEMANTICS

OF

PROGRAMMING LANGUAGES

Course Notes

for

MC 308

Dr. R. L. Crole

Department

of

Mathematics and Computer Science

Page 2: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

Preface

These notes are to accompany the module MC 308. They contain all of the core material

for the course. For more motivation and background, as well as further comments about

some of the details of proofs, please attend the lectures.

These notes are new for this year: please do let me know about any typos or other errors

which you find. If you have any other (constructive) comments, please tell me about

them.

Books recommended for MC 308 are listed in the Module Guide: ask if you need advice.

If you are to do well in this course, you must attend the lectures. They

will give you additional examples, highlight key issues which may not appear

quite as important from the notes as in fact the issues are, and give guidance

towards what you need to know for the examinations. Chapter summaries

will be given out in the lectures.

Acknowledgements

Some sections of these notes were developed from a course given by Dr. A. M. Pitts,

University of Cambridge.

c©R. L. Crole July 13, 2011

Page 3: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

Contents

1 Introduction and Background 1

1.1 Course Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.2 Notation Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.3 Inductively Defined Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.4 Rule Induction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2 Operational Semantics of an Imperative Language 12

2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.2 The Syntax of Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.3 A Transition Relation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.4 An Evaluation Relation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

2.5 Semantic Equivalence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

2.6 Command Contexts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

3 The Denotational Semantics of an Imperative Language 29

3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

3.2 Preliminary Denotational Definitions . . . . . . . . . . . . . . . . . . . . . 29

3.3 Denotational Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

4 The CSS Machine 38

4.1 Architecture of the CSS Machine . . . . . . . . . . . . . . . . . . . . . . . 38

4.2 Correctness of the CSS Machine . . . . . . . . . . . . . . . . . . . . . . . . 39

4.3 CSS Executions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

5 Elementary Domain Theory 49

5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

5.2 Cpos and Continuous Functions . . . . . . . . . . . . . . . . . . . . . . . . 49

5.3 Constructions on Cpos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

5.4 Denotational Semantics of IMP . . . . . . . . . . . . . . . . . . . . . . . . 59

Page 4: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

6 Operational Semantics of Functional Languages 61

6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

6.2 Types and Expressions for FUNe . . . . . . . . . . . . . . . . . . . . . . . 61

6.3 Function Declarations and Programs for FUNe . . . . . . . . . . . . . . . . 66

6.4 Operational Semantics for FUNe . . . . . . . . . . . . . . . . . . . . . . . 68

6.5 The Language FUNl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

6.6 Operational Semantics for FUNl . . . . . . . . . . . . . . . . . . . . . . . . 72

6.7 The Language TURe and its Operational Semantics . . . . . . . . . . . . . 75

6.8 The Language TURl and its Operational Semantics . . . . . . . . . . . . . 77

7 The Denotational Semantics of Functional Languages 79

7.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

7.2 Denotations for Type Assignments in TURe . . . . . . . . . . . . . . . . . 79

7.3 Denotations of Function Declarations and Programs in TURe . . . . . . . 83

7.4 Equivalence of Operational and Denotational Semantics . . . . . . . . . . . 86

7.5 Further Denotational Semantics . . . . . . . . . . . . . . . . . . . . . . . . 90

Page 5: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

List of Tables

2.1 Expressions ie, be, and co in IMP . . . . . . . . . . . . . . . . . . . . . . . 14

2.2 Configuration Transitions (e , s) (e ′ , s ′) in IMP . . . . . . . . . . . . . 17

2.3 Evaluation Functions I, B and C for IMP . . . . . . . . . . . . . . . . . . 20

2.4 Evaluation Relation (e , s) ⇓ s ′ in IMP . . . . . . . . . . . . . . . . . . . . 22

4.1 The CSS Re-Writes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

5.1 Properties of Continuous Functions . . . . . . . . . . . . . . . . . . . . . . 60

6.1 Type Assignment Relation ∆ | Γ ` E :: σ in FUNe . . . . . . . . . . . . . . 65

6.2 Evaluation Relation dec∆ ` P ⇓e V in FUNe . . . . . . . . . . . . . . . . . 70

6.3 Evaluation Relation dec∆ ` P ⇓l V in FUNl . . . . . . . . . . . . . . . . . 74

6.4 Type Assignment Relation ∆ | Γ ` E :: σ in TURe . . . . . . . . . . . . . . 76

6.5 Evaluation Relation dec∆ ` P ⇓e c in TURe . . . . . . . . . . . . . . . . . 77

6.6 Evaluation Relation dec∆ ` P ⇓l c in TURl . . . . . . . . . . . . . . . . . 78

7.1 Denotational Semantics [[∆ | Γ ` E ]] in TURe . . . . . . . . . . . . . . . . 81

7.2 Denotational Semantics [[∆ | Γ ` E ]] in TURl . . . . . . . . . . . . . . . . . 91

Page 6: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

List of Figures

2.1 A Transition Sequence in IMP . . . . . . . . . . . . . . . . . . . . . . . . . 18

2.2 An Example Deduction for . . . . . . . . . . . . . . . . . . . . . . . . . 18

2.3 An Example Deduction of an Evaluation . . . . . . . . . . . . . . . . . . . 23

Page 7: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

1

Introduction and Background

1.1 Course Overview

Motivation 1.1.1 At least two quite distinct issues can be associated with a program-

ming language:

(1) The definition of the SYNTAX of the language. This involves specifying an alphabet

of symbols and characters, along with a definition of the expressions, phrases, programs,

values and so on of the language.

(2) The definition of the SEMANTICS of the language. This involves specifying the

meaning of the expressions, phrases, programs, values, modules, datatypes and so on of

the language. We talk about giving a semantics to the syntax.

In this course we shall study (2). We shall see how techniques of mathematics and logic

can be used to give completely rigorous definitions of the meanings of programs written

in a particular syntax. What are the benefits of a formal semantics for a programming

language?

• It gives a basis for:

• the correctness of implementations;

• verifications that programs meet their specification;

• efficiency analysis; and

• proving that certain fragments of code in a program are interchangeable.

• It can help to detect hidden, or non-obvious features of a programming language. For

example, the dynamic binding found in many versions of LISP was regarded as a “bug”

in the first, experimental implementations, but this soon became an accepted “feature”

of LISP.

• It provides a mathematical analysis of computational and programming constructs which

are independent of the actual programming language.

• Semantic techniques can often be used in the design of a programming language; for

example ML arose in this way.

There are a number of different kinds of semantic styles:

(1) In OPERATIONAL semantics, the meaning of programming language expressions are

defined by giving rules which specify ways in which the expressions evaluate or execute.

The rules used make use of the syntactic structure of program expressions.

Page 8: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

2 Chapter 1. Introduction and Background

(2) In DENOTATIONAL semantics, the meaning of a programming language is given by

specifying various mathematical structures and functions which provide a model of the

programming language.

(3) In AXIOMATIC semantics, the meaning of the expressions of a programming language

are given indirectly through a formal logic which expresses properties of programs.

In MC 308 we concentrate on operational and denotational semantics. Before we begin

in earnest, we give a summary of some very basic mathematical facts, and then present

an account of some techniques of induction which will be used throughout the course.

1.2 Notation Summary

Logic

We use superscripts and primes to denote variants of mathematical entities. For example,

if x and y are variables, so too are x1, x2, y10, x′, y′′′′ and so on. We write A ≡ B to

indicate syntactic identity. Thus 2 + 3 = 5 but 2 + 3 6≡ 5.

If P and Q are mathematical propositions, we can form new propositions as follows:

• P and Q (sometimes written P ∧Q);

• P or Q (sometimes written P ∨Q);

• P implies Q (sometimes written P =⇒ Q or P → Q);

• not P (sometimes written ¬P );

• P if and only if Q (often written P iff Q or P ⇐⇒ Q)—this is simply an abbreviation

for

(P =⇒ Q) and (Q =⇒ P );

• for all x, P (sometimes written ∀x. P );

• there exists x, P (sometimes written ∃x. P ).

Sets

We shall use the following sets throughout MC 308:

empty set ∅

natural numbers N = { 0, 1, 2, 3, . . . }

integers Z = { . . . ,−2,−1, 0, 1, 2, . . . }

Booleans B = {T ,F }

Page 9: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

1.2. Notation Summary 3

a ∈ A denotes set membership, for example T ∈ B. The following definitions are assumed

to be well known:

Subset A ⊆ B ⇐⇒ for all a ∈ A, a ∈ B⇐⇒ for all x, (x ∈ A =⇒ x ∈ B)

Union A ∪B def= { x | x ∈ A or x ∈ B }

Intersection A ∩B def= { x | x ∈ A and x ∈ B }

Difference A \B def= { x | x ∈ A and x 6∈ B }

Powerset P(A)def= { S | S ⊆ A }

Cartesian Product A×B def= { (a, b) | a ∈ A and b ∈ B }

Total Functions

We define the set of total functions between sets A and B to be

[A,B]totdef= { f ∈ P(A×B) | ∀a ∈ A, ∃ a unique b ∈ B, (a, b) ∈ f }.

We usually refer to a total function simply as a function. We write f : A → B for

f ∈ [A,B]tot . If a ∈ A and f : A → B then f(a) denotes the unique b ∈ B for

which (a, b) ∈ f . If also g : B → C is a function, then there is a function denoted by

g ◦ f : A → C, which is defined by (g ◦ f)(a)def= g(f(a)) on each a ∈ A. We call g ◦ f

the composition of f and g. Informally, g ◦ f is the function which first applies f and

then applies g. The identity function, written idA : A → A is the function defined by

idA(a)def= a on each a ∈ A.

Partial Functions

We define the set of partial functions between sets A and B to be

[A,B]pardef=

{ f ∈ P(A×B) | ∀a ∈ A, ∀b, b′ ∈ B, ((a, b) ∈ f and (a, b′) ∈ f) =⇒ b = b′ }.

We write f : A⇀B to mean that f ∈ [A,B]par . If a ∈ A and f : A⇀B either there exists

a unique b ∈ B for which (a, b) ∈ f , or such a b does not exist. In the former case we say

that “f(a) is defined” and in this case f(a) denotes the unique b. In the latter case we

say that “f(a) is undefined”. Note that ∅ ∈ [A,B]par satisfies the definition of a partial

function, so ∅ : A⇀B. We say ∅ is the totally undefined partial function between A

and B—why is this?

Page 10: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

4 Chapter 1. Introduction and Background

Monotone Functions

If f : (D,�) → (D,�) is a monotone function between posets, that is d � d′ implies

f(d) � f(d′) for all d, d′ ∈ D, then x ∈ D is a prefixpoint of f if f(x) � x, and a

fixpoint of f if f(x) = x. We write fix (f) for the least element in the set of fixpoints of

f , if the least element exists.

1.3 Inductively Defined Sets

Motivation 1.3.1 As motivation for this section, consider the following:

The set E ⊆ N of even natural numbers is the least subset of the natural numbers satisfying

(a) 0 ∈ E, and

(b) for all n ∈ N, if n ∈ E then n+ 2 ∈ E.

Note that “least” means1 that if another subset S ⊆ N satisfies (a) and (b) (by which we

mean 0 ∈ S, and for all n ∈ N, n ∈ S implies n+2 ∈ S) then E ⊆ S. The above definition

of E amounts to saying that the elements of E are created by the rules (a) and (b), and

that (by leastness) there can be no other elements in E. We say that E is inductively

defined by the rules (a) and (b). So E = { 0, 2, 4, 6, 8, . . . }, another set satisfying (a) and

(b) is (for example) Sdef= { 0, 2, 4, 5, 6, 7, 8, 9, . . . }, and indeed E ⊆ S.

More generally, an inductively defined set I is the least (or smallest) set for which

(a) certain elements are always in I, such as c ∈ I; and

(b) whenever certain elements h1 ∈ I and h2 ∈ I and . . . and hk ∈ I, then c′ ∈ I.

(a) is sometimes called the “base clause” and (b) the “inductive clause”. In the last

example, I is E, c is 0, h1 is n, k = 1, and c′ is n+ 2. We shall now give some machinery

in which we can give a very precise formulation of inductively defined sets.

Definitions 1.3.2 A rule R for inductively defining a set denoted by I is a pair (H, c)

where H is any finite set, and c is an element. Note that H might be ∅, in which case we

say that R is a base rule. If H is non-empty we say R is an inductive rule. In the case

that H is non-empty we might write H = {h1, . . . , hk } where 1 ≤ k. We can write down

a base rule R = (∅, c) for inductively defining the set I using the following notation

Base

(R)c in I

and an inductive rule R = (H, c) = ({h1, . . . , hk }, c) as

1Let E denote the set of all sets satisfying (a) and (b). Partially order E by ⊆. Then E is the leastelement of E .

Page 11: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

1.3. Inductively Defined Sets 5

Inductive

h1 in I h2 in I . . . hk in I(R)

c in I

Note that the order of the statements h1 in I h2 in I . . . hk in I appearing

above the line is irrelevant: the hi are elements of the set H. You may like to think of

the hi in I as hypotheses and c in I as a conclusion. The notation hi in I is meant

to suggest that hi is an element of the set I.

Any set S2 is closed under a base rulec in I

if c ∈ S; and is closed under an inductive

rule h1 in I h2 in I ... hk in Ic in I

if whenever h1 ∈ S and h2 ∈ S and . . . and hk ∈ S, then

c ∈ S. The set S is closed under a set of rules R if S is closed under each rule in R.

We can now say that:

Inductively Defined Sets

A set I is inductively defined by a set of rules R if

IC I is closed under R; and

IL for every set S which is closed under R, we have I ⊆ S.

Note that a base rule corresponds to the “base clause” and an inductive rule corresponds

to the “inductive clause” as described in Motivation 1.3.1.

Example 1.3.3 A set3 R of rules for defining the set E of even numbers is R = { 1, 2 }where

(1)0 in E

e in E(2)

e+ 2 in E

IC means that elements of the inductively defined set may be built up by applying the

rules: it says that

(1) 0 ∈ E(2) for all e, e ∈ E =⇒ e+ 2 ∈ E.

and thus the elements of E are 0, 2 (that is, 0 ∈ E implies 0 + 2 = 2 ∈ E), 4 and so

on. IL amounts to saying that there can be no elements of E other than those arising by

successive application of the rules: any other set S closed under the rules must contain E

as a subset. An example of such an S is { 0, 2, 4, 6, 7, 8, 9, 10, . . . }. Check this!!

2S is any set, and might well be I!3Strictly speaking, the elements of the set R are the numbers 1 and 2. But these are just intended to

be labels for our two rules, and no confusion should result.

Page 12: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

6 Chapter 1. Introduction and Background

Definitions 1.3.4 If I is inductively defined by a set of rules R, a deduction of x in I

is given by a finite list

y1 in I, y2 in I, . . . , ym in I (∗)

where

(i) m ∈ N and m ≥ 1;

(ii) y1 in I is a conclusion of a base rule;

(iii) for any 2 ≤ i ≤ m, yi in I is the conclusion of some rule R for which the hypotheses

of R form a (possibly empty) subset of { y1 in I, . . . , yi−1 in I } (that is, the hypotheses

have already been deduced); and

(iv) ym in I is x in I.

Note that (∗) is a list—the order of the yi is crucial. We call m the length of the

deduction.

Proposition 1.3.5 Suppose that I is inductively defined by a set of rules R. Then

I = { x | there exists a deduction of x in I }

Proof Write Jdef= { x | there exists a deduction of x in I }. One can check that J

is closed under R (do it!) so that I ⊆ J by IL. We show that J ⊆ I as follows: we prove

by Mathematical Induction on n that

∀n ≥ 1, for all deductions l of length ≤ n, ∀x, if l is a deduction of x in I, then x ∈ I.

Check this! Thus if x ∈ J there must be a deduction of x in I which has length n for

some n ≥ 1, so that x ∈ I. Hence J ⊆ I. We conclude that I = J as required. �

Remark 1.3.6 Proposition 1.3.5 amounts to saying that for any x,

x ∈ I if and only if there exists a deduction of x in I.

≫ Warning 1.3.7 IC means that the elements of the Inductively defined set I

are Constructed by “applying” the rules in R—x ∈ I if there exists a deduction

of x in I. IL captures precisely the idea that I is the Least set satisfying the

rules, that is, there can be no elements of I other than those constructed by

the rules—x ∈ I only if there exists a deduction of x in I. Here, least refers

to the subset ordering ⊆ on sets.

Motivation 1.3.8 We now generalise the definition of an inductively defined set to that

of simultaneously inductively defined sets. This idea is crucial to the rest of the course!!

Page 13: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

1.3. Inductively Defined Sets 7

Definitions 1.3.9 Let I1, I2, . . . , In where n ≥ 1 denote sets. A base rule takes the

form

Base

(R)c in Ii

where 1 ≤ i ≤ n, and an inductive rule takes the form

Inductive

h1 in Ii1 h2 in Ii2 . . . hk in Iik(R)

c in Ii

where i1, i2, . . . , ik, i are elements of { 1, 2, . . . , n }.

Sets S1, S2, . . . , Sn are closed under a base rulec in Ii

if c ∈ Si; and are closed under an

inductive ruleh1 in Ii1 h2 in Ii2 ... hk in Iik

c in Iiif whenever h1 ∈ Si1 and h2 ∈ Si2 and . . . and

hk ∈ Sik , then c ∈ Si. The sets S1, S2, . . . , Sn are closed under R if S1, S2, . . . , Sn are

closed under each rule in R. We can now say that:

Simultaneously Inductively Defined Sets

Sets I1, I2, . . . , In are simultaneously inductively defined by a set of rulesR if

IC I1, I2, . . . , In are closed under R; and

IL for every collection of n sets (say S1, S2, . . . , Sn) which are closed under R,we have I1 ⊆ S1 and I2 ⊆ S2 and . . . and In ⊆ Sn.

Definitions 1.3.10 If I1, I2, . . . , In are inductively defined by a set of rules R a deduc-

tion that x in Ii is given by a list

y1 in Ii1 , y2 in Ii2 , . . . , ym in Iim (∗)

with m ≥ 1, i1, i2, . . . , im ∈ { 1, . . . , n }, where

(i) y1 in Ii1 is a conclusion of a base rule;

(ii) for any 2 ≤ j ≤ m, yj in Iij is the conclusion of some rule R for which the hypotheses

of R form a (possibly empty) subset of { y1 in Ii1 , . . . , yj−1 in Iij−1} (that is, the

hypotheses have already been deduced); and

(iii) ym in Iim is x in Ii.

Page 14: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

8 Chapter 1. Introduction and Background

Note that (∗) is a list—the order of the yj in Iij is crucial.

A labelled deduction that x in Ii looks like

y1 in Ii1 (Ri1)y2 in Ii2 (Ri2)

. . .ym in Iim (Rim)

in which the vertical sequence of the yj in Iij is a deduction of x in Ii, and each Rijis the rule from R which has been used to deduce that yj in Iij .

Remark 1.3.11 One can check that if I1, I2, . . . , In are simultaneously inductively de-

fined sets, then for each i ∈ { 1, . . . , n },

x ∈ Ii if and only if there exists a deduction of x in Ii.

Examples 1.3.12

(1) Suppose that Σ is any set, which we think of as an alphabet. Each element l of Σ

is called a letter. We inductively define the set Σ∗ of all non-empty words over the

alphabet Σ by the set of rules R def= { 1, 2 } (so 1 and 2 are just labels for rules!) given by4

[l ∈ Σ] (1)l in Σ∗

w in Σ∗ w′ in Σ∗

(2)ww′ in Σ∗

A word is just a list of letters. IC says that Σ∗ is closed under the rules 1 and 2. Closure

under Rule 1 says that any letter l is a word, that is, l ∈ Σ∗. Closure under Rule 2 says

that if w and w′ are any two words, that is w ∈ Σ∗ and w′ ∈ Σ∗, then the list of letters

ww′ obtained by writing down the list of letters w followed immediately by the list of

letters w′ is a word (that is, ww′ ∈ Σ∗). Note that it may be helpful to think of l, w and

w′ in rules (1) and (2) as variables.

As an example, let Σ = { a, b, c }. We can show that abac ∈ Σ∗ by giving a labelled

deduction of abac in Σ∗:

a in Σ∗ (1)b in Σ∗ (1)ab in Σ∗ (2)c in Σ∗ (1)ac in Σ∗ (2)

abac in Σ∗ (2)

If we compare this labelled deduction with the general definition in Definitions 1.3.10, we

see that m = 6, and y1 = a, y2 = b, etc to y6 = abac. We have

(i) y1 = a is a conclusion to the base rule (1);

4In rule (1), [l ∈ Σ] is called a side condition. It means that in reading the rule, l can be any elementof Σ.

Page 15: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

1.4. Rule Induction 9

(ii) (for example if i = 5) y5 = ac is a conclusion to (2). Here, the set of hypotheses is

{ a in Σ∗, c in Σ∗ }, and certainly the set of hypotheses is a subset of those ξ in Σ∗

already deduced:

{ a in Σ∗, c in Σ∗ } ⊆ { a in Σ∗, b in Σ∗, ab in Σ∗, c in Σ∗ }

= { y1 in Σ∗, . . . , y5−1 in Σ∗ }

(iii) ym = y6 = abac.

We can also write a deduction tree which makes explicit which hypotheses are used

when a rule is applied:

(1)a in Σ∗

(1)b in Σ∗

(2)ab in Σ∗

(1)a in Σ∗

(1)c in Σ∗

(2)ac in Σ∗

(2)abac in Σ∗

(2) Let Σ = { a, b, c, d, e } and let sets I1 and I2 of words be simultaneously inductively

defined by the rules

(1)b in I1

(2)c in I2

w in I1 w′ in I2(3)

ww′ in I2

w in I1(4)

aadwe in I2

w′ in I2(5)

w′e in I2

w′ in I2(6)

aw′a in I1

A deduction tree for aaadbeace in I2 is

(1)b in I1

(4)aadbe in I2

(6)aaadbea in I1

(2)c in I2

(5)ce in I2

(3)aaadbeace in I2

1.4 Rule Induction

Definitions 1.4.1 We state the Principle of Rule Induction for Simultaneously Induc-

tively Defined sets:

Page 16: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

10 Chapter 1. Introduction and Background

Rule Induction

Let I1, I2, . . . , In be inductively defined by a set of rules R. Suppose we wish toshow that for all i ∈ { 1, 2, . . . , n } the property PropIi(x) holds for all elementsx ∈ Ii, that is, we wish to prove

for all x ∈ I1,PropI1(x) and

for all x ∈ I2,PropI2(x) and

...

for all x ∈ In,PropIn(x).

Then all we need to do is

• for every base ruleb in Ii

∈ R prove that if b ∈ Ii then PropIi(b) holds; and

• for every inductive ruleh1 in Ii1 ,...,hk in Iik

c in Ii∈ R prove that if h1 ∈ Ii1 and

h2 ∈ Ii2 and . . . and hk ∈ Iik , and PropIi1 (h1) and PropIi2 (h2) and . . . and

PropIik(hk) all hold, so does PropIi(c).

We call the assertions PropIij (hj) (where 1 ≤ j ≤ k) inductive hypotheses.

We refer to carrying out • above as showing that the properties are closed underthe rules in R, or sometimes as verifying property closure.

To see that Rule Induction works, write

Sidef= { x | x ∈ Ii and PropIi(x) holds }.

Notice that checking the rules in R are closed under the properties amounts to verifying

that S1, S2, . . . , Sn are closed under R. Thus property IL tells us that Ii ⊆ Si for each i.

Also, Si ⊆ Ii for each i by definition. Hence Si = Ii for each i. So if i ∈ { 1, 2, . . . , n } and

x is any element of Ii, then x ∈ Si, and so PropIi(x) holds.

Examples 1.4.2 Refering to Examples 1.3.12 part (2), suppose that we wish to prove

that

every word in I2 has an even number of occurrences of a.

Write #(w) for the number of occurrences of a in w. For a word w, what shall we take

PropI1(w) and PropI2(w) to be? Obviously we want

PropI2(w)def= #(w) is even .

If we look at rule (4), it is clear that #(aadwe) will be even if #(w) is even, where w ∈ I1.

So we guess that (maybe) #(w) is also even for all words in I1, and set

PropI1(w)def= #(w) is even .

Page 17: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

1.4. Rule Induction 11

Let us now apply Rule Induction: we check the closure of each rule (1) to (6) under the

given properties.

(Rule (1)): #(b) = 0, even, so PropI1(b) holds.

(Rule (2)): #(c) = 0, even, so PropI2(c) holds.

(Rule (3)): Suppose that PropI1(w) and PropI2(w′) hold (these are the Inductive Hy-

potheses). Note that #(ww′) = #(w) + #(w′), and so #(ww′) is even by the inductive

hypotheses. Thus PropI2(ww′) holds.

(Rule (4)): Suppose that PropI1(w) holds. Then clearly we have #(aadwe) = #(w) + 2

is even, so PropI2(aadwe) holds.

(Rule (5)): Suppose that PropI2(w′) holds. Then #(w′e) = #(w′) is even. Hence

PropI2(w′e) holds.

(Rule (6)): Suppose that PropI2(w′) holds. Then #(aw′a) = 2 + #(w′) is even. Hence

PropI1(aw′a) holds.

Thus by Rule Induction we are done, and we can conclude that

for all w ∈ I1, #(w) is even, andfor all w ∈ I2, #(w) is even.

Thus we have proved both the original proposition, and into the bargain that all words

in I1 also have an even number of occurrences of a.

Page 18: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

2

Operational Semantics of an Imperative Language

2.1 Introduction

Motivation 2.1.1 We shall look at a formal definition of a simple imperative language

which we call IMP . We define the syntax of this language, and then describe how pro-

grams in the language execute—the operational semantics of IMP . The expressions of

the language comprise integers, Booleans and commands. As our language is imperative,

it has a concept of state. Thus IMP has a collection of (memory) locations which hold

data—a state is any particular assignment of data to the locations. The commands of

the language comprise instructions for changing the state. A program, or configuration,

in IMP consists of an expression together with a specified state. The program executes

by using instructions coded by the expression to manipulate the state. The (final) results

of a program execution are given by the state at the end of execution.

If e is an expression and s a state, then a configuration will be any pair of the form

(e , s). We shall define assertions of the form (e , s) (e ′ , s ′) which assert that in state

s , e executes in one cycle to e ′ with the state after the computation cycle being s ′. Such

assertions comprise a formal operational semantics. We shall also give an operational

semantics which shows how expressions can execute in a multiple number of steps to pro-

duce a final state (and a program output if the expression is an integer or a Boolean), and

show how this style of operational semantics matches the former “single cycle” definition

in an exact way.

2.2 The Syntax of Expressions

Motivation 2.2.1 We begin to describe formally the language IMP . The first step is

to give a definition of the syntax of expressions of the language. In this course, expression

syntax will in fact be abstract syntax—every syntactic object will be a finitely branching

tree. We shall adopt the following notation for finite trees: If T1, T2, T3 and so on to Tn is

a (finite) sequence of finite trees, then we shall write root(T1, T2, T3, . . . , Tn) for the finite

treeroot

T1�

T2

�T3

. . . Tn

-

whose root is denoted by the symbol root.

Page 19: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

2.2. The Syntax of Expressions 13

For example, +(2,−(3, 5)) denotes the tree

+

2�

−-

3�

5

-

We shall often use infix notation, writing (for example) 2 + 3 instead of +(2, 3) if such

notation is clearer to read. The above example would be written 2 + (3− 5).

Definitions 2.2.2 The expression syntax of IMP will be built out of various sets of

symbols. These are

Locdef= {x1, x2, . . . } the set of locations;

ICstdef= { n | n ∈ Z } the set of integer constants;

BCstdef= { b | b ∈ B } the set of Boolean constants;

IOprdef= {+,−, ∗} a fixed, finite set of integer valued operators;

BOprdef= {=, <,≤, . . . } a fixed, finite set of Boolean valued operators;

We shall let the symbol c range over elements of Z ∪ B. Note that the operator symbols

will be regarded as denoting the obvious mathematical functions. For example, ≤ is the

function which takes a pair of integers and returns a truth value. Thus ≤ : Z× Z→ B is

the function given by (m,n) 7→ m ≤ n, where

m ≤ n =

{T if m is less than or equal to n

F otherwise

For example, 5 ≤ 2 = F .

Note that we write c to indicate that the constant c is “held in memory”. We shall

require that c = c′ if and only if c = c′. Given (for example) 2 and 3 we cannot add

these “numbers” until our programming language IMP instructs that the contents of the

memory locations be added—thus 2 + 3 6= 5. However, when 2 is added to 3 by IMP , the

result is 5, and we shall write

2 + 3 = 5.

The set of expression constructors is specified by

Loc ∪ ICst ∪ BCst ∪ IOpr ∪ BOpr ∪ { skip, assign, sequence, cond,while }.

We now define the expressions of the language IMP . We begin by specifying three sets,

IExp, of integer expressions, BExp, of Boolean expressions, and Com, of com-

mands. The set Exp of expressions of the language is given by the (disjoint) union of

these three sets:

Expdef= IExp ∪ BExp ∪ Com.

Each expression is a finite tree, whose nodes are expression constructors. If e ranges over

expressions, we shall adopt the following abbreviations:

Page 20: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

14 Chapter 2. Operational Semantics of an Imperative Language

[when x ∈ Loc] eLOC

x in IExp[when n ∈ Z] eINT

n in IExp

eTRUE

T in BExpeFALSE

F in BExp

ie1 in IExp ie2 in IExp[when op ∈ IOpr ] eIOP

ie1 op ie2 in IExp

ie1 in IExp ie2 in IExp[when op ∈ BOpr ] eBOP

ie1 op ie2 in BExp

eSKIP

skip in Com

ie in IExp[when x ∈ Loc] eASS

x := ie in Com

co1 in Com co2 in ComeSEQ

co1 ; co2 in Com

be in BExp co1 in Com co2 in ComeCOND

if be then co1 else co2 in Com

be in BExp co in ComeLOOP

while be do co in Com

Table 2.1: Expressions ie, be, and co in IMP

•We write e := e ′ for the finite tree assign(e, e ′);

• e ; e ′ for sequence(e, e ′);

• if e then e ′ else e ′′ for cond(e, e ′, e ′′); and

• while e do e ′ for while(e, e ′).

The sets IExp, BExp and Com are simultaneously inductively defined by the rules in

Table 2.1. We shall also adopt the following bracketing and scoping conditions:

• Arithmetic operators group to the left. Thus ie1 op ie2 op ie3 abbreviates (ie1 op

ie2) op ie3 with the expected extension to any finite number of integer expressions.

• Sequencing associates to the right.

• if be then co else co ′ means if (be) then (co) else (co ′).

• while be do co means while (be) do (co).

Remark 2.2.3 We will usually denote elements of any given set of syntactic objects by

one or two fixed symbols. So for example, e is always used to denote expressions, that is,

Page 21: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

2.3. A Transition Relation 15

elements of Exp. This allows us to cut down on notation. As an example, the following

all have identical meanings:

• For all e, . . .

• For all expressions e, . . .

• For all e ∈ Exp, . . .

The first sentence is shorter than the others, but conveys the same meaning. ie ranges

over integer expressions, be over Boolean expressions, co over commands, and op over

arithmetic operators.

We shall use brackets as informal punctuation when writing expressions, for example

compare the following two commands:

if be then co1 else (co2 ; co3) and (if be then co1 else co2) ; co3.

≫ Warning 2.2.4 A feature of inductively defined syntax is that whenever a

syntactic expression is known to be an element of an inductively defined set,

we can determine which rules were used to construct the expression. This

is precisely where we make use of the fact that IMP expressions are finite

trees. We illustrate by example. Suppose that while be do co is a command,

that is while be do co ∈ Com. We know that there is a deduction of this fact,

using the rules in Table 2.1. Then the only rule which could be used in the

last step of the deduction must be eLOOP. This follows from the fact that the

root of the finite tree while be do co is while.

By way of illustration, if while be do co in Com had been deduced from another

rule, eSEQ say, then there would be commands co1 and co2 for which

sequence

co1�

co2

-

=

while

be�

co

-

and so sequence ≡ while which is nonsense. Similarly, no other rule (apart

from eLOOP) could be used to deduce that while be do co in Com.

It also follows that we must have be ∈ BExp and co ∈ Com—these facts must

hold if while be do co ∈ Com. Why?

2.3 A Transition Relation

Motivation 2.3.1 We shall consider the locations of IMP as being elements of some

given set Loc. A state is given by specifying what data is held in the locations. For us,

the data is simple and only consists of integers. Thus a state is a function from the set of

locations to Z. As we have mentioned, a configuration is given by a pair (e, s) where e is an

Page 22: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

16 Chapter 2. Operational Semantics of an Imperative Language

expression and s a state. We shall in fact define a binary relation on configurations which

takes the form (e1 , s1) (e2 , s2). Its intended meaning is that the first configuration

computes in one step or cycle to the second configuration. We shall also prove that the

computation steps are deterministic.

Definitions 2.3.2 The set States of states is given by [Loc,Z]tot . If s ∈ States and

x ∈ Loc, we refer to s(x) as “the integer held in x at state s”. If s ∈ States , x ∈ Loc and

n ∈ Z, then there is a state denoted by s{x 7→n} : Loc → Z which is the function defined by

(s{x 7→n})(y)def=

{n if y = xs(y) otherwise

for each y ∈ Loc. We say that state s is updated at x by n.

The elements of the set Exp × States will be known as configurations. We shall induc-

tivley define a binary relation on Exp × States by the rules in Table 2.2, where we shall

write (e1 , s1) (e2 , s2) instead of ((e1 , s1), (e2 , s2)) in . We call a transition

relation, and any instance of a relationship in is called a transition step.

Proposition 2.3.3 The binary relation enjoys the following properties:

(i) For every transition (e1 , s1) (e2 , s2), then either e1, e2 ∈ IExp, or e1, e2 ∈ BExp, or

e1, e2 ∈ Com; and

(ii) for every transition (e1 , s1) (e2 , s2), if neither e1 nor e2 is a command, then s1 = s2.

Proof Both parts follow by a simple Rule Induction for . Details are left as an easy

exercise. We shall soon give a very detailed example of a more complicated proof by Rule

Induction. �

Example 2.3.4 Let us write co for while x > 0 do co ′ where co ′ is the command

y := y + 2 ; x := x− 1. Suppose that s is a state for which s(x) = 1 and s(y) = 0. Let us

write s ′def= s{y 7→2} and s ′′

def= s{y 7→2}{x 7→0} = s ′{x 7→0}. We give an example of a sequence of

configuration transitions for the language IMP in Figure 2.1. We also give, as an example,

the deduction of the transition step ∗ in Figure 2.2. Of course, each of the transition

steps given in Figure 2.1 have similar deductions to that for ∗, but in practice one can

write down (correct) transition steps directly, without formal deduction trees, simply by

understanding the intended meaning of the language IMP .

Theorem 2.3.5 The operational semantics of IMP , as specified by the transition rela-

tion , is deterministic, that is to say that for all expressions e, e ′ and e ′′, and states

s , s ′ and s ′′, if

(e , s) (e ′ , s ′) and (e , s) (e ′′ , s ′′)

then e ′ = e ′′ and s ′ = s ′′.

Page 23: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

2.3. A Transition Relation 17

Rules for integer and Boolean Expressions

LOC

(x , s) (s(x) , s)

(ie1 , s) (ie2 , s) OP1

(ie1 op ie , s) (ie2 op ie , s)

(ie1 , s) (ie2 , s) OP2

(n op ie1 , s) (n op ie2 , s)

OP3(n1 op n2 , s) (n1 op n2 , s)

Rules for Commands

(ie1 , s) (ie2 , s) ASS1

(x := ie1 , s) (x := ie2 , s)

ASS2(x := n , s) (skip , s{x 7→n})

(co1 , s1) (co2 , s2) SEQ1

(co1 ; co , s1) (co2 ; co , s2)

SEQ2(skip ; co , s) (co , s)

(be1 , s) (be2 , s) COND1

(if be1 then co1 else co2 , s) (if be2 then co1 else co2 , s)

COND2(if T then co1 else co2 , s) (co1 , s)

COND3(if F then co1 else co2 , s) (co2 , s)

LOOP

(while be do co , s) (if be then (co ; while be do co) else skip , s)

Table 2.2: Configuration Transitions (e , s) (e ′ , s ′) in IMP

Page 24: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

18 Chapter 2. Operational Semantics of an Imperative Language

(co , s) (if x > 0 then co′ ; co else skip , s)

(if 1 > 0 then co′ ; co else skip , s)

(if T then co′ ; co else skip , s)

(co′ ; co , s)

((y := 0 + 2 ; x := x− 1) ; co , s)

((y := 2 ; x := x− 1) ; co , s)

∗ ((skip ; x := x− 1) ; co , s ′)

(x := x− 1 ; co , s ′)

(x := 1− 1 ; co , s ′)

(x := 0 ; co , s ′)

(skip ; co , s ′′)

(co , s ′′)

(if x > 0 then co′ ; co else skip , s ′′)

(if 0 > 0 then co′ ; co else skip , s ′′)

(if F then co′ ; co else skip , s ′′)

(skip , s ′′)

Figure 2.1: A Transition Sequence in IMP

ASS2(y := 2 , s) (skip , s ′)

SEQ1(y := 2 ; x := x− 1 , s) (skip ; x := x− 1 , s ′)

SEQ1((y := 2 ; x := x− 1) ; co , s) ((skip ; x := x− 1) ; co , s ′)

Figure 2.2: An Example Deduction for

Page 25: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

2.3. A Transition Relation 19

Proof We can prove this result by Rule Induction. If we write

Prop(((e , s), (e ′ , s ′)))def= for all (e ′′ , s ′′), (e , s) (e ′′ , s ′′) =⇒ (e ′′ = e ′ and s ′′ = s ′)

then we can prove that

for all (e , s) (e ′ , s ′), Prop(((e , s), (e ′ , s ′))) (∗)

holds by using Rule Induction, and this latter statement is equivalent to the statement of

the theorem.

We consider property closure for just one rule, say

(ie1 , s) (ie2 , s) ASS1

(x := ie1 , s) (x := ie2 , s)

The inductive hypothesis is Prop(((ie1 , s), (ie2 , s))), that is

for all (y , z), (ie1 , s) (y , z) =⇒ (y = ie2 and z = s) (IH)

We need to prove Prop(((x := ie1 , s), (x := ie2 , s))), that is

for all (u , v), (x := ie1 , s) (u , v) =⇒ (u = (x := ie2) and v = s) (C)

To prove (C) we choose an arbitrary configuration (e ′ , s ′) and suppose that (x:=ie1 , s) (e ′ , s ′). This could only be deduced from ASS1 and so e ′ = (x := ie3) and s ′ = s for

some ie3, where

(ie1 , s) (ie3 , s).

Hence using (IH) we can deduce ie3 = ie2 (and s = s !). Thus e ′ = (x := ie2) and we

already showed that s ′ = s . As (e ′ , s ′) was arbitrary, we have proved (C).

Checking property closure of the remaining rules is left as an easy exercise. �

≫ Warning 2.3.6 You may care to compare carefully the above proof with

the general exposition of Rule Induction. Note that (∗) is

for all ((e , s), (e ′ , s ′))︸ ︷︷ ︸i

∈ ︸︷︷︸I

,Prop(((e , s), (e ′ , s ′)))︸ ︷︷ ︸Prop(i)

Now, Prop(i) is a mathematical statement involving i. Precisely what is it?

It is in fact

for all (e ′′ , s ′′), fst(i) (e ′′ , s ′′) =⇒ e ′′ = fst(snd(i)) and s ′′ = snd(snd(i))

where fst and snd are functions which extract the first or second coordinates

of a pair.

Page 26: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

20 Chapter 2. Operational Semantics of an Imperative Language

Statesdef= [Loc,Z]tot

I: IExp −→ [States,Z]tot

B:BExp −→ [States,B]tot

C:Com −→ [States,States]par

I(ie)(s) = n where n ∈ Z is the unique integer such that (ie , s) ∗ (n , s)

B(be)(s) = b where b ∈ B is the unique Boolean such that (be , s) ∗ (b , s)

C(co)(s)def=

{unique s ′ such that (co , s) ∗ (skip , s ′) if s ′ exists

undefined otherwise

Table 2.3: Evaluation Functions I, B and C for IMP

Definitions 2.3.7 We say that a configuration (e , s) is terminal if there is no con-

figuration (e ′ , s ′) for which (e , s) (e ′ , s ′). One can see from the rules which define

that the terminal configurations are (c , s) where c ∈ Z ∪ B is any integer or Boolean

and s is any state, and (skip , s). An infinite transition sequence for a configuration

(e , s) takes the form

(e , s) (e1 , s1) (e2 , s2) . . . (ei , si) . . .

where no configuration (ei , si) is terminal. A finite transition sequence for a config-

uration (e , s) takes the form

(e , s) (e1 , s1) (e2 , s2) . . . (em , sm)

where (em , sm) is terminal. You should note that Theorem 2.3.5 implies that each non-

terminal configuration (e , s) has a unique transition sequence which is either finite or

infinite. We shall write ∗ for the reflexive, transitive closure of .

If it is the case that e ∈ IExp ∪ BExp, then for any state s we can prove that (e , s)

has a finite transition sequence. (This can be proved using Rule Induction—try it as an

exercise.) Thus there are (well defined) functions I and B as detailed in Table 2.3: for

example, for any integer expression ie, there is a total function I(ie) : States → Z whose

value I(ie)(s) at any state s is given in the Table. In the case that co ∈ Com, then for

any state s it is possible (co , s) (skip , s ′) for some state s ′. If so, by Theorem 2.3.5 we

know that s ′ is the unique state for which the latter relationship holds. So, for any given

co, there are certain states s for which we can produce a unique s ′ which depends on co

and s . Thus there is a function C as detailed in Table 2.3, where for each command co,

C(co) is a partial function from states to states.

Page 27: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

2.4. An Evaluation Relation 21

Examples 2.3.8

(1) Let co be while T do skip. Then we have

(co , s) (if T then (skip ; co) else skip , s) (skip ; co , s) (co , s) . . .

and this cycle repeats forever. Thus (co , s) has an infinite transition sequence, and

note that as s was arbitrary, C(co) : States ⇀ States is undefined on all states, that is

C(co) = ∅.

(2) Suppose that co is the command

y := 1 ; (while x > 1 do (y := x ∗ y ; x := x− 1)).

Then C(co) : States⇀States is the (total) function defined by

C(co)(s)def=

{s{y 7→n!}{x 7→1} if n > 1

s{y 7→1} if n ≤ 1

where ndef= s(x).

Remark 2.3.9 Clearly IMP is not a particulary useful or practical programming lan-

guage. But it is Turing powerful in the usual sense. Fix a pair of locations x and y. If

f : N→ N is any partial recursive function, then we can find a command co such that for

each n ∈ N, if state s satisfies n = s(x) then

C(co)(s) is defined ⇐⇒ f(n) is defined

and when they are both defined, C(co)(s)(y) = f(n).

2.4 An Evaluation Relation

Motivation 2.4.1 We shall now describe an operational semantics for IMP which, in

the case of integer expressions, specifies how such expressions can compute to integers.

The operational semantics has assertions which look like (ie , s) ⇓IExp n. The idea is

that such an assertion corresponds to the configuration (ie , s) making a finite number of

transition steps to the configuration (n , s). A similar idea applies to Boolean expressions

and commands. In Theorem 2.4.4, we clarify these intuitive ideas precisely.

Definitions 2.4.2 We shall inductively define the sets ⇓IExp , ⇓BExp and ⇓Com . These

sets are in fact ternary relations of the following form:

⇓IExp ⊆ IExp × States × Z

⇓BExp ⊆ BExp × States × B

⇓Com ⊆ Com × States × States

These sets are defined by the rules in Table 2.4. We shall use the following conventions:

Page 28: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

22 Chapter 2. Operational Semantics of an Imperative Language

⇓LOC

(x , s) ⇓IExp s(x)[ where c ∈ Z ∪ B] ⇓ CONST

(c , s) ⇓IExp c

(ie1 , s) ⇓IExp n1 (ie2 , s) ⇓IExp n2[ where op ∈ IOpr ] ⇓OP1

(ie1 op ie2 , s) ⇓IExp n1 op n2

(ie1 , s) ⇓IExp n1 (ie2 , s) ⇓IExp n2[ where op ∈ BOpr ] ⇓OP2

(ie1 op ie2 , s) ⇓BExp n1 op n2

⇓SKIP

(skip , s) ⇓Com s

(ie , s) ⇓IExp n⇓ASS

(x := ie , s) ⇓Com s{x 7→n}

(co1 , s1) ⇓Com s2 (co2 , s2) ⇓Com s3⇓SEQ

(co1 ; co2 , s1) ⇓Com s3

(be , s1) ⇓BExp T (co1 , s1) ⇓Com s2⇓COND1

(if be then co1 else co2 , s1) ⇓Com s2

(be , s1) ⇓BExp F (co2 , s1) ⇓Com s2⇓COND2

(if be then co1 else co2 , s1) ⇓Com s2

(be , s1) ⇓BExp T (co , s1) ⇓Com s2 (while be do co , s2) ⇓Com s3⇓LOOP1

(while be do co , s1) ⇓Com s3

(be , s) ⇓BExp F⇓LOOP2

(while be do co , s) ⇓Com s

Table 2.4: Evaluation Relation (e , s) ⇓ s ′ in IMP

We write (ie , s) ⇓IExp n instead of (ie, s , n) in ⇓IExp

We write (be , s) ⇓BExp b instead of (be, s , b) in ⇓BExp

We write (co , s1) ⇓Com s2 instead of (co, s1, s2) in ⇓Com

Example 2.4.3 Let us write co for while x > 0 do co ′ where co ′ is the command

y := y+ 2 ; x :=x− 1. Suppose that s is a state for which s(x) = 1 and s(y) = 0. A proof

of (co , s) ⇓ s{y 7→2}{x 7→0} is given in Figure 2.3. It is an exercise to add in the appropriate

labels to the deduction tree, and to fill in T .

Theorem 2.4.4 For any ie ∈ IExp, be ∈ BExp, co ∈ Com, s , s ′ ∈ States , n ∈ Z and

Page 29: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

2.4. An Evaluation Relation 23

P1 P2 P3

(co , s) ⇓ s{y 7→2}{x 7→0}

where P1 is

(x , s) ⇓ 1 (0 , s) ⇓ 0

(x > 0 , s) ⇓ T

and P2 is

(y , s) ⇓ 0 (2 , s) ⇓ 2

(y + 2 , s) ⇓ 2

(y := y + 2 , s) ⇓ s{y 7→2}

T

(x := x− 1 , s{y 7→2}) ⇓ s{y 7→2}{x 7→0}

(y := y + 2 ; x := x− 1 , s) ⇓ s{y 7→2}{x 7→0}

and P3 is

(x , s{y 7→2}{x 7→0}) ⇓ 0 (0 , s{y 7→2}{x 7→0}) ⇓ 0

(x > 0 , s{y 7→2}{x 7→0}) ⇓ F

(co , s{y 7→2}{x 7→0}) ⇓ s{y 7→2}{x 7→0}

Figure 2.3: An Example Deduction of an Evaluation

Page 30: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

24 Chapter 2. Operational Semantics of an Imperative Language

b ∈ B we have that

(ie , s) ∗ (n , s) ⇐⇒ (ie , s) ⇓IExp n

(be , s) ∗ (b , s) ⇐⇒ (be , s) ⇓BExp b

(co , s) ∗ (skip , s ′) ⇐⇒ (co , s) ⇓Com s ′

where ∗ denotes reflexive, transitive closure of .

Proof We break the proof into three parts:

(a) Prove the right to left implications by Rule Induction.

(b) Prove by Rule Induction for that

(ie , s) (ie ′ , s) and (ie ′ , s) ⇓ n =⇒ (ie , s) ⇓ n

(be , s) (be ′ , s) and (be ′ , s) ⇓ b =⇒ (be , s) ⇓ b

(co , s) (co ′ , s ′) and (co ′ , s ′) ⇓ s ′′ =⇒ (co , s) ⇓ s ′′

(c) Use (b) to deduce the left to right implications.

(a) We shall prove by Rule Induction that

for all (ie , s) ⇓IExp n, (ie , s) ∗ (n , s)

for all (be , s) ⇓BExp b, (be , s) ∗ (b , s)

for all (co , s) ⇓Com s ′, (co , s) ∗ (skip , s ′)

We shall just check the property closure of rule (⇓ LOOP1). Suppose that the appropriate

properties hold of the hypotheses, that is we have

(be , s1) ∗ (T , s1) (H1)

(co , s1) ∗ (skip , s2) (H2)

(while be do co , s2) ∗ (skip , s3) (H3)

We need to prove that

(while be do co , s1) ∗ (skip , s3) (C)

Let us write co1 for while be do co. Then

(co1 , s1) (if be then co ; co1 else skip , s1) ( LOOP)

∗ (if T then co ; co1 else skip , s1) (H1) and several uses of ( COND1)

(co ; co1 , s1) ( COND2)

∗ (skip ; co1 , s2) (H2) and several uses of ( SEQ1)

(co1 , s2) ( SEQ2)

∗ (skip , s3) (H3)

which proves (C).

Page 31: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

2.4. An Evaluation Relation 25

(b) We shall define a binary relation on the set Exp × States of configurations with rela-

tionships denoted by

(e , s)� (e ′ , s ′)

which hold if and only if either

e, e ′ ∈ IExp, s = s ′ and for all n ∈ Z, (e ′ , s) ⇓IExp n =⇒ (e , s) ⇓IExp n

or

e, e ′ ∈ BExp, s = s ′ and for all b ∈ B, (e ′ , s) ⇓BExp b =⇒ (e , s) ⇓BExp b

or

e, e ′ ∈ Com, and for all s ′′ ∈ States , (e ′ , s ′) ⇓Com s ′′ =⇒ (e , s) ⇓Com s ′′.

Then proving (b) is equivalent to proving that

for all (e , s) (e ′ , s ′), (e , s)� (e ′ , s ′)

which we can show by Rule Induction for the set . Let us just consider property closure

for the rule ( LOOP). We have to prove that

(co1 , s)� (if be then (co ; co1) else skip , s)

where co1def= while be do co, that is for all states s ′′ if

(if be then (co ; co1) else skip , s) ⇓ s ′′ (1)

then

(co1 , s) ⇓ s ′′ (2)

But (1) can hold only if it has been deduced either from (⇓ COND1) or (⇓ COND2). We

consider the two cases:

(Case (⇓ COND1)): (1) was deduced from the hypotheses

(be , s) ⇓ T (3)

and

(co ; co1 , s) ⇓ s ′′ (4)

where the latter assertion is deduced using (⇓ SEQ) from the hypotheses

(co , s) ⇓ s ′ (5)

and

(co1 , s ′) ⇓ s ′′ (6)

for some state s ′. If we apply (⇓ LOOP1) to (3), (5) and (6) we obtain (2).

Page 32: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

26 Chapter 2. Operational Semantics of an Imperative Language

(Case (⇓ COND2)): (1) was deduced from the hypotheses

(be , s) ⇓ F (7)

and

(skip , s) ⇓ s ′′ (8)

But (8) can only be deduced using (⇓ SKIP) so that s = s ′′ and then (⇓ LOOP2) applied to

(7) yields (2) as required.

(c) It is easy to see that the relation� defined in the proof of (b) is reflexive and transitive;

hence since it contains (which is exactly what we proved in (b)) it also contains ∗,that is

for all (e , s) ∗ (e ′ , s ′), (e , s)� (e ′ , s ′).

Thus if (ie , s) ∗ (n , s) then we have (ie , s) � (n , s) and hence by the definition of

�for all m ∈ Z, (n , s) ⇓ m =⇒ (ie , s) ⇓ m

Taking n = m and using (⇓ CONST) gives (ie , s) ⇓ n, as required. This shows the first

left to right implication. The remaining two implications are similar.

2.5 Semantic Equivalence

Motivation 2.5.1 We shall consider two commands to have the same meaning, that is

to be semantically equivalent, if they have the same affect on any arbitrary state. This

rather rough and ready idea is made precise in the definitions which follow:

Definitions 2.5.2 We say that two IMP commands co1 and co2 are semantically

equivalent if for all states s and s ′

C(co1)(s) is defined and equal to s ′ ⇐⇒ C(co2)(s) is defined and equal to s ′

and when this happens we write co1 ∼ co2. It is a corollary of Theorem 2.4.4 that we

have co1 ∼ co2 if and only if

for all s , s ′ ∈ States , (co1 , s) ⇓ s ′ ⇐⇒ (co2 , s) ⇓ s ′.

Example 2.5.3 Let us prove that the two commands

(if be then co else co ′) ; co ′′ and if be then (co ; co ′′) else (co ′ ; co ′′)

are semantically equivalent.

Let us write co1 for the first command, and co2 for the second. First, suppose that we

have

(co1 , s) ⇓ s ′ (1)

Page 33: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

2.6. Command Contexts 27

Then this can only have been deduced from (⇓ SEQ) with the hypotheses

(if be then co else co ′ , s) ⇓ s ′′ (2)

and

(co ′′ , s ′′) ⇓ s ′ (3)

for some state s ′′. The rule used to deduce (2) must have been either (⇓ COND1) or

(⇓ COND2) so that either

(be , s) ⇓ T and (co , s) ⇓ s ′′ (4)

or

(be , s) ⇓ F and (co ′ , s) ⇓ s ′′ (5)

In the first case, if we apply (⇓ SEQ) to (3) and (4) we get

(be , s) ⇓ T and (co ; co ′′ , s) ⇓ s ′ (6)

and in the second case, if we apply (⇓ SEQ) to (3) and (5) we get

(be , s) ⇓ F and (co ′ ; co ′′ , s) ⇓ s ′ (7)

If (6) holds, then using (⇓ COND1) we get (co2 , s) ⇓ s ′. If (7) holds, then using (⇓ COND2)

we also get (co2 , s) ⇓ s ′, as required.

In a similar fashion, we can begin with (co2 , s) ⇓ s ′ and deduce (1) so that co1 ∼ co2 as

required.

2.6 Command Contexts

Motivation 2.6.1 We pose a question which will be answered in the next chapter.

Suppose that co1 ∼ co2 and that co[co1] is a command with an occurrence of co1 in it.

If co[co2] denotes the command co[co1] with the command co1 changed to co2, then is it

the case that co[co1] ∼ co[co2]? We can make this precise by defining command contexts

C which are basically commands co possibly containing “gaps in the code”. These gaps

will be denoted by �. An example of a command context is if T then � else x := 2—code

for the first branch of the conditional is missing.

Definitions 2.6.2 We inductively define a command context C using the grammar

C ::= �| skip| x := ie| C ; C| if be then C else C| while be do C

Given any command co, we shall write C[co] to denote the command which results from

replacing all occurrences of � in C by co (we omit the formal recursive definition). Note

that C[co] is indeed another command.

Page 34: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

28 Chapter 2. Operational Semantics of an Imperative Language

Theorem 2.6.3 For any commands co1 and co2, we have

co1 ∼ co2 ⇐⇒ for all command contexts C, C[co1] ∼ C[co2].

Proof

(=⇒): See the end of Chapter 3.

(⇐=): This is trivial: take C to be �. �

Page 35: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

3

The Denotational Semantics of an Imperative Language

3.1 Introduction

Motivation 3.1.1 Recall the following functions, where Statesdef= [Loc,Z]tot :

I : IExp −→ [States ,Z]tot

B : BExp −→ [States ,B]tot

C : Com −→ [States , States ]par

Each of these functions has a similar definition. In the case of I, if ie is any integer

expression and s is any state, then the integer I(ie)(s) is defined to be the unique n for

which (ie , s) ∗ (n , s). This, as we saw, is a perfectly sensible definition, but how can

we calculate I(ie)(s) directly? If we were asked to prove that I(ie)(s) = n, we can do

this by using the rules defining to give a deduction of (ie , s) ∗ (n , s), but this does

not help us calculate n if we are just given ie and s . In fact this is a similar situation

to the simple functional languages in MC208. One has an operational semantics defining

P ⇓ V (where the latter relationship means that program P evaluates to a value V ) but

given any P the definition of ⇓ does not let us calculate V directly.

However, in this chapter we shall describe another semantics for IMP which goes some

way towards allowing us to calculate (execute) IMP expressions directly. We introduce a

denotational semantics which will provide a framework from which we can (almost)

directly calculate the functions above.

A denotational semantics for a language can be thought of as a mathematical model of

the language. It is intended to be far more abstract than an operational semantics, and

the model attempts to free itself from the particular syntax and implementation details

of the programming language. One pay off is that using a denotational semantics we can

compare apparently quite distinct constructs from different programming languages—a

comparison is much easier in the setting of an abstract mathematical model.

3.2 Preliminary Denotational Definitions

Motivation 3.2.1 We shall define functions

[[−]] : IExp −→ [States ,Z]tot

[[−]] : BExp −→ [States ,B]tot

[[−]] : Com −→ [States , States ]par

Page 36: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

30 Chapter 3. The Denotational Semantics of an Imperative Language

which have an obvious computation algorithm, and for which we can prove that

[[ie]] = I(ie) and [[be]] = B(be) and [[co]] = C(co).

Note that it is traditional to use the same symbol [[−]] to denote (three) different functions;

[[−]] is said to be overloaded. By “obvious computation algorithm” we mean that given

any ie, be, co and s , it is clear how to calculate [[ie]](s), [[be]](s) and [[co]](s) directly. How

might we define [[−]]? Suppose that e is an expression. We know that e is a finite tree,

and that it was constructed inductively. So e is of the form C(e1, . . . , en) where C is a

constructor and the ei are the immediate subtrees (subexpressions) of e. If we already

knew the definitions of the [[ei]] then it might be possible to define [[e]] in terms of the

(already defined) [[ei]]. But this just amounts to a recursive definition of the function [[e]].

This is preceisely how we formulate our denotational semantics—and the “computation

algorithm” referred to above amounts to computing [[e]] recursively.

In fact it is very easy to give definitions of the first two functions, but the third will take

some work. We shall have to introduce some mathematical machinery in order to allow

us to define [[−]] on commands. Once the definitions of the machinery are complete, we

shall give a full definition of [[−]].

Motivation 3.2.2 The function C : Com → [States , States ]par involves dealing with

partial functions between States and States . In order to specify such a partial function,

say f , for any state s we have to either say that f is undefined at the state s (in which

case we shall say informally that “f(s) is undefined”) or we have to say that f is defined

at s and specify a unique state which we denote by f(s) (in which case we say informally

that “f(s) is defined”). In fact we can give an alternative definition of the set of partial

functions between states. By alternative, we mean that there is in fact a set of total

functions which, in a precise sense, very much resembles the set of partial functions

between states. This latter set of (total) functions is conceptually easier to deal with, but

will still provide us with a perfectly good model for commands.

Basically the idea is this: We shall consider, just for the moment, any partial function

f : A ⇀ B between sets A and B. We consider replacing the target set B by a set

B∪{⊥} where ⊥ is distinct from the elements of B. Then the partial function f : A⇀B

“corresponds” to a total function f : A→ B ∪{⊥} where f(a)def= f(a) if f(a) is defined,

and f(a)def= ⊥ otherwise. Conversely, given a function g : A→ B ∪ {⊥}, it is clear that

there is a partial function g̃ : A⇀B (what is g̃?). It is easy to verify that f̃ = f and

g̃ = g and thus there is a bijection

[A,B]par ∼= [A,B ∪ {⊥}]tot

and the two sets (of functions) are “mathematically identical”. We need to make this a

little more precise for our current setting:

Definitions 3.2.3 We shall define a set

States⊥def= { [s ] | s ∈ States } ∪ {⊥}

Page 37: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

3.2. Preliminary Denotational Definitions 31

where you should think of [s ] as a copy of s so that if [s ] = [s ′] then s = s ′ for all states

s and s ′, and ⊥ is a fixed element such that ⊥ 6= [s ] for any state s . We call ⊥ bottom

or the undefined state. Note that this amounts to there being an injection

ι : States → States⊥

where ι(s)def= [s ].

Proposition 3.2.4 There is a bijection

I : [States , States ]par ∼= [States , States⊥]tot

where for f ∈ [States , States ]par we define I(f) ∈ [States , States⊥]tot by

I(f)(s)def=

{[f(s)] if f(s) is defined

⊥ otherwise

for any state s .

Proof We shall prove that I is injective, and leave surjectivity as an exercise. Suppose

that I(f) = I(f ′). We have to show that f = f ′, that is if s is any state we need to see that

either both f(s) and f ′(s) are undefined or else both are defined and f(s) = f ′(s). By

hypothesis we have I(f)(s) = I(f ′)(s). We consider cases according to whether I(f)(s)

is bottom or not:

(Case I(f)(s) is bottom): Clearly I(f ′)(s) must also be bottom and thus neither f(s) or

f ′(s) is defined.

(Case I(f)(s) is [f(s)]): We must have that I(f ′)(s) is [f ′(s)] (why?) and thus [f(s)] =

[f ′(s)]. So f(s) = f ′(s) as required.

As s was assumed to denote any arbitrary state, we are done. �

Motivation 3.2.5 As we have said, the function [[−]] : Com → [States , States ]par will be

equal to C, but is to have a definition which allows for direct calculation of [[co]](s) for any

co and s . Now that we have seen that the sets [States , States ]par and [States , States⊥]tot are

bijective, and thus essentially “mathematically identical”, we shall try to define a function

[[−]] : Com → [States , States⊥]tot . This will give us a perfectly good mathematical model.

To do this we shall need some auxiliary definitions. We shall now give each of these, and

then give our full definition of [[−]]. We shall motivate each of the auxiliary definitions by

seeing how they arise naturally when we consider what properties our denotational model

of IMP should have.

λ-notation

Suppose that f : X → Y is any function which is given by a mapping x 7→ E(x) where

E(x) ∈ Y is an expression involving x. Then it is sometimes convenient to be able to refer

to the function f and at the same time make its definition explicit. We write λx∈X.E(x)

for the function f . Thus, for example, λx∈N.x + 1 : N → N is the function which maps

any number to its successor; for example (λx∈N.x+ 1)(4) = 5.

Page 38: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

32 Chapter 3. The Denotational Semantics of an Imperative Language

Lifting

Motivation 3.2.6 What is [[co1 ; co2]]? Let us suppose that we know the definitions of

[[co1]] : States → States⊥ and [[co2]] : States → States⊥

Operationally, the intended meaning of co1 ; co2 is that the command takes any state s ,

performs command co1 which either loops or produces a new state s ′, and then in the

latter case performs command co2 in state s ′.

Hence [[co1]](s) is either ⊥ or is a new value state1 [s′]. Thus [[co1 ; co2]](s) should be ⊥if [[co1]](s) is ⊥, and otherwise should be [[co2]](s ′). We can capture this neatly with the

following definitions:

Definitions 3.2.7 Suppose that g : States → States⊥ and that x ∈ States⊥. Then we

define a function g⊥ : States⊥ → States⊥ by setting

g⊥(x)def=

{g(s) if x = [s ] for some s ∈ States

⊥ otherwise

where x is any element of States⊥. Thus we could define

[[co1 ; co2]]def= λs∈States.[[co2]]⊥([[co1]](s))

which states precisely the intended denotation described above.

Conditionals

Motivation 3.2.8 Let us think about if be then co else co ′. Given a state s , the latter

expression computes co in state s if be computes to T in state s , or computes co ′ in state

s if be computes to F in state s . Thus we might wish to say that [[if be then co else co ′]](s)

is [[co]](s) or [[co ′]](s) according to whether [[be]](s) is T or F .

Definitions 3.2.9 Given any b ∈ B and x, x′ ∈ States⊥ we define a function

cond : B× States⊥ × States⊥ −→ States⊥

by setting

cond (b, x, x′)def=

{x if b = T

x′ if b = F

We call this the conditional function for States⊥. We can use this conditional function

to define the semantics of if-then expressions as

[[if be then co else co ′]]def= λs∈States.cond ([[be]](s), [[co]](s), [[co ′]](s))

assuming that, recursively, we already have definitions of [[be]], [[co]] and [[co ′]].

1We refer to elements [s] of States⊥ as value states.

Page 39: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

3.2. Preliminary Denotational Definitions 33

Least Fixed Points

Motivation 3.2.10 Let us think about what [[while be do co]] : States → States⊥ should

be. Operationally, while be do co executes in a state s by first evaluating be in s . If the

result is T , then the command co ; while be do co is executed, and if the result is F then

skip is executed (and in this case the final state is s). This means that in our model we

should have

[[while be do co]](s) = cond ([[be]](s), [[co ; while be do co]](s), [s ])

and writing f for [[while be do co]] this amounts to

f(s) = cond ([[be]](s), f⊥([[co]](s)), [s ]).

Thus whatever f is, it must satisfy the latter equation. Hence [[while be do co]] should be

an element f ∈ [States , States⊥]tot for which Φ(f) = f where

Φ : [States , States⊥]tot −→ [States , States⊥]tot

is the function given by

λf∈[States,States⊥]tot .λs∈States.cond ([[be]](s), f⊥([[co]](s)), [s ]).

Recall that such an f satisfying Φ(f) = f is called a fixpoint of Φ.

We have a problem in that Φ may have more than one fixed point. Which one of them

ought to be chosen for the semantics of our while expression? The answer is that it does

not matter, provided we can produce a useful model of our programming language. One

test of the usefulness of the denotational semantics is that, in some sense, it corresponds

closely to the operational semantics. We shall now show how we can choose our fixpoint

uniquely, and later show that we made a good choice in the sense just described. We

make our choice by considering a partial order � on the set [States , States⊥]tot . We can

then consider the set of prefixpoints of

Φ : ([States , States⊥]tot ,�) −→ ([States , States⊥]tot ,�)

and choose the least one (assuming it exists) for our semantic definition. Let us define a

suitable partial order.

Definitions 3.2.11 Recall that we have

I : [States , States ]par ∼= [States , States⊥]tot

The set on the left hand side is by definition (see page 3) a subset of P(States × States)

and so we can consider relationships between its elements given by subset inclusion, say

f ⊆ f ′. A moments thought reveals that this means for all states s , if f(s) is defined then

so too is f ′(s) and f(s) = f ′(s)—make sure you understand this!

Page 40: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

34 Chapter 3. The Denotational Semantics of an Imperative Language

We can then transport these (partial order) relationships across the bijection, so that for

any

g, g′ ∈ [States , States⊥]tot ,

we define the relationship g � g′ to hold if and only if f ⊆ f ′ where f and f ′ are the

unique elements for which I(f) = g and I(f ′) = g′. Thus g � g′ if and only if

for all s ∈ States , g(s) 6= ⊥ =⇒ g(s) = g′(s).

With Φ defined as above, we have

Proposition 3.2.12 There is a function fix (Φ) : States → States⊥ for which

(i) Φ(fix (Φ)) = fix (Φ), that is fix (Φ) is a fixpoint of Φ, and

(ii) for all g : States → States⊥, if Φ(g) � g (that is g is a prefixpoint of Φ) then fix (Φ) � g

(that is fix (Φ) is a least prefixpoint of Φ).

Proof This is delayed until Chapter 5. �

3.3 Denotational Semantics

Definitions 3.3.1 We can now give the full definition of the denotational semantics of

IMP . We shall define the denotational functions

[[−]] : IExp −→ [States ,Z]tot

[[−]] : BExp −→ [States ,B]tot

[[−]] : Com −→ [States , States⊥]tot

by recursion on the structure of e using the following clauses, where s is an arbitrary

state:

• [[c]]def= λs∈States.c;

• [[x]]def= λs∈States.s(x);

• [[e1 op e2]]def= λs∈States.[[e1]](s) op [[e2]](s);

• [[skip]]def= λs∈States.[s ];

• [[x := ie]]def= λs∈States.[s{x 7→[[ie]](s)}];

• [[co ; co ′]]def= λs∈States.[[co ′]]⊥([[co]](s));

• [[if be then co else co ′]]def= λs∈States.cond ([[be]](s), [[co]](s), [[co ′]](s)) ; and

• [[while be do co]]def= fix (Φ) where Φ is the function

λg∈[States,States⊥]tot .λs∈States.cond ([[be]](s), g⊥([[co]](s)), [s ]).

Page 41: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

3.3. Denotational Semantics 35

Motivation 3.3.2 We shall show that there is a very precise correspondence between

the operational and denotational semantics of IMP . This correspondence is stated in the

following theorem:

Theorem 3.3.3 For all ie ∈ IExp, be ∈ BExp, co ∈ Com, n ∈ Z, b ∈ B and s , s ′ ∈States we have

I(ie)(s) = n ⇐⇒∗ (ie , s) ⇓IExp n ⇐⇒ [[ie]](s) = n

B(be)(s) = b ⇐⇒∗ (be , s) ⇓BExp b ⇐⇒ [[be]](s) = b

C(co)(s) = s ′ ⇐⇒∗ (co , s) ⇓Com s ′ ⇐⇒ [[co]](s) = [s ′]

Proof The bi-implications ⇐⇒∗ were established in Chapter 2, and are included for

completeness in the statement of the theorem.

(=⇒) We prove the left to right implications by using Rule Induction for the simultane-

ously inductively defined sets ⇓IExp , ⇓BExp and ⇓Com . For example,

Prop⇓IExp((ie, s , n))

def= [[ie]](s) = n;

what are the other properties?

We shall just check property closure for the rules ⇓ OP2 and ⇓ LOOP1.

(Case ⇓ OP2): The inductive hypotheses are

[[ie1]](s) = n1 and [[ie2]](s) = n2

and we have to prove that [[ie1 op ie2]](s) = n1 op n2. But this is trivial, as

[[ie1 op ie2]](s)def= [[ie1]](s) op [[ie2]](s) = n1 op n2

with the latter equality following by the Inductive Hypotheses.

(Case ⇓ LOOP1): Let co ′ be while be do co and suppose that the following Inductive

Hypotheses hold for some states s1, s2 and s3:

[[be]](s1) = T and [[co]](s1) = [s2] and [[co ′]](s2) = [s3] (H)

We have to prove that

[[co ′]](s1) = [s3] (C)

Now [[co ′]] = fix (Φ) where

Φ = λg∈[States,States⊥]tot .λs1∈States.cond ([[be]](s1), g⊥([[co]](s1)), [s1])

Hence we have

[[co ′]] = fix (Φ) = Φ(fix (Φ)) = Φ([[co ′]]) = λs1∈States.cond ([[be]](s1), [[co ′]]⊥([[co]](s1)), [s1])

Page 42: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

36 Chapter 3. The Denotational Semantics of an Imperative Language

Thus we have

[[co ′]](s1) = cond ([[be]](s1), [[co ′]]⊥([[co]](s1)), [s1])

= cond (T , [[co ′]]⊥([s2]), [s1]) by (H)

= [[co ′]]⊥([s2])

= [[co ′]](s2)

= [s3] by (H)

which is (C). We leave the reader to check property closure for the remaining rules.

(⇐=) We use Rule Induction for the sets IExp, BExp and Com. So for example we take

PropIExp(ie)def= for all n ∈ N, for all s , [[ie]](s) = n =⇒ (ie , s) ⇓IExp n;

what are the other properties?

We only consider property closure for the rule eLOOP. We write co ′ for while be do co.

The Inductive Hypotheses are

for all s , s ′ ∈ States , [[co]](s) = [s ′] =⇒ (co , s) ⇓Com s ′ (H1)

and

for all b ∈ B, for all s ∈ States , [[be]](s) = b =⇒ (be , s) ⇓BExp b (H2)

and then we have to prove that

for all s , s ′ ∈ States , [[co ′]](s) = [s ′] =⇒ (co ′ , s) ⇓Com s ′ (C)

Now, (C) is equivalent to

[[co ′]] � I(C(co ′)) ∈ [States , States⊥]tot (1)

where we recall from page 20 that

C(co ′)(s)def=

{unique s ′ such that (co ′ , s) ⇓Com s ′ if s ′ exists

undefined otherwise

and I is the bijection of page 31.

But we have [[co ′]] = fix (Φ) and so using Proposition 3.2.12 part (ii), (1) will hold providing

that

Φ(I(C(co ′))) � I(C(co ′)) (2)

which is equivalent to saying that for all states s ,

Φ(I(C(co ′)))(s) 6= ⊥ =⇒ Φ(I(C(co ′)))(s) = I(C(co ′))(s) (C ′)

Now for any arbitrary s ,

Φ(I(C(co ′)))(s) = cond ([[be]](s), (I(C(co ′)))⊥([[co]](s)), [s ])

Page 43: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

3.3. Denotational Semantics 37

and so if Φ(I(C(co ′)))(s) 6= ⊥ then either

[[be]](s) = T and Φ(I(C(co ′)))(s) = (I(C(co ′)))⊥([[co]](s)) 6= ⊥ (3)

or

[[be]](s) = F and Φ(I(C(co ′)))(s) = [s]. (4)

In the first case (3) we have

⊥ 6= Φ(I(C(co ′)))(s) = (I(C(co ′)))⊥([[co]](s)) =

I(C(co ′))(s ′)if [[co]](s) = [s ′] for some s ′

⊥ otherwise

and thus [[co]](s) = [s ′] and I(C(co ′))(s ′) = [s ′′] for some states s ′ and s ′′. Then by

(H1) and the definition of C we have (co , s) ⇓ s ′ and (co ′ , s ′) ⇓ s ′′. As [[be]](s) = T

by assumption, (H2) tells us that (be , s) ⇓ T . Applying (⇓ LOOP1) we conclude that

(co ′ , s) ⇓ s ′′. So C(co ′)(s) = s ′′ and thus I(C(co ′))(s) = [s ′′] using Proposition 3.2.4.

Hence

Φ(I(C(co ′)))(s) = [s ′′] = I(C(co ′))(s).

In the second case (4) we have Φ(I(C(co ′)))(s) = [s ] and using (H2) we deduce that

(be , s) ⇓BExp F . Applying (⇓ LOOP2) we have (co ′ , s) ⇓Com s and so I(C(co ′))(s) = [s ].

Hence

Φ(I(C(co ′)))(s) = [s ] = I(C(co ′))(s).

From cases (3) and (4) the desired conclusion (C ′) follows. �

Corollary 3.3.4 For commands co1 and co2 we have co1 ∼ co2 ⇐⇒ [[co1]] = [[co2]].

Proof This follows immediately from Theorem 3.3.3. Why? �

Motivation 3.3.5 We can now complete the proof of Theorem 2.6.3:

Proof

(=⇒): We can prove by induction on C that

for all co1, for all co2, for all C, ([[co1]] = [[co2]] =⇒ [[C[co1]]] = [[C[co2]]]). (∗)

Then if co1 ∼ co2, the corollary gives [[co1]] = [[co2]], (∗) gives [[C[co1]]] = [[C[co2]]], and

thus the corollary gives C[co1] ∼ C[co2]. This is true for any arbitrary C. �

Page 44: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

4

The CSS Machine

4.1 Architecture of the CSS Machine

Motivation 4.1.1 We have seen that a denotational semantics gives a direct method for

calculating the functions I, B and C. This involves a mathematical model of IMP , and

while this situtation is fine for a theoretical examination of IMP , we would like to have

a more direct, computational method for calculating the above functions. We provide

just that in this chapter, by defining an abstract machine which executes via single step

re-write rules.

You may like to compare these ideas with those in MC208 where we introduced the

SECD machine, which was an operational architecture for computing a value V from any

program P (provided that such a V satisfying P ⇓e V exists). In this chapter we shall

describe an architecture for directly computing/executing IMP expressions. An analogy

with MC208 is

functional language compares to IMP

functional programs compare to IMP ie and be expressions

functional values compare to constants c

calculating values from programs compares to calculating I and B

SECD machine compares to CSS machine

SECD re-writes compare to CSS re-writes

You should note that this comparison is very rough and ready, and should be treated with

caution. But it ought to give you a clearer idea of the aims of the current chapter.

Definitions 4.1.2 In order to define the CSS machine, we first need a few preliminary

definitions. The CSS machine consists of rules for transforming CSS configurations. Each

configuration is composed of code which is executed, a stack which consists of a list of

integers or Booleans, and a state which is the same as for IMP .

A CSS code C is a list which is produced by the following grammars:

ins ::= e | op | STO(x) | BR(co1, co2) C ::= nil | ins : C

where e is any IMP expression, op is any operator, x is any variable and co1 and co2 are

any two commands. The objects ins are CSS instructions. A stack σ is produced by

the grammar

σ ::= nil | c : σ

Page 45: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

4.2. Correctness of the CSS Machine 39

where c is any integer or Boolean. A state s is indeed an IMP state. We shall write −instead of nil for the empty code or stack list.

A CSS configuration is a triple (C, σ, s) whose components are defined as above. A CSS

transition takes the form

(C1 , σ1 , s1 ) 7−→ (C2 , σ2 , s2 )

and indicates a relationship between CSS configurations. Thus 7−→ is a binary relation

on the set of all CSS configurations. This binary relation is defined inductively by a set

of rules, each rule having the form

R(C1 , σ1 , s1 ) 7−→ (C2 , σ2 , s2 )

that is, every rule has no hypotheses. We call such a binary relation as 7−→ which is

inductively defined by rules with no hypotheses a re-write relation. The CSS re-writes

are defined in Table 4.1, where each rule R is written

C1 σ1 s1 7−→ C2 σ2 s2

Remark 4.1.3 You may like to compare such re-write rules with the transition steps of

IMP which we met in Chapter 2. They are similar, except that any individual re-write

does not require justifying via a deduction tree, because by definition a re-write step is

defined by a rule with empty hypotheses.

κ0 7−→ κ1 7−→ κ2 7−→ κ3 7−→ κ4 . . . 7−→ κn

no tree

κi 7−→ κi+1

Rewrite Rules (Abstract Machine)

deduction tree deduction tree deduction tree deduction tree

γ0 γ1 γ2 γ3 . . . γn

Transition Semantics

In this informal picture, κ denotes a typical CSS configuration, and γ a typical IMPconfiguration.

4.2 Correctness of the CSS Machine

Motivation 4.2.1 We prove that the CSS machine is correct for our operational seman-

tics. This means that whenever we execute an expression according to the semantics in

Chapter 2, the result matches that of the CSS machine, and vice versa. We make this

precise in the following theorem:

Page 46: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

40 Chapter 4. The CSS Machine

n : C σ s 7−→ C n : σ s

ie1 op ie2 : C σ s 7−→ ie2 : ie1 : op : C σ s

x : C σ s 7−→ C s(x) : σ s

op : C n1 : n2 : σ s 7−→ C n1 op n2 : σ s

T : C σ s 7−→ C T : σ s

F : C σ s 7−→ C F : σ s

skip : C σ s 7−→ C σ s

x := ie : C σ s 7−→ ie : STO(x) : C σ s

STO(x) : C n : σ s 7−→ C σ s{x 7→n}

(co1 ; co2) : C σ s 7−→ co1 : co2 : C σ s

if be then co1 else co2 : C σ s 7−→ be : BR(co1, co2) : C σ s

BR(co1, co2) : C T : σ s 7−→ co1 : C σ s

BR(co1, co2) : C F : σ s 7−→ co2 : C σ s

while be do co : C σ s 7−→ be : BR((co ; while be do co), skip) : C σ s

Table 4.1: The CSS Re-Writes

Page 47: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

4.2. Correctness of the CSS Machine 41

Theorem 4.2.2 For all n ∈ Z, b ∈ B, ie ∈ IExp, be ∈ BExp, co ∈ Com and s , s1, s2 ∈States we have

(ie , s) ⇓IExp n ⇐⇒ ie − s 7−→t − n s

(be , s) ⇓BExp b ⇐⇒ be − s 7−→t − b s

(co , s1) ⇓Com s2 ⇐⇒ co − s1 7−→t − − s2

where 7−→t denotes the transitive closure of 7−→. (Note that in the CSS configurations,

we have written ie instead of ie : nil, n instead of n : nil, and so on. This slight abuse of

notation should keep things tidy, and not cause any problems).

Motivation 4.2.3 The proof method for Theorem 4.2.2 is as follows: For the =⇒implication(s) we use Rule Induction for the sets ⇓IExp , ⇓BExp and ⇓Com . For the ⇐=

implication(s) we use Mathematical Induction on k, where of course κ 7−→t κ′ iff for some

k ∈ N,

κ = κ1 7−→ κ2 7−→ . . . 7−→ κk = κ′.

If it is not immediately clear to you how Mathematical Induction will be used, then

look ahead to page 45. We shall need a few preliminary results before we can prove the

theorem.

Lemma 4.2.4 The CSS machine re-writes are deterministic, that is each CSS configu-

ration re-writes to a unique CSS configuration:

More precisely, if

C σ s 7−→ C1 σ1 s1 and C σ s 7−→ C2 σ2 s2

then C1 = C2, σ1 = σ2 and s1 = s2.

Proof This follows from simply inspecting the definition of 7−→: given any C σ s ,

either there is no transition (the configuration is stuck), or there is only one transition

which is valid. �

Lemma 4.2.5 Given any sequence of CSS re-writes, we can (uniformly) extend both

the code and stack of each configuration, without affecting the execution of the original

code and stack:

For any codes Ci, stacks σi, states si and k ∈ N,

C1 σ1 s1 7−→k C2 σ2 s2

=⇒C1 : C3 σ1 : σ3 s1 7−→k C2 : C3 σ2 : σ3 s2

where we define 7−→0 to be the identity binary relation on the set of all CSS configurations,

and of course 7−→1 means just 7−→; and we write C : C ′ to mean that the list C is appended

to the list C ′.

Page 48: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

42 Chapter 4. The CSS Machine

Proof We use induction on k ∈ N, that is we prove Prop(k) holds for all k ∈ N where

Prop(k) is the assertion that

for all appropriate codes, stacks and states

C1 σ1 s1 7−→k C2 σ2 s2

=⇒C1 : C3 σ1 : σ3 s1 7−→k C2 : C3 σ2 : σ3 s2 .

(Proof of Prop(0)): This is trivially true (why?).

(Proof of for all k0 ∈ N, Prop(k)k≤k0 =⇒ Prop(k0 + 1)): Let k0 be arbitrary and assume

(inductively) that Prop(k) holds for all k ≤ k0. We prove Prop(k0 + 1) from these

assumptions. Spelling this out, we shall show that if

for all codes, stacks and states,

C1 σ1 s1 7−→k C2 σ2 s2

=⇒C1 : C3 σ1 : σ3 s1 7−→k C2 : C3 σ2 : σ3 s2

holds for each k ≤ k0, then

for all codes, stacks and states,

C1 σ1 s1 7−→k0+1 C2 σ2 s2

=⇒C1 : C3 σ1 : σ3 s1 7−→k0+1 C2 : C3 σ2 : σ3 s2 .

Let us choose arbitrary codes, stacks and states for which

C1 σ1 s1 7−→k0+1 C2 σ2 s2

We now consider the possible forms that C1 can take; here we just give a couple of cases:

(Case C1 is −): We have to prove that

− σ1 s1 7−→k0+1 C2 σ2 s2

=⇒− : C3 σ1 : σ3 s1 7−→k0+1 C2 : C3 σ2 : σ3 s2

But there are no transitions from a configuration with empty code. Thus the above

implication asserts that “false =⇒ ??” which is true. (Ask if you are confused by this).

(Case C1 is n : C1): Suppose that we have

n : C1 σ1 s1 7−→k0+1 C2 σ2 s2

Page 49: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

4.2. Correctness of the CSS Machine 43

We need to prove that

n : C1 : C3 σ1 : σ3 s1 7−→k0+1 C2 : C3 σ2 : σ3 s2 (1)

By Lemma 4.2.4 we must have1

n : C1 σ1 s1 7−→1 C1 n : σ1 s1 7−→k0 C2 σ2 s2

and so by induction (k0 ≤ k0 !!)

C1 : C3 n : σ1 : σ3 s1 7−→k0 C2 : C3 σ2 : σ3 s2 (2)

But

n : C1 : C3 σ1 : σ3 s1 7−→1 C1 : C3 n : σ1 : σ3 s1 (3)

and then (2) and (3) prove (1) as required.

(Case C1 is BR(co1, co2) : C1): Assume that2

BR(co1, co2) : C1 T : σ1 s1 7−→k0+1 C2 σ2 s2

We need to prove that

BR(co1, co2) : C1 : C3 T : σ1 : σ3 s1 7−→k0+1 C2 : C3 σ2 : σ3 s2 (4)

Now

BR(co1, co2) : C1 T : σ1 s1 7−→1 co1 : C1 σ1 s1

and so by induction we have

co1 : C1 : C3 σ1 : σ3 s1 7−→k0 C2 : C3 σ2 : σ3 s2 (5)

But

BR(co1, co2) : C1 : C3 T : σ1 : σ3 s1 7−→1 co1 : C1 : C3 σ1 : σ3 s1 (6)

and then (5) and (6) imply (4) as required. We omit the remaining cases. �

Lemma 4.2.6 Given a sequence of re-writes in which the code of the first configura-

tion takes the form of two appended codes, then each of these codes may be executed

separately:

For all k ∈ N, and

1All we are saying here is that any sequence of re-write steps must have a unique form. We often usedeterminism of 7−→ in the next few pages, without always quoting Lemma 4.2.4.

2Given that the code begins with the instruction BR(co1, co2) and we know that there is a validre-write, the stack must begin with T .

Page 50: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

44 Chapter 4. The CSS Machine

for all appropriate codes, stacks and states, if

C1 : C2 σ s 7−→k − σ′′ s ′′

then there is a stack and state σ′ and s ′, and k1, k2 ∈ N for which

C1 σ s 7−→k1 − σ′ s ′

C2 σ′ s ′ 7−→k2 − σ′′ s ′′

where k1 + k2 = k.

Proof We use Mathematical Induction on k; let Prop(k) denote the property of k given

in the above box.

(Proof of Prop(0)): This is trivially true (why?).

(Proof of for all k0 ∈ N, Prop(k)k≤k0 =⇒ Prop(k0 + 1)): Let k0 be arbitrary and assume

(inductively) that Prop(k) holds for all k ≤ k0. We prove Prop(k0 + 1) from these

assumptions. Let us choose arbitrary codes, stacks and states for which

C1 : C2 σ s 7−→k0+1 − σ′′ s ′′

and then consider the possible forms that C1 can take.

(Case C1 is while be do co : C1):

We suppose that

while be do co : C1 : C2 σ s 7−→k0+1 − σ′′ s ′′

and hence by Lemma 4.2.4

while be do co : C1 : C2 σ s

7−→1 be : BR((co ; while be do co), skip) : C1 : C2 σ s

7−→k0 − σ′′ s ′′

So as k0 ≤ k0 (!), by induction we have k1, k2 where k0 = k1 + k2 and σ′ and s ′ such that

be : BR((co ; while be do co), skip) : C1 σ s 7−→k1 − σ′ s ′ (1)

and

C2 σ′ s ′ 7−→k2 − σ′′ s ′′ (2)

But

while be do co : C1 σ s 7−→1 be : BR((co ; while be do co), skip) : C1 σ s (3)

and so we are done using (1) with (3), and (2). The other cases are left as exercises. �

Page 51: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

4.2. Correctness of the CSS Machine 45

Lemma 4.2.7 For all appropriate codes, stacks, states and natural numbers,

ie σ s 7−→k − σ′ s ′ =⇒

s = s ′ and σ′ = n : σ some n ∈ Z and ie − s 7−→k − n s

and

be σ s 7−→k − σ′ s ′ =⇒

s = s ′ and σ′ = b : σ some b ∈ B and be − s 7−→k − b s

Proof A lengthy, trivial Rule Induction on IExp and BExp. �

Proving Theorem 4.2.2

Let us now give the proof of the correctness theorem:

Proof (=⇒): We use Rule Induction for ⇓IExp , ⇓BExp and ⇓Com . We show property

closure for just one example rule:

(Case ⇓ OP1): The inductive hypotheses are

ie1 − s 7−→t − n1 s and ie2 − s 7−→t − n2 s

Then we have

ie1 op ie2 − s 7−→ ie2 : ie1 : op − s

by Lemma 4.2.5 and inductive hypotheses 7−→t ie1 : op n2 s

by Lemma 4.2.5 and inductive hypotheses 7−→t op n1 : n2 s

7−→ − n1 op n2 s

as required. We leave the reader to verify property closure of the remaining rules.

(⇐=): We prove each of the three right to left implications separately, by Mathematical

Induction. Note that the first is:

for all ie, n, s , ie − s 7−→t − n s =⇒ (ie , s) ⇓IExp n.

But this statement is logically equivalent to

for all k, for all ie, n, s , ie − s 7−→k − n s =⇒ (ie , s) ⇓IExp n

which you should check!! We prove the latter assertion by induction on k ∈ N, letting

Prop(k) denote the boxed proposition:

(Proof of Prop(0)): This is trivially true (why?).

Page 52: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

46 Chapter 4. The CSS Machine

(Proof of for all k0 ∈ N, Prop(k)k≤k0 =⇒ Prop(k0 + 1)): Suppose that for some arbitrary

k0, ie, n and s

ie − s 7−→k0+1 − n s (∗)

and then we prove (ie , s) ⇓IExp n by considering cases on ie.

(Case ie is m): If m 6= n then (∗) is false, so the implication is true. If m = n, note that

as (n , s) ⇓IExp n there is nothing to prove.

(Case ie is ie1 op ie2): Suppose that

ie1 op ie2 − s 7−→k0+1 − n s

and so

ie2 : ie1 : op − s 7−→k0 − n s .

Using Lemmas 4.2.6 and 4.2.7 we have that

ie2 − s 7−→k1 − n2 s

ie1 : op n2 s 7−→k2 − n s

where k1 + k2 = k0, and repeating for the latter transition we get

ie1 n2 s 7−→k21 − n1 : n2 s

op n1 : n2 s 7−→k22 − n s (1)

where k21 + k22 = k2. So as k1 ≤ k0, by Induction we deduce that (ie2 , s) ⇓IExp n2, and

from Lemma 4.2.7 that

ie1 − s 7−→k21 − n1 s .

Also, as k21 ≤ k0, we have Inductively that (ie1 , s) ⇓IExp n1 and hence

(ie1 op ie2 , s) ⇓IExp n1 op n2.

But from Lemma 4.2.4 and (1) we see that n1 op n2 = n and we are done.

We omit the remaining cases.

Note that the second right to left implication (dealing with Boolean expressions) involves

just the same proof technique.

The third right to left implication is (equivalent to):

for all k,

for all co, s , s ′ co − s 7−→k − σ s ′ =⇒ σ = − and (co , s) ⇓Com s ′

which you should check!! We prove the latter assertion by induction on k ∈ N, letting

Prop(k) denote the boxed proposition:

(Proof of Prop(0)): This is trivially true (why?).

Page 53: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

4.3. CSS Executions 47

(Proof of for all k0 ∈ N, Prop(k)k≤k0 =⇒ Prop(k0 + 1)): Choose arbitrary k0 ∈ N. We

shall show that if

for all co, s , s ′, co − s 7−→k − σ s ′ =⇒ σ = − and (co , s) ⇓Com s ′

for all k ≤ k0, then

for all co, s , s ′, co − s 7−→k0+1 − σ s ′ =⇒ σ = − and (co , s) ⇓Com s ′

Pick arbitrary co and σ and s , s ′ and suppose that

co − s 7−→k0+1 − σ s ′

We consider cases for co:

(Case co is x := ie): Using Lemma 4.2.4, we must have

x := ie − s 7−→1 ie : STO(x) − s 7−→k0 − σ s ′

and so by Lemmas 4.2.6 and 4.2.7

ie − s 7−→k1 − n s

STO(x) n s 7−→k2 − σ s ′ (1)

where k1 + k2 = k0. By determinism for (1) we have σ = − and s{x 7→n} = s ′. By the first

right to left implication for integer expressions (proved above) we have (ie , s) ⇓IExp n.

Hence (x := ie , s) ⇓Com s{x 7→n}, and as s{x7→n} = s ′ we are done. NB this case did not

make use of the inductive hypotheses Prop(k)k≤k0 !

(Case co is co ; co ′): Do this as an exercise!

The remaining cases are omitted. �

4.3 CSS Executions

Examples 4.3.1

(1) Let s be a state for which s(x) = 6. Then we have

10− x − s 7−→ x : 10 : − − s

7−→ 10 : − 6 s

7−→ − 10 : 6 s

7−→ − 4 s

where we have written − for both empty list and subtraction—care!

Page 54: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

48 Chapter 4. The CSS Machine

(2) Let s be a state for which s(x) = 1. Then we have

if x ≥ 0 then x := x− 1 else skip − s 7−→ x ≥ 0 : BR(x := x− 1, skip) − s

7−→ 0 : x ≥: BR(x := x− 1, skip) − s

7−→ x :≥: BR(x := x− 1, skip) 0 s

7−→ ≥: BR(x := x− 1, skip) 1 : 0 s

7−→ BR(x := x− 1, skip) T s

7−→ x := x− 1 − s

7−→ x− 1 : STO(x) − s

7−→ 1 : x : − : STO(x) − s

7−→ x : − : STO(x) 1 s

7−→ − : STO(x) 1 : 1 s

7−→ STO(x) 0 s

7−→ − − s{x 7→0}

Page 55: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

5

Elementary Domain Theory

5.1 Introduction

Motivation 5.1.1 We have seen how to give a denotational semantics to IMP . This

involved us dealing with partial functions between states. In particular, in order to model

a while loop, we needed a fixpoint of a certain function (between [States , States ]par and

itself). To choose that fixpoint, we introduced a partial order on the set of partial functions

between states. This is fine for a simple language such as IMP , but for more complex

languages we need to be able to choose fixpoints at a more abstract level, and this involves

dealing with more complex partial orders (recall the partial order on [States , States ]par is

really very simple, being given simply by the subset ⊆ relation).

We can achieve this abstraction by using Domain Theory. Basically, a domain is a certain

kind of partially ordered set for which we can guarantee that fixpoints of certain kinds

of functions always exist. These functions are called continuous. We will model recursive

programs as least fixpoints of continuous functions. In fact, in order to ensure that

whatever we are doing within our model, fixpoints always exist when we need them, all

of our programming language constructs (not just recursive programs) will be modelled

by continuous functions. Now, of course there are fewer continous functions than total

functions, but this does not present a problem as continous functions are sufficient to

model the kinds of programming languages we are interested in. Let us now introduce

continuous functions:

5.2 Cpos and Continuous Functions

Definitions 5.2.1 Recall that a partial order � on a set D is a binary relation on D

which is

• reflexive (for all d ∈ D, d � d);

• transitive (for all d, d′, d′′ ∈ D, d � d′ and d′ � d′′ implies d � d′′); and

• anti-symmetric (for d, d′ ∈ D, d � d′ and d′ � d implies d = d′).

A partially ordered set P is a pair (D,�) where D is any set and � is a partial order

on D. We often abbreviate partially ordered set to poset. We call D the underlying set

of the poset P . If d, d′ ∈ D are any two elements, we say that d and d′ are comparable if

either d � d′ or d′ � d. The two elements are incomparable if they are not comparable.

We shall often refer to a poset simply by naming its underlying set (so we might say

“consider the poset D”) and we shall use the same symbol � to denote the partial orders

on a variety of different posets (we might say that the symbol � has been overloaded).

Page 56: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

50 Chapter 5. Elementary Domain Theory

Definitions 5.2.2 A chain in a poset D is a function c : N→ D for which

c0 � c1 � c2 � . . .

where we write cn instead of the more usual notation c(n) for functions. This helps us to

think of the elements cn (where n ∈ N) as a “sequence” of elements of D which are indexed

by the natural numbers. We call each cn a link in the chain c. We shall often refer to a

chain in D by explicitly naming the elements in the image of the chain c : N → D, that

is, just naming the links of the chain. We might say “consider the chain

c0 � c1 � c2 � . . .

in D”. Finally, we may also say “consider the chain (cn | n ∈ N) in D” where the

notation indicates that we have specified a sequence of elements in D (but have not made

the ordering explicit).

Note that the image of c is a subset of D, that is

{ cn | n ∈ N } ⊆ D.

Thus we can consider the join (least upper bound) of this subset of D, which if it exists

will be denoted by∨∞n cn. So, recall that this means

for all d ∈ D,∞∨n=0

cn � d⇐⇒ ( for all n ∈ N, cn � d)

We refer to the element∨∞n=0 cn of D as the join of the chain c. A cpo is a poset D

which possesses a join for every chain c in D.

Examples 5.2.3

(1) The powerset P(A) of a set A which is partially ordered by ⊆ is a cpo. Given a chain

X0 ⊆ X1 ⊆ X2 . . . in A, its join is given by⋃∞n=0 Xn, that is

∞∨n=0

Xn =∞⋃n=0

Xn.

We check that⋃∞n=0Xn is indeed the least upper bound of the chain (Xn | n ∈ N). It is

trivially an upper bound: Xm ⊆⋃∞n=0 Xn holds by definition of union for each m ∈ N. So

we check that⋃∞n=0Xn is least. If U is any element of P(A) for which Xn ⊆ U for each

n ∈ N, then we need to verify that⋃∞n=0 Xn ⊆ U . This is trivial:

a ∈∞⋃n=0

Xn =⇒ a ∈ Xm for some m ∈ N =⇒ a ∈ U.

(2) The set [A,B]par of partial functions from A to B, partially ordered by ⊆, is a cpo

with joins given by union, just as in (i). It is an exercise to verify this.

Page 57: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

5.2. Cpos and Continuous Functions 51

(3) For any set A the relation of equality is a partial order:

for all a, a′ ∈ A, a � a′ ⇐⇒ a = a′

With this order, A is in fact a cpo. We call it the discrete cpo on A. So any chain c in

A must satisfy c0 = c1 = c2 = . . . and so∨∞n=0 cn = c0. Check this!

(4) Set N∞ def= N ∪ {∞}. We can define a partial order on N∞ by setting

for all x, x′ ∈ N∞, x � x′ ⇐⇒ (x, x′ ∈ N and x ≤ x′) or (x′ =∞).

We call N∞ the topped vertical natural numbers. Then it is an exercise to verify

that N∞ is a cpo. We can draw an informal Hasse diagram of N∞:

·····

3

2

1

0

Definitions 5.2.4 Recall that a function1 f : D → E between cpos is monotone if

for all d, d′ ∈ D, d � d′ =⇒ f(d) � f(d′)

(where of course f(d) � f(d′) refers to the partial order on E).

We say that f : D → E is continuous if it is monotone, and for all chains c in D we

have

f(∞∨n=0

cn) =∞∨n=0

f(cn) (∗)

Remark 5.2.5 We make two comments about the definition of continuity:

(i) Note that the composition f ◦ c : N→ E is indeed a chain2 since f is monotone, that

is (f(cn) | n ∈ N) is a chain in E. Thus the join on the right hand side of (∗) does exist.

(ii) For any m ∈ N we have cm �∨∞n=0 cn. Thus when f is monotone, f(cm) � f(

∨∞n=0 cn),

and so∞∨m

f(cm) � f(∞∨n=0

cn).

Thus (∗) holds if and only if f(∨∞n=0 cn) �

∨∞n=0 f(cn).

1In these notes, the adjectives monotone and continuous will only be applied to total functions; andwhenever we just talk of a “function” it is implicit that it is total, unless we specifically state that it ispartial.

2thus (f ◦ c)ndef= f(cn).

Page 58: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

52 Chapter 5. Elementary Domain Theory

Proposition 5.2.6

(i) The function idDdef= λd∈D.d : D → D is continuous.

(ii) The composition g ◦ f def= λd∈D.g(f(d)) : D → F of continuous functions f : D → E

and g : E → F is continuous.

(iii) If D is a discrete cpo, then any function f : D → E is continuous.

Proof An exercise. �

5.3 Constructions on Cpos

Motivation 5.3.1 You will be familiar with various procedures for building up new sets

from certain given sets, for example we can construct the cartesian product A×B given

the sets A and B. We can perform similar operations with cpos replacing sets, which we

now describe. All of these constructions will be used in giving a denotational semantics

to the languages which appear later on in the course.

Binary Product

Definitions 5.3.2 Given cpos D1 and D2, their binary product has underlying set

which is the usual (cartesian) binary product D1 ×D2 with a partial order defined by

for all d1, d′1 ∈ D1, d2, d

′2 ∈ D2, (d1, d2) � (d′1, d

′2)⇐⇒ d1 � d′1 and d2 � d′2.

This poset is indeed a cpo: let us see that joins of all chains exist. Suppose that c : N→D1 ×D2 is a chain, where each cn is an element of D1 ×D2 which we denote by (c1

n, c2n).

It is easy to see that each of (c1n | n ∈ N) and (c2

n | n ∈ N) is a chain in D1 and D2

respectively. Then it is the case that

∞∨n=0

cn = (∞∨n=0

c1n,

∞∨n=0

c2n)

where the joins on the right exist as each of D1 and D2 is a cpo. It is an exercise for you

to check this.

There are continuous projection functions given by

fst : D1 ×D2 → D1 fst(d1, d2)def= d1

snd : D1 ×D2 → D2 snd(d1, d2)def= d2

Given continuous functions f1 : E → D1 and f2 : E → D2 there is a continuous function3

denoted by 〈f1, f2〉 : E → D1 ×D2 which is defined by 〈f1, f2〉(e)def= (f1(e), f2(e)).

3Care! Note that 〈f1, f2〉 ∈ [E,D1 ×D2]cts and that (f1, f2) ∈ [E,D1]cts × [E,D2]cts .

Page 59: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

5.3. Constructions on Cpos 53

Given continuous functions f1 : E1 → D1 and f2 : E2 → D2 there is a continuous function

denoted by f1 × f2 : E1 × E2 → D1 ×D2 which is defined by

f1 × f2def= 〈f1 ◦ fst , f2 ◦ snd〉.

Thus it follows that (f1 × f2)(e1, e2) = (f1(e1), f2(e2)).

Examples 5.3.3 An informal Hasse diagram of N∞ × N∞:

(∞,∞)

........

...... ..............

.......

........

..... .................

.......

........

..... .................

...

(0,∞)....

........

. .................(2, 2) ....

........

.....

(∞, 0)

.............

.............(1, 2)

.............(2, 1)

........

.....

........

.....

(0, 2)

.............(1, 1) (2, 0)

........

.....

(0, 1) (1, 0)

(0, 0)

n-ary Product

Definitions 5.3.4 Suppose that D1, D2, . . . Dn are each cpos, where n is a finite non-

zero natural number. We can extend the definition of binary product to the case of n

cpos. There is a cpo denoted either by D1 × D2 × . . . × Dn or often by Πi=ni=1Di whose

underlying set consists of n-tuples of elements

Πi=ni=1Di

def= { (d1, . . . , dn) | di ∈ Di }

with an order defined by

(d1, . . . , dn) � (d′1, . . . , d′n) ⇐⇒ for all i ∈ { 1, . . . , n }, di � d′i

Thus, informally, two n-tuples are related by � in Πi=ni=1Di if and only if each of their

respective components are related in the appropriate cpo Di. We shall write ~d as an

abbreviation for (d1, . . . , dn) when no confusion can result.

Page 60: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

54 Chapter 5. Elementary Domain Theory

There are continuous projection functions proj i : Πi=ni=1Di → Di given by (d1, . . . , dn) 7→

di. Thus in the case that n = 2 we have fst = proj 1 and snd = proj 2. We sometimes

write proj i(t) as ti when t ∈ Πi=ni=1Di.

We write Dn to denote the cpo

D × . . .×D︸ ︷︷ ︸n-times

Finally, we let D0 denote the one-point cpo { ∗ } (where ∗ is some arbitrary element).

Cpos of Continuous Functions

Definitions 5.3.5 Suppose that D and E are cpos. Then the cpo of continuous functions

denoted by [D,E]cts has underlying set4

{ f | f ∈ [D,E]tot and f is continuous }

with a partial order given by

f � f ′ ⇐⇒ for all d ∈ D, f(d) � f ′(d).

Joins of chains in [D,E]cts are given pointwise: Suppose that c : N→ [D,E]cts is a chain,

so that each cn is a continuous function between D and E. Then

∞∨n=0

cn = λd∈D.∞∨n=0

cn(d),

that is, if we write fdef=∨∞n=0 cn, then f(d) =

∨∞n=0 cn(d) for any d ∈ D. You should check

the details of these definitions and assertions very carefully!

There is a continuous function ev : [D,E]cts×D → E which is defined by ev(f, d)def= f(d).

We call ev the evaluation function. Finally, given a continuous function g : D′×D → E

there is a continuous function cur(g) : D′ → [D,E]cts where for each d′ ∈ D′ we have

cur(g)(d′)def= λd∈D.g(d′, d). We call cur(g) the currying of g. Note that the following

equation is a simple consequence of the definitions:

g = ev ◦ (cur(g)× idD).

Proposition 5.3.6 The function ev : [D,E]cts ×D → E is continuous. Let the function

g : D′ ×D → E be continuous. Then cur(g) : D′ → [D,E]cts is also continuous.

Suppose that h : D′ → D is continuous, and that E is a cpo. Then the function h∗ :

[D,E]cts → [D′, E]cts defined by h∗(f)def= f ◦ h is continuous.

Proof A routine exercise. �4Thus [D,E]cts ⊆ [D,E]tot ; any continuous (total) function is certainly a total function.

Page 61: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

5.3. Constructions on Cpos 55

Bottom Elements

Definitions 5.3.7 Recall from MC150 that a bottom element of a poset D is an

element ⊥ ∈ D satisfying ⊥ � d for each element d ∈ D. If D has a bottom element, say

⊥, then this is unique. For suppose that ⊥′ were also a bottom element. Then we have

⊥′ � ⊥ and also ⊥ � ⊥′ and thus by anti-symmetry ⊥ = ⊥′. We may write ⊥D for the

bottom element of D.

Examples 5.3.8

(1) The poset P(A) has a bottom, namely ∅.

(2) The set of partial functions [A,B]par has a bottom, namely the totally undefined

function, ∅ ⊆ A×B.

(3) The discrete cpo on a set A has a bottom iff A has exactly one element.

(4) Clearly 0 is a bottom of the cpo N∞.

(5) Suppose that D1 and D2 are cpos, each with bottom, in which both bottoms are

denoted by ⊥. Then D1 × D2 is also a cpo with bottom, with (⊥,⊥) as the bottom

element. Check this!

(6) If D and D′ are cpos, and D′ is also a cpo with bottom, then the set of continuous

functions [D,D′]cts is a cpo with bottom. The bottom element is given by the function

λd∈D.⊥, that is the function which maps each d ∈ D to ⊥ ∈ D′.

(7) Now go back over each of these examples with pencil and paper and make sure you

really understand all of the missing details!!

Lifted Cpos

Definitions 5.3.9 Suppose that D is a cpo. The lifted cpo D⊥ has underlying set

D⊥def= { [d] | d ∈ D } ∪ {⊥}

where we assume that d 7→ [d] is an injection, and ⊥ 6= [d] for any d ∈ D. The partial

order is given by

x � x′ ⇐⇒

either x = ⊥

or there exists d, d′ ∈ D, x = [d] and x′ = [d′] and d � d′

Thus ⊥ is a bottom of D⊥, and the injection

ιdef= λd∈D.[d] : D → D⊥

is order reflecting which means that for any d, d′ ∈ D, whenever [d] � [d′] then d � d′.

Page 62: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

56 Chapter 5. Elementary Domain Theory

If f : D → E is a continuous function where E is a cpo with bottom and D is a cpo, then

there is a continuous function f⊥ : D⊥ → E given by

f⊥(x)def=

{f(d) if x = [d] for some d ∈ D

⊥ if x = ⊥

We call f⊥ the lift of the function f . Note that we have f⊥ ◦ ι = f , which you may find

helpful to picture as a diagram of functions:

Df- E

D⊥

ι

?f⊥

-

Finally, note that there is a continuous function lift : [D,E]cts → [D⊥, E]cts which is

defined by lift(f)def= f⊥. Thus lift maps a continuous function f to its lift. Of course, we

should check that all of our assertions about continuity are true; we summarise things in

the next proposition:

Proposition 5.3.10 Let D and E be cpos, let E have a bottom, and let f :D → E be

continuous. Then

(i) The injection ι : D → D⊥ is continuous.

(ii) The function f⊥ : D⊥ → E is continuous.

(iii) The function lift : [D,E]cts → [D⊥, E]cts is continuous.

Proof We prove (iii) and leave (i) and (ii) as exercises. Suppose that (cn | n ∈ N) is a

chain in [D,E]cts (so that each cn is a continuous function between D and E). We wish

to prove that lift(∨∞n=0 cn) =

∨∞n=0 lift(cn), that is

(∞∨n=0

(cn))⊥ =∞∨n=0

(cn)⊥ : D⊥ −→ E (†)

Let x ∈ D⊥ be arbitrary. If x = ⊥, note that (cn)⊥(⊥) = ⊥ for each n ∈ N and so

(∞∨n=0

cn)⊥(x) = (∞∨n=0

cn)⊥(⊥) = ⊥ =∞∨n=0

(cn)⊥(⊥) =∞∨n=0

(cn)⊥(x) = (∞∨n=0

(cn)⊥)(x).

If x = [d], note that (cn)⊥(x) = cn(d) and so

(∞∨n=0

cn)⊥(x) = (∞∨n=0

cn)(d) =∞∨n=0

cn(d) =∞∨n=0

(cn)⊥(x) = (∞∨n=0

(cn)⊥)(x).

Thus as x was arbitrary, (†) holds. �

Page 63: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

5.3. Constructions on Cpos 57

Examples 5.3.11

(1) A Hasse diagram for B⊥ = {T ,F }⊥:

[T ] [F ]

(2) We can regard the set of integers Z as a discrete cpo, rather than as a poset with the

“usual” vertical ordering. Thus we have n � m if and only if n = m for all n,m ∈ Z.

Then an informal Hasse diagram for Z is

. . . −2 −1 0 1 2 . . .

and we call the cpo Z with the discrete partial order the flat integers.

An informal Hasse diagram for the lifted flat integers Z⊥ is

. . . [−2] [−1] [0] [1] [2] . . .

. . . . . .

Definitions 5.3.12 Suppose that f : D1 ×D2 × . . .×Dn → E is a continuous function

where E is a cpo with bottom, and the Di are cpos. Then there is a continuous function

f⊥Di: D1 ×D2 × . . .× (Di)⊥ × . . .×Dn −→ E

which is defined by the mapping

(d1, . . . , x, . . . , dn) 7→

{f(d1, . . . , di, . . . , dn) if x = [di] for some di ∈ Di

⊥E if x = ⊥Di

We say that f has been lifted on the ith component. We can extend this idea to a

multiple number of arguments; we just illustrate for n = 3. If f : D1×D2×D3 → E, then

f⊥D1,⊥D3

: (D1)⊥×D2× (D3)⊥ → E is the function which maps (x1, d2, x3) to ⊥E if either

x1 or x3 is bottom, or if x1 = [d1] and x3 = [d3] then f⊥D1,⊥D3

(x1, d2, x3) = f(d1, d2, d3).

If we lift f on all its components, then we write f~⊥ for the lifted function.

Examples 5.3.13 Let p : Z× Z× Z→ Z⊥ be defined by p(x, y, z) = [x+ y + z] where

Z⊥ and Z are the lifted flat integers, and flat integers. Convince yourself that the product

cpo Z× Z× Z is discrete. Note that

p~⊥ : Z⊥ × Z⊥ × Z⊥ −→ Z⊥

and that we have for example p~⊥(⊥,⊥,⊥) = ⊥, p~⊥([2], [4],⊥) = ⊥ and p~⊥([2], [5], [8]) =

[15]. Verify that p~⊥ is continuous!

Page 64: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

58 Chapter 5. Elementary Domain Theory

Conditional Functions

Definitions 5.3.14 If we regard B as a discrete cpo, then for each cpo D there is a

conditional function

cond : B×D ×D −→ D

whose value at any triple (b, d, d′) ∈ B×D ×D is given by

cond (b, d, d′)def=

{d if b = T

d′ if b = F

Least Fixed Points

Motivation 5.3.15 Suppose that D is a cpo with bottom and that f : D → D is

continuous. Let us think about the elements ⊥, f(⊥), f 2(⊥)def= f(f(⊥)), f 3(⊥) . . . and

so on. Note that

⊥ � f(⊥) since ⊥ is a bottom

f(⊥) � f(f(⊥)) = f 2(⊥) since f is monotone

f 2(⊥) � f 3(⊥) since f is monotone

... etc etc

Thus ⊥ � f(⊥) � f 2(⊥) � . . . is a chain in D and so we may define

fix (f)def=

∞∨n=0

fn(⊥)

where f 0(⊥)def= ⊥ and fn+1(⊥)

def= f(fn(⊥)).

Now, as f is continuous, we have

f(fix (f)) =∞∨n=0

f(fn(⊥)) =∞∨n=0

fn+1(⊥).

But it is trivial to see that the join∨∞n=0 f

n+1(⊥) must be equal to the join∨∞n=0 f

n(⊥)

(just think about the definition of a join) and so

f(fix (f)) = fix (f).

Thus fix (f) is indeed a fixpoint of f . If f(d) � d, we call d a prefixpoint of f . Note

that for such a d ∈ D, fn(⊥) � fn(d) � d and so∨∞n=0 f

n(⊥) � d, that is fix (f) � d. In

particular, if f(d) = d, then f(d) � d and so fix (f) � d. Thus fix (f) is the least element

in the set of prefixpoints of f , and also the least element in the set of all fixpoints of f .

Page 65: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

5.4. Denotational Semantics of IMP 59

Theorem 5.3.16 Given a cpo with bottom D and a continuous function f : D → D,

then f has a least fixpoint which is given by

fix (f)def=

∞∨n=0

fn(⊥)

where f 0(⊥)def= ⊥ and fn+1(⊥)

def= f(fn(⊥)). Thus f(fix (f)) = fix (f), and for any d ∈ D

if f(d) = d then fix (f) � d. Moreover, if f(d) � d then fix (f) � d.

Proof See above. �

Motivation 5.3.17 We summarise all of the results of this section in Table 5.1.

5.4 Denotational Semantics of IMP

Motivation 5.4.1 We can now complete the results of Chapter 3 by proving Proposi-

tion 3.2.12.

Proof The relation � defined on [States , States⊥]tot on page 34 coincides (on restriction

to the continuous functions) with the partial ordering on the set of continuous functions

[States , States⊥]cts , where States is the discrete cpo on the set of states, and States⊥is the lifted cpo. Check the coincidence!! Note that [States , States⊥]cts is a cpo with

bottom, as States⊥ (trivially) has a bottom. Hence Proposition 3.2.12 is a special case of

Theorem 5.3.16, provided that

Φ : [States , States⊥]tot −→ [States , States⊥]tot

is continuous. Recall that

Φ = λg∈[States,States⊥]tot .λs∈States.cond ([[be]](s), g⊥([[co]](s)), [s ]).

Now consider the following function Γ:

[States , States⊥]cts × Statescond ◦ 〈[[be]] ◦ snd , ev ◦ (([[co]]∗ ◦ lift)× idStates), ι ◦ snd〉

- States⊥

where

ev : [States , States⊥]tot × States −→ States⊥

and

cond : B× States⊥ × States⊥ −→ States⊥.

If (g, s) is an arbitrary element in [States , States⊥]cts × States it is easy to check that

Γ(g, s) = Φ(g)(s). Thus of course Φ = cur(Γ). It follows from Table 5.1 that Φ is indeed

continuous, because the functions

[[be]] : States → B and [[co]] : States → States⊥

are continuous as States is discrete, and thus Φ is built up from continuous functions.

Page 66: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

60 Chapter 5. Elementary Domain Theory

Suppose that D, E, F , D1, D2, . . . Dn are each cpos, that S is a set regarded as adiscrete cpo, and that we have continuous functions

l : D′ → D f : D → E g : E → F

k : D1 ×D2 → E ( fi : E → Di 1 ≤ i ≤ n )

k′ : Πi=ni=1Di → E

Then the following functions (which are built out of the above functions) are alsocontinuous:

(i) idD : D → D.

(ii) g ◦ f : D → F .

(iii) h : S → D where h is any function between S and the underlying set of D.

(iv) h : D → E where h is any constant function such that h(d)def= e0 for all d ∈ D

and fixed e0 ∈ E.

(v) l∗ : [D,E]cts → [D′, E]cts .

(vi) fst : D × E → D and snd : D × E → E.

(vii) proj i : Πi=ni=1Di → Di.

(viii) 〈f1, . . . , fn〉 : E → Πni=1Di.

(ix) ev : [D,E]cts ×D → E.

(x) cur(k) : D1 → [D2, E]cts .

(xi) ι : D → D⊥.

(xii) f⊥ : D⊥ → E provided E has a bottom.

(xiii) k′~⊥: Πn

i=1(Di)⊥ → E provided E has a bottom.

(xiv) lift : [D,E]cts → [D⊥, E]cts provided E has a bottom.

(xv) cond : B×D ×D → D.

Table 5.1: Properties of Continuous Functions

Page 67: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

6

Operational Semantics of Functional Languages

6.1 Introduction

Motivation 6.1.1 In this chapter we turn our attention to functional programming

languages. Such languages provide a syntax of expressions in which one can write down

functions directly, much as they appear in mathematics, without having to think about

how to code them as commands acting on a state. In fact the simple functional languages

we meet here do not have any kind of state: a program is an expression which potentially

denotes a value which can be returned to the programmer. The operational semantics

gives rules for reducing programs to values. In this chapter we shall study the syntax and

operational semantics of four small functional programming languages.

6.2 Types and Expressions for FUNe

Motivation 6.2.1 We begin by defining the types and expressions of a simple language

called FUNe . (We shall assume that readers have some familiarity with the datatypes of

functions, pairs and lists. If not, consult the course notes for MC 208.) We then briefly

recall the idea of a functional programming language. Such a language provides a syntax

within which one can write down functions much as we do in mathematics. The language

has no concept of state. Every expression of the language can be thought of as a data-

value (as against, say, a command) and the language executes by simplifying complex

expressions to much simpler expressions. The simpler expressions are returned as output

to the programmer.

Definitions 6.2.2 The types of the language FUNe are given by the grammar

σ ::= int | bool | σ → σ | (σ, σ) | [σ]

We shall write Type for the set of types. Thus FUNe contains the types of integers,

Booleans, (higher order) functions, (binary) products and lists. We shall write

σ1 → σ2 → σ3 → . . .→ σn → σ

for

σ1 → (σ2 → (σ3 → ( . . .→ (σn → σ) . . .))).

Thus for example σ1 → σ2 → σ3 means σ1 → (σ2 → σ3).

Let Var be a fixed set of variables. We shall also need a fixed set of function identifiers

FId , with typical elements denoted by F. These symbols will be used to define higher

order functions in FUNe —compare

Page 68: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

62 Chapter 6. Operational Semantics of Functional Languages

Fxx ′ = x + x ′ in FUNe to fxy=x+y in Miranda.

The expressions of the functional language FUNe are given by the grammar1

E ::= x variables| c constant| F function identifier| E1 op E2 operator| if E1 then E2 else E3 conditional| (E1,E2) pairing| fst(E ) first projection| snd(E ) second projection| E1 E2 function application| nilσ empty list| hd(E ) head of list| tl(E ) tail of list| E1 : E2 cons for lists| elist(E ) test for empty list

Remark 6.2.3 We shall adopt a few conventions to make expressions more readable:

• The expressions of the language are in fact finite trees. We have not bothered to make

this explicit, as we assume the reader is by now used to this fact. For example, fst(E)

denotes a tree whose root is a constructor symbol fst and whose single immediate subtree

is E. Note that the formal definition of expressions as (certain obvious) finite trees makes

various desirable equations hold. Thus for example if fst(E1) ≡ fst(E2), then we must

have E1 ≡ E2 (make sure you understand this!).

• In general, we shall write our “formal” syntax in an informal manner, using brackets

“(” and “)” to disambiguate where appropriate—recall that in Miranda one can add such

brackets to structure programs. So for example, if we apply E2 to E3 to get E2 E3, and

then apply E1 to the latter expression, we write this as E1 (E2 E3).

• E1E2E3 . . .En is shorthand for (. . . ((E1E2)E3) . . .) En. We say that application asso-

ciates to the left. For example, E1E2E3 is short for (E1 E2) E3. Note that if we made the

tree structure of applications explicit, rather than using the sugared notation E E ′ instead

of, say, ap(E ,E ′), then (E1 E2) E3 would be a shorthand notation for the tree denoted by

ap(ap(E1,E2),E3).

• The integer valued integer operators also associate to the left; thus we will write (for

example) n + m + l to mean (n + m) + l, with the obvious extension to a finite number

of integer constants.

• The cons constructor associates to the right. So, for example, we shall write E1 : E2 : E3

for E1 : (E2 : E3). This is what one would expect—the “head of the list” is appended

to the “tail of the list”. (Recall that lists such as [1, 4, 6], which one often finds in real

languages, would correspond to the FUNe list 1 : 4 : 6 : nilint).

1As usual, op∈ {+,−, ∗,≤, < }. If E1 represents a function f , and E2 an argument a, then E1 E2

represents f(a).

Page 69: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

6.2. Types and Expressions for FUNe 63

• Try writing out each of the general expression forms as finite trees.

Definitions 6.2.4 For an expression E , the set fvar(E ) consists of the variables which

appear in E . Being a set, a variable may appear in E many times, but is only recorded

once in fvar(E ). We could give a formal recursive definition of fvar(E ) using the inductive

definition of E , but we do not bother with this. We shall also talk of the function identifiers

which appear in E . Again, we do not bother with a formal definition, as there are no

technical difficulties such as bound function identifiers in our simple setting.

If E and E1, . . . ,En are expressions, then E [E1, . . . ,En/x1, . . . , xn] denotes the expression

E with Ei replacing xi for each 1 ≤ i ≤ n. (We omit the proof that the finite tree

E [E1, . . . ,En/x1, . . . , xn] is indeed an expression).

Examples 6.2.5 Examples of expressions are

(1) x ;

(2) hd(2 : 4);

(3) x (x y);

(4) x : 2 : 3.

(5) F2 3.

(6) fvar(x : (2 + y + y) : (z x)) = {x, y, z }.

(7) (xy : 2 : z)[F, 2 + 3, z/x, y, z] = F(2 + 3) : 2 : z.

Definitions 6.2.6 A context Γ is a finite set of (variable, type) pairs, where the type

is a FUNe type, and the variables are required to be distinct so that one does not assign

two different types to the same variable. So for example Γ = { (x1, σ1), . . . , (xn, σn) }. We

usually write a typical pair (x , σ) as x :: σ, and a typical context as

Γ = x1 :: σ1, . . . , xn :: σn.

Note that a context is by definition a set, so the order of the xi :: σi does not matter

and we omit curly braces simply to cut down on notation. We write Γ,Γ′def= Γ ∪ Γ′ and

Γ, x :: σdef= Γ ∪ {x :: σ }.

A function arity is a type of the form σ1 → σ2 → σ3 → . . . → σk → σ where k is a

non-zero natural number. You should think of such a function arity as typing information

for a function identifier: the function takes k inputs with types σi and gives an output of

type σ. We shall denote function arities by the Greek letter α.

A function environment is specified by a finite set of (function identifier, function

arity) pairs, with a typical function environment being denoted by

∆ = F1 :: α1, . . . ,Fm :: αm.

Page 70: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

64 Chapter 6. Operational Semantics of Functional Languages

We say that αi is the function arity of Fi, and that if αi is

σ1 → σ2 → σ3 → . . .→ σk → σ

then we refer to k as the numerical arity of Fi.

We shall say that a variable x appears in a context Γ if x :: σ ∈ Γ for some type σ. Thus

z appears in x :: int, y :: [bool], z :: int→ int. We shall similarly say that a type appears in

a context, or that a function identifier or arity appears in a function environment.

Example 6.2.7 A simple example of a function environment is

∆def= map :: (int→ int)→ [int]→ [int], suc :: int→ int

which declares the arities of the map function and the successor function. Note that

(int → int) → [int] → [int] is the function arity of map; its numerical arity is 2. Another

simple example of a function environment is plus :: (int, int)→ int.

Motivation 6.2.8 Given a context Γ of typed variables, and a function environment

∆, we can build up expressions E which use only variables and function identifiers which

appear in Γ and ∆. This is how we usually write (functional) programs: we first declare

variables and types, possibly also functions and types, and then write our program E

which uses these data. We shall define judgements of the form ∆ | Γ ` E :: σ which

should be understood as follows: given the function environment ∆, and the context Γ

of variable typings, then the expression E is well formed and has type σ. Given ∆ and

Γ, we say that E is assigned the type σ. We call ∆ | Γ ` E :: σ a type assignment

relation.

Definitions 6.2.9 We shall inductively define a type assignment (ternary) relation which

takes the form ∆ | Γ ` E :: σ using the rules in Table 6.1.

Proposition 6.2.10 If ∆ | Γ ` E :: σ, then the function identifiers which appear in E

appear in ∆, and the variables which appear in E appear in Γ.

Suppose that ∆,∆′ is a function environment, that Γ,Γ′ is a context, and that ∆ | Γ `E :: σ. Then in fact ∆,∆′ | Γ,Γ′ ` E :: σ is also a derivable type assignment.

Proof Follows by a simple Rule Induction. Exercise! �

Remark 6.2.11 Note that if ∆ | Γ ` E :: σ, then ∆ and Γ may contain function

identifiers and variables which do not (necessarily) appear in E. For example

F :: int→ int | x :: int, y :: int, z :: int ` Fx :: int

is a valid type assignment. The motto is “just because we declared some variables or

function identifiers, does not mean we need to program with them”.

Note that the second part of the previous proposition says that “given any type assign-

ment, we can add function identifiers to the function environment, and variables to the

context, without changing the type of E .” Sometimes this is called weakening.

Page 71: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

6.2. Types and Expressions for FUNe 65

( where x :: σ ∈ Γ) ` VAR

∆ | Γ ` x :: σ`INT

∆ | Γ ` n :: int

`TRUE

∆ | Γ ` T :: bool`FALSE

∆ | Γ ` F :: bool

∆ | Γ ` E1 :: int ∆ | Γ ` E2 :: int( where op is integer valued ) ` OP1

∆ | Γ ` E1 op E2 :: int

∆ | Γ ` E1 :: int ∆ | Γ ` E2 :: int( where op is Boolean valued ) ` OP2

∆ | Γ ` E1 op E2 :: bool

∆ | Γ ` E1 :: bool ∆ | Γ ` E2 :: σ ∆ | Γ ` E3 :: σ`COND

∆ | Γ ` if E1 then E2 else E3 :: σ

∆ | Γ ` E1 :: σ2 → σ1 ∆ | Γ ` E2 :: σ2`AP

∆ | Γ ` E1 E2 :: σ1

∆ | Γ ` E1 :: σ1 ∆ | Γ ` E2 :: σ2`PAIR

∆ | Γ ` (E1,E2) :: (σ1, σ2)

∆ | Γ ` E :: (σ1, σ2)`FST

∆ | Γ ` fst(E ) :: σ1

∆ | Γ ` E :: (σ1, σ2)`SND

∆ | Γ ` snd(E ) :: σ2

( where F :: α ∈ ∆) `FAP

∆ | Γ ` F :: α

`NIL

∆ | Γ ` nilσ :: [σ]

∆ | Γ ` E1 :: σ ∆ | Γ ` E2 :: [σ]`CONS

∆ | Γ ` E1 : E2 :: [σ]

∆ | Γ ` E :: [σ]`HD

∆ | Γ ` hd(E ) :: σ

∆ | Γ ` E :: [σ]`TL

∆ | Γ ` tl(E ) :: [σ]

∆ | Γ ` E :: [σ]`ELIST

∆ | Γ ` elist(E ) :: bool

Table 6.1: Type Assignment Relation ∆ | Γ ` E :: σ in FUNe

Page 72: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

66 Chapter 6. Operational Semantics of Functional Languages

Proposition 6.2.12 Given a function environment ∆, a context Γ and an expression E ,

if there is a type σ for which ∆ | Γ ` E :: σ, then such a type is unique. Thus FUNe is

monomorphic.

Proof We can prove this using Rule Induction. In fact we verify that

for all ∆ | Γ ` E :: σ1, for all σ2, (∆ | Γ ` E :: σ2 =⇒ σ1 = σ2).

We check property closure for the rule HD: The inductive hypothesis is that

for all σ2, (∆ | Γ ` E :: σ2 =⇒ [σ] = σ2)

where ∆ | Γ ` E :: [σ]. We wish to prove that

for all σ2, (∆ | Γ ` hd(E ) :: σ2 =⇒ σ = σ2)

where ∆ | Γ ` hd(E ) :: σ.

Let σ2 be arbitrary, where ∆ | Γ ` hd(E ) :: σ2. Then we must have ∆ | Γ ` E :: [σ2].

From the inductive hypothesis we see that [σ] = [σ2]. It follows that σ = σ2 as required.

Property closure of the remaining rules is left as an exercise. �

Examples 6.2.13

(1) With ∆ as in Example 6.2.7, we have

∆ | x :: int, y :: int, z :: int ` map suc (x : y : z : nilint) :: [int]

(2) We have

twicehead :: [int]→ int→ (int, int) | y :: [int], x :: int ` twicehead y x :: (int, int)

(3) We have

∅ | ∅ ` if T then fst((2 : nilint, nilint)) else (2 : 6 : nilint) :: [int]

6.3 Function Declarations and Programs for FUNe

Motivation 6.3.1 A function declaration is a method for declaring that certain function

identifiers have certain meanings. We look at two examples:

We begin by specifying a function environment, such as plus :: (int, int) → int or fac ::

int→ int. Then to declare that plus is a function which takes a pair of integers and adds

them, we write plus x = fst(x )+ snd(x ). To declare that fac denotes the factorial function,

we would like

fac x = if x < 1 then 1 else x ∗ fac(x − 1)

Page 73: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

6.3. Function Declarations and Programs for FUNe 67

Thus in general, if F is a function identifier, we might write Fx = E where E is an

expression which denotes “the result” of applying F to x . In FUNe , we are able to specify

statements such as Fx = E which are regarded as preliminary data to writing a program—

we declare the definitions of certain functions. The language is then able to provide the

user with functions F whose action is specified by the expression E . Each occurrence of

F in program code executes using its declared definition. This is exactly like Miranda.

In general, a function declaration will specify the action of a finite number of function

identifiers, and moreover the definitions can be mutually recursive—each function may

be defined in terms of the others. Note that the factorial function given above is defined

recursively: the identifier fac actually appears in the expression giving “the result” of the

function.

A program in FUNe is an expression in which there are no variables and each of the

function identifiers appearing in the expression have been declared. The idea is that a

program is an expression in which there is no “missing data” and thus the expression

can be “evaluated” as it stands. A value is an “evaluated program”. It is an expression

which has a particularly simple form, such as an integer, or a list of integers, and thus is

a sensible item of data to return to a user. We now make all of these ideas precise.

Definitions 6.3.2 A function declaration dec∆, where ∆ = F1 :: α1, . . . ,Fm :: αm is

a given, fixed, function environment for which

αj = σj1 → σj2 → σj3 → . . .→ σjkj → σj

consists of the following data:

F1 x11 . . . x1k1 = EF1 where ∆ | x11 :: σ11, . . . , x1k1 :: σ1k1 ` EF1 :: σ1

F2 x21 . . . x2k2 = EF2 where ∆ | x21 :: σ21, . . . , x2k2 :: σ2k2 ` EF2 :: σ2...

Fj xj1 . . . xjkj = EFjwhere ∆ | xj1 :: σj1, . . . , xjkj :: σjkj ` EFj

:: σj...

Fm xm1 . . . xmkm = EFm where ∆ | xm1 :: σm1, . . . , xmkm :: σmkm ` EFm :: σm

Note that the data which are specified in dec∆ just consist of the declarations Fj~x =

EFj; the type assignments just need to hold of the specified EFj

. We shall sometimes

abbreviate the jth type assignment to ∆ | ΓFj` EFj

:: σj. We call the expression EFjthe

definitional body of Fj. Note that the type assignments force each of the variables in

{ xj1, . . . , xjkj } to be distinct (for each j ∈ { 1, . . . ,m }).We define a program expression P to be any expression for which fvar(P) = ∅, that

is, no variables occur in P . A program in FUNe is a judgement of the form

dec∆ in P

where dec∆ is a given function declaration and the program expression P satisfies a type

assignment of the form

∆ | ∅ ` P :: σ.

Page 74: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

68 Chapter 6. Operational Semantics of Functional Languages

We may sometimes simply refer to P as a program, when no confusion can arise from

this. We call σ the type of the program dec∆ in P (and sometimes just say σ is the

type of P).

Examples 6.3.3

(1) Let ∆ = F1 :: [int] → int → int,F2 :: int → int. Then an example of a function

declaration dec∆ isF1x11x12 = hd(tl(tl(x11))) + F2x12

F2x21 = x21 ∗ x21

Note that here we labelled the variables with subscripts to match the general definition

of function declaration—in future we will not bother to do this. It is easy to see that the

declaration is well defined: for example ∆ | x21 :: int ` x21 ∗ x21 :: int.

(2) Let ∆ be F :: int→ int→ int→ int. Then we have a declaration dec∆

Fx y z = x+ y + z

where of course ∆ | x :: int, y :: int, z :: int ` x+ y + z :: int.

(3) The next few examples are all programs

F x = if x ≤ 1 then 1 else x ∗ F (x − 1) in F 4

(4)

F1 x y z = if x ≤ 1 then y else z

F2 x = F1 x 1 (x ∗ F2 (x − 1))

}in F2 4

(5)

Ev x = if x = 0 then T else Od (x − 1)

Od x = if x = 0 then F else Ev (x − 1)

}in Ev 12

Note that Ev and Od are defined by mutual recursion, and that they only correctly de-

termine the evenness or oddness of non-negative integers. How would you correct this

deficiency?

(6) F x = F x in F (3 : nilint) is a program which does not evaluate to a value; the

program loops.

6.4 Operational Semantics for FUNe

Definitions 6.4.1 Let dec∆ be a function declaration. A value expression is any

expression V which can be produced by the following grammar

V ::= c | nilσ | (V ,V ′) | Fj ~V | V : V ′

Page 75: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

6.4. Operational Semantics for FUNe 69

where c is any Boolean or integer, σ is any type, and ~V is an application of the form

V1 V2 . . . Vl−1 Vl where 0 ≤ l < kj, and kj is the numerical arity of Fj. Note that l

is strictly less than kj. See Remark 6.4.4. A value is any value expression for which

dec∆ in V is a valid FUNe program.

Motivation 6.4.2 The operational semantics of FUNe gives rules for proving that a

program P evaluates to a value V within a given function declaration dec∆. For any

given function declaration, we write this as dec∆ ` P ⇓e V , and a trivial example is, say,

dec∆ ` 3 + 4 + 10 ⇓e 17.

This is an eager or call-by-value language. This means that when expressions are evalu-

ated, their arguments (or sub-expressions) are fully evaluated before the whole expression

is evaluated. We give a couple of examples:

In evaluating a function application FP1P2 we first compute values for P1 and P2, say V1

and V2, and then evaluate FV1V2. In evaluating a pair (P1,P2), we compute values for

P1 and P2, say V1 and V2, giving a final value of (V1,V2).

Definitions 6.4.3 We shall define an evaluation relation whose judgements will take

the form

dec∆ ` P ⇓e V

where P and V are respectively a program expression and value expression whose function

identifiers appear in the function declaration dec∆. The rules for inductively generating

these judgements are given by the rules in Table 6.2.

Remark 6.4.4 You may find the definition of F~V as a value expression rather odd. In

fact, there is good reason for the definition. The basic idea behind the definition of a value

is that “values are those expressions which are as fully evaluated as possible, according to

the call-by-value execution strategy”. This explains why F~V is indeed a value expression;

a small example will clarify:

Suppose that

F :: int→ int→ int→ int,

and that P1 and P2 are integer programs, which compute to the values n1 and n2. Then

FP1 is not a value, because the language is eager. It will evaluate to Fn1. But this latter

expression cannot be evaluated any further—informally, the function F cannot itself be

called until it is applied to three integer arguments. Thus Fn1 is a value. Giving it the

argument P2, we have a program Fn1 P2 which evaluates to the value Fn1 n2. Again, we

have a value, as the expression cannot be computed any further. Finally, however, we can

supply a third argument to Fn1 n2 giving Fn1 n2 P3. This evaluates to Fn1 n2 n3, and at

last F has its full quota of three arguments—thus the latter expression is not a value as

we can now compute the function F using rule ⇓e FAP.

Examples 6.4.5

Page 76: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

70 Chapter 6. Operational Semantics of Functional Languages

⇓eVAL

dec∆ ` V ⇓e V

dec∆ ` P1 ⇓e m dec∆ ` P2 ⇓e n⇓eOP

dec∆ ` P1 op P2 ⇓e m op n

dec∆ ` P1 ⇓e T dec∆ ` P2 ⇓e V⇓eCOND1

dec∆ ` if P1 then P2 else P3 ⇓e V

dec∆ ` P1 ⇓e F dec∆ ` P3 ⇓e V⇓eCOND2

dec∆ ` if P1 then P2 else P3 ⇓e V

dec∆ ` P1 ⇓e V1 dec∆ ` P2 ⇓e V2⇓ePAIR

dec∆ ` (P1,P2) ⇓e (V1,V2)

dec∆ ` P ⇓e (V1,V2)⇓eFST

dec∆ ` fst(P) ⇓e V1

dec∆ ` P ⇓e (V1,V2)⇓eSND

dec∆ ` snd(P) ⇓e V2

{dec∆ ` P1 ⇓e F ~V dec∆ ` P2 ⇓e V2 dec∆ ` F ~V V2 ⇓e V

where either P1 or P2 is not a value⇓eAP

dec∆ ` P1 P2 ⇓e V

dec∆ ` EFj[V1, . . . ,Vkj/x1, . . . , xkj ] ⇓

e V[Fj~x = EFj

declared in dec∆] ⇓eFAP

dec∆ ` FjV1 . . .Vkj ⇓e V

dec∆ ` P ⇓e nilσ⇓eNIL

dec∆ ` tl(P) ⇓e nilσ

dec∆ ` P ⇓e V : V ′

⇓eHD

dec∆ ` hd(P) ⇓e V

dec∆ ` P ⇓e V : V ′

⇓eTL

dec∆ ` tl(P) ⇓e V ′

dec∆ ` P1 ⇓e V dec∆ ` P2 ⇓e V ′

⇓eCONS

dec∆ ` P1 : P2 ⇓e V : V ′

dec∆ ` P ⇓e nilσ⇓eELIST1

dec∆ ` elist(P) ⇓e T

dec∆ ` P ⇓e V : V ′

⇓eELIST2dec∆ ` elist(P) ⇓e F

Table 6.2: Evaluation Relation dec∆ ` P ⇓e V in FUNe

Page 77: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

6.4. Operational Semantics for FUNe 71

(1) With F as in the last remark, the expressions F 2 and F 2 3 are (programs and) values.

F 2 3 (4 + 1) is a program, but not a value: the function F has numerical arity three, and

can now be evaluated.

(2) Let dec∆ be that of Examples 6.3.3 part (2). Then we can prove that

dec∆ ` F 2 3 (4 + 1) ⇓e 10

as follows:

F 2 3 ⇓e F 2 3

4 ⇓e 4 1 ⇓e 1

4 + 1 ⇓e 5 T⇓e AP

F 2 3 (4 + 1) ⇓e 10

where T is the tree

2 ⇓e 2 3 ⇓e 3

2 + 3 ⇓e 5 5 ⇓e 5

2 + 3 + 5 ⇓e 10===========================

(x+ y + z)[2, 3, 5/x, y, z] ⇓e 10⇓e FAP

F 2 3 5 ⇓e 10

Note that we have omitted all occurrences of dec∆ ` in the tree above to save space—

please feel free to do the same when you write down such deductions of evaluations. It is

an exercise to fill in the missing labels on the rules.

(3) Consider the program large x = 1+ large x in fst((3, large 0)). If we attempt to prove

that this program evaluates to a value V , the deduction tree takes the form:

3 ⇓e V

...

1 + large 0 ⇓e V ′

large 0 ⇓e V ′

(3, large 0) ⇓e (V, V ′)

fst((3, large 0)) ⇓e V

for some value V ′. It is easy to see that no finite deduction exists, and so there is no value

V for which dec∆ ` fst((3, large 0)) ⇓e V . Informally, we cannot take the first component

of the pair without first evaluating its sub-expressions, as FUNe is eager. Compare this

evaluation to the execution of the same program in the lazy FUNl on page 73.

Theorem 6.4.6 Let dec∆ be a function declaration. The evaluation relation for FUNe

is deterministic in the sense that if a program evaluates to a value, that value is unique.

More precisely, for all P , V1 and V2, if

dec∆ ` P ⇓e V1 and dec∆ ` P ⇓e V2

then V1 = V2.

Page 78: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

72 Chapter 6. Operational Semantics of Functional Languages

Proof We prove by Rule Induction that

for all dec∆ ` P ⇓e V1, for all V2, (dec∆ ` P ⇓e V2 =⇒ V1 = V2)

The routine details are omitted. �

Theorem 6.4.7 Evaluating a program dec∆ in P does not alter its type. More

precisely,

(∆ | ∅ ` P :: σ and dec∆ ` P ⇓e V ) =⇒ ∆ | ∅ ` V :: σ

for any P , V , σ and ∆. The conservation of type during program evaluation is called

subject reduction.

Proof We prove by Rule Induction that

for all dec∆ ` P ⇓e V ∀σ(∆ | ∅ ` P :: σ =⇒ ∆ | ∅ ` V :: σ).

The proof is omitted �

6.5 The Language FUNl

Motivation 6.5.1 The language FUNl is identical to FUNe , except that it has a lazy

operational semantics. We explain below exactly what this means. The expressions,

contexts, function environments, function declarations and type assignments of FUNl

are exactly the same as for FUNe . In a nutshell, we can say that the definition of the

relationships ∆ | Γ ` E :: σ for FUNl is specified by the rules in Table 6.1.

6.6 Operational Semantics for FUNl

Motivation 6.6.1 The operational semantics of FUNl is lazy or call-by-name. This

means that certain expressions can be evaluated before their subexpressions are computed.

This method of computation applies to functions, pairs and lists. This has the advantage

that if any of the subexpressions are not required in the computation of the expression,

then no time is lost evaluating the subexpression. Lazy refers to the fact that the language

does not bother to compute subexpressions if it does not need to. The definition of program

is the same as before. We shall need a different notion of value in FUNl . We give the

new definition of value, and then give the lazy operational semantics of FUNl .

Definitions 6.6.2 Let dec∆ be a function declaration. A value expression is any

expression V which can be produced by the following grammar

V ::= c | nilσ | (P ,P ′) | Fj ~P | P : P ′

where c is any Boolean or integer, σ is any type, P and P ′ are any program expressions,

and ~P is an application of the form PP1 P2 . . . Pl−1 Pl where 0 ≤ l < kj, and kj is the

numerical arity of Fj. Note that l is strictly less than kj.

A value is any value expression for which dec∆ in V is a valid FUNl program.

Page 79: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

6.6. Operational Semantics for FUNl 73

Definitions 6.6.3 We shall define an evaluation relation whose judgements will take

the form

dec∆ ` P ⇓l V

where P and V are respectively a program expression and value expression whose function

identifiers appear in the function declaration dec∆. The rules for inductively generating

these judgements are given by the rules in Table 6.3.

Examples 6.6.4

(1) Recall Examples 6.4.5. Consider the program large x = 1 + large x in fst((3, large 0))

once again. Let us try to see if this program evaluates to a value, say V . Working the

rules in Table 6.3 backwards, there must be P1 and P2 and rules R and R′ such that we

haveR

(3, large 0) ⇓l (P1,P2)R′

P1 ⇓l V⇓l FST

fst((3, large 0)) ⇓l V

and clearly we have a valid (finite) deduction tree when P1 is 3, P2 is large 0, V is 3 and

R and R′ are both instances of ⇓l VAL. In the lazy language, we can extract the first

component of a pair without having first to compute the second component.

(2) Let ∆ be F :: int → [int], and dec∆ be Fx = x : F (x + 2). Then there is a program

dec∆ in hd(tl(F 1)). We prove that dec∆ ` hd(tl(F 1)) ⇓l 3.

1 : F (1 + 2) ⇓l 1 : F (1 + 2)⇓l FAP

F 1 ⇓l 1 : F (1 + 2) T

tl(F 1) ⇓l (1 + 2) : F ((1 + 2) + 2)

1 ⇓l 1 2 ⇓l 2

1 + 2 ⇓l 3

hd(tl(F 1)) ⇓l 3

where T is the tree

⇓l VAL

(1 + 2) : F ((1 + 2) + 2) ⇓l (1 + 2) : F ((1 + 2) + 2)

F (1 + 2) ⇓l (1 + 2) : F ((1 + 2) + 2)

It is an exercise to check this deduction tree is correct, adding in the labels for the rules.

Why might we call F 1 the lazy list of odd numbers? Try evaluating F 1 using the eager

semantics. What happens?

Theorem 6.6.5 The language FUNl is monomorphic, deterministic, and satisfies sub-

ject reduction.

Proof The proofs of these facts are basically the same as for FUNe and are omitted.

Page 80: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

74 Chapter 6. Operational Semantics of Functional Languages

⇓lVAL

dec∆ ` V ⇓l Vdec∆ ` P1 ⇓l m dec∆ ` P2 ⇓l n

⇓lOP

dec∆ ` P1 op P2 ⇓l m op n

dec∆ ` P1 ⇓l T dec∆ ` P2 ⇓l V⇓lCOND1

dec∆ ` if P1 then P2 else P3 ⇓l V

dec∆ ` P1 ⇓l F dec∆ ` P3 ⇓l V⇓lCOND2

dec∆ ` if P1 then P2 else P3 ⇓l V

dec∆ ` P ⇓l (P1,P2) dec∆ ` P1 ⇓l V⇓lFST

dec∆ ` fst(P) ⇓l V

dec∆ ` P ⇓l (P1,P2) dec∆ ` P2 ⇓l V⇓lSND

dec∆ ` snd(P) ⇓l V

{dec∆ ` P1 ⇓l F ~P dec∆ ` F ~P P2 ⇓l V

where either P1 or P2 is not a value⇓lAP

dec∆ ` P1 P2 ⇓l V

dec∆ ` EFj[P1, . . . ,Pkj/x1, . . . , xkj ] ⇓

l V[Fj~x = EFj

declared in dec∆] ⇓lFAP

dec∆ ` FjP1 . . .Pkj ⇓l V

dec∆ ` P ⇓l nilσ⇓lNIL

dec∆ ` tl(P) ⇓l nilσ

dec∆ ` P1 ⇓l P2 : P3 dec∆ ` P2 ⇓l V⇓lHD

dec∆ ` hd(P1) ⇓l V

dec∆ ` P1 ⇓l P2 : P3 dec∆ ` P3 ⇓l V⇓lTL

dec∆ ` tl(P1) ⇓l V

dec∆ ` P ⇓l nilσ⇓lELIST1

dec∆ ` elist(P) ⇓l T

dec∆ ` P1 ⇓l P2 : P3⇓lELIST2

dec∆ ` elist(P1) ⇓l F

Table 6.3: Evaluation Relation dec∆ ` P ⇓l V in FUNl

Page 81: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

6.7. The Language TURe and its Operational Semantics 75

6.7 The Language TURe and its Operational Semantics

Motivation 6.7.1 The language TURe is basically a simplified version of FUNe . We

introduce it because giving a denotational semantics to FUNe is rather too tricky for

an undergraduate course. We shall study a denotational semantics of TURe in the next

chapter.

Definitions 6.7.2 The types of the language TURe are given by the grammar

σ ::= int | bool.

(So all expressions in TURe will be either integers or Booleans).

Let Var be a fixed set of variables. The expressions of the functional language TURe

are given by the grammar

E ::= x variables| c constant| E op E ′ operator| if E then E ′ else E ′′ conditional| F(E1, . . . ,Ek) k-ary functions

where k ranges over the non-zero natural numbers.

Remark 6.7.3 In this language, an expression such as F(E1,E2,E3) is not “an appli-

cation of F to a triple”. The language TURe does not have application expressions, or

pairing, or indeed tuples of any kind. All it has is expressions of the form F(E1, . . . ,Ek)

which are intended to be the result of a function identifier F acting on k arguments. Such

an expression denotes a tree of the form

F

.8

E1 E2

�E3

. . . Ek

-

We also intend such function identifiers to act only on integer expressions and to only

return integer expressions. The reason for this rather gross simplification is simply to

make the presentation of material in the next chapter as simple as possible, while still

retaining the essential ideas.

Definitions 6.7.4 A function arity is now a natural number k ∈ N. This reflects

the intended meaning of function identifiers—we only need to specify the number of their

arguments, and not the types (which are assumed to be of type int).

Page 82: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

76 Chapter 6. Operational Semantics of Functional Languages

( where x :: int ∈ Γ) ` VAR

∆ | Γ ` x :: int`INT

∆ | Γ ` n :: int

`TRUE

∆ | Γ ` T :: bool`FALSE

∆ | Γ ` F :: bool

∆ | Γ ` E1 :: int ∆ | Γ ` E2 :: int( where op is integer valued ) ` OP1

∆ | Γ ` E1 op E2 :: int

∆ | Γ ` E1 :: int ∆ | Γ ` E2 :: int( where op is Boolean valued ) ` OP2

∆ | Γ ` E1 op E2 :: bool

∆ | Γ ` E1 :: bool ∆ | Γ ` E2 :: σ ∆ | Γ ` E3 :: σ`COND

∆ | Γ ` if E1 then E2 else E3 :: σ

∆ | Γ ` E1 :: int . . . ∆ | Γ ` Ek :: int`FAP

∆,F :: k | Γ ` F(E1, . . . ,Ek) :: int

Table 6.4: Type Assignment Relation ∆ | Γ ` E :: σ in TURe

A function environment is specified by a finite set of (function identifier, function

arity) pairs, with a typical function environment being denoted by

∆ = F1 :: k1, . . . ,Fm :: km.

We shall inductively define a type assignment (ternary) relation which takes the form

∆ | Γ ` E :: σ using the rules in Table 6.4.

Definitions 6.7.5 A function declaration dec∆, where ∆ = F1 :: k1, . . . ,Fm :: km is

a given, fixed, function environment consists of the following data:

F1(x11, . . . , x1k1) = EF1 where ∆ | x11 :: int, . . . , x1k1 :: int ` EF1 :: intF2(x21, . . . , x2k2) = EF2 where ∆ | x21 :: int, . . . , x2k2 :: int ` EF2 :: int

...Fj(xj1, . . . , xjkj) = EFj

where ∆ | xj1 :: int, . . . , xjkj :: int ` EFj:: int

...Fm(xm1, . . . , xmkm) = EFm where ∆ | xm1 :: int, . . . , xmkm :: int ` EFm :: int

We define a program expression P in TURe to be any expression for which fvar(P) =

∅, that is, no variables occur in P . A program in TURe is a judgement of the form

dec∆ in P

Page 83: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

6.8. The Language TURl and its Operational Semantics 77

⇓eVAL

dec∆ ` c ⇓e cdec∆ ` P1 ⇓e m dec∆ ` P2 ⇓e n

⇓eOP

dec∆ ` P1 op P2 ⇓e m op n

dec∆ ` P1 ⇓e T dec∆ ` P2 ⇓e c⇓eCOND1

dec∆ ` if P1 then P2 else P3 ⇓e c

dec∆ ` P1 ⇓e F dec∆ ` P3 ⇓e c⇓eCOND2

dec∆ ` if P1 then P2 else P3 ⇓e c

{dec∆ ` P1 ⇓e n1 . . . dec∆ ` Pkj ⇓e nkjdec∆ ` EFj

[n1, . . . , nkj/x1, . . . , xkj ] ⇓e n[Fj(~x) = EFj

declared in dec∆] ⇓eFAP

dec∆ ` Fj(P1, . . . ,Pkj ) ⇓e n

Table 6.5: Evaluation Relation dec∆ ` P ⇓e c in TURe

where dec∆ is a given function declaration and the program expression P satisfies a type

assignment of the form

∆ | ∅ ` P :: σ

where σ is of course either int or bool. We may sometimes simply refer to P as a program,

when no confusion can arise from this. We call σ the type of the program dec∆ in P

(and sometimes just say σ is the type of P).

A value is any c where c is any Boolean or integer.

Definitions 6.7.6 We shall define an evaluation relation whose judgements will take

the form

dec∆ ` P ⇓e c

where P and c are respectively a program expression and value. The rules for inductively

generating these judgements are given by the rules in Table 6.5. Note that the operational

semantics is eager.

Theorem 6.7.7 The language TURe is monomorphic, deterministic with respect to the

evaluation relation, and subject reduction holds.

Proof The proof method is identical to that for FUNe , and indeed the details are pretty

much the same. It is an exercise to provide some of the details of the appropriate Rule

Inductions. �

6.8 The Language TURl and its Operational Semantics

Definitions 6.8.1 The expressions, contexts, function environments, function declara-

tions and type assignments of TURl are exactly the same as for TURe . In a nutshell, we

Page 84: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

78 Chapter 6. Operational Semantics of Functional Languages

⇓lVAL

dec∆ ` c ⇓l cdec∆ ` P1 ⇓l m dec∆ ` P2 ⇓l n

⇓lOP

dec∆ ` P1 op P2 ⇓l m op n

dec∆ ` P1 ⇓l T dec∆ ` P2 ⇓l c⇓lCOND1

dec∆ ` if P1 then P2 else P3 ⇓l c

dec∆ ` P1 ⇓l F dec∆ ` P3 ⇓l c⇓lCOND2

dec∆ ` if P1 then P2 else P3 ⇓l c

dec∆ ` EFj[P1, . . . ,Pkj/x1, . . . , xkj ] ⇓

l n[Fj(~x) = EFj

declared in dec∆] ⇓lFAP

dec∆ ` Fj(P1, . . . ,Pkj ) ⇓l n

Table 6.6: Evaluation Relation dec∆ ` P ⇓l c in TURl

can say that the definition of the relationships ∆ | Γ ` E :: σ for TURl are specified by

the rules in Table 6.4.

The operational semantics is (slightly) different. We shall define an evaluation relation,

whose relationships will be written dec∆ ` P ⇓l V , via the rules given in Table 6.6. Note

that this is a lazy language.

Theorem 6.8.2 The language TURl is monomorphic, deterministic with respect to the

evaluation relation, and subject reduction holds.

Proof The proof method is as usual. �

Examples 6.8.3 Show that the program

large(x ) = 1 + large(x )

const(x ) = 4

}in const(large(0))

evaluates to 4 in TURl , but does not evaluate to a value in TURe .

In TURl we have⇓lVAL

4 ⇓l 4=============4[large(0)/x] ⇓l 4

⇓lFAP

const(large(0)) ⇓l 4

The case of TURe is an exercise.

Page 85: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

7

The Denotational Semantics of Functional Languages

7.1 Introduction

Motivation 7.1.1 We shall now present a denotational semantics for TURe . The basic

idea behind this kind of semantics is just the same as for IMP . Such a semantics can

be thought of as a mathematical model, in which we attempt to abstract away from

the operational details of the programming language, seeing the crucial concepts of the

language appearing in a very general setting. We shall see that the method of modelling

the recursion present in the operational semantics of a while be do co loop in IMP is

just the same as the method of modelling recursive function declarations in TURe —by

fixpoints of continuous functions. Thus we have a framework in which two apparently

different languages, with quite distinct operational semantics, can in fact be seen to be

quite similar.

7.2 Denotations for Type Assignments in TURe

Motivation 7.2.1 Let us think about how we might model the type assignment

F :: 1 | x :: int ` E :: int.

The type assignment indicates that E is an expression containing the identifier F and the

variable x . Thus E “depends” on F and x . Now, x is of type int so we could model x

by specifying an integer e in Z. Also, F is of type int → int and we could model this by

giving a function between Z and Z, that is a function f in [Z,Z]tot . We can then regard

the meaning of E as a function (call it h) which acts on the meanings of F and x , namely

f and e, and returns an integer (as E has type int). So we could require h to take the

pair (f, e) as input and return an integer h(f, e) as output. Thus

h : ([Z,Z]tot × Z) −→ Z (∗)

is a function which we can regard as the meaning of F :: 1 | x :: int ` E :: int.

These ideas need refining. First, F may “represent” a recursive program which can loop.

Thus we really need to model it as a partial function on integers. As we have seen, it is

easier to think about functions between Z and Z⊥. Similarly, E is an expression whose

operational behaviour may constitute a loop, so its meaning ought also to be a partial

function. Moreover, E may contain recursively defined functions. As we have seen, we

can model such recursion using fixpoints, and in order to ensure that these exist we have

to deal with continuous functions. We can regard Z as a discrete cpo, and then the set

Page 86: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

80 Chapter 7. The Denotational Semantics of Functional Languages

of total functions [Z,Z⊥]tot coincides with the set of continuous functions [Z,Z⊥]cts . We

shall partially order this latter set of continuous functions just as we did in on page 54,

and moreover we have a cpo

[Z,Z⊥]cts × Z

defined using the definitions in Section 5.3. So in fact we should ask that

h : [Z,Z⊥]cts × Z −→ Z⊥

be a continuous function (which is a refinement of (∗)).If in fact F :: k, then we can model F as a function which acts on a k-tuple of integers,

and returns an integer. The meaning of F is thus a continuous function from Zk to Z⊥,

that is an element of [Zk,Z⊥]cts . The latter is of course also a cpo—see Section 5.3.

What about modelling ∆ = F1 :: k1, . . . ,Fm :: km? It seems sensible to model this as an

m-tuple of functions, say (f1, . . . , fm) where each fj models Fj. Thus fj ∈ [Zkj ,Z⊥]cts and

~f = (f1, . . . , fm) ∈ Πj=mj=1 [Zkj ,Z⊥]cts

Similarly, we can model Γ = x1 :: int, . . . , xn :: int as an n-tuple of integers, say

~e = (e1, . . . , en) ∈ Zn

Putting this all together,

we can regard the meaning of ∆ | Γ ` E :: int as a function (say h) which takes ~f and ~e asinputs, and either returns an integer as output, or ⊥ if “E loops.” Thus

h : (Πj=mj=1 [Zkj ,Z⊥]cts)× Zn −→ Z⊥.

Remark 7.2.2

(i) In fact Πj=mj=1 [Zkj ,Z⊥]cts is a cpo with bottom. It has a bottom element given by

(λ~n∈Zk1 .⊥, . . . , λ~n∈Zkm .⊥)

where λ~n∈Zkj .⊥ : Zkj → Z⊥.

(ii) It may be helpful to spell out the definition of the partial order on Πj=mj=1 [Zkj ,Z⊥]cts

explicitly. If ~f, ~f ′ ∈ Πj=mj=1 [Zkj ,Z⊥]cts , then ~f � ~f ′ if and only if

for all j = 1, . . . ,m, for all (n1, . . . , nkj) ∈ Zkj ,

fj(n1, . . . , nkj) � f ′j(n1, . . . , nkj) in Z⊥

if and only if

for all j = 1, . . . ,m, for all (n1, . . . , nkj) ∈ Zkj , for all n ∈ Z

fj(n1, . . . , nkj) = [n] =⇒ f ′j(n1, . . . , nkj) = [n]

Page 87: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

7.2. Denotations for Type Assignments in TURe 81

[[∆ | Γ ` xi]](~f,~e)def= [ei]

[[∆ | Γ ` c]](~f,~e) def= [c]

[[∆ | Γ ` E1 op E2]](~f,~e)def= (ι ◦ op)~⊥ ([[∆ | Γ ` E1]](~f,~e) , [[∆ | Γ ` E2]](~f,~e))

[[∆ | Γ ` if E1 then E2 else E3]](~f,~e)def=

cond⊥B([[∆ | Γ ` E1]](~f,~e), [[∆ | Γ ` E2]](~f,~e), [[∆ | Γ ` E3]](~f,~e))

[[∆ | Γ ` Fj(E1, . . . ,Ekj )]](~f,~e)

def= (fj)~⊥([[∆ | Γ ` E1]](~f,~e), . . . , [[∆ | Γ ` Ekj ]](

~f,~e))

op : Z× Z −→ X

ι ◦ op : Z× Z −→ X⊥

(ι ◦ op)~⊥ : Z⊥ × Z⊥ −→ X⊥

cond⊥B : B⊥ ×X⊥ ×X⊥ −→ X⊥

fj : Zkj −→ Z⊥

(fj)~⊥ : (Z⊥)kj −→ Z⊥

X = Z or B

Table 7.1: Denotational Semantics [[∆ | Γ ` E ]] in TURe

(iii) If Γ = ∅ we take n = 0 and if ∆ = ∅ we take m = 0.

Definitions 7.2.3 Recall that in general, if exp is a syntactical expression in a program-

ming language, and we are intending to model exp as some mathematical entity, then we

shall write [[exp]] for the object modelling exp. We can think of [[exp]] as a semantical

explanation of exp, and we refer to [[exp]] as the denotational semantics of exp.

Thus for TURe , for each type assignment ∆ | Γ ` E :: σ (where σ is either int or bool)

we shall define a (continuous) function of the form

[[∆ | Γ ` E :: int]] : (Πj=mj=1 [Zkj ,Z⊥]cts × Zn) −→ Z⊥

or

[[∆ | Γ ` E :: bool]] : (Πj=mj=1 [Zkj ,Z⊥]cts × Zn) −→ B⊥.

We do this recursively, using the rules in Table 7.1, where we denote a typical element of

(Πj=mj=1 [Zkj ,Z⊥]cts)× Zn by (~f,~e). Note that because TURe enjoys subject reduction, we

omit the type of E in each of the judgements defining the denotational semantics. You

may like to recall the notation of Section 5.3. Note that in this chapter we sometimes use

prefix notation for operators op. Thus, for example, ≤(6, 8) = T .

Page 88: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

82 Chapter 7. The Denotational Semantics of Functional Languages

Example 7.2.4 Set ∆def= suc :: 1,F′ :: 4. So

[[∆ | x :: int, y :: int ` x ≤ y ]] : ([Z,Z⊥]cts × [Z4,Z⊥]cts)× Z2 −→ B⊥

and we have m = 2, k1 = 1, k2 = 4 and n = 2. Then

[[∆ | x :: int, y :: int ` x ≤ y ]]((f, f ′), (4, 3))

= (ι◦ ≤)~⊥ ([[∆ | x :: int, y :: int ` x ]]((f, f ′), (4, 3)) , [[∆ | x :: int, y :: int ` y ]]((f, f ′), (4, 3)))

= (ι◦ ≤)~⊥ ([4] , [3])

= (ι◦ ≤) (4 , 3)

= [4 ≤ 3]

= [F ] ∈ B⊥.

What role, if any, do the function identifiers play?

Proposition 7.2.5 Each function [[∆ | Γ ` E ]] is indeed continuous.

Proof (Please see page 60). This is proved by induction on the derivation of ∆ | Γ `E :: σ. The base cases are when E is a variable or constant. In the first case, the denota-

tional function is a projection, hence continuous, and in the second case, the denotational

function is constant, hence continuous. In the inductive cases, the denotational functions

are built up from continuous functions, using continuity preserving operations. �

Remark 7.2.6 Recall that programs P satisfy type assignments of the form ∆ | ∅ `P :: σ. Thus their denotations are functions of the form

[[∆ | ∅ ` P ]] : (Πj=mj=1 [Zkj ,Z⊥]cts)× Z0 −→ X⊥

where X is Z or B depending on σ. Now Z0 is the cpo with just one element, say { ∗ }.Thus the previous function essentially determines a function of the form

g : Πj=mj=1 [Zkj ,Z⊥]cts −→ X⊥

where g(~f)def= [[∆ | ∅ ` P ]](~f, ∗). From now on we shall abuse notation, and consider

program denotations as functions of the form

[[∆ | ∅ ` P ]] : Πj=mj=1 [Zkj ,Z⊥]cts −→ X⊥.

Similarly, if Γ has n variables, we shall take

[[∅ | Γ ` E ]] : Zn −→ X⊥

with X as above.

Page 89: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

7.3. Denotations of Function Declarations and Programs in TURe 83

7.3 Denotations of Function Declarations and Programs in TURe

Motivation 7.3.1 We aim to give a denotational model of programs dec∆ in P .

First we need to give a model of a function declaration dec∆. Roughly, the idea behind

modelling dec∆ is this: Each function in the declaration is determined by its definitional

body. Further, each function may be recursive. We can give a denotation to the function

bodies using Table 7.1. We can then form the tuple of functions modelling the declaration

bodies. Then the denotation of the function declaration is given by the fixpoint of the

tuple function.

Definitions 7.3.2 Suppose that dec∆ is a typical function declaration for TURe

F1(x11, . . . , x1k1) = EF1

F2(x21, . . . , x2k2) = EF2

...Fj(xj1, . . . , xjkj) = EFj

...Fm(xm1, . . . , xmkm) = EFm

where ∆ = F1 :: k1, . . . ,Fm :: km, and we let j run between 1 and m. We write ΓFjfor

xj1 :: int, . . . , xjkj :: int.

By Proposition 7.2.5 we know that each definitional body EFjdetermines a continuous

function

[[∆ | ΓFj` EFj

]] : Πj=mj=1 [Zkj ,Z⊥]cts × Zkj → Z⊥

and hence

Φjdef= cur([[∆ | ΓFj

` EFj]]) : Πj=m

j=1 [Zkj ,Z⊥]cts → [Zkj ,Z⊥]cts .

Thus there is a continuous function

Φdef= 〈Φ1, . . . ,Φm〉 : Πj=m

j=1 [Zkj ,Z⊥]cts −→ Πj=mj=1 [Zkj ,Z⊥]cts .

We can apply Theorem 5.3.16 to see that Φ has a least fixpoint

fix (Φ) ∈ Πj=mj=1 [Zkj ,Z⊥]cts .

With this, we define

[[dec∆]]def= fix (Φ) = fix (〈cur([[∆ | ΓF1 ` EF1 ]]), . . . , cur([[∆ | ΓFm ` EFm ]])〉).

Finally, we define the denotation of a program dec∆ in P to be

[[dec∆ in P ]]def= [[∆ | ∅ ` P ]]([[dec∆]]).

Examples 7.3.3

Page 90: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

84 Chapter 7. The Denotational Semantics of Functional Languages

(1) Let ∆ be P :: 2, and let dec∆ be P (x, y) = x+ y. Writing Γ for x :: int, y :: int, clearly

∆ | Γ ` x + y :: int. Note that, with respect to our general notation, we have m = 1,

1 ≤ j ≤ m, kj = k1 = 2, and n = 2. So

pdef= [[∆ | Γ ` x+ y :: int]] : [Z2,Z⊥]cts × Z2 −→ Z⊥.

If (f, (e, e′)) ∈ [Z2,Z⊥]cts × Z2, then

p(f, (e, e′)) = (ι ◦+)~⊥ ([[∆ | Γ ` x]](f, (e, e′)) , [[∆ | Γ ` y]](f, (e, e′)))

= (ι ◦+)~⊥ ([e] , [e′])

= [e+ e′]. (∗)

Now, [[dec∆]] is defined to be fix (Φ) where

Φdef= cur(p) : [Z2,Z⊥]cts −→ [Z2,Z⊥]cts .

But for any f ∈ [Z2,Z⊥]cts we have cur(p)(f) = λ(e,e′)∈Z2.[e + e′] using (∗). Thus Φ is a

constant function. Using this, it is trivial that for each n ≥ 0 ∈ N we have

Φn+1(⊥[Z2,Z⊥]cts )def= Φ(Φn(⊥[Z2,Z⊥]cts )) = λ(e,e′)∈Z2.[e+ e′]

and thus for all (e, e′) ∈ Z2

[[dec∆]](e, e′) =∞∨n=0

Φn(⊥[Z2,Z⊥]cts ) = [e+ e′].

Did you expect this?!? Note that the link Φ0(⊥[Z2,Z⊥]cts ) is ⊥[Z2,Z⊥]cts and every other link

in the chain (Φn(⊥[Z2,Z⊥]cts ) | n ∈ N) is the function λ(e,e′)∈Z2.[e+ e′].

(2) Let ∆ be F :: 1 and let dec∆ be

F(x ) = if x ≤ 1 then 1 else x ∗ F(x− 1).

Writing EF for the body of the function declaration, and Γ for x :: int we have

hdef= [[∆ | Γ ` EF]] : [Z,Z⊥]cts × Z −→ Z⊥.

If (f, e) ∈ [Z,Z⊥]cts × Z, then

h(f, e) = cond⊥B([[∆ | Γ ` x ≤ 1]](f, e) , [[∆ | Γ ` 1]](f, e) , [[∆ | Γ ` x ∗ F (x− 1)]](f, e))

= cond⊥B((ι◦ ≤)~⊥ ([[∆ | Γ ` x ]](f, e) , [[∆ | Γ ` 1]](f, e)) , [1] ,

(ι ◦ ∗)~⊥ ([[∆ | Γ ` x ]](f, e) , [[∆ | Γ ` F (x− 1)]](f, e)))

= cond⊥B((ι◦ ≤)~⊥ ([e] , [1]) , [1] , (ι ◦ ∗)~⊥ ([e] , f~⊥([[∆ | Γ ` x− 1]])(f, e)))

...

= cond⊥B([e ≤ 1] , [1] , (ι ◦ ∗)~⊥ ([e] , f~⊥((ι ◦ −)~⊥ ([e] , [1]))))

= cond⊥B([e ≤ 1] , [1] , (ι ◦ ∗)~⊥ ([e] , f~⊥([e− 1])))

= cond⊥B([e ≤ 1] , [1] , (ι ◦ ∗)~⊥ ([e] , f(e− 1)))

Page 91: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

7.3. Denotations of Function Declarations and Programs in TURe 85

Thus we have

h(f, e) =

[1] if e ≤ 1

[e ∗ e′] if e > 1 and f(e− 1) = [e′] for some e′ ∈ Z

⊥ if e > 1 and f(e− 1) = ⊥

(1)

We now claim that for each e ∈ Z, [[dec∆]] : Z→ Z⊥ where

[[dec∆]](e) = ξdef=

{[1] if e ≤ 1

[e ∗ (e− 1) ∗ . . . ∗ 1] if e > 1

Recall that [[dec∆]]def= fix (Φ) where Φ = cur(h). Now if we write ⊥[Z,Z⊥]cts for the bottom

element of [Z,Z⊥]cts , we have [[dec∆]] =∨∞n=1 Φn(⊥[Z,Z⊥]cts ) and so we will prove that for

any e ∈ Z,

ξ =∞∨n=1

Φn(⊥[Z,Z⊥]cts )(e) (2)

We claim that for each n ≥ 1,

Φn(⊥[Z,Z⊥]cts )(e) =

[1] if e ≤ 1

[e ∗ (e− 1) ∗ (e− 2) ∗ . . . ∗ 1] if 1 < e ≤ n

⊥ if n < e

Prop(n)

If Prop(n) holds for all n, then it is an exercise to verify that (2) follows. So we shall

now prove by induction that for all n ≥ 1, Prop(n). First note that Prop(1) holds, for

Φ(⊥[Z,Z⊥]cts )(e) = cur(h)(⊥[Z,Z⊥]cts )(e) = h(⊥[Z,Z⊥]cts , e) and thus using (1) we have

Φ(⊥[Z,Z⊥]cts )(e) =

{[1] if e ≤ 1

⊥ if e > 1

Now suppose inductively that Prop(n) holds for an arbitrary n. As Φn+1 def= Φ ◦ Φn we

have Φn+1(⊥[Z,Z⊥]cts )(e) = Φ(Φn(⊥[Z,Z⊥]cts ))(e) = h(Φn(⊥[Z,Z⊥]cts ), e), and so

Φn+1(⊥[Z,Z⊥]cts )(e) =

[1] if e ≤ 1

[e ∗ e′] if e > 1 and Φn(⊥[Z,Z⊥]cts )(e− 1) = [e′] some e′ ∈ Z

⊥ if e > 1 and Φn(⊥[Z,Z⊥]cts )(e− 1) = ⊥

But whenever e > 1, then1 by Prop(n)

Φn(⊥[Z,Z⊥]cts )(e− 1) = [e′] some e′ ∈ Z ⇐⇒ 1 < e− 1 ≤ n or e = 2

(and e′ = (e− 1) ∗ (e− 2) ∗ . . . ∗ 1) and

Φn(⊥[Z,Z⊥]cts )(e− 1) = ⊥ ⇐⇒ n < e− 1

1from where does e = 2 arise?

Page 92: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

86 Chapter 7. The Denotational Semantics of Functional Languages

Thus

Φn+1(⊥[Z,Z⊥]cts )(e) =

[1] if e ≤ 1

[e ∗ (e− 1) ∗ (e− 2) ∗ . . . ∗ 1] if 1 < e ≤ n+ 1

⊥ if n+ 1 < e

Thus Prop(n+ 1) holds and the induction is complete.

Let us finish by computing the denotation of dec∆ in F(3). We have

[[dec∆ in F(3)]] = [[∆ | ∅ ` F(3)]]([[dec∆]])

= [[dec∆]]⊥([[∆ | ∅ ` 3]]([[dec∆]]))

= [[dec∆]]⊥([3])

= [[dec∆]](3)

= [3 ∗ 2 ∗ 1]

= [6]

Did you expect this ?!?

7.4 Equivalence of Operational and Denotational Semantics

Motivation 7.4.1 We would like to prove a correspondence between the operational

and denotational semantics of TURe , which mimics correspondences such as

I(ie)(s) = n ⇐⇒ (ie , s) ⇓IExp n ⇐⇒ [[ie]](s) = n.

To this end, we set up some suitable notation, and then prove a correspondence theorem,

the latter making use of the next lemma.

Definitions 7.4.2 Let us define E(P)(dec∆) by

E(P)(dec∆)def=

{[c] if dec∆ ` P ⇓e c for some c ∈ Z ∪ B

⊥ otherwise

This gives us some notation for program evaluation. What about function declarations?

In view of Theorem 6.4.6, we can see that for any function declaration dec∆ and Fjappearing in ∆, then

{ ((n1 . . . , nkj), n) | dec∆ ` Fj(n1, . . . , nkj) ⇓e n }

defines a partial function in [Zkj ,Z]par which we denote by D(Fj)(dec∆). Equivalently, we

have defined a function D(Fj)(dec∆) : Zkj → Z⊥ for each Fj ∈ ∆ given by

D(Fj)(dec∆)(n1 . . . , nkj) =

{[n] if dec∆ ` Fj(n1, . . . , nkj) ⇓e n for some n ∈ Z

⊥ otherwise

Page 93: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

7.4. Equivalence of Operational and Denotational Semantics 87

Lemma 7.4.3 Suppose we have a type assignment of the form ∆ | Γ,Γ′ ` E :: int,

where Γ′ = yn+1 :: int, . . . , yn′ :: int. Then for any (e1, . . . , en, e′n+1, . . . , e

′n′) ∈ Zn+n′ and

~f ∈ Πj=mj=1 [Zkj ,Z⊥]cts we have

[[∆ | Γ ` E [e′n+1, . . . , e′n′/yn+1, . . . , yn′ ]]](~f, (e1, . . . , en)) =

[[∆ | Γ,Γ′ ` E ]](~f, (e1, . . . , en, e′n+1, . . . , e

′n′)).

Proof We use Rule Induction on the expression E . The details are omitted. �

Theorem 7.4.4 Let dec∆ be a given function declaration with ∆ = F1 :: k1, . . . ,Fm :: km.

We define

Ddec∆

def= (D(F1)(dec∆), . . . ,D(Fm)(dec∆))

and so (by definition) (Ddec∆)j = D(Fj)(dec∆).

(i) We have

[[dec∆]] = Ddec∆∈ Πj=m

j=1 [Zkj ,Z⊥]cts

that is,

[[dec∆]]j(n1 . . . , nkj) = [n] ⇐⇒ D(Fj)(dec∆)(n1 . . . , nkj) = [n].

(ii) We have

[[dec∆ in P ]] = E(P)(dec∆)

that is

[[∆ | ∅ ` P ]]([[dec∆]]) = [c] ⇐⇒ E(P)(dec∆) = [c].

Proof We shall prove the following statements:

(a) For all P and c,

E(P)(dec∆) = [c] =⇒ [[∆ | ∅ ` P ]]([[dec∆]]) = [c].

(b) Ddec∆� [[dec∆]] in Πj=m

j=1 [Zkj ,Z⊥]cts .

(c) [[dec∆]] � Ddec∆in Πj=m

j=1 [Zkj ,Z⊥]cts .

(d) For all P and c,

[[∆ | ∅ ` P ]]([[dec∆]]) = [c] =⇒ E(P)(dec∆) = [c].

The theorem follows trivially from the latter statements.

Page 94: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

88 Chapter 7. The Denotational Semantics of Functional Languages

(a) This part follows by an essentially routine Rule Induction; in particular we prove

for all dec∆ ` P ⇓e c, [[∆ | ∅ ` P ]]([[dec∆]]) = [c].

Let us consider property closure of the rule ⇓e FAP for some Fj. The inductive hypotheses

are

[[∆ | ∅ ` Pr]]([[dec∆]]) = [nr]

where 1 ≤ r ≤ kj and

[[∆ | ∅ ` EFj[n1, . . . , nkj/x1, . . . , xkj ]]]([[dec∆]]) = [n].

Then we have

[[∆ | ∅ ` Fj(P1, . . . ,Pkj)]]([[dec∆]])

= ([[dec∆]]j)~⊥([[∆ | ∅ ` P1]]([[dec∆]]), . . . , [[∆ | ∅ ` Pkj ]]([[dec∆]]))

= ([[dec∆]]j)~⊥([n1], . . . , [nkj ])

= [[dec∆]]j(n1, . . . , nkj)

=∗ cur([[∆ | ΓFj` EFj

]])([[dec∆]])(n1, . . . , nkj)

= [[∆ | ΓFj` EFj

]]([[dec∆]], (n1, . . . , nkj))

= [[∆ | ∅ ` EFj[n1, . . . , nkj/x1, . . . , xkj ]]]([[dec∆]])

= [n]

where step ∗ uses the fixpoint property of [[dec∆]] and the penultimate equality follows

from Lemma 7.4.3 (with n = 0 and n′ = kj).

(b) By definition of the partial order on the product cpo Πj=mj=1 [Zkj ,Z⊥]cts and the partial

order on each cpo [Zkj ,Z⊥]cts , we can see that Ddec∆� [[dec∆]] in Πj=m

j=1 [Zkj ,Z⊥]cts iff for

each j between 1 and m we have

D(Fj)(dec∆) � [[dec∆]]j in [Zkj ,Z⊥]cts ,

if and only if for all (n1 . . . , nkj) ∈ Zkj and n ∈ Z

dec∆ ` Fj(n1 . . . , nkj) ⇓e n =⇒ [[dec∆]]j(n1 . . . , nkj) = [n].

So suppose that dec∆ ` Fj(n1 . . . , nkj) ⇓e n. Then it follows by part (a) that

[[∆ | ∅ ` Fj(n1 . . . , nkj)]]([[dec∆]]) = [n].

But by definition of the denotational semantics we have

[[∆ | ∅ ` Fj(n1 . . . , nkj)]]([[dec∆]]) = [[dec∆]]j(n1 . . . , nkj)

as so part (b) follows.

Page 95: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

7.4. Equivalence of Operational and Denotational Semantics 89

(c) Because [[dec∆]] is defined as the least fixpoint of the function Φ : Πj=mj=1 [Zkj ,Z⊥]cts →

Πj=mj=1 [Zkj ,Z⊥]cts , to prove (c) it suffices to show that Ddec∆

is a prefixed point of Φ,

Φ(Ddec∆) � Ddec∆

in Πj=mj=1 [Zkj ,Z⊥]cts

that is, for each j between 1 and m we have

Φj(Ddec∆) � D(Fj)(dec∆) in [Zkj ,Z⊥]cts . (1)

Using the definition of Φj on page 83 and of D(Fj)(dec∆) we see that (1) holds if for all

(n1 . . . , nkj) ∈ Zkj and n ∈ Z

[[∆ | ΓFj` EFj

]](Ddec∆, (n1 . . . , nkj)) = [n] =⇒ dec∆ ` Fj(n1 . . . , nkj) ⇓e n (2)

and so by (⇓e FAP), we see that (2) holds if

[[∆ | ΓFj` EFj

]](Ddec∆, (n1 . . . , nkj)) = [n] =⇒ dec∆ ` EFj

[n1 . . . , nkj/~x] ⇓e n (3)

Instead of proving the previous statement we prove the following stronger statement (4)

and then deduce (3) from (4): For all E , (n1 . . . , nkj) and c,

[[∆ | ΓFj` E ]](Ddec∆

, (n1 . . . , nkj)) = [c] =⇒ dec∆ ` E [n1 . . . , nkj/~x] ⇓e c (4)

We prove (4) by Rule Induction on E . We shall look at just one case, when E is of the

form F′j′(E ′1, . . . ,E′kj′

). In this case we see that [[∆ | ΓFj` E ]](Ddec∆

, (n1 . . . , nkj)) = [c]

means that there are mr ∈ Z where 1 ≤ r ≤ kj′ for which

[[∆ | ΓFj` E ′r]](Ddec∆

, (n1 . . . , nkj)) = [mr] and (Ddec∆)j′(m1, . . . ,mkj′

) = [c]

Using the latter assertions we see that by induction we have for each r

dec∆ ` E ′r[n1 . . . , nkj/~x] ⇓e mr (5)

and that by definition of Ddec∆,

dec∆ ` Fj′(m1, . . . ,mkj′) ⇓e c (6)

Applying (⇓e FAP) to (5) and (6) we obtain

dec∆ ` Fj′(E ′1[n1, . . . , nkj/~x], . . . ,E ′kj′ [n1, . . . , nkj/~x])︸ ︷︷ ︸E [n1,...,nkj

/~x]

⇓e c

as required. We omit the other inductive cases. Therefore (4) holds and hence so does

(3).

(d) This is proved by Rule Induction on P . We shall just consider the induction step

when P is Fj(P ′1, . . . ,P′kj

). In this case, using the definition of the semantics, if

[[∆ | ∅ ` P ]]([[dec∆]]) = [c]

Page 96: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

90 Chapter 7. The Denotational Semantics of Functional Languages

then there must be mr where 1 ≤ r ≤ mkj for which

[[∆ | ∅ ` P ′r]]([[dec∆]]) = [mr] (7)

and

[[dec∆]]j(m1, . . . ,mkj) = [c] (8)

By induction, (7) gives

dec∆ ` P ′r ⇓e mr (9)

and by parts (b) and (c) we have [[dec∆]] = Ddec∆, so (8) gives

dec∆ ` Fj(m1, . . . ,mkj) ⇓e c (10)

Applying (⇓e FAP) to (9) and (10) we obtain dec∆ ` P ⇓e c as required, that is

E(P)(dec∆) = [c].

7.5 Further Denotational Semantics

Motivation 7.5.1 Consider a variable x :: int. In the lazy or call-by-name language, a

program, rather than a value, may be passed to a variable. This program may loop. Thus

we model a variable of type int as an element of Z⊥, rather than Z, with ⊥ modelling a

looping program.

Consider a function identifier F :: 1. In the language TURe , which is eager (call-by-value)

we thought of each F as acting on an integer value, and returning a possibly looping

program. Thus we modelled F as a function f : Z → Z⊥. In TURl , we think of F as

acting on an integer program and returning a possibly looping program. Thus there is

the possiblilty that the program which F acts on may itself loop and so we shall model F

by a function of the form Z⊥ → Z⊥.

In general, we model an identifier F :: k by a function of the form (Z⊥)k → Z⊥, and model

a type assignment of the form ∆ | Γ ` E :: σ by a continuous function of the form

[[∆ | Γ ` E :: σ]] : (Πj=mj=1 [(Z⊥)kj ,Z⊥]cts)× (Z⊥)n −→ X⊥

where X is Z if σ is int and B if σ is bool.

Definitions 7.5.2 We define the functions [[∆ | Γ ` E ]] by the rules in Table 7.2. Note

that as TURl satisfies subject reduction, we omit the types from the expressions to save

space.

Theorem 7.5.3 For all c ∈ Z ∪ B we have

[[∆ | ∅ ` P ]]([[dec∆]]) = [c]⇐⇒ dec∆ ` P ⇓l c.

Proof The proof is identical in principle to the proof of Theorem 7.4.4. Try looking at

the details of induction steps involving expressions of the form Fj(E1, . . . ,Ekj). �

Page 97: SEMANTICS OF PROGRAMMING LANGUAGES Course NotesSEMANTICS OF PROGRAMMING LANGUAGES Course Notes for MC 308 Dr. R. L. Crole Department of Mathematics and Computer Science Preface These

7.5. Further Denotational Semantics 91

[[∆ | Γ ` xi]](~f,~e)def= ei

[[∆ | Γ ` c]](~f,~e) def= [c]

[[∆ | Γ ` E1 op E2]](~f,~e)def= (ι ◦ op)~⊥ ([[∆ | Γ ` E1]](~f,~e) , [[∆ | Γ ` E2]](~f,~e))

[[∆ | Γ ` if E1 then E2 else E3]](~f,~e)def=

cond⊥B([[∆ | Γ ` E1]](~f,~e), [[∆ | Γ ` E2]](~f,~e), [[∆ | Γ ` E3]](~f,~e))

[[∆ | Γ ` Fj(E1, . . . ,Ekj )]](~f,~e)

def=

fj([[∆ | Γ ` E1]](~f,~e), . . . , [[∆ | Γ ` Ekj ]](~f,~e))

op : Z× Z −→ X

ι ◦ op : Z× Z −→ X⊥

(ι ◦ op)~⊥ : Z⊥ × Z⊥ −→ X⊥

cond⊥B : B⊥ ×X⊥ ×X⊥ −→ X⊥

fj : (Z⊥)kj −→ Z⊥

Table 7.2: Denotational Semantics [[∆ | Γ ` E ]] in TURl