Скачиваний:
201
Добавлен:
17.06.2016
Размер:
2.69 Mб
Скачать

Определение 2

singlepeak([]).

singlepeak([U]).

singlepeak([U,V|Y]):-U<V,singlepeak([V|Y]).

singlepeak([U,V|Y]):-U>V,down([V|Y]).

down([]).

down([U]).

down([U,V|Y]):-U>V,down([V,Y]).

В определении 3 предикат singlepeak еще больше сокращается за счет

применения правила 1. Таким образом, используя определение 3

singlepeak(Y,up)

выполняется успешно, если Y содержит список, добавляемый к списку целых

чисел, расположенных в порядке возрастания значений, а

singlepeak(Y,down)

выполняется успешно, если Y содержит список целых чисел, расположенных в

порядке убывания.

Определение 3.

singlepeak([],_).

singlepeak([_],_).

singlepeak([U,V|W],up):-

U<V,singlepeak([V|W],up).

singlepeak([U,V|W]):-

U>V,singlepeak([V|W],down).

-----------------------------------------------------------------

Правило 4. Доверяйте больше работы механизму унификации в Турбо

Прологе.

-----------------------------------------------------------------

На первый взгляд, описание предиката equal для проверки равенства

двух списков должно выглядеть следующим образом

equal([],[]).

equal([U|X],[U|Y]):-equal(X,Y).

но в этом нет необходимости. Используйте определение

equal(X,X).

а механизм унификации сделает все остальное !

-----------------------------------------------------------------

Правило 5. Для повторяющихся операций используйте поиск с

возвратом, а не рекурсию.

-----------------------------------------------------------------

Поиск с возвратом позволяет уменьшить размер стека. Задача заключа-

ется в использовании комбинации repeat...fail вместо рекурсии. Этот метод

является настолько важным, что ему посвящается следующий раздел данной

главы.

Использование предиката fail

Для того, чтобы повторно оценивать некоторую последовательность под-

целей, зачастую бывает необходимо вводить предикат, подобный приведенному

ниже предикату run с предложениями следующего вида

run:-readln(X),

process(X,Y),

write(Y),

run.

вызывая тем самым ненужные дополнительные затраты, связанные с использо-

ванием хвостовой рекурсии, которая не может быть устранена системой, пос-

кольку предикат process(X,Y) вызывает поиск с возвратом.

В этом случае применение комбинации repeat...fail позволяет избежать

хвостовой рекурсии.

Введя предикат

repeat.

repeat:-repeat.

мы можем переопределить предикат run без помощи хвостовой рекурсии следу-

ющим образом:

run:-readln(X),

process(X,Y),

write(Y),

fail.

Предикат fail вызывает поиск с возвратом к предикату process и, в

конечном счете, к повторному выполнению предиката repeat, которое всегда

завершается успешно.

Детерминизм и отсечение

Директивы компилятора check_determ является весьма полезной в тех

случаях, когда необходимо определить места для использования отсечения,

поскольку эта директива позволяет отметить те предложения, которые порож-

дают недетерминированные предикаты. Если вы хотите сделать эти предикаты

детерминированными, то вам необходимо ввести в них отсечение, предотвра-

щающее поиск с возвратом (что и порождает недетерминизм). Общим правилом

в таких случаях является введение отсечения со смещением влево настолько,

насколько это возможно без ущерба для логики работы программы.

Всегда помните следующие два правила, согласно которым компилятор

выявляет недетерминированные предложения:

1. Если в предложении нет отсечения и присутствует еще одно пред-

ложение с такими же аргументами в головной части предложения.

2. В теле предложения стоит обращение к недетерминированному пре-

дикату и после этого обращения отсутствует отсечение.

Второе правило может выполняться в следующих случаях:

- при обращении к недетерминированному предикату, объявленному

программистом

- при обращении к предикату динамической базы данных, перед кото-

рым отсутствует директива determ

- при обращении к одному из следующих специализированных стандар-

тных предикатов db_btrees, db_chains, chain_terms или retract,

когда перед предикатом динамической базы данных отсутствует ди-

ректива determ

383

Соседние файлы в папке Документация