我正在为学校使用prolog解决一个逻辑难题。以下是线索:
-
Brown、Clark、Jones和Smith是四位杰出的公民作为建筑师、银行家、医生和律师的社区,尽管不一定分别地
布朗比琼斯更保守,但比史密斯更自由,是一个比他年轻的人更好的高尔夫球手比克拉克年长的男性收入更高。
银行家的收入比建筑师高,他既不是最年轻的也不是最老的。
医生是一个比律师更差的高尔夫球手,他不那么保守而不是建筑师。
不出所料,最年长的人是最保守的收入最高,最年轻的人是最好的高尔夫球手。
每个人的职业是什么?
提示:根据体质、能力、相对年龄等对人进行排名使用数字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关系,比如
例如:
richer(4,1).
moreconservative(4,1).
poorer(1,4).
poorer(1,3).
所有的关系都是如此。
我想我已经忠实地将所有线索翻译到prolog中,但当我查询数据库时,它只是说失败。例如:
?- 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).
.....
这意味着,所有比布朗年轻的人(包括没有)一定是比他更穷的高尔夫球手。
这里也有一个陷阱。既然我们被告知比布朗年轻的男人,这意味着必须至少存在一个这样的男人(不像数学定义中的含义)。我们也必须对此进行编码。例如,
( member(X,L), age(X,AX), younger(AX,A6) -> true ),
.....
(当然,对新的logvar使用唯一的名称)。您必须对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.
,您可能会遇到未实例化变量的问题(正如最近在这里讨论的那样)。