Domanda

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.

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top