Example

As an example of improving a contract, consider the refinement of the class account into a class {\em credit_account}, which allows a consumer to overdraw an account to a limit of some maximum amount. See slide 3-credit-account.

Refining the account contract

\zline{\fbox{C++}}
  class credit_account : public account {
  public:
  credit_account(float x) { _maxcredit = x; _credit = 0; }
  
  float balance() { return _balance + _credit; }
  
  float credit(float x) { 
  	require( x + _credit <= _maxcredit );
  	hold();
  	_credit += x;
  	promise( _credit = old_credit + x );
  	promise( _balance = old_balance);
  	promise( invariant() );
  	}
  
  void reduce(float x) {
  	require( 0 <= x && x <= _credit );
  	hold();
  	_credit -= x;
  	promise( _credit = old_credit - x );
  	promise( _balance = old_balance );
  	promise( invariant() );
  	}
  
  
  bool invariant() {
  	return _credit <= _maxcredit && account::invariant();
  	}
  protected:
  float _maxcredit, _credit;
  float old_credit;
  void hold() { old_credit = _credit; account::hold(); }
  };
  

slide: Refining the account contract

As a first observation, we may note that the invariant of account immediately follows from the invariant of credit_account. Also, we may easily establish that the pre-condition of withdraw has (implicitly) been weakened, since we are allowed to overdraw the {\em credit_account} by the amount given by credit. Note, however, that this is implied by the virtual definition of balance(). To manage the credit given, the methods credit and reduce are supplied. This allows us to leave the methods deposit and withdraw unmodified.