首页 文章

Prolog - 一个谜语的解决方案

提问于
浏览
1

我在互联网上找到了一个谜语,我想用Prolog解决它 . 我有一个Prolog程序,但结果与我的逻辑方法不符,所以我对我在Prolog程序中缺少的内容感兴趣 . 任何帮助,将不胜感激 . 很抱歉发布到stackoverflow,我找不到更合适的stackexchange站点来解决这个问题 .

谜语的文字:

在丛林中生活着一群当地人,他们的表情有着非同寻常的怪癖:男人总是说实话;女人从不按顺序说两句错误句子,或依次说两句真句 . 最令人不舒服的是,男人和女人的穿着和看起来一般都是一样的,所以对真理的认识有时很复杂 . 一位人类学家试图研究当地人,但他仍然不熟悉母语 . 所以有一天,他遇到了一个家庭并问孩子他是男孩,人类学家不明白答案 . 这就是为什么他转向父母,其中一人告诉他“孩子说他是个男孩”,另一个说“孩子是女孩,孩子撒了谎” . 人类学家需要知道孩子如何回应(或撒谎)继续研究当地传统,决定孩子和父母双方的性别 .

我认为我的逻辑方法是正确的:

孩子可以是女人也可以是男人 . 让他成为一个男人 . 然后他不得不说他是一个男人,因为男人总是说实话 . 父母2说孩子是女孩,孩子撒谎 . 父母2肯定不是一个男人,因为孩子是一个男人是矛盾的 . 但父母不能成为女性,因为只有一句话必须是假的 . 但这不是因为孩子是男孩,他当然不会说谎 . 此外,孩子是一个男人,因此他不是女孩,因此这两个句子都是不真实的 . 孩子肯定不是男人 . 让孩子成为女人 . 由于孩子可能会说她是男人还是女人,因此这有点复杂 . 让孩子成为女人并说她是男人 . 让我们从父母2开始 . 这一定是一个男人,因为他说婴儿是一个女人并撒谎 . 父母1可以是女性,因为她说婴儿说她是男孩 . 女人可能会或可能不会撒谎 . 如果我们承认孩子可以有两个父亲,那也可能是一个男人 . 为了控制,让孩子成为一个女人,并说她是一个女人 . 父母2必须是女性,因为她说婴儿是女孩,这是真的,但同时说她在撒谎,这是不正确的 . 父母1必须是男人,但不能因为男人总是说实话 . 但父母1说孩子说他是个男孩,这不是真的 . 只有孩子可以为父母生两个妻子,这才有可能 . 解决方案:孩子是女性,父母1是女性,父母2是男性 .

我的Prolog程序说这个问题有多种解决方案 . 第一个说孩子和父母一样是男人 . 父母2是女人 . 正确的解决方案是第七个 . 我错过了一些“如果”或者!运营商在哪里?或者这种方法完全不好?

% split(+list, -listOfItemsAtEvenPositions, -listOfItemsAtOddPositions)

split([], [], []).
split([X|TList], Even, [X|TOdd]) :- rozdel(TList, TOdd, Even).

% says(+gender, +listOfSentences, -listOfTrueSentences)

% Men always say the truth.
says(man, X, X).

% Women never say two false sentences in sequence, or two true sentences in sequence.
says(woman, Sentences, TrueSentences) :-
   split(Sentences, _, TrueSentences); % Every odd sentence says the truth.
   split(Sentences, TrueSentences, _). % Every even sentence says the truth.

% solution(-genderOfChild, -genderOfFirstParent, -genderOfSecondParent)

solution(Child, Parent1, Parent2) :-

   % The child said something.
   says(Child, _, _),

   % The first parent says: "The child said he was a boy"
   says(Parent1, [says(Child, [Child=man], _)], _),

   % The second parent says: "The child is a girl, the child lied."
   says(Parent2, [Child=woman, says(Child, [Child=man], _)], _),

   % The child cannot have two parents of same gender.
   Parent1 \= Parent2.

我是Prolog的新手所以就是这样 .

1 回答

  • 2

    这是我写的

    :- use_module(library(clpb)).
    
    solve(L) :-
        L = [A,B,C,D],
        % A : true means the child is a boy
        % B : true means the child tells the truth
        % C : true means person 1 is a man
        % D : true means person 2 is a man
    
    
        % person 1 : The child said he was a boy (and a man tells the truth)
        % if person 1 is a man
        sat(C =< A),
        % if person 1 is a woman, we can't write anything
        % because there's only one sentence
    
    
        % person 2 "The child is a girl, the child lied"
        % if person 2 is a man
        sat(D =< ~A * ~B),
        % if person 2 is a woman
        sat(~D =< ((~A # B) # (A # ~B))),
    
        % Prolog works
        labeling([A,B,C,D]).
    

    我明白了:

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

    这意味着孩子是女孩,她也是1个人 . 人2是男人 .

    请注意,人1可以忽略:

    :- use_module(library(clpb)).
    
    solve(L) :-
        L = [A,B,C],
        % A : true means the child is a boy
        % B : true means the child tells the truth
        % C : true means person 2 is a man
    
    
        % person 2 "The child is a girl, the child lied"
        % if person 2 is a man
        sat(C =< ~A * ~B),
        % if person 2 is a woman
        sat(~C =< ((~A # B) # (A # ~B))),
    
        % Prolog works
        labeling([A,B,C]).
    

    回答:

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

相关问题