Вам нужно немного поработать до go, чтобы понять концепции Пролога. Ваша первоначальная попытка полна атомов (нижний регистр), а не переменных (верхний регистр). В нем есть изменчивость. Вы думаете, что у Пролога есть функции (у него есть предикаты), которые возвращают значения (их нет - они либо успешны, либо терпят неудачу).
Я сделал предположение, что вы очищаете первые три значения вне списка, а затем отбрасывая первый элемент и возвращаясь вниз.
Итак, если у меня есть этот список [1,2,1,2]
, я сначала посмотрю на [1,2,1]
, а затем на [2,1,2]
.
Или, в этом более длинном примере:
[1,2,1,2,2,1,1] => [1,2,1]
[2,1,2,2,1,1] => [2,1,2]
[1,2,2,1,1] => [1,2,2]
[2,2,1,1] => [2,2,1]
[2,1,1] => [2,1,1]
Как только в списке будет только 2 элемента, я могу остановиться.
Я предполагаю, что каждый из списка из трех значения - это ваши [Elt1, Elt2, Elt3]
.
Чтобы вычислить это, нам нужны входной список и выходная сумма, но для рекурсии вниз по списку нам нужен аккумулятор, чтобы отслеживать текущую сумму, поскольку мы go. Первый предикат прост:
compute(List,Sum) :- compute(List,0,Sum).
Теперь у вас есть 5 предикатов, которым мы должны сопоставить.
- список, содержащий 2 элемента - мы можем вернуть наш аккумулятор
Elt1 = Elt2
затем sum = sum + (elt1 + elt2)
Elt1 = Elt3
затем sum = sum + (elt1 * elt3)
Elt2 = Elt3
и Elt3 \= 0
затем sum = sum + (100 / elt3)
- Ничего из вышеперечисленного поэтому мы просто передаем текущий аккумулятор, т.е.
sum = sum
compute([_,_],Sum,Sum).
compute([Elt1,Elt2,Elt3|Tail],AccNow,Sum) :-
Elt1 = Elt2,
!,
AccNext is AccNow + Elt1 + Elt2,
compute([Elt2,Elt3|Tail],AccNext,Sum).
compute([Elt1,Elt2,Elt3|Tail],AccNow,Sum) :-
Elt1 = Elt3,
!,
AccNext is AccNow + Elt1 * Elt3,
compute([Elt2,Elt3|Tail],AccNext,Sum).
compute([_,Elt2,Elt3|Tail],AccNow,Sum) :-
Elt3 \= 0,
Elt2 = Elt3,
!,
AccNext is AccNow + 100 / Elt3,
compute([Elt2,Elt3|Tail],AccNext,Sum).
compute([_,Elt2,Elt3|Tail],Acc,Sum) :-
compute([Elt2,Elt3|Tail],Acc,Sum).
Если я попробую это на ?- compute([1,2,1,2],X).
, то получу X = 5
. Это совпадает с предикатом Elt1 = Elt3
и дает мне 0 + 1 * 1
, а затем снова по предикату Elt1 = Elt3
дает мне 1 + 2 * 2
или 5
.
Если я попробую это на ?- compute([1,2,1,2,2,1,1],X).
, я получу X = 159
. Я оставлю это вам, чтобы убедиться, что это правильный результат.
Просто имейте в виду, что все, что пытается сделать Prolog, - это успех. Если его просят доказать цель (например, compute/3
), он находит первый совпадающий предикат и пытается доказать это (путем доказательства любых подцелей), а когда он терпит неудачу, он просто возвращается к предыдущей точке выбора и пробует другой выбор и продолжает. Если это доказывает первоначальную цель, значит, она успешна. Если этого не произошло, то это не удалось. Нет возвращаемых значений - только связанные переменные.