解决Prolog中的谜题

时间:2016-11-14 22:48:37

标签: prolog zebra-puzzle

我是prolog的新手,我正在努力解决这个难题。我在youtube上做了一些关于prolog基础知识的教程,但我需要一些帮助解决下面的难题。

两周前,四名爱好者在他们附近的天空中看到了物体。四人中的每一人都在另一天报告了他或她的目击事件。联邦调查局来了,能够给每个人一个不同的解释,说明他或她有什么"真的"看到。你能确定每个人看到对象的那一天(星期二到星期五),以及它结果出来的对象吗?

  1. 先生。本周早些时候,K在看到气球的那个时刻看到了他的目击,但在本周晚些时候的某个时刻,却发现了那个发现风筝的人(谁不是G女士)。
  2. 周五看到的是Barn女士或看过飞机的人(或两人)。
  3. 先生。尼克周二没有看到他。
  4. 先生。 K不是那个被证明是电话杆的人。
  5. 我已经正确设置了我的规则,但我似乎无法将逻辑降低。我正在寻找指导而非直接答案。在最右边,我列出了我试图回答的每个问题的编号

            enthu(mr_k).
            enthu(ms_barn).
            enthu(ms_g).
            enthu(mr_nik).
    
            object(ballon).
            object(kite).
            object(plane).
            object(tele_pole).
    
            day(tuesday).
            day(wednesday).
            day(thursday).
            day(friday).
    
    
    
            sight(X,ballon).
    
            sighting(mr_k):-   1
            day(X),
            sight(X,Y),
            didntc_kite(ms_g).
    
            friday_sight:- enthu(ms_barn);    2
            saw(X,plane);
            both(ms_barn,X).
    
    
            nosight_tuesday(mr_nik,X).          3
    
            no_telepole(mr_k,Y).          4
    

1 个答案:

答案 0 :(得分:0)

我知道你没有要求解决方案,但我发现如果没有可行的解决方案,我很难描述该怎么做。我为此道歉。

这就是我要做的事情:

/*
1. Mr. K made his sighting at some point earlier in the week than the one who saw the balloon, but at some point later in the week, than the one who spotted the Kite ( who isn't Ms. G ).
2. Friday's sighting was made by either Ms. Barn or the one who saw a plane ( or both ).
3. Mr. Nik did not make his sighting on Tuesday.
4. Mr. K isn't the one whose object turned out to be a telephone pole.
*/

?-
% Set up a list of lists to be the final solution
        Days = [[tuesday,_,_],[wednesday,_,_],[thursday,_,_],[friday,_,_]],
/* 1 */ before([_,mr_k,_],[_,_,balloon],Days),
/* 1 */ before([_,_,kite],[_,mr_k,_],Days),
/* 2 */ (member([friday,ms_barn,_],Days);
            member([friday,_,plane],Days);
            member([friday,ms_barn,plane],Days)),
% Fill in the rest of the people
        members([[_,mr_k,_],[_,ms_barn,_],[_,ms_g,_],[_,mr_nik,_]],Days),
% Fill in the rest of the objects
        members([[_,_,balloon],[_,_,kite],[_,_,plane],[_,_,tele_pole]],Days),
% Negations should be done after the solution is populated
/* 1 */ member([_,NOT_ms_g,kite],Days), NOT_ms_g \= ms_g,
/* 3 */ member([tuesday,NOT_mr_nik,_],Days), NOT_mr_nik \= mr_nik,
/* 4 */ member([_,NOT_mr_k,tele_pole],Days), NOT_mr_k \= mr_k,
    write(Days),
    nl,
    fail.

% Checks that `X` comes before `Y`
% in the list `Ds`
before(X,Y,Ds) :-
    remainder(X,Ds,Rs),
    member(Y,Rs).

% Finds a member of a list and
% unifies the third parameter such
% that it is the remaining elements in
% the list after the found member
remainder(X,[X|Ds],Ds).
remainder(X,[_|Ds],Rs) :- remainder(X,Ds,Rs).

% An extended version of `member` that
% checks if the members of the first list
% are all members of the second
members([],_).
members([X|Xs],Ds) :-
    member(X,Ds),
    members(Xs,Ds).

这让我:

[[tuesday, ms_g, tele_pole],
    [wednesday, mr_nik, kite],
    [thursday, mr_k, plane],
    [friday, ms_barn, balloon]]