# CODE THAT KEEPS TRACK OF THE COINS IN A TOY BANK: # module DimesBank { # fields in module: dimes = 0 #PREMISES FOR ATTACHED PROOF, IF ANY: # (dimes == 0) #PREMISES FOR NEXT LINE: # (dimes == 0) money = 0 #PREMISES FOR ATTACHED PROOF, IF ANY: # (money == 0) # (dimes == 0) # we want the module to maintain true this invariant property: """{ globalinvOK money == dimes * 10 }""" #PREMISES FOR NEXT LINE: # (money == (dimes * 10)) # the checker verifies that the invariant holds true HERE, on initialization. # the method/function below can use the invariant, and the function # must ensure that the invariant holds on exit: def handleCoinInsertion(howmany) : """handles the insertion of howmany dimes into the bank:""" """{ pre howmany >= 0 post True # the function enforces the invariant, that's it. }""" global dimes, money #PREMISES FOR NEXT LINE: # (howmany >= 0) # (money == (dimes * 10)) # we can introduce the invariant as a premise as needed: """{ 1.OK money == dimes * 10 premise }""" #PREMISES FOR NEXT LINE: # (money == (dimes * 10)) dimes = dimes + howmany #PREMISES FOR ATTACHED PROOF, IF ANY: # (dimes == (dimes_old + howmany)) # (money == (dimes_old * 10)) """{ 1.OK money == dimes_old * 10 premise 2.OK dimes == dimes_old + howmany premise 4.OK money + (howmany * 10) == dimes * 10 algebra 1 2 }""" #PREMISES FOR NEXT LINE: # ((money + (howmany * 10)) == (dimes * 10)) # invariant is broken here, but the next command restores it: money = money + (howmany * 10) #PREMISES FOR ATTACHED PROOF, IF ANY: # (money == (money_old + (howmany * 10))) # ((money_old + (howmany * 10)) == (dimes * 10)) """{ 1.OK money_old + (howmany * 10) == dimes * 10 premise 2.OK money == money_old + (howmany * 10) premise 3.OK money == dimes * 10 subst 2 1 }""" #PREMISES FOR NEXT LINE: # (money == (dimes * 10)) # POSTCONDITION AND ALL GLOBAL INVARIANTS VERIFIED AT END OF FUNCTION #PREMISES FOR NEXT LINE: # (money == (dimes * 10)) # the checker verifies here that the invariant is true again. # } END MODULE # the following would be in a component that imports (uses) the module: # throughout every line of the following code, the invariant is holding true: coins = readInt("press button and insert your coins!") #PREMISES FOR ATTACHED PROOF, IF ANY: # True # (money == (dimes * 10)) #PREMISES FOR NEXT LINE: # (money == (dimes * 10)) assert coins > 0 #PREMISES FOR NEXT LINE: # (coins > 0) # (money == (dimes * 10)) novar = handleCoinInsertion(coins) #PREMISES FOR ATTACHED PROOF, IF ANY: # True # (coins > 0) # (money_old == (dimes_old * 10)) #PREMISES FOR NEXT LINE: # (coins > 0) print money #PREMISES FOR NEXT LINE: # (coins > 0)