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 解决这个问题,即使我已经知道答案,但在 prolog 中是全新的,并且在阅读教程后仍然感到困惑。
4

1 回答 1

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

因为在memberC1 的末尾没有绑定,所以 C1\=vivaldi 必然会失败。但这会起作用:

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
于 2017-04-12T19:30:22.043 回答