用prolog解决简单逻辑难题
大家好,我还是个新手,我仍然不知道如何用Prolog解决这个难题,我做了一些尝试,但似乎是错误和不完整的,这就是问题: 在一次音乐独奏会上,五名学生(约翰、凯特、拉里、玛丽和尼克)表演了五首乐曲。两个是巴赫,两个是莫扎特,一个是维瓦尔第。有三位小提琴手和两位钢琴家。每个学生只演奏一首曲子,只演奏一种乐器。在下列条件下,找出学生、他们各自的乐器和作曲家的顺序:用prolog解决简单逻辑难题,prolog,zebra-puzzle,Prolog,Zebra Puzzle,大家好,我还是个新手,我仍然不知道如何用Prolog解决这个难题,我做了一些尝试,但似乎是错误和不完整的,这就是问题: 在一次音乐独奏会上,五名学生(约翰、凯特、拉里、玛丽和尼克)表演了五首乐曲。两个是巴赫,两个是莫扎特,一个是维瓦尔第。有三位小提琴手和两位钢琴家。每个学生只演奏一首曲子,只演奏一种乐器。在下列条件下,找出学生、他们各自的乐器和作曲家的顺序: 作曲家们没有连续演奏。维瓦尔第是最后一位,莫扎特是第一位 有一首钢琴曲在两首小提琴曲之间演奏,两首小提琴曲在第一首和最后一首钢琴曲之间演奏
半码
:
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,
N1==John\u num+1,
这种事我已经做过很多次了。首先,您需要一个函数来进行求解:
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)
List=[
musicians(1,_,_,_), % and so on