Пролог - реализация некоторых основных арифметических операций

Я новичок в Прологе, и мне нужно реализовать некоторые основные арифметические операции над натуральными числами без использования встроенных предикатов.

Я представляю натуральное число 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)))))), и после последней пары перейдет в бесконечный цикл, для неизвестная мне причина.

Другие вопросы по тегам