Для быстрого доступа к записям внешней БД в Турбо-Прологе можно использовать деревья. Деревьев во внешней БД может быть несколько, но каждое должно иметь уникальное имя. Работа с деревьями осуществляется следующим образом. Если Вы хотите, чтобы к некоторой записи БД был возможен быстрый доступ, необходимо занести эту запись в любую цепь БД, получить значение ссылки на эту запись и установить для неё уникальный ключ (ключом может быть любая строка символов с ограниченной длиной). Затем, используя предикат key_insert, занести в дерево полученную ссылку на запись по этому ключу. Чтобы получить содержимое записи, с помощью предиката key_search отыскивают по ключу значение ссылки на искомую запись. Имея ссылку на запись, можно получить содержимое этой записи, используя предикат ref_term.
bt_create(СелекторБД,ИмяДерева,СелекторДерева,ДлинаКлюча,
Порядок)
(db_selector,string,bt_selector,integer,integer)
— (i,i,o,i,i)
Предикат создает новое дерево с именем ИмяДерева в БД с логическим именем СелеторБД.Максимальная длина ключей в этом дереве задается параметром ДлинаКлюча (параметр ДлинаКлюча может лежать в интервале от 1 до 255, однако его нужно сделать как можно меньшим, в целях экономии места). Параметр Порядок может лежать в интервале от 1 до 255. Он используется для размещения ключей в дереве по страницам. Обычно порядок принимают равным 16.
Выходным параметром является СелекторДерева, который в дальнейшем используется всеми нижеследующими предикатами для работы с этим деревом.
bt_open(СелекторБД,ИмяДерева,СелекторДерева)
(db_selector,string,bt_selector) — (i,i,o)
Предикат открывает для доступа дерево с именем ИмяДерева, которое уже существует в БД с логическим именем СелекторБД. Выходной параметр СелекторДерева имеет то же назначение, что и в предыдущем предикате.
bt_close(СелекторБД,СелекторДерева)
(db_selector,bt_selector) — (i,i)
Предикат закрывает доступ к дереву, имеющему селектор СелекторДерева, в БД с логическим именем СелекторБД. Используется обычно перед закрытием БД.
bt_delete(СелекторБД,ИмяДерева)
(db_selector,string) — (i,i)
Предикат удаляет дерево с именем ИмяДерева из БД, имеющей логическое имя СелекторБД.
nondeterm db_btrees(СелекторБД,ИмяДерева)
(db_selector,string) — (i,o)
Предикат позволяет получить имена всех деревьев в БД с логическим именем СелекторБД. Работает, как и предикат db_chains.
bt_statistics(СелекторБД,СелекторДерева,ЧислоКлючей,ЧислоСтра-
ниц,Глубина,ДлинаКлюча,Порядок,РазмерСтраницы)
(db_selector,bt_selector,real,real,
integer,integer,integer,integer)
— (i,i,o,o,o,o,o,o)
Предикат позволяет получить статистику по дереву с селектором СелекторДерева, которое находится в БД с логическим именем СелекторБД.
key_insert(СелекторБД,СелекторДерева,Ключ,Ссылка)
(db_selector,bt_selector,string,ref) — (i,i,i,i)
Предикат вставляет в дерево ссылку на запись Ссылка по ключу Ключ.
key_delete(СелекторБД,СелекторДерева,Ключ,Ссылка)
(db_selector,bt_selector,string,ref) — (i,i,i,i)
Предикат удаляет из дерева ссылку на запись Ссылка, которая была занесена по ключу Ключ.
key_first(СелекторБД,СелекторДерева,ПервичнаяСсылка)
(db_selector,bt_selector,ref) — (i,i,o)
Предикат находит ссылку на запись ПервичнаяСсылка, которой соответствует ключ с наименьшим значением.
key_last(СелекторБД,СелекторДерева,ПоследняяСсылка)
(db_selector,bt_selector,ref) — (i,i,o)
Предикат находит ссылку на запись ПоследняяСсылка, которой соответствует ключ с наибольшим значением.
key_search(СелекторБД,СелекторДерева,Ключ,Ссылка)
(db_selector,bt_selector,string,ref) — (i,i,i,o)
Предикат находит ссылку на запись Ссылка, которой соответствует ключ Ключ.
key_current(СелекторБД,СелекторДерева,Ключ,Ссылка)
(db_selector,bt_selector,string,ref) — (i,i,o,o)
Предикат находит текущий Ключ и соответствующую ссылку на запись Ссылка.
key_next(СелекторБД,СелекторДерева,СледующаяСсылка)
(db_selector,bt_selector,ref) — (i,i,o)
Предикат находит ссылку на запись СледующаяСсылка, ключ на которую превышает значение текущего ключа.
key_prev(СелекторБД,СелекторДерева,ПредыдущаяСсылка)
(db_selector,bt_selector,ref) — (i,i,o)
Предикат находит ссылку на запись СледующаяСсылка, ключ на которую меньше значения текущего ключа.
%============================================================
% Пример работы с деревьями внешней БД.
Domains
db_selector = db
пациент = п(фамилия,пол,год_рождения)
фамилия = string
пол = мужчина; женщина
год_рождения = integer
Predicates
занесение_пациента_в_БД(bt_selector,фамилия,пол,
год_рождения)
repeat
печать_следующего_пациента
Clauses
repeat.
repeat:-repeat.
занесение_пациента_в_БД(СелекторДерева,Фамилия,Пол,
ГодРождения):-
chain_insertz(db,»список пациентов»,пациент,
п(Фамилия,Пол,ГодРождения),Ссылка),
str_int(Ключ,ГодРождения),
key_insert(db,СелекторДерева,Ключ,Ссылка).
печать_следующего_пациента:-
key_prev(db,СелекторДерева,Ссылка),!,
ref_term(db,пациент,Ссылка,п(Фамилия,Пол,Год)),
write(Фамилия,»,»,Пол,»,»,Год,»г.»),
nl,!,
fail.
печать_следующего_пациента. % конец списка пациентов
Goal
db_create(db,»MYFILE.DBA»,in_file),
bt_create(db,»дерево»,СелекторДерева,4,16),
занесение_пациента_в_БД(СелекторДерева,»Иванов»,мужчина,
1951),
занесение_пациента_в_БД(СелекторДерева,»Петрова»,женщина,
1956),
занесение_пациента_в_БД(СелекторДерева,»Сидоров»,мужчина,
1961),
key_first(db,СелекторДерева,СсылкаНаСтаршегоПациента),
ref_term(db,пациент,СсылкаНаСтаршегоПациента,
п(ФамилияСтарПац,_,_)),
write(«Самый старший пациент: «,ФамилияСтарПац),nl,
write(«Список пациентов в порядке увеличения их возраста:»),
key_last(db,СелекторДерева,СсылкаНаМладшегоПациента),
ref_term(db,пациент,СсылкаНаМладшегоПациента,
п(ФамилияМладПац,ПолМладПац,ГодРождМладПац)),
write(ФамилияМладПац,»,»,ПолМладПац,»,»,ГодРождМладПац,
«г.»),nl,
repeat,
печать_следующего_пациента,
!,
write(«Конец списка пациентов.\n»),
bt_close(СелекторДерева),
db_close(db).
Задание
Составить ЭС диагностики с внутренней БЗ. Предметную область выбрать самостоятельно (например, диагностика неисправности компьютера, некоторого заболевания, принадлежности животного или растения к некоторому виду, инвестиции, платежеспособность и кредиты и т.п.).
