- •Лабораторная работа № 1. Малая экспертная система.
- •Теоретические сведения
- •Диагностические экспертные системы.
- •Пример применения байесовской стратегии оценки выводов
- •Контрольные задания:
- •Контрольные вопросы:
- •Лабораторная работа № 2. Знакомство с инструментальными средствами для создания экспертных систем.
- •Теоретические сведения
- •Контрольное задание:
- •Контрольное задание:
- •Контрольные вопросы:
- •Лабораторная работа № 4.
- •Теоретические сведения
- •Контрольное задание:
- •Основные стандартные домены
- •Основные стандартные предикаты:
- •Ключевые слова
- •Контрольные задания:
- •Контрольные вопросы:
- •Лабораторная работа №7. Предложения (факты и правила), цели на языке пролог.
- •Теоретические сведения Clauses (условия): Facts (факты) и Rules (правила)
- •О фактах
- •Контрольные вопросы:
- •Лабораторная работа №8. Переменные на языке программирования пролог.
- •Теоретические сведения
- •Анонимные переменные
- •Контрольное задание:
- •Принципы отката:
- •Контрольные задания:
- •Преимущества рекурсии
- •Оптимизация обратной рекурсии
- •Контрольные задания:
- •Объявление списков
- •Головы и хвосты
- •Обработка списков
- •Использование списков
- •Контрольное задание:
- •Контрольные вопросы:
- •Лабораторная работа №13. Секция фактов Лабораторная работа № 1.
- •Теоретические сведения
- •Объявление секций фактов
- •Модификация секции фактов
- •Добавление фактов в период исполнения программы
- •Загрузка фактов из файла в период исполнения программы
- •Удаление фактов в период исполнения программы
- •Удаление нескольких фактов сразу
- •Ключевые слова для объявления фактов
- •Описания Факты, объявленные с ключевым словом nondeterm
- •Факты, объявленные с ключевым словом determ
- •Факты, объявленные с ключевым словом single
- •Сохранение базы данных фактов во время выполнения программы
- •Контрольные задания:
- •Контрольные вопросы:
Контрольные вопросы:
Сформулируйте понятие искусственной нейронной сети.
Опишите структуру искусственной нейронной сети.
Охарактеризуйте классификацию искусственных нейронных сетей.
Перечислите виды и охарактеризуйте искусственных нейронных сетей.
Каково назначение функции адаптации?
Какие виды адаптивных функций вы знаете?
В чем причина возникновения паралича искусственной нейронной сети?
Лабораторная работа № 4.
РАЗРАБОТКА ЭКСПЕРТНОЙ СИСТЕМЫ НА ЯЗЫКЕ ПРОЛОГ.
Цель работы: изучение развитых типов данных в программах на Прологе, необходимых для программной реализации экспертных систем, а также возможностей построения и обработки баз данных на Прологе.
Используемое программное обеспечение: PROLOG.EXE.
Теоретические сведения
Пролог – язык, предназначенный для программирования приложений, использующие системы и методы систем искусственного интеллекта.
Программа на прологе представляет собой совокупность утверждений, состоящих из целей и хранящихся в базе знаний.
В конце утверждения ставится точка.
Существует 2 типа утверждений:
Факт - безусловная истина;
Правило состоит из одной главной цели и одной или более хвостатых целей, которые истины при некоторых условиях в виде конъюнкции.
Символ :- в правиле означает если …, то … (при условии …, что…).
Логические операции на Прологе
Логические операции |
Обозначение |
конъюнкция (И) |
, |
дизъюнкция (ИЛИ) |
; |
отрицание |
not() |
Цели бывают простые и составные.
Составная цель состоит из нескольких подцелей, соединенных либо конъюнкцией, либо разделенных дизъюнкцией.
Если подцели конъюнктивные, то для выполнения главной цели должны быть выполнены все хвостовые цели. Если дизъюнктивные, то - хотя бы одна из хвостовых.
Пролог–программа - совокупность фактов и правил, позволяющих делать какие-либо заключения на основе этих фактов.
Программирующий на Прологе определяет «объекты» и «отношения», а затем и «правила», в которых указывается, когда эти отношения являются истинными.
Предикат - это свойство объекта или отношение между объектами.
Аргументы предиката - объекты, которые связывают предикат.
Правила позволяют выводить из фактов некоторый другой факт.
Правило - заключение, о котором известно, что оно истинно, если одно или несколько других заключений или фактов истинны.
Пример правила:
Если нам известно, что бабушка человека - это мама его мамы или мама его папы. Соответствующее правило будет иметь вид:
бабушка (Х,У):- мать(X,Z), мать (Z,Y); % мама его мамы
бабушка (Х,У):- мать(X,Z), отец (Z,Y). % мама его папы
Есть предложение: «Лене нравится собаки, если они привлекательные».
Объекты: лена и собаки.
Отношение: нравится.
Свойство: привлекательные.
Факты:
нравится(лена, собаки).
привлекательные(собаки).
В факте «нравится(лена, собаки)» отношение «нравится» - имя предиката, а объекты «лена» и собаки» - его аргументы.
Правило: нравится(лена, собаки):- привлекательные(собаки).
Переменные прописываются с прописной буквы, а константы – со строчной.
Имя переменной содержит буквы латинского алфавита, цифры, нижнее подчеркивание.
Пример:
Факт: нравится(лена, собаки).
Запрос: нравится(лена, X).
Ответ: собаки
В прологе нет оператора присваивания. Значения переменные получают в результате установления их соответствия с константами в фактах и правилах.
Виды переменных:
Анонимные переменные используются для игнорирования ненужных значений. Обозначаются (_). Как правило используются для поиска.
Пример:
родитель(николай, егор). % факт
родитель(Родитель,_). % запрос
Родитель = николай. % ответ на запрос.
Свободные переменные не имеют какого-либо значения.
Связанные переменные – когда у свободных переменных появляется значения.
Свободные переменные остаются связанными лишь то время, которое необходимо для поиска ответа на запрос; затем Пролог освобождает их, возвращается назад и ищет альтернативные решения.
Основные разделы программы на языке Пролог:
domains - в нем описываются любые используемые домены (типы аргументов пользователя);
predicates - раздел объявления пользовательских предикатов (предикаты, объявленные словом nondeterm - недетерминированные предикаты - объявляются, если задача предполагает возможность получения нескольких решений);
clauses - раздел предложений, в котором описываются факты и правила;
goal – в нем определяются цели и запросы.
Цель может задаваться в программе и являться внутренней, либо задаваться в диалоговом окне и соответственно являться внешней.
Дополнительные разделы:
database - предусмотрен для объявления в программе фактов, которые должны стать частью динамической базы данных.
В Прологе имеется несколько встроенных предикатов, существенно облегчающих использование динамической базы данных (consult - загрузка, save - сохранение, assert или assertz - добавление фактов в конец, asserta - в начало базы данных, retract - удаление одной записи, retractall - всех записей).
constants - раздел объявления констант (например, π, e).
global - используется для объявления, например, глобальных доменов, фактов (global domains, global facts, global database).
Встроенные предикаты:
nl - обеспечивает переход на новую строку
предикат отсечения (обозначается «!») используется для ограничения пространства поиска, с целью повышения эффективности работы программы.
Способы организации циклов на Прологе:
С использованием встроенного предиката fail (неудача).
С помощью рекурсии.
С использованием пользовательского предиката repeat.
repeat. % факт.
repeat:- repeat. % правило.
Для того чтобы запустить Turbo Prolog необходимо, открыть файл Prolog.exe.
Перед вами появится рабочее окно (рис. 1):
Рис. 1. Окно Turbo Prolog.
В этом окне имеется главное меню, включающее в себя следующие составляющие (рис. 2):
Рис. 2. Главное меню окна Turbo Prolog.
Рассмотрим каждую из них в отдельности.
Files (рис. 3):
Рис. 3. Меню Files.
Load - загрузка файла;
Pick - выбор из последних загруженных файлов;
New file - создание нового файла;
Save - сохранение файла;
Write to - запись под новым именем;
Directory - выбор текущей директории;
Change dir - изменение директории;
OS shell - переход программы на dos-оболочку;
Quit - выход.
При выборе Edit происходит переход в Editor где можно редактировать файл (рис. 4).
Рис. 4. Меню Edit.
При выборе меню Run появляется возможность вести диалог с проектом.
При выборе меню Compile (рис. 5)
Рис. 5. Меню Compile.
появляются следующие подменю:
Memory - программа компилируется в оперативную память;
OBJ file - программа компилируется в OBJ-файл;
EXE file <auto link> - программа компилируется в EXE-file;
Project <all modules> - компилируются все модули программы;
Link only - компилируется только в ссылку.
Меню Options представляет собой (рис. 6):
Рис. 6. Меню Options.
Link options - опции ссылки;
Edit PRJ file - редактирование PRJ-file;
Compiler Directives - настройка компиляции.
Меню Setup содержит (рис. 7)
Рис. 7. Меню Setup.
Colors - установка цвета;
Window size - установка размера окна;
Directories - установка директории;
Miscellaneous - настройка отображения информации;
Load SYS file - загрузка системного файла;
Save SYS file - сохранение системного файла.
Функторы и альтернативные домены
Функторы представляют собой составные объекты программы на Прологе. Они позволяют структурировать данные для удобства их представления и обработки. Функторы объявляются в разделе domains следующим образом:
domains
имя_функтора=тип (типы аргументов)
Одна из наиболее важных задач, для которых применяются функции в программах на Прологе - объявление аргументов предикатов, которые в разных случаях могут принимать значения разных типов. В этом случае необходимо объявить набор функторов, называемых альтернативным доменом:
domains
альтернативный_домен = функтор_1 (типы аргументов);
функтор_2 (типы аргументов);
…
функтор_n (типы аргументов).
Если затем указать «альтернативный домен» в качестве типа аргумента при объявлении предиката (в разделе predicates), то в качестве аргумента предиката можно будет указывать любой из функторов «функтор_1», ..., «функтор_n».
Пример:
Имеется информация о проектах и о сотрудниках, работающих над ними. Предположим, что стоимость контрактов на разработку всех проектов указывается в тысячах долларов, но по некоторым проектам оплата производится в рублях по курсу на определенную дату. Для проектов, оплачиваемых в рублях, требуется указывать не только стоимость контракта (в долларах), но и дату для определения курса. Для проектов, оплачиваемых в долларах, указывать дату не требуется.
Предположим, что оплата по проектам П70 и П100 производится в долларах, а по проектам П20 и П120 - в рублях. Тогда факты базы данных, описывающие проекты, могут иметь следующий вид (рис. 8):
clauses
proekt ("P20", "Rubin", rub(700, “10.09.2011”)).
proekt ("P100", "Vektor ", doll(1400)).
proekt ("P70", "Gorizont", doll(500)).
proekt ("P120", "Kristall", rub(1100, “12.10.2011”)).
Рис. 8. Факты базы данных, описывающие проекты.
Здесь rub и doll - функторы. Конечно, можно использовать и любые другие имена. Альтернативный домен, включающий функторы rub и doll, должен быть объявлен следующим образом (рис. 9):
domains
oplata=rub (integer, string);
doll (integer)
Рис. 9. Альтернативный домен, включающий функторы rub и doll.
Здесь oplata - имя альтернативного домена (можно использовать и любое другое имя).
Предикат proekt, в котором используется альтернативный домен oplata, должен быть объявлен в разделе predicates следующим образом (рис. 10):
predicates
nondeterm proekt (string, string, oplata)
Рис. 10. Объявление предиката proekt.
Такое объявление означает, что третьим аргументом предиката proekt может быть любой функтор, входящий в альтернативный домен oplata, т.е. rub или doll.
Примечание. При работе с функторами важно не путать их с предикатами. Функтор - не предикат, а элемент данных; он является аргументом предиката. Объединение нескольких элементов данных с помощью функтора никогда не означает какой-либо операции над ними. Стандартных функторов, а также зарезервированных слов, связанных с функторами, в Прологе нет.
Ввод функтора может выполняться стандартным предикатом readterm (тип, имя_переменной). Здесь «тип» - альтернативный домен, указанный в разделе domains (для рассмотренного примера - oplata). «Имя_переменной» - переменная, с которой связывается функтор. Функтор вводится в точном соответствии с его объявлением: указывается имя функтора (в рассмотренном примере - rub или doll) и его аргументы.
Пример:
Программа для поиска всех проектов, оплачиваемых в рублях (с указанием заказчика и стоимости контракта) (рис. 11).
domains
oplata=rub (integer, string);
doll (integer)
predicates
nondeterm proekt (string, string, oplata)
nondeterm poisk
goal
poisk.
clauses
proekt ("P20", "Rubin", rub(700, “10.09.2011”)).
proekt ("P100", "Rubin", doll(1400)).
proekt ("P70", "Горизонт", doll(500)).
proekt ("P120", "Kristall", rub(1100, “12.10.2011”)).
poisk:- proekt (N, Naz, rub (Opl,_)),
write (N, " ", Naz, " ", Opl), nl, fail. poisk. % объявление переменных.
Рис. 11. Программа для поиска всех проектов, оплачиваемых в рублях.
При доказательстве целевого предиката poisk сопоставление предиката proekt (N, Naz, rub (Opl,_)) с фактами proekt выполняется успешно только в том случае, если третьим аргументом факта proekt является функтор rub. Для вывода всех желаемых проектов используется механизм искусственного возврата (fail).
Базы данных в программах на Прологе
В программах на Прологе имеется возможность хранить предикаты-факты, обрабатываемые программой, отдельно от самой программы. Файл, содержащий предикаты-факты, называется базой данных.
Факты, хранящиеся в файле базы данных, объявляются в разделе global facts (или global database). Нестандартные типы данных, используемые в базе данных, должны быть объявлены в разделе global domains.
В одной базе данных могут храниться факты, имеющие разные имена, разное количество аргументов и т.д. Все они должны быть объявлены в разделе global facts.
Пример:
Чтобы хранить в файле базы данных информацию о проектах и о сотрудниках, работающих над ними, потребуется следующее объявление (рис. 12):
global domains
oplata=rub (integer, string);
doll(integer)
spisok=string*
global facts
rabota (string, spisok)
proekt (string, string, oplata)
Рис. 12. Объявление глобальных доменов и фактов.
Информация базы данных может храниться в текстовом файле с расширением *.dba. В каждой строке базы данных может содержаться только один факт. В базе данных не должно быть пустых строк, в том числе в конце базы данных (после последнего факта). Факты в базе данных должны быть набраны без пробелов. Точка в конце фактов не ставится.
Загрузка базы данных
Загрузка базы данных во время работы программы выполняется стандартным предикатом consult(имя_файла). Имя файла базы данных может задаваться константой (в этом случае оно должно быть заключено в кавычки) или переменной. Если используется переменная, то ей должно быть присвоено имя файла базы данных. Для указания имени файла в этом случае может использоваться предикат readln или операция присваивания.
Если имя файла базы данных указывается в тексте программы (например, задается в предикате consult или присваивается переменной), то в нем необходимо использовать две наклонные черты (\\). Если имя файла вводится с клавиатуры с помощью оператора readln, то используется одна наклонная черта (\).
Пусть, например, база данных, содержащая информацию о проектах и о сотрудниках, работающих над этими проектами, хранится в файле PROEKT.DBA на диске D: в папке ES. Тогда для загрузки базы данных можно использовать следующий предикат: consult(“d:\\es\\proekt.dba”).
Перед предикатом consult рекомендуется указывать стандартный предикат retractall(_), удаляющий из памяти все факты базы данных (например, если они сохранились от предыдущего запуска программы).
Пример:
Предикат, запрашивающий имя базы данных и выполняющий ее загрузку (рис. 13).
loading:- write(“Vvedite nazvanie”), readln(F),
retractall(_), consult(F), !.
loading.
Рис. 13. Загрузка базы данных.
По запросу “Введите имя базы данных” может быть введено, например, следующее имя: d:\es\proekt.dba.
Второй клоз предиката loading, не выполняющий никаких действий, предусмотрен на случай, если пользователь откажется от загрузки, нажав клавишу ESC. В этом случае стандартный предикат readln завершается неудачей. Происходит возврат ко второму клозу предиката loading, и он доказывается успешно.
Просмотр базы данных
Прежде чем выполнять какие-либо действия в базе данных, необходимо загрузить ее в память компьютера, используя стандартный предикат consult. После этого предикаты-факты, загруженные из файла базы данных, могут использоваться в программе точно так же, как и факты, указанные в самой программе.
Пример:
Предикаты для просмотра перечня всех сотрудников, работающих над проектами (рис. 14):
prosmotr_sotr:- rabota (F, S),
write (“Фамилия: ”, F," Проекты: ",S), nl, readchar(_), fail. prosmotr_sotr.
Рис. 14. Просмотр базы данных.
Работа этого предиката ничем не отличается от работы аналогичных предикатов.
Изменение базы данных
В ходе работы программы можно создавать новые факты базы данных или, наоборот, удалять имеющиеся. Поэтому базы данных в программах на Прологе называются динамическими.
Для создания новых фактов используются предикаты asserta (добавление факта в начало базы данных), assertz (добавление факта в конец базы данных), assert (действует так же, как assertz).
Пример:
Предикат для добавления информации о новом сотруднике (рис. 15). Вводится фамилия сотрудника и список проектов, над которыми он работает.
dobav_sotr:- write ("Фамилия: "), readln (Fam),
write ("Проекты: "), readterm (spisok, Spis_pr), assert (rabota (Fam, Spis_pr)).
Рис. 15. Добавление информации о новом сотруднике.
Предикат assert создает в памяти новый факт rabota. Например, если введена фамилия Сергеев и список проектов [“П100”,”П120”], то будет создан следующий факт: rabota(“Сергеев”, [“П100”,“П120”]).
Аналогично можно реализовать предикат для добавления информации о проекте (рис. 16):
dobav_pr:- write ("Шифр: "), readln (Shifr), write ("Заказчик: "), readln (Zak), write ("Оплата: "), readterm(oplata, Opl), assert (proekt(Shifr, Zak, Opl)).
Рис. 16. Добавление информации о проекте.
Следует напомнить, что в рассматриваемом примере третий аргумент предиката proekt (оплата) задается с помощью функтора. Например, если для некоторого проекта требуется указать, что его стоимость составляет 800 тыс. долларов и оплачивается в долларах, то по запросу “Оплата: ” необходимо ввести: doll(800). Если проект стоимостью 800 тыс. долларов оплачивается в рублях по курсу на 5 сентября 2002 года, то следует ввести: rub(800, “5.09.2002”).
Для удаления фактов базы данных используются стандартные предикаты retract и retractall.
Пример:
Предикат для удаления информации о сотруднике (рис. 17).
udal_sotr:- write ("Фамилия: "), readln (Fam), retractall (rabota (Fam,_)).
Рис. 17. Удаление информации о сотруднике.
Предикат retractall удаляет все факты, соответствующие указанным данным. В данном примере удаляются все факты rabota, где первым аргументом является указанная фамилия. Если таких фактов нет (например, фамилия введена неверно), то никаких изменений в базе данных не происходит, однако предикат rertractall считается доказанным успешно.
Предикат retractall(_) удаляет из памяти все факты базы данных. Его рекомендуется указывать перед загрузкой базы данных, чтобы удалить из памяти факты, которые могли сохраниться от предыдущего запуска программы.
Предикат retract удаляет из памяти только первый факт, соответствующий указанным данным. Если таких фактов нет, то никаких изменений в базе данных не происходит; однако доказательство предиката rertractall считается неудачным, и происходит возврат. Поэтому чаще применяется предикат retractall.
Примечание. Важно обратить внимание, что все рассмотренные возможности изменения базы данных относятся только к фактам, загруженным в память компьютера, но не к содержимому файла базы данных. Например, если удалить какие-либо факты с помощью предикатов retract или retractall, то они удаляются только из памяти, но не из файла, хранящегося на диске. Чтобы изменить содержимое файла базы данных, необходимо сначала внести необходимые изменения в памяти, а затем сохранить базу данных.
Сохранение базы данных
Для сохранения содержимого базы данных в файле используется стандартный предикат save(имя_файла). Например, чтобы сохранить базу данных в файле PROEKT.DBA на диске D: в папке ES, можно использовать предикат: save(“d:\\es\\proekt.dba”). Можно также запрашивать имя базы данных, как показано в следующем примере.
Пример:
Предикат, запрашивающий имя файла и выполняющий сохранение базы данных в указанном файле (рис. 18).
sohran:- write(“Введите имя базы данных для сохранения: ”), readln(F), save(F), !. sohran.
Рис. 18. Сохранение базы данных в указанном файле.
При вводе путевого имени файла необходимо использовать одиночные наклонные черты (\).
Второй клоз предиката sohran обеспечивает его успешное доказательство в случае, если пользователь откажется от сохранения, нажав клавишу ESC.
Дополнительные возможности применения баз данных
Динамические базы данных широко применяются в Прологе для самых разнообразных операций по обработке данных. Предикаты assert и retract (или retractall) позволяют организовать временное хранение и изменение данных.
Пример:
Предикат, вычисляющий суммарную стоимость проектов, оплачиваемых в рублях и в долларах (рис. 19).
summa:- retractall (sumdoll(_)), assert (sumdoll (0)),
proekt (_, _, doll(S)), sumdoll (Sd), Sd1=Sd+S,
retractall(sumdoll(_)), assert(sumdoll(Sd1)), fail.
summa:- retractall (sumrub(_)), assert (sumrub (0)),
proekt (_, _, rub(S,_)), sumrub (Sr), Sr1=Sr+S,
retractall (sumrub(_)), assert (sumrub(Sr1)), fail.
summa:- sumdoll (Sd), write ("Оплата в долларах: ", Sd), nl,
sumrub (Sr), write ("Оплата в рублях: ", Sr), readchar(_).
Рис. 19. Вычисление суммарной стоимости проектов, оплачиваемых в рублях и в долларах.
При вызове этого предиката сначала происходит обращение к первому клозу. Стандартный предикат retractall (sumdoll(_)) удаляет из памяти факт базы данных sumdoll, если он там есть. Стандартный предикат assert (sumdoll(0)) создает факт базы данных sumdoll(0). Затем в базе данных отыскивается первый предикат proekt, где третьим аргументом является функтор doll; это предикат proekt ("П100", "Рубин", doll(1400)). Переменная S принимает значение 1400. В базе данных отыскивается предикат sumdoll(0), и переменная Sd принимает значение 0. Переменная Sd1 принимает значение Sd+S=0+1400=1400. Предикат retractall(sumdoll(_)) удаляет из памяти факт sumdoll(0), а предикат assert создает в памяти предикат sumdoll(1400). Предикат fail создает состояние искусственной неудачи; это требуется, чтобы найти сумму стоимостей по всем проектам.
Происходит возврат к ближайшей «развилке», в данном случае - к предикату proekt (_, _, doll(S)). В базе данных отыскивается следующий предикат proekt, где третьим аргументом является функтор doll; это предикат proekt ("П70", "Горизонт", doll(500)). Переменная S принимает значение 500. В базе данных отыскивается предикат sumdoll. Так как имеется предикат sumdoll(1400), переменная Sd принимает значение 1400. Вычисляется переменная Sd1=Sd+S=1400+500=1900. Предикат retractall(sumdoll(_)) удаляет из памяти факт sumdoll(1400), а предикат assert создает в памяти предикат sumdoll(1900). Предикат fail снова создает состояние искусственной неудачи. Так как в базе данных больше нет фактов proekt с функторами doll, происходит переход ко второму клозу предиката summa. Итак, по окончании обработки первого клоза предиката summa в базе данных создан факт sumdoll(1900).
Таким образом, подсчитана сумма стоимостей проектов, оплачиваемых в долларах.
Второй клоз предиката summa обрабатывается аналогично первому. В результате создается факт sumrub(1800), содержащий сумму стоимостей проектов, оплачиваемых в рублях.
В третьем клозе предиката summa выполняется вывод результатов на экран.
Факты базы данных sumdoll и sumrub должны быть объявлены в разделе global facts (рис. 20):
global facts
sumdoll (real)
sumrub (real)
Рис. 20. Объявление глобально фактов sumdoll и sumrub.
Примечание. Напомним, что в Прологе невозможны операции вида S=S+X. Такая операция интерпретируется как сравнение значений S и S+X и поэтому всегда завершается неудачей. Из-за этого для реализации суммирования потребовалось использовать факты динамической базы данных.
Программа для работы с базой данных
Рассмотрим разработку программы, позволяющей выполнять различные операции с базой данных о проектах и сотрудниках.
Приведем целевой предикат, создающий простейшее меню операций с базой данных (рис. 21) и обеспечивающий выполнение выбранных операций (рис. 22).
Рис. 21. Меню для работы с базой данных.
goal
start.
clauses
start:-clearwindow,
makewindow (1,7,7,"База данных",0,0,14,40),
repeat, clearwindow,
write ("1 - загрузка"), nl,
write ("2 - добавление"), nl,
write ("3 - удаление"), nl,
write ("4 - просмотр"), nl,
write ("5 - сохранение"), nl,
write ("6 - выход"), nl,
write ("7 - поиск"), nl,
write ("Введите номер операции: "), readint (N),
obrab (N), removewindow.
Рис. 22. Создание простейшего меню операций с базой данных.
Стандартный предикат makewindow создает на экране окно. Смысл аргументов предиката следующий: 1 - номер окна; 7, 7 - цвет окна и рамки (черное окно, белая рамка), “База данных” - заголовок окна (выводится сверху); 0, 0 – координаты левого верхнего угла окна; 14, 40 – высота и ширина окна.
Предикат repeat необходим для того, чтобы операции с базой данных могли выполняться многократно.
Предикат clearwindow очищает окно. Предикаты write выводят на экран элементы меню (возможные операции с базой данных), а предикат readint запрашивает номер желаемой операции.
Предикат obrab реализует операции, выбираемые из меню. Он должен иметь по меньшей мере десять клозов (по числу операций в меню). При этом все клозы предиката obrab (кроме клоза для операции выхода, соответствующего номеру 6) должны заканчиваться неудачей. В этом случае выполняется возврат к предикату repeat. Он успешно доказывается, на экран снова выводится меню, и повторяется запрос желаемой операции. Реализация предиката obrab (рис. 23):
obrab(1):- makewindow(2,7,7,"Загрузка",12,0,3,60), zagruzka,
removewindow, shiftwindow(1), !,fail.
obrab(2):- makewindow(3,7,7,"Добавление",12,0,10,80), dobav,
removewindow, shiftwindow(1), !,fail.
obrab(3):- makewindow(4,7,7,"Удаление",12,0,10,80), udal,
removewindow,shiftwindow(1), !,fail.
obrab(4):- makewindow(5,7,7,"Просмотр",12,0,10,80), prosmotr,
removewindow, shiftwindow(1), !,fail.
obrab(5):-makewindow(6,7,7,"Сохранение",12,0,3,60), sohran,
removewindow, shiftwindow(1), !,fail.
obrab(6).
obrab(7):-makewindow(7,7,7,"Поиск",12,0,10,80), poisk,
removewindow, shiftwindow(1), !,fail.
Рис. 23. Реализация предиката obrab.
Рассмотрим клоз obrab(4). Он будет доказываться, если на запрос "Введите номер: " будет введен номер 4, т.е. выбрана операция просмотра. Предикат makewindow создает окно для просмотра. Затем вызывается предикат prosmotr, непосредственно выполняющий просмотр. Для нормальной работы программы он должен доказываться успешно. Предикат removewindow удаляет с экрана текущее окно (окно просмотра). Предикат shiftwindow(1) выполняет возврат курсора в окно с номером 1 (окно меню).
Предикат fail вызывает состояние искусственной неудачи, в результате чего происходит возврат к предикату repeat и повторение работы с меню. Предикат отсечения (!) указан только для того, чтобы при возврате не рассматривались остальные клозы предиката obrab.
Предикаты zagruzka, dobav, udal, prosmotr, sohran, poisk рассмотрены выше. Все используемые предикаты должны быть объявлены в разделе predicates.
