Пролог - реализация некоторых основных арифметических операций
Я новичок в Прологе, и мне нужно реализовать некоторые основные арифметические операции над натуральными числами без использования встроенных предикатов.
Я представляю натуральное число Term в унарной нотации, означая, что у меня есть константа 0 и рекурсивный функтор-преемник s [т.е. 4 = s(s(s(s(0))))]. Я реализую арифметические операции, с учетом вышеупомянутых обозначений.
Набор правил:
% nat(N)/1 ---> N is a natural number
nat(0).
nat(s(X)) :-
nat(X).
% add(X,Y,Z)/3 ---> Z = X + Y
add(X,0,X) :-
nat(X).
add(X,s(Y),s(Z)) :-
add(X,Y,Z).
% mult(X,Y,Z)/3 ---> Z = X * Y
mult(0,X,0) :-
nat(X).
mult(s(X),Y,Z) :-
mult(X,Y,XY),
add(XY,Y,Z).
теперь, когда я запрашиваю:
?- mult(s(s(0)), s(s(s(0))), RES).
У меня все ок
RES = s(s(s(s(s(s(0))))))).
когда я запрашиваю: (нравится спрашивать 6/3=?)
?- mult(X, s(s(s(0))), s(s(s(s(s(s(0))))))).
Я застрял в бесконечном цикле и получаю ТАК
даже если я изменю порядок рекурсивного вызова в предикате mult, это не поможет:
mult(s(X),Y,Z) :-
add(XY,Y,Z),
mult(X,Y,XY).
Я запускаю swi-prolog на машине с Linux.
Буду признателен за ваш совет!
1 ответ
ОК, есть быстрое решение (неправильная рекурсия):
% add(X,Y,Z)/3 ---> Z = X + Y
add(0,X,X) :-
nat(X).
add(s(X),Y,s(Z)) :-
add(X,Y,Z).
а затем мульт:
mult(s(X),Y,Z) :-
add(XY,Y,Z),
mult(X,Y,XY).
даст желаемый результат.
пока что для запроса:
?- mult(X,Y,s(s(s(s(s(s(0))))))).
он выведет все пары X,Y, которые соответствуют: X * Y = s(s(s(s(s(s(s)))))), и после последней пары перейдет в бесконечный цикл, для неизвестная мне причина.