Пролог рекурсивно умножается - PullRequest
0 голосов
/ 13 декабря 2018

Я пытаюсь рекурсивно умножить два числа в Прологе, т.е. 3*4 = 3+3+3+3 = 12.

Мой код:

mult(0,Y,Y).
mult(X,Y,Z) :- 
    NewX is X-1, 
    Z is Y + mult(NewX,Y,Z).

, но я держу либо в бесконечном цикле, либо мне говорят mult это не функция.

1 Ответ

0 голосов
/ 13 декабря 2018

То, что вы здесь создали, это предикат .Предикат не такой же, как функция в информатике, вы не можете написать A is B + some_pred(C) или, по крайней мере, не так, как я знаю в ISO Prolog, и определенно не без добавления некоторой дополнительной логики.

Для передачи значений используются переменные.Таким образом, мы можем вызвать рекурсивный предикат mult/3 и использовать переменную, которая будет объединена с результатом.Затем мы можем выполнить с ним арифметику, например:

mult(0, _, 0).
mult(X, Y, Z) :-
    X1 is X - 1,
    mult(X1, Y, <b>Z1</b>),
    Z is Y + <b>Z1</b>.

Обратите внимание, что вы можете не переназначить (другое) значение переменной.Поэтому, если, как и в вопросе, дважды использовать Z, тогда, если Y не равно 0, это не удастся.

Однако вышеприведенного все еще недостаточно, поскольку это приведет крезультат, но затем застрять в бесконечном цикле, так как если он вызывает (в конечном итоге) mult(0, 4, Z) (4 здесь просто значение), есть два способа решить это: с базовым случаем и с рекурсивным случаем.

Таким образом, нам нужен «охранник» для второго случая, например:

mult(0, _, 0).
mult(X, Y, Z) :-
    <b>X > 0</b>,
    X1 is X - 1,
    mult(X1, Y, Z1),
    Z is Y + Z1.

Затем мы получим, например:

?- mult(14, 25, Z).
Z = 350 ;
false.

Можно улучшить скоростьэто предикат mult/3 путем реализации версии с аккумулятором .Я оставляю это как упражнение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...