将逻辑谜题转换为谓词演算和prolog / dlv

时间:2015-11-05 20:33:27

标签: prolog logic predicate answer-set-programming

问题是:盐被盗了!好吧,发现罪魁祸首是卡特彼勒, 比尔蜥蜴或柴郡猫。这三个人被审判并做了以下 在法庭上的陈述:

CATERPILLAR: Bill the Lizard ate the salt.
BILL THE LIZARD: That is true!
CHESHIRE CAT: I never ate the salt.

事情发生时,至少有一人撒了谎,至少有一个人说实话。谁吃了 盐?

我肯定知道账单是否属实,所有陈述都是真的,如果柴郡是真的,那么一切都是假的,所以它一定是毛毛虫。

在谓词演算和编程中,它会是这样的:

suspect(caterpillar).
suspect(lizard).
suspect(cat).

:- suspect(cat), suspect(lizard).
:- suspect(cat), suspect(caterpillar).
:- suspect(lizard), suspect(caterpillar).

%where these imply not more than one of these can be true or returned in our set

但是后来在谓词逻辑中进一步描述了这一点,我不知道如何描述他们所做的描述或恳求。如果一个陈述是真的,那么如何暗示其他人可能是虚假的。

1 个答案:

答案 0 :(得分:2)

关于这个难题的一个好处是你甚至不需要一阶谓词逻辑来对它进行建模:它足以使用命题逻辑,因为是否有嫌疑人谎言或说明真相可以用布尔变量表示,而语句本身也只是布尔变量的陈述。

因此,在使用Prolog解决此任务时,请考虑对 Boolean 变量使用约束求解器。有关详细信息,请参阅

以下是使用SICStus Prolog或SWI的示例解决方案:

:- use_module(library(clpb)).

solution(Pairs) :-
        Suspects = [_Caterpillar,Lizard,Cat],
        pairs_keys_values(Pairs, [caterpillar,lizard,cat], Suspects),
        Truths = [CaterpillarTrue,LizardTrue,CatTrue],
        % exactly one of them ate the salt
        sat(card([1], Suspects)),
        % the statements
        sat(CaterpillarTrue =:= Lizard),
        sat(LizardTrue =:= Lizard),
        sat(CatTrue =:= ~Cat),
        % at least one of them tells the truth:
        sat(card([1,2,3], Truths)),
        % at least one of them lies:
        sat(card([1,2,3], [~CaterpillarTrue,~LizardTrue,~CatTrue])).

由此可以毫不费力地确定独特的解决方案:

?- solution(Pairs).
Pairs = [caterpillar-1, lizard-0, cat-0].