1

在尝试检查 OCL 中的重复项时,我面临着挑战。

这是类图的简化:

                                       +-----------+
                                       |ChapterName|
                                       +-----------+
                                           ^ 0..* chapterNames
                                           |
                                           ^
                                           V
                 +-------+    books 0..* +----+
                 |Catalog|<>------------>|Book|
                 +-------+               +----+
      catalogs 0..* ^                       ^ 0..* books
                    |                       | 
                  +----+  customers 0..* +--------+
                  |Shop|<>-------------->|Customer|
                  +----+                 +--------+

每个类的属性声明如下:

  • 章节名称
    • 姓名
  • 目录
    • 类别

问题: 我要检查的是客户是否有任何章节名称重复的书籍,也属于目录中的特定类别。

我还没有设法绕开逻辑。到目前为止,我所拥有的是:

context Shop
self.customers.books->select(cubks | cubks =
  self.catalogs.books->select(cabks | cabks = cubks)->first())

...应该从客户拥有的目录中找到书籍。

问题:如何添加更多约束来解决上述问题?

还。我在 Eclipse 中使用 Eclipse、EMF 和 OCL 控制台。

4

1 回答 1

1
context Shop::checkForDuplicates(catalog:Catalog)
post: result = 
     self.customer.books->flatten()->select(book|
       catalog.books->contains(book)
     )->forEach(book|
       chapterNames->asSet()->size()=chapterNames->size()
     )

customer是一个Setbooks是 aBag或 a Set(取决于是否允许重复书籍,我假设它是 a Bag,尽管没关系)。然后customer.books是一袋书(每个顾客一个袋子),customer.books->flatten()是一袋顾客拥有的所有书籍。

catalog.books是 aBag或 a Set(没关系)。该select操作仅返回给定中包含的那些书catalog(并且属于 some Customer,因为我们是从之前构建的包中选择的)。

book.chapterNames是一个Sequence(我假设关联是有序的)与那本书中的章节名称。对于集合中的每个元素(即对于给定目录中的每一本书,由客户拥有)forAll返回iff,主体评估为.truetrue

现在的诀窍是依靠 operation Sequence::asSet(),它返回序列中的所有元素,并删除了重复项。然后,如果没有元素被删除(即如果每个元素都是唯一的),则包的大小等于集合的大小。

于 2013-03-01T02:47:09.417 回答