- •Федеральное государственное бюджетное образовательное учреждение высшего образования "Санкт-Петербургский государственный университет телекоммуникаций им. Проф. М.А. Бонч-Бруевича"
- •По лабораторной работе №5
- •Постановка задачи
- •Перечень предикатов (функций)
- •1. Предикаты ввода-вывода и управления
- •2. Предикаты работы с записями базы данных
- •Блок-схемы
- •Проверка функционала программы
- •Код программы
Проверка функционала программы
Для проверки работоспособности программы были выполнены тестовые запросы к базе знаний в среде Prolog. Результаты выполнения запросов приведены ниже в виде скриншотов, подтверждающих корректность работы предикатов и правил.
Рисунок 1. Меню управления базой данных.
Рисунок 2. Вывод записей базы данных по одной.
Рисунок 3. Сохранение базы данных в текущий текстовый файл.
Рисунок 4. Добавление записи.
Рисунок 5. Удаление записи.
Рисунок 6. Редактирование записи.
Рисунок 7. Подсчет записей в базе данных.
Рисунок 8. Сохранение базы данных в csv-формате.
Рисунок 9. Изменение имени текущего файла.
Код программы
NOWARNINGS
DOMAINS
name, article, vehicle, description = string
price, quantity = integer
file = file_pointer
steering_gear_domain = steering_gear(name, article, vehicle, description, price, quantity)
menu_option = integer
DATABASE
steering_gear(
name,
article,
vehicle,
description,
price,
quantity
)
temp_gear(
name,
article,
vehicle,
description,
price,
quantity
)
current_filename(string)
PREDICATES
load_database_from_file
load_database_from_file(string)
print_all_gears
print_all_gears_stepwise
print_gear(steering_gear_domain)
wait_for_enter
menu
action(menu_option)
add_gear
delete_gear
delete_gear_by_name(string)
save_all_gears
save_database_to_file
save_database_to_file(string)
ensure_database_loaded
count_items
count_items_helper(integer, integer)
copy_to_temp
restore_from_temp
clear_temp
get_current_filename(string)
set_current_filename(string)
change_filename
show_current_filename
reload_database
read_positive_integer(string, integer)
edit_gear
edit_gear_by_name(string)
save_all_gears_csv
save_database_to_csv
save_database_to_csv(string)
CLAUSES
% Получение текущего имени файла
get_current_filename(Filename) :-
current_filename(Filename), !.
get_current_filename("datauaz.txt").
% Установка текущего имени файла
set_current_filename(Filename) :-
retractall(current_filename(_)),
assertz(current_filename(Filename)).
% Показать текущее имя файла
show_current_filename :-
get_current_filename(Filename),
write("Current database file: ", Filename), nl.
% Загрузка базы данных
load_database_from_file :-
get_current_filename(Filename),
load_database_from_file(Filename).
load_database_from_file(Filename) :-
existfile(Filename), !,
write("Loading database from file: ", Filename), nl,
consult(Filename),
write("Database loaded successfully!"), nl.
load_database_from_file(Filename) :-
write("File ", Filename, " not found. Creating empty database."), nl.
% Перезагрузка базы данных
reload_database :-
get_current_filename(Filename),
retractall(steering_gear(_, _, _, _, _, _)),
load_database_from_file(Filename),
write("Database reloaded from file!"), nl,
wait_for_enter.
% Сохранение базы данных в файл
save_database_to_file :-
get_current_filename(Filename),
save_database_to_file(Filename).
save_database_to_file(Filename) :-
write("Saving database to file: ", Filename), nl,
openwrite(file_pointer, Filename),
writedevice(file_pointer),
save_all_gears,
closefile(file_pointer),
writedevice(screen),
write("Database saved successfully!"), nl.
% Смена имени файла
change_filename :-
write("Enter new filename: "),
readln(NewFilename),
set_current_filename(NewFilename),
write("Current filename changed to: ", NewFilename), nl,
wait_for_enter.
% Гарантирует, что база загружена перед операциями
ensure_database_loaded :-
steering_gear(_, _, _, _, _, _), !.
ensure_database_loaded :-
load_database_from_file.
% Сохранение всех данных в файл
save_all_gears :-
steering_gear(Name, Article, Vehicle, Description, Price, Quantity),
write("steering_gear(\"", Name, "\",\"", Article, "\",\"", Vehicle, "\",\"", Description, "\",", Price, ",", Quantity, ")"), nl,
fail.
save_all_gears.
% Вывод всей базы сразу
print_all_gears :-
ensure_database_loaded,
write("=== STEERING GEARS DATABASE ==="), nl, nl,
steering_gear(Name, Article, Vehicle, Description, Price, Quantity),
print_gear(steering_gear(Name, Article, Vehicle, Description, Price, Quantity)),
fail.
print_all_gears :-
write("=== END OF DATABASE ==="), nl.
% Пошаговый вывод базы
print_all_gears_stepwise :-
ensure_database_loaded,
write("=== STEERING GEARS DATABASE ==="), nl, nl,
steering_gear(Name, Article, Vehicle, Description, Price, Quantity),
print_gear(steering_gear(Name, Article, Vehicle, Description, Price, Quantity)),
wait_for_enter,
fail.
print_all_gears_stepwise :-
write("=== END OF DATABASE ==="), nl.
% Вывод информации об одном объекте
print_gear(steering_gear(Name, Article, Vehicle, Description, Price, Quantity)) :-
write("Name: ", Name), nl,
write("Article: ", Article), nl,
write("Vehicle: ", Vehicle), nl,
write("Description: ", Description), nl,
write("Price: ", Price, " rub"), nl,
write("Quantity: ", Quantity), nl,
write("-----------------------------------"), nl.
% Подсчет количества элементов в базе
count_items :-
ensure_database_loaded,
count_items_helper(0, Count),
write("Total items in database: ", Count), nl,
wait_for_enter.
count_items_helper(Acc, Count) :-
steering_gear(_, _, _, _, _, _),
retract(steering_gear(Name, Article, Vehicle, Description, Price, Quantity)),
NewAcc = Acc + 1,
assertz(temp_gear(Name, Article, Vehicle, Description, Price, Quantity)),
count_items_helper(NewAcc, Count).
count_items_helper(Count, Count) :-
restore_from_temp.
% Копирование в временную базу
copy_to_temp :-
clear_temp,
steering_gear(Name, Article, Vehicle, Description, Price, Quantity),
assertz(temp_gear(Name, Article, Vehicle, Description, Price, Quantity)),
fail.
copy_to_temp.
% Восстановление из временной базы
restore_from_temp :-
retractall(steering_gear(_, _, _, _, _, _)),
temp_gear(Name, Article, Vehicle, Description, Price, Quantity),
assertz(steering_gear(Name, Article, Vehicle, Description, Price, Quantity)),
fail.
restore_from_temp :-
clear_temp.
% Очистка временной базы
clear_temp :-
retractall(temp_gear(_, _, _, _, _, _)).
% Чтение положительного целого числа с проверкой
read_positive_integer(Prompt, Value) :-
write(Prompt),
readint(Value),
Value > 0, !. % Успех если значение больше 0
read_positive_integer(Prompt, Value) :-
write("Error: Value must be greater than 0. Please try again."), nl,
read_positive_integer(Prompt, Value). % Рекурсивный вызов при ошибке
% Добавление нового объекта
add_gear :-
ensure_database_loaded,
write("Enter name: "),
readln(Name), nl,
write("Enter article: "),
readln(Article), nl,
write("Enter vehicle: "),
readln(Vehicle), nl,
write("Enter description: "),
readln(Description), nl,
% Используем новый предикат для чтения положительных чисел
read_positive_integer("Enter price: ", Price), nl,
read_positive_integer("Enter quantity: ", Quantity), nl,
assertz(steering_gear(Name, Article, Vehicle, Description, Price, Quantity)),
write("Item successfully added!"), nl,
wait_for_enter.
% Удаление объекта по имени
delete_gear :-
ensure_database_loaded,
write("Enter name of the item to delete: "),
readln(Name), nl,
delete_gear_by_name(Name).
delete_gear_by_name(Name) :-
retract(steering_gear(Name, Article, Vehicle, Description, Price, Quantity)),
write("Item deleted successfully!"), nl,
wait_for_enter.
delete_gear_by_name(Name) :-
write("Item '", Name, "' not found."), nl,
wait_for_enter.
% Ожидание Enter
wait_for_enter :-
write("Press Enter to continue..."),
readchar(_),
nl.
% Редактирование объекта по имени
edit_gear :-
ensure_database_loaded,
write("Enter name of the item to edit: "),
readln(Name), nl,
edit_gear_by_name(Name).
% Если нашли элемент с таким именем — показываем старые значения и спрашиваем новые
edit_gear_by_name(Name) :-
steering_gear(Name, Article, Vehicle, Description, Price, Quantity), !,
write("Current values:"), nl,
print_gear(steering_gear(Name, Article, Vehicle, Description, Price, Quantity)),
write("Enter new name: "),
readln(NewName), nl,
write("Enter new article: "),
readln(NewArticle), nl,
write("Enter new vehicle: "),
readln(NewVehicle), nl,
write("Enter new description: "),
readln(NewDescription), nl,
read_positive_integer("Enter new price: ", NewPrice), nl,
read_positive_integer("Enter new quantity: ", NewQuantity), nl,
retract(steering_gear(Name, Article, Vehicle, Description, Price, Quantity)),
assertz(steering_gear(NewName, NewArticle, NewVehicle, NewDescription, NewPrice, NewQuantity)),
write("Item successfully updated!"), nl,
wait_for_enter.
% Если по имени ничего не найдено
edit_gear_by_name(Name) :-
write("Item '", Name, "' not found."), nl,
wait_for_enter.
% Сохранение БД в CSV-файл
save_database_to_csv :-
ensure_database_loaded,
write("Enter CSV filename: "),
readln(Filename), nl,
save_database_to_csv(Filename).
% Сохранение БД CSV-файл по имени
save_database_to_csv(Filename) :-
ensure_database_loaded,
write("Saving database to CSV file: ", Filename), nl,
openwrite(file_pointer, Filename),
writedevice(file_pointer),
write("\"Name\",\"Article\",\"Vehicle\",\"Description\",\"Price\",\"Quantity\""), nl,
save_all_gears_csv,
closefile(file_pointer),
writedevice(screen),
write("CSV file saved"), nl.
% Запись всех элементов в CSV
save_all_gears_csv :-
steering_gear(Name, Article, Vehicle, Description, Price, Quantity),
write( Name, ",",
Article, ",",
Vehicle, ",",
Description, ",",
Price, ",",
Quantity),
nl,
fail.
save_all_gears_csv.
% Меню
menu :-
clearwindow,
makewindow(1, 2, 11, "UAZ Patriot Steering Gears Database", 0, 0, 25, 80),
show_current_filename,
write("************ MENU ************"), nl,
write("1 - Change database filename"), nl,
write("2 - Reload database from file"), nl,
write("3 - Show full database"), nl,
write("4 - Show database by 1 item"), nl,
write("5 - Save database to file"), nl,
write("6 - Add new item"), nl,
write("7 - Delete item"), nl,
write("8 - Edit item"), nl,
write("9 - Count items in database"), nl,
write("10 - Export database to CSV"), nl,
write("11 - Exit"), nl,
write("Select an option: "),
readint(N), nl,
action(N).
% Действия меню
action(1) :-
change_filename,
menu.
action(2) :-
reload_database,
menu.
action(3) :-
print_all_gears,
wait_for_enter,
menu.
action(4) :-
print_all_gears_stepwise,
wait_for_enter,
menu.
action(5) :-
save_database_to_file,
wait_for_enter,
menu.
action(6) :-
add_gear,
menu.
action(7) :-
delete_gear,
menu.
action(8) :-
edit_gear,
menu.
action(9) :-
count_items,
menu.
action(10) :-
save_database_to_csv,
wait_for_enter,
menu.
action(11) :-
write("Exiting program... Goodbye!"), nl.
action(_) :-
write("Invalid option. Try again."), nl,
wait_for_enter,
menu.
GOAL
clearwindow,
set_current_filename("datauaz.txt"),
menu.
Выводы
В ходе выполнения лабораторной работы была разработана функциональная база данных на языке логического программирования Prolog (Turbo Prolog 2.0) для управления информацией о рулевых редукторах автомобиля УАЗ Патриот. Были определены домены, предикаты и правила, позволяющие:
организовать структурированное хранение и управление данными о рулевых редукторах;
реализовать функциональность для добавления, удаления, редактирования и поиска записей в базе данных;
обеспечить загрузку и сохранение базы данных в текстовом файле, а также экспорт данных в формате CSV;
создать интерактивное меню для удобного взаимодействия пользователя с программой;
проверить корректность работы программы на различных наборах данных, включая пустую и предварительно заполненную базы, что подтвердило стабильность и надёжность всех функций.
Таким образом, работа продемонстрировала возможности использования Prolog для реализации баз данных и организации интерактивного взаимодействия с пользователем.
