什么时候合金模型太抽象,什么时候不够抽象?

时间:2017-11-09 14:44:48

标签: alloy

my last Stack Overflow post中,我问如何创建一个Alloy模型,该模型限制每个反斜杠被另一个反斜杠转义,前提是反斜杠不会转义为逗号。 Daniel Jackson回复了我的帖子,建议我的模型应该更抽象。事实上,我已经创建了一个更抽象的模型。但我觉得它过于抽象,它避免了正确约束反斜杠的问题(见this post)。

我很困惑,什么时候合金模型太抽象了,什么时候不够抽象?

1 个答案:

答案 0 :(得分:0)

首先,我认为你的模型对底层世界模型的表达过于复杂。我认识到你正在努力解决的问题,逃避。这肯定是一个令人讨厌的领域。

对我而言,关键是让模型使用seq,因为它是一系列Char。

abstract sig Char {}
    abstract sig EscapedCharacter extends Char {}
one sig A,B,C extends Char {}
one sig Backslash, Comma extends EscapedCharacter {}

pred valid[ string : seq Char ] {
    string.isEmpty 
    or 
        string[0] = Backslash 
            implies {
              # string > 1 
          and string[1] in EscapedCharacter 
          and valid[ string.subseq[2,#string]]
                }
            else string[0] != Comma and valid[ string.rest ]    
}

run valid for 4

不幸的是,这使用了递归。我实际上失败了如何在没有递归的情况下指定它,但我试图找出答案。不幸的是,因为你需要在菜单中启用递归,这仅限于3个级别,即使很小的问题也是如此。这种限制的原因是递归需要展开,这会爆炸状态空间。 但是,我希望我们能找到一种让递归更像是一等公民的方法,因为大多数开发人员的可读性都很高。

无论如何,当我们断言一些例子时它看起来很有用:

assert InvalidExample {
    not valid[ 0->Backslash ]
}
check InvalidExample for 4

assert InvalidExample2 {
    not valid[ (0->A) + (1->Backslash) + (2->Backslash)+  (3->Comma) ]
}
check InvalidExample2 for 4

assert ValidExample {
    valid[ (0->Backslash) + (1->Comma) ]
}
check ValidExample for 4

已更新错过原始要求逗号必须始终前面加一个反斜杠(我应用了我的常识,而不是按字面意思读取。)