Solving Caliban problems with prolog

我的未来我决定 提交于 2020-01-05 18:57:26

问题


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.


回答1:


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



来源:https://stackoverflow.com/questions/20079467/solving-caliban-problems-with-prolog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!