Программирование на языке Пролог | страница 67



Теперь мы рассмотрим несколько примеров использования отсечения в перечисленных выше ситуациях. Однако необходимо помнить, что во всех этих случаях отсечение имеет один и тот же смысл. Выделение трех случаев использования отсечения обусловлено чисто методическими соображениями, чтобы показать, по каким причинам в программах могут использоваться отсечения.

4.3.1. Подтверждение правильности выбора правила

При программировании на Прологе очень часто возникает желание использовать для описания одного предиката несколько утверждений. Одно утверждение будет использоваться, если аргументы имеют один вид, другое будет использоваться для аргументов иного вида и так далее. Часто мы можем указать, какое правило следует использовать для данного целевого утверждения, указав в качестве аргументов в заголовке правила необходимые образцы структур так, чтобы это правило могло быть сопоставлено лишь с соответствующими целевыми утверждениями. Однако это не всегда возможно. Если мы не можем сказать заранее, какого вида аргументы будут использоваться, или если мы не можем перечислить все множество возможных образцов аргументов, то мы можем принять компромиссное решение. Это значит, что задаются правила для аргументов определенных типов, а в конце задается правило-«ловушка» для всех остальных правил. В качестве примера такого способа рассмотрим следующую программу. Определим предикат сумма таким образом, что при выборе в качестве целевого утверждения сумма(N, X), где N – некоторое целое число, переменной X присваивается значение, равное сумме всех целых чисел от 1 до N. Так, например, возможен следующий диалог:

?- сумма(5,X).

X = 15;

нет

Полученный ответ объясняется тем, что 1+2+3+4+5 равно 15. Здесь приведена соответствующая программа.


сумма(1,1):-!.

сумма(N,Результат):- N1 is N-1, сумма(N1,Результат),Результат is Результат+N.


Приведенное определение является рекурсивным. Идея состоит в том, что выход на граничное условие происходит в случае, когда первый аргумент равен 1. В этом случае ответ тоже равен 1. Второе утверждение вводит рекурсивное целевое утверждение сумма. Однако первый аргумент нового целевого утверждения на единицу меньше, чем первый аргумент в исходном целевом утверждении. Следующее целевое утверждение, которое будет порождено этим целевым утверждением, снова будет иметь первый аргумент на единицу меньше. И так далее до тех пор, пока не будет достигнуто граничное условие. Так как первый аргумент всегда на единицу меньше, то в конце концов произойдет выход на граничное условие (в предположении, что исходное целевое утверждение имеет первый аргумент не меньше 1) и выполнение программы закончится.