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

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

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
21
% Пример 2. Структурированные типы данных в Турбо-ПРОЛОГе
domains % раздел объявления типов данных созданных пользователем fname,sname,lname,work = string day,month,year,oklad = integer % простые типы fio = fio(lname, fname, sname) % структура fio с функтором fio date = dat(day, month, year) % структура date c функтором dat father = fath(fio, date, work, oklad) % тип данных - father mother = moth(fio, date, work, oklad) % тип данных - mother сhild = chld(fio, date, work, oklad) % тип данных - child predicates zapros % предикат для запроса family(father, mother, child) % предикат о членах семьи clauses % клаузы, содержащие информацию о членах трех семей family(fath(fio("Попов", "Иван", "Петрович"), dat(10,06,1958), "Инженер", 9500), moth(fio("Сперанская", "Ирина", "Леонидовна"), dat(21,09,1961), "Бухгалтер", 9000), chld(fio("Попов", "Сергей", "Иванович"), dat(02,03,1979), "Студент", 824)). family(fath(fio("Ковров", "Евгений", "Дмитриевич"), dat(29,07,1948), "Экономист", 12500), moth(fio("Коврова", "Ольга", "Геннадьевна"), dat(21,09,1954), "Домохозяйка", 0), chld(fio("Ковров", "Олег", "Евгеньевич"), dat(7,10,1977), "Грузчик", 7000)). family(fath(fio("Петров", "Денис", "Валентинович"), dat(25,11,1952), "Терапевт", 2500), moth(fio("Петрова", "Алла", "Алексеевна"), dat(04,02,1952), "Учитель", 1500), chld(fio("Петрова", "Лада", "Денисовна"), dat(16,01,1971), "Секретарь", 4532)). zapros:-family(_,moth(fio(_,N,_),dat(_,_,Y),_,_),_), Y>1960, write(N), nl, fail; true.
22
Особенно важную роль при составлении запросов к структурированной базе данных играет анонимная переменная («_»). Замена определённых по-
зиций в структурах анонимными переменными позволяет сформировать
экономные запросы, не выводящие ненужной информации. Сочетание ано-
нимной переменной со структурированием информации позволяет заменять
одной переменной (часто называемой в данном контексте слотом) сразу целую группу объединённых общим функтором переменных.
Так, в приведенной программе составлен запрос к структурированной
базе данных «семьи», выводящий информацию обо всех мамах, рожденных
после 1960 года. Наличие слотов позволяет игнорировать нетребуемую ин­формацию о других членах семей и о профессии и доходах мам.
Для удобства создан и сам предикат zapros, не имеющий аргументов и
фактически являющийся просто логической переменной. Такие предикаты
существенно упрощают диалог с ПРОЛОГ-машиной, позволяя заранее
определить требуемые запросы, позволяя в режиме диалога только вызы-
вать очередной запрос без громоздкого набора информации.
Заполнять базу данных можно двумя основными способами:
1) непосредственно с помощью многоаргументных фактов как в приве-
денном примере программы;
2) посредством бинарных фактов и правил с многоаргументными преди-
катами. Так, фраза «Сотрудник Попов Иван Петрович, рожденный 10 июня
1958 года, инженер с окладом 9500 р. c идентификационным номером 12»,
представленная многоместным неструктурированным предикатом, выглядит
как:
member(12,"Попов","Иван","Петрович",10,06,1958,"Инженер",9500).
Девять аргументов этого предиката легко перепутать как при заполнении
базы данных информацией, так и при извлечении информации из базы дан-
ных посредством запросов. В структурированном виде эта информация мо­жет быть представлена фактом:
member(12, fio("Попов", "Иван", "Петрович"),
dat(10, 06, 1958),
work("Инженер", 9500)).
23
Однако возможно представление этой информации с помощью набора бинарных предикатов: name("Иван", 12).
surname("Попов", 12). fathername("Иваныч", 12). day(10, 12). month(6, 12). years(1958, 12). work("Инженер", 12). price(9500, 12).
и правил для неструктурированного предиката:
member(N, SurNm, Nm, FathNm, D, M, Y, Wrk, Prc, N) :­ name(Nm, N), surname(SurNm, N), fathername(FathNm, N), day(D,N), month(M,N), years(Y,N), work(W,N), price(Prc,N).
или для структурированного предиката:
member(N, fio(SurNm,Nm,FathNm), dat(D,M,Y), work(Wrk,Prc)) :­ name(Nm, N), surname(SurNm, N), fathername(FathNm, N), day(D,N), month(M,N), years(Y,N), work(W,N),price(Prc,N).
Фактически набор элементарных фактов с помощью двуместных преди-
катов с общим для всех предикатов аргументом, содержащим номер со-
трудника, является набором реляционных таблиц с общим ключевым по-
лем. Такое представление информации более объёмно и требует создания
дополнительных бинарных предикатов в разделе predicates, но при этом
легко модифицируется, так как заменить один бинарный факт на другой
проще, чем многоаргументный факт. При этом получает свою дальнейшую
реализацию принцип представления информации с помощью правил.
Выбор способа представления сложной структурированной информации
остаётся за пользователем. Важно заметить, что система запросов к клау-
зам, использующим предикаты со структурированными аргументами, не из-
меняется в зависимости от того, используется база данных со структуриро-
ванными фактами, или же используется база данных с бинарными фактами
и структурированными правилами.
24
Задания для лабораторной работы №2
Необходимо создать хорошо структурированную базу данных и систему за-
просов к ней в соответствии с вариантами задания. При разработке базы дан­ных для хранения информации допустимо использовать лишь один предикат.
1. Разработать базу данных «семья» (family), используя данные о семье и
предках А.С. Пушкина из Приложения 1 (Таблица 8).
2. Разработать базу данных «Табель о рангах» на основе Приложения 2.
3. Разработать базу данных «лицей» (lyceum) об учащихся Царскосельско-
го Лицея (см. Приложение 3, Таблицы 1 и 2).
4. Разработать базу данных «преподаватели» (professor), используя дан-
ные о преподавателях Царскосельского Лицея из Приложения 3 (Таблица 3).
5. Разработать базу данных «режим дня» (regime), используя расписание
дня лицеиста из Приложения 3 (Таблица 4) или собственный режим дня.
6. Разработать базу данных «расписание занятий», используя недельное
расписании учебы лицеиста из Приложения 3 (Таблица 4) или своё расписа­ние.
7. Разработать базу данных «табель оценок» (tabel) на основе успеваемо-
сти лицеистов из Приложения 3 (Таблица 5) или успеваемости группы студен­тов.
8. Разработать базу данных «расписание экзаменов» с указанием сведений
об экзаменаторе, используя данные о Лицее из Приложения 3 (Таблица 5).
9. Разработать структурированную базу данных «планета» (planeta), ис-
пользуя Приложение 4 (Таблица 1).
10. Разработать базу данных «спутник» (satellite) (Приложение 4, Таблица
2).
11. Разработать базу данных «звездная_ величина», для чего использовать
Приложение 4 (Таблица 3).
12. Разработать базу данных «самые яркие звёзды», для чего использовать
данные из Приложения 4 (Таблица 4).
13. Разработать базу данных «сотрудник» (member), содержащую поля
«ФИО» (fio), «день рождения» (date), «карьера» (career) и т. п.
14. Разработать базу данных «анкета» (form), содержащую поля «ФИО»
(fio), «адрес» (address), «день рождения» (date), «текущая дата» (currency_date) и т. п.
25
15. Разработать базу данных «студент» (student), содержащую поля «ФИО»
(fio), «место учебы» (place), «оценки» (marks), «учебные планы» (plans) и т. п.
16. Разработать базу данных «семья», используя данные о семье учащего-
ся.
17. Разработать базу данных «преподаватели», используя данные о ка-
федре.
18. Разработать базу данных «расписание занятий», используя собствен-
ное недельное расписании учебы.
Методические указания
При подготовке к выполнению и сдаче лабораторной работы рекоменду-
ется ознакомиться с теоретическим понятием терм, изложенным в книгах [1, 3, 4]. Структурированные типы данных Турбо-ПРОЛОГа можно изучить по гл. 3 [7], а такие же типы данных у языка Visual Prolog — по гл. 12 [8]. При-
меры использования структур, отличные от простейших баз данных, рас-
смотрены в гл. 4 [10]. Заполнение базы данных с помощью бинарных преди­катов рассмотрено в [11].
Материалы для заданий почерпнуты из книг:
А)Черкасов П.П., Чернышевский Д.В. История императорской России. От
Петра Великого до Николая II», — М. : Международные отношения, 1994.
Б) Советский энциклопедический словарь. — М. : Советcкая энциклопе-
дия, 1986.
В) Царскосельский лицей. Наставники и питомцы. 1811–1817 / Сост. Д. А.
Рутгайзер — г. Пушкин, издание Царскосельского Лицея, 1991.
Г) Маров М. Я. Планеты Солнечной системы, — М. : Наука, 1981. Д) Силкин Б. И. В мире множества лун / Ред. Е.Л. Рускол. — М. : Наука,
1981.
Содержание отчёта:
1) заголовок лабораторной работы;
2) цель лабораторной работы;
3) индивидуальное задание;
4) описание предикатов, созданных программистом;
5) текст логической программы;
6) результаты работы программы (один из запросов должен выводить
всю базу данных без купюр);
7) выводы.
26
Р а бота №3. АЛЬТЕРНАТИВНЫЕ ДОМЕННЫЕ СТРУКТУРЫ
И ВСТРОЕННЫЙ МЕХАНИЗМ СОЗДАНИЯ СПИСКОВ
Цель работы изучение возможностей создания альтернативных до-
менных структур на ПРОЛОГе. Исследование встроенного механизма со-
здания динамических списковых структур данных. Создание рекурсивных
типов данных.
Общие сведения
Статические структуры часто не обладают возможностями достаточно
гибко, с точки зрения практики, представлять информацию. Так в рассмот-
ренном в предыдущей лабораторной работе примере базы данных «семья» существует одна единственная позиция «работа» (work), а также позиция «зарплата» (price) для любого члена семьи без различия. Однако это не со-
всем удобно на практике, так как отразить в базе данных неработающих
членов семей, учащихся детей, иждивенцев и пенсионеров, оказывается возможным лишь заполняя поле work соответствующими символьными строками. В результате, с позиции синтаксиса логической программы, раз­личий в социальном статусе членов семьи обнаружить невозможно. Также
представляется неудобным жёстко связывать информацию о положении в
семье с социальным положением члена семьи, так как это не соответствует реальности.
Преодолеть это отсутствие гибкости позволяет механизм создания аль-
тернативных доменных структур, имеющийся во многих версиях языка
ПРОЛОГ, в том числе в языках Турбо-ПРОЛОГ и Visual Prolog фирмы Bor-
land.
Так, в приведённом ниже Примере 3 дано описание типа данных work, имеющего несколько разных структур с функторами work, study и dependant. Это так называемая альтернативная доменная структура. Она формируется следующим образом. Вслед за именем типа после знака равенства через точку с запятой перечисляются структуры с указанием функторов и типов аргументов, входящих в них:
work = work(work_place, post, price); % структура "работа" study(study_place, gruppa, grant); % структура "учеба" dependant(status, pension) % структура "иждивенец"
27
Тип данных work описывает позицию в структурированных типах данных
father=fath(fio,date,work), mother=moth(fio,date,work), child=chld(fio,date,work)
и, значит, в одной и той же позиции соответствующей клаузы могут нахо-
диться различные структуры данных, например:
fath(fio(<...>), dat(<...>), work("ООП", "Инженер", 19500), <>), или fath(fio(<...>), dat(<...>), study("МАИ", 03419, 1024), <>), или fath(fio(<...>), dat(<...>), dependant("Пенсионер", 2000), <>).
Таким образом, оказывается возможным формировать весьма гибко
структурированную информацию и учитывать различие в типах полей дан-
ных одного и того же предиката на синтаксическом уровне. Это позволяет
формировать более гибкие запросы вроде «Как зовут всех неработающих и неучащихся мам?», задаваемые в виде:
family( _, moth(Mama, _, dependant(_, _)), _).
Альтернативные доменные структуры помимо возможностей, описанных
выше, предоставляют также весьма важные и полезные возможности для
создания рекурсивных структур данных. Это позволяет синтаксис языков Турбо-ПРОЛОГ и Visual Prolog, так как имя типа поля данных одной из структур в альтернативной записи справа от знака равенства может совпа­дать с именем типа слева от знака равенства. С помощью такой синтаксиче-
ской конструкции оказывается возможными синтезировать динамические
структуры данных, такие как списки, деревья, очереди, стеки и т. п.
Например, список данных типа symbol представляет собой динамиче-
скую двухместную (бинарную) структуру, первый элемент которой имеет тип
symbol, а второй также является списком. При этом самый простой (самый короткий) список — пустой список, не содержащий никаких элементов (void).
Такой тип данных может быть создан следующим образом:
domains list = void; l(symbol, list)
Видно, что имя типа совпадает с именем типа аргумента в бинарной
структуре с функтором l. Для хранения и обработки списков их необходимо
сделать аргументами предназначенных для этого предикатов, например,
так:
28
predicates p(list) q(list)
Тогда список [a, b, c, d] может быть представлен фактом
p(l(a, l(b, l(c, l(d, void))))).
а пустой список фактом
q(void).
Аналогично можно создать «дерево» и другие рекурсивные типы. Наиболее часто используемая динамическая структура «список» имеет
встроенный механизм создания практически во всех версиях ПРОЛОГа. Это
обстоятельство существенно облегчает создание списков в сравнении с со-
зданием других динамических структур данных, принципы которого были
сейчас рассмотрены. Для того чтобы создать список, достаточно при описа-
нии спискового типа данных в разделе domains в правой части оператора равенства после описания типа элементов списка поставить знак «*». Так,
тип списков целых чисел с именем number можно создать следующим обра-
зом:
domains number = integer* .
Тогда список может быть аргументом предиката:
predicates l(number) .
Встроенный механизм предполагает представление списка данных с по-
мощью стандартной синтаксической конструкции — квадратных скобок «[» и «]». Причём элементы перечисляются через запятую, а пустой список запи­сывается как «[]». Так для создания списка целых чисел в разделе clauses может быть задан факт:
l([3,4,5,2,7,6,1,8,9,0]).
Другой способ стандартного представления списков разделение на
голову (Head) и хвост (Tail), разделяемые вертикальной чертой «|»:
l([Head| Tail]).
Такой синтаксис используется в правилах обработки списков. В Примере
3 элементами списка является структурированный тип:
domains
child= chld(fio, date, work)
children=child*
29
% Пример 3. Альтернативные доменные структуры и списковый тип данных.
domains day, month, year, price, grant, pension, gruppa=integer
fname, sname, lname, work_place, study_place, post, status=string fio=fio(lname, fname, sname) date=dat(day, month, year) work=work(work_place, post, price); % структура "работа" study(study_place, gruppa, grant); % структура "учеба" dependant(status, pension) % структура "иждивенец" father=fath(fio, date, work) mother=moth(fio, date, work) child=chld(fio, date, work) % элементы списка имеют этот тип данных children=child* % списковый тип данных children («дети»)
predicates zapros1
zapros2 family(father, mother, children)
clauses
family(fath(fio("Васильев", "Иван", "Никифорович"), dat(10,06,1958), work("ООП", "Инженер", 14500)), moth(fio("Васильева", "Ирина", "Леонидовна"), dat(21,09,1961), work("ПБОЮЛ Васильева", "Продавец", 12000)), % далее следует список из двух структур с информацией о двух детях [chld(fio("Васильев", "Сергей", "Иванович"), dat(02, 03, 1979), study("МАИ", 13, 324)), chld(fio("Васильев", "Алексей", "Иванович"), dat(24, 07, 1983), dependant("Безработный", 200)) ]). family(fath(fio("Козлов", "Евгений", "Дмитриевич"), dat(29, 07, 1975), work("ТОО Дружба","Экономист", 12500))), moth(fio("Козлова", "Ольга", "Геннадьевна"), dat(21, 09, 1977), dependant("Домохозяйка",0))), []). % пустой список family(fath(fio("Петров", "Денис", "Валентинович"), dat(25, 11, 1952), work("П-ка №61", "Терапевт", 2500))), moth(fio("Петрова", "Алла", "Алексеевна"), dat(04, 02,1952), work("шк. №866", "Учитель", 1500)),
% список из одного структурированного элемента – один ребёнок в семье
[chld(fio("Петрова", "Лада", "Денисовна"), dat(16,01,1971), work("СМУ N71 ","Секретарь",4532))]).
zapros1:- % фамилии, имена и отчества всех неработающих мам. family(_, moth(Mama, _, dependant(_, _)), _), write(Mama), nl, fail; true.
% Вывести информацию обо всех детях.
zapros2:- family(_, _, Baby), write(Baby), nl, fail; true.
30
Задания для лабораторной работы №3
Часть 1. Улучшение структурированных баз данных с
альтернативных
доменов и списковых структур данных
помощью
Необходимо создать базу данных с использованием альтернативных домен-
ных структур и встроенного механизма разработки списков. Для заполнения базы
данных возможно использовать материал 2-й лабораторной работы.
1. Разработать базу данных «семья», предусмотрев различные варианты за-
нятости для членов семьи, а также возможность представления семей с различ-
ным количеством детей и неполных семей.
2. Разработать базу данных «анкета», содержащую альтернативные структуры
данных и списки «семейное положение» и «социальный статус».
3. Разработать базу данных «сотрудник», содержащую альтернативные струк-
туры «образование» и «квалификация» и списковое поле «карьера».
4. Разработать базу данных «лицейский служащий» с альтернативной структу-
рой «должность» и со списком предметов (Приложение 3).
5. Разработать базу данных «лицеисты» со списками прозвищ учащихся (При-
ложение 3).
6. Разработать базу данных «расписание сессии», представив её списком
предметов, различая зачёты и экзамены с помощью альтернативных структур.
7. Разработать базу данных «светило» с альтернативным доменом «тип»
(звезда или планета) с соответствующим списком спутников (Приложение 4).
8. Разработать базу данных «Табель о рангах», используя альтернативные
доменные структуры для разных наименований одного чина и списки для пред-
ставления разных чинов, соответствующих одному рангу (Приложение 2).
9. Разработать базу данных «воинские звания и должности», используя аль-
тернативные структуры для должностей или званий в различных родах войск.
10. Разработать базу данных «династия», используя списковый тип данных
для членов семей, а альтернативные домены — для их статуса (Приложение 1).
11. Разработать базу данных «царская династия», используя списковый тип
данных для семей, а альтернативные домены — для статуса (Приложение 1).
12. Разработать базу данных «созвездия звёздного неба», создавая списки
близких названий, а альтернативные домены — для типа (Приложение 4).
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]