Alloy 中两个表达式之间的区别?

Difference between two expressions in Alloy?

假设我们有以下 Alloy 模型:

abstract sig Season {}
one sig Spring, Summer, Fall, Winter extends Season {}

abstract sig Student {
  bornIn: one Season
}

abstract sig Freshman, Sophomore extends Student {}
one sig John, Walter extends Freshman {}
one sig Sarah extends Sophomore {}

pred isCompatibleWith(s1, s2: Student) {
  s1.bornIn = s2.bornIn
}

我想说大二的Sarah绝对不能和任何大一的人合得来

fact {
  not Sarah.isCompatibleWith[Freshman]
}

Alloy 对我的语法很满意。我添加一个断言:

assert WhyDoesThisNotHold {
 not Sarah.isCompatibleWith[John]
}

但是Alloy找到了一个反例:莎拉和约翰都出生在夏天!

而当我将 fact 更改为此时,Alloy 没有找到反例:

fact {
  no f: Freshman | Sarah.isCompatibleWith[f]
}

这两种语法有什么区别,为什么第一种语法不符合我的预期? (因为它是有效的 Alloy 语法,它实际上在说什么?)

你的第一个事实并不像你预期的那样,因为你用所有 Freshman 的集合作为参数调用谓词 isCompatibleWith,但是这个谓词并不意味着检查两个之间的兼容性套学生。 (可以通过用交集运算符 & 替换 = 符号并检查结果集是否为空。

我现在将向您展示这个事实如何不妨碍约翰和莎拉兼容。 假设 Sarah 和 John 出生在夏天,Walter 出生在冬天,那么事实成立,因为 :

not Sarah.isCompatibleWith[Freshman]  =  not Sarah.isCompatibleWith[Walter+John]
                                      =  not Sarah.bornIn=(Walter+John).bornIn
                                      =  not Summer = (Summer+Winter)
                                      =  not false
                                      =  true