2013-05-11 92 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