爱因斯坦拼图的合金模型

时间:2017-12-25 15:33:11

标签: alloy

[更新]感谢@Daniel Jackson和@Peter Kriens的出色见解,我修复了我的Alloy模型。现在Alloy Analyzer生成一个实例。我写了这个问题并展示了解决方案。我为5个房子中的每一个都展示了颜色,国籍,饮料,香烟和宠物。顺便说一句,是德国人养鱼。 Here是我的写作。

我创造了爱因斯坦拼图的合金模型。见下文。当我运行我的模型时,Alloy Analyzer发现了几个实例。我以为只有一个实例(一个解决方案)。这让我想知道我的模型是否正确。你看到我的模特有问题吗?爱因斯坦难题只有一个解决方案吗?

这是爱因斯坦之谜:

在同一条路上,有五座不同颜色的房子彼此相邻。在每个房子里住着一个不同国籍的人。每个人都有他最喜欢的饮料,他最喜欢的香烟品牌,并饲养特定类型的宠物。以下是约束条件:

1.  The Englishman lives in the red house.
2.  The Swede keeps dogs.
3.  The Dane drinks tea.
4.  The green house is just to the left of the white one.
5.  The owner of the green house drinks coffee.
6.  The Pall Mall smoker keeps birds.
7.  The owner of the yellow house smokes Dunhills.
8.  The man in the center house drinks milk.
9.  The Norwegian lives in the first house.
10. The Blend smoker has a neighbor who keeps cats.
11. The man who smokes Blue Masters drinks beer.
12. The man who keeps horses lives next to the Dunhill smoker.
13. The German smokes Prince.
14. The Norwegian lives next to the blue house.
15. The Blend smoker has a neighbor who drinks water.

要回答的问题是:谁养鱼?

这是我的Alloy模型:

open util/ordering[House]

sig House {
    color: Color,
    nationality: Nationality,
    drink: Drink,
    cigarette: Cigarette,
    pet: Pet
}

abstract sig Color {}
one sig red extends Color {}
one sig green extends Color {}
one sig yellow extends Color {}
one sig blue extends Color {}
one sig white extends Color {}

abstract sig Nationality {}
one sig Englishman extends Nationality {}
one sig Swede extends Nationality {}
one sig Dane extends Nationality {}
one sig German extends Nationality {}
one sig Norwegian extends Nationality {}

abstract sig Drink {}
one sig tea extends Drink {}
one sig coffee extends Drink {}
one sig milk extends Drink {}
one sig beer extends Drink {}
one sig water extends Drink {}

abstract sig Cigarette {}
one sig Pall_Mall extends Cigarette {}
one sig Dunhills extends Cigarette {}
one sig Blend extends Cigarette {}
one sig Blue_Masters extends Cigarette {}
one sig Prince extends Cigarette {}

abstract sig Pet {}
one sig dog extends Pet {}
one sig bird extends Pet {}
one sig horse extends Pet {}
one sig cat extends Pet {}
one sig fish extends Pet {}

fact {
    some disj h1, h2, h3, h4, h5: House | h1.color = red and h2.color = green and h3.color = yellow and h4.color = blue and h5.color = white
    no disj h,h': House | h.nationality = h'.nationality
    some h: House | (h.nationality = Englishman) and (h.color = red)
    some h: House | (h.nationality = Swede) and (h.pet = dog)
    some disj h, h': House | (h.color = green) and (h'.color = white) and (h'.prev = h)
    some h: House | (h.color = green) and (h.drink = coffee)
    some h: House | (h.cigarette = Pall_Mall) and (h.pet = bird)
    some h: House | (h.color = yellow) and (h.cigarette = Dunhills)
    some h: House | (some h.prev.prev) and (some h.next.next) and (h.drink = milk)
    some h: House | (h = first) and (h.nationality = Norwegian)
    some h: House | (h.cigarette = Blue_Masters) and (h.drink = beer)
    some disj h,h': House | (h.pet = horse) and (h'.cigarette = Dunhills) and ((h.next = h') or (h.prev = h'))
    some h: House | (h.nationality = German) and (h.cigarette = Prince)
    some disj h,h': House | (h.nationality = Norwegian) and (h'.color= blue) and (h.next = h')
    some disj h,h': House | (h.cigarette = Blend) and (h'.drink = water) and (h.next = h')
}

pred Who_keeps_fish {
    some h: House | h.pet = fish
}

run Who_keeps_fish for 5

3 个答案:

答案 0 :(得分:3)

puzzle应该有一个独特的解决方案。 但是,由于不完整的对称性破坏,我不会惊讶地发现多个实例。更令人惊讶的是(并告诉我你的模型存在问题)是生成的第一个实例同时有挪威鱼和德国鱼。看起来好像你需要添加房屋的占用者保持不同宠物的约束(即,宠物关系是单射的)。

答案 1 :(得分:1)

我认为你的代码文本偏离原始定义太多了。根据我的经验,当你必须遵循现有规范时,在Alloy中尽可能用文字表达文本是至关重要的。即你适合模型,使词汇符合原始规范(拼图)。

在这种情况下,房子似乎是推理的中心点。所以我创建了一个包含不同属性的House原子。我将这些字段命名为匹配描述中的单词。然后我用〜来获得正确的单词顺序。即“英国人生活”成为“英国人。生活”或“活着。英国人”。我发现这种策略对于使用Alloy(或任何形式语言)非常重要。验证的责任应该在我的大脑上试图解释数学符号的基础模型上。我认为这与创建DSL类似。

然后我得到了一个具有以下模型的解决方案:

open util/ordering[House]

enum Color { red, green, yellow, blue, white}
enum Nationality { Englishman, Swede, Dane, German, Norwegian}
enum Drink { tea, coffee, milk, beer, water}
enum Cigarette {Pall_Mall, Dunhills, Blend, Blue_Masters, Prince}
enum Pet { dogs, birds, horses, cats, fish }

sig House {
    colored  : one Color,
    lives    : one Nationality,
    drinks   : one Drink,
    smoker   : one Cigarette,
    keeps    : one Pet
} 

fact  ensureUniqueFieldsForEachHouse {

    # House = 5

    all disj h1, h2 : House | 
        all f : House$.subfields | 
            h1.(f.value) != h2.(f.value)
}

pred House.hasNeighbourWho[ other : House ] { 
    other in this.(prev+next) 
}

let centerHouse = first.next.next

fact {
    // 1.  The Englishman lives in the red house.
    Englishman.~lives in colored.red

    // 2.  The Swede keeps dogs.
    Swede.~lives in keeps.dogs

    // 3.  The Dane drinks tea.
    Dane.~lives in drinks.tea

    // 4.  The green house is just to the left of the white one.
    green.~colored = colored.white.prev

    // 5.  The owner of the green house drinks coffee.
    green.~colored = drinks.coffee

    // 6.  The Pall Mall smoker keeps birds.
    Pall_Mall.~smoker = keeps.birds

    // 7.  The owner of the yellow house smokes Dunhills.
    yellow.~colored = smoker.Dunhills

    // 8.  The man in the center house drinks milk.
    centerHouse = drinks.milk

    // 9.  The Norwegian lives in the first house.
    Norwegian.~lives  = first

    // 10. The Blend smoker has a neighbor who keeps cats.
    Blend.~smoker.hasNeighbourWho[ keeps.cats ] 

    // 11. The man who smokes Blue Masters drinks beer.
    Blue_Masters.~smoker = drinks.beer

    // 12. The man who keeps horses lives next to the Dunhill smoker.
    keeps.horses.hasNeighbourWho[smoker.Dunhills]

    // 13. The German smokes Prince.
    German.~lives = smoker.Prince

    // 14. The Norwegian lives next to the blue house.
    Norwegian.~lives.hasNeighbourWho[colored.blue]

    // 15. The Blend smoker has a neighbor who drinks water.
    Blend.~smoker.hasNeighbourWho[drinks.water]
}

run { one keeps.fish } for 5

答案 2 :(得分:0)

最初的解决方案似乎忽略了没有主人拥有相同的宠物、香烟和饮料的限制。

    no disj h,h': House | h.pet = h'.pet // otherwise there are solutions with green and white house having both dog as pet
    no disj h,h': House | h.cigarette = h'.cigarette // not really required
    no disj h,h': House | h.drink = h'.drink // not really required

没有这些,如上所述,您将获得非法解决方案。 Here is a rendering constructed with ProB showing an illegal solution

更正后,您get this solution with ProB (using Alloy2B and VisB: (如果您对可视化感兴趣,请参阅 here