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 = bal@pre – n context CheckingAccount::withdraw(n: Integer) pre: n>=0 post: true context CheckingAccount::withdraw(n: Integer) pre: bal – n >=limit post: bal = bal@pre – 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. X context A inv: INV1 context B inv: INV2 context A::op(x:T) context B::op(x:T) pre: PRE1 pre: PRE2 post: POST1 post: POST2 context B inv: INV1 and INV2 context B::op(x:T) pre: PRE1 and PRE2 post: POST1 and POST2 Exercise context Account context CheckingAccount inv: bal >0 inv: bal >= limit context Account::deposit(n: Integer) context CheckingAccount::withdraw(n: Integer) pre: n>0 pre: (n>=0) and (bal – n >=limit) post: bal = bal@pre + n post: bal = bal@pre – 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 = bal@pre + n context CheckingAccount::withdraw(n: Integer) pre: (n>=0) and (bal – n >=limit) post: bal = bal@pre – n