Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Логическое программирование. Учебно-методическое пособие к лабораторным работам

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
11
В то же время, когда посылки утверждения связаны дизъюнктивной свя-
зью, утверждение теоретически может быть представлено несколькими кла-
узами с одной и той же головой, но разными телами. Например, утвержде­ние
«Родителем человека является его мать или его отец»
выглядит как
родитель(X, Y) мать(X, Y).
родитель(X, Y) отец(X, Y).
Однако большинство версий языка ПРОЛОГ имеют практические воз­можности для дизъюнктивного соединения посылок в теле клаузы с помо-
щью символа «;» (связки or):
parent(X, Y) if mother(X, Y) or father(X, Y).
или
parent(X, Y) :─ mother(X, Y); father(X, Y).
При составлении логических программ наряду с вышеизложенным сле-
дует учесть, что предикаты, используемые в программе на языке Турбо­ПРОЛОГ или на языке Visual Prolog, должны быть предварительно описаны в начале программы в разделе predicates. В этом разделе перечисляются предикаты с указанием типов и количества их аргументов (см. ниже Пример
1). Имена предикатов могут состоять из латинских букв, цифр и символа
подчёркивания и начинаться с латинской буквы в любом регистре.
Основные встроенные типы данных языков Turbo Prolog и Visual PROLOG
symbol начинается со строчной латинской буквы, содержит латинские
буквы, цифры и символ подчёркивания _или произвольный
набор символов в кавычках: “apples”, “x”, “b_1”, “var12”,
“”_Prolog”, “john”.
string произвольная строка символов, заключённых в кавычки:
”12345”, ”_перец”, ”F”, ”Hello!”, ”ballon”
char произвольный символ: S’, ’Ф’, ’%’, ’?’, ’\13’, ’*’
(Внимание! Ане равно А, так как строка из одной литеры здесь не символ)
integer двухбайтовое целое число (-32768 … 32767): -32, 5, 149, 31071,
real вещественное число диапазона +1. 7Е-307…+1.7Е 308 по моду-
лю: 0, -1, 1. 5Е-3, -2. 71Е 12.
12
Вслед за разделом predicates следует раздел clauses, содержащий соб-
ственно текст программы, то есть декларативную постановку задачи или ба-
зу знаний по какому-то конкретному вопросу.
Переменные в логических программах должны начинаться с заглавных
латинских букв и содержать латинские буквы, цифры и символ подчёркива-
ния: X, Y, Ball, P1, B_x_2.
Важно знать, что в одной клаузе каждая переменная должна встречаться
минимум дважды. Если переменная в клаузе встречается только один раз, то ПРОЛОГ-машина выдаёт предупреждающее сообщение (warning).
Особое место занимает в логических программах анонимная перемен- ная, предназначенная для замены однократно встречающихся в клаузе пе­ременных. Необходимость в использовании анонимных переменных возни­кает из-за того, что в клаузальной форме логики не используются в явном виде кванторы. В неявном виде на каждую переменную в клаузе действует квантор всеобщности «для всех» (или «для каждого»). В то же время кван­тор существования в клаузальной форме логики отсутствует. Если квантор существования действует на переменную в теле клаузы, то эта переменная заменяется анонимной переменной. В качестве примера рассмотрим фразу:
«Мужчиной является тот, кто является кому-либо отцом».
Переформулированная в логике исчисления предикатов эта фраза зву-
чит как:
«Если для каждого X существует Y, такой, что X – отец Y, то X – мужчина».
В клаузальной подсистеме системы формальной логики эта фраза вы­глядит так:
мужчина(X) отец(X, Y).
В логической программе соответствующая клауза имеет вид:
man(X) :- father(X, _).
Таким образом, в теле клаузы анонимные переменные неявно отражают действие кванторов существования.
Совершенно другой смысл имеют анонимные переменные, расположен-
ные в голове клаузы. В этом случае их появление эквивалентно действию квантора всеобщности. Так, утверждения вроде «Каждый ошибается», «У
всякого есть обувь» или «Каждый ест» теоретически представляются кла-
узами:
13
ошибается(X)
имеет(X, обувь)
ест(X)
А в логической программе фактами:
faulter(_).
owns(_, shoes).
eats(_).
Завершая рассмотрение основных приёмов набора фактов и правил ло­гической программы, следует сказать, что расположение клауз в программе
для рассмотренных выше ситуаций может быть произвольным за тем ис-
ключением, что клаузы с одной и той же головой должны находиться вместе не перемешиваясь с другими клаузами. Это требование позволяет ускорять
обработку и выполнение программ на языках Турбо-ПРОЛОГ и Visual
PROLOG.
Соблюдая все перечисленные правила набора клауз логической про­граммы, в итоге получаем текст некоей базы знаний, отражающей деклара­тивную информацию по некоторой проблеме. Причём факты составляют базу данных по рассматриваемой задаче, а правила позволяют создать наилучшую по результативности систему запросов из всех теоретически возможных. Сами же запросы (вопросы) к логической программе задаются
двумя способами:
а) в режиме диалога с ПРОЛОГ-машиной в окне goal после запуска про-
граммы – внешняя цель [15];
б) в разделе goal, находящемся непосредственно перед разделом
clauses (внутренняя цель [15] – см. Пример 1) непосредственно в мо- мент старта логической программы.
Каждый запрос представляет собой конъюнкцию целей и по форме яв-
ляется телом клаузы без головы. Так, вопрос
«Кто является внуком Петра
III?
»
задаётся клаузой внук (Vnuk, ”Пётр_III”). ,
или запросом в разделе goal:
grandson (Vnuk, ”Пётр_III”).
Приведённый далее пример на Турбо-ПРОЛОГе иллюстрирует структу-
ру программы и некоторые приёмы создания клауз.
14
/* Пример 1. Программа на Турбо-ПРОЛОГе */
predicates /* Раздел, где описываются предикаты */ mother(string, string) father(string, string) man(string) woman(string) male(string) female(string) son(string, string) grandson(string, string) goal /* Раздел, где задается цель логической программы */ grandson(Vnuk,"Петр_III"), write(Vnuk), nl, fail; true.
% определить, имя внука Петра III, написать его, перейти на следующую % строку и продолжить поиск другого внука, пока не будут найдены все
clauses /* Раздел, где описываются клаузы логической программы */
/* Подраздел, где задаются факты */
mother("Екатерина_II", "Павел_I"). /* Екатерина II - мать Павла I */ mother("Мария_Фёдоровна", "Александр_I"). mother("Мария_Фёдоровна", "Константин"). mother("Мария_Фёдоровна", "Николай_I"). mother("Александра_Фёдоровна ", "Александр_II"). mother("Мария_Александровна ", "Александр_III"). mother("Дагмара_Датская", "Николай_II"). mother("Алиса_Гессенская", "Алексей"). mother("Алиса_Гессенская ", "Анастасия"). father("Петр_III", "Павел_I"). /* Петр III - отец Павла I */ father("Павел_I", "Александр_I"). father("Павел_I", "Константин"). father("Павел_I", "Николай_I"). father("Николай_I", "Александр_II"). father("Александр_II", "Александр_III"). father("Александр_III", "Николай_II"). father("Николай_II", "Алексей"). father("Николай_II", "Анастасия"). female("Анастасия"). /* пол Анастасии - женский */
male("Алексей"). /* пол Алексея - мужской */
/* Подраздел, где задаются правила */
woman(X) if mother(X,_) or female(X). % Некто - женщина, если она мать кому-либо или её пол - женский. man(X) if father(X,_) or male(X). % Некто - мужчина, если он отец кому-либо или его пол - мужской. son(X,Y) if man(X) and mother(Y,X) or man(X) and father(Y,X). % X - сын Y, если X - мужчина и Y - его мать или
% если X - мужчина и Y - его отец.
grandson(X,Y) :- man(X), father(Z,X), father(Y,Z); man(X), mother(Z,X), father(Y,Z); man(X), father(Z,X), mother(Y,Z); man(X), mother(Z,X), mother(Y,Z).
15
Работа в среде Турбо-ПРОЛОГа начинается с запуска файла prolog.exe
и существенно не отличается от работы в средах программирования, пред-
ставляющих хорошо известные программные продукты фирмы Borland (Tur­bo-Pascal, Turbo-С и Turbo-Basic). Только копирование фрагмента текста осуществляется несколько иначе: в начале выделяемого фрагмента ставит­ся курсор и осуществляется нажатие клавиш Ctrl-F5. Затем курсором выде-
ляется нужный фрагмент, после чего снова осуществляется нажатие кла-
виш Ctrl-F5. Фрагмент скопирован. Запуск логической программы на выпол­нение производится либо командой меню Run, либо сочетанием клавиш
Alt-R.
Если в логической программе присутствовал раздел goal, то в автомати-
чески возникающем окне диалога будет показан результат. Если же раздел
goal отсутствовал, то в окне диалога появится строка приглашения «GOAL:» для задания вопроса ПРОЛОГ-машине. После ввода вопроса в окне диалога будет показан ответ ПРОЛОГ-машины. Для возвращения в ок­но редактора программ необходимо воспользоваться клавишей Esc, воз­вращающей в меню.
Выход из среды Турбо-ПРОЛОГа осуществляется нажатием Alt-X.
Если же программист желает работать в среде Visual Prolog 5.0, то пред­варительное знакомство с другими программными продуктами, ориентиро­ванными на программирование под операционную систему Windows, суще-
ственно облегчит освоение этой дружественной среды. Важное и не совсем
привычное отличие языка Visual Prolog 5.0 состоит в том, что запуск логиче-
ской программы на выполнение осуществляется не традиционной кнопкой
Run, а кнопкой TestGoal.
Задания для лабораторной работы №1
Часть 1. «Родственные отношения»
Описав предикаты «мать» и «отец», а также «мужской_пол» и «жен­ский_пол» (mother(…, …), father(..., …), male(...), female(…)), создать с помо-
щью этих предикатов базу знаний, аналогичную приведённому выше приме-
ру, изобразив её семантическую сеть. К созданной базе знаний составить
следующие запросы:
16
1. а) Ребёнок. 2. а) Сын.
б) Родитель. б) Дочь.
в) Мужчина. в) Дедушка. г) Женщина. г) Бабушка. д) Муж. д) Внук. е) Жена. е) Внучка.
3. а) Брат. 4. а) Сводный_брат. б) Сестра. б) Сводная_сестра. в) Брат_по_отцу. в) Дядя. г) Брат_по_матери. г) Тётя. д) Сестра_по_отцу. д) Племянник. е) Сестра_по_матери. е) Племянница.
5. а) Кузен (двоюродный брат). 6. а) Зять (муж дочери). б) Кузина (двоюродная сестра). б) Сноха (жена сына). в) Деверь (брат мужа). в) Свекор (отец мужа). г) Шурин (брат жены). г) Свекровь (мать мужа). д) Золовка (сестра мужа). д) Тесть (отец жены). е) Свояченица (сестра жены). е) Тёща (мать жены).
7. а) Предок. 8. а) Сват. б) Потомок. б) Сватья. в) Родственник. в) Падчерица. г) Свойственник. г) Пасынок. д) Невестка (жена кровного родственника). д) Отчим. е) Зять (муж кровной родственницы). е) Мачеха.
Для упрощения процедуры проверки работы программы рекомендуется
использовать реальные данные о своих родных, либо о родственных связях
известных исторических лиц (см. ПРИЛОЖЕНИЕ 1) согласно вариантам:
17
1. «Предки и потомки Игоря и Ольги» (Таблица 1),
2. «Родственные связи Ярослава Мудрого» (Таблица 2),
3. «Родственные отношения Владимира Мономаха» (Таблица 3),
4. «Потомки и наследники Александра Невского» (Таблица 4),
5. «Семья Ивана III» (Таблица 5),
6. «Родоначальники династии Романовых» (Таблица 6),
7. «Дом Романовых от Петра I до Николая II» (Таблица 7),
8. «Семья и родня А.С. Пушкина» (Таблица 8),
9. «Святослав, его дети и внуки» (Таблица 1),
10. «Родословная Владимира Мономаха» (Таблица 2),
11. «Потомки Юрия Долгорукого» (Таблица 3),
12. «Иван Калита и его дети» (Таблица 4),
13. «Иван IV, его несчастные потомки и свойственники» (Таблица 5),
14. «От Филарета до Елизаветы» (Таблица 6),
15. «Иностранные царицы в доме Романовых» (Таблица 7),
16. «Семья и потомки Абрама Петровича Ганнибала» (Таблица 8),
17. «Предки и родственники Игоря Северского» (Таблица 3),
18. «Родственники и свойственники Дмитрия Донского» (Таблица 4).
Часть 2. «Табель о рангах»
Создать базу данных «Табель о рангах России» (см. ПРИЛОЖЕНИЕ 2) с по-
мощью предикатов: гражданский(Чин, Класс), придворный(Чин, Класс), гор-
ный(Чин, Класс), пехотный(Чин, Класс), кавалерийский(Чин, Класс), артиллерий-
ский(Чин, Класс), казацкий(Чин, Класс) <условно>, морской(Чин, Класс), учё­ный(Степень, Класс), титул(Название, Класс).
Определить отношения: чин_и_титул (Название_чина, Название_Титула), старший_по_чину(Кто, Кому), младший_по_чину(Кто, Кому), равный_по_чину(Кто, Кому), равный_по_классу(Кто, Кому), старший_по_классу(Кто, Кому), младший_по_классу (Кто, Кому), и т. п.
18
Методические указания
При подготовке к выполнению и сдаче лабораторной работы рекоменду-
ется дополнительно ознакомиться с теоретическими положениями, изло-
женными в [1–6], терминологией, представленной в гл. I-V из [2], а также в [3–7]. Редактор Турбо-ПРОЛОГа и его встроенные типы данных можно изу­чить по гл.1–3 [7], а Visual Prolog изучать по [8, 9]. Программа «Родственные отношения» рассмотрена в гл.1 [10].
Материалы для приложений взяты из следующих источников:
А) Данилов А. История России. IX-XIX вв. Справочные материалы. — М. : Гуманитарный издательский центр ВЛАДОС, 1997.
Б) История СССР с древнейших времён до наших дней. — М. : Наука,
1968.
В) Лесной С. Откуда ты, Русь? — Ростов-на-Дону : Донское слово, Квад- рат, 1995.
Г) Черкасов П.П., Чернышевский Д.В. История императорской России. От Петра Великого до Николая II. — М. : Международные отношения, 1994.
Д) Советский энциклопедический словарь — М. : Советская энциклопе- дия, 1986.
Е) Царскосельский лицей. Наставники и питомцы. 1811–1817. Состави­тель Д.А. Рутгайзер. — г. Пушкин : издание Царскосельского Лицея, 1991.
Ж) Энциклопедия истории России 862–1917. [Электронный ресурс] — Коминфо, 2004.
Содержание отчёта:
1) заголовок;
2) цель лабораторной работы;
3) индивидуальное задание;
4) семантическую сеть базы знаний;
5) описание предикатов, созданных программистом;
6) текст логической программы;
7) результаты работы программы;
8) выводы.
19
Р а б о т а 2. СТРУКТУРИРОВАННОЕ ПРЕДСТАВЛЕНИЕ
ИНФОРМАЦИИ НА ПРОЛОГе
Цель работы знакомство с различными способами структурированно-
го представления информации в логическом программировании; особенно-
сти разработки пользовательских типов данных на языках Турбо-ПРОЛОГ и
Visual PROLOG.
Общие сведения
Структурированное представление информации необходимо для удоб-
ства её хранения и обработки. В логическом программировании структури- рованные переменные являются аргументами предикатов. Теоретической
моделью структурированных переменных в логике исчисления предикатов
1-го порядка являются термы.
Терм — выражение формализованного языка, являющееся формальным
именем объекта или именной формы. Понятие терм определяется индук-
тивно. Термом называется символьное выражение:
t(X1, X2, ... , Xn) ,
где t —имя терма, называемое функтор или «функциональная буква», а X1, X2, ... , Xn — тоже термы, структурированные или простейшие.
Простейшим термом является предметная переменная или предметная
константа, то есть символьное имя, служащее для обозначения конкретно-
го объекта. Как следует из определения, структуры могут быть многократно вложены друг в друга.
Внешне термы похожи на предикаты, поэтому следует помнить, что пре-
дикаты есть логические функции, а термы — только аргументы этих функ­ций. Функторы есть лишь имена структур. Кроме того, предикаты не могут быть вложены друг в друга, в отличие от термов.
Теоретические термы в практике логического программирования реали-
зуются с помощью структурированных типов данных, создаваемых пользо­вателем.
Для разработки таких типов в тексте программы на Турбо-ПРОЛОГе и на языке Visual Prolog должен быть создан специальный раздел domains,
20
предшествующий разделу predicates. В разделе domains описываются типы
аргументов предикатов, которые будут иметь переменные в клаузах. Назва-
ния этих типов помещаются вместо названий встроенных типов данных в аргументах создаваемых предикатов в разделе predicates.
Общий синтаксис создания структурированных типов данных следую­щий:
<имя_типа>=<функтор>(<список_имен_типов_аргументов>)
или, в простейшем случае, такой:
<имя_пользовательского_типа>=<имя_встроенного_типа_данных>.
В последнем варианте это неструктурированный пользовательский тип.
Ниже, в Примере 2, можно увидеть описание созданных пользователь-
ских типов на практике. Среди созданных в этом примере пользовательских типов данных есть простейшие, такие как fname, sname, lname, work, day, month и year, а также структурированные, такие как fio, date, father, mother и
child. Видно, что имя типа может совпадать с функтором (тип fio), хотя и не
обязательно. Также можно видеть, что создаваемые структуры могут быть
много раз вложены друг в друга. Например, структура father в качестве сво-
их компонент имеет структурированные типы fio и date, а также простейшие
типы work и oklad. Таковы же типы mother и child. Наряду с этим возможно
наличие структурированных типов данных, имеющих только одну компонен-
ту. Создание таких типов объясняется потребностью в дополнительном
удобстве представления информации. Важно подчеркнуть разницу между
использованием имён типов и функторами в разделах predicates и clauses,
так как имена типов используются в разделе predicates, а функторы — в разделе clauses, при создании структурированной базы данных. Поэтому названия типов данных рекомендуется делать достаточно полными и со­держательными, имена же функторов, с целью экономии размеров клауз,
рекомендуется сокращать. Также важно заметить, что в системе вложенных
структур роль главного функтора всегда играет предикат (как в структуре
family — см. Пример 2).
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]