2017-04-12 51 views
0

好傢伙我還是新手,我還是不知道如何解決這個難題與Prolog的,我做了一些嘗試,似乎是錯誤的和不完整的,這是一個問題:解決簡單的音樂家邏輯謎題在序言

在一場音樂會上,五名學生(約翰,凱特,拉里,瑪麗和尼克)共演出了五首音樂作品。兩首巴赫,兩首莫扎特和一首維瓦爾第。有三名小提琴手和兩名鋼琴家。每個學生只做一件作品,只玩一種樂器。找同學,他們各自的儀器和作曲家的順序,符合下列條件:

  1. 作曲家不連續播放。維瓦爾第最後一次出場,莫扎特首先出場。

  2. 有一首鋼琴作品在兩首小提琴作品之間演奏,兩首小提琴作品在第一首和最後一首鋼琴作品之間演奏。

  3. 莫扎特沒有鋼琴作品。

  4. 凱特打了第三。

  5. 約翰演奏了一首莫扎特的作品,緊隨其後的是演奏鋼琴的尼克。

  6. 瑪麗沒有扮演維瓦爾第。

這裏我half-code

List=[ 
    musicians(_,_,_,_), 
    musicians(_,_,_,_), 
    musicians(_,_,_,_), 
    musicians(_,_,_,_), 
    musicians(_,_,_,_)], 
member(musicians(1,_,_,mozart),List) , 
member(musicians(5,_,_,vivaldi),List) , 
member(musicians(_,_,P1,mozart),List) ,P1\==piano, 
member(musicians(3,kate,_,_),List) , 
member(musicians(_,john,_,mozart),List) , 
member(musicians(N1,nick,piano,_),List) ,N1==john_num+1, 
member(musicians(_,mary,_,C1),List) ,C1\==vivaldi, 
  1. 我不知道怎麼寫的#2語句關於鋼琴和小提琴。
  2. 我不知道該怎麼寫缺口後聲明約翰N1==john_num+1,
  3. 全息我只是堅持用解決Prolog的這個問題,甚至儘管我已經知道答案,但在序言全新的,仍然困惑閱讀後教程。

回答

0

我已經做了很多次這樣的事情。首先,你需要一個函數來解決:

solve(List) :- % and now you can go on to define List, etc. 

這裏是我如何做:生成和測試方法。

solve(List) :- 
    generate(List), 
    verify(List). 

generate(List)會生成所有可能的解決方案和verify將只允許符合約束的人。這是基本的方法。我通常將驗證交叉到生成部件,儘快拋出不好的解決方案。

您的解決方案使用member很有趣,並且可能有效,但在測試之前仍需要生成一個東西。例如,這將無法工作:

member(musicians(_,mary,_,C1),List) ,C1\==vivaldi 

因爲在member C1的端部不束縛,所以C1 \ =維瓦爾第將必然失敗。但是,這會工作:

member(C1,[bach, mozart]), member(musicians(_,mary,_,C1),List) 

的#2A問題也產生了這樣:

member(ViolinNumber1,[1,2,3,4,5]), member(ViolinNumber2,[1,2,3,4,5]), 
member(PianoNumber,[1,2,3,4,5]), 
ViolinNumber1 < PianoNumber, PianoNumber < ViolinNumber2, 
member(musicians(ViolinNumber1,_,violin,_),List), 
member(musicians(ViolinNumber2,_,violin,_),List), 
member(musicians(PianoNumber,_, piano ,_),List) 

你通過得到的,你知道你有兩個小提琴片之間的鋼琴曲。

這可能是需要的順序是從一開始就獨特的,那就是,有沒有在#2插槽兩片(說)一個好主意:

List=[ 
    musicians(1,_,_,_), % and so on