I use Bold for Delphi that has an implementation of OCL. OCL is good at filtering lists, etc. But I have not found a good, generic way of traversing linked lists.
Suppose I have a class PlanMission
. It contains a single link PlanMission.previous
that points to itself. It also has a boolean attribute isDummy
.
I want to traverse a list of PlanMissions
until I have an instance with isDummy
.
I can do
if isdummy then
self
else if previous->notEmpty and previous.isdummy then
previous
else if previous.previous->notEmpty and previous.previous.isdummy then
previous.previous
else
nil
endif
endif
endif
What I really want is something like this:
traverseList(previous, isDummy)
traverseList
does not exist, but it should have 2 parameters.
previous
: The link to follow isDummy
: A boolean condition so I know when to stopHow can this be accomplished?
Edit clarification I don't want any Delphi code. I want code in OCL. Those that use Bold know what I mean. OCL is a query language with query objects, attributes, etc. It is free of side effects, so it is readonly. Introduction to OCL can be found here.
You need to compute the ordered transitive closure of the previous
relationship.
(self, self.previous, self.previous.previous, etc.)
In OCL 2.3.1 it is self->asOrderedSet()->closure(previous)
then you may extract the first dummy PlanMission
(or null if there is none) by:
let c:Set(PlanMission) =
self->asOrderedSet()->closure(previous)->select(x|x.isDummy) in
if c->isEmpty() then null else select(x|x.isDummy)->first()
In section 11.9 Mapping Rules for Predefined Iterator Expressions of OCL 2.3.1 there is a definition of closure
in terms of iterate
that you may use if your tool supports an older version of OCL.