0

我有以下代码

isInRange(Point1,Point2,Range):-
manhatan2(Point1,Point2,Manhatan),
Range>Manhatan.

manhatan2 计算 2 个点之间的 manhatan 距离,作为 2 元素列表 [X,Y]

我不明白为什么 isInRange 总是评估为 true

isInRange([0,0],[0,10],9) 计算结果为真 isInRange([0,0],[0,10],100) 也计算结果为真

我很确定我的 manhatan 功能是正确的。已经用许多值对其进行了测试

谁能帮我理解我的代码有什么问题?

%编辑从这里开始

所以我追踪了这该死的东西,这是我使用的更多代码

modul(A,B,R):-A<B,R is B-A.
modul(A,B,R):-A>B,R is A-B.

extractFromList([H|_],X,R):- X is 0,R is H.
extractFromList([_|T],X,R):- X1 is X-1,extractFromList(T,X1,R).

manhatan(X1,Y1,X2,Y2,R):- modul(X1,X2,R1),modul(Y1,Y2,R2),R is R1+R2.

manhatan2(P1,P2,R):-
extractFromList(P1,0,X1),
extractFromList(P1,1,Y1),
extractFromList(P2,0,X2),
extractFromList(P2,1,Y2),
manhatan(X1,Y1,X2,Y2,R).

extract fromFromList 从给定列表中提取第 X 个元素

模块应该返回 |AB|

跟踪 isInRange([0,0],[0,10],100) 任何我想要的东西。

跟踪 isInRange([0,0],[0,10],9) 在将 manhatan 与范围进行比较时停止并开始重做 modul(0,10,_GXXX) 将 _GXXX 评估为 -10,因此 Manhatan < Range 条件评估为true 因此所有 isInRange 评估为 true

为什么这样做?

为什么它以这种方式重做模计算?

4

1 回答 1

0

简短的回答:以下代码可以满足您的要求:

manhattan(L1,L2,Result) :- manhattan(L1,L2,0,Result).

manhattan([],[],Res,Res).
manhattan([H1|T1],[H2|T2],Acc,Res) :-
    AccNew is Acc + abs(H1-H2),
    manhattan(T1,T2,AccNew,Res).

isInRange(P1, P2, Range) :-
    manhattan(P1, P2, Distance),
    Range > Distance.

更长的答案:我尝试了您的代码,但它的行为与您描述的不同。对我来说,isInRange 总是失败,因为如果 A==B,'modul' 会失败。您应该将第一种情况的测试更改为 A =< B。或者,更好的是,使用内置的“abs”函数。

我假设在您以前的版本中,您没有在第二种情况下进行测试。在这种情况下,Prolog 将在第一种情况导致失败时尝试第二种情况(例如,因为 Range > Manhatan 失败)。以一种方式在第二种情况下添加测试以解决此问题。

于 2013-10-27T09:17:14.083 回答