Logic alloy:使用断言检查约束时的arity问题

Logic alloy:使用断言检查约束时的arity问题,logic,alloy,Logic,Alloy,我最近开始在一个项目中使用alloy进行实验,我遇到了一个不平等算术的问题。这里是一个简化的例子。我有四个签名: 话 定义 文档:文档有文本(一系列单词) 字典:字典将一个单词序列映射到一个定义序列(为了保持简单,假设一个单词应该只有一个定义) 下面是一个简单的代码示例: module dictionaries open util/relation as relation sig Word {} sig Definition {} sig Document { text: s

我最近开始在一个项目中使用alloy进行实验,我遇到了一个不平等算术的问题。这里是一个简化的例子。我有四个签名:

  • 定义
  • 文档:文档有文本(一系列单词)
  • 字典:字典将一个单词序列映射到一个定义序列(为了保持简单,假设一个单词应该只有一个定义)
下面是一个简单的代码示例:

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
因此,我的问题是:

  • 如何约束词典,使词典中的每个单词都映射到一个定义?按照上面的代码进行操作是否正确

  • 如何检查断言是否遵守此约束?显然,dict.entries中的code
    w意味着dict.define中的w->def
    不起作用,因为dict.entries中的
    w
    和dict.define中的
    w->def不具有相同的算术性,我得到错误消息“in只能在相同算术性的两个表达式之间使用”


  • 我认为你在挣扎于
    seq
    assertions
    而不是arity

    • seq
      在合金中并不常见,您仅在需要更改元素顺序时使用它。在本例中,我认为在当前描述中不需要进行排序
    • 断言验证整个模型的不变量。您试图断言的是您在模型中声明的事实,而不是您断言的事实。如果您已经定义了操作,并且希望验证某些事情永远不会发生,而不管这些操作是如何执行的以及以什么顺序执行的,那么断言非常有用。也就是说,断言验证的是模型的结果,而不是事实。(尽管有时用其他方式验证某些内容很有用。)
    • Alloy在全局表中的导航功能非常强大。尽管看起来是面向对象的,关键是要理解字段实际上是连接的全局表。(这是我花了很长时间才弄到的。)
    • 模型中不应有冗余信息。可以使用
      define
      表中的函数对
      条目
      defseq
      定义
      进行建模
    • 基础语言非常强大。对于这种规模的问题,您通常不需要任何实用程序。尤其是在你感受到合金的关系模型之后,关系似乎显得相当多余
    好的,一步一步:

    文档是一系列单词:

    我会把一个文档变成一组单词,因为这样更自然,也更容易使用。在这个问题中,单词的顺序不起作用,所以使用正规集似乎可以吗?(计算字数需要一个序号。)

    字典将一系列单词映射到一系列定义(为了保持简单,假设一个单词应该只有一个定义)

    我想你的意思是词典可以把一个词对应到一个定义?每个单词都有词条吗?还是有些词有词条?你说的“a”我认为是有一个定义的词?如果是:

     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