Logic alloy:使用断言检查约束时的arity问题
我最近开始在一个项目中使用alloy进行实验,我遇到了一个不平等算术的问题。这里是一个简化的例子。我有四个签名:Logic alloy:使用断言检查约束时的arity问题,logic,alloy,Logic,Alloy,我最近开始在一个项目中使用alloy进行实验,我遇到了一个不平等算术的问题。这里是一个简化的例子。我有四个签名: 话 定义 文档:文档有文本(一系列单词) 字典:字典将一个单词序列映射到一个定义序列(为了保持简单,假设一个单词应该只有一个定义) 下面是一个简单的代码示例: module dictionaries open util/relation as relation sig Word {} sig Definition {} sig Document { text: s
- 话
- 定义
- 文档:文档有文本(一系列单词)
- 字典:字典将一个单词序列映射到一个定义序列(为了保持简单,假设一个单词应该只有一个定义)
module dictionaries
open util/relation as relation
sig Word {}
sig Definition {}
sig Document {
text: seq Word
}
sig Dictionary {
entries: seq Word,
defseq: seq Definition,
define: Word->Definition,
}{
//dictionary maps word to def only for the word present in dictionary
dom[define] = elems [entries] function [define, elems [entries]]
//content of the list of defintions
defseq = entries.define
}
//assert all word in a dictionary have a definition
assert all_word_defined {
all w: Word | all dict: Dictionary | some def: Definition |
//w in dict.entries implies w->def in dict.define
}
check all_word_defined
因此,我的问题是:
w意味着dict.define中的w->def
不起作用,因为dict.entries中的w
和dict.define中的w->def不具有相同的算术性,我得到错误消息“in只能在相同算术性的两个表达式之间使用”
我认为你在挣扎于
seq
和assertions
而不是arity
在合金中并不常见,您仅在需要更改元素顺序时使用它。在本例中,我认为在当前描述中不需要进行排序seq
- 断言验证整个模型的不变量。您试图断言的是您在模型中声明的事实,而不是您断言的事实。如果您已经定义了操作,并且希望验证某些事情永远不会发生,而不管这些操作是如何执行的以及以什么顺序执行的,那么断言非常有用。也就是说,断言验证的是模型的结果,而不是事实。(尽管有时用其他方式验证某些内容很有用。)
- Alloy在全局表中的导航功能非常强大。尽管看起来是面向对象的,关键是要理解字段实际上是连接的全局表。(这是我花了很长时间才弄到的。)
- 模型中不应有冗余信息。可以使用
表中的函数对define
、条目
和defseq
进行建模定义
- 基础语言非常强大。对于这种规模的问题,您通常不需要任何实用程序。尤其是在你感受到合金的关系模型之后,关系似乎显得相当多余李>
sig Definition {}
sig Dictionary {
define : Word -> one Definition,
}
define
表(即Dictionary->Word->Definition
)有一个约束,即对于给定的Dictionary->Word组合,必须有一个定义。这意味着并非所有单词都必须在表中,但如果一个单词在表中,则必须只有一个定义。(您也可以使用其他约束对此进行建模。最好是写出一个表并查看列。)
您可以将条目
定义为字典中的一组单词。您可以将其作为函数更好地建模:
fun Dictionary.entries : set Word {
this.define.univ
}
第一个联接选择define
表中的this
字典并删除第一列。第二个联接将删除最后一列
类似于defseq
:
fun Dictionary.defseq : set Definition {
this.define[univ]
}
box join[]
只将方括号的内部与其前面的表的第一列连接起来,留下定义列。即:
(univ).(this.define)
如何检查断言是否遵守此约束
我认为不清楚你试图断言什么。(这是你发现的正式语言的力量!)在Alloy中,你陈述了一个事实,即字典中的一个词映射到一个定义。断言你定义为事实的东西是没有用的。在断言之前,首先需要更多的定义
通常,您开始编写谓词,然后查找模型的示例。例如,如果我们想看《无限字典》中的一本,那么我们可以写:
pred show( d : Dictionary ) {
d.define.univ = Word
}
run show for 5
在本例中,您将看到一本字典,其中每个单词都有一个定义
我写了一篇可能对你有用的博客:谢谢你的回复和博客帖子!将映射视为表当然很有用。我知道我不应该试图断言什么是事实。问题是,我与其他人合作,而且我非常擅长创造自己的事实(我可以在实例中看到反例)。因此,断言帮助我再次检查我是否正确地表达了我的事实!特别是当我得到很多实例时,我不想点击几百个实例来查看所有的实例是否正确…PS:alloy analyzer对你的命题fun Dictionary.entries{this.define.univ}
(它告诉我有语法错误)。你能把你的模型放到Github上吗?
pred show( d : Dictionary ) {
d.define.univ = Word
}
run show for 5