Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Работа с базой данных



Реляционная модель предполагает, что база данных — это описание некоторого множества отношений. Пролог-программу можно рассматривать как именно такую базу данных: описание отношений частично присутствует в ней в явном виде (факты), а частично — в неявном (правила). Более того, встроенные предикаты дают возможность корректировать эту базу данных в процессе выполнения программ. Это делается добавлением к программе (в процессе вычисления) новых предложений или же вычеркиванием из нее уже существующих. Предикаты, используемые для этой цели, таковы: assert (добавить), asserta, assertz и retract (удалить).

Цель

assert(С)

всегда успешна, а в качестве своего побочного эффекта вызывает "констатацию" предложения С, т.е. добавление его к базе данных.

Цель

retract(С)

приводит к противоположному эффекту: удаляет предложение, сопоставимое с С. Следующий диалог иллюстрирует их работу:

?- кризис.

no

?- assert(кризис).

yes

?- кризис.

yes

?- retract(кризис).

yes

?- кризис.

no

Предложения, добавленные к программе таким способом, ведут себя точно так же, как и те, что были в "оригинале" программы. Следующий пример показывает, как с помощью assert и retract можно работать в условиях изменяющейся обстановки. Предположим, что у нас есть такая программа о погоде:

хорошая:-

солнечно, not дождь.

необычная:-

солнечно, дождь.

отвратительная:-

дождь, туман.

дождь.

туман.

Ниже приводится пример диалога с этой программой, во время которого база данных постепенно изменяется:

?- хорошая.

no

?- отвратительная.

yes

?- retract(туман).

yes

?- отвратительная.

no

?- assert(солнечно).

yes

?- необычная.

yes

?- retract(дождь).

yes

?- хорошая.

yes

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

быстр(энн).

медл(том).

медл(пат).

К этой программе можно добавить правило:

?- assert(

(быстрее(X, Y):-

быстр(X), медл(Y))).

yes

?- быстрее(А, В).

А = энн

В = том

?- retract(медл(X)).

X = том;

X = пат;

?- быстрее(энн, _).

Заметьте, что при добавлении нового правила синтаксис требует, чтобы оно (как аргумент assert) было заключено в скобки.

При добавлении нового предложения может возникнуть желание указать, на какое место в базе данных его следует поместить. Такую возможность обеспечивают предикаты asserta и assertz. Цель

asserta(С)

помещает С в начале базы данных. Цель

assertz(С)

— в конце. Вот пример, иллюстрирующий работу этих предикатов:

?- assеrt(p(a)), assertz(p(b)), asserta(p(c)).

yes

?- p(X).

X = с;

X = а;

X = b

Между consult и assertz существует связь. Обращение к файлу при помощи consult можно в терминах assertz определить так: считать все термы (предложения) файла и добавить их в конец базы данных.

Одним из полезных применений предиката asserta является накопление уже вычисленных ответов на вопросы. Пусть, например, в программе определен предикат

решить(Задача, Решение)

Мы можем теперь задать вопрос и потребовать, чтобы ответ на него был запомнен, с тем чтобы облегчить получение ответов на будущие вопросы:

?- решить(задача1, решение),

asserta(решить(Задача1, Решение)).

Если в первой из приведенных целей будет успех, ответ (Решение) будет сохранен, а затем использован так же, как и любое другое предложение, при ответе на дальнейшие вопросы.

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

Развитие этой идеи состоит в использовании assert для порождения всех решений в виде таблицы фактов. Например, создать таблицу произведений всех чисел от 0 до 9 можно так: породить пару чисел X и Y, вычислить Z, равное X * Y, добавить эти три числа в виде строки в таблицу произведений, а затем создать искусственно неуспех. Неуспех вызовет возврат, в результате которого будет найдена новая пара чисел, и в таблицу добавится новая строка и т.д. Эта идея реализована в процедуре

таблица:-

L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],

принадлежит(X, L), % Выбрать первый сомножитель

принадлежит(Y, L), % Выбрать второй сомножитель

Z is X*Y,

assert(произв(X,Y,Z)),

fail.

Вопрос

?- таблица.

потерпит, конечно, неудачу, однако в качестве своего побочного эффекта приведет к добавлению в базу данных целой таблицы произведений. После этого можно, например, спросить, какие пары дают произведения, равные 8:

?- произв(А, В, 8).

А = 1

В = 8;

А = 2

В = 4;

...

Здесь следует сделать одно замечание, относящееся к стилю программирования. Приведенные примеры показали некоторые явно полезные применения assert и retract. Однако использование этих отношений требует особой внимательности. Не рекомендуется применять их слишком часто и без должной осторожности - это плохой стиль программирования. Ведь добавляя и удаляя предложения, мы фактически изменяем программу. Поэтому отношения, выполнявшиеся в некоторой ее точке, могут оказаться неверными в другой. В разные моменты времени ответы на одни и те же вопросы будут различными. Таким образом, большое количество обращений к assert и retract может затемнить смысл программы и станет трудно разобрать, что истинно, а что — нет. В результате поведение программы может стать непонятным, трудно объяснимым, и вряд ли можно будет ей доверять.





Дата публикования: 2015-10-09; Прочитано: 194 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.008 с)...