年龄约束查找
所以我在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
。 我在做什么错?
以下@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分的结果,这是怪异这种问题。
我的变量命名有一些错误,但最后我明白了! –
突出的一个潜在问题是名单L
中的T_age+3
条款。在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
与L
的第三个元素中的术语T_age+3
不匹配。请记住:Prolog不会将其作为方程式T_age+3 = 17
解决。它只是将17看作原子整数,并将T_age+3
看作是带有两个参数的术语,并发现它们不匹配。所以这个member
调用失败,整个谓词失败。
我的意图是匹配3岁以上的年龄比其他人年龄!我的概念现在很清楚!你能否提出一种可能的解决办法,以便我可以得到可能的人的输出?非常感谢! –
我发布了基于你的建议的另一个版本,这也不起作用:( –
@jeet你是说它只是失败?按照我的回答中的建议,或者做一个“跟踪”或像我一样穿过它。我认为我回答了你原来的问题,所以如果你发现我对这个问题的回答是可以接受的,也许你可以接受它:)在你的更新中,表达式'member(person(_,yang,Y),Y是X + 3 ,L).'因为您将3个参数传递给'member/2',这是一个错误。也,。在这种情况下,'Y是X + 3'将被解释为一个术语('是(+(X,3),L)')。正如我在我的回答中所提到的,除非使用特定的算术评估,否则Prolog不会评估表达式。 – lurker
'L'是一个看起来像'person(...)'('person/3')的术语列表。一些'成员'检查正在''L'中寻找类似'h(...)'的术语,这些术语在'L'中不存在,所以这些将会失败。另外,你的一些''成员'检查有3个参数,(* eg *,'member(h,(_,_,15),L)'),并且会产生一个错误。 – lurker
@lurker对不起,大的复制粘贴错字。更正了,但仍然没有结果。 –