簡體   English   中英

愛因斯坦謎題的合金模型

[英]Alloy model of the Einstein puzzle

[更新] 感謝@Daniel Jackson 和@Peter Kriens 的出色見解,我修復了我的合金模型。 現在 Alloy Analyzer 生成一個實例。 我寫了這個問題並展示了解決方案。 我為 5 個房子中的每一個顯示顏色、國籍、飲料、香煙和寵物。 順便說一下,養魚的是德國人。 是我寫的。

我創建了愛因斯坦謎題的合金模型。 見下文。 當我運行我的模型時,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.

要回答的問題是:誰養魚?

這是我的合金模型:

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

這個謎題應該有一個獨特的解決方案。 不過,由於不完全對稱破壞,我不會對發現多個實例感到驚訝。 更令人驚訝的是(並向我表明您的模型存在問題)是生成的第一個實例同時包含挪威和德國飼養的魚。 看起來好像您需要添加房屋的居住者飼養不同寵物的約束(即,寵物關系是單射的)。

我認為您的代碼文本與原始定義偏差太大。 根據我的經驗,當您必須遵循現有規范時,在 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  : disj Color,
    lives    : disj Nationality,
    drinks   : disj Drink,
    smoker   : disj Cigarette,
    keeps    : disj Pet
} 

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]
}
pred solution[ p : House ] {
     p = keeps.fish
}
run solution for 5 but exactly 5 House

更新刪除元數據並使用disj代替

最初的解決方案似乎忽略了沒有主人擁有相同的寵物、香煙和飲料的限制。

    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

沒有這些,如上所述,您將獲得非法解決方案。 這是使用 ProB 構建的渲染圖,顯示了非法解決方案

更正后,您將使用 ProB 獲得此解決方案(使用 Alloy2B 和 VisB :(如果您對可視化感興趣,請參閱此處

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM