
- •1.Введение в функциональное и логическое программирование
- •1.1. Основные классы вычислительных моделей
- •1.1.1 Процедурная вычислительная модель
- •1.1.2 Функциональная вычислительная модель
- •1.1.3. Логическая вычислительная модель
- •1.1.4. Объектно-ориентированная вычислительная модель (ооп)
- •1.2.Метод оценки (способ получения результатов)
- •1.3. Обмен информацией в процессе оценки
- •1.4.Понятие искусственного интеллекта
- •1.5.Символьные языки программирования
- •1.6. Основные направления в искусственном интеллекте
- •Для работы в сфере ии надо иметь:
- •1) Языки ии, обеспечивающие простоту модификации
- •3) Важна и структура самой машины, позволяющая с
- •2.Основы логического программирования и язык Пролог.
- •2.1.Основные понятия
- •2.2.Определение отношений на основе фактов и правил
- •2.3 Пример программы на языке Пролог
- •2.4.Использование рекурсии
- •2.5.Декларативная и процедурная трактовка программы
- •2.6. Cтруктура программы
- •2.7.Особенности лп:
- •2.8 Использование предиката not и
- •3.Синтаксис Пролога
- •3.1. Объекты данных
- •3.2. Составные объекты и альтернативные домены. В утверждениях объекты представляют собой данные.
- •3.2.1. Составная структура
- •Листинг3.1. Использование доменной структуры с именем personal_library
- •3.2.2.Доменная структурная диаграмма программы “Библиотека” (дсд)
- •3.2.3.Предикатная структурная диаграмма программы “Библиотека” (псд)
- •3.2.4. Альтернативные домены
- •Выводы:
- •Рассмотрение работы с составными объектами и альтернативными доменами закончено. Посмотрим, как именно строится логический вывод, реализованный на эвм?
- •3.3. Сопоставление структур(matching)
- •3.4.Унификация и подстановки (Unify).
- •3.5.Основные правила поиска с возвратом:
- •Листинг 3.4.Унификация и поиск с возвратом
- •4.Принцип резолюции
- •Метод резолюции в исчислении предикатов – это пра-
- •4.1.Логическое следствие
- •4.2. Логический вывод
- •4.3 Преимущества и недостатки метода резолюции
- •4.4. Пример применения метода резолюций.
- •5. Управление поиском решений
- •5.1.Метод отката после неудачи – опн
- •5.2 Метод отсечения и отката – оо
- •5.2.1.Влияние предиката cut на составную цель
- •5.2.3. Использование зеленых и красных отсечений
- •5.2.4.Использование предиката not как средства управления
- •5.3.Метод повтора, определяемый пользователем (мп)
- •5.4.Методы организации рекурсии
- •Листинг 5.9. Бесконечная рекурсия (хвостовая рекурсия)
- •Пример программы, которая циклически считывает символ, введенный пользователем. Если символ не равен #, то он выводится на экран, иначе процесс заканчивается.
- •Листинг 5.14. Пример рекурсии для генерации ряда чисел в порядке возрастания
- •Определение
- •Список помогает сделать программу компактной, эффектив-
- •Список – это рекурсивный составной объект, поэтому
- •6.1.Операции над структурами данных типа список.
- •6.2.Предикат findall
- •6.3. Операции со структурами данных.
Листинг 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.
Добавим еще одно предложение после рекурсивного вызова
Листинг 5.11.Пример не хвостовой рекурсии из-за того, что вызов процедуры – не последний шаг
predicates
count(integer)
check(integerl)
clauses
count(N):-
write(N),
NewN=N+1,
сheck(NewN),
count(NewN),
nl.
check(Z):-
Z<5.
Из-за наличия nl вызов процедуры count() перестал быть последним шагом, стек придется сохранить, чтобы обработку можно было вернуть к вызывающей процедуре.
Еще один случай не хвостовой рекурсии:
Листинг 5.12.Пример не хвостовой рекурсии за счет использования недетерминированного предиката
check_determ
predicates
count(integer)
check(integer)
clauses
count(N):-
write(N),nl,
NewN=N+1,
сheck(NewN),
count(NewN).
count(N).
check(Z):-Z<5.
Добавили второй count(N). Получили недетерминированный предикат. Этот предикат еще не проверен к моменту выполнения рекурсивного вызова, поэтому стек должен быть сохранен, так как в случае неуспеха рекурсивного вызова процедура может откатиться и начать проверку этой альтернативы.
Замечания:
- Если проверку chеck(NewN) не поставить, то предыдущие программы будут работать до истощения памяти.
- Непроверенные альтернативы не обязательно должны быть отдельными предложениями рекурсивной процедуры. Они могут находиться в любом вызываемом предикате. Например,
. . . . . .
check(NewN),
. . . . . . . .
check(Z):-Z>=0.
check(Z):-Z<0.
Eсли Z>0,то первое check(Z) достигло цели, а второе в этот момент еще не проверено, поэтому предикат count() должен сохранить свои стековые копии, чтобы иметь возможность вернуться и начать проверку второго предложения, если рекурсивный вызов будет неудачен.
Для поиска недетерминированных предложений используйте директиву check_determ.
Для удаления альтернативных вызовов используйте cut, достигнув которого можно больше не обращать внимание на альтернативные предложения, а раз так, то и стек хранить не надо, и рекурсивный вызов может свободно идти дальше. Если отсечение выполнено, то компьютер считает, что непроверенных альтернатив больше нет, и не создает стекового фрейма.
Пример программы, которая циклически считывает символ, введенный пользователем. Если символ не равен #, то он выводится на экран, иначе процесс заканчивается.
Листинг 5.13. Использование рекурсии для циклического считывания символов
domains
char_data=char
predicates
write_prompt
read_a_character
goal
clearwindow,
write_prompt,
read_a_character.
clauses
write_prompt:-
write(“введи символ”),nl,
write(“окончание по #”),nl,nl.
read_a_character:-
readchar(Char_data),
Char_data<>’#’,
write(Char_data),
read_a_character.