2016-04-28 136 views
0

所以我在Prolog中有一个简单的爱因斯坦/斑马谜题变体。年龄约束查找

enter image description here

,我想出了这个可能的解决方案:

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。 我在做什么错?

+1

'L'是一个看起来像'person(...)'('person/3')的术语列表。一些'成员'检查正在''L'中寻找类似'h(...)'的术语,这些术语在'L'中不存在,所以这些将会失败。另外,你的一些''成员'检查有3个参数,(* eg *,'member(h,(_,_,15),L)'),并且会产生一个错误。 – lurker

+0

@lurker对不起,大的复制粘贴错字。更正了,但仍然没有结果。 –

回答

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分的结果,这是怪异这种问题。

+0

我的变量命名有一些错误,但最后我明白了! –

1

突出的一个潜在问题是名单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 = yangC2 = 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的前两个元素。第三个参数17L的第三个元素中的术语T_age+3不匹配。请记住:Prolog不会将其作为方程式T_age+3 = 17解决。它只是将17看作原子整数,并将T_age+3看作是带有两个参数的术语,并发现它们不匹配。所以这个member调用失败,整个谓词失败。

+0

我的意图是匹配3岁以上的年龄比其他人年龄!我的概念现在很清楚!你能否提出一种可能的解决办法,以便我可以得到可能的人的输出?非常感谢! –

+0

我发布了基于你的建议的另一个版本,这也不起作用:( –

+0

@jeet你是说它只是失败?按照我的回答中的建议,或者做一个“跟踪”或像我一样穿过它。我认为我回答了你原来的问题,所以如果你发现我对这个问题的回答是可以接受的,也许你可以接受它:)在你的更新中,表达式'member(person(_,yang,Y),Y是X + 3 ,L).'因为您将3个参数传递给'member/2',这是一个错误。也,。在这种情况下,'Y是X + 3'将被解释为一个术语('是(+(X,3),L)')。正如我在我的回答中所提到的,除非使用特定的算术评估,否则Prolog不会评估表达式。 – lurker