База данных расписания группы

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

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

    Задача состоит в создании программы, содержащей базу данных о расписании занятий группы студентов в университете. Эта программа должна отвечать на вопросы, наподобие приведенных ниже:

    1. Занят ли лектор Иван Иванович Иванов в понедельник в 9 часов?
    2. В каком корпусе университета находится 456 аудитория?
    3. Занята ли 456 аудитория во вторник в 16 часов?

    Исходя из вопросов нужно выбрать “правильную” структуру базы. Рассмотрим решение на Visual Prolog.

    описание типов и базы данных в prolog

    В условии задачи фигурируют лектор (очевидно, задаваемый фамилией), день недели, время, названия учебных предметов, номер аудитории и корпуса университета. Для каждой такой сущности вводим свой тип:

    DOMAINS
    	lector = string
    	subject = string
    	day = sun;mon;tue;wed;thu;fri;sat
    	time_d = time(integer, integer)
    	campus = string
    	room = integer
    	campus_room_d = campus_room(campus, room)

    Заметьте, что время задается структурой, объединяющей часы и минуты, а структура учебной аудитории содержит название корпуса и номер аудитории.

    В задании не требуется изменять содержимое базы, поэтому мы не будем описывать базу в разделе database – это было бы также нужно при необходимости хранения базы во внешнем файле. При необходимости, вы можете сделать это по образцу, представленному в статье “Пример работы с базами данных в Prolog“. Мы же будем использовать внутреннюю базу, поэтому структуру записи зададим в разделе predicates (рядом с прототипами функций):
    nondeterm timetable(lector, subject, day, time_d, campus_room_d)
    Тогда в разделе clauses можно разместить примеры записей базы:

    	timetable("Petrov Petr Petrovich", "english", tue, time(14, 10), campus_room("A", 456)).
    	timetable("Sidorov Sidr Sidorovich", "physics", tue, time(8, 00), campus_room("B", 451)).
    	timetable("Ivanov Ivan Ivanovich", "music", tue, time(8, 00), campus_room("B", 456)).
    	timetable("Ivanov Ivan Ivanovich", "music", mon, time(10, 00), campus_room("B", 456)).
    	timetable("Sidorov Sidr Sidorovich", "physics", mon, time(15, 55), campus_room("B", 456)).

    Работа со временем в Prolog

    Выше была описана структура времени, но в нашей задаче стоит вопрос о диапазоне времени – ведь если занятие началось в time(15, 55), то оно не кончилось тут же, а длится полтора часа. Нам потребуются вспомогательные предикаты. Чтобы получить значение времени через полтора часа мы просто прибавим 90 минут, однако не всегда при этом получится корректное значение времени. Для корректировки исопльзуем такой предикат:

    correct_time(time(HH, MM), time(HH, MM)):-
    	HH < 24, MM < 60, !.
    correct_time(time(HH, MM), time(CorrectHH, CorrectMM)):-
    	MM >= 60, !, 
    	CorrectMM = MM mod 60, HHwithCarry = HH + (MM div 60),
    	correct_time(time(HHwithCarry, CorrectMM), time(CorrectHH, CorrectMM)).
    correct_time(time(HH, MM), time(CorrectHH, MM)):-
    	HH >= 24, CorrectHH = HH mod 24.

    Предикат получения время окончания лекции:

    lecture_time(time(FromHH, FromMM), To):-
    	EndMM = FromMM + 90,
    	correct_time(time(FromHH, EndMM), To).

    Предикат проверки, что момент времени находится в заданном диапазоне:

    in_period(time(FromHH, FromMM), time(ToHH, ToMM), time(HH, MM)):-
    	From = FromHH * 60 + FromMM,
    	To = ToHH * 60 + ToMM,
    	Time = HH * 60 + MM,
    	Time >= From, Time <= To.

    проверки условий в базе данных

    Перечисленные ниже предикаты отвечают на вопросы задачи:

      is_busy(Who, Day, Time):-
        timetable(Who, _Subject, Day, From, _Campus),
        lecture_time(From, To),
        in_period(From, To, Time), !.
        
      where_is_the_room(Room, Campus):-
        timetable(_Who, _Subject, _Day, _From, campus_room(Campus, Room)).
        
      is_busy(Room, Campus, Day, Time):-
        timetable(_Who, _Subject, Day, From, campus_room(Campus, Room)),
        lecture_time(From, To),
        in_period(From, To, Time), !.

    Примеры их использования, а также вызовы, проверяющие корректность работы со временем приведены в разделе goal (нужную строчку нужно раскомментировать):

    GOAL    
      %lecture_time(time(8, 30), X).
      %in_period(time(8,30), time(10,00), time(19,00)).
       
       %is_busy("Ivanov Ivan Ivanovich", mon, time(9, 00)). % first goal
       
       % where_is_the_room(456, Campus). % second goal
       
       is_busy(456, Campus, mon, time(16, 00)). % third goal

    Ниже приведены скриншоты, показывающие ответ программы на каждый из предложенных запросов:

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