首页 > 解决方案 > 在 ocl 集合中获取元素索引?[ocl_Eclipse]

问题描述

我正在处理以下域:

我的域图

我想表达以下约束:“不允许连续两次旋转类型的动作”我尝试了这个声明,但eclipse 没有识别 indexOf(element):

class Choreography
{
    property actions : Action[+|1] { ordered composes };
    attribute name : String[?];

    /*Succession of two actions of Type is not permitted */

    invariant rotate_succ:
    self.actions->asSequence()->forAll(a1:Action,a2:Action
        |

        a1.oclIsTypeOf(Rotate) and (indexOf(a1)=indexOf(a2)+1) implies  
        not a2.oclIsTypeOf(Rotate)
    )


    ;

有谁知道如何使用 ocl 集合中的随机元素的索引?

标签: eclipseocl

解决方案


OrderedCollection(T):indexOf(obj : OclAny[?]) : Integer[1]

操作需要一个 OrderedCollection (Sequence/OrderedSet) 作为它的源和一个 OclAny 作为它的参数。您尚未确定源,因此 OCL 将首先考虑一个导致

a1.indexOf(a1)
a2.indexOf(a1)

如果 Action 有 indexOf 操作,歧义将是一个错误。然后它考虑一个隐含的自我,它也失败了,因为没有 Choreography.indexOf() 操作。

我想你的意思是

self.actions->indexOf(a1)

等等等等,或者更易读地将 self.actions 放在一个 let 变量中以供多用。

(使用 oclIsTypeOf 很少是正确的。除非您有特定意图,否则使用 oclIsKindOf。)

(self.actions 已经是一个 OrderedCollection,所以不需要 asSequence())。

您对 indexOf 的使用将导致二次性能。最好使用索引 - 例如:

let theActions = self.actions in
    Sequence{1..theActions->size()-1}->forAll(index |
      theActions->at(index).oclIsKindOf(Rotate)
      implies not theActions->at(index+1).oclIsKindOf(Rotate))

推荐阅读