合金奇怪的行为?

时间:2017-04-04 16:09:28

标签: alloy

abstract sig S {}
one sig S1, S2 in S {}
fact {S1 != S2}
run {-1 < S1.(S2 -> 1)}

当我打开实例时,我得到了

integers={-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}
univ={-1, -2, -3, -4, -5, -6, -7, -8, 0, 1, 2, 3, 4, 5, 6, 7, S$0, S$1}
Int={-1, -2, -3, -4, -5, -6, -7, -8, 0, 1, 2, 3, 4, 5, 6, 7}
seq/Int={0, 1, 2, 3}
String={}
none={}
this/S={S$0, S$1}
this/S1={S$1}
this/S2={S$0}

来自评估者,

  

(1)S1。(S2-> 1)评估为{}

     

(2)none = S1。(S2 - > 1)评估为真

     

(3)-1&lt; S1。(S2-> 1)评估为真//为什么整数更小   而不是空集?

     

(4)-1&lt; none给出类型错误//这看起来不错但是给(3),为什么   这会给出类型错误吗?

     

(5)0 <= S1。(S2-> 1)评估为真

     

(6)0> = S1。(S2-> 1)评估为真

     

(7)0 = S1。(S2-> 1)评估为假//给定(5)(6),似乎   S1。(S2-> 1)评估为0,但不是。

     

(8)0 =无评估为假

     

(9)0&lt; = none给出类型错误//(8)(9)似乎很有趣   &#34; =&#34;不被解释为整数比较。

有谁可以解释为什么(1) - (9)发生?有错误吗?

1 个答案:

答案 0 :(得分:4)

(1)这应该是显而易见的原因:它是关系联接而S1S2

不同

(2)none评估为空集,所以给定(1)none = S1.(S2->1)

是有意义的

(3)那里没有类型错误,因为-1的类型是int,而S1.(S2->1)的类型是S.(S->int)int 。问题只是为什么-1小于某个求值为空集的整数类型表达式。首先,表达式-1 < S1.(S2->1)必须评估某些东西(即,不能像在编程语言中那样抛出异常)。此外,这是一个布尔表达式,因此它必须评估为truefalse。那么Alloy做的是,为了评估<运算符,它必须将两边都转换为单个(标量)整数,即使两边实际上都是整数集(所有都是合金中的集合/关系) ),它通过总结每组中存在的所有原子来实现。所以只是为了算术比较S1.(S2->1)评估为0

(4)现在应该很清楚-1 < none确实是一个类型错误,因为左侧的类型是int而右侧的类型是{{ 1}}

(5),(6)与(3)相同的解释

(7)none为false,因为0 = S1.(S2->1) 总是一组比较,而非整数比较。如果您尝试=之类的内容,则会获得1 + 2 = 3,因为集{1,2}不是{3}。

(8)同样的事情,false是一个集合比较

(9)相同的解释是针对(4)