Использование составных термов
В Прологе функциональный терм или предикат можно рассматривать как структуру данных, подобную записи в языке Паскаль. Терм, представляющий совокупность термов, называется составным термом. Предикаты, записанные в виде составного терма, называются составной структурой данных. Составные структуры данных в Турбо-Прологе объявляются в разделе domains. Если термы структуры относятся к одному и тому же типу доменов, то этот объект называется однодоменной структурой данных. Если термы структуры относятся к разным типам доменов, то такая структура данных называется многодоменной структурой данных. Использование доменной структуры упрощает структуру предиката.
Пример 12: Необходимо создать БД, содержащую сведения о книгах из личной библиотеки. Зададим составной терм с именем personal_library, имеющим следующую структуру: personal_library= book (title, author, publisher, year), и предикат collection (collector, personal_library). Терм book называется функтором структуры данных. Пример программы, использующей составные термы для описания личной библиотеки и поиска информации о книгах, напечатанных в 1990 году, выглядит следующим образом:
domains
collector, title, author, publisher = symbol
year = integer
personal_library = book (title, author, publisher, year)
predicates
collection (collector, personal_library)
clauses
collection (irina, book («Using Turbo Prolog», «Yin with Solomon», »Moscow, World», 1993)).
collection (petr, book («The art of Prolog», «Sterling with Shapiro», »Moscow, World», 1990)).
collection (anna, book («Prolog: a relation language and its applications», «John Malpas», »Moscow, Science», 1990)).
goal
collection (X, book( Y,_, _, 1990)
Представление данных часто требует наличия большого числа структур. В Прологе эти структуры должны быть описаны. Для более компактного описания структур данных в Прологе предлагается использование альтернативных описаний доменов.
Пример 13: Необходимо создать БД, содержащую сведения о книгах и аудиозаписях из личной библиотеки.
domains
person, title, author, artist, album, type = symbol
thing = book (title, author); record (artist, album, type)
predicates
owns (person, thing)
clauses
owns (irina, book («Using Turbo Prolog», «Yin with Solomon»)).
owns (petr, book («The art of Prolog», «Sterling with Shapiro»)).
owns (anna, book («Prolog: a relation language and its applications», «John Malpas»)).
owns (irina, record («Elton John», «Ice Fair», «popular»)).
owns (petr, record («Benny Goodman», «The King of Swing», »jazz»)).
owns (anna record («Madonna», «Madonna», «popular»»)).
goal
owns (X, record(_, _, «jazz»)
Пример 14:
Создать базу данных о заданной предметной области в виде множества фактов языка Пролог (не менее 5 фактов). Информацию о каждом компоненте БД представить в виде структуры. Разработать набор предикатов, осуществляющих взаимодействие с БД, при помощи которых можно реализовать все типы запросов, приведенные в варианте задания.
Предметная область – расписание движения самолетов. Каждый рейс может быть описан структурой: название авиакомпании, номер рейса, пункт отлета, пункт прилета, время отлета, время прилета, список пунктов промежуточных посадок, список тарифов. Тариф может быть описан структурой: тип класса салона, цена.
Реализовать следующий запрос:
Найти все авиакомпании, у которых время полета меньше заданного.
В приведенном ниже примере используются следующие домены:
list_station-список пунктов промежуточных посадок, list_tariff - список тарифов, name_company - название авиакомпании, number_flight - номер рейса, station_start, station_finish, - пункт отлета, пункт прилета, time_start, time_finish - время отлета, время прилета, type_class - тип класса салона, price – цена.
flight – предикат, описывающий заданную предметную область, q5 – предикат, реализующий запрос.
domains
list_station=symbol*
list_tariff=tariff*
name_company, station_start, station_finish, type_class = symbol
time_start, time_finish, price =real
number_flight=integer
tariff= tar(type_class, price)
predicates
flight (name_company, number_flight, station_start, station_finish, time_start, time_finish, list_station, list_tariff)
q5(real)
clauses
flight ("Company1",1,"Samara","Moscow",18.00,19.30,[],[tar(econom,3000),tar(business,4000)]).
flight ("Company2", 4, "Samara", "Prague", 5.30, 8.30, [], [tar(econom,5000), tar(business,7500)]).
flight ("Company2", 74, "Samara", "Rome", 15.30, 22.00, ["Moscow", "London"], [tar(econom,15000),tar(business,17500)]).
flight ("Company3", 56, "Samara", "Sofia", 3.30, 8.20, ["Moscow", "Minsk"], [tar(econom,10000),tar(business,12000)]).
flight ("Company1", 8, "Samara", "Oslo", 17.30, 23.10, ["Moscow", "Paris"], [tar(econom,5000),tar(business,7500)]).
q5(Time):-flight (Name,_,_,_,Time1, Time2,_,_), abs(Time2-Time1)<Time, write(Name), nl, fail.
goal
q5(4.00).
Пример 15: решить предыдущую задачу с использованием внутренней базы данных. Найденные решения записать в виде фактов внутренней базы данных Пролога. Предусмотреть проверку факта, являющегося ответом на запрос в БД. Если такой факт существует, то выдать его в качестве ответа на запрос. Если такого факта не существует во внутренней базе данных, то запустить запрос на выполнение и записать результат в БД.
domains
list_station=symbol*
list_tariff=tariff*
name_company, station_start, station_finish, type_class = symbol
time_start, time_finish, price =real
number_flight=integer
tariff= tar(type_class, price)
facts
dq5(name_company)
predicates
flight (name_company, number_flight, station_start, station_finish, time_start, time_finish, list_station, list_tariff)
q5(real)
clauses
flight ("Company1",1,"Samara","Moscow",18.00,19.30,[],[tar(econom,3000),tar(business,4000)]).
flight ("Company2", 4, "Samara", "Prague", 5.30, 8.30, [], [tar(econom,5000), tar(business,7500)]).
flight ("Company2", 74, "Samara", "Rome", 15.30, 22.00, ["Moscow", "London"], [tar(econom,15000),tar(business,17500)]).
flight ("Company3", 56, "Samara", "Sofia", 3.30, 8.20, ["Moscow", "Minsk"], [tar(econom,10000),tar(business,12000)]).
flight ("Company1", 8, "Samara", "Oslo", 17.30, 23.10, ["Moscow", "Paris"], [tar(econom,5000),tar(business,7500)]).
q5(_):-dq5(Nameavia), write('*', Nameavia), nl, fail.
q5(Time):-not(dq5(_)), flight (Name,_,_,_,Time1, Time2,_,_), abs(Time2-Time1)<Time, write(Name), nl, assert(dq5(Name)), fail.
goal
q5(4.00); q5(4.00).