2017-04-12 107 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