2013-02-28 62 views
1

我在尝试检查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
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; booksBagSet(取决于是否允许重复的书籍,我假设它是Bag,尽管它并不重要)。然后customer.books是一袋书(每个顾客一袋),并且customer.books->flatten()是一袋所有顾客拥有的书籍。

catalog.booksBagSet(无所谓)。 select操作仅返回给定catalog中包含的那些书籍(因为我们从之前构建的包中选择,属于某个Customer)。

book.chapterNamesSequence(我假定关联订购),在这本书的章节的名称。 forAll返回true iff对于集合中的每个元素(即对于给定目录中的每个图书由客户拥有),则主体评估为true

现在的技巧是依赖于操作Sequence::asSet(),该操作返回序列中删除重复项的所有元素。然后,袋子的尺寸等于设置的尺寸,如果没有元素被移除(即,如果每个元素都是唯一的)。