If H and s have no negatives and H;s->*H';s', then
H' and s' have no negatives.
To really see the structure of what is going on,
we can be extra pedantic and define "noneg" inductively
over (heaps,) statements, and expressions.
judgments: noneg(e), noneg(s)
c >= 0 noneg(e1) noneg(e2)
-------- --------- -------------------
noneg(c) noneg(x) noneg(e1+e2)
noneg(e1) noneg(e2) noneg(e)
------------------- ----------- -----------
noneg(e1*e2) noneg(skip) noneg(x:=e)
noneg(s1) noneg(s2)
--------------------
noneg(s1;s2)
noneg(e) noneg(s1) noneg(s2) noneg(e) noneg(s)
---------------------------- -----------------
noneg(if e s1 s2) noneg(while e s)
Proof: By induction on the number of steps taken n.
If n=0, then H'=H and s'=s. check.
If n>0, then there exist H'' and s'' such that
H;s->(n-1) H'';s'' and H'';s''->H';s'
So by induction H'' and s'' have no negatives.
So this lemma suffices:
Lemma: If H and s have no negatives and H;s->H';s', then
H' and s' have no negatives.
Proof: By induction on (the height of) the derivation of
H;s->H';s'. By cases on the rule used at the bottom:
case seq1: Then s is skip;s' and H' is H. So noneg(H').
Since noneg(skip;s'), then noneg(s').
case assign: Then there exists an x, e, c such that
s is x:=e, s' is skip, H;e V c and H'=H,x->c. So
trivially noneg(s'). So I need noneg(H,x->c). Since
noneg(H), just need noneg(c).
Lemma: For all H, e, c,
If noneg(H) and noneg(e), and H;e V c, then
noneg(c). (To Be Proven)
case seq2: (there exists s1, s2, and s1' such that)
s is s1;s2 and s' is s1';s2 and H;s1->H';s1'
by a shorter derivation. So by induction
noneg(H') and noneg(s1'). Since noneg(s),
then noneg(s2). So from noneg(s1') and noneg(s2),
then noneg(s1';s2) and that's s'.
case if1: then there exists e and s2 such that
s is if e s' s2 and H' is H. So trivially noneg(H').
noneg(s) means noneg(s').
case if2: then there exists e and s2 such that
s is if e s2 s' and H' is H. So trivially noneg(H').
noneg(s) means noneg(s').
case while: then there exists e and s2 such that
s is while e s2 and s' is if e (s2; s) skip and H' is H.
So trivially noneg(H'). Since noneg(s), noneg(e) and
noneg(s2).
noneg(s2) noneg(s) -----------
noneg(e) -------------------- noneg(skip)
noneg(s2;s)
--------------------------------------------
noneg(if e (s2;s) skip)
Lemma: For all H, e, c,
If noneg(H) and noneg(e), and H;e V c, then
noneg(c).
By induction on height of derivation, cases on bottommost
rule:
const rule: Then e is c and noneg(e) is enough.
variable rule: Then noneg(H) is enough.
plus rule: Then there exist e1 and e2 and c1 and c2
such that e is
e1+e2 and c is c1 blue-plus c2 and H;e1 V c1
and H;e2 V c2. So noneg(e1) and noneg(e2).
So by induction (twice) noneg(c1) and noneg(c2).
So by math noneg(c1 blue-plus c2).
times rule: see plus rule.
------------
The Seq Lemma: If H;s1 ->n H';s1' then
H;(s1;s2) ->n H';(s1';s2)
Proof: By induction on n:
n=0: trivial
n>0: the H;s1 ->n-1 H'';s1'' for some H'';s1''
and H'';s1'' -> H';s1'
So by induction, H;(s1;s2)->n-1 H'';(s1'';s2).
Now, using H'';s1'' -> H';s1' and SEQ2, I can
derive H'';(s1'';s2) -> H';(s1';s2).
So H;(s1;s2)->n H';(s1';s2).
------------
This is not a proof, but some notes I wrote at the end of
class about denotational semantics for while-loops:
let dom = {string->int, _|_}
[[while e s]]
let g : ((dom -> dom) -> (dom->dom))
= fun heapTransformer ->
fun h ->
if [[e]] h
then heapTransformer ([[s]] h)
else h
let base : dom->dom
(fun h -> _|_)
g(base)
g(g(base))
g(g(g(base)))
g^i(base) -- "right" for i iterations then diverge
so take g^infinity
but wait, is that well-defined?
yes, it's the least fixed-point of g