Semantics of the while-loop and the soundness of its Hoare-logic rule
----------------------------------------------------------------------

Recall that a loop is understood as the limit or union of its approximating loops:

for W =  while B do C end

define   W0 = alwaysloop

         W1 = if B then C; W0 
              else return
              
         W2 = if B then C; W1 
              else return
         ...
         W(i+1) = if B then C; Wi 
                  else return
         ...

The results returned by  W  will be exactly the same ones as the union
of all the results returned by the  Wi's.   W  is the "limit" of the
sequence of functions defined by the  Wi's.

(This same idea holds for the semantics of a recursively defined
function --- such a function is the limit of a sequence of approximating functions.)


The denotational semantics of the while-loop employs this idea:

To keep it simple, let's omit Environments:
C : Command -> Store -> Store_

C[[ while B do C end ]] =  Union { wi | i >= 0 }

  where   w0 = lam s. _|_
  
          w(i+1) = lam s. if B[[ B ]] s :  check(wi, C[[ C ]] s)
                          else  s
                                 
Details:
  a function's _graph_ is the set of its argument, answer pairs,
  where the answer value is not _|_.
  For example, for  f(n) = n+1,  where  n: Nat,  its graph is
  {(0,1), (1,2), (2,3), ... (i, i+1), ...}
  
     graph(w0) = { }
     
     graph(w1) = {(s, s) |  B[[ B ]]s == ff }
     
     graph(w2) = {(s, s) |  B[[ B ]]s == ff }
                 union  {(s, s') |  s' = C[[ C ]]s 
                                    s' != _|_
                                    and  B[[ B ]]s' == ff }
                                     
               = {(s, s) |  B[[ B ]]s == ff } union
                 {(s, s'') |  B[[ B ]]s = tt, s' = C[[ C ]s,  
                              s' != _|_, and (s', s'') in graph(w1)}
     ...
     graph(w(i+1)) = {(s, s) |  B[[ B ]]s == ff } union
                     {(s, s'') |  B[[ B ]]s = tt, s' = C[[ C ]s  
                                  s' != _|_, and (s', s'') in graph(wi)}
        
        
So,  graph(w) = union( { graph(wi) | i >= 0 } )
     where  w  is   C[[ while B do C end ]]


Properties:

    for all i >= 0,  graph(wi)  defines a function.
    
    for all i >= 0,  graph(wi) subset graph(i+1)
    
    for all s: Store,  (s,s') in graph(w) 
       iff there is some k such that  (s,s') in graph(wk).
       
    graph(wk) defines a function.
               
               
The "Union" defined at the top of this page is more precisely a
_join_ operation on the lattice of functions of form,
Store -> Store_   (It takes some work to formalize this, so we
stick with the graphs!)

====================================

The while-loop rule:


   { I ^ B } C { I }
 ----------------------------------
 { I } while B do C end { ~B ^ I }
 
 
 How to prove its soundness:
 
 1) First, show for all i >= 0 that
 
   { I ^ B } C { I }
 -------------------------
   { I } wi { ~B ^ I }
   
 using the definition of soundness I gave you last week.
 Here it is again:   
   {P}f{Q}  is sound iff  for all s: Store,  
        if B[[P]]s = tt and (f s) != _|_,
        then  B[[Q]](f s) = tt.
 
 Prove by mathematical induction on the value of i:
 
 First, assume soundness of  { I ^ B } C { I }.

 Basis step:  i = 0: 
 graph(w0) = {}, so there is no  s  such that  w0(s) != _|_ .
 The result is vacuously true.
 
 Induction step: i = k+1.
 The induction hypothesis lets us assume soundness of the above
 rule for  wk. 

 We must prove, for every  s: Store, if
    (a) B[[ I ]]s = tt  and 
    (b) (w(k+1) s) = s'', where  s'' != _|_.
 then   B[[ ~B ^ I ]]s'' = tt.  (*)
 
 Recall that  graph(w(i+1)) = {(s, s) |  B[[ B ]]s = ff } 
       union {(s, s'') |  B[[ B ]]s = tt,
                          s' = C[[ C ]s  and (s', s'') in graph(wi)}
 
 This makes two cases to consider:
 (i)  B[[ B ]]s = ff.   This and (a) give us  B[[ ~B ^ I ]]s = tt. (*)
 Done.
 
 (ii) B[[ B ]]s = tt,  s' = C[[ C ]s,  s' != _|_, 
      and (s', s'') in graph(wk).
      By (a), we have that  B[[I ^ B]]s = tt.
      By the soundness of  { I ^ B } C { I }, we have
      B[[ I ]]s'.  But (s', s'') in graph(wk), too.
      By the induction hypothesis on wk, we deduce
      that { I } wk { ~B ^ I } is sound,
      that is,  wk(s') = s'' and  B[[~B ^ I]]s'' (*).  Done.

      
 
2) Now we obtain the main result:  

Assume  { B ^ I } C { I }  is sound.
Show, for all s: Store,  
        if B[[ I ]]s = tt and (w s) != _|_,
        then  B[[ ~B ^ I ]](w s) = tt.
        
Recall the crucial property of  w :
  (s, s') in graph(w) iff there is some  k >= 0  such that  
                          (s, s') in graph(wk).
                             
If   B[[ I ]]s = tt,  (w s) = s',  s' != _|_,  
then there is some  k >=0  such that (s, s') in graph(wk) as well.
By the result proved in Step (1),
B[[ ~B ^ I ]](wk s) = tt, that is,  B[[ ~B ^ I ]]s' = tt.  Done.