三元关系中下界多重some
和one
的语义难以理解。根据 Software Abstractions (Rev. ed。)第79-80页,关系addr: Book -> (Name -> some Addr)
应该等同于all b: Book | b.addr in Name -> some Addr
(另请参见第97页)。但后一个公式究竟意味着什么呢?我的想象力在这里失败了。这就是我在Alloy Analyzer 4.1.0中做过一些实验的原因。这个模型的含义是:
sig Name, Addr {}
sig Book { addr: Name -> some Addr }
assert implication {
#Book = 0 or all n: Name | some b: Book, a: Addr | n in b.addr.a
}
check implication
成立(没有发现反例)。因此,如果有任何书籍,每个名称应至少在其中一本书籍中注册。允许使用未记录的地址,如果没有书籍,也会突然显示未记录的名称。
以下模型的含义:
sig Name, Addr {}
sig Book { addr: Name some -> Addr }
assert implication {
#Book = 0 or all a: Addr | some b: Book | #b.addr.a > 0
}
check implication
再次举行。这是以前型号的镜像:除非根本没有书,否则禁止使用未记录的Addrs。对于姓名的文档没有任何限制。
两种型号可以组合使用,配方更简洁:
sig Name, Addr {}
sig Book { addr1: Name -> some Addr, addr2: Name some -> Addr }
assert implications {
some Book implies Name in Book.addr1.Addr and Addr in Book.addr2[Name]
}
check implications
因此,如果有任何Book,所有名称应该参与addr1和所有 Addrs参与addr2。多重性one
的行为相似。
似乎软件抽象和分析器并没有讲述像 R:A - >这样的结构的相同故事。 (B m - > n C)就下限约束而言,但我可能错过了一些东西。我发现的含义并不是我所预期的,可能还有其他奇怪的含义,我还没有发现。我越来越觉得嵌套的下限多重性毫无意义。我能纠正这个吗?
答案 0 :(得分:1)
第一个例子困惑了我很久;令我感到惊讶的是,在任何情况下都没有未映射的名称。然而,对于它的价值,我在p上找到了。第一版中的第78段声明“多重性只是一种简写,可以用标准约束代替;多重约束在
r: A m -> n B
可以写成
all a: A | n a.r
all b: B | m r.b
将第一个重写规则应用于语句
all b: Book | b.addr in Name -> some Addr
您从第一个示例模型派生出来,我们得到
all b: Book | all n: Name | some n.(b.addr)
或散文“对于所有书籍 b 和名称 n ,在 b.addr < n 中有一些映射< / em>“,至少解决了我最初的困惑。要允许未映射的名称,必须编写sig Book { addr: set (Name -> Addr) }
或(如旋风之旅的后续示例中)sig Book { names: set Name, addr: names -> some Addr}
。
我在第二次重写规则(涉及 m 的规则)方面遇到了一些麻烦。在Name
(没有 m )上没有明确的多样性,我花了一些时间查阅本书,找到关系上默认多重性约束的规范(类似于默认的{{ 1}}对于其他领域),并在得出没有默认多重性约束的结论之前,尝试各种编写等效约束的方法;相反,默认情况是没有多重性约束。所以第二次重写规则给出了p。 78不适用于one
;没有多重约束,效果是对于 Addr 中的每个 a ,可能有零个或多个(b.addr).a <的实例/ em>的
我想从语言设计的角度来看,我认为Name -> some Addr
有明确的“默认多重性约束”并允许使用
set
表示每个地址的 b.addr 中可能有零个或多个条目。
但我倾向于认为无论有没有这样的改变,你仍然可以说all b: Book | all a: Addr | set (b.addr).a
/* currently produces type error */
和some
在三元关系中的影响很难理解。