为什么Alloy中两个模型的一致性检查性能没有差别?

时间:2015-03-27 13:35:55

标签: alloy

我有以下两种型号。第一个描述模型。 在第二个模型中删除了Node Gender及其相关的边和约束。 enter image description here

//Signatures for nodes
sig NPerson{}
abstract sig NGender{}
abstract sig NCivilStatus{}
lone sig Nmale, Nfemale extends NGender{}
lone sig Nmarried, Nsingle, Ndivorced, Nwidowed extends NCivilStatus{}

//Signatures for edges
sig Ehusband{src:one NPerson, trg:one NPerson}
sig Ewife{src:one NPerson, trg:one NPerson}
sig EpGender{src:one NPerson, trg:one NGender}
sig EpCivstat{src:one NPerson, trg:one NCivilStatus}

//facts
fact HasHusbandIsMarried{
    all h:Ehusband|let P0=h.src,P1=h.trg|
    (P0=h.src and P1=h.trg) implies (some civstat0:EpCivstat|let married=civstat0.trg|
    (civstat0.src=P0 and married in Nmarried)) 
}

fact inv_Ewife_Ehusband{
    all x:NPerson, y:NPerson| (some xy:Ehusband| xy.src=x and xy.trg=y) <=>  (some yx:Ewife| yx.src=y and yx.trg=x) 
}

fact multi_EpCivstat{
    //mulitplicity on pCivstat:Person->CivilStatusmin:1;max:1
    all n:(NPerson)| let count = #{e:(EpCivstat)| e.src = n}| count>=1 and count <=1}

fact MarriedWithoutHusband{
    all civstat0:EpCivstat|let P0=civstat0.src,married=civstat0.trg|
    married in Nmarried and not (some h:Ehusband|let P2=h.trg|
    h.src=P0) implies (some w:Ewife|let P1=w.trg|
    w.src=P0) 
}

fact HasWifeIsMarried{
    all wife0:Ewife|let P1=wife0.src,Person1=wife0.trg|
    (P1=wife0.src and Person1=wife0.trg) implies (some civstat0:EpCivstat|let married=civstat0.trg|
    (civstat0.src=P1 and married in Nmarried)) 
}

fact multi_EpGender{
    //mulitplicity on pGender:Person->Gendermin:1;max:1
    all n:(NPerson)| let count = #{e:(EpGender)| e.src = n}| count>=1 and count <=1}

fact mult1_Ehusband{
    //mulitplicity on husband:Person->Person[0,1]
    all n:(NPerson)| lone e:(Ehusband)|e.src=n
}

fact mult1_Ewife{
    //mulitplicity on wife:Person->Person[0,1]
    all n:(NPerson)| lone e:(Ewife)|e.src=n
}

fact xor_Ewife_Ehusband{
    //XOR constraint between wife:Person->Person and husband:Person->Person
    all n:(NPerson) | let e1 = (some e : Ewife | e.src = n), e2=(some e : Ehusband | e.src = n)|(e1 or e2) and not(e1 and e2)
}

fact MarriedWithoutWife{
    all s:EpCivstat|let p1=s.src,married=s.trg|
    married in Nmarried and not (some w:Ewife|let p3=w.trg|
    w.src=p1) implies (some h:Ehusband|let p2=h.trg|
    h.src=p1) 
}

fact surj_EpGender{
    //surjective on pGender:Person->Gender
    all n:(NGender)| some e:(EpGender)| e.trg = n
}

fact irr_Ehusband{
    //reflexive on husband:Person->Person
    no e:(Ehusband)| e.src = e.trg
}

fact AtLeastOneSingle{
    some civstat0:EpCivstat|let P0=civstat0.src,single=civstat0.trg|
    single in Nsingle
}

fact surj_EpCivstat{
    //surjective on pCivstat:Person->CivilStatus
    all n:(NCivilStatus)| some e:(EpCivstat)| e.trg = n
}

fact irr_Ewife{
    //reflexive on wife:Person->Person
    no e:(Ewife)| e.src = e.trg
}

Alloy中的第二个模型

//Signatures for edges
sig Ehusband{src:one NPerson, trg:one NPerson}
sig Ewife{src:one NPerson, trg:one NPerson}
sig EpCivstat{src:one NPerson, trg:one NCivilStatus}

//facts
fact HasHusbandIsMarried{
    all h:Ehusband|let P0=h.src,P1=h.trg|
    (P0=h.src and P1=h.trg) implies (some civstat0:EpCivstat|let married=civstat0.trg|
    (civstat0.src=P0 and married in Nmarried)) 
}

fact inv_Ewife_Ehusband{
    all x:NPerson, y:NPerson| (some xy:Ehusband| xy.src=x and xy.trg=y) <=>  (some yx:Ewife| yx.src=y and yx.trg=x) 
}

fact multi_EpCivstat{
    //mulitplicity on pCivstat:Person->CivilStatusmin:1;max:1
    all n:(NPerson)| let count = #{e:(EpCivstat)| e.src = n}| count>=1 and count <=1}

fact MarriedWithoutHusband{
    all civstat0:EpCivstat|let P0=civstat0.src,married=civstat0.trg|
    married in Nmarried and not (some h:Ehusband|let P2=h.trg|
    h.src=P0) implies (some w:Ewife|let P1=w.trg|
    w.src=P0) 
}

fact HasWifeIsMarried{
    all wife0:Ewife|let P1=wife0.src,Person1=wife0.trg|
    (P1=wife0.src and Person1=wife0.trg) implies (some civstat0:EpCivstat|let married=civstat0.trg|
    (civstat0.src=P1 and married in Nmarried)) 
}

fact mult1_Ehusband{
    //mulitplicity on husband:Person->Person[0,1]
    all n:(NPerson)| lone e:(Ehusband)|e.src=n
}

fact mult1_Ewife{
    //mulitplicity on wife:Person->Person[0,1]
    all n:(NPerson)| lone e:(Ewife)|e.src=n
}

fact xor_Ewife_Ehusband{
    //XOR constraint between wife:Person->Person and husband:Person->Person
    all n:(NPerson) | let e1 = (some e : Ewife | e.src = n), e2=(some e : Ehusband | e.src = n)|(e1 or e2) and not(e1 and e2)
}

fact MarriedWithoutWife{
    all s:EpCivstat|let p1=s.src,married=s.trg|
    married in Nmarried and not (some w:Ewife|let p3=w.trg|
    w.src=p1) implies (some h:Ehusband|let p2=h.trg|
    h.src=p1) 
}

fact irr_Ehusband{
    //reflexive on husband:Person->Person
    no e:(Ehusband)| e.src = e.trg
}

fact AtLeastOneSingle{
    some civstat0:EpCivstat|let P0=civstat0.src,single=civstat0.trg|
    single in Nsingle
}

fact surj_EpCivstat{
    //surjective on pCivstat:Person->CivilStatus
    all n:(NCivilStatus)| some e:(EpCivstat)| e.trg = n
}

fact irr_Ewife{
    //reflexive on wife:Person->Person
    no e:(Ewife)| e.src = e.trg
}

我使用run {}来检查两个模型的一致性。 这两个模型没有实例。 我想看看性能差异。所以我使用范围直到23。 但结果并不是我的预期。

模型不一致。因此,为了找到模型的有效实例,或确定没有实例,我希望分析器需要检查模型的每个可能实例。直观地说,如果我们删除部分结构,应该检查更少的可能实例,这意味着检查应该花费更少的时间。

但是表现为第二 模型甚至比第一个模型更差。 以下是两种型号的验证时间(毫秒)。

Scope m1    m2
3   158     11
4   95      59
5   109     105
6   245     157
7   364     256
8   871     402
9   1652    646
10  1861    1479
11  1406    2418
12  5421    4343
13  6886    2609
14  10425   6553
15  13081   5871
16  19731   19453
17  16491   22249
18  21984   18191
19  39671   45510
20  60001   49958
21  67709   67892
22  101256  97801
23  135082  168585

有人可以解释原因吗?

1 个答案:

答案 0 :(得分:1)

在非常高的抽象层次上,我认为你的谜题的答案在于Jackson的软件抽象第2.2节中的讨论:

  

当然,分析仪不会单独构建和检查每个案例;即使每个案例只使用一个处理器周期,10个 30 个案[如前面第二节给出的例子]。 2.2]仍然需要比宇宙时代更长的时间。通过修剪可能性树,它可以排除大的子空间而无需完全检查它们。

有人猜测(但我没有测量过这个!)当第二个模型消除了一些约束时,它会使修剪搜索空间变得更加困难。 (为了衡量这一点,我会看看我是否可以构建第三个模型来保留额外的签名而不是约束,并看看它的时间比较。)

表演几乎总是一件复杂的事情;你通过测量而不仅仅是推测,迈出了正确的第一步。

[Postscript] 在较低的抽象级别,我为问题中包含的两个模型中的每个模型添加了一个空的谓词和run命令,将一些丢失的签名声明恢复为第二个,并比较了在默认范围内搜索实例所花费的时间。我不清楚这两个模型在性能方面存在一致的差异。乍一看,似乎同一模型中相同模型的运行之间的差异有时比模型1和模型2之间的差异更大。

Scope  Model 1...............  Model 2...............
       Trans.   Solve   Total  Trans.   Solve   Total

    3     132      32     164      17      11      28
           68      13      81      12      15      27 
           31      13      44      14       6      20
           23      12      35      10      47      57 
           13      16      29       9      15      24

    5      59      86     145      38     180     218
           37      88     125      54     103     157
           45      95     140      51     106     157
           31      89     120      24      89     113
           58      93     151      24      91     115

   10     640    6997    7637     140   13746   13886
          169    7237    7406     214   13717   13931
          189    6704    6893     188   15107   15295

   15     592   82872   83464     472   15522   15994
          543   78690   79233     574   16396   16970

   20    2701  840961  843662    1179 1082708 1083887

再看一下你报告的时间,我没有看到你所描述的事态的任何迹象:

  

但是第二个模型的性能甚至比第一个模型的性能更差。

相反,在您报告时间的21个范围中的16个中,模型2更快,而不是更慢。无论如何,差异并不是特别引人注目:对于大多数示波器,您报告两个模型的时间在10%或15%之间,而对于几乎所有示波器而言,报告的时间都在相同的数量级。 (所以,如果你现在告诉我一些或所有行的列被颠倒了,我的回答仍然是“告诉我为什么你认为这表明性能上有一个令人费解的差异”。)