2015-12-18 64 views
0

我知道這不應該是很難的,但我不能代碼,並與序言解決這個特定的邏輯謎題解決邏輯拼圖序言

三個朋友在不同的國度拿到前三名 作爲頂運動員。邁克爾喜歡籃球,並且比他的美國朋友打得更好。來自英格蘭的西蒙在網球上表現最好板球選手 獲得第一名。誰是澳大利亞人? Sigurd獲得了哪些地方 ?

有人可以幫我出來或給我一個暗示從哪裏開始? 謝謝。

+3

請張貼問題之前嘗試的東西出來。首先將Prolog語法翻譯成問題描述中給出的事實。然後對這些事實作一個查詢。 – dasblinkenlight

回答

0

我覺得在問題陳述中存在矛盾,或者我正在使用一些我不應該使用或誤解問題的東西。

  1. 邁克爾打籃球。
  2. 邁克爾的排名高於美國人。
  3. 西蒙來自英格蘭。
  4. 西蒙打網球。
  5. 板球運動員獲得第一名。

我推斷板球選手必須是西格爾德,因爲邁克爾和西蒙都不打板球。這意味着西古德獲得了第一名。邁克爾無法獲得第三名,因爲他的位置高於別人,但也不能排在第一位,因爲他屬於西古德,所以他必須排在第二位。但這意味着西蒙排在第三位,西蒙是美國人,但我們從我們的假設中知道西蒙來自英格蘭。

我對這個問題有什麼誤解?

爲了解決這個問題,下面是接近這樣的問題時要遵循的步驟。

  1. 像上面所做的那樣列出一個清單,只是在問題陳述中脫離他們的句子的基本事實。
  2. 轉換該列表Prolog的事實:

    player(michael). 
    player(simon). 
    player(sigurd). 
    
    nation(england). 
    nation(america). 
    nation(australia). 
    
    game(basketball). 
    game(tennis). 
    game(cricket). 
    
    origin(simon, england). 
    
    plays(michael, basketball). 
    
  3. 制定規則來編碼問題所表達的更復雜的關係。例如:

    place(X, 1) :- player(X), plays(X, cricket). 
    

在這裏,我不禁多,因爲我知道不會有一個解決方案,我理解這個問題的辦法,但我希望它至少指明瞭方向。

1

下面是一個旨在解決您的問題的公式。它略顯冗長,並不是特別有效,但應該相當清楚。

all_diff(L) :- \+ (select(X,L,R), memberchk(X,R)). 

countries([england,usa,australia]). 
country(X) :- 
    countries(C), member(X, C).   

placings([1,2,3]).  
placing(X) :-  
    placings(C), member(X, C). 

sports([tennis,cricket,basketball]).  
sport(X) :-  
    sports(C), member(X, C). 

names([michael, simon, sigurd]).  
name(X) :-  
    names(C), member(X, C). 


solution(Solution) :-  
    Solution = [E1, E2, E3],  
    E1 = [michael, C1, S1, P1],  
    E2 = [simon, C2, S2, P2],  
    E3 = [sigurd, C3, S3, P3],  
    country(C1),  
    country(C2),  
    country(C3),  
    all_diff([C1,C2,C3]),   
    sport(S1),  
    sport(S2),  
    sport(S3),  
    all_diff([S1,S2,S3]),  
    placing(P1),  
    placing(P2),  
    placing(P3),  
    all_diff([P1,P2,P3]), 

    member([michael,CMichael,basketball,PMichael], Solution),  
    CMichael \= usa, 

    member([_,usa,_,PAmerican], Solution),  
    PMichael < PAmerican, 

    member([simon,england,tennis,_], Solution), 

    member([_,_,cricket,1], Solution). 

然而,正如丹尼爾·萊昂斯說,有其實這組約束的無解:

?- solution(S). 
false. 

如果你敲出來的最終約束(即一個關於板球運動員服用第一地方),你可以看到,會有解決方案:

?- solution(S). 
S = [[michael, australia, basketball, 1], [simon, england, tennis, 2], [sigurd, usa, cricket, 3]] ; 
S = [[michael, australia, basketball, 1], [simon, england, tennis, 3], [sigurd, usa, cricket, 2]] ; 
S = [[michael, australia, basketball, 2], [simon, england, tennis, 1], [sigurd, usa, cricket, 3]] ; 
false. 

如果拼圖的提法改爲有這個最終的事實:

「板球選手排名第二。」

......你有一個獨特的解決方案:

?- solution(S). 
S = [[michael, australia, basketball, 1], [simon, england, tennis, 3], [sigurd, usa, cricket, 2]] ; 

作爲題外話:它是完全可以接受的(有時優選)使用丹尼爾里昂的方法,用於指定例如作爲單獨事實的集合體系(在這種情況下可以說是更優雅)。然而,我使用非平凡PL程序的經驗告訴我,將集合指定爲列表通常更方便,用附加謂詞枚舉該列表的單個成員。這可以很容易地將這些成員單獨或作爲一個完整的集合來處理。

+0

我想知道更多關於您的非平凡PL計劃。我認爲你的意思是Prolog。 –

+0

我在大中型Prolog代碼庫上作爲商業程序員工作。 (我們周圍的人不多......) – Kaitain

+0

如果他們中的任何一個都是開源的(哈哈),我很樂意看到代碼。我現在沒有找工作,但下次招聘時請給我發電子郵件。我很想有機會專業地改進Prolog。 –