在OCL中查找嵌套重复项

时间:2013-02-28 23:17:02

标签: ocl

我在尝试检查OCL中的重复项时遇到了挑战。

以下是类图的简化:

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

每个类的属性声明如下:

  • CHAPTERNAME
    • 名称
  • 目录
    • 分类

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

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

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

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

问题:如何添加更多限制来解决上述问题?

另外。我在Eclipse中使用Eclipse,EMF和OCL控制台。

1 个答案:

答案 0 :(得分: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()
     )

customerSet; books可以是BagSet(取决于是否允许重复的图书,我会假设它是Bag,但这并不重要)。然后customer.books是一袋书袋(每个顾客一袋),customer.books->flatten()是客户拥有的所有书籍的一袋。

catalog.booksBagSet(无关紧要)。 select操作仅返回给定catalog中包含的书籍(并且属于某些Customer,因为我们从之前构建的包中进行选择)。

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

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