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.