Нельзя предусмотреть заранее все пути доступа к базе данных, которые могут понадобиться пользователям. Однако, поскольку генерация базы данных с помощью модуля BEGIN осуществляется пользователем самостоятельно, он может обеспечить необходимые для него средства доступа.
Как уже было отмечено, режимы чтения и модификации данных часто предусматривают выполнение одних и тех же действий и иногда полиостью совпадают. Рассмотрим в качестве примера базу данных для фирм, торгующих строительными материалами. Пользователю в ряде случаев удобно держать информацию о приобретенных и проданных материалах отдельно от сведений о действительном количестве этих материалов, находящихся в данный момент времени на складе. В таком случае с отношениями in и out можно использовать отношение stock, которое изменяло бы значения, соответствующие количествам различных материалов на складе. При другом варианте построения базы данных можно отказаться от раздельного хранения сведений о приобретении и продаже материалов. Вместо этого данные о торговых операциях можно суммировать с числами, характеризующими количество материалов на складе, но с разными знаками: с плюсом в случае приобретения и с минусом в случае продажи.
Ниже приводится программа пользователя, созданная с помощью модулей BEGIN и UPDATE. В данной программе 5.7 сведения о приобретении и. продаже хранятся отдельно.
Программа 5.7
fields (sand cement bricks)
zeroes( ∅ ∅ ∅)
keys (McDoo Fee Home)
in rels out
McDoo in (6 ∅ 15 5 ∅ ∅)
Fee in (2 ∅ ∅ 55 18 ∅ ∅)
Home in (5 ∅ ∅ 12 ∅ 3 ∅ ∅ ∅)
McDoo out (2 ∅ 4 25 ∅)
Fee out (9 ∅ 1 ∅ 55 ∅)
Home out (2 ∅ ∅ 7 ∅ 19 ∅ ∅)
Программа 5.8 позволяет определить количество любого строительного материала, находящегося в настоящее время на складе. Программа может, например, работать следующим образом:
all (x: McDoo stock x)
Определить все (х: McDoo имеет-на-складе х)]
(4 ∅ sand)
[4 ∅ песок]
(11 cement)
[11 цемент]
(25 ∅ bricks)
[25 ∅ кирпичи]
No (more) answers
[Ответов (больше) нет]
С помощью данной программы можно также получать количество какого-либо строительного материала у определенного торговца. Например, чтобы получить количество песка у торговце, необходимо выполнить следующую команду:
all (x: Fee stock (x sand)
[определить все (х.; Fee имеет-на-складе (х песок))]
11 ∅
No (more) answers
[Ответов (больше) нет]
Упражнение 5.9
Напишите запросы для получения:
1) имей торговцев, на складе которых более 400 кирпичей (получить также число кирпичей у этих торговцев);
2) имей торговцев, имеющих песка больше, чем у Fee; определить также, сколько песка на складах у этих торговцев;
3) количество песка и цемента у каждого торговца.
Приведенные выше отношения match и stock должны быть присоединены к модулю UPDATE, служащему одновременно o для чтения и модификации информации в базе данных.
Отношение match позволяет находить соответствующие друг другу элементы списков in и out для того, чтобы затем можно было вычислить количество определенного материала на данном складе. Указанное отношение может быть эффективно использовано, например, в том случае, когда в базе данных хранятся лишь итоговые величины. Последовательность действий при этом следующая: чтение данных, соответствующих введенным, затем вычисление их новых значений и, наконец, запись новых значений в базу данных. Для реализации указанных операций предназначены два отношения, описанные в программе 5.8.
Программа 5.8
change (X Y Z) if
(key X rel Y change Z) is-told and
changel(XYZ)
changel (XYZ) if
(X Y x) delete and
у isall (y: (z XI) match (x Z) and SUM (X1 z y)) and
Y1 isall (Y1: Y1 ON y) and
(XY Y1) add and
Для практического использования отношений из программ 5.7 и 5.8 они должны быть оформлены в виде отдельного модуля с именем, отличающимся от других рассмотренных выше модулей. Новый модуль может быть назван, например, ACCESS.
Ниже приводится распечатка программы с базой данных, созданной с помощью модулей BEGIN и UPDATE. Эту базу данных можно использовать для проверки правильности работы модуля ACCESS. В ней содержатся сведения о количестве книг разного вида, предлагаемых несколькими книготорговыми фирмами.
keys (York Luton Leeds Bath Bury Hull) in rels out
Luton in (1 ∅ ∅ 7 ∅ 12 ∅ 85 7 ∅ 2 ∅ ∅ 9 ∅ 5 ∅)
Leeds in (8 ∅ 6 ∅ 6 ∅ 7 ∅ 5 ∅ 4 ∅ 6 ∅ 3 ∅)
Bath in (5 ∅ 3 ∅ 3 ∅ 4 ∅ 2 ∅ 5 ∅ 5 ∅ 2 ∅)
Hull in (2 ∅ 3 ∅ 25 25 4 ∅ 2 ∅ 2 ∅ 2 ∅)
York in (25 25 4 ∅ 3 ∅ 3 ∅ 35 4 ∅ 15)
Bury in (25 1 ∅ 1 ∅ 2 ∅ 2 ∅ 3 ∅ 25 3 ∅)
York out (3 7 9 2 12 16 23 12)
Bath out (13 21 11 24 9 33 8 7)
Bury out (9 5 3 14 9 19 23 7)
Leeds out (32 3 ∅ 27 45 2 ∅ 19 39 18)
Hull out (6 4 9 8 2 3 7 4)
Luton out (35 22 68 41 27 1 ∅4 52 18)
Для работы с базой данных достаточно уметь обращаться к ней при помощи отношений stock и change, что, как можно было заметить, не представляет труда даже для неподготовленного пользователя.
С помощью отношения change пользователь определяет, к какому отношению базы данных (in или out) принадлежит изменяемая запись, указывает соответствующий ей ключ и вводит данные, необходимые для модификации этой записи. Отношение changel осуществляет поиск в базе данных информации, соответствующей списку, введенному с помощью отношения change, а затем суммирует найденные и введенные данные, получая в результате исправленный список данных. Отношение isall используется в рассмотренном отношении changel дважды.
Итак, прежде чем приступить к практическому использованию приведенной выше базы данных со сведениями о книготорговых фирмах, необходимо оформить программу ACCENS в виде модуля, добавив к списку экспорта имена отношений stock и change и присоединив к списку экспорта модуля UPDATE имя отношения isall.
Ниже приводятся возможные варианты запросов к базе данных:
all (x у: х stock у)
Luton (65 computers)
Luton (48 science)...
all (x y: x stock (y cookery))
Luton 44
Leeds 25
all (x у z: x stock (y z) and у LESS 10)
Bath 9 science
York 3 war...
В результате следующего диалога в базу данных будут внесены изменения:
all (x: change x)
key х rel у change x ? just Luton out ( ∅ ∅ ∅ 2 5 22 8 5)
(Luton out ( ∅ ∅ ∅ 2 5 22 8 5)
No (more) answers
В том, что изменения внесены правильно, можно убедиться с помощью следующего запроса, позволяющего вывести содержимое базы данных на экран:
all (x: Luton out x)
(35 22 68 43 32 126 6 ∅ 23)
all (x: Luton stock x)
(65 computers)
(48 science)
(52 gardening)
(42 cookery)...
Над информацией; хранящейся в рассматриваемой базе данных, можно выполнить операции сравнения. Приведенный ниже при-' мер демонстрирует эту возможность:
all (х у: х stock (у war) and Leeds stock (z war) and у LESS z)
[определить все (x у: х имеет-на-складе (у книг-о-войне) и
Leeds имеет-на-складе (z книг-о-войне) и у LESS z)]
YORK 3
No (more) answers
[Ответов (больше) нет]
В рассмотренных выше примерах, связанных с информацией о книготорговых фирмах, все изменения описывались положительными числами. Однако возможны случаи, когда изменения удобно представлять в виде отрицательных чисел. Такие ситуации могут возникнуть, когда фирме приходится принимать книги, возвращаемые по той или иной причине покупателем, или, в другом случае, самой возвращать книги другой фирме, у которой они были ранее приобретены. Приведенный ниже пример иллюстрирует второй из указанных случаев, который может возникнуть, когда, например, фирма (Bury) замечает спад покупательского интереса к романтической литературе.
all (: change x)
key X rel Y change Z ? just Bury in ( ∅ ∅ ∅ ∅ ∅ -25 ∅ ∅)
No (more) answers
Теперь можно убедиться в корректности внесенных изменений следующим образом:
all (x: Bury in x)
(25 1 ∅ 1 ∅ 2 ∅ 2 ∅ 5 25 3 ∅)
No (more) answers
Упражнение 5.10
Составьте запросы, позволяющие определить:
1) сколько книр-вестернов имеется у каждой фирмы;
2) названия фирм, у которых книг по садоводству больше, чем у фирмы York;
3) названия всех тех фирм, которые имеют больше книг по кулинарии, чем по садоводству;
4) общее количество художественной литературы у каждой фирмы.
Упражнение 5.11
Составьте запросы, позволяющие достаточно просто получить следующие сведения:
1) объемы поступлений и продаж по всем видам литературы, а также общее число книг на складе для некоторой фирмы;
2) число книг-веетернов, проданных данной фирмой;
3) прибыль, полученную данной фирмой в результате продажи определенного вида литературы при условии, что известны цены, по которым книги были куплены и проданы.
Выполнив предложенные выше уиражения, читатель, вероятно, смог убедиться в том, что сформировать запросы для получения сведений о поступлении на складе и продаже книг какой-либо одной тематики не вызывает особых затруднений. Однако сделать запрос о суммарных показателях по нескольким тематикам [см. упражнения 5.11, (1) и (3)] гораздо сложнее. Следует отметить, что именно запросы такого вида часто используются при обращениях к базам данных. В программе 5.9 приведены несколько дополнительных отношений, облегчающих составление запросов указанного типа. Эти отношения, а также предложения, позволяющие упростить определение тематик проданных и купленных книг, могут быть присоединены к модулю ACCESS.
Отношение tot первоначально определяет, что сумма элементов нужного списка равна нулю. Затем с помощью хвостовой рекурсии вычисляется сумма всех элементов списка. Следующие три отношения, использующие tot, служат для получения объемов поступлений, продаж и имеющейся в текущий момент на складе литературы. Запрос может быть, например, таким:
all (х у: х in z and z tot у)
Программа 5.9
() tot ∅
(XY)totZif
Y tot x and
SUM(XxZ)
X in-tot Y if
X in Z and
Z tot Y
X out-tot Y if
X out Z and
Z tot Y
X stock-tot Y if
X in-tot Z and
X out-tot x and
SUM(YxZ)
X in-type (Y Z) if
X in x and
fields у and
(Y Z) match (x y)
X out-type (Y Z) if
X out x and
fields у and
(Y Z) match (x y)
С помощью отношений in-type и out-type можно для каждой фирмы получить объемы поступившей и проданной литературы определенной тематики. Например:
all (х у: Hull in-type (x у))
2 ∅ computers
3 ∅ science ...
Следует отметить, что рассмотренная выше программа может использоваться для работы с базой данных, содержащей сведения о приобретении и продаже каких-либо других предметов или материалов. Ниже приводится несколько запросов, демонстрирующих возможности рассмотренных отношений.
1. Определить количество научной литературы на складе каждой фирмы.
all (x у: х out-type (у science))
York 7
Bath 21
2. Найти фирмы, продавшие кулинарных книг больше, чем Bury.
all (х у: Bury out-type (z cookery) and x out-type (y cookery) and z
LESS y)
Bath 24
Leeds 45 ...
3. Найти фирмы, продавшие книг каждого типа меньше, чем это сделал Hull.
all (х у z: Hull out-type (X z) and x out-type (y z) and у
LESS X)
York 3 computers
Bury 3 gardening ...
4. Найти фирмы, продавшие больше книг по садоводству, чем по кулинарии.
all (x у z: х out-type (у gardening) and x out-type (z cookery) and
z LESS y)
York 9 2
Hull 9 8
Упражнение 5.12
Составьте запроси для получения:
1) названий фирм, имеющих на складе книг по вычислительной технике больше, чем York;
2) названий фирм, продавших книг каждой тематики больше, чем имеется таких же книг на складе фирмы Hull; найти и число проданных ими книг по соответствующим тематикам;
3) названий фирм, на складе которых книг любой тематики больше, чем книг по вычислительной технике, проданных фирмой Luton (найти также число и тематику книг);
4) названий фирм, продавших книг по любой тематике больше общего количества книг, имеющегося у фирмы Hull (определить также число и тематику книг).
Программе 5.10
X max if
X ON Y and
(forail Z ON Y and not Z EQ X then Z LESS X)
X min Y if
X ON Y and
(forail Z ON Y and not Z EQ X then X LESS Z)
X ave Y if
Y tot Z and
Y items x and TIMES (xXZ)
() items ∅
(X Y) items Z if
Y items x and
SUM (x 1 Z)
frac(XYZ)if
TIMES (XZY)
percent (X Y Z) if
frac (x Y Z) and
TIMES (1 ∅ ∅ xX)
В программе 5.10 приведены другие полезные для работы с базой данных отношения: нахождение наибольшего и наименьшего элементов списка, среднего арифметического, а также относительной величины элемента списка, выраженной в процентах.
Ниже помещены примеры использования новых отношений.
1. Определить для каждой фирмы тематику книг, пользующихся наибольшим спросом:
all (х у z: х out X and у max X and x out-type (y 2))
York 23 western
Bath 33 romance
2. Определить число полей в запиеях базы данных.
all (x: fields у and у items x)
8
No (more) answers
3. Определить для каждой фирмы тематику книг, объем продажи которых ниже среднего уровня продажи для данной фирмы.
all (х у z: х out X and Y ave X and x out-type (y z) and у LESS Y)
York 3 computers0
York 7 science ...
Если пользователю приходится часто обращаться к базе данных с какими-либо однотипными, но сложными по форме запросами, то в этом случае к программе следует добавить отношение, позволяющее проще описывать запросы такого типа. Например, приведенное ниже отношение облегчает ввод запросов для получения суммарных объемов проданных книг по нескольким фирмам.
1) процентную долю проданных какой-либо фирмой книг по отношению к общему объему продажи;
2) общее число книг определенной тематики, проданных несколькими фирмами;
3) процентную долю общего количества книг одной тематики, проданных несколькими фирмами, по отношению к общему для этих фирм объему продажи книг;
4) тематику книг, пользующихся наибольшим спросом у покупателей;
5) тематику книг, пользующихся у покупателей наименьшим спросом.
Упражнение 5.14
Для обработки некоторых запросов упражнения 5.13 понадобится много времени. Опишите способы ускорения процесса получения ответа. Какими преимуществами и недостатками они обладают.
При выполнении последнего упражнения читатель должен был еще раз убедиться в том, что отношения, служащие для чтения и обновления базы данных, в значительной степени зависят от того, как база данных используется.
МожНо значительно облегчить работу с базой данных, если включить в программу отношения, позволяющие упростить вид часто вводимых запросов. Так, например, для пользователей рассмотренной выше базы данных были бы удобны отношения, предназначенные для получения выражения в процентах показателей торговых, операций и различных итоговых величин.
Расчет итоговых показателей часто требует больших затрат времени. В таких случаях целесообразнее хранить указанные показатели в базе данных, определив их значения заранее.
В некоторых прикладных задачах даже небольшие изменения необходимо, вносить в базу данных немедленно. Такой режим работы с базой данных используется, например, в системе резервирования авиабилетов, когда в каждый момент времени нужны самые последние сведения о проданных и возвращенных билетах. В случае базы данных для книготорговых фирм такая оперативность совершенно не нужна. Сведения, хранящиеся в ней, могут понадобиться лишь при планировании закупок и продаж, производящемся не столь уж часто.
Большая часть моделей микроЭВМ не может обеспечить ни достаточно высокой скорости обработки запросов, ни доступа к базе данных сразу нескольких пользователей. Поэтому для построения систем резервирования авиабилетов ЭВМ этого класса не годятся. Для микроЭВМ больше подходят задачи, где обновление информации производится с достаточно большими интервалами времени, например, ежедневно или раз в неделю, как в случае рассмотренной выше базы данных для книготорговых фирм. При таком режиме обновления информации вычисление и занесение в базу данных некоторых итоговых показателей реализовать будет несложно. Однако за ускорение процесса получения итоговых данных приходится расплачиваться увеличением объема памяти, занимаемой базой данных.
Ниже приводится полный текст программы, предназначенной для модификации и чтения записей базы данных книготорговых фирм (программа 5.11). В данной программе объединены отношения, имеющиеся в программах с 5.7 по 5.10, а также отношения, обеспечивающие более быстрое получение ответов на запросы, аналогичные тем, что нужно было получить в упражнениях 5.13 и 5.14. С помощью данной программы пользователь может изменять различные поля базы данных. После этого программа выполняет расчет различных итоговых показателей, таких, например, как общий объем книг, проданных каждой фирмой, общий объем продажи книг по каждой тематике, а также различных показателей, выраженных в процентах.
Поскольку указанные расчеты требуют довольно много вычислений, соответствующие процедуры будут выполняться долго.
Поэтому модификацию рассмотренной базы данных следует проводить через определенные промежутки времени и вводить сразу все накопленные к данному моменту исправления. Об окончании ввода пользователь сигнализирует, отвечая на запрос Пролог-системы сообщением just (последний ответ) или по (ответов больше
Данная программа занимает довольно много места, поэтому, чтобы сэкономить память, следует ввести в Пролог-систему команду "KILL errmes-mod" и удалить ненужные отношения модулей program-mod и query-mod так, как было описано выше.
Программе 5.11
(X Y) match ((X|Z)(Y|x))
(XY)match((Z|x)(y|z))if
(XY) match (xz)
X stock (Y Z) if
fields x and
in (X y) and
out (X z) and
(Z X1) match (xy) and
(Z Y1) match (xz) and
SUM(Y1 Y X1) change (XYZ) if
(key X rel Y change Z) is-told and
changel(XYZ) change X if
outtot KILL and
intot KILL and
salestot KILL and
soldpercent KILL and
typesales KILL and
allsales KILL and
seller KILL
change X if
out (XY) and
Y tot Z and
(X outtot Z) add and
in (X x) and
x tot у and
(X intot y) add
change X if
Y isall (Y: outtot (Z Y)) and
Y tot X and
(X salestot) add
change X if
salestot (Y) and
outtot (X Z) and
percent (x Z Y) and
(X soldpercent x) add
X change У if
X field and
Y isall (Y: Z outtype (Y X)) and
(X typesales Y) add
X change Y if
typesales (X Z) and
Z tot Y and
(X allsales Y) add (X Y)
change (Z x) if
у isall (y: allsales (X y)) and
Z max у and
x min у and
allsales (X Z) and
allsales (Y x) and
(seller (X Z Y x)) add and
/
changel(XYZ)if
(XYx) delete and
у isall (y: (z XI) match (x Z) and
SUM (X1 z y)) and
Y1 isall (Y1:Y1 ON y) and
(XY Y1) add and
/
() tot ∅
(X|Y) tot Z if
Y tot x and
SUM(XxZ)
X max Y if
X ON Y and
(forall Z ON Y and not Z EQ X then Z LESS X) and
/
X min Y if
X ON Y and
(forall Z ON Y and not Z EQ X then X LESS Z) and
/
X ave Y if
Y tot Z and
Y items x and TIMES (x X Z) and
/
() items ∅
(X|Y) items Z if
Y items x and
SUM (x 1 Z) and
/
percent (X Y Z) if
TIMES (x Z Y) and
TIMES (1 ∅ ∅ xX) and
/
X stocktot Y if
intot (X Z) and
outtot (X x) and
SUM(YxZ)
X intype (Y Z) if
in (X x) and
fields у and
(Y Z) match (x y)
X outtype (Y Z) if
out (X x) and
fields у and
(Y Z) match (x y)
X field if
fields Y and
X ON Y
X key if
keys Y and
X ON Y
С помощью данной программы можно, например, обрабатывать информацию, хранящуюся в ранее рассмотренной базе данных для книготорговых фирм, содержащих отношения in, out, fields, keys и rels. Ниже приводится пример диалога пользователя с программой 5.11:
all (: change x)
[определить все (: изменения х)]
key X rel Y change Z ? ans Luton out (2 ∅ 1 ∅ 12 25 1 ∅ 3 ∅ 2 ∅ 1 ∅)
[ключ X отношение Y изменение Z ? ответ Luton продал (2 ∅ 1 ∅ 15 25 1 ∅ 3 ∅ 2 ∅ 1 ∅)]
key X rel Y change Z ? just Leeds out (5 55 1 ∅ 8 6 5 3)
[ключ X отношение Y изменение Z ? последний-ответ Leeds продал (5 5 5 1 ∅8 6 5 3)]
...
...
No (more) answers
[Ответов (больше) нет]
Многоточиями здесь отмечены пустые строки, генерируемые программой после завершения очередного этапа процесса модификации. Если вместо использованного в приведенном примере запроса ввести "all (x : change x)", то вместо пустых строк будут выводиться изменяемые при модификации предложения. Несмотря на то, что описанный процесс выполняется долго, а база данных при этом значительно увеличивается в объеме, ответы на запросы типа тех, что требовались в упражнении 5.13, будут выдаваться практически без промедления, так как теперь после работы данной программы они оказываются заранее занесенными в базу данных.
Приведем краткое описание новых отношений, появившихся в последней рассмотренной программе:
outtot и intot - общий объем закупок и продаж для фирмы
salestot - общий объем продажи для нескольких фирм
soldpercent - выраженное в процентах отношение объема продажи одной фирмы к общему объему продажи
typesales - количество проданных фирмой книг одной тематики
allsales - количество книг одной тематики, проданных несколькими фирмами
seller - число и тематика книг, пользующихся наибольшим и наименьшим спросом
Для того чтобы сохранить изменения, внесенные в базу данных в результате выполнения программы 6.11, программу с базой данных следует оформить в виде модуля, который после того, как модификация завершается, может быть убран из памяти командой KILL. Следует учитывать, что работа с отдельными модулями обеспечивает экономию памяти, а также повышает скорость последовательного доступа к базе данных.
С помощью рассматриваемой программы пользователь может выводить на экран информацию несколькими способами. Самый простой из них заключается в том, чтобы полностью выводить необходимые отношения. Отметим, что для такого способа пользователю не нужно знать структуру программы с базой данных, а о Прологе ему необходимы лишь минимальные сведения. Пользуясь отношениями описанной программы, можно получать различные, в том числе и не совсем тривиальные сведения. Например, следующий запрос позволяет получить общий объем продажи книг по различным тематикам
list allsales
computers allsales 123
science allsales 104
Чтобы найти процент от общего объема продажи для фирмы Вигу, можно воспользоваться таким запросом:
& all (x: Bury soldpercent x)
7.9040852
No (more) answers
Кроме того, зная структуру программы, пользователь может извлекать из базы данных информацию, получение которой заранее не предусмотрено. Ниже приведен пример использования программы для определения тематики самой ходовой книги, объема полученной за нее прибыли и процентной оценки этой прибыли по отношению к общему объему прибыли.
all (х у z: seller (х у | X) and Y salestot and percent (z у Y))
romance 230 2.0426287E1
No (more) answers
Упражнение 5.15
С помощью рассмотренной программы получите следующую информацию:
1) число книг-вестернов, проданных каждой фирмой;
2) названия фирм, получивших прибыль менее 10% по отошению к общему объему прибыли;
3) названия фирм, продавших менее 100 книг;
4) общее число проданных книг по каждой тематике.
Упражнение 5.16
Дополните отношение change предложениями, которые позволяют получать:
1) процентную долю прибыли каждой фирмы по отношению к общей стоимости книг, поступивших в продажу;
2) наибольшее среди всех фирм число проданных книг одной тематики (одновременно выдавать также название фирмы и указанную тематику);
3) процентную долю прибыли некоторой фирмы, которая выручена за книги заданной тематики;
4) процентную долю прибыли некоторой фирмы за книги одной тематики по отношению к общему объему прибыли.