我将尝试对您的代码进行尽可能少的更改。
绝对错误的一件事是您尝试计算差异的位置。Prolog 仅在使用is运算符时进行算术计算。你的代码:
if((Hi1row - Hi2row), IsumDiff, Hi1row),
只是将 (XY) 形式的表达式传递给if谓词,而不是计算它。稍后在内部if,您不计算差异,而是尝试将表达式与零进行比较……但失败了,因为您只能将数字与数字进行比较,而不能与表达式进行比较——并且Diff被分配给一个表达式。
如果你重写 if 的第一个子句,它会起作用(即使你也应该is在这里去掉它):
if((X-Y), Iresult, Entry) :-
X > Y,
Iresult is Entry.
这样,您的if谓词将从表达式中获取 X 和 Y 以便能够比较它们。
此外,您需要避免使用if谓词来产生两个可能的答案。if即使 X>Y: 在回溯过程中,您的第二个子句也会被调用。最简单的方法是放在!第一个子句的末尾。这意味着:“到目前为止,我接受了这个程序中的第一个解决方案,我不想从这里回去寻找任何其他解决方案”。该条款将更改为:
if((X-Y), Iresult, Entry) :-
X > Y,
Iresult is Entry,
!.
但是......这在小程序中很好,如果您确实需要在程序的其他部分进行回溯,这可能会破坏它。更简洁的方法是检查两个子句中的适当条件。将它们重写为:
if((X-Y), Iresult, Entry) :-
X > Y,
Iresult is Entry.
if((X-Y), Iresult, _) :-
X =< Y,
Iresult is 0.
然后你确定如果 X>Y,第二个子句将失败。
在这些修改之后,您的代码应该可以工作......如果没有,请报告。尽管如此,它仍然不会很序幕。这有点太冗长了。
编辑:
好的,我会以一种简单的方式编写它:
sum_if_bigger([], [], 0).
sum_if_bigger([A|L1], [B|L2], Result) :-
sum_if_bigger(L1, L2, Partial),
Result is Partial + max(0, A-B).
...或以尾递归方式:
sum_if_bigger_tr(L1, L2, R) :-
sum_if_bigger_tr(L1, L2, 0, R).
sum_if_bigger_tr([], [], R, R).
sum_if_bigger_tr([A|L1], [B|L2], Partial, Result) :-
NewPartial is Partial + max(0, A-B),
sum_if_bigger_tr(L1, L2, NewPartial, Result).