使用Prolog解决Caliban问题 [英] Solving Caliban problems with prolog

查看:105
本文介绍了使用Prolog解决Caliban问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力使用学校的序言来解决逻辑难题.线索如下:

  1. 布朗,克拉克,琼斯和史密斯是为自己服务的4位重要公民 社区为行为学家,银行家,医生和律师,尽管不一定 分别.

    比琼斯更保守但比史密斯更自由的布朗, 比比他年轻并且拥有 比克拉克(Clark)年长的男人收入要高.

    比建筑师收入更高的银行家也不是最小的 也不是最古老的.

    医生比高尔夫球员更穷,但医生却不那么保守 比建筑师.

    不出所料,最年长的男人是最保守的,并且拥有 收入最高,而最小的男人是最好的高尔夫球手.

    每个人的职业是什么?

    提示:按人员的能力,能力,相对年龄等对他们进行排名 使用数字1,2,3,4请注意说明1是否代表 例如,年龄最小或年龄最大.这样做使比较易于编码.

要进行编码(如下所示),将线索给出的所有关系解释为列表列表,其中每个列表都定义了

 %[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).

所有关系都如此.

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

   ?- profession(L).
    fail.

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

解决方案

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).
.....

这意味着,所有人比布朗年轻的人(包括一个人)必须是比他更贫穷的高尔夫球手.

这里也有一个陷阱.由于我们被告知比布朗年轻的人,这意味着必须至少存在一个这样的人(不同于数学上的在这里讨论).

I'm working on solving a logic puzzle using prolog for school. Here's the clues:

  1. Brown, Clark, Jones and Smith are 4 substantial citizens who serve their community as achitect, banker, doctor and lawyer, though not necessarily respectively.

    Brown, who is more conservative than Jones but more liberal than Smith, is a better golfer than the men who are younger than he is and has a larger income than the men who are older than Clark.

    The banker, who earns more than the architect, is neither the youngest nor the oldest.

    The doctor, who is a poorer golfer than the lawyer, is less conservative than the architect.

    As might be expected, the oldest man is the most conservative and has the largest income, and the youngest man is the best golfer.

    What is each man's profession?

    hint: to rank people for weath, ability, relative age, etc use the numbers 1,2,3,4 Be careful to state whether 1 represents, e.g., youngest or oldest. Doing this makes comparisons easy to code.

To code (as follows) interprets all the relationships, given by the clues, as a list of lists, wherein each list defines the

 %[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).

I define the relative_politics,relative_salary,relative_age, and golf_ability relationships like so

EG:

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

And it goes on for all relationships.

I think I have faithfully translated all of the clues to prolog but it just says fail when I query the database. EG:

   ?- profession(L).
    fail.

I am using NU Prolog. I'm wondering if I made an error in my translation of the clues or I omitted a fact that is needed for the database to satisfy all the conditions of the list L.

解决方案

bettergolfer(G3,younger(_,A6)) ... it doesn't work this way, in Prolog. Instead, have this

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

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

this means, all the persons (including none) that are younger than Brown, must be poorer golfers than he is.

There is a catch here, too. Since we're told about the men younger than Brown, it means there must exist at least one such man (unlike in the mathematical definition of implication). We have to code this too. For example,

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

(using unique names for the new logvars of course). You'll have to make the same transformation for your richer(M3,older(_,A3)).

Great idea BTW, to have the comparison predicates defined in a generative fashion:

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

If you were to define them as arithmetic comparisons, poorer(A,B):- A<B., you could potentially run into problems with uninstantiated variables (as recently discussed here).

这篇关于使用Prolog解决Caliban问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆