# simple example of a global variable invariant: # a timer that counts down to zero time = 0 #PREMISES FOR ATTACHED PROOF, IF ANY: # (time == 0) # we want to maintain true this invariant property: """{ globalinvOK time >= 0 }""" #PREMISES FOR NEXT LINE: # (time >= 0) # the checker verifies that the invariant holds true HERE, on initialization. # the function below can use the invariant, and the function # must ensure that the invariant holds on exit: def tick() : """{ pre True post ans == time return ans }""" global time #PREMISES FOR NEXT LINE: # True # (time >= 0) # as needed, we can introduce the globalinv into a proof: """{ 1.OK time >= 0 premise }""" #PREMISES FOR NEXT LINE: # (time >= 0) if time != 0 : #PREMISES FOR THEN-ARM: # (time != 0) # (time >= 0) time = time - 1 #PREMISES FOR ATTACHED PROOF, IF ANY: # (time == (time_old - 1)) # (time_old != 0) # (time_old >= 0) """{ 1.OK time_old != 0 premise 2.OK time_old >= 0 premise 3.OK time_old > 0 algebra 1 2 4.OK time == time_old - 1 premise 5.OK time >= 0 algebra 3 4 }""" #PREMISES FOR NEXT LINE: # (time >= 0) else : #PREMISES FOR ELSE-ARM: # not (time != 0) # (time >= 0) print "RING RING RING" #PREMISES FOR NEXT LINE: # not (time != 0) # (time >= 0) """{ 1.OK time >= 0 premise }""" #PREMISES FOR NEXT LINE: # (time >= 0) #PREMISES FOR NEXT LINE: # (time >= 0) ans = time #PREMISES FOR ATTACHED PROOF, IF ANY: # (ans == time) # (time >= 0) #PREMISES FOR NEXT LINE: # (ans == time) # (time >= 0) # POSTCONDITION AND ALL GLOBAL INVARIANTS VERIFIED AT POINT OF RETURN # we have proved enough facts that the checker can verify that the # invariant holds true and so does the function's postcondition return ans #PREMISES FOR NEXT LINE: # (ans == time) # (time >= 0) # POSTCONDITION AND ALL GLOBAL INVARIANTS VERIFIED AT END OF FUNCTION #PREMISES FOR NEXT LINE: # (time >= 0) def init(starttime) : """{ pre starttime > 0 post True }""" global time #PREMISES FOR NEXT LINE: # (starttime > 0) # (time >= 0) time = starttime #PREMISES FOR ATTACHED PROOF, IF ANY: # (time == starttime) # (starttime > 0) # (time_old >= 0) #PREMISES FOR NEXT LINE: # (time == starttime) # (starttime > 0) # POSTCONDITION AND ALL GLOBAL INVARIANTS VERIFIED AT END OF FUNCTION #PREMISES FOR NEXT LINE: # (time >= 0) # the checker easily verifies the global invariant: time >= 0 # Driver code starts here: run the timer # invariant holds true novar = init(10) #PREMISES FOR ATTACHED PROOF, IF ANY: # True # (time_old >= 0) #PREMISES FOR NEXT LINE: # invariant holds true a = tick() #PREMISES FOR ATTACHED PROOF, IF ANY: # (a == time) #PREMISES FOR NEXT LINE: # (a == time) # invariant holds true a = tick() #PREMISES FOR ATTACHED PROOF, IF ANY: # (a == time) # (a_old == time_old) #PREMISES FOR NEXT LINE: # (a == time) # invariant holds true a = tick() #PREMISES FOR ATTACHED PROOF, IF ANY: # (a == time) # (a_old == time_old) #PREMISES FOR NEXT LINE: # (a == time) # invariant holds true