Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


Внутренние (динамические) базы данных




На Прологе легко реализуются реляционные базы данных. Любая таблица такой базы данных может быть описана соответствующим набором фактов, где каждой записи исходной таблицы будет соответствовать один факт, а каждому полю – аргумент предиката, реализующего таблицу. Turbo Prolog имеет встроенные средства для работы с внутренними и внешними базами данных. Внутренние базы данных обрабатываются исключительно в оперативной памяти, в отличие от внешних баз данных. Внутренняя база данных состоит из фактов, которые можно динамически в процессе выполнения программы добавлять в базу данных и удалять из неё, сохранять в файле и загружать факты из файла. Эти факты могут использовать только предикаты, описаные в разделе описания предикатов базы данных.

DATABASE [ — <имя базы данных>]

<имя предиката>(<имя домена первого аргумента>,...,

< имя домена n-го аргумента>)

...

 

Если раздел описания базы данных в программе только один – то он может не иметь имени (стандартное имя dbasedom). В базе данных могут содержаться только факты, а не правила вывода. Факты базы данных не могут содержать свободных переменных.

Существуют встроенные предикаты, предназначенные для работы с внутренней базой данных:

Для добавления фактов во внутреннюю базу данных может использоваться один из трёх предикатов:

asserta – добавляет факт перед другими фактами.

assertz – добавляет факт после других фактов.

assert – добавлен для совместимости с другими версиями Пролога и работает точно так же, как и assertz.

Для удаления служат предикаты retract и retractall. Чтобы удалить всё используется retractall с анонимной переменной.

Для сохранения динамической базы на диске служит предикат save – сохранение в текстовый файл.

Факты, сохранённые в текстовом файле на диске, могут быть загружены в оперативную память предикатом consult.

Каждый факт в таком файле должен занимать отдельную строку, количество аргументов и их тип должны соответствовать описанию предиката в разделе database.

Пример. Программа, реализующая компьютерный вариант телефонного справочника. Находит по фамилии человека его телефонный номер или, наоборот, по телефонному номеру — фамилию владельца телефона. В программе будет 5 операций:

· Получение информации о телефонном номере по фамилии человека.

· Получение информации о фамилии абонента по телефонному номеру.

· Добавление новой записи в телефонную базу.

· Изменение существующей в телефонной базе записи.

· Удаление записи из телефонной базы.

DOMAINS /* раздел описания доменов */

name, number = String /* фамилию абонента и телефонный

номер будем хранить в виде

строк */

file=f /* файловый домен будем использовать для

считывания с диска и записи на диск нашей

телефонной базы */

DATABASE /* раздел описания предикатов внутренней

базы данных */

phone(name, number)

PREDICATES /* раздел описания предикатов */

name_phone(name, number) /* этот предикат находит номер

телефона по фамилии абонента */

phone_name(name, number) /* этот предикат находит фамилию

абонента по номеру телефона */

m(char) /* этот предикат реализует выполнение

соответствующего пункта меню */

menu /* этот предикат реализует вывод меню и

обработку выбора пользователя */

start /* этот предикат проверяет наличие файла

с телефонной базой на диске и либо загружает

факты из нее во внутреннюю базу данных,

если такой файл существует, либо создает

этот файл, если его не было */

CLAUSES /* раздел описания предложений */

name_phone(Name,Phone):–

phone(Name,Phone),!.

name_phone(_,"Нет информации о телефонном номере").

/* если соответствующего факта

во внутренней базе данных не нашлось,

вместо телефонного номера возвращаем

соответствующее сообщение */

phone_name(Name,Phone):–

phone(Name,Phone).

phone_name("Нет информации о владельце телефона",_).

/* если соответствующего факта

во внутренней базе данных не нашлось,

вместо фамилии абонента возвращаем

соответствующее сообщение */

menu:–

clearwindow, /* очистка текущего окна */

write("1– Получение телефонного номера

по фамилии "),nl,

write("2 — Получение фамилии абонента по номеру

телефона "),nl,

write("3 — Добавление новой записи в телефонную

базу."),nl,

write("4 — Изменение номера абонента"),nl,

write("5 — Удаление записи из телефонной базы"),nl,

write("0 — Выйти"),nl,

readchar(C), /* читаем символ с клавиатуры */

m(C). /* вызываем выполнение соответствующего пункта

меню */

m('1'):–

clearwindow,

write("Введите фамлию"), nl,

readln(Name),

name_phone(Name, Phone),

write("Номер телефона: ",Phone),

readchar(_),

menu.

m('2'):–

clearwindow,

write("Введите номер телефона"),nl,

readln(Phone),

phone_name(Name, Phone),

write("Фамилия абонента: ",Name),

readchar(_),

menu.

m('3'):–

clearwindow,

write("Введите фамилию"),nl,

readln(Name),

write("Введите номер телефона"),nl,

readln(Phone),

assert(phone(Name,Phone)),

/* добавляем факт во внутреннюю

базу данных */

menu.

m('4'):–

clearwindow,

write("Введите фамилию"),nl,

readln(Name),

write("Введите новый номер телефона"),nl,

readln(Phone),

retract(phone(Name,_)),

/* удаляем устаревшую информацию

из внутренней базы данных */

assert(phone(Name,Phone)),

/* добавляем новую информацию

в телефонную базу */

menu.

m('5'):–

clearwindow,

write("Укажите номер телефона, запись о котором

нужно удалить из телефонной базы"), nl,

readln(Phone),

retract(phone(_,Phone)), /* удаляем соответствующий

факт из внутренней базы

данных */

menu.

m('0'):–

save("phones.ddb "), /* сохраняем телефонную базу

в файл */

retractall(_)./* удаляем все факты из внутренней

базы данных */

m(_):–

menu. /* если пользователь по ошибке нажал клавишу,

отличную от тех, реакция на которые

предусмотрена, ничего плохого

не произойдет, будет отображено меню

еще раз */

start:–

existfile("phones.ddb"),!, /* если файл с телефонной

базой существует */

consult("phones.ddb "), /* загружаем факты во

внутреннюю базу данных */

menu. /* вызываем меню */

start:–

openwrite(f,"phones.ddb"),

/* если файла с телефонной

базой не существует, создаем

его */

closefile(f),

menu. /* вызываем меню */

GOAL /* раздел внутренней цели*/

Start

 

Пример. Повышение эффективности программ за счет добавления уже вычисленных фактов в базу данных. При попытке вычислить предикат сначала проверяется, нет ли в базе данных уже вычисленного значения, и если оно там уже есть, то просто берется это значение. Если же ответа еще нет, он вычисляется обычным способом, после чего добавляется в базу данных для повторного использования. Эта техника еще называется мемоизация или табулирование.

Базис индукции для первых двух чисел Фиббоначи оставим без изменений. Для шага индукции добавим еще одно правило. Первым делом будем проверять внутреннюю базу данных на предмет наличия в ней уже вычисленного числа. Если оно там есть, то никаких дополнительных вычислений проводить не нужно. Если же числа в базе данных не окажется, вычислим его по обычной схеме как сумму двух предыдущих чисел, после чего добавим соответствующий факт в базу данных.

fib2(0,1):–!. /* нулевое число Фиббоначи равно единице */

fib2(1,1):–!. /* первое число Фиббоначи равно единице */

fib2(N,F):–

fib_db(N,F),!. /* пытаемся найти N-е число

Фиббоначи среди уже

вычисленных чисел, хранящихся

во внутренней базе данных */

fib2(N,F) :–

N1=N–1, fib2(N1,F1), /* F1 это N–1-е число

Фиббоначи */

N2=N–2, fib2(N2,F2), /* F2 это N–2-е число

Фиббоначи */

F=F1+F2, /* N-е число Фиббоначи равно сумме

N–1-го числа Фиббоначи и N–2-го

числа Фиббоначи */

asserta(fib_db(N,F)).

/* добавляем вычисленное N-е число

Фиббоначи в нашу внутреннюю базу

данных*/


Поделиться:

Дата добавления: 2015-04-05; просмотров: 97; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.007 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты