用prolog解决Caliban问题

时间:2013-11-19 18:40:30

标签: prolog logic relation zebra-puzzle

我正在为学校使用prolog解决逻辑难题。这是线索:

  1. 布朗,克拉克,琼斯和史密斯是4位为他们服务的重要公民 社区作为建筑师,银行家,医生和律师,虽然不一定 分别

    布朗,比琼斯更保守,但比史密斯更自由,   是一个比他年轻的男人更好的高尔夫球手   收入高于比克拉克年长的男人。

    银行家的收入高于建筑师,并不是最年轻的   也不是最古老的。

    比律师更差的高尔夫球手,医生不那么保守   而不是建筑师。

    正如所预料的那样,最年长的男人是最保守的并拥有   最大的收入,最年轻的男人是最好的高尔夫球手。

    每个男人的职业是什么?

    提示:根据健康,能力,相对年龄等对人进行排名     使用数字1,2,3,4小心说明1是否代表,     例如,最年轻或最老的。这样做可以使比较变得容易编码。

  2. 代码(如下所示)将线索给出的所有关系解释为列表列表,其中每个列表定义

     %[profession,surname,politics,relative_age, relative_salary, golf_ability]:    
    
    profession(L) :- L = [[_,'Brown',_,_,_,_],[_,'Jones',_,_,_,_],[_,'Clark',_,_,_,_],
        [_,'Smith',_,_,_,_]],
    member([_,'Brown',P1,A6,M3,G3],L),
    member([_,'Jones',P2,_,_,_],L),
    member([_,'Clark',_,A3,_,_],L),
    member([_,'Smith',P3,_,_,_],L),
        moreconservative(P1,P2),
        moreliberal(P1,P3),
        bettergolfer(G3,younger(_,A6)),
        richer(M3,older(_,A3)),
    member(['banker',_,_,A1,M1,_],L),
    member(['architect',_,P5,_,M2,_],L),
        richer(M1,M2),
        (A1 = 2;A1 = 3),
    member(['doctor',_,P4,_,_,G1],L),
    member(['lawyer',_,_,_,_,G2],L),
        worsegolfer(G1,G2),
        moreliberal(P4,P5),
    member([_,_,4,4,4,_],L),
    member([_,_,_,1,_,4],L).
    

    我定义了relative_politics,relative_salary,relative_age和golf_ability关系,如此

    EG:

        richer(4,1).
        moreconservative(4,1).
        poorer(1,4).
        poorer(1,3).
    

    所有关系都在继续。

    我认为我已经忠实地将所有线索翻译成prolog但是当我查询数据库时它只是说失败了。 EG:

       ?- profession(L).
        fail.
    

    我正在使用NU Prolog。我想知道我在翻译线索时是否犯了错误,或者我省略了数据库满足列表L的所有条件所需的事实。

1 个答案:

答案 0 :(得分:1)

bettergolfer(G3,younger(_,A6)) ...在Prolog中这种方式不起作用。相反,有这个

   (  member( X,L), age(X,AX), golf(X,GX),
      (  younger(AX,A6) -> better_golfer(G3,GX) ; true )),
   .....

age( [_,_,_,A,_,_],A).
golf([_,_,_,_,_,G],G).
.....

这意味着,所有比布朗更年轻的人​​(包括 none ),必须是比他更差的高尔夫球手。

这里也有一个问题。因为我们被告知比布朗更年轻的男人,这意味着必须存在至少一个这样的男人(与数学definition of implication不同)。我们也必须编码。例如,

    ( member(X,L), age(X,AX), younger(AX,A6) -> true ),
    .....

(当然,使用新logvars的唯一名称)。您必须为 richer(M3,older(_,A3)) 进行相同的转换。

好主意BTW,以生成方式定义比较谓词:

poorer(1,2). 
poorer(1,3). 
poorer(1,4). 
poorer(2,3). 
poorer(2,4). 
poorer(3,4).
richer(A,B):- poorer(B,A)

如果要将它们定义为算术比较poorer(A,B):- A<B.,则可能会遇到未实例化变量的问题(最近discussed here)。