2

问题是:盐被偷了!好吧,我们发现罪魁祸首要么是毛毛虫,要么是蜥蜴比尔,要么是柴郡猫。三人受审并在法庭上发表以下声明:

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

但是,然后在谓词逻辑中进一步描述这一点,我不会如何描述他们所做的描述或请求。如果一个陈述是真的,那如何暗示其他陈述可能是错误的。

4

1 回答 1

2

关于这个谜题的一个好处是,您甚至不需要一阶谓词逻辑来对其建模:使用命题逻辑就足够了,因为可以用布尔变量指示嫌疑人是在说谎还是说真话,而陈述本身也只是对布尔变量的语句。

因此,在使用 Prolog 解决此任务时,请考虑对布尔变量使用约束求解器。有关这方面的更多信息,请参见

这是一个使用 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].
于 2015-11-05T21:23:43.800 回答