Examples of denotational semantics

Denotational semantics – Example 1 (2014-10-14)
Consider the program:
if 0≤y then skip else y:=0-y
We compute its denotation, d:
d = Sds⟦if 0≤y then skip else y:=0-y⟧
= cond(B⟦0≤y⟧, Sds⟦skip⟧,Sds⟦y:=0-y⟧)
= cond(B⟦0≤y⟧, id,Sds⟦y:=0-y⟧)
Using the definition of cond, we get
d s = id s
if B⟦0≤y⟧s = tt
= Sds⟦y:=0-y⟧s if B⟦0≤y⟧s = ff
Using the definitions of B and Sds again, we get
ds=s
if A⟦0⟧s ≤A⟦y⟧s
= s[y ↦ A⟦0-y⟧s] if A⟦0⟧s >A⟦y⟧s
and using the definitions of A and N, we get
ds=s
if 0 ≤ s y
= s[y ↦ -s y] if 0 > s y
considering that s = s[y ↦ s y], that s y = |s y| if 0 ≤ s y and that -s y = |s y| if
0 > s y, we can rewrite this to
d s = s[y ↦ |s y|] if 0 ≤ s y
= s[y ↦ |s y|] if 0 > s y
or simply
d s = s[y ↦ |s y|]
In other words, the denotation of the program above is a function with takes a
state and computes an new state where y is updated with its absolute value.
Denotational semantics – Example 2.
Consider this program taken from exercise 5.3:
y:=1; while ¬x=1 do (y:=y*x;x:=x-1)
Let F be the function defined by:
F g = cond(B⟦¬x=1⟧, g o Sds⟦y:=y*x;x:=x-1⟧,id)
We compute the denotation, d, of the program:
d = Sds⟦y:=1; while ¬x=1 do (y:=y*x;x:=x-1)⟧
= Sds⟦while ¬x=1 do (y:=y*x;x:=x-1)⟧ o Sds⟦y:=1⟧
= FIX F o Sds⟦y:=1⟧
Using the property of fixpoints that (FIX F) = F (FIX F)
= F (FIX F) o Sds⟦y:=1⟧
Let d' = F (FIX F) = cond(B⟦¬x=1⟧, FIX F o Sds⟦y:=y*x;x:=x-1⟧,id) =
= cond(B⟦¬x=1⟧, F (FIX F) o Sds⟦y:=y*x;x:=x-1⟧,id)
= cond(B⟦¬x=1⟧, d' o Sds⟦y:=y*x;x:=x-1⟧,id)
Using the definition of cond, we get
d' s = d' o Sds⟦y:=y*x;x:=x-1⟧s if B⟦¬x=1⟧s = tt
= id s
if B⟦¬x=1⟧s = ff
Using the definitions of B and Sds again, (several times) we get
d' s = d' s[y ↦ A⟦y*x⟧s,x ↦ A⟦x-1⟧s[y ↦ A⟦y*x⟧s]] if A⟦x⟧s ≠ A⟦1⟧s
=s
if A⟦x⟧s =A⟦1⟧s
and using the definitions of A and N, we get
d' s = d' s[y ↦ s y * s x, x ↦ s x -1] if s x ≠ 1
=s
if s x = 1
We can now see that d' is a function that -- if applied to a state in which x has a
positive value -- is recursively defined, with each recursive application updating
the state so that y is multiplied by x and decreasing x by one until x is equal to
1 at which point the function simply returns the state given as its argument. In
other words, if y was initially 1, then d' will compute a state in which y is the
factorial of the original x. This informal argument can be made rigorous using
induction.
Recall that d = F (FIX F) o Sds⟦y:=1⟧ = d' o Sds⟦y:=1⟧. Using the definition of
Sds, we get d s = d'(s[y↦1]), thus d is the same as d', except that it initially sets
y to 1 in the state.
In other words, the denotation of the program, d, is a function that computes a
state in which y has been set to the factorial of x is the state which is given as
argument to d (and also in which x is set to 1).
d s = s[x ↦ 1, y ↦ (s x)!]