Prolog中的矛盾

时间:2018-02-16 05:48:42

标签: prolog

我正在测试Prolog测试矛盾的能力。为了测试这个,我想出了以下场景:

有三名嫌疑人:a,b和c,他们正在接受审判,其中一名嫌犯是有罪的,其余的是无辜的。

案件的事实是,

(事实1)如果a是无辜的,那么c必须是有罪的,并且

(事实2)如果a是无辜的,则c必须是无辜的。

对谁有罪的答案是怀疑'a',因为怀疑'c'不能既有罪又无辜。以下代码是我的实现:

who_guilty(Suspects) :-
% Knowledge Base
Suspects=[[Name1,Sentence1],
            [Name2, Sentence2],
            [Name3,Sentence3]],

% Suspects
Names=[a,b,c],
Names=[Name1,Name2,Name3],

% One Is Guilty
Sentences=[innocent,innocent,guilty],
permutation(Sentences,[Sentence1,Sentence2,Sentence3]),

% If A Innocent Then C Is Guilty
(member([a,innocent],Suspects) -> member([c,guilty], Suspects) ; true),

% If A Innocent Then C Is Innocent
(member([a,innocent],Suspects) -> member([c,innocent], Suspects) ; true).

要获得Prolog的答案,需要运行的查询是who_guilty(S)。然后Prolog将输出两个相同的答案:

S = [[a,有罪],[b,无辜],[c,无辜]]?

S = [[a,有罪],[b,无辜],[c,无辜]]

我的核心问题是,如何才能获得一个答案,而不是两个答案?

4 个答案:

答案 0 :(得分:1)

使用clpb:

:- use_module(library(clpb)).

% 0 means guilty
% 1 means innocent
guilty(A,B,C) :-
    % only one is guilty
    sat(~A * B * C + A * ~B * C + A * B * ~C),
    % Fact 1
    sat(A =< ~C),
    % Fact 2
    sat(A =< C).

?- guilty(A,B,C).
A = 0,
B = C, C = 1.

答案 1 :(得分:1)

紧凑的解决方案,遵循您对表达事实的直觉。

who_guilty(L) :-
    select(guilty,L,[innocent,innocent]),
    ( L = [innocent,_,_] -> L = [_,_,guilty] ; true ),
    ( L = [innocent,_,_] -> L = [_,_,innocent] ; true ).

的产率:

?- who_guilty(L).
L = [guilty, innocent, innocent] ;
false.

感谢joel76(+1),这是一个基于库的更合成的解决方案(clpb)

?- sat(card([1],[A,B,C])*(~A =< ~C)*(~A =< C)).
A = 1,
B = C, C = 0.

1意味着有罪......

答案 2 :(得分:0)

使用clpfd库,您可以轻松解决此问题:

solve(L):-
    L = [A,B,C], %0 innocent, 1 guilty
    L ins 0..1,
    A + B + C #= 1, %one is guilty
    A #= 0 #==> C #= 1, %if a is innocent then c must be guilty
    A #= 0 #==> C #= 0, %if a is innocent then c must be innocent
    label(L).

?- solve(L).
L = [1, 0, 0]

答案 3 :(得分:0)

你应该添加一个新的谓词,检查某人是否无辜和有罪,然后对是否存在矛盾的结果回答是。您正在给Prolog两个事实,这意味着对查询有两个正确的结论。你真正的问题是&#34;我是否有相互矛盾的事实?&#34;,这意味着A和NOT A同时都是真的。 contradiction(A, not(A)).

所有真理都是普遍存在的,你提出了两个与Prolog相矛盾的真理,所以两者都适用于Prolog。