prolog - 序言:谋杀之谜解决方案
问题描述
我最近开始学习 Prolog 是为了好玩。我发现了以下谋杀之谜。由于除了基础知识之外我对 Prolog 知之甚少,因此我无法真正评估链接中提供的解决方案,但是,它对我来说似乎并不是特别好。我的解决方案不足以产生正确的答案,所以我正在寻找一些关于如何到达那里的指示,或者是否有可能用我的方法到达那里。这是万一链接断开的难题:
要查明是谁杀死了博迪先生,您需要了解每个人在哪里,以及房间里有什么武器。线索分散在整个测验中(在阅读完所有 10 个问题之前,您无法解决问题 1)。
首先,您需要了解嫌疑人。有三个男人(乔治、约翰、罗伯特)和三个女人(芭芭拉、克里斯汀、约兰达)。每个人都在不同的房间(浴室、餐厅、厨房、客厅、储藏室、书房)。在每个房间里都发现了一件可疑的武器(袋子、火器、毒气、刀、毒药、绳子)。谁在厨房被发现?
线索1:厨房里的人没有带绳子、刀或包。那么,在厨房里发现了哪种武器,而不是枪支呢?
线索 2:芭芭拉要么在书房,要么在浴室;约兰达在另一个。芭芭拉是在哪个房间找到的?
线索 3:提包的人既不是芭芭拉也不是乔治,他既不在浴室也不在餐厅。谁把包放在房间里?
线索4:在研究中发现了拿着绳子的女人。绳子是谁拿的?
线索 5:客厅里的武器是在约翰或乔治身上找到的。客厅里放着什么武器?
线索6:刀不在餐厅里。那么刀在哪里呢?
线索 7:Yolanda 没有携带在书房和储藏室中发现的武器。与尤兰达一起发现了什么武器?
线索 8:枪和乔治在房间里。枪支是在哪个房间找到的?
人们发现博迪先生在储藏室里被毒死了。在那个房间里发现的嫌疑人就是凶手。那么,你指的是谁呢?
这是作者解决方案的链接。
这是我尝试的解决方案:
male(george).
male(john).
male(robert).
female(barbara).
female(christine).
female(yolanda).
person(X) :- male(X).
person(X) :- female(X).
room(kitchen).
room(bathroom).
room(diningroom).
room(livingroom).
room(pantry).
room(study).
weapon(bag).
weapon(firearm).
weapon(gas).
weapon(knife).
weapon(poison).
weapon(rope).
/*
Clue 1: The man in the kitchen was not found with
the rope, knife, or bag.
Which weapon, then, which was not the firearm,
was found in the kitchen?
*/
/* X is Weapon, Y is Room, Z is Person */
killer(X, Y, Z) :-
room(Y) = room(kitchen),
male(Z),
dif(weapon(X), weapon(rope)),
dif(weapon(X), weapon(knife)),
dif(weapon(X), weapon(bag)),
dif(weapon(X), weapon(firearm)).
/*
Clue 2: Barbara was either in the study or the bathroom;
Yolanda was in the other.
Which room was Barbara found in?
*/
/* It was easy to deduce the following from other data */
killer(X, Y, Z) :-
female(Z) = female(barbara),
room(study) = room(Y).
killer(X, Y, Z) :-
female(Z) = female(yolanda),
room(bathroom) = room(Y).
/*
Clue 3: The person with the bag, who was not Barbara nor
George, was not in the bathroom nor the dining room.
Who had the bag in the room with them?
*/
killer(X, Y, Z) :-
weapon(bag) = weapon(X),
dif(room(Y), room(bathroom)),
dif(room(Y), room(diningroom)),
dif(person(Z), male(george)),
dif(person(Z), female(barbara)).
/*
Clue 4: The woman with the rope was found in the study.
Who had the rope?
*/
killer(X, Y, Z) :-
weapon(rope) = weapon(X),
room(study) = room(Y),
female(Z).
/*
Clue 5: The weapon in the living room was found with either
John or George. What weapon was in the living room?
*/
killer(X, Y, Z) :-
room(Y) = room(livingroom),
dif(male(Z), male(robert)).
/*
Clue 6: The knife was not in the dining room.
So where was the knife?
*/
killer(X, Y, Z) :-
weapon(knife) = weapon(X),
room(Y) \= room(diningroom).
/*
Clue 7: Yolanda was not with the weapon found
in the study nor the pantry.
What weapon was found with Yolanda?
*/
killer(X, Y, Z) :-
female(yolanda) = female(Z),
dif(room(study), room(Y)),
dif(room(pantry), room(Y)).
/*
Clue 8: The firearm was in the room with George.
In which room was the firearm found?
*/
killer(X, Y, Z) :-
weapon(firearm) = weapon(X),
male(george) = male(Z).
/*
It was discovered that Mr. Boddy was gassed in the pantry.
The suspect found in that room was the murderer.
Who, then, do you point the finger towards?
*/
killer(X, Y, Z) :-
room(Y) = room(pantry),
weapon(X) = weapon(gas).
解决方案
我对这个问题采取了更积极的态度。我没有尝试任何形式的否定,而是进行了简单的统一。
关键是这个谓词对:
members([],_).
members([M|Ms],Xs) :- select(M,Xs,Ys),members(Ms,Ys).
这是一个基本的置换谓词。它将采用第一个参数的列表并尝试统一第二个列表的所有排列。
现在很多规则变得很容易表达:
例如,线索 1:
clue1(House) :- members([[P,kitchen,_],[_,_,rope],[_,_,knife],[_,_,bag],[_,_,firearm]],House),man(P).
所以这意味着rope
,knife
和都是房子的成员,但在不同的房间bag
里。Prolog 将继续回溯,直到找到适合这些项目的情况。firearm
kitchen
这是我的完整解决方案:
man(george).
man(john).
man(robert).
woman(barbara).
woman(christine).
woman(yolanda).
members([],_).
members([M|Ms],Xs) :- select(M,Xs,Ys),members(Ms,Ys).
clue1(House) :- members([[P,kitchen,_],[_,_,rope],[_,_,knife],[_,_,bag],[_,_,firearm]],House),man(P).
clue2(House) :- member([barbara,study,_],House), member([yolanda,bathroom,_],House).
clue2(House) :- member([barbara,bathroom,_],House), member([yolanda,study,_],House).
clue3(House) :- members([[_,_,bag],[barbara,_,_],[george,_,_]],House),members([[_,_,bag],[_,bathroom,_],[_,dining_room,_]],House).
clue4(House) :- members([[P,study,rope]],House),woman(P).
clue5(House) :- members([[john,living_room,_]],House).
clue5(House) :- members([[george,living_room,_]],House).
clue6(House) :- members([[_,_,knife],[_,dining_room,_]],House).
clue7(House) :- members([[yolanda,_,_],[_,study,_],[_,pantry,_]],House).
clue8(House) :- member([george,_,firearm],House).
clue9(House,P) :- members([[P,pantry,gas]],House).
solve(X) :-
House = [[_,bathroom,_],[_,dining_room,_],[_,kitchen,_],[_,living_room,_],[_,pantry,_],[_,study,_]],
clue1(House),
clue2(House),
clue3(House),
clue4(House),
clue5(House),
clue6(House),
clue7(House),
clue8(House),
clue9(House,X),
members([[george,_,_],[john,_,_],[robert,_,_],[barbara,_,_],[christine,_,_],[yolanda,_,_]],House),
members([[_,_,bag],[_,_,firearm],[_,_,gas],[_,_,knife],[_,_,poison],[_,_,rope]],House),
write(House),
true.
那给了我:
?- solve(X).
[[yolanda,bathroom,knife],[george,dining_room,firearm],[robert,kitchen,poison],[john,living_room,bag],[christine,pantry,gas],[barbara,study,rope]]
X = christine .
推荐阅读
- python - 表单未在 django admin 中保存电子邮件
- python - django 火车预订系统(订票)
- javascript - Python selenium how to execute execute_script on a JavaScript element with arguments
- elasticsearch - 在 nodejs 中使用 nock 测试 elasticsearch
- php - 触发 Woocommerce 自定义字段时出现致命错误
- javascript - 按子数组值分组并将字段带到主数组
- c++ - range-v3:调整已经实现迭代器接口的自定义类(开始/结束)
- c - 使用 memcpy() 复制结构是否合法?
- c++ - C++ – delete 关键字的意义何在?
- java - NavigationView 点击事件