我是Prolog的新手并且正在完成家庭作业。我的程序应该采用两个相等长度的列表,并执行D = sqrt((X1-Y1)^ 2 +(X2-Y2)^ 2 + ... +(XN-YN)^ 2)。我已经编写了代码来获得正确的答案,但它没有正确呈现。我认为它可能是逻辑流程的一个问题,因为它似乎以无限循环结束。它应该看起来像:
?- distance([1,2,3], [2,3,4], D).
D = 1.732051.
我的代码给了我正确的结果,但它打印出来像:
?- distance([1,2,3],[2,3,4],D).
1.732051
true
只是因为我有一条线来打印结果。它也没有结束(没有句号),直到我进入,这就是为什么我担心我有一个循环。如何重新编写代码或重定向逻辑,使其正常打印?
distance([],[],D) :-
F is sqrt(D),
format("~f~n", [F]).
distance([A|T1], [B|T2], D) :-
var(D),
S is (A-B)*(A-B),
distance(T1, T2, S);
C is A-B,
E is C*C,
F is D+E,
distance(T1, T2, F).
答案 0 :(得分:2)
您的程序不会进入无限循环,否则您很可能会在某个时刻出现堆栈溢出错误。 发生的事情是你的代码留下了一个开放的选择点,所以最终解释器试图重做(失败)。 您没有按预期获得结果,因为调用过程中使用的变量D永远不会被绑定。
你最好解决这个问题,思考如何递归建模。在这种情况下,您可以例如在输入列表为空时和不存在时分割问题(我在这里假设调用带有空列表的过程将导致结果为0)。
因此,在这种情况下,您将创建两个子句,一个用于基本情况(空列表),另一个用于递归步骤。我还将使用prolog中使用的常用方法,包括使用累加器。
因此我们为distance / 3创建一个事实,它将调用另一个使用此累加器的过程:
distance(L1,L2,F) :-
distance(L1, L2, 0, F).
我们使用累加器来保存代码中项目差异(A-B)*(A-B)之和的部分结果:
现在我们从基本案例(空列表)开始:
distance([],[],S,F) :-
F is sqrt(S).
这里我们说明当没有剩余项目时的结果是累加器的平方根。
我们现在遵循递归步骤,即计算每个列表中第一项的平方项差异并进行递归。
distance([A|T1], [B|T2], D, SQRT) :-
S is D+(A-B)*(A-B),
distance(T1, T2, S, SQRT).
现在我们完成了:
?- distance([1,2,3],[2,3,4],D).
D = 1.7320508075688772.
答案 1 :(得分:0)
我不理解format
函数的使用,所以我所能做的只是提供我自己的尝试。我认为你的尝试有一个缺点,就是递归的基本情况没有明确说明。
请考虑我的方法:
distance([],[],0).
distance([A],[A],0).
distance([A|T1],[B|T2],D) :-
distance(T1,T2,F),
D is sqrt((A-B)*(A-B) + F*F).
答案 2 :(得分:0)
我认为你应该使用累加器:
distance(L1, L2, D) :-
distance(L1, L2, 0, D).
distance([], [], TT, D) :-
D is sqrt(D).
distance([X1 | Y1], [X2 | Y2], TT, D) :-
TT1 is TT + (X1 - X2) * X1 - X2),
distance(Y1, Y2, TT1, D).