|
||||
|
Назад | Содержание| Вперёд 7. 4. Работа с базой данных Реляционна...Назад | Содержание| Вперёд 7. 4. Работа с базой данных Реляционная модель предполагает, что базаданных - это описание некоторого множестваотношений. Пролог-программу можно рассматриватькак именно такую базу данных: описание отношенийчастично присутствует в ней в явном виде (факты),а частично - в неявном (правила). Более того,встроенные предикаты дают возможностькорректировать эту базу данных в процессевыполнения программ. Это делается добавлением кпрограмме (в процессе вычисления) новыхпредложений или же вычеркиванием из нее уже существующих. Предикаты, используемые дляэтой цели, таковы: 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( дождь). уes ?- хорошая. yes Добавлять и удалять можно предложения любойформы. Следующий пример показывает, что, крометого, retract может работатьнедетерминировано: используя механизм возвратовс помощью только одной цели retract можноудалить целое множество предложений.Предположим, что в программе, с которой мы"консультируемся", есть такие факты: быстр( энн). медл( том). медл( пат). К этой программе можно добавить правило: ?- assert( ( быстрее( X, Y) :- быстр( X), медл( Y) ) ). yes ?- быстрее( А, В). А = энн В = том ?- retract( медл( X) ). Х = том; X = пат; nо ?- быстрее( энн, _). nо Заметьте, что при добавлении нового правиласинтаксис требует, чтобы оно (как аргумент assert)было заключено в скобки. При добавлении нового предложения можетвозникнуть желание указать, на какое место в базе данных его следуетпоместить. Такую возможность обеспечиваютпредикаты asserta и assertz . Цель asserta( С) помещает С в начале базы данных. Цель assertz( С) - в конце. Вот пример, иллюстрирующий работуэтих предикатов: ?- assеrt( р( a)), assertz(р( b) ), asserta( p( c) ). yes ?- p( X). Х = с; Х = а; Х = b Между consult и assertz существуетсвязь. Обращение к файлу при помощи consultможно в терминах assertz определить так:считать все термы (предложения) файла и добавитьих в конец базы данных. Одним из полезных применений предиката assertaявляется накопление уже вычисленных ответов навопросы. Пусть, например, в программе определенпредикат решить( Задача,Решение) Мы можем теперь задать вопрос и потребовать,чтобы ответ на него был запомнен, с тем чтобыоблегчить получение ответов на будущие вопросы: ?- решить(задача1, решение), asserta(решить( Задача1, Решение) ). Если в первой из приведенных целей будет успех,ответ ( Решение) будет сохранен, а затемиспользован так же, как и любое другоепредложение, при ответе на дальнейшие вопросы. Преимущество такого "запоминания" состоит в том, что на дальнейшие вопросы,сопоставимые с добавленным фактом, ответ будетполучен, как правило, значительно быстрее, чем впервый раз. Ответ будет теперь получен как факт, ане как результат вычислений, требующих, возможно,длительного времени. Развитие этой идеи состоит в использовании assertдля порождения всех решений в виде таблицыфактов. Например, создать таблицу произведенийвсех чисел от 0 до 9 можно так: породить пару чиселХ и Y, вычислить Z, равное Х * 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может затемнить смысл программы и станет трудноразобрать, что истинно, а что - нет. В результатеповедение программы может стать непонятным,трудно объяснимым, и вряд ли можно будет ейдоверять. Упражнения 7. 6. (а) Напишите вопрос к пролог-системе, которыйудаляет из базы данных всю таблицу произв. (b) Измените этот вопрос так,чтобы он удалил из таблицы только те строки, вкоторых произведение равно 0. 7. 7. Определитеотношение копия( Терм, Копия) которое порождает такую копию Терм'а Копия,в которой все переменные переименованы. Этолегко сделать, используя assert и retract. Назад | Содержание| Вперёд |
|
||
Главная | В избранное | Наш E-MAIL | Добавить материал | Нашёл ошибку | Наверх |
||||
|