三元关系中的多重性



三元关系中下界乘法someone的语义很难理解。根据软件摘要(修订版)第79-80页,关系式addr: Book -> (Name -> some Addr)应等同于all b: Book | b.addr in Name -> some Addr(另见第97页)。但后一个公式究竟意味着什么?我的想象力在这里失灵了。这就是为什么我在合金分析仪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

成立(未找到反例)。因此,如果有任何一本书,每个名字都应该至少在其中一本书中注册。允许使用未记录的Addrs,如果没有Books,突然间也允许使用未登记的Names。

以下模型的含义:

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

再次保持。这与之前的模式如出一辙:除非根本没有Book,否则禁止无证Addr。而且在名称的文档方面没有任何限制。

这两种模型可以组合在一起,公式更简洁:

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,所有Addr都应参与addr2。多重性one表现相似。

就下界约束而言,软件抽象和Analyser似乎没有讲述像R:A->(Bm->nC)这样的结构的相同故事,但我可能遗漏了一些东西。我发现的含义并不是我所期望的,可能还有其他奇怪的含义我还没有发现。我越来越觉得嵌套的下界乘法毫无意义。我说得对吗?

第一个例子让我困惑了很长一段时间;让我惊讶的是,在任何情况下都没有未映射的名字。然而,值得一提的是,我在第一版的第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的映射",这至少解决了我最初的困惑。要允许未映射的名称,必须编写sig Book { addr: set (Name -> Addr) }或(如Whirlwind教程中稍后的示例所示)sig Book { names: set Name, addr: names -> some Addr}

我在第二条重写规则(涉及m的规则)上遇到了更多的麻烦。Name上没有显式多重性(nom),我花了一些时间翻阅这本书,找到了关系上默认多重性约束的规范(类似于其他领域的默认one),并尝试了各种写等价约束的方法,然后得出结论,不存在默认多重性限制;相反,默认情况是存在多重性约束。因此,第78页给出的第二条重写规则不适用于Name -> some Addr;不存在多重性约束,其效果是,对于Addr中的每个a,可能有零个或多个(b.Addr).a实例

我想从语言设计的角度来看,我认为set的显式"默认多重性约束"和允许这样的语句可能会有所帮助

all b: Book | all a: Addr | set (b.addr).a
/* currently produces type error */

意思是对于每个地址,在b.addr中可能有零个或多个条目。

但我倾向于认为,无论是否有这样的变化,你仍然可以正确地说,someone在三元关系中的作用可能很难把握。

相关内容

最新更新