(**** * * Module ScheduleDB defines the major database objects of the scheduling tool . * * NOTE: this is work in progress. Several objects are yet to be defined, most * notably Option. Also, more complete object descriptions are needed. * *) module ScheduleDB; from RoomDB import RoomDB; from InstructorDB import InstructorDB; from CourseDB import all; from ScheduleEntry import all; from Attributes import all; export ScheduleDB; export all; object ScheduleDB components: pdb:PermanentDatabase and sched:Schedule and settings:Settings and user:User; description: (* The full schedule DB is comprised of the permanent databases, the specific schedule items (on a quarter basis), the global settings, and the users database (a collection of user credentials/permissions). *); end; object PermanentDatabase = PermDatabase*; object PermDatabase = rdb:RoomDB and cdb:CourseDB and idb:InstructorDB and cons:Constraint* description: (* The permanent databases contain static preferences, course selections, teacher preferences and other information that is set a single time and applied to the quarter level schedules. *); end PermDatabase; object Constraint = cc:CourseCon and tc:TimeCon description: (* The Constraint database contains all of the Course and Time Constraints for the schedule. *); end Constraint; object CourseCon = dcc:DeptCC and acc:CourseACC and bcc:CourseBCC description: (* The course contraint table holds a pairing of all the courses that can't be taught at the same time for a given quarter. *); end CourseCon; object DeptCC = SClass description: (* The Department of the Course in the Course Constraint table. *); end DeptCC; object CourseACC = SClass description: (* The Course Name and Number of the Course that can't be taught at the same time as CourseBCC. *); end CourseCC; object CourseBCC = SClass description: (* The Course Name and Number of the Course that can't be taught at the same time as CourseACC. *); end CourseCC; object TimeCon = CourseTC and RoomTC and InstructorTC and DayOfWeekTC and TimeTC description: (* The time contraint table holds a pairing of all the time constraints for the given quarter. *); end TimeCon; object RoomTC = integer description: (* The Room Number of the Class for a given Time Constraint. *); end RoomTC; object CourseTC = string description: (* The Course Name and Number for a given Time Constraint. *); end CourseTC; object InstructorTC = string description: (* The Instructor Name assigned to a given Time Constraint. *); end InstructorTC; object DayOfWeekTC = string description: (* The DayOfWeekTC is the Day assigned to a given Time Constraint. *); end DayOfWeekTC; object TimeTC = integer description: (* The TimeTC is the time in Military Time assigned to a given Time Constraint. *); end TimeTC; object Schedule components: attrs:Attributes* and entries:ScheduleEntry* and tdbs:TemporaryDatabases and qtr:Quarter and yr:Year and ph:Phase; description: (* The schedule object is a collection of all the information to comprise a single, quarter-level schedule. This includes the temporary databases (a copy of the permanent databases that is editable by the scheduler), the actual schedule entry (a listing of all the classes, rooms, instructors and times), and the scheduling attributes which measures how 'good' a specific schedule is. *); end Schedule; object Quarter = string description: (* The Quarter of the current Schedule {Fall, Winter, Spring, Summer}. *); end Quarter; object Year = integer description: (* The Year of the current Schedule. *); end Year; object Phase = integer description: (* The Phase of the current Schedule {Preliminary, Draft, Final}. *); end Phase; object TemporaryDatabases = rdb:RoomDB and idb:InstructorDB and cdb:CourseDB and cons:Constraint*; object User components: UserName and Password and Type; description: (* The users database contains a username and password pairing for each user in the system as well as a type to determine whether they are an instructor (0) or scheduler (1). *); end User; object UserName = string description: (* The UserName is a string containing the login name for an instructor or a scheduler. This is used to authenticate with the Scheduling Tool. *); end UserName; object Password = string description: (* The Password is a string containing the password for an instructor or a scheduler. This is used to authenticate with the Scheduling Tool. *); end Password; object Type = integer description: (* The Type is used to determine whether the user is an instructor (0) or scheduler (1). *); end Type; object Settings components: CentralServer and OnlineWksp and OfflineWksp and UserName and Password; description: (* The settings object contains the global settings for an instance of the scheduling tool. *); end Settings; object CentralServer = string description: (* The CentralServer is that domain name or the ip address of the server hosting the scheduling tool software. *); end CentralServer; object OnlineWksp = string description: (* The OnlineWksp is the local directory path for all online files. *); end OnlineWksp; object OfflineWksp = string description: (* The OfflineWksp is the local directory path for all offline files. *); end OfflineWksp; (* The DeleteScheduleEntry is part of the Hand Editing Operations and i s * used when the user clicks the scissors (Delete) icon. *) operation DeleteScheduleEntry (entry:ScheduleEntry, sched:Schedule) -> sched':Schedule precondition: (* * The entry inputted for deletion must already exist in the current * set of Schedule Entries. *) entry in sched.entries; postcondition: (* * A Schedule Entry is in the Output Schedule Entry set if and only if it is not the * existing entry to be deleted and it is in the input Schedule. *) forall (entry' in sched.entries) ( (entry' in sched.entries) iff ((entry' != entry) and (entry' in sched.entries))); description: (* Delete the given Schedule Entry from the given set of Schedule Entries. The given record must already be in the Schedule Entries which is verified in the pre-condition. *); end DeleteScheduleEntry; (* The ChangeScheduleEntry is part of the Hand Editing Operations and is used * when the user clicks the Edit icon and makes a change to the Instructor/Class for a given * time slot. (See Figure 2.5.4.5 - Overriding A Class). *) operation ChangeScheduleEntry (entry:ScheduleEntry, sched:Schedule, instr:SInstructorName, class:SClass) -> sched':Schedule precondition: (* * The entry inputted to change must already exist in the current * set of Schedule Entries and the Instructor inputted cannot be teaching at * the time of this entry. *) entry in sched.entries and not ( exists (entry' in sched.entries) ( (entry'.instr = instr) and (entry'.class = entry.class) ) ); postcondition: (* * A Schedule Entry is in the new set of ScheduleEntries if and only if it is the new * entry or it is in the input set and it is not the entry that is to be changed. *) forall (entry' in sched.entries) ( (entry' in sched.entries) iff ((((entry'.instr != entry.instr) and (entry'.class != entry.class)) or ((entry'.instr = instr) and (entry'.time = entry.time))) and (entry' in sched.entries))); description: (* Change the given Schedule Entry ing the given set of Schedule Entries to the new Instructor / Class combo. The given record must already be in the Schedule Entries which is verified in the pre-condition. *); end ChangeScheduleEntry; (* The AddScheduleEntry is an operation that is used to Add a new Schedule Entry to a set of Schedule Entries. * Although this action is not specifically defined in the Hand Editing scenario, such an operation will pertain * to later Generation. *) operation AddScheduleEntry (entry:ScheduleEntry, sched:Schedule) -> sched':Schedule precondition: (* * The entry inputted to add must NOT already exist in the current * set of Schedule Entries. The Instructor inputted cannot be teaching at * the time in any other entry and the Room may not be occupied already. *) entry in sched.entries and not ( exists (entry' in sched.entries) ( (entry'.instr = entry.instr) and (entry'.time = entry.time) ) ) and not ( exists (entry' in sched.entries) ( (entry'.room = entry.room) and (entry'.time = entry.time) ) ); postcondition: (* * A Schedule Entry is in the new set of ScheduleEntries if and only if it is the new * entry or it is in the input set. *) (forall (entry' in sched.entries) (entry' in sched.entries) iff ((entry' = entry) or (entry' in sched.entries))); description: (* Add the given Schedule Entry into the given set of Schedule Entries. *); end AddScheduleEntry; operation FindScheduleEntry (entry:ScheduleEntry, sched:Schedule, tdb:TemporaryDatabases) -> string precondition: (* * The entry Inputed exists in the Schedule. *) entry in sched.entries ; postcondition: exists (course in tdb.cdb.ce) ( entry.class.subj = course.coursename and entry.class.secNum = course.coursenumber ); description: (* The FindScheduleEntry is an operation that is used by the Hand Editing scenario to locate the detailed * information for a given entry when a user clicks the specific entry. Additionally, it can be used by * later search functions or sorting functions if necessary. *); end FindScheduleEntry; operation GenerateSchedule (sched:Schedule, tdb:TemporaryDatabases) -> entry:ScheduleEntry* precondition: (* * There is at least one set of complete Schedule Entries that * can be produced from the given Schedule, Schedule.TemporaryDatabases, * and Schedule.Constraints. *) MeetsConstraints(sched,tdb) ; postcondition: (* * The set of Schedule Entries generated for the given Schedule is * the 'best' Schedule. This means that no other Schedule both * meets the constraints and has a better Average Strength. *) not ( exists (sched': Schedule) ( HowGood(sched') > HowGood(sched) )) and IsBestSchedule(sched, tdb) ; description: (* Generate a new set of Schedule Entries based on the inputted Schedule. The Schedule will consist of all the necessary Databases, Preferences and Constraints to ensure that an optimal Schedule is generated. The functions HowGood and IsBestSchedule ensure that the schedule produced is optimal. *); end GenerateSchedule; (* This function is responsible for determining HowGood a set of Schedule * Entries are for a given schedule based on an algorithm (that is yet * to be defined)***. *) function HowGood(sched:Schedule) -> integer = ( ); (* * For a given Schedule, no other Schedule can exist that * is stronger than the inputted schedule. *) function IsBestSchedule(sched:Schedule, tdb:TemporaryDatabases) -> boolean = ( MeetsConstraints(sched, tdb) and forall (attributes in sched.attrs) ( not ( exists (sched':Schedule) ( MeetsConstraints(sched', tdb) and (forall (attributes' in sched'.attrs) ( attributes'.sstr.sst > attributes.sstr.sst) ) ) ) ) ); (* * For a given Schedule, none of the constraints specified in * Schedule->Constraints are broken. *) function MeetsConstraints(sched:Schedule, tdb:TemporaryDatabases) -> boolean = ( forall (entry in sched.entries) ( NoRoomTimeOverlap(entry, sched) and NoTeacherOverlap(entry, sched) and NoCourseOverlap(entry, sched, tdb) ) ); (* * For a given Schedule Entry, no rooms are schedule at the same time. *) function NoRoomTimeOverlap(entry: ScheduleEntry, sched:Schedule) -> boolean = ( not ( exists (entry' in sched.entries) ( (entry'.room = entry.room) and (entry'.time = entry.time) ) ) ); (* * For a given Schedule Entry, no teachers are scheduled at two places at the same time. *) function NoTeacherOverlap(entry:ScheduleEntry, sched:Schedule) -> boolean = ( not ( exists (entry' in sched.entries) ( (entry'.instr = entry.instr) and (entry'.time = entry.time) ) ) ); (* * For a given Schedule Entry, no class is scheduled at the same time that is * marked as a non-concurrent class in the Course Constraints database (ie. CSC 315 * and CSC 357 shouldn't be taught concurrently). *) function NoCourseOverlap(entry:ScheduleEntry, sched:Schedule, tdb:TemporaryDatabases) -> boolean = ( forall (constraint in tdb.cons) ( not ( exists (entry' in sched.entries) ( (entry'.time = entry.time) and (entry'.class = constraint.cc.acc) and (entry'.class = constraint.cc.bcc) ) ) ) ); end ScheduleDB;