Dynamic Database on Turbo Prolog

Theory

Usually the program is Prologue consists of four main program sections. These include:

  • chapter clauses (offers);

  • chapter predicates (predicates);

  • chapter domains (domains);

  • chapter goal (goals).

Chapter clauses is the heart Prologue-programs; it is in this section that the facts and rules that will operate Prologuewhile trying to resolve the purpose of the program.

Chapter predicates is the section in which the predicates and the domains (types) of their arguments are declared.

Chapter domains serves to declare all non-standard domains we use Prologue.

Chapter goal is the section where you put the target Prologue-programs.

Database

The database predicates in Turbo Prolog are described in the section database, which must appear before the predicates section. All statements with predicates described in database are dynamic database.

The database is called dynamic, since during the operation of the program it (the database) can delete any statements contained in it, as well as add new ones. A dynamic database (DBD) can be written to disk and read from it into RAM. The DDB contains only facts, not rules. In a static database, statements are facts and are part of the program code.

Built-in predicates for working with the database

The following predicates are used to add to the database:

  • asserta(fact) // adding to the beginning of the dbasedom database

  • asserta(fact, dbaseName) // adding to the beginning of the database dbaseName

  • assertz(fact) // adding to the end of the dbasedom database

  • assertz(fact, dbaseName) // adding to the end of the database dbaseName

Loading facts from a file:

  • consult(fileName) // upload to dbasedom database

  • consult(fileName, dbaseName) // load into database dbaseName

Removing a fact:

  • retract(fact) // delete from dbasedom database

  • retract(fact, dbaseName) // delete from database dbaseName

Saving the database in a file:

  • save(fileName) // save database dbasedom in file fileName

  • save(fileName, dbaseName) // saving database dbaseName in file fileName

Program description

The database will contain one table, the T-shirt table, whose columns are listed below:

  1. name – name.

  2. Price (RUB) — price in rubles.

  3. Sex – men’s or women’s T-shirt.

  4. Size (International) – The international size of the T-shirt.

  5. Size (Europe) — the European size of the T-shirt.

  6. color – color.

  7. Material – T-shirt material.

  8. Production year – the year of production.

The following features of the program are expected:

  1. Reading a database from a CSV file

  2. Adding a new record to the database;

  3. Delete T-shirt by name;

  4. Changing a record in the database;

  5. T-shirt search by name;

  6. Display all T-shirts in the console;

  7. Saving the database to a CSV file;

  8. Deleting all records from the database;

  9. Exit from the program;

Code

At the very beginning there is a description of all domains, databases and predicates used in the program:

Domains
     name, world, color, sex, material = string % домены строкового типа
     europe, year, price = integer % домены целочисленного типа
	 file = datafile % домен типа file
	 arr = string* % массив из строк
	 integers = integer* % массив из целых чисел
Database
     dt_shirt(name, price, sex, world, europe, color, material, year) % описание предиката БД
Predicates
     repeat % зацикливает кусок кода
     do_mbase % создаёт главное окно программы и вызывает предикат menu
     menu % создаёт меню программы
     process(integer) % ждет ввода номера функции из меню и затем вызывает её
     clear_database % очищение базы данных
     error % сообщает об ошибке
	 read_until_not_integer(integer) % ждет ввода целого числа
	 write_all % вывод всех футболок в командную строку
	 write_all(arr,integers,arr,arr,integers,arr,arr,integers) % вывод всех футболок в командную строку
	 write_all_csv % запись всех футболок в csv файл
	 write_all_csv(arr,integers,arr,arr,integers,arr,arr,integers) % запись всех футболок в csv файл
	 read_rows() % считывает строки из csv файла
	 front_string(string, string, string) % считывание одного значения из csv до разделителя ;
	 read_prov(integer) % ввод номера функции из меню
	 find(integer) % вызов предиката поиска в зависимости от введенного числа
	 find_shirt_name(string) % поиск футболки по имени
	 find_material(string) % поиск футболки по материалу
	 find_name(string) 
	 find_mat(string) 

A little lower is the Goal section, which contains predicates that are called when the program starts:

Goal
     do_mbase. % вызов предиката do_mbase

And finally Clauses. Here I will describe all the rules of the program.

repeat – necessary for looping. Implemented by calling itself:

repeat.
repeat:-repeat.

read_prov – when entering an integer, returns this number, otherwise calls the predicate error:

read_prov(Vibor):- 
                readint(Vibor);

                error,
                Vibor = 0,
                menu.

Menu

Application menu
Application menu

do_mbase – a predicate from which the execution of the program begins. Creates the main window and calls menu.

menu – creates a menu and waits for the user to enter a number from 1 to 9. When entering a number, a predicate is called process, which performs one of nine selected functions:

do_mbase :-
          makewindow(1,11,3," T-SHIRTS DATABASE ",0,0,25,80),
          menu,
          clear_database.

 menu :-
          repeat, clearwindow,
          nl,
          write(" ********************************* "),nl,
          write(" * 1. Read Database from file    * "),nl,
          write(" * 2. Add new T-shirt in DB      * "),nl,
          write(" * 3. Delete T-shirt from DB     * "),nl,
          write(" * 4. Edit T-shirt in DB         * "),nl,
          write(" * 5. Find T-shirt               * "),nl,
          write(" * 6. Show all data              * "),nl,
          write(" * 7. Write Database to file     * "),nl,
          write(" * 8. Delete All DB              * "),nl,
          write(" * 9. Exit                       * "),nl,
          write(" ********************************* "),nl,
          write(" Choose number 1-9 : "),
          read_prov(Vibor),nl,
          process(Vibor),Vibor = 9.

Next, we describe all these functions.

Description of functions

Reading database from csv file

Reading database from csv file
Reading database from csv file

process(1) – creates a window where you can enter the name of the csv file from which we want to read the database. Reading occurs due to the predicate read_rows(). If the database is successfully read, the message “DB successfully read from file.” is displayed. On failure, “Error reading file!” is displayed. Then, in both cases, after pressing the spacebar, it jumps back to the menu.

process(1) :-
          makewindow(2,11,3,"Read data from file",2,20,15,40),shiftwindow(2),		
          write("Input File name (data.csv): "),
          readln(Filename), 
          existfile(Filename),
          openread(datafile, Filename), 
          readdevice(datafile),
          read_rows(),
          closefile(datafile), readdevice(keyboard),
          write("DB successfully read from file."),nl,!,
          write("Press space bar"), readchar(_), 
          removewindow, shiftwindow(1), clearwindow, menu;
  
          write("Error reading file!"), nl, !,
          write("Press space bar."),readchar(_),
          removewindow, shiftwindow(1), clearwindow, menu, fail.

read_rows() – reads the csv file line by line, using eight calls (we have 8 parameters in the database) of the predicate front_string. After reading each row, inserts the resulting values ​​at the end of the database dt_shirtusing the built-in predicate assertz.

front_string(Line, Param, Tail) — reads the line until it encounters the csv separator – ;

Has 3 options:

  1. Line – initial line

  2. Param – part of the string before the first delimiter – ;

  3. Tail – the remaining line after the delimiter – ;

read_rows() :-not(eof(datafile)),
                readln(Line),
                front_string(Line, F1_STR, Tail1), 
                front_string(Tail1, F2_STR, Tail2), str_int(F2_STR, Price),
                front_string(Tail2, F3_STR, Tail3), 
                front_string(Tail3, F4_STR, Tail4), 
                front_string(Tail4, F5_STR, Tail5), str_int(F5_STR, Europe),
                front_string(Tail5, F6_STR, Tail6), 
                front_string(Tail6, F7_STR, Tail7), 
                front_string(Tail7, F8_STR, _), str_int(F8_STR, Year),
                assertz(dt_shirt(F1_STR,Price,F3_STR,F4_STR,Europe,F6_STR,F7_STR,Year)), !, read_rows();
                
                not(eof(datafile)), !,
                write(" ********************************"), nl,
                write(" *        READING ERROR!        * "), nl,
                write(" * REMAINING DATA WAS NOT READ! * "), nl,
                write(" *     SOME MATERIALS ADDED!    * "), nl,
                write(" ******************************** "), nl; !.

front_string("", "", "") :- !.
front_string(Line, Param, Tail) :-frontchar(Line, LineH, LineT), 
                                LineH = ';', !, 
                                Param = "", Tail = LineT;
                                
                                frontchar(Line, LineH, LineT), 
                                LineH <> ';', !, 
                                front_string(LineT, T, Tail), 
                                str_char(LineHS, LineH),	
                                concat(LineHS, T, Param).

Adding a new T-shirt to the database

Adding a new T-shirt to the database
Adding a new T-shirt to the database

process(2) – creates a window where you can enter the parameters of a new T-shirt. Input of numerical values ​​occurs through a predicate read_until_not_integer. After entering all the parameters, they are inserted at the end of the database dt_shirtusing the built-in predicate assertz.

process(2) :-
        makewindow(3,11,3,"Add data",2,20,18,58),shiftwindow(3),
        write("Please, Input T-shirt:"),nl,
        write("Name: "), readln(Name),
        write("Price (RUB): "), read_until_not_integer(Price),
        write("Sex: "), readln(Sex),
        write("Size (International) : "), readln(World),
        write("Size (Europe): "), read_until_not_integer(Europe),
        write("Color: "), readln(Color),
        write("Material: "), readln(Material),
        write("Production year: "), read_until_not_integer(Year),
        assertz(dt_shirt(Name,Price,Sex,World,Europe,Color, Material,Year)),
        write(Name," added to DB"), nl,!,
        write("Press space bar. "), readchar(_),
        removewindow, shiftwindow(1), clearwindow, menu.

read_until_not_integer – checks if the entered value is an integer greater than 0 or not. If not, then it is called again.

read_until_not_integer(Integer):-
        readint(Integer),
        Integer >=0, !;
        
        write("Enter integer number >=0: "),
        read_until_not_integer(Integer).

Removing a T-shirt from the database

Removing a T-shirt from the database
Removing a T-shirt from the database

process(3) – creates a window where you can enter the name of the T-shirt to be deleted. After entering the name of the T-shirt, it is deleted from the database dt_shirtusing the built-in predicate retract.

process(3) :-
        makewindow(4,11,3,"Delete data",10,30,7,40),shiftwindow(4),
        write("Input T-shirt name: "), readln(Name),
        retract(dt_shirt(Name,_,_,_,_,_,_,_)),
        write(Name," removed from DB "), nl, !,
        write("Press space bar."), readchar(_), 
        removewindow, shiftwindow(1);
        
        write("No data."),nl,!,
        write("Press space bar."),readchar(_),
        removewindow, shiftwindow(1).

Change information about a T-shirt

process(4) – creates a window where you can enter the name of the T-shirt, the information about which you want to change. After entering the name of the T-shirt, it is deleted from the database dt_shirtusing the built-in predicate retract. Next, all pairs are introduced

process(4) :-
          makewindow(5,11,3,"Edit data",2,20,18,58),shiftwindow(5),
          write("Input T-shirt name: "), readln(Name1),
          retract(dt_shirt(Name1,_,_,_,_,_,_,_)),
          write("Name: "), readln(Name),
          write("Price (RUB): "), read_until_not_integer(Price),
          write("Sex: "), readln(Sex),
          write("Size (International) : "), readln(World),
          write("Size (Europe): "), read_until_not_integer(Europe),
          write("Color: "), readln(Color),
          write("Material: "), readln(Material),
          write("Production year: "), read_until_not_integer(Year),
          assertz(dt_shirt(Name,Price,Sex,World,Europe,Color, Material,Year)),nl, !,
          write("Press space bar."), readchar(_), 
          removewindow, shiftwindow(1);
          
          write("No data."),nl,!,
          write("Press space bar."),readchar(_),
          removewindow, shiftwindow(1), clearwindow, menu.

Show all information about the T-shirt

1-search by name;  2-search by material
1-search by name; 2-search by material
Search by name (left);  Search by material (right)
Search by name (left); Search by material (right)

process(5) – creates a window where you can choose how to search for the desired T-shirt: 1 – by name or 2 – by material. Then the predicate is called findwhich searches for a T-shirt by the parameter we have chosen and then displays all the information about it.

process(5) :-
        makewindow(6,11,3," Show T-shirt ", 2,30,22,47),  shiftwindow(6),
        write("1. Find T-shirt by Name "),nl,
        write("2. Find T-shirt by Material "),nl, 
        write(" Choose number 1-2 : "),
        read_until_not_integer(N), 
        N>0,N<3,
        find(N),
        write("Press space bar"), readchar(_), 
        removewindow, shiftwindow(1), clearwindow, menu;

        write("Wrong input."),nl,!,
        write("Press space bar."),readchar(_),
        removewindow, shiftwindow(1), clearwindow, menu.

find(1) – it is necessary to enter the name of the T-shirt, information about which we want to receive. After entering the name, the predicate is called find_shirt_nameA that searches the database for a T-shirt. If such a name was found, all information about the T-shirt is displayed in the console. If not, the message “No such T-shirt in database!” is displayed.

find(2) – similar find(1)only now it is necessary to enter the material of the T-shirt we are interested in.

find(1):-clearwindow, write("Input T-shirt name: "), readln(Name),
                  find_shirt_name(Name), find_name(Name).

find(1):-write("No such T-shirt in database!").

find(2):-clearwindow, write("Input T-shirt material: "), readln(Material),
                  find_material(Material), find_mat(Material).

find(2):-write("No such T-shirt in database!").

find(_):-write("Error ").

find_shirt_name(Name):- 
        dt_shirt(Name,Price,Sex,World,Europe,Color, Material,Year),nl,
        write(" Name                : ",Name),nl,
        write(" Price (RUB)         : ",Price),nl,
        write(" Sex                 : ",Sex),nl,
        write(" Size (International): ",World),nl,
        write(" Size (Europe):      : ",Europe), nl,
        write(" Color               : ",Color),nl,
        write(" Material            : ",Material),nl,
        write(" Production year     : ",Year),nl, nl, fail.
find_shirt_name(_).

find_material(Material):-
        dt_shirt(Name,Price,Sex,World,Europe,Color, Material,Year),nl,
        write(" Name                : ",Name),nl,
        write(" Price (RUB)         : ",Price),nl,
        write(" Sex                 : ",Sex),nl,
        write(" Size (International): ",World),nl,
        write(" Size (Europe):      : ",Europe), nl,
        write(" Color               : ",Color),nl,
        write(" Material            : ",Material),nl,
        write(" Production year     : ",Year),nl, nl, fail.
find_material(_).

find_name(Name):-dt_shirt(Name,_,_,_,_,_,_,_).
find_mat(Material):-dt_shirt(_,_,_,_,_,_,Material,_).

Show all records in the database

Show all records in the database
Show all records in the database

process(6) – creates a window in which all database records are displayed on the screen. To do this, use the predicate write_all.

process(6) :-
        makewindow(7,11,3," Show All data ", 0,0,25,80),  shiftwindow(7),
        write("Name, Price(Rub), Sex, Size(Inter.), Size(Europe), Color, Material, Year"),
        nl,
        write("************************************************************************"),
        nl,
        write_all,
        nl,!,
        write("Press space bar."),readchar(_),
        removewindow, shiftwindow(1), clearwindow, menu;
        
        write("No data."),nl,!,
        write("Press space bar."),readchar(_),
        removewindow, shiftwindow(1), clearwindow, menu.

write_all() – uses a predicate findall(X,P,L)which collects in the list L all objects X that satisfy the goal P.

write_all([P1|T1], [P2|T2], [P3|T3], [P4|T4], [P5|T5], [P6|T6], [P7|T7], [P8|T8]) – displays all values ​​found in the database separated by commas.

write_all() :-
    findall(P1, dt_shirt(P1,_,_, _,_,_,_,_), P1s),
    findall(P2, dt_shirt(_,P2,_,_,_,_,_,_ ), P2s),
    findall(P3, dt_shirt(_,_,P3, _,_,_,_,_), P3s),
    findall(P4, dt_shirt(_,_,_,P4,_,_,_,_ ), P4s),
    findall(P5, dt_shirt(_,_,_,_,P5,_,_,_ ), P5s),
    findall(P6, dt_shirt(_,_,_,_,_,P6,_,_ ), P6s),
    findall(P7, dt_shirt(_,_,_, _,_,_,P7,_), P7s),
    findall(P8, dt_shirt(_,_,_, _,_,_,_,P8), P8s),
    write_all(P1s, P2s, P3s, P4s, P5s, P6s, P7s, P8s);
    writedevice(screen).

write_all([], [], [], [], [], [], [], []) :- !.
write_all([P1|T1], [P2|T2], [P3|T3], [P4|T4], [P5|T5], [P6|T6], [P7|T7], [P8|T8]) :-
          write(P1,", ",
          P2," (RUB), ",
          P3,", ",
          P4,", ",
          P5,", ",
          P6,", ",
          P7,", ",
          P8),nl,
          write("------------------------------------------------------------------------"),nl,
          write_all(T1, T2, T3, T4, T5, T6, T7, T8).

Write database to csv file

Write database to csv file
Write database to csv file
Database in CSV file
Database in CSV file

process(7) – creates a window in which you must enter a file name to save the database. After the recorder is put on the file – writedevice(datafile) and the predicate is called write_all_csvAn that writes the database to a file.

process(7) :-
        makewindow(8,11,3," Write Database to file ", 7,30,12,47),  shiftwindow(8),
        write("Input file name (data.csv): "),
        readln(Filename),
        existfile(Filename), % Существует ли файл 
        openwrite(datafile, Filename), 
        writedevice(datafile), 
        write_all_csv,
        closefile(datafile), 
        writedevice(screen),
        write("DB successfully written to file."),
        nl,!,
        write("Press space bar."),readchar(_),
        removewindow, shiftwindow(1), clearwindow, menu;
        
        write("Error writing file!"),nl,!,
        write("Press space bar."),readchar(_),
        removewindow, shiftwindow(1), clearwindow, menu.

write_all_csv() – arranged similarly write_all(), but instead of commas, T-shirt parameters are separated by the symbol -;. This is necessary for correct writing to the csv file.

write_all_csv() :-
    findall(P1, dt_shirt(P1,_,_, _,_,_,_,_), P1s),
    findall(P2, dt_shirt(_,P2,_,_,_,_,_,_ ), P2s),
    findall(P3, dt_shirt(_,_,P3, _,_,_,_,_), P3s),
    findall(P4, dt_shirt(_,_,_,P4,_,_,_,_ ), P4s),
    findall(P5, dt_shirt(_,_,_,_,P5,_,_,_ ), P5s),
    findall(P6, dt_shirt(_,_,_,_,_,P6,_,_ ), P6s),
    findall(P7, dt_shirt(_,_,_, _,_,_,P7,_), P7s),
    findall(P8, dt_shirt(_,_,_, _,_,_,_,P8), P8s),
    write_all_csv(P1s, P2s, P3s, P4s, P5s, P6s, P7s, P8s);
    writedevice(screen).

write_all_csv([], [], [], [], [], [], [], []) :- !.
write_all_csv([P1|T1], [P2|T2], [P3|T3], [P4|T4], [P5|T5], [P6|T6], [P7|T7], [P8|T8]) :-
          write(P1,"; ",
          P2,"; ",
          P3,"; ",
          P4,"; ",
          P5,"; ",
          P6,"; ",
          P7,"; ",
          P8),nl,
    write_all_csv(T1, T2, T3, T4, T5, T6, T7, T8).

Removing all records from the database

Removing all records from the database
Removing all records from the database

process(8) – creates a window in which, if all records are successfully deleted from the database, the message “DB has been cleared” will be displayed. If an error occurs, “Error writing file!” will be displayed.

process(8) :-
        makewindow(9,11,3," Delete All DB ",10,30,7,40),  shiftwindow(9),
        clear_database,
        write("DB has been cleared"),
        nl,!,
        write("Press space bar."),readchar(_),
        removewindow, shiftwindow(1), clearwindow, menu;
        
        write("Error writing file!"),nl,!,
        write("Press space bar."),readchar(_),
        removewindow, shiftwindow(1), clearwindow, menu.

clear_database – removes all facts from the database using the built-in predicate retract:

 clear_database:-
          retract(dt_shirt(_,_,_,_,_,_,_,_)),
          fail.
 clear_database:-!.

Exiting the program

Exiting the program
Exiting the program

process(9) – clears the database and displays the message “See you again!”.

process(9) :-
        clear_database,
        write("See you again! "),readchar(_),exit.

End

That’s like all.

I hope you found what you were looking for)

Link to source code: https://github.com/KirillTaE/Dynamic_DataBase_on_TurboProlog

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *