所以我在Prolog中有一个更简单的爱因斯坦/斑马拼图变体。
我想出了这个可能的解决方案:
b_setval(T_age, Var).
friends(L) :-
L = [person(A1, B1, T_age), person(A2, B2, C2), person(A3, B3, T_age+3)],
:
:
member(person(_,yang,T_age+3),L),
member(person(_,_,18),L).
但我的查询friends(L). - false.
仅返回false
,如上所述。
我做错了什么?
答案 0 :(得分:1)
突出的一个潜在问题是列表T_age+3
中的L
字词。在Prolog中,这不会在线进行算术评估。它只是术语'+'(T_age,3)
。因此,唯一匹配此列表成员的元素将是一个看起来像person(X, Y, <something>+3)
的术语。目前还不清楚这是否是你的意图。
您可以执行trace
查看每个member
调用如何实例化变量,但为了说明的目的,请尝试手动执行此操作:
L = [person(A1, B1, T_age), person(A2, B2, C2), person(A3, B3, T_age+3)],
member(person(ada, _,T_age),L),
...
此member
调用应该会成功,因为Prolog可以通过统一person(A1, B1, T_age)
将其与列表中的A1 = ada
相匹配。列表L
现在看起来像:
[person(ada, B1, T_age), person(A2, B2, C2), person(A3, B3, T_age+3)]
转到下一个member
来电:
member(person(ama, _, _),L),
...
这不能与第一个成员匹配,但可以通过统一A2 = ama
来匹配第二个成员。 L
现在是:
[person(ada, B1, T_age), person(ama, B2, C2), person(A3, B3, T_age+3)]
然后你有:
member(person(ana, _, _),L),
这不能与第一个或第二个成员匹配,但可以通过统一A3 = ana
来匹配第三个成员。 L
现在是:
[person(ada, B1, T_age), person(ama, B2, C2), person(ana, B3, T_age+3)]
下一个member
来电是:
member(person(_,chang, _),L),
通过统一B1 = chang
可以再次匹配第一个成员,因此L
成为:
[person(ada, chang, T_age), person(ama, B2, C2), person(ana, B3, T_age+3)]
然后
member(person(_,yang,T_age+3),L),
这将通过统一B2 = yang
和C2 = T_age+3
来匹配列表的第二个元素。 L
然后成为:
[person(ada, chang, T_age), person(ama, yang, T_age+3), person(ana, B3, T_age+3)]
然后
member(person(_,thatcher,17),L),
这是你遇到麻烦的地方。由于第二个参数,它无法匹配L
的前两个元素。第三个参数17
与T_age+3
的第三个元素中的L
一词不匹配。请记住:Prolog并没有将其解释为等式T_age+3 = 17
。它只是将17视为原子整数,并将T_age+3
视为具有两个参数的术语,并发现它们不匹配。所以这个member
调用失败了,整个谓词都失败了。
答案 1 :(得分:1)
按照@luker的回答后,您可以检查答案
friends(L) :-
% 1
L = [person(ada, _, Ta), person(ama, _, _), person(ana, _, _)],
% 2
member(person(_,_,15), L),
member(person(_,_,17), L),
member(person(_,_,18), L),
% 3
member(person(_, chang, _), L),
% 4
member(person(_, yang, Ty), L), Ty is Ta + 3,
% 5
member(person(_, thatcher, 17), L).
有趣的是,这会产生2个结果,这对于这类问题来说很奇怪。