我正在试验合金并编写了这段代码。
one sig s1{
vals: some Int
}{
#vals = 4
}
one sig s2{
vals: some Int
}{
#vals = 4
}
fact {
all a : s1.vals | a > 2
all i : s2.vals | i < 15
s1.vals = s2.vals
}
pred p{}
run p
在我看来,{3,4,5,6}至少是一个解决方案,但是Alloy说没有找到实例。当我发表评论s1.vals = s2.vals
或将i < 15
更改为i > 2
时,会找到实例。
有人可以解释一下为什么吗?感谢。
答案 0 :(得分:2)
整数的默认位宽是4位,而Alloy使用二进制补码整数,所以你的run p
要求一个整数范围从-8到7的世界。在那个世界中,约束i < 15
受整数溢出的影响,实际上是i < -1
。 (要看到这一点,请注释掉两个约束,以便获得一些实例。然后(a)浏览Analylzer生成的实例并查看其中出现的整数;您将看到它们的范围为我描述。另外,(b)打开评估员并输入数字&#34; 15&#34 ;;你会看到它在这个宇宙中的值是-1。)
如果您更改run
命令以为整数提供适当的位宽(例如run p for 5 int
),那么您将获得可能更符合您期望的实例。
然而,另一个改变,导致更惯用的Alloy模型,是通过定义值的sig来抽象出特定的值:
sig value {}
然后将s1和s2中vals
的声明从some Int
更改为some value
,并注释掉它们的数字约束(或替换其他一些有趣的约束)。然后在合适的范围内运行p(例如run p for 8 value
)。