【问题标题】:How to express tree structure constraints如何表达树结构约束
【发布时间】:2021-01-20 09:07:19
【问题描述】:

如何表达以下约束:

1 - 恰好有一个文件夹不是另一个目录的子目录。 (我无法完全理解文件夹/子文件夹主题以及如何描述文件夹系统中唯一可能的排除项)

还有一些问题来自第一个问题

2 文件夹的最高嵌套数不超过n。

3) 你系统上的文件总数不能超过n。

4) 给定系统中的文件(子目录)总数不能超过n。

【问题讨论】:

  • 你有什么问题?
  • 哦,对不起。已编辑。我应该在 UML 中定义列出的约束
  • 可能一个子目录另一个目录意思是一个子目录另一个目录我> 。 (subdirectory) in 4 的目标是什么?为什么在 1 和 2 中没有对系统的引用,而在 3 和 4 中却是 your systema given system ?声明根本不清楚,我只能说您通常在 OCL 中使用 constraints 来满足这些要求,但是当声明不清楚时,我无法提供更多帮助
  • 我还是没看到问题。约束已定义。
  • 您是否正在寻找 OCL 约束?这些约束中的大多数不能使用简单的多重关联来表达。

标签: uml diagram ocl


【解决方案1】:

你的四个约束不能简单地用多重性来表达。

在 UML 中,这些约束可以使用 OCL 编写,请参阅 formal/2014-02-03

当然,约束可以写在类图中,例如参见formal/2017-12-05 的第 37 页的图 7.14 注释符号中的约束

1 - 恰好有一个文件夹不是另一个目录的子目录

一种写法是:

Folder.allInstances()->select(f | f.upfolder->isEmpty())->size() = 1

在哪里

  • Folder.allInstances() 返回类 Folder 的实例
  • Folder.allInstances()->select(f | f.upfolder->isEmpty()) 迭代实例并返回没有 upfolder 的实例
  • Folder.allInstances()->select(f | f.upfolder->isEmpty())->size() = 1 然后检查有一个没有 upfolder 的文件夹

2 文件夹的最高嵌套数不超过n

一种方法是定义一个计算文件夹深度的函数,然后检查所有文件夹的深度小于或等于 n

context Folder
def: depth() : Integer =
  if upfolder->notEmpty() then
    upfolder->first().depth() + 1
  else
    0

Folder.allInstances()->forAll(f | f.depth() <= n)

如果条件depth() &lt;= n 对所有元素都为真,则forAll 为真

但是只有计算没有子文件夹的文件夹的深度才有用,所以

Folder.allInstances()
  ->select(f | f.subfolder->isEmpty())
     ->forAll(f | f.depth() <= n)

3) 您系统上的文件总数不能超过n。

4) 给定系统中的文件(子目录)总数不能超过数量n。

我不明白为什么 4 中的 (subdirectory) 也不明白为什么 3on your system4a given system 而有12 中没有关于 system 的内容。

假设目标是检查文件总数小于或等于 n 并且文件夹的文件由属性 file 给出:

Folder.allInstances()->collect(f | f.file.size()).sum() <= n

在哪里

  • Folder.allInstances()-&gt;collect(f | f.file.size()) 返回所有文件夹的文件数集合
  • Folder.allInstances()-&gt;collect(f | f.file.size()).sum()返回文件总数

【讨论】:

  • 太棒了!你真的是这里的THE ocl 大师!
  • @Christophe 谢谢,是的,很少有人做 OCL,事实上我只用 OCL 来回答 S.O.所以我是初学者
【解决方案2】:

不鼓励使用 allInstances()。

  1. 非常希望有一些 FileSystem 类只有一个根文件夹,因此可以保证简单的多重性约束。

  2. 很容易通过 [0..3] 多重性声明处理。

  3. 由派生属性缓存的 depth() 助手是一个很好的解决方案。

或者只是:context File inv: Folder->closure(upFolder).size()

  1. 上下文文件夹 inv: self->closure(subfolder).File->size()

【讨论】:

  • The use of allInstances() is discouraged:由谁?你从哪里得到的?为什么,出于性能原因? OCL 是非常遥远的表演概念。声明中没有提供访问实例的方法,因此没有其他选择
  • 1. It is very desirable to have ... :确保拥有文件系统的根是正确的方式......但声明中没有任何内容,所以必须以其他方式进行
  • 2. Is easily handled by a [0..3] multiplicity declaration:关于什么的多重性?为什么 0..3 ?以及多重性如何处理文件夹的深度?
  • 3. A depth() helper helpfully cached by a derived property is a good solution. :首先深度是2.而不是3.,如果我们不必计算深度,它会更好,但首先它不存在于该语句,第二个必须在每次必须移动文件夹时更新,第三个注意“标准”文件系统中不存在信息。所以我指出了一种计算方法
  • 3. context Folder inv: self-&gt;closure(subfolder).File-&gt;size() &lt; n: 出于对关闭的怀疑(这就是我不使用它的原因),问题是关于系统的,所以只有当 self 是 (非直接可用)文件系统的根目录。当然,如果任何文件夹都是如此,那么它也适用于根目录
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
  • 1970-01-01
相关资源
最近更新 更多