2013-05-11 94 views
2

这就是问题所在:SWI-Prolog的益智

维克多被谋杀,而亚瑟,伯特伦,和查尔顿都 嫌疑人。亚瑟说他没有这样做。他说伯特伦是受害者的朋友,但卡尔顿恨这个受害者。伯特伦说,他当天在谋杀案当天就出门了,除此之外,他甚至都不知道那个家伙 。卡尔顿说他是无辜的,他在谋杀前与受害人见面了亚瑟和贝特拉姆 。假设每个人 - 除了 可能对凶手 - 说实话,使用决议到 解决犯罪。

这是我在序言SWI

% Facts: 
p('Arthur'). % suspect 
p('Bertram'). % suspect 
p('Carleton'). % suspect 
p('Victor'). % victim 
% Arthur 
says('Arthur', i('Arthur')). 
says('Arthur', f('Bertram', 'Victor')). 
says('Arthur', ht('Carleton', 'Victor')). 
% Bertram 
says('Bertram', o('Bertram')). 
says('Bertram', nk('Bertram', 'Victor')). 
% Carleton 
says('Carleton', i('Carleton')). 
says('Carleton', t('Arthur', 'Victor')). 
says('Carleton', t('Bertram', 'Victor')). 
% Rules: 
holds(X) :- says(Y, X), \+m(Y). 
holds(i(X)) :- p(X), \+m(X). 
holds(f(X,Y)) :- p(X), p(Y), holds(f(Y,X)). 
holds(f(X,Y)) :- p(X), p(Y), \+holds(nk(X,Y)). 
holds(o(X)) :- p(X), p(Y), holds(t(X,Y)). 
holds(o(X)) :- p(X), \+m(X). 
holds(nk(X,Y)) :- p(X), p(Y), \+holds(nk(Y,X)). 
holds(nk(X,Y)) :- p(X), p(Y), \+holds(f(X,Y)). 
holds(t(X,Y)) :- p(X), p(Y), holds(t(Y,X)). 
holds(t(X,Y)) :- p(X), p(Y), p(Z), holds(t(X,Z)), holds(t(Z,Y)). 
m(X) :- p(X). 

答案是假设是伯特伦写道,但我一直在得到亚瑟。不知道我做错了什么。

回答

1

我相当确信规则会比这更简单。

例如,如果p(X)总是正确的,那么意味着什么m(X) :- p(X).?维克多有话要说吗?

逻辑上必须坚持Occam's Razor编程逻辑它不是一个例外,尽管这个术语有一个更实际的含义 - 见KISS principle

我想我们只能认同谋杀应该是相抵触的其他两个人。只有一个事实存在问题:一个人是否知道维克多。

那么我们所知道的犯罪可以概括:

t(a) :- k(b), k(c). 
t(b) :- \+ k(b). 
t(c) :- k(a), k(b). 
k(_). 

其中,t(X)代表X testimony that和K(X)代表X known Victor。 我们不知道k(X),那么我们必须添加k(_)。

就这样,Prolog的可以建议:

?- t(X). 
X = a ; 
X = c. 

即只有a或b才是真的。

编辑:因为Prolog是不是propositive,当它来到否定,这里是一个办法,征求解决方案:

m(X) :- member(X, [a,b,c]), \+ t(X). 

但让我们更明确的方法:

代替如前所述,我们的事实基础也可表示为:

say(a, know_victim(b, yes)). 
say(a, know_victim(c, yes)). 

say(b, know_victim(b, no)). 

say(c, know_victim(a, yes)). 
say(c, know_victim(b, yes)). 

现在让我们来看看一些个别人说

liar(I) :- 
    select(I, [a,b,c], Js), 
    say(I, Fact), 
    maplist(negate(Fact), Js). 
negate(know_victim(I, X), J) :- 
    say(J, know_victim(I, Y)), 
    X \= Y. 

相反产生

?- liar(I). 
I = b ; 
false. 
+0

但问题并没有说亚瑟知道胜利者,只是说亚瑟胜利者。 – 2013-05-11 12:37:18

+0

这可能是一个典型的辩护法律论据... – CapelliC 2013-05-11 12:59:02

+0

非常非常好,谢谢!我读了你的't(X): - G'谓词,“对于'X'的证词是真的,'G'必须是真的。”那么我们看到't(b)'是不可能的,所以伯特兰肯定是个骗子。当然,没有任何一个法庭会根据这个判决来定罪。 :)即使“不(a)”是不可能的,我们仍然不能断定亚瑟是一个凶手。是的,他是一个骗子(根据这个假设),他确实说他没有杀害维克多的受害者,但是* - 他的证词只是整个*是(假)的。再说,这还不够。 :) – 2013-05-11 14:01:32