Тема: Использование составных объектов. Использование альтернативных доменов
Задание 1.
Функтор структуры personal_library в листинге 3.7 имеет имя book. Описание таково:
personal_library = book(title,author,publisher,year)
collector,title,author,publisher = symbol
year = integer
Предикат, использующий эту структуру, определяется так:
collection(collector,personal_library)
Описание содержит два имени объектов. Первое имя относится к обычному объекту, второе - к структуре из нескольких объектов.
Использование доменной структуры упрощает структуру предиката. Если не использовать конструкцию доменной структуры, то программы требовала бы такого описания предиката collection:
collection(collector,title,author,publisher,year)
В этом описании 4 последних объекта обозначают атрибуты книги. Правило, которое оперирует с персональными библиотеками рассматривало бы эти 4 последних объекта как независимые сущности, что сделало бы код программы более сложным.
Данная программа использует внешнюю цель. Для того, чтобы узнать, какие книги принадлежат Смиту, необходимо ввести такое целевое утверждение:
collection(smith,Books).
Объект smith является частным значением из домена collector, а Books - свободной переменной. Цель заключается в отыскании всех книг, принадлежащих Смиту. Результат работы программы с данным целевым утверждением представлен на рисунке 3.11.
Предположим теперь, что Вы хотите знать имена владельцев и названия книг, напечатанных в 1967 году. Цель для поиска этой информации выглядит следующим образом:
collection(Collector,book(Title,_,_,1967)).
Здесь свободными переменными являются уже Сollector и Title. Подчерки (_) указывают на то, что Вас не интересуют объекты с родовыми именами author и publisher. (Напомним, что подчерк замещает собой анонимную переменную.)
Выдача программы представлена на рис. 3.12.
Следующие два упражнения познакомят Вас с использованием целевых утверждений различных типов.
* Упражнения
Вы хотите задать вопрос:
Как зовут коллекционера, которому принадлежит книга под названием "Database.A Primer." ?
Этот запрос в Турбо-Прологе формулируется в виде
collection(Collector,book("Database:A Primer",_,_,_)).
Что получится ?
Задание 2.
Вы хотите задать вопрос:
Каковы названия книг, опубликованных после 1980 года ?
Целевая конструкция для этого вопроса выглядит так:
collection(_,book(Title,_,_,Year)),
Year > 1980.
Что получится ?
Программа "Библиотека" (листинг 3.7) демонстрирует использование доменной структуры с именем personal_library.
Эта структура содержит сведения о книгах из личных собраний.
____________________________
Листинг 3.7
/* Программа: Библиотека Файл: PROG0307.PRO */
/* Назначение: Демонстрация одноуровневого составного */
/* объекта. */
domains
personal_library = book(title,author,publisher,year)
/* персональная библиотека = книга(название,автор,
издательство,год издания) */
collector,title,author,publisher = symbol
year = integer
predicates
collection(collector,personal_library)
/* коллекция (имя коллекционера, библиотека) */
clauses
collection(kahn,
book("The Computer and the Brain",
"von Neumann",
"Yale University Press",1958)).
collection(kahn,
book("Symbolic Logic",
"Lewis Carroll",
"Dower Publications",1958)).
collection(johnson,
book("Database: A Primer",
"C.J.Date",
"Addison-Wesley",1983)).
collection(johnson,
book("Problem-Solving Methods in AI",
"Nils Nilsson",
"McGraw Hill",1971)).
collection(smith,
book("Alice in Wonderland",
"Lewis Carroll",
"The New American Library",1960)).
collection(smith,
book("Fables of Aesop",
"Aesop-Calder",
"Dover Publications",1967)).
/***** конец программы *****/
_____________________________
Практическое занятие №3.
Тема: Арифметика в Турбо-Прологе.
Задание 1.
Турбо-Пролог располагает двумя числовыми типами доменов: целыми и действительными числами. Четыре основные арифметические операции - это сложение, вычитание, умножение и деление. Для их реализации в Турбо-Прологе используются предикаты. Программа "Числа" (листинг 3.11) показывает, как можно при помощи предикатов реализовать эти операции.
Правилами для реализации сложения, вычитания, умножения и деления целых чисел являются
add(X,Y):-
Z = X + Y, write("Sum = ", nl.
substruct(X,Y):-
Z = X - Y, write("Diff = ", nl.
multiply(X,Y):-
Z = X * Y, write("Pro = ", nl.
divide(X,Y):-
Z = X / Y, write("Quo = ", nl.
а четырьмя правилами для реализации сложения, вычитания, умножения и деления действительных чисел -
fadd(P,Q):-
R = P + Q, write("Fsum = ",R), nl.
fsubstruct(P,Q):-
R = P - Q, write("Fdiff = ",R), nl.
fmultiply(P,Q):-
R = P * Q, write("Fpro = ",R), nl.
fdivide(P,Q):-
R = P / Q, write("Fquo = ",R), nl.
Внутренняя цель составлена из последовательности утверждений, использующих эти правила. В ее формулировке присутствуют числовые значения, которые передаются в тела правил.
Очень важно соблюсти соответствие типов данных и типов объектов предикатов.
Отметим, что деление целого числа на целое может дать десятичную дробь. В этом случае все знаки вплоть до десятого являются верными.
Предположим, что Вы хотите сложить четыре десятичных числа. Предикатом для выполнения этой операции служит
sum(real,real,real,real,real)
Напишите правило для сложения четырех чисел. Включите правило и предикат в программу "Числа".
Задание 2.
Запустите эту модифицированную программу и задайте такую внешнюю цель:
sum(3.9,4.6,2.6,9.7,Z).
Каков будет результат ?
____________________________
Листинг 3.11
/* Программа: Числа Файл: PROG0311.PRO */
/* Назначение: Демонстрация реализации арифметики. */
predicates
add(integer,integer).
substruct(integer,integer).
multiply(integer,integer).
divide(integer,integer).
fadd(real,real).
fsubstruct(real,real).
fmultiply(real,real).
fdivide(real,real).
goal
write(" Results"), nl, nl,
add(44,23),
substruct(44,23),
multiply(44,23),
divide(44,23),
fadd(12.65,7.3),
fsubstruct(12.65,7.3),
fmultiply(12.65,7.3),
fdivide(12.65,7.3), nl,
write(" All done, bye!").
clauses
add(X,Y):-
Z = X + Y, write("Sum = ", nl.
substruct(X,Y):-
Z = X - Y, write("Diff = ", nl.
multiply(X,Y):-
Z = X * Y, write("Pro = ", nl.
divide(X,Y):-
Z = X / Y, write("Quo = ", nl.
fadd(P,Q):-
R = P + Q, write("Fsum = ",R), nl.
fsubstruct(P,Q):-
R = P - Q, write("Fdiff = ",R), nl.
fmultiply(P,Q):-
R = P * Q, write("Fpro = ",R), nl.
fdivide(P,Q):-
R = P / Q, write("Fquo = ",R), nl.