Employing the Object Constraint Language
in Model-Based Engineering
Martin Gogolla
University of Bremen
Database Systems Group
Outline
●
Motivation: About modeling
●
Modeling with UML and OCL
●
Validation and verification of structure
●
Validation and verification of behavior
Why do engineers build models?
- To understand
... problems and solutions
Models as "Means for Knowledge Acquisition"
- To communicate
... understanding and design intent
Models as "Means for Knowledge Transfer"
- To predict
... the interesting characteristics of system under study
Models as "Surrogates"
- To specify
... the implementation of the system
Models as "Blueprints"
Building models is done by selecting statements through
abstraction, i.e., reduction of information preserving
properties relative to a given set of concerns
[From: Bran Selic, UML2 Tutorial @ MoDELS 2012]
System under study Abstraction Statements (Models)
A model describes a Labelled Transition System
Outline
●
Motivation: About modeling
●
Modeling with UML and OCL
●
Validation and verification of structure
●
Validation and verification of behavior
Model analysis
●
Aim of model analysis: Check model for relevant and interesting
properties; detect deficiencies on the modeling level before
implementation
●
Example properties
– Is the set of states and transitions not empty?
Which properties do the states have?
– Which transition sequences are possible?
– Are the transitions deterministic?
Are there states with no outgoing transition?
– ...
●
General model properties: Consistency, Independence (Minimality),
Detection of consequences, Exploration of reachability, ...
(Textual) Modeling with UML and OCL within USE
(UML-based Specification Environment)
●
Class diagrams (classes, associations, generalization, abstract
classes, association clases, aggregation, composition, ...)
●
Protocol State Machines (states and guarded transitions)
●
Support for full OCL with all collection kinds (sets, bags, sequences,
ordered sets) and operations (forAll, select, collect, iterate, closure, ...)
●
Central assurance technique: Expressing scenarios (test cases);
UML object and sequence diagrams
●
Employing OCL for ad-hoc queries, class invariants, operation pre-
and postconditions, operation definitions (for side-effect free
operations), state invariants, transition pre- and postconditions
●
Employing SOIL (Simple Ocl-like Imperative Language) for
implementing operations manipulating the system state
●
Validation: Are we building the right product?
Verification: Are we building the product right?
Outline
●
Motivation: About modeling
●
Modeling with UML and OCL
●
Validation and verification of structure
●
Validation and verification of behavior
Model understanding and analysis with positive examples
●
Search for scenarios satisfying all constraints
●
Prove consistency of structural model
●
Provide valid object diagrams with meaningful objects and values to
stakeholders not interested in technical details
●
Systematically construct object diagrams in order to span up a
particular search space consisting of a sequence of object diagrams
●
Automatically construct object diagrams with the so-called
model validator which realizes a transformation from UML and OCL
into relational logic implemented in Alloy resp. Kodkod
All constraints valid: Consistency of invariants & inherent constraints
One constraint fails
context Person inv asymmetricFriendship:
inviter->intersection(invitee)->isEmpty
context Person inv listMembersMustBeFriends:
friends()->includesAll(ownedList->collect(l|l.member))
context Access inv accessOnlyToFriends:
accessed.poster.friends()->includesAll(accessor.pAccessor())
context Commenting inv commentOnlyByFriends:
commented.poster.friends()->includes(commenter)
context Commenting inv commentOnlyIfUndenied:
commented.denied()->excludes(commenter)
Person::friends():Set(Person)=
invitee->union(inviter)->excluding(self)
Person::pAccessor():Set(Person)=Set{self}
List::pAccessor():Set(Person)=member
Post::denied():Set(Person)=
access->select(deny=true).accessor.pAccessor()->asSet()
Model analysis with negative examples
●
Positive and negative scenarios (test cases) desireable
●
Scenarios may also violate constraints
●
Violating scenarios uncover interesting properties
Independence of invariants
●
Configure the invariants before calling the search procedure by
negating or disabling them
●
Explore invariant indepence by negating exactly one invariant
●
If successful, the found object diagram proves independence
● ∃ ObjDia ( INV1
ᴧ ¬ INV2
ᴧ INV3
)
↔ ∃ ObjDia ( INV1
ᴧ INV3
¬ᴧ INV2
)
↔ ∃ ObjDia ¬ ¬ ( INV1
ᴧ INV3
¬ᴧ INV2
)
↔ ¬ ∀ ObjDia ( ¬ ( INV1
ᴧ INV3
) ˅ INV2
)
↔ ¬ ∀ ObjDia ( INV1
ᴧ INV3
⇒ INV2
)
● INV2
independentOf ( INV1
ᴧ INV3
)
●
Similar technique can be employed for checking consequences
Outline
●
Motivation: About modeling
●
Modeling with UML and OCL
●
Validation and verification of structure
●
Validation and verification of behavior
Modeling Behavior with SOIL and Statecharts
●
Employ OCL pre- and postconditions for operations
●
Employ SOIL statements for implementing operations
manipulating the system state
●
Employ UML statecharts (UML protocol state machines)
for specifying complete object life cycles (in extension to the
OCL pre- and postconditions which cover single state transitions with
one pre and one post state)
●
Employ UML sequence diagrams for capturing execution traces
with object lifelines and exchanged messages
Life cycle restriction with state charts:
'accept' and 'decline' not always possible
class Person < Accessor
operations
invite(invitee:Person)
begin SOIL
[prescriptive]
insert (self,invitee) into Pendship;
invitee.invited(self);
end
pre inviteeNotSelf: invitee<>self OCL
[descriptive]
pre inviteeNotFriend: friends()->excludes(invitee)
pre inviteeNotPending: pends()->excludes(invitee)
post pInvited: self.pInvitee->includes(invitee)
accept(inviter:Person)
begin
inviter.accepted(self);
delete (inviter,self) from Pendship;
insert (inviter,self) into Friendship;
end
pre pInvited: inviter.pInvitee->includes(self)
post pendingCanceled: inviter.pInvitee->excludes(self)
post invited: inviter.invitee->includes(self)
decline(inviter:Person) ...
invited(inviter:Person) ...
accepted(invitee:Person) ...
declined(invitee:Person) ...
end
Result of scenario construction
●
Structural model: Class diagram and invariants
●
Behavioral model: Operation pre- and postconditions, SOIL operation
realization, and statecharts including transition pre- and
postconditions and state invariants
●
All operations touched at least once in the scenario
●
Invariants, operation pre- and postconditions, and transition pre- and
post conditions are all valid
●
Structural and behavioral model are consistent
Summary
●
Software development concentrating on models as first class citizens
●
Successfully applied approach in larger German project:
XGenerator @ Deutschland online
●
UML (Class and Statechart diagrams) in combination with OCL (not
mentioned yet the darker side of the force, namely class diagram
features like subsets, redefines, union, association inheritance and
association class inheritance)
●
SOIL (Simple Ocl-like Imperative Language) for operation
implementation together model unit tests (Object and Sequence
diagrams)
●
Employ model validator for searching object diagram spaces
●
Validation and verification
●
Aim of modeling: Obtain trustworthy models
Perspectives
●
Support for model transformation: From descriptive models to
prescriptive models, from platform-indepedent models to platform-
dependent ones, ...
●
Technical extension in USE
- statecharts features, e.g. adding change events and nested states
- sequence diagram, e.g. states and object diagram on lifelines
●
Filmstriping models, i.e. simulating system dynamics by encoding
filmstrips (state sequences and operation calls) into a single state
●
Temporal logic for dynamic properties!
Deontic logic for obligations and permissions?
●
Monitoring running applications (JVM, CRL, ...) with models
●
THANKS: to Mark Richters, Jörn Bohling, Fabian Büttner,
Mirco Kuhlmann and Lars Hamann for their work on USE!
Apologies for this long presentation. I did not find
the time to prepare a short smart one. [B. Pascal]
Thanks for your attention!
Relevant Properties
●
Consistency: Are the model inherent constraints (e.g., multiplicities,
agggregation, composition) and class invariants consistent? Is there
at least one object diagram? Empty populations? Finite populations?
Classes? Associations? Consistency also for other constraints, e.g.
invariants and operation pre- and postconditions?
●
Independence: Are the class invariants independent? Is there an
invariant which is implied by the other invariants? Are the invariants
implied by the operation pre- and postconditions?
●
Consequences: Is a newly stated invariant a consequence of the
stated ones? Must operationA always be followed by operationB?
●
Reachability: Is a given object diagram reachable from another object
diagram through a sequence of operation calls? Which operation calls
lead from a start object diagram to an end object diagram? Are there
operation call sequences leading to dead end object diagrams?
●
Many further properties worth to be investigated!
Example property: Agggregation and composition
context Person inv cannotBeMemberOfFriendsList:
ownedList.member.ownedList.member->excludes(self)
Object diagram
violating diamonds
and constraint
Pendship = Pending Friendship
Actual model a bit more complicated: internal operations needed
'on the other side' of the invitation: 'invited', 'accepted', and 'declined'
sys.String2ObjDia(
Sequence{
Tuple{PERSON:'ada',
INVITEES:Sequence{'bob','cyd'},
POSTS:Sequence{'ada_birthday','ada_marriage'},
COMMENTS:Sequence{'bob_promotion','well
done'},
DENIES:Sequence{'ada_birthday','cyd'}},
Tuple{PERSON:'bob',
INVITEES:Sequence{'cyd'},
POSTS:Sequence{'bob_birthday','bob_promotion'},
COMMENTS:Sequence{'ada_birthday','congrats',
'cyd_birthday','congrats'},
DENIES:Sequence{}},
Tuple{PERSON:'cyd',
INVITEES:Sequence{},
POSTS:Sequence{'cyd_birthday'},
COMMENTS:Sequence{'bob_promotion','cheers'},
DENIES:Sequence{'cyd_birthday','ada'}}})
System::String2ObjDia(s:
Sequence(Tuple(PERSON:String,
INVITEES:Sequence(String),
POSTS:Sequence(String),
COMMENTS:Sequence(String),
DENIES:Sequence(String))) )
String2ObjDia(s:Seq(Tuple(PERSON:String, parameters &
class/assoc
INVITEES:Sequence(String), SOIL
features
POSTS:Sequence(String),
COMMENTS:Sequence(String),
DENIES:Sequence(String))))
begin
declare ps:Person, po:Post, po_str:String, co_str:String,
co:Commenting, ps_str:String, ac:Access;
for x in s->collectNested(e|e.PERSON) do
ps:=new Person(x); end;
for x in s->collectNested(e|e.PERSON) do
for y in s->any(e|e.PERSON=x).INVITEES do
insert (Person.byUseId(x),Person.byUseId(y)) into Friendship; end;
end;
for x in s->collectNested(e|e.PERSON) do
for y in s->any(e|e.PERSON=x).POSTS do
po:=new Post(y); insert (Person.byUseId(x),Post.byUseId(y)) into
Posting;
end; end;
for x in s->collectNested(e|e.PERSON) do
for y in Set{0..(s->any(e|e.PERSON=x).COMMENTS->size() div 2)-1} do
po_str:=s->any(e|e.PERSON=x).COMMENTS->at(y*2+1);
co_str:=s->any(e|e.PERSON=x).COMMENTS->at(y*2+2);
co:=new Commenting between (Person.byUseId(x),Post.byUseId(po_str));
co.comment:=co_str; end; end;
for x in s->collectNested(e|e.PERSON) do
for y in Set{0..(s->any(e|e.PERSON=x).DENIES->size() div 2)-1} do
po_str:=s->any(e|e.PERSON=x).DENIES->at(y*2+1);
ps_str:=s->any(e|e.PERSON=x).DENIES->at(y*2+2);
ac:=new Access between(Post.byUseId(po_str),Person.byUseId(ps_str));
ac.deny:=true; end; end;
procedure societyComplete(numPerson:Integer,
numFriendship:Integer,
numList:Integer, numMember:Integer, numPost:Integer,
numComment:Integer, numDeny:Integer)
var persons:Sequence(Person), p1:Person, p2:Person,
lists:Sequence(List), l:List, po:Post, posts:Sequence(Post),
acc:Accessor, commentings:Sequence(Commenting),
accesses:Sequence(Access)
begin
persons:=CreateN(Person,[numPerson])
for i:Integer in [Sequence{1..numFriendship}]
begin p1:=Try([persons]) p2:=Try([persons])
if [p1.invitee->excludes(p2)] then
begin Insert(Friendship,[p1],[p2]) end
end
lists:=CreateN(List,[numList])
for i:Integer in [Sequence{1..numList}]
.. Insert(ListOwnership,[p1],[lists->at(i)]) ..
..ListMembership..Post..Posting..
for i:Integer in [Sequence{1..numComment}]
.. Create(Commenting,[p1],[po]) ..
..
for i:Integer in [Sequence{1..commentings->size}]
.. [commentings->at(i)].comment:=[''] ..
for i:Integer in [Sequence{1..numDeny}]
.. acc:=Try([persons->union(lists)]) ..
..
end
From B. Selic: MODELS 2012 Tutorial
context Person inv noSelfInvitation: OCL collection operations
invitee->excludes(self)
context p1,p2:Person inv symmetricFriends:
p1.friends()->includes(p2)=p2.friends()->includes(p1)
context Person inv listMembersMustBeFriends:
friends()->includesAll(ownedList->collect(l|l.member))
context Person inv asymmetricFriendship:
inviter->intersection(invitee)->isEmpty()
context Access inv accessOnlyToFriends: ...
context Commenting inv commentOnlyByFriends: ...
context Commenting inv commentOnlyIfUndenied:
commented.denied()->excludes(commenter)
Person::friends():Set(Person)=
invitee->union(inviter)->excluding(self)
Person::pAccessor():Set(Person)=Set{self}
List::pAccessor():Set(Person)=member
Post::denied():Set(Person)=
access->select(deny=true).accessor.pAccessor()->asSet()

Ecmfa2013

  • 1.
    Employing the ObjectConstraint Language in Model-Based Engineering Martin Gogolla University of Bremen Database Systems Group
  • 2.
    Outline ● Motivation: About modeling ● Modelingwith UML and OCL ● Validation and verification of structure ● Validation and verification of behavior
  • 3.
    Why do engineersbuild models? - To understand ... problems and solutions Models as "Means for Knowledge Acquisition" - To communicate ... understanding and design intent Models as "Means for Knowledge Transfer" - To predict ... the interesting characteristics of system under study Models as "Surrogates" - To specify ... the implementation of the system Models as "Blueprints" Building models is done by selecting statements through abstraction, i.e., reduction of information preserving properties relative to a given set of concerns [From: Bran Selic, UML2 Tutorial @ MoDELS 2012]
  • 4.
    System under studyAbstraction Statements (Models)
  • 5.
    A model describesa Labelled Transition System
  • 6.
    Outline ● Motivation: About modeling ● Modelingwith UML and OCL ● Validation and verification of structure ● Validation and verification of behavior
  • 8.
    Model analysis ● Aim ofmodel analysis: Check model for relevant and interesting properties; detect deficiencies on the modeling level before implementation ● Example properties – Is the set of states and transitions not empty? Which properties do the states have? – Which transition sequences are possible? – Are the transitions deterministic? Are there states with no outgoing transition? – ... ● General model properties: Consistency, Independence (Minimality), Detection of consequences, Exploration of reachability, ...
  • 9.
    (Textual) Modeling withUML and OCL within USE (UML-based Specification Environment) ● Class diagrams (classes, associations, generalization, abstract classes, association clases, aggregation, composition, ...) ● Protocol State Machines (states and guarded transitions) ● Support for full OCL with all collection kinds (sets, bags, sequences, ordered sets) and operations (forAll, select, collect, iterate, closure, ...) ● Central assurance technique: Expressing scenarios (test cases); UML object and sequence diagrams ● Employing OCL for ad-hoc queries, class invariants, operation pre- and postconditions, operation definitions (for side-effect free operations), state invariants, transition pre- and postconditions ● Employing SOIL (Simple Ocl-like Imperative Language) for implementing operations manipulating the system state ● Validation: Are we building the right product? Verification: Are we building the product right?
  • 11.
    Outline ● Motivation: About modeling ● Modelingwith UML and OCL ● Validation and verification of structure ● Validation and verification of behavior
  • 12.
    Model understanding andanalysis with positive examples ● Search for scenarios satisfying all constraints ● Prove consistency of structural model ● Provide valid object diagrams with meaningful objects and values to stakeholders not interested in technical details ● Systematically construct object diagrams in order to span up a particular search space consisting of a sequence of object diagrams ● Automatically construct object diagrams with the so-called model validator which realizes a transformation from UML and OCL into relational logic implemented in Alloy resp. Kodkod
  • 17.
    All constraints valid:Consistency of invariants & inherent constraints
  • 18.
  • 19.
    context Person invasymmetricFriendship: inviter->intersection(invitee)->isEmpty context Person inv listMembersMustBeFriends: friends()->includesAll(ownedList->collect(l|l.member)) context Access inv accessOnlyToFriends: accessed.poster.friends()->includesAll(accessor.pAccessor()) context Commenting inv commentOnlyByFriends: commented.poster.friends()->includes(commenter) context Commenting inv commentOnlyIfUndenied: commented.denied()->excludes(commenter) Person::friends():Set(Person)= invitee->union(inviter)->excluding(self) Person::pAccessor():Set(Person)=Set{self} List::pAccessor():Set(Person)=member Post::denied():Set(Person)= access->select(deny=true).accessor.pAccessor()->asSet()
  • 20.
    Model analysis withnegative examples ● Positive and negative scenarios (test cases) desireable ● Scenarios may also violate constraints ● Violating scenarios uncover interesting properties
  • 21.
    Independence of invariants ● Configurethe invariants before calling the search procedure by negating or disabling them ● Explore invariant indepence by negating exactly one invariant ● If successful, the found object diagram proves independence ● ∃ ObjDia ( INV1 ᴧ ¬ INV2 ᴧ INV3 ) ↔ ∃ ObjDia ( INV1 ᴧ INV3 ¬ᴧ INV2 ) ↔ ∃ ObjDia ¬ ¬ ( INV1 ᴧ INV3 ¬ᴧ INV2 ) ↔ ¬ ∀ ObjDia ( ¬ ( INV1 ᴧ INV3 ) ˅ INV2 ) ↔ ¬ ∀ ObjDia ( INV1 ᴧ INV3 ⇒ INV2 ) ● INV2 independentOf ( INV1 ᴧ INV3 ) ● Similar technique can be employed for checking consequences
  • 22.
    Outline ● Motivation: About modeling ● Modelingwith UML and OCL ● Validation and verification of structure ● Validation and verification of behavior
  • 23.
    Modeling Behavior withSOIL and Statecharts ● Employ OCL pre- and postconditions for operations ● Employ SOIL statements for implementing operations manipulating the system state ● Employ UML statecharts (UML protocol state machines) for specifying complete object life cycles (in extension to the OCL pre- and postconditions which cover single state transitions with one pre and one post state) ● Employ UML sequence diagrams for capturing execution traces with object lifelines and exchanged messages
  • 24.
    Life cycle restrictionwith state charts: 'accept' and 'decline' not always possible
  • 25.
    class Person <Accessor operations invite(invitee:Person) begin SOIL [prescriptive] insert (self,invitee) into Pendship; invitee.invited(self); end pre inviteeNotSelf: invitee<>self OCL [descriptive] pre inviteeNotFriend: friends()->excludes(invitee) pre inviteeNotPending: pends()->excludes(invitee) post pInvited: self.pInvitee->includes(invitee) accept(inviter:Person) begin inviter.accepted(self); delete (inviter,self) from Pendship; insert (inviter,self) into Friendship; end pre pInvited: inviter.pInvitee->includes(self) post pendingCanceled: inviter.pInvitee->excludes(self) post invited: inviter.invitee->includes(self) decline(inviter:Person) ... invited(inviter:Person) ... accepted(invitee:Person) ... declined(invitee:Person) ... end
  • 32.
    Result of scenarioconstruction ● Structural model: Class diagram and invariants ● Behavioral model: Operation pre- and postconditions, SOIL operation realization, and statecharts including transition pre- and postconditions and state invariants ● All operations touched at least once in the scenario ● Invariants, operation pre- and postconditions, and transition pre- and post conditions are all valid ● Structural and behavioral model are consistent
  • 33.
    Summary ● Software development concentratingon models as first class citizens ● Successfully applied approach in larger German project: XGenerator @ Deutschland online ● UML (Class and Statechart diagrams) in combination with OCL (not mentioned yet the darker side of the force, namely class diagram features like subsets, redefines, union, association inheritance and association class inheritance) ● SOIL (Simple Ocl-like Imperative Language) for operation implementation together model unit tests (Object and Sequence diagrams) ● Employ model validator for searching object diagram spaces ● Validation and verification ● Aim of modeling: Obtain trustworthy models
  • 34.
    Perspectives ● Support for modeltransformation: From descriptive models to prescriptive models, from platform-indepedent models to platform- dependent ones, ... ● Technical extension in USE - statecharts features, e.g. adding change events and nested states - sequence diagram, e.g. states and object diagram on lifelines ● Filmstriping models, i.e. simulating system dynamics by encoding filmstrips (state sequences and operation calls) into a single state ● Temporal logic for dynamic properties! Deontic logic for obligations and permissions? ● Monitoring running applications (JVM, CRL, ...) with models ● THANKS: to Mark Richters, Jörn Bohling, Fabian Büttner, Mirco Kuhlmann and Lars Hamann for their work on USE!
  • 35.
    Apologies for thislong presentation. I did not find the time to prepare a short smart one. [B. Pascal] Thanks for your attention!
  • 36.
    Relevant Properties ● Consistency: Arethe model inherent constraints (e.g., multiplicities, agggregation, composition) and class invariants consistent? Is there at least one object diagram? Empty populations? Finite populations? Classes? Associations? Consistency also for other constraints, e.g. invariants and operation pre- and postconditions? ● Independence: Are the class invariants independent? Is there an invariant which is implied by the other invariants? Are the invariants implied by the operation pre- and postconditions? ● Consequences: Is a newly stated invariant a consequence of the stated ones? Must operationA always be followed by operationB? ● Reachability: Is a given object diagram reachable from another object diagram through a sequence of operation calls? Which operation calls lead from a start object diagram to an end object diagram? Are there operation call sequences leading to dead end object diagrams? ● Many further properties worth to be investigated!
  • 37.
    Example property: Agggregationand composition context Person inv cannotBeMemberOfFriendsList: ownedList.member.ownedList.member->excludes(self) Object diagram violating diamonds and constraint
  • 38.
  • 39.
    Actual model abit more complicated: internal operations needed 'on the other side' of the invitation: 'invited', 'accepted', and 'declined'
  • 40.
  • 44.
    String2ObjDia(s:Seq(Tuple(PERSON:String, parameters & class/assoc INVITEES:Sequence(String),SOIL features POSTS:Sequence(String), COMMENTS:Sequence(String), DENIES:Sequence(String)))) begin declare ps:Person, po:Post, po_str:String, co_str:String, co:Commenting, ps_str:String, ac:Access; for x in s->collectNested(e|e.PERSON) do ps:=new Person(x); end; for x in s->collectNested(e|e.PERSON) do for y in s->any(e|e.PERSON=x).INVITEES do insert (Person.byUseId(x),Person.byUseId(y)) into Friendship; end; end; for x in s->collectNested(e|e.PERSON) do for y in s->any(e|e.PERSON=x).POSTS do po:=new Post(y); insert (Person.byUseId(x),Post.byUseId(y)) into Posting; end; end; for x in s->collectNested(e|e.PERSON) do for y in Set{0..(s->any(e|e.PERSON=x).COMMENTS->size() div 2)-1} do po_str:=s->any(e|e.PERSON=x).COMMENTS->at(y*2+1); co_str:=s->any(e|e.PERSON=x).COMMENTS->at(y*2+2); co:=new Commenting between (Person.byUseId(x),Post.byUseId(po_str)); co.comment:=co_str; end; end; for x in s->collectNested(e|e.PERSON) do for y in Set{0..(s->any(e|e.PERSON=x).DENIES->size() div 2)-1} do po_str:=s->any(e|e.PERSON=x).DENIES->at(y*2+1); ps_str:=s->any(e|e.PERSON=x).DENIES->at(y*2+2); ac:=new Access between(Post.byUseId(po_str),Person.byUseId(ps_str)); ac.deny:=true; end; end;
  • 45.
    procedure societyComplete(numPerson:Integer, numFriendship:Integer, numList:Integer, numMember:Integer,numPost:Integer, numComment:Integer, numDeny:Integer) var persons:Sequence(Person), p1:Person, p2:Person, lists:Sequence(List), l:List, po:Post, posts:Sequence(Post), acc:Accessor, commentings:Sequence(Commenting), accesses:Sequence(Access) begin persons:=CreateN(Person,[numPerson]) for i:Integer in [Sequence{1..numFriendship}] begin p1:=Try([persons]) p2:=Try([persons]) if [p1.invitee->excludes(p2)] then begin Insert(Friendship,[p1],[p2]) end end lists:=CreateN(List,[numList]) for i:Integer in [Sequence{1..numList}] .. Insert(ListOwnership,[p1],[lists->at(i)]) .. ..ListMembership..Post..Posting.. for i:Integer in [Sequence{1..numComment}] .. Create(Commenting,[p1],[po]) .. .. for i:Integer in [Sequence{1..commentings->size}] .. [commentings->at(i)].comment:=[''] .. for i:Integer in [Sequence{1..numDeny}] .. acc:=Try([persons->union(lists)]) .. .. end
  • 48.
    From B. Selic:MODELS 2012 Tutorial
  • 50.
    context Person invnoSelfInvitation: OCL collection operations invitee->excludes(self) context p1,p2:Person inv symmetricFriends: p1.friends()->includes(p2)=p2.friends()->includes(p1) context Person inv listMembersMustBeFriends: friends()->includesAll(ownedList->collect(l|l.member)) context Person inv asymmetricFriendship: inviter->intersection(invitee)->isEmpty() context Access inv accessOnlyToFriends: ... context Commenting inv commentOnlyByFriends: ... context Commenting inv commentOnlyIfUndenied: commented.denied()->excludes(commenter) Person::friends():Set(Person)= invitee->union(inviter)->excluding(self) Person::pAccessor():Set(Person)=Set{self} List::pAccessor():Set(Person)=member Post::denied():Set(Person)= access->select(deny=true).accessor.pAccessor()->asSet()