Paper Title: On the Precise Meaning of the OCL Constraints Presented by Alla Dove
What we want OCL to be Main Purpose of OCL: Provide precise information in UML, which can be ambiguous Use in Advanced Support Tools: – check database integrity – check correctness of rules – prove that code never violates the constraints
What OCL is really like Lack of precise semantics Questions: – When during the execution is the validity of invariant enforced? – Is it possible to specify non-terminating operations in OCL? – What is the meaning when several constraints are attached to the operation? – What impact do the constraints on the superclass have on its subclasses?
Invariants context CheckingAccount inv: bal >= limit
Problem Question: When during the execution is the validity of invariant enforced? bal = $100 withdraw ($70)=>bal = $30 deposit ($30)=>bal = $60 withdraw ($70)=>bal = -$10 deposit ($30)=>bal = $20 Need to have a checkpoint at the end of a series of transfers.
Proposed Informal Semantics If an operation is used to compute intermediate results, use “volatile” property volatile=true =>invariant is not enforced context CheckingAccount inv: bal >= limit context CheckingAccount::withdraw(n:Interger): void volatile=true …
Undefinedness of Pre and Post Undefinedness = non-existence of result – Exception undefinedness division by zero accessing object through a reference which is null – Non-termination undefinedness loops that run forever
Problem Question: Is it possible to specify non-terminating operations in OCL? In OCL, an operation is always required to terminate. “Exception undefinedness” only
Proposed Solution Require all query operations defined in OCL to terminate Other operations transforming the state may or may not terminate
Splitting of Constraints Question: What is the meaning when several constraints are attached to the same operation? Complex post and pre conditions are split into smaller ones: context CheckingAccount::withdraw(n: Integer) pre: (n>=0) and (bal – n >=limit) post: bal = – n context CheckingAccount::withdraw(n: Integer) pre: n>=0 post: true context CheckingAccount::withdraw(n: Integer) pre: bal – n >=limit post: bal = – n May not always be a good idea; some parts may not be satisfied n=2 bal=1 limit=0
Inheritance of Constraints Question: What impact do the constraints on the superclass have on its subclasses? Liskov’s Substitution Principle: A class can always be substituted by any of its subclasses.
Proposed Solution Two approaches: 1. Make developer responsible - may overlook critical cases - not consistent with object-oriented paradigm 2. Consider all constraints on superclass to be constraints on its subclasses. context A inv: INV1 context A::op(x:T) pre: PRE1 post: POST1 context B inv: INV2 context B::op(x:T) pre: PRE2 post: POST2 X context B inv: INV1 and INV2 context B::op(x:T) pre: PRE1 and PRE2 post: POST1 and POST2
Exercise context CheckingAccount inv: bal >= limit context CheckingAccount::withdraw(n: Integer) pre: (n>=0) and (bal – n >=limit) post: bal = – n context Account inv: bal >0 context Account::deposit(n: Integer) pre: n>0 post: bal = + n What is the full list of OCL constraints for CheckingAccount?
Result: context CheckingAccount inv: bal >0 and bal >= limit context CheckingAccount::deposit(n: Integer) pre: n>0 post: bal = + n context CheckingAccount::withdraw(n: Integer) pre: (n>=0) and (bal – n >=limit) post: bal = – n