Answers to Self-Study Questions
Test Yourself #1
We want to know the value of:
P [[ Z=A; if Z==0 then Z=1. ]]
By the definition of P, this is:
λn. let
| s = ( update [[A]] n newstore ) in
|
| let
| s' = ( C [[ Z=A; if Z==0 then Z=1 ]] s ) in
|
|
| access [[Z]] s'
|
|
Note that
is the store that maps A to n, and maps all
other Ids to zero. Let's call this store s1 in what follows.
So we have:
let s' = ( C [[ Z=A; if Z==0 then Z=1 ]] s1 ) in
access [[Z]] s')
Using the definition of C for a sequence of
statements we get:
let s' = ( C [[ if Z==0 then Z=1 ]] ( C [[ Z=A ]] s1 )
in access [[Z]] s')
Now using the definition of C for an assignment we get:
let s' = ( C [[ if Z==0 then Z=1 ]] ( update [[Z]] (
E [[A]] s1 ) s1 ) in access [[Z]] s')
Using the definition of E for an identifier, we have:
which simplifies to:
which (since s1 maps A to n) evaluates to n.
Therefore, we have the (sub)expression
which evaluates to the store that maps A and Z to
n, and all other identifiers to zero. We'll call that store s2. Now we have:
let s' = (( C [[ if Z==0 then Z=1 ]] s2) in access
[[Z]] s')
Using the definition of C for an if-then statement we get:
let s' = ( if (B [[Z==0]] s2) then (C
[[Z=1]] s2) else s2 ) in access [[Z]] s'
Using the definition
of B for an equality test, and the fact that s2 maps Z to n, we have:
let s' = if (n equals zero) then (C [[ Z=1 ]]
s2) else s2 in access [[Z]] s'
By the definition of C
for an assignment, we have:
let s' = if (n equals zero) then (update [[Z]]
(E [[1]]) s2) else s2 in access [[Z]] s'
which using
the definition of E for a number literal becomes:
let s' = if (n equals zero) then (update [[Z]] one
s2) else s2 in access [[Z]] s'
Note that
is a store that maps Z to one. Call this store s3:
let s' = if (n equals zero) then s3 else s2
in access [[Z]] s'
The
Evaluates to whatever value the store s' maps Z to.
Observe that for s3, this value is one, and for s2 it is n. We now have for the
entire program:
λ n.if (n equals zero) then one else n
Test Yourself #2
The store represents the state of the program,
and once it becomes ⊥, all states produced after that point must also be ⊥.
C is the only valuation function that produces a new state for the
program, which is why it must be strict. B and E do not produce a
new state, so they do not need to be strict.
Test Yourself #3
E [[E1/E2]] = λk.λs.E [[E1]]
(λn1.λs2.E [[E2]] (λn2.λs3.if n2 equals zero then ⊥
else k (n1 divided-by n2) s3) s2) s1
Test Yourself #4
λn.let
| s1 = (update [[A]] n newstore) |
| in let
| s2 = ((C [[B=A/0;...]] λs.s) s1) |
|
| in access [[Z]] s2
|
Note that s1 is a
store that maps A to n, and all other Ids to zero. We have:
let s2 = ((C [[B=A/0;...]] λs.s) s1) in access [[Z]]
s2
Applying C [[C1;C2]] we get:
let s2 = ((λc1.λs.C [[B=A]] (C[[...]] c1) s) λs.s) s1
in access [[Z]] s2
Applying C for assignment, we get:
let s2 = (λc1.λs. (λc2.λs. (E [[A/0]] (λn.λs.c2 (update
[[B]] n s) s) (C[[...]] c1) s) λs.s)) s1 in access [[Z]] s2
Let's just focus on the E portion for now:
This is:
λk.λs.E [[A]] (λn1.λs2.E [[0]] (λn2.λs3.if n2 equals
zero then ⊥ else k (n1 divided-by n2) s3) s2) s
Applying
E [[N]], we get:
λk.λs.E [[A]] (λn1.λs2. (λk'.λs'.k' zero s') (λn2.λs3.if n2
equals zero then ⊥ else k (n1 divided-by n2) s3) s2) s
λk.λs.E [[A]] (λn1.λs2. ((λn2.λs3.if n2 equals zero
then ⊥ else k (n1 divided-by n2) s3) zero s2)) s
If we apply
the zero, we get:
λk.λs.E [[A]] (λn1.λs2. ((λs3.if true then ⊥
else k (n1 divided-by zero) s3) s2)) s
λk.λs.E [[A]] (λn1.λs2. ((λs3.⊥) s2)) s
λk.λs.E [[A]] (λn1.λs2. ⊥) s
Using E[[I]], we get:
λk.λs.(λk'.λs'.k' (access [[A]] s') s') (λn1.λs2. ⊥) s
λk.λs.(λn1.λs2. ⊥) (access [[A]] s) s
Recall that this was originally E [[A/0]]. If we now
plug that back into the program, we get:
let s2 = ((λc1.λs. (λc2.λs. ((λk.λs. ⊥) (λn.λs.c2 (update [[B]] n
s) s)) (C[[...]] c1) s) ) λs.s) s1 in access [[Z]] s2
let s2 = ((λc1.λs. (λc2.λs. ⊥) (C[[...]] c1) s ) λs.s) s1
in access [[Z]] s2
let s2 = ((λc1.λs. ⊥) λs.s) s1 in access [[Z]] s2
let s2 = ⊥ in access [[Z]] s2
Of course, this was originally a program, wrapped in a
λn which we've omitted for convenience above. Adding everything back in, we get
the final solution:
As it turns out, the result of this program does not
depend on its input.