Exercise 3.5 Using these facts about arithmetic expressions, by structural induction, prove the evaluation of boolean expressions is firstly deterministic, and secondly total
5.2 Denotational semantics
We define the semantic functions
A:
Aexp -> (E -> N) B : Bexp -> (E -> T)C : Com -> (E ~ E)
by structural induction. For example, for commands, for each command c we define the partial function C[c] assuming the previous definition of c' for sub commands c' of c. The command c is said to denote C[c], and C[c] is said to be a denotation of c.
Denotations of Aexp:
Firstly, we define the denotation of an arithmetic expression, by structural induction, as a relation between states and numbers:
A[n] = {(er, n)
Ier
E E}A[X~
= {(er, er(X)) I er
E E}A[aa +
al~= {( er, no + nd I
(U, no) EA[ao]
&(er, nd
EA[al]}
A[ao - al] = {(er,na - nd I (u,no)
E A[ao~ &(er,nd
EA[ad}
A[ao
x al~= {(er,no
x nl)I (u,na)
EA[aa]
&(er,nl)
EA[al]}'
An obvious structural induction on arithmetic expressions a shows that each denotation
A[a]
is in fact a function. Notice that the signs"+", "-",
"x" on the left-hand sides represent syntactic signs in IMP whereas the signs on the right represent operations onnumbers, so e.g., for any state a,
A[3 + 5]a = A[3]a + A[5]a =
3+
5=
8,as is to be expected. Note that using A-notation we can present the definition of the semantics in the following equivalent way:
A[n]
=Aa
EE.n A[X] = Aa
EE.a(X)
A[ao + al]
=Aa
EE.(A[ao]a + A[al]a) A[ao - al] = Aa
EE.(A[ao]a - A[al]a) A[ao
xal] = Aa
EE.(A[ao]a
xA[al]a).
Denotations of Bexp:
The semantic function for booleans is given in terms of logical operations conjunction AT, disjunction VT and negation ""T, on the set of truth values T. The denotation of a boolean expression is defined by structural induction to be a relation between states and truth values.
B[true]
= {(a,
true)I a
E E}B[false]
=
{(a, false)I
a E E}B[ao = al] = {(a,
true)I a
E E &A[ao]a = A[ada}U {(a,
false)I a
E E &A[ao]a
=1=A[ada}, B[ao
~al] = {(a,
true)I a
E E &A[ao]a
~A[ada}u
{(a,
false)I a
E E &A[ada 1:: A[al]a}, B[...,b]
={(a,""Tt) I a
E E &(a, t)
EB[b]},
B[bo
Vbd = {(a, to
VTtl) I a
E E &(a, to)
EB[bo]
&(a,
tI) EB[bd}·
"
A simple structural induction shows that each denotation is a function. For example,
!3[ ~ { true if A[ao]a ::; A[al~a, ao
<
al~a =- false if A[ao~a
1:.
A[al~afor all a E ~.
Denotations of Com:
The definition of C[c~ for commands c is more complicated. We will first give denotations as relations between states; afterwards a straightforward structural induction will show that they are, in fact, partial functions. It is fairly obvious that we should take
C[skip~
=
{(a, a)I
a E ~}C[X := a~ = {(a, a[n/ Xl)
I
a E ~ & n = A[a~a}C[co; cd = C[Cl~ 0 C[co~, a composition of relations,
the definition of which explains the order-reversal in Co and Cl, C[if b then Co else Cl~
=
{(a, a')
I
!3[b~a = true & (a, a') E C[co]} U {(a, a')I
!3[b~a = false & (a, a') E C[Cl]}' But there are difficulties when we consider the denotation of a while-loop. Writew =: while b do c.
We have noted the equivalence
w rv if b then c; weIse skip
so the partial function C[w] should equal the partial function C[if b then c; weIse skipl Thus we should have:
C[w] ={(a, a')
I
!3[b]a = true & (a, a') E C[c; w]} U {( a, a)I
!3[b]a = false}={(a, a')
I
!3[b~a = true & (a, a') E C[w] 0 C[c]} U {(a,a)I
!3[b]a=
false}.Writing 'P for C[w~,
13
for !3[b] and 'Y for C[c] we require a partial function 'P such that 'P ={ (a, a')I
f3(a) = true & (a, a') E ip 0 'Y}U{(a, a)
I
f3(a) = false}.But this involves <p on both sides of the equation. How can we solve it to find <p? We clearly require some technique for solving a recursive equation of this form (it is called
"recursive" because the value we wish to know on the left recurs on the right). Looked at in another way we can regard f, where
f(<p) ={(o-, 0-') I (3(0-) = true & (0-,0-') E <p 0 , } U
{( 0-,0-) I (3(0-)
=
false}={ (0-,0-') I :30-". (3(0-) = true & (0-,0-") E , & (0-",0-') E <p} U
{(o-,o-) 1(3(0-)
=
false},as a function which given <p returns r( <p). We want a fixed point <p of
r
in the sense that<p
=
f(<p).The last chapter provides the clue to finding such a solution in Section 4.4. It is not hard to check that the function f is equal to
R,
whereR
is the operator on sets determined by the rule instancesR ={({(o-",o-')}/(o-,o-')) 1(3(0-)
=
true & (0-,0-") E , }u
{(0/(0-,0-)) 1(3(0-) = false}.
As Section 4.4 shows
R
has a least fixed point<p
=
fix(R)where <p is a set-in this case a set of pairs-with the property that
We shall take this least fixed point as the denotation of the while program w. Certainly its denotation should be a fixed point. The full justification for taking it to be the least fixed point will be given in the next section where we establish that this choice for the semantics agrees with the operational semantics.
Now we can go ahead and define the denotational semantics of commands in the
following way, by structural induction:
where
C[skip] = {(O", 0")
10"
E E}C[X := a] = {(O", O"[nj Xl)
I
0" E E & n = A[a] 0" }C[if b then Co else CI] =
{(O",O"')
I
B[b]O"=
true & (0',0"') E C[conU {(O",o")I
B[b]O" = false & (0",0"') E C[CIn C[while b do c]=
fix(r)r(ip) ={(O",O"')
I
B[b]O"=
true & (0",0") E ipoC[cn U{(O",O")
I
B[b]O'=
false}.In this way we define a denotation of each command as a relation between states. No-tice how the semantic definition is compositional in the sense that the denotation of a command is constructed from the denotations of its immediate subcommands, reflected in the fact that the definition is by structural induction. This property is a hallmark of denotational semantics. Notice it is not true of the operational semantics of IMP because of the rule for while-loops in which the while-loop reappears in the premise of the rule.
We have based the definition of the semantic function on while programs by the op-erational equivalence between while programs and one "unfolding" of them into a con-ditional. Not surprisingly it is straightforward to check this equivalence holds according to the denotational semantics.
Proposition 5.1 Write
w
==
while b do c for a command c and boolean expression b. ThenC[w] = C[if b then c; weIse skip].
Proof: The denotation of w is a fixed point of f, defined above. Hence C[wI =f(C[wI)
=((O",O"') I 8[bIO" = true & (0",0"') E C[wI 0 C[cD U {( 0",0")
I
8[b]0" = false}={(O",O"') I 8[b]0" = true & (0",0"') E C[c;wD
u
{( 0",0"')I
8[b]0" = false & (0",0"') E C[skip]}=C[if b then c; weise skiplD
Exercise 5.2 Show by structural induction on commands that the denotation C[cI is a partial function for all commands c.
(The case for while-loops involves proofs by mathematical induction showing that f n(0) is a partial function between states for all natural numbers n, and that these form an increasing chain, followed by the observation that the union of such a chain of partial
functions is itself a partial function.) 0
In Section 5.4 we shall introduce a general theory of fixed points, which makes sense when the objects defined recursively are not sets ordered by inclusion.
5.3 Equivalence of the semantics
Although inspired by our understanding of the operational behaviour of IMP the denota-tional semantics has not yet been demonstrated to agree with the operadenota-tional semantics.
We first check the operational and denotational semantics agree on the evaluation of expressions:
Lemma 5.3 For all a E Aexp,
A[aI
=
{(O",n)I
(a, 0") --; n}.Proof: We prove the lemma by structural induction. As induction hypothesis we take P(a) ~ defA[aI = {(O",n)
I
(a, 0") --; n}.Following the scheme of structural induction the proof splits into cases according to the structure of an arithmetic expression a.
a
==
m: From the definition of the semantic function, in the case where a is a number m, we have(O",n) E A[mI ~ 0" E:E & n
==
m.Clearly, if (cr,
n)
EA[m]
thenn ==
m and{m,
cr) -->n.
Conversely, if{m,
cr) -->n
then the only possible derivation is one in whichn ==
m and hence (cr,n)
EA[m].
a
==
X: Similarly, if a is a location X,(cr,
n)
EA[X]
~ (cr E E &n == cr(X))
~
{X,
cr) --> n.a == ao +
al: AssumeP(ao)
andP(ad
for two arithmetic expressionsao,
al. We haveSupposing (cr,
n)
EA[ao
+al], there areno,
nl such thatn = no +nl
and (cr,no)
EA[ao]
and (cr,nl) E A[all From the assumptions
P(ao)
andP(ad,
we obtainThus we can derive
(ao +al,
cr) -->n.
Conversely, any derivation of(ao +
aI, cr) -->n
must have the form(ao,
cr) -->no (aI,
cr) --> nl(ao + aI,
cr) -->n
for some
no,
nl such thatn
=no + nl.
This time, from the assumptionsP(ao)
andP(ad,
we obtain(cr,no)
EA[ao]
and(cr,nd
E A[all Hence(cr,n)
EA[a].
The proofs of the other cases, for arithmetic expressions of the form a 0 - al and
ao
x aI, follow exactly the same pattern. By structural induction on arithmetic expressions we conclude thatA[a]
={(cr,n) I (a,cr)
-->n},
for all arithmetic expressions a. o
Lemma 5.4 For b E Bexp,
8[b] = {(cr, t)
I
(b,a) --> t}.Proof: The proof for boolean expressions is similar to that for arithmetic expressions.
It proceeds by structural induction on boolean expressions with induction hypothesis P(b) ~ defB[b]
=
{(cr,t) I (b,a) --> t}for boolean expression b.
We only do two cases of the induction. They are typical, and the remaining cases are left to the reader.
b == (ao
=al):
Letao, al
be arithmetic expressions. By definition, we haveThus
B[ao = al] ={
(cr, true)I
cr E I; &A[ao]cr = A[al]cr}U
{(cr, false)I
cr E I; &A[ao]cr =I A[al]cr}.
(cr, true) E
B[ao
=al]
~ cr E I; &A[ao]cr
=A[al]cr.
If (cr, true) E
B[ao
=al]
thenA[ao]cr
=A[al]cr,
so, by the previous lemma,(ao,
cr) -> nand(aI,
cr) ->n,
for some number n. Hence from the operational semantics for boolean expressions we obtain
(ao
= al,cr) -> true.Conversely, supposing
(ao
=aI,
cr) -> true, it must have a derivation of the form(ao,cr)
-+n
(al,cr) ->n (ao = aI, a)
-> trueBut then, by the previous lemma,
A[ao]cr = n = A[adcr.
Hence (cr, true) EB[ao = al].
Therefore
(cr, true) E
B[ao = al]
~(ao = al,a)
-> true.Similarly,
(cr,false) E
B[ao = al]
~(ao =
al,cr) -> false.It follows that
B[ao =
ad=
{(cr, t) I(ao = aI,
cr) -> t}.b == bo
1\bl :
Letbo,
bl be boolean expressions. AssumeP(b o)
andP(bd.
By definition, we have(cr, t) E
B[bo
1\ bl ] ~ cr E I; & :lto, tl.t
=to
I\T tl & (cr,to)
EB[b 9]
&(a,
h) EB[bI].
Thus, supposing (cr,
t)
EB[bo
1\ bl]' there areto,
tl such that (cr,to)
EB[bo]
and(a, td
EB[b
1 ]. From the assumptionsP(bo)
andP(bd
we obtainThus we can derive (bo 1\ bl , a) ---*
t
wheret =
to I\T tl. Conversely, any derivation of (bo 1\ bl , a) ---* t must have the form(bo, a) ---* to (bl , a) ---* tl (bo 1\ bl , a) ---* t
for some to, tl such that
t =
tOI\Ttl' From the P(bo) and P(bd, we obtain (a, to) E B[bo]and (a,
td
EB[bll
Hence (a, t) E B[blAs remarked the other cases of the induction are similar. o Exercise 5.5 The proofs above involve considering the form of derivations. Alternative proofs can be obtained by a combination of structural induction and rule induction. For example, show
1. {(a,n)
I
(a,a) ---* n} ~ A[a], 2. A[a] ~ {(a,n)I
(a,a) ---* n},for all arithmetic expressions a by using rule induction on the operational semantics of arithmetic expressions for 1 and structural induction on arithmetic expressions for 2. 0
Now we can check that the denotational semantics of commands agrees with their operational semantics:
Lemma 5.6 For all commands c and states a, a', (c, a) ---* a' ::} (a, a') E C[c].
Proof: We use rule-induction on the operational semantics of commands, as stated in Section 4.3.3. For c E Com and a, a' E ~, define
P(c, a, a') {::::::::} de/(a, a') E C[c].
If we can show P is closed under the rules for the execution of commands, in the sense of Section 4.3.3, then
(c, a) ---* a' ::} P( c, a, a')
for any command c and states a, a'. We check only one clause in Section 4.3.3, that associated with while-loops in the case in which the condition evaluates to true. Recall it is:
(b, a) ---* true (c, a) ---* a" (w, a") ---* a' (w, a) ---* a'
where we abbreviate w
==
while b do c. Following the scheme of Section 4.3.3, assume (b,a) -> true & (c,a) -> a" & P(c,a,a") & (w,a") -> a' & P(w,a",a').By Lemma 5.4
B[b]a
=
true.From the meaning of P we obtain directly that
C[c]a = a" and C[w]a" = a'.
Now, from the definition of the denotational semantics, we see C[w]a
=
C[c; w]a=
C[w] (C[c]a)=
C[w]a"=
a'.But C[w]a
=
a' means P(w, a, a') i.e. P holds for the consequence of the rule. Hence P is closed under this rule. By similar arguments, P is closed under the other rules for the execution of commands (Exercise!). Hence by rule induction we have proved thelemma. 0
The next theorem, showing the equivalence of operational and denotational semantics for commands, is proved by structural induction with a use of mathematical induction inside one case, that for while-loops.