Я попытаюсь представить как можно меньше изменений для вашего кода.
Одна вещь, которая определенно неверна, - это то, где вы пытаетесь вычислить разницу. Prolog выполняет арифметические вычисления только при использовании оператора is
. Код:
if((Hi1row - Hi2row), IsumDiff, Hi1row),
это просто передавая выражение вида (X-Y) в if
предиката, а не его расчета. Позже внутри if
вы не вычисляете разницу, но пытаетесь сравнить выражение с нолем ... что не удается, потому что вы можете сравнивать числа только с числами, а не с выражениями, а Diff
получает назначение.
Это будет работать, если вы перезаписать первое предложение о, если следующим образом (даже если вы должны также избавиться от этой 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, то второе предложение не удастся.
После этих изменений ваш код должен работать ... Сообщите об этом, если это не так. Это все равно будет не очень пролого-иш; это немного слишком многословно.
Edit:
Хорошо, я напишу его простым способом:
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).
Какой из них вам нужно вычислить: сумму (макс (A [я], B [я]) для г в 1..len (A)) или sum (max (A [i] -B [i], 0) для i в 1..len (A))? – liori
(BTW, вы чрезмерно употребляете 'is'. Вам нужно' is' рассчитать сумму и разницу, она не нужна для простых назначений. – liori
Я не уверен, что я понимаю ваш вопрос. Если у меня есть два списка, List 1 является [ 0,0,0,1], а List 2 - [0,0,3,0]. Мне нужно выполнить поиск по списку, пока не найду соответствующий элемент в списке 1, который больше, чем список List 2. В этом случае это произойдет с 1> 0. Предикат «if» возвращает это значение, которое больше (1), которое добавляется к текущему итогу. В этом итоге общее число, которое мне нужно вернуть в конце. –