# A bank account and its maintenance functions. # class BankAccount { # The global variable, the money in the account: account = 100 # we'll start at 100.... #PREMISES FOR ATTACHED PROOF, IF ANY: # (account == 100) # the global invariant (called the _class invariant_): """{ globalinvOK account >= 0 }""" # this property must stay true forever #PREMISES FOR NEXT LINE: # (account >= 0) def deposit(howmuch) : """deposit adds howmuch to account""" """{ pre howmuch >= 0 post True }""" global account #PREMISES FOR NEXT LINE: # (howmuch >= 0) # (account >= 0) """{ 1.OK account >= 0 premise # the globalinv holds on entry 2.OK howmuch >= 0 premise # the function's precondition 3.OK account >= 0 and howmuch >= 0 andi 1 2 }""" #PREMISES FOR NEXT LINE: # ((account >= 0) and (howmuch >= 0)) account = account + howmuch #PREMISES FOR ATTACHED PROOF, IF ANY: # (account == (account_old + howmuch)) # ((account_old >= 0) and (howmuch >= 0)) """{ 1.OK account == account_old + howmuch premise 2.OK account_old >= 0 and howmuch >= 0 premise 3.OK account >= 0 algebra 1 2 }""" #PREMISES FOR NEXT LINE: # (account >= 0) # POSTCONDITION AND ALL GLOBAL INVARIANTS VERIFIED AT END OF FUNCTION #PREMISES FOR NEXT LINE: # (account >= 0) # We must prove the global invariant is preserved at the exit. def withdraw(howmuch) : """withdraw removes howmuch from account""" """{ pre howmuch >= 0 post True }""" global account #PREMISES FOR NEXT LINE: # (howmuch >= 0) # (account >= 0) # the same two premises hold here like in deposit if howmuch <= account : #PREMISES FOR THEN-ARM: # (howmuch <= account) # (howmuch >= 0) # (account >= 0) # now we know that howmuch <= account : account = account - howmuch #PREMISES FOR ATTACHED PROOF, IF ANY: # (account == (account_old - howmuch)) # (howmuch <= account_old) # (howmuch >= 0) # (account_old >= 0) """{ 1.OK account == account_old - howmuch premise 2.OK howmuch <= account_old premise 3.OK account >= 0 algebra 1 2 }""" #PREMISES FOR NEXT LINE: # (account >= 0) else : #PREMISES FOR ELSE-ARM: # not (howmuch <= account) # (howmuch >= 0) # (account >= 0) """{ 1.OK not(howmuch <= account) premise 2.OK account >= 0 premise # the invariant }""" #PREMISES FOR NEXT LINE: # (account >= 0) pass #PREMISES FOR NEXT LINE: # (account >= 0) """{ 1.OK account >= 0 premise }""" #PREMISES FOR NEXT LINE: # (account >= 0) #PREMISES FOR NEXT LINE: # (account >= 0) # (howmuch >= 0) # END IF """{ 1.OK account >= 0 premise }""" #PREMISES FOR NEXT LINE: # (account >= 0) # POSTCONDITION AND ALL GLOBAL INVARIANTS VERIFIED AT END OF FUNCTION #PREMISES FOR NEXT LINE: # (account >= 0) # The global invariant is preserved at the exit. # } END class BankAccount