19.11.2014 Views

The Fortress Language Specification - CiteSeerX

The Fortress Language Specification - CiteSeerX

The Fortress Language Specification - CiteSeerX

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>The</strong> invariant clause consists of a sequence of expressions of any type. <strong>The</strong>se expressions are evaluated before and<br />

after a function call. For each expression e in this sequence, if the value of e when evaluated before the function call<br />

is not equal to the value of e after the function call, a CalleeViolation exception is thrown.<br />

Here are some examples:<br />

factorial(n : Z64) requires n ≥ 0 =<br />

if n = 0 then 1<br />

else nfactorial(n − 1)<br />

end<br />

mangle(input : List) ensures sorted(result) provided sorted(input) =<br />

if input ≠ Empty<br />

then mangle(first(input))<br />

mangle(rest(input))<br />

end<br />

Overloaded function contracts are handled similarly with method contracts described in Section 9.4. In particular,<br />

substitutability is preserved: the statically most applicable function to a call should be substitutable with the dynamically<br />

most applicable function to the call. For a call of function f, we use the term static contract of f to refer to a<br />

contract declared in the statically most applicable function declaration and the term dynamic contract of f to refer to<br />

a contract declared in the dynamically most applicable function declaration. Three exceptions may be thrown due to<br />

an overloaded function contract violation: CallerViolation is thrown when the requires clause of the static contract<br />

fails, CalleeViolation is thrown when the ensures or invariant clause of the dynamic contract fails, and<br />

ContractOverloadingViolation is thrown when the requires clause of the dynamic contract or the ensures or<br />

invariant clause of the static contract fails.<br />

Evaluation of a call of function f proceeds as follows. Let C and C ′ be the static and dynamic contracts of f,<br />

respectively. If the requires clause of C fails, a CallerViolation exception is thrown. Otherwise, if the requires<br />

clause of C ′ fails, a ContractOverloadingViolation exception is thrown. Otherwise, the provided subclauses of C<br />

and C ′ are evaluated. For every provided subclause that evaluates to true , the corresponding ensures subclause is<br />

recorded in a table E for later comparison. Similarly, the invariant clauses of C and C ′ are evaluated and the results<br />

are stored in E for later comparison. <strong>The</strong>n the body of the dynamically most applicable function declaration of f is<br />

evaluated. After evaluation of the body, all ensures subclauses of the dynamic contract recorded in E are checked<br />

to ensure that they evaluate to true , and all invariant clauses of the dynamic contract recorded in E are checked<br />

to ensure that they evaluate to values equal to the values they evaluated to before evaluation of the body. If any such<br />

check fails, a CalleeViolation exception is thrown. Otherwise, all ensures subclauses and invariant clauses<br />

of the static contract in E are checked. If any of these checks fails, a ContractOverloadingViolation exception is<br />

thrown.<br />

90

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!