(Позвольте мне добавить это в волну промежуточных вопросов.)
Обычное определение суммы двух натуральных чисел — nat_nat_sum/3
:
nat_nat_sum(0, N, N).
nat_nat_sum(s(M), N, s(O)) :-
nat_nat_sum(M, N, O).
Строго говоря, это определение слишком общее, так как мы имеем теперь успех и для
?- nat_nat_sum(A, B, unnatural_number).
Аналогично получаем следующую подстановку ответов:
?- nat_nat_sum(0, A, B).
A = B.
Мы интерпретируем эту подстановку ответов как включающую все натуральные числа и не заботимся о других терминах.
Учитывая это, теперь давайте рассмотрим его свойство завершения. На самом деле достаточно рассмотреть следующий неудачный фрагмент. То есть не только nat_nat_sum/3
не завершится, если этот слайс не завершится. На этот раз они абсолютно одинаковы! Таким образом, мы можем сказать, если.
nat_nat_sum(0, N, N) :- false. nat_nat_sum(s(M), N, s(O)) :- nat_nat_sum(M, N, O), false.
Этот фрагмент отказа теперь демонстрирует симметрию между первым и третьим аргументом: они оба влияют на незавершение точно таким же образом! Таким образом, хотя они описывают совершенно разные вещи — одно слагаемое, другое сумму, — они оказывают совершенно одинаковое влияние на окончание. И бедный второй аргумент не имеет никакого значения.
Чтобы быть уверенным, срез сбоя не только идентичен своему общему условию завершения (используйте cTI), который читается
nat_nat_sum(A,B,C)terminates_if b(A);b(C).
Он также заканчивается точно так же для тех случаев, которые не подпадают под это условие, например
?- nat_nat_sum(f(X),Y,Z).
Теперь мой вопрос:
Есть ли альтернативное определение
nat_nat_sum/3
, которое имеет условие завершения:nat_nat_sum2(A,B,C) terminates_if b(A);b(B);b(C).
(Если да, покажите это. Если нет, объясните, почему)
Другими словами, новое определение nat_nat_sum2/3
должно заканчиваться, если уже один из его аргументов является конечным и обоснованным.
Мелкий шрифт. Рассматривайте только чистые, монотонные программы на Прологе. То есть никаких встроенных модулей, кроме (=)/2
и dif/2
(Я назначу награду в размере 200 за это)