为什么多个Alloy声明不等同于嵌套的Alloy声明?

时间:2017-10-08 19:44:30

标签: alloy

Software Abstractions的第293页说这两者是等价的:

all x: X, y: Y | F

all x: X | all y: Y | F

但这两个不等同:

one x: X, y: Y | F

one x: X | one y: Y | F

为什么后两者不相同?

我通过具体的例子学得最好,所以让我们举一个具体的例子。

上周我乘船游览阿拉斯加。晚餐时我和另外五个人坐在一起。其中一对夫妇(杰森和丹尼斯)正在庆祝他们的第25个(银色)结婚纪念日。

我在餐桌上创造了一个人们的合金模型。该模型指出,有一个m:man,w:女士夫妇,其妻子是w,w的丈夫是m,m和w正在庆祝银纪念日:

one m: Man, w: Woman |
    m.wife = w and 
    w.husband = m and 
    m.anniversary = Silver and
    w.anniversary = Silver

Alloy Analyzer生成的实例符合我的预期。

然后我修改了表达式以使用嵌套表达式:

one m: Man |
    one w: Woman |
        m.wife = w and 
        w.husband = m and 
        m.anniversary = Silver and
        w.anniversary = Silver

Alloy Analyzer生成了相同的实例!

接下来,我写了一个断言,断言这两个版本是等价的:

Version1 iff Version2

合金分析仪返回:没有找到反例!

以下是我的模特。为什么两个版本相同?是否有一个小的调整,我可以对模型显示嵌套版本和非嵌套版本之间的差异?

罗杰在阿拉斯加游轮餐桌上的合金模型

abstract sig Man {
    wife: lone Woman,
    anniversary: lone Anniversary
}
one sig Roger extends Man {}
one sig Jason extends Man {}

abstract sig Woman {
    husband: lone Man,
    anniversary: lone Anniversary
}
one sig Faye extends Woman {}
one sig Nina extends Woman {}
one sig Claudia extends Woman {}
one sig Denise extends Woman {}

abstract sig Anniversary {}
one sig Silver extends Anniversary {}

pred v1_One_couple_celebrating_25th_wedding_anniversary {
    one m: Man, w: Woman | m.wife = w and w.husband = m and 
                           m.anniversary = Silver and w.anniversary = Silver }

pred v2_One_couple_celebrating_25th_wedding_anniversary {
    one m: Man | 
        one w: Woman | 
            m.wife = w and w.husband = m and 
            m.anniversary = Silver and w.anniversary = Silver }

assert Both_versions_are_identical {
    v1_One_couple_celebrating_25th_wedding_anniversary 
    iff
    v2_One_couple_celebrating_25th_wedding_anniversary
}
check Both_versions_are_identical

2 个答案:

答案 0 :(得分:2)

您可以运行这些示例来查看差异:

sig Man {}

sig Woman { 
    // married is a relation Woman set -> set Man
    married : set Man 
}

// there is exactly one married couple
run { one w : Woman, m : Man | w->m in married } for 5

// there is exactly one woman that has exactly one husband;
// apart from that, several men may share a wife, and vice-versa
run { one w : Woman | one m : Man | w->m in married } for 5

答案 1 :(得分:0)

谓词太过限制,无法产生差异。

如果示例被修改了一下,可以看到嵌套版本和非嵌套版本之间的区别:允许每个人与一组女性结婚:

sig Man {
    wives: set Woman
}

将约束放宽到:w in m.wives

这是新的非嵌套版本:

one m: Man, w: Woman |
    w in m.wives and
    w.husband = m and
    w.anniversary = Silver

那里说的只有一个男人:男人,女士:w是妻子中的一个,w的丈夫是m,m和w正在庆祝银子纪念日。

这是合金分析仪生成的一个实例:Man1有妻子Woman1和Woman2。 Woman1有丈夫Man1。同样,Woman2有丈夫Man1。 Woman1正和她的丈夫(Man1)庆祝25周年结婚纪念日。

以下是嵌套版本:

one m: Man |
    one w: Woman | 
        w in m.wives and 
        w.husband = m and
        w.anniversary = Silver

这就是说只有一个m:约束为真的男人,其约束条件是:有一个女人,女人是男人的妻子,他们结婚25年。可能有另一个约束为真的人。

这是合金分析仪生成的一个实例:Man1有妻子Woman0和Woman1。 Man1和Woman1结婚25年。 Man2有妻子Woman2。他们已经结婚25年了。

以下是Alloy模型。

男性与多个妻子结婚的合金模型

sig Man {
    wives: set Woman
}

sig Woman {
    husband: lone Man,
    anniversary: lone Anniversary
}

abstract sig Anniversary {}
one sig Silver extends Anniversary {}

pred v1_One_couple_celebrating_25th_wedding_anniversary {
    one m: Man, w: Woman | w in m.wives and w.husband = m and 
                           w.anniversary = Silver 
}

pred v2_One_couple_celebrating_25th_wedding_anniversary {
   one m: Man |
        one w: Woman | 
            w in m.wives and w.husband = m and w.anniversary = Silver 
}

assert Both_versions_are_identical {
    v1_One_couple_celebrating_25th_wedding_anniversary 
    iff
    v2_One_couple_celebrating_25th_wedding_anniversary
}   
check Both_versions_are_identical