- •1.1.1 Процедурная вычислительная модель
- •1.1.2 Функциональная вычислительная модель
- •1.1.4. Объектно-ориентированная вычислительная модель (ооп)
- •1.2.Метод оценки (способ получения результатов)
- •5.1.Метод отката после неудачи – опн
- •Листинг 5.9. Бесконечная рекурсия (хвостовая рекурсия)
- •Влияние предиката cut на составную цель
- •Goal: a(X), b(y), !, c(X,y,z).
- •Определение
- •Список помогает сделать программу компактной, эффектив-
- •Список – это рекурсивный составной объект, поэтому
Листинг 5.9. Бесконечная рекурсия (хвостовая рекурсия)
predicates
count(real)
clauses
count(N):-
write(N),nl,
NewN=N+1,
count(NewN).
Эта процедура count(N) –является хвостовой рекурсией, которая вызывает себя без резервирования нового стекового фрейма, и потому не истощает запас памяти, в конечном итоге произойдет целочисленное переполнение, но остановки из-за нехватки памяти не будет.
Введение условия, ограничивающего бесконечную рекурсию:
Листинг 5.10.Ограничение бесконечной рекурсии
predicates
count(integer)
check(integerl)
clauses
count(N):-
write(N),nl,
NewN=N+1,
сheck(NewN),
count(NewN).
check(Z):-Z<5.
goal
clearwindow,
write(“result:”),nl,
count(1).
Замечание:
В Прологе мы не можем изменить значение переменной, поэтому создаем новую переменную NewN.
Отрицание как недостижение цели. Предикат not. Предположения о замкнутости и открытости мира.
Влияние предиката cut на составную цель и процедуру. Подтвердить конкретными примерами
Влияние предиката cut на составную цель
Пусть cut является одной из подцелей составной цели.
После того как компилятор пройдет предикат cut, он больше не сможет вернуться назад к подцелям, стоящим перед этим предикатом. И все значения переменных, расположенных слева от предиката cut, которые они получили в процессе унификации будут заморожены.
Пример:
Goal: a(X), b(y), !, c(X,y,z).
При выполнении этой цели компилятор пройдет через предикат cut только в том случае, если и подцель a(X), и подцель b(Y) окажутся уже успешными.
После того как предикат cut окажется обработан, компилятор не сможет вернуться назад для повторного рассмотрения подцелей “a” и “b”, если подцель”c” потерпит неудачу при текущем значении переменных X и Y.
Эта составная цель не обладает декларативным смыслом. Но с процедурной точки зрения ее можно прочесть так:
взять значение переменной X из подцели “a” и значение переменной Y из подцели “b” а затем выполнить подцель c(X,Y,Z).
5.2.2.Влияние предиката cut на процедуру
Пусть компилятор возвращается назад через множество предложений, образующих процедуру. В теле одного из предложений находится предикат cut. Если компилятор дойдет до cut, то он не сможет вернуться назад для рассмотрения остальных предложений данного множества.
Листинг 5.2. Программа, в которой нет предиката cut
predicates
a(symbol)
d(symbol)
clauses
a(“1”):-
write(“один”).
a(X):-
d(X),
write(“два”).
a(“3”):-
write(“три”).
d(“2a”).
d(“2b”).
Возьмем цель goal: a(N).
В соответствии с представленной схемой получаем все четыре решения:
1) один, N=1;
2) два, N=2a;
3) два, N=2b;
4) три,N=3.
Изменим программу, вставим предикат cut между двумя подцелями правила a(X) и проанализируем, что произойдет в результате выполнения программы, которая будет запущена той же самой целью goal:a{N).
Листинг 5.3.Программа с предикатом cut
predicates
a(symbol)
d(symbol)
clauses
a(“1”):-
write(“один”).
a(X):-
d(X),
!,
write(“два”).
a(“3”):-
write(“три”).
d(“2a”).
d(“2b”).
В результате получим только два ответа:
1) один, N=1;
2) два, N=2.
3) система ‘заморозила’ все альтернативы, стоящие до cut,и лишила тем самым возможности вернуться к подцели d(X),чтобы воспользоваться веткой d(“2b”).
4) отбросила все утверждения процедуры a , стоящие после утверждения с предикатом cut.(то есть перейти к утверждению a(“3”) –невозможно)
Использование предиката cut позволило отбросить части пространства поиска.
Рассмотрим еще один пример.
Составные объекты и альтернативные домены. Предикатная и доменная структурные диаграммы.
Компоновка данных в список