Frage

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 stop

How 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.

War es hilfreich?

Lösung

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top