在prolog中解决简单的音乐家逻辑谜题

时间:2017-04-12 16:49:26

标签: prolog zebra-puzzle

大家好我还是新手,我还是不知道如何用Prolog解决这个难题,我做了一些尝试,似乎错了,不完整,这就是问题:

在一场音乐会上,五名学生(John,Kate,Larry,Mary和Nick)演奏了五首音乐作品。两个由巴赫,两个由莫扎特和一个由维瓦尔第。有三位小提琴手和两位钢琴家。每个学生只演奏一件,只演奏一件乐器。根据以下条件查找学生,他们各自的乐器和作曲家的顺序:

  1. 作曲家没有连续出场。维瓦尔迪最后一场比赛,莫扎特先上场。

  2. 在两首小提琴曲之间播放了一首钢琴曲,在第一首和最后一首钢琴曲之间播放了两首小提琴曲。

  3. 莫扎特没有钢琴曲。

  4. 凯特打第三。

  5. John演奏了莫扎特的作品,紧接着是钢琴演奏的尼克。

  6. 玛丽没有扮演维瓦尔第的作品。

  7. 和我的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. 之后写下昵称
    4. nah我只是坚持使用Prolog来解决这个问题,即使我已经知道了答案,但在prolog中完全是新的并且在阅读教程后仍然感到困惑。

1 个答案:

答案 0 :(得分: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 \ = 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