I ll try to introduce as little changes as possible to your code.
One thing that is definitely wrong is where you try to calculate the difference. Prolog does arithmetic computations only when using is
operator. Your code:
if((Hi1row - Hi2row), IsumDiff, Hi1row),
is merely passing the expression of the form (X-Y) to the if
predicate, and not calculating it. Later inside if
, you do not compute the difference but try to compare the expression to zero... which fails, because you can only compare numbers to numbers, and not to expressions -- and Diff
gets assigned to an expression.
It would work if you rewrite the first clause of if as follows (even though you should also get rid of that is
here):
if((X-Y), Iresult, Entry) :-
X > Y,
Iresult is Entry.
This way your if
predicate will get X and Y from the expression to be able to compare them.
Also, you need to avoid your if
predicate to yield two possible answers. Your second if
clause will be invoked even when X>Y: in the process of backtracking. The easiest way is to put !
at the end of first clause. It means: "Up to this point, I accept the first solution in this program and I don t want to go back from here to find any other solutions". The clause will be changed to:
if((X-Y), Iresult, Entry) :-
X > Y,
Iresult is Entry,
!.
But... this is good in small programs, and if you actually need backtracking in other parts of your program, this can break it. The cleaner way would be to check proper condition in both clauses. Rewrite them to:
if((X-Y), Iresult, Entry) :-
X > Y,
Iresult is Entry.
if((X-Y), Iresult, _) :-
X =< Y,
Iresult is 0.
Then you re sure that if X>Y, the second clause will fail.
After these modifications your code should work... Please report if it doesn t.
It still won t be very prolog-ish though; it is a little bit too verbose.
Edit:
Ok, I d write it in a simple way:
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).
...or in a tail-recursive way:
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).