База данных – владельцы бытовой техники

      Комментарии к записи База данных – владельцы бытовой техники отключены

В этой теме 1 ответ, 2 участника, последнее обновление  Васильев Владимир Сергеевич 11 мес., 3 нед. назад.

  • Автор
    Сообщения
  • #2587

    questioner
    Участник

    Мне необходимо решить задачу с использованием баз данных на Prolog:

    У каждого владельца может быть по 5 разных типов бытовой техники, но могут быть и не все типы.
    Для каждого вида техники предусмотреть такие поля:

    1. Марка
    2. Год выпуска
    3. Цена
    4. Страна производитель

    Я прочитал пример работы с базами данных в Prolog, однако, мне не понятно как связать владельцев с видами техники и как добавить ограничение чтобы у одного владельца было не более 5 видов техники.

  • #2588

    Вам нужно сначала описать типы данных, например – владельца можно задавать именем (строковый тип), а цену – дробным числом. При этом вид бытовой техники представляет собой составной тип данных, а т.к. у одного владельца может быть несколько видов техники – то потребуется тип данных для списка техники:

    domains
      brand_d = string
      year_d = integer
      cost_d = real
      country_d = string
      appliance_d = appilance(brand_d, year_d, cost_d, country_d)
      appliances_d = appliance_d*
      owner_d = string

    Связь владельцев с видами техники происходит в базе данных – запись БД хранит имя владельца и список техники:

    database owner_db
      nondeterm owner(owner_d, appliances_d)

    Нам потребуется несколько вспомогательных предикатов:

    1. read_appilance выполняет ввод данных о виде техники:
        read_appilance(appilance(Brand, Year, Cost, Country)):-
        	write("Brand: "), readln(Brand),
        	write("Year: "), readint(Year),
        	write("Cost: "), readreal(Cost),
        	write("Country: "), readln(Country).

    2. length определяет длину списка;
    3. add_owner проверяет наличие владельца с заданным именем в базе и при его отсутствии – добавляет в БД нового владельца с пустым списком техники:

        add_owner(Owner):-
        	owner(Owner, _Appliances), !;
        	assert(owner(Owner, [])).

    4. can_add_appliance – проверяет возможность добавления техники заданному владельцу при этом проверяет наличие владельца и длину списка принадлежащей ему техники:
        can_add_appliance(Owner):-
        	owner(Owner, Appliances), 
        	length(Appliances, AppliancesLength),
        	AppliancesLength < 5, !;
        	owner(Owner, _Appliances), !,
        	write("this owner already has 5 appliances\n"), !, fail;
        	write("such owner not exist\n"), !, fail.

    Теперь реализуем меню, позволяющее:

    • выйти из программы;
    • вывести содержимое БД;
    • добавить владельца;
    • добавить вид техники владельцу.

    Первое правило меню выводит список пункта, запрашивает целое число (номер пункта), вызывает обработчик, соответствующий этому номеру если он не равен нулю (таким образом реализовано завершение работы программы).

    Для вывода БД на экран программа обращается к факту owner, выводит его аргументы и выполняет fail, тем самым запуская механизм поиска с возвратами. В результате все факты БД будут выведены на экран, после чего обращение к БД завершится неудачей управление будет передано коду, записанному после логического ИЛИ (точки с запятой). Этот код рекурсивно запускает функцию menu для запроса следующего действия у пользователя (таким же образом работают все остальные пункты меню).

    При добавлении нового владельца программа вызывает предикат add_owner, а при добавлении техники – сначала can_add_appliance, а затем выполняет ввод информации о технике и ее добавление в БД. При добавлении в базу техники необходимо удалить старую запись при помощи retract, а затем добавить новую с увеличенным списком при помощи assert. Читать подробнее про assert и retract.

    Наконец, при вводе некорректного номера пункта меню срабатывает правило с анонимной переменной (унификация с ней пройдет успешно для любого введенного значения), при этом выводится предупреждение и, как и в остальных пунктах, – возврат к меню:

      menu(0):-
      	write("\t0 - exit\n"),
      	write("\t1 - dump database\n"),
      	write("\t2 - add owner\n"),
      	write("\t3 - add owner appliance\n"),
      	write(": "), readint(MenuPoint), 
      	MenuPoint <> 0, !, menu(MenuPoint); !.
      menu(1):-
      	owner(Owner, Appliances),
      	write(Owner), write(" -> "), write(Appliances), nl, fail; 
      	menu(0), !.
      menu(2):-
      	write("enter owner's name: "),
      	readln(Owner),
      	add_owner(Owner),
      	menu(0), !.
      menu(3):-
      	write("enter owner's name: "),
      	readln(Owner),
      	can_add_appliance(Owner), 
      	read_appilance(Appliance),
      	retract(owner(Owner, Appliances)),
      	assert(owner(Owner, [Appliance|Appliances])),
      	menu(0), !;
      	write("such owner not exist\n"), menu(0), !.
      menu(_):-
      	write("wrong menu point\n"),
      	menu(0).
    

Для ответа в этой теме необходимо авторизоваться.