序言中斑马拼图的变体,我不知道哪里出错了
Variation of the zebra puzzle in prolog, and I can't figure out where I'm going wrong
我知道 zebra 谜题在这里经常被问到,但这有点不同:我们得到了 zebra 的变体拼图在Prolog中编写。我对此非常陌生,但去年我什至尝试从一些人那里获得帮助,他们自己有不同的变体,他们不确定我的代码发生了什么。
我会post整件事,我希望这不是压倒性的或不好的做法。
register_renderer/2
:- use_rendering(table,
[header(dorm('Major', 'Car', 'Team', 'Music', 'Drink'))]).
csMusic(Music) :-
dorms(Dorms),
member(dorm(computerscience,_,_,Music,_),Dorms).
engDrink(Drink) :-
dorms(Dorms),
member(dorm(english,_,_,_,Drink),Dorms).
dorms(Dorms) :-
length(Dorms, 5),
% 1. The computer science student lives in the middle of the corridor.
Dorms = [_,_,(dorm(computerscience,_,_,_,_)),_,_],
% 2. The history major is a jazz fan.
member(dorm(history,_,_,jazz,_),Dorms),
% 3. The Yankees fan drives a Toyota.
member(dorm(_,toyota,yankees,_,_),Dorms),
% 4. The accounting major drinks Coke.
member(dorm(accounting,_,_,_,coke),Dorms),
% 5. The engineering major drinks coffee.
member(dorm(engineering,_,_,_,coffee),Dorms),
% 6. The computer science student and history student are neighbors.
adjacent((dorm(computerscience,_,_,_,_)),(dorm(history,_,_,_,_)),Dorms),
% 7. The student at the far end of the hall likes classical music.
Dorms = [_,_,_,_,(dorm(_,_,_,classical,_))],
% 8. The tea drinker drives a Tesla.
member(dorm(_,_,_,_,_),Dorms),
% 9. The classical music fan lives next to the jazz listener.
adjacent((dorm(_,_,_,classical,_)),(dorm(_,_,_,jazz,_)),Dorms),
% 10. The English major does not live in either of the first two rooms.
member(dorm(english,_,_,_,_),Dorms),
not(Dorms = [dorm(english,_,_,_,_)]),
not(Dorms = [_,dorm(english,_,_,_,_),_,_,_]),
% 11. The Royals fan drives a Tesla.
member(dorm(_,tesla,royals,_,_),Dorms),
% 12. The Cubs fan listens to jazz.
member(dorm(_,_,cubs,jazz,_),Dorms),
% 13. The engineering major follows the Chiefs
member(dorm(engineering,_,chiefs,_,_),Dorms),
% 14. The first room is the home of the Broncos fan
Dorms = [dorms(_,_,broncos,_,_),_,_,_,_],
% 15. The Coke drinker drives a Nissan.
member(dorm(_,nissan,_,_,coke),Dorms),
% 16. The country music fan and the techno fan are neighbors.
adjacent((dorm(_,_,_,country,_)),(dorm(_,_,_,techno,_)),Dorms),
% 17. The accounting major lives in the first room.
Dorms = [dorms(accounting,_,_,_,_),_,_,_,_],
% 18. The fans of the 2 Kansas City teams (Chiefs and Royals) are neighbors
adjacent((dorm(_,_,chiefs,_,_)),(dorm(_,_,royals,_,_)),Dorms),
% 19. The accounting major listens to rock music
member(dorm(accounting,_,_,rock,_),Dorms),
% 20. The Yankees fan drinks milk.
member(dorm(_,_,yankees,_,milk),Dorms),
% 21. The Chevy driver listens to country music.
member(dorm(_,chevy,_,country,_),Dorms),
% 22. The jazz fan drives a Ford.
member(dorm(_,ford,_,jazz,_),Dorms),
% 23. Water isnt used.
member(dorm(_,_,_,_,water),Dorms).
next(A, B, Ls) :- append(_, [A,B|_], Ls).
next(A, B, Ls) :- append(_, [B,A|_], Ls).
adjacent(A,B,List) :- next(A,B,List); next(B,A,List).
我的数据库加载得很好,但是当我尝试 运行 任何东西时结果都是错误的。如果我运行dorms(Dorms)
打印出所有结果,我返回false
。当我运行csMusic
(试图找到CS专业听的音乐类型)或engDrink
(试图找到英语专业喝的是什么饮料)时,我返回false
.
我对 Prolog 知之甚少,但在解决这个问题时,我尽力按照 swipl 网站进行操作。是否有任何人可以指出的容易我遗漏的东西?可能是命名不一致?
非常感谢帮助,谢谢!
如果dorms(Dorms)
失败,那么csMusic(Music)
肯定会失败,因为它需要dorms(Dorms)
才能成功。
找到问题的一种方法是尝试注释掉一些线索,然后 运行 查询 dorms(Dorms)
。你会发现你得到了多种解决方案。最终你会找到一条导致失败的线索。当然,这可能不是坏线索。
另一件可能出错的事情是 "not" 的使用。例如,如果您 运行 此查询:
?- length(Dorms, 5), not(Dorms = [dorm(english,_,_,_,_)]). % 10.
Dorms = [_9200, _9206, _9212, _9218, _9224].
这个结果是你期望的吗?您可能想查看 Prolog 用于否定的 "closed world assumption" 并考虑另一种编写此线索的方法。
要点:没有必要在 dorm(...)
周围加上括号。比如第一个约束可以写成Dorms = [_,_,dorm(computerscience,_,_,_,_),_,_]
.
在第 8 条中,我实际上没有提到茶或特斯拉。
在第 10 条中,我第一次使用 not 时数组中的项数不正确。
在第 14 和 17 条中,我将 dorm 拼错为 'dorms'.
解决这些问题后,我能够收到正确且完整的答案。
我知道 zebra 谜题在这里经常被问到,但这有点不同:我们得到了 zebra 的变体拼图在Prolog中编写。我对此非常陌生,但去年我什至尝试从一些人那里获得帮助,他们自己有不同的变体,他们不确定我的代码发生了什么。
我会post整件事,我希望这不是压倒性的或不好的做法。
register_renderer/2
:- use_rendering(table,
[header(dorm('Major', 'Car', 'Team', 'Music', 'Drink'))]).
csMusic(Music) :-
dorms(Dorms),
member(dorm(computerscience,_,_,Music,_),Dorms).
engDrink(Drink) :-
dorms(Dorms),
member(dorm(english,_,_,_,Drink),Dorms).
dorms(Dorms) :-
length(Dorms, 5),
% 1. The computer science student lives in the middle of the corridor.
Dorms = [_,_,(dorm(computerscience,_,_,_,_)),_,_],
% 2. The history major is a jazz fan.
member(dorm(history,_,_,jazz,_),Dorms),
% 3. The Yankees fan drives a Toyota.
member(dorm(_,toyota,yankees,_,_),Dorms),
% 4. The accounting major drinks Coke.
member(dorm(accounting,_,_,_,coke),Dorms),
% 5. The engineering major drinks coffee.
member(dorm(engineering,_,_,_,coffee),Dorms),
% 6. The computer science student and history student are neighbors.
adjacent((dorm(computerscience,_,_,_,_)),(dorm(history,_,_,_,_)),Dorms),
% 7. The student at the far end of the hall likes classical music.
Dorms = [_,_,_,_,(dorm(_,_,_,classical,_))],
% 8. The tea drinker drives a Tesla.
member(dorm(_,_,_,_,_),Dorms),
% 9. The classical music fan lives next to the jazz listener.
adjacent((dorm(_,_,_,classical,_)),(dorm(_,_,_,jazz,_)),Dorms),
% 10. The English major does not live in either of the first two rooms.
member(dorm(english,_,_,_,_),Dorms),
not(Dorms = [dorm(english,_,_,_,_)]),
not(Dorms = [_,dorm(english,_,_,_,_),_,_,_]),
% 11. The Royals fan drives a Tesla.
member(dorm(_,tesla,royals,_,_),Dorms),
% 12. The Cubs fan listens to jazz.
member(dorm(_,_,cubs,jazz,_),Dorms),
% 13. The engineering major follows the Chiefs
member(dorm(engineering,_,chiefs,_,_),Dorms),
% 14. The first room is the home of the Broncos fan
Dorms = [dorms(_,_,broncos,_,_),_,_,_,_],
% 15. The Coke drinker drives a Nissan.
member(dorm(_,nissan,_,_,coke),Dorms),
% 16. The country music fan and the techno fan are neighbors.
adjacent((dorm(_,_,_,country,_)),(dorm(_,_,_,techno,_)),Dorms),
% 17. The accounting major lives in the first room.
Dorms = [dorms(accounting,_,_,_,_),_,_,_,_],
% 18. The fans of the 2 Kansas City teams (Chiefs and Royals) are neighbors
adjacent((dorm(_,_,chiefs,_,_)),(dorm(_,_,royals,_,_)),Dorms),
% 19. The accounting major listens to rock music
member(dorm(accounting,_,_,rock,_),Dorms),
% 20. The Yankees fan drinks milk.
member(dorm(_,_,yankees,_,milk),Dorms),
% 21. The Chevy driver listens to country music.
member(dorm(_,chevy,_,country,_),Dorms),
% 22. The jazz fan drives a Ford.
member(dorm(_,ford,_,jazz,_),Dorms),
% 23. Water isnt used.
member(dorm(_,_,_,_,water),Dorms).
next(A, B, Ls) :- append(_, [A,B|_], Ls).
next(A, B, Ls) :- append(_, [B,A|_], Ls).
adjacent(A,B,List) :- next(A,B,List); next(B,A,List).
我的数据库加载得很好,但是当我尝试 运行 任何东西时结果都是错误的。如果我运行dorms(Dorms)
打印出所有结果,我返回false
。当我运行csMusic
(试图找到CS专业听的音乐类型)或engDrink
(试图找到英语专业喝的是什么饮料)时,我返回false
.
我对 Prolog 知之甚少,但在解决这个问题时,我尽力按照 swipl 网站进行操作。是否有任何人可以指出的容易我遗漏的东西?可能是命名不一致?
非常感谢帮助,谢谢!
如果dorms(Dorms)
失败,那么csMusic(Music)
肯定会失败,因为它需要dorms(Dorms)
才能成功。
找到问题的一种方法是尝试注释掉一些线索,然后 运行 查询 dorms(Dorms)
。你会发现你得到了多种解决方案。最终你会找到一条导致失败的线索。当然,这可能不是坏线索。
另一件可能出错的事情是 "not" 的使用。例如,如果您 运行 此查询:
?- length(Dorms, 5), not(Dorms = [dorm(english,_,_,_,_)]). % 10.
Dorms = [_9200, _9206, _9212, _9218, _9224].
这个结果是你期望的吗?您可能想查看 Prolog 用于否定的 "closed world assumption" 并考虑另一种编写此线索的方法。
要点:没有必要在 dorm(...)
周围加上括号。比如第一个约束可以写成Dorms = [_,_,dorm(computerscience,_,_,_,_),_,_]
.
在第 8 条中,我实际上没有提到茶或特斯拉。 在第 10 条中,我第一次使用 not 时数组中的项数不正确。 在第 14 和 17 条中,我将 dorm 拼错为 'dorms'.
解决这些问题后,我能够收到正确且完整的答案。