# 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