Базы и банки знаний

Санкт-Петербургский государственный технический университет

Кафедра системного анализа и управления





















РАСЧЕТНОЕ ЗАДАНИЕ



Дисциплина: базы и банки знаний.

Тема: язык Пролог.











Выполнил студент группы 3082/2				        Торопов. К.Д.



Проверил							       			



			                                                     “__”___________2001г.













































Санкт-Петербург 

2001



Содержание.

1.Теоретическая часть……………………………………………………………3.

2.Постановка задачи...........................................................................................…4.

3.Текст программы..................................................................................................4.

4.Выводы.................................................................................................................13.

5.Литература............................................................................................................13.























































































Теоретическая часть.



             Prolog является компиляторно-ориентированным языком программирования высокого уровня и предназначен для программирования задач из области искусственного интеллекта(ИИ) . Как язык программирования ИИ он особенно хорош для создания экспертных систем, динамических баз данных, программ с применением естественно-языковых конструкций; он также может быть использован для других задач общего характера. Prolog имеет окна, цветную графику и интерактивные средства ввода-вывода, что свидетельствует о его максимальном удобстве для пользователя прикладных программ.

             Prolog – это декларативный язык, программы на котором содержат объявления логических взаимосвязей, необходимых для решения задачи. Обозначения, используемые в Prolog для выражения логических взаимосвязей, унаследованы из логики предикатов.

            Prolog имеет внутренние подпрограммы для выполнения сопоставления и связанных с ним процессов. Они являются неотъемлемой частью языка и называются внутренними подпрограммами унификации. Эти подпрограммы выполняют сопоставление целей и подцелей с фактами и головами правил для того , чтобы доказать (или вычислить) эти цели или подцели. Эти же подпрограммы определяют, сгенерированы ли новые подцели правой части правила. Программист в соответствии с логическим синтаксисом Prolog объявляет, какие факты и правила дают тот или иной результат при различных подцелях, а внутренние подпрограммы унификации выполняют оставшуюся часть работы.

            Факты и правила являются утверждениями, которые образуют данные программы на Prolog. Правила имеют левую часть и правую часть. Левая часть правила истинна, если истинна правая часть правила. Правила генерируют новые факты, когда все утверждения в теле оказываются вычисленными.

Prolog использует откаты для определения альтернативных путей вычисления цели или подцели. Если подцель оказалась неуспешной, а указатели отката были установлены, то для предыдущей подцели будет сделана попытка добиться успеха, начиная с точки отката.

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

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

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



Постановка задачи.

Требуется написать программу учёта книг – название, автор(или список авторов), год выпуска, издательство. Программа должна позволять найти нужную книгу, добавить/удалить книгу, изменить содержимое нужной записи и сохранить всё в файл.



Текст программы.



DOMAINS

  name,izd,aut=string

  list=aut*

  god=integer

  file=datafile;

       indexfile

  

GLOBAL DATABASE 

  kniga(name,list,izd,god)

PREDICATES

 nondeterm repeat /*повтор*/

 nondeterm menu   /*основное меню*/

 nondeterm menu_modify /*меню модификации*/

 nondeterm process(integer) /*различные операции из перечня меню*/

 nondeterm proc(integer) /*различные операции из перечня меню модификации*/

 nondeterm do_dbase  /*цель*/

 nondeterm dbassert(dbasedom) /*добавление данных*/

 nondeterm dbass(dbasedom,string,string) /*модуль ввода данных*/

 nondeterm readlist(list) /*чтение списка*/

 nondeterm writelist(list) /*вывод списка*/

 nondeterm dbretract(dbasedom) /*удаление данных*/

 nondeterm dbret(dbasedom,string,string)/*модуль удаления данных*/

 nondeterm dbret1(dbasedom,real)/*вспомогательный модуль удаления данных*/

 nondeterm dbread(dbasedom)/*чтение данных*/

 nondeterm dbrd(dbasedom,string,string) /*модуль для выборки данных*/

 nondeterm dbaaccess(dbasedom,real)/*вспомогательный модуль выборки и поиска данных*/

 nondeterm append(list,list,list) /*присоединение списка*/

 nondeterm delete_it(aut,list,list) /*удаление элемента списка*/

 

GOAL

  do_dbase.

  

CLAUSES

/*Диалог с этой базой данных осуществляется по принципу меню.

Основываясь на запросе пользователя, СУБД активизирует 

соответствующие процессы для удовлетворения этого запроса.*/



/*задание цели в виде правила*/

  do_dbase :-

          menu.

  menu:-

     repeat,

     

     nl,

     write("***********************************"),nl,

     write(" 1.Add a book to database        "),nl,

     write(" 2.Delete a book from database"),nl,

     write(" 3.View a book from database  "),nl,

     write(" 4.Modify a book in database  "),nl,

     write(" 5.Quit from this program     "),nl,

     write("***********************************"),nl,

     nl,

     write("Please enter your choice,1,2,3,4,5: "),

     readint(Choice),nl,

     Choice>0,Choice<6,

     process(Choice),

     Choice=5,

     !.

  /*меню модификации*/   

     menu_modify:-

     repeat,nl,

     write("***********************************"),nl,

     write(" 1.Modify name        "),nl,

     write(" 2.Add authors"),nl,

     write(" 3.Delete authors"),nl,

     write(" 4.Modify izdanie"),nl,

     write(" 5.Modify god  "),nl,

     write(" 6.Return to main menu."),nl,

     write("***********************************"),nl,

     nl,

     write("Please enter your choice,1,2,3,4,5,6: "),

     readint(C),nl,

     C>0,C<7,

     proc(C),

     menu.

 /* Добавление информации о книге */    

process(1):-

     write("Enter name  "),

     readln(Name),

     write("Enter authors  "),

     readlist(List),

     write("Enter izdanie  "),

     readln(Izd),

     write("Enter god  "),

     readint(God),nl,

     dbassert(kniga(Name,List,Izd,God)),

     write(Name,"has been added to a database."),nl,!,

     write("Press space bar."),

     readchar(_),!.

     

 /* Удаление информации о книге */ 

 /*если запись существует*/ 

process(2):-

     

     write("Enter name  "),

     readln(Name),

     dbretract(kniga(Name,_,_,_)),

     write(Name,"has been deleted from the DATABASE."),

     nl,!,

     write("Press space bar."),

     readchar(_),!. 

     

  /*если запись не существует*/    

process(2):-

     write("Can't find that book in the database."),nl,

     closefile(datafile),

     closefile(indexfile),nl,!,

     write("Press space bar."),

     readchar(_),!.    

     

  /* Просмотр информации о книге */ 

  /*если запись существует*/  

 process(3):-

     

     write("Enter name  "),

     readln(Name),

     dbread(kniga(Name,List,Izd,God)),nl,

     write("  ",Name),nl,

     writelist(List),nl,

     write("  ",Izd),nl,

     write("  ",God),nl,!,

     write("Press space bar."),

     readchar(_),!.

  /*если запись не существует*/   

 process(3):-

 

     write("Can't find that book in the database."),nl,

     closefile(datafile),

     closefile(indexfile),nl,!,

     write("Press space bar."),

     readchar(_),!.

     

/* Вызов меню модификации */     

 process(4):-

     nl,

     menu_modify.

     

/* Выход из диалога */       

 process(5):-

     write("Press space bar."),

     readchar(_),

     exit.

      

/* Просессы меню модификации */



/* Изменение названия книги */ 

/*если запись уществует*/     

proc(1):-



     nl,write("Запрос: "),nl,

     write("   Название книги: "),

     readln(Name),

     dbread(kniga(Name,List,Izd,God)),nl,

     write("  ",Name),nl,

     writelist(List),nl,

     write("  ",Izd),nl,

     write("  ",God),nl,!,

     write("Enter name  "),

     readln(Name1),

     dbretract(kniga(Name,_,_,_)),nl,

     dbassert(kniga(Name1,List,Izd,God)),

     write(Name,"has been modified in database."),nl,!,

     write("Press space bar."),

     readchar(_),!.

     

/*если запись не существует*/    

proc(1):-



     write("Can't find that book in the database."),nl,

     closefile(datafile),

     closefile(indexfile),nl,!,

     write("Press space bar."),

     readchar(_),!.

        

/*изменение издания*/

/*если запись существует*/       

proc(4):-

     nl,write("Запрос: "),nl,

     write("   Название книги: "),

     readln(Name),

     dbread(kniga(Name,List,Izd,God)),nl,

     write("  ",Name),nl,

     writelist(List),nl,

     write("  ",God,"  ",Izd),nl,!,

     write("Enter Izd  "),

     readln(Izd1),

     dbretract(kniga(Name,_,_,_)),nl,

     dbassert(kniga(Name,List,Izd1,God)),

     write(Name,"has been modified in database."),nl,!,

     write("Press space bar."),

     readchar(_),!.

     

/*если запись не существует*/    

proc(4):-



     write("Can't find that book in the database."),nl,

     closefile(datafile),

     closefile(indexfile),nl,!,

     write("Press space bar."),

     readchar(_),!.

     

/*изменение года выпуска*/

/*если запись сущесвует*/               

proc(5):-



     nl,write("Запрос: "),nl,

     write("   Название книги: "),

     readln(Name),

     dbread(kniga(Name,List,Izd,God)),nl,

     write("  ",Name),nl,

     writelist(List),nl,

     write("  ",God,"  ",Izd),nl,!,

     write("Enter God  "),

     readint(God1),

     dbretract(kniga(Name,_,_,_)),nl,

     dbassert(kniga(Name,List,Izd,God1)),

     write(Name,"has been modified in database."),nl,!,

     write("Press space bar."),

     readchar(_),!.

     

 /*если запись не существует*/    

proc(5):-



     write("Can't find that book in the database."),nl,

     closefile(datafile),

     closefile(indexfile),nl,!,

     write("Press space bar."),

     readchar(_),!.

        

/*добавление списка авторов*/

/*если запись существует*/       

proc(2):-

     

     nl,write("Запрос: "),nl,

     write("   Название книги: "),

     readln(Name),

     dbread(kniga(Name,List,Izd,God)),nl,

     write("  ",Name),nl,

     writelist(List),nl,

     write("  ",Izd),nl,

     write("  ",God),nl,!,

     write("Enter authors: "),

     readlist(List1),

     append(List,List1,List2),

     dbretract(kniga(Name,_,_,_)),

     dbassert(kniga(Name,List2,Izd,God)),

     write(Name,"has been modified in database."),nl,!,

     write("Press space bar."),

     readchar(_),!.

     

/*если запись не существует*/    

proc(2):-

     write("Can't find that book in the database."),nl,

     closefile(datafile),

     closefile(indexfile),nl,!,

     write("Press space bar."),

     readchar(_),!.

     

/*удаление автора*/

/*если запись существует*/              

proc(3):-

     nl,write("Запрос: "),nl,

     write("   Название книги: "),

     readln(Name),

     dbread(kniga(Name,List,Izd,God)),nl,

     write("  ",Name),nl,

     writelist(List),nl,

     write("  ",God,"  ",Izd),nl,!,

     write("Enter author to delete: "),

     readln(Aut),

     delete_it(Aut,List,List1),

     dbretract(kniga(Name,_,_,_)),

     dbassert(kniga(Name,List1,Izd,God)),

     write(Name,"has been modified in database."),nl,!,

     write("Press space bar."),

     readchar(_),!.

     

/*если запись не существует*/    

proc(3):-

     write("Can't find that book in the database."),nl,

     closefile(datafile),

     closefile(indexfile),nl,!,

     write("Press space bar."),

     readchar(_),!.

           

/*возврат в основное меню*/      

proc(6).

     

     

            

/*Повтор*/ 

     repeat.

     repeat:-repeat.

     

/* Правила для работы с БД */      

     dbassert(Term):-

        dbass(Term,"cbook.ind","cbook.dba").

     dbretract(Term):-

         dbret(Term,"cbook.ind","cbook.dba").

     dbread(Term):-

         dbrd(Term,"cbook.ind","cbook.dba"). 

             

/* Правило dbass записывает информацию в файл datafile и модифицирует файл indexfile */

    /*запись данных в уже существующий файл*/       

     dbass(Term,Indexfile,Datafile):-

        /*проверка существования файлов*/   

         existfile(Indexfile),

         existfile(Datafile),

        /*открывает файл данных на добавление*/

         openappend(datafile,Datafile),

         writedevice(datafile),

        /*зпоминает позицию*/  

         filepos(datafile,Pos,0),

        /*добавление записи*/  

         write(Term),nl,

        /*закрыват файл данных*/  

         closefile(datafile),

        /*открывает индексный файл на добавление*/  

         openappend(indexfile,Indexfile),

         writedevice(indexfile),

        /*Запись значения индекса, задаваемого переменной Pos.

        Для записи индекса отводится поле, состоящее из 7 позиций.*/  

         writef("%7.0\n",Pos),

        /*закрывает индексный файл*/  

         closefile(indexfile).

         

     /*если файлы не существуют*/     

     dbass(Term,Indexfile,Datafile):-

         /*создаёт файл данных для записи*/ 

         openwrite(datafile,Datafile),

         writedevice(datafile),

         /*запоминает позицию*/    

         filepos(datafile,Pos,0),

         /*добавление записи*/    

         write(Term),nl,

         /*закрывает файл данных*/

         closefile(datafile),

         /*создаёт индексный файл для записи*/ 

         openwrite(indexfile,Indexfile),

         writedevice(indexfile),

         /*Запись значения индекса, задаваемого переменной Pos.

         Для записи индекса отводится поле, состоящее из 7 позиций.*/

         writef("%7.0\n",Pos),

         /*закрывает индексный файл*/

         closefile(indexfile).

         

 /* Правило dbret удаляет данные из БД */         

     dbret(Term,Indexfile,Datafile):-

         /*открывает файл данных на чтение*/

         openread(datafile,Datafile),

         /*открывает индексный файл на модификацию*/

         openmodify(indexfile,Indexfile),

         /*испльзуется вспомогательный модуль, который осуществляет поиск

         нужной записи и её удаление */

         dbret1(Term,-1),

         /*закрывает файл данных*/

         closefile(datafile),

         /*закрывает индексный файл*/

         closefile(indexfile).

         

     dbret1(Term,Datpos):-

         Datpos>=0,

         filepos(datafile,Datpos,0),

         readdevice(datafile),

         readterm(dbasedom,Term),!,

         filepos(indexfile,-9,1),



         /*Этот предикат вызывает запись на диск содержимого внутреннего  буфера индексного файла. Таким образом dbret1 предотвращает возможность работы с

         данными, которые были удалены до этого.*/

         flush(indexfile),

         writedevice(indexfile),

         writef("%7.0\n",-1),

         readdevice(keyboard),

         writedevice(screen).



     /*осуществляет поиск нужного индекса в индексном файле*/    

     dbret1(Term,_):-

         readdevice(indexfile),

         readreal(Datpos1),

         dbret1(Term,Datpos1).

         

/* Правило dbrd извлекает информацию из файла datafile */          

     dbrd(Term,Indexfile,Datafile):-

         openread(datafile,Datafile),

         openread(indexfile,Indexfile),



         /*испльзуется вспомогательный модуль dbaaccess, осуществляющий

         поиск и выборку данных из файла БД*/   

         dbaaccess(Term,-1),

         closefile(datafile),

         closefile(indexfile).



     /*Этот предикат читает данные, логически связанные со значением индекса,

     задаваемым переменной Datapos.*/    

     dbaaccess(Term,Datpos):-

         Datpos>=0,

         filepos(datafile,Datpos,0),

         readdevice(datafile),

         readterm(dbasedom,Term).



     /*Это правило пытается найти в базе такую запись, индекс которой   присутствует  в индексном файле. Если индекс находится, то правило успешно; если нет, то неуспешно.В случае успеха переменная Term получает нужные пользователю значения*/ 

     dbaaccess(Term,_):-

         readdevice(indexfile),

         readreal(Datpos1),

         dbaaccess(Term,Datpos1).

         

 /* Правила работы со списками */

 /*Чтение списка*/          

     readlist([H|T]):-

         write("> "),nl,

         readln(H),!,

         readlist(T).

     readlist([]).

 /*Вывод списка*/      

     writelist([H|T]):-

         write(H, " "),

         writelist(T).

         writelist([]).

 /*Присоединение списка*/          

     append([],L,L).

         append([N|L1],L2,[N|L3]):-

         append(L1,L2,L3).

 /*Удаление элемента списка*/         

     delete_it(_,[],[]).

         delete_it(X,[H|T],L):-H=X,!,delete_it(X,T,L).

         delete_it(X,[H|T],[H|L]):-delete_it(X,T,L).           





















Выводы.



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







Литература.

Ц. Ин, Д. Соломон  «Использование Турбо-Пролога» , Издательство «Мир»





11