中国围棋游戏模型

时间:2014-12-20 19:34:42

标签: alloy

对于一个大学项目,我试图在Alloy中写下Go(http://en.wikipedia.org/wiki/Go_%28game%29)的中文游戏。 (我使用4.2版本)

我设法写了基础结构。在9 x 9宽的电路板上播放,但是我使用较小的3 x 3来更快地检查它。 该板由十字架制成,可以是空的,也可以是黑色或白色的石头。

abstract sig Colour {}
one sig White, Black, Empty extends Colour {}

abstract sig Cross { 
  Status: one Colour, 
  near: some Cross, 
  group: lone Group
}
one sig C11, C12, C13, 
        C21, C22, C23, 
        C31, C32, C33 extends Cross {}

sig Group {
  stones : some Cross, 
  freedom : some Cross
} 

pred closeStones {
  near= 
  C11->C12 + C11->C21 +
  C12->C11 + C12->C13 + C12->C22 +
  C13->C12 + C13->C23 +
  C21->C22 + C21->C11 + C21->C31 +
  C22->C21 + C22->C23 + C22->C12 + C22->C32 +
  C23->C22 + C23->C13 + C23->C33 +
  C31->C32 + C31->C21 +
  C32->C31 + C32->C33 + C32->C22 + 
  C33->C32 + C33->C23
}

fact stones2 {
   all g : Group | 
   all c : Cross | 
     (c.group=g) iff c in g.stones
}

fact noGroup{
  all c : Cross | (c.Status=Empty) iff c.group=none
}

fact groupNearStones {
  all disj c,d : Cross |
  ((d in c.near) and c.Status=d.Status) 
  iff 
  d.group=c.group
}

问题是:遵循Go规则,每个宝石都必须被视为一个群体的一部分。这个组由所有相同颜色的adiacent石头制成。 我的事实" groupNearStones"应足以描述这种情况,但这样我就无法获得由3块石头组成的团体。

我尝试过以不同的方式重写它,但是分析师说它找到了" 0变量"或者它将所有具有相同状态的宝石组合在一起,无论它们是否彼此靠近。

如果你能给我任何见解,我将不胜感激,因为我已经在这个简单的问题上打了几天。

1 个答案:

答案 0 :(得分:2)

问自己两个问题。

首先:在Go中,什么构成一个群体?你说自己:它是一组相同颜色的相邻宝石。并不是说小组中的每一块石头都必须彼此相邻;每块石头都可以与该组中的另一块石头相邻。

所以从正式的角度来看:给定一块石头S,组中的一组石头为S,是通过关系same_color_and_adjacent或S.*same_color_and_adjacent可到达的石头的传递闭合。

第二:什么构成相同的颜色和相邻?我认为你可以用你拥有的东西轻松定义。

侧面问题;如果你重新确定行和列的概念,你可能会发现将模型扩展到任意大小的板更容易。

我希望这会有所帮助。

[附录:]显然它没有足够的帮助。我会尝试更明确一点,但我希望完整的解决方案来自你,而不是来自我。

请注意,定义像same_color_and_adjacent这样的关系的关键不是要消除模型中事实或谓词的表达,而是要使它们更容易编写和正确编写。这不是魔术。

首先考虑一个单一关系的事实groupNearStones的重新制定,该关系适用于相邻且具有相同颜色的石头对。可以通过修改Cross的声明来定义关系:

abstract sig Cross { 
  Status: one Colour, 
  near: some Cross, 
  group: lone Group,
  near_and_similar : some Cross
}{
  near_and_similar = near & { c : Cross | c.@Status = Status}
}

现在你现有的事实可以写成:

fact groupNearStones2 {
  all disj c,d : Cross |
  d in c.near_and_similar
  iff 
  d.group=c.group
}

实际上,我会将groupNearStones的两个版本都写为谓词,而不是事实。这将允许您通过运行如下的检查来检查新公式是否与旧公式完全等效:

pred GNS_equal_GNS2 {
  groupNearStones iff groupNearStones2
}

(我运行这样的支票;我有点懒。)

现在,让我们考虑一下你提到的问题:

  • 你永远不会得到包含三颗以上宝石的团体。实际上,考虑到groupNearStones的制定,我很惊讶你得到的团体超过两个。考虑一下groupNearStones所说的:一组中的任何两块石头都是相邻的并且具有相同的颜色。在一张纸上画一块板,画一组五块石头。现在问一下这样一个组是否满足事实groupNearStones。假设该组是C11,C12,C13,C21,C22。 groupNearStones对C21,C13对怎么说?

    你看到了问题吗?关系near和'是否足够接近于同一组'真的一样吗?如果它们不相同,它们是否相关?

    提示:考虑传递闭包。

  • 你永远不会得到包含一块石头的小组。

    这是多么令人惊讶,因为只有当c和d不相交时,groupNearStones说c.group = d.group?如果你从来没有得到单石群,那么应该是单石群的每块石头都不属于任何群体,因为这样的石头不能满足s.group = s.group的表达。

    你看到了问题吗?

    提示:考虑反身传递闭包。