(**** * * Module Preferences defines the preferences objects and operation * of the scheduling tool. * * NOTE: this is work in progress. Several objects are yet to be defined. * Also, more complete object descriptions are needed. * *) module InstructorPref; export InstructorPref; object InstructorPref components: TimePreference and CoursePreference and ProximalPreference and PatternPreference; description: (* The full preference object is comprised of the four types of preferences: Time, Course, Proximal and Pattern. *); end; object TimePreference = timepref: TimePref*; object TimePref = tpd: TPDays and tpg: TPHours and tpp:TPPreference description: (* The time preference database contains a list of all the preferences assigned by the instructors for the current Phase (defined in ScheduleDB). The TPDays is the day {Monday,Tuesday,etc} of the week, the TPHours is the time they wish to teach at in Military time, and the TPPreference is an integer representing their desire to teach at the specific time and day (0-10, explained in Requirements 2.2). *); end TimePref; object TPDays = string description: (* TPDays is the Day Preference stored as one of Monday, Tuesday, etc in string format. *); end TPDays; object TPHours = string description: (* TPHours is the Hour Preference stored as an hour in Military time. Range is 08:00-18:00. *); end TPHours; object TPPreference = integer description: (* TPPreference is integer representation of a teachers desire to teach at a specific time, from 0 (can't teach) to 10 (MUST teach). *); end TPPreference; object CoursePreference = cpref: CoursePref*; object CoursePref = cpc: CPClass and cpp: CPPreference description: (* The course preference database contains a list of all the preferences assigned by the instructors for the current Phase (defined in ScheduleDB). The CPClass is composed of a Major/CourseNo pairing (ie: CPE308) and the CPPreference is an integer representing their desire to teach at the specific class and day (0-10, explained in Requirements 2.2). *); end CoursePref; object CPClass = string description: (* CPClass is the Major/CourseNo pairing (ie: CPE308) for the specific Class. *); end CPClass; object CPPreference = integer description: (* CPPreference is integer representation of a teachers desire to teach a specific class, from 0 (can't teach) to 10 (MUST teach). *); end CPPreference; object ProximalPreference = ppt: PPTemporal and ppd: PPDistance and ppo: PPOrder description: (* The proximal preference database contains the proximal preference assigned by the instructors for the current Phase (defined in ScheduleDB). PPTemporal is composed of their Time Distance preference, PPDistance is how far they wish their Lecture to be from Lab or their Office, and PPOrder is whether they want Lab before (Order = 0) or after (Order = 1) Lecture. All of these preferencing options are elaborated on in Requirements 2.2.4 *); end ProximalPreference; object PPTemporal = integer description: (* PPTemporal is composed of a their Time Distance preference (the prefered time gap between Lecture and Lab). *); end PPTemporal; object PPDistance = integer description: (* PPDistance is how far an instructor wishes their Lecture to be from Lab or their Office. This value can be 100, 250, 500, 1000, or 10000000000. 10000000000 signifies no preference. *); end PPDistance; object PPOrder = boolean description: (* PPOrder is whether an instructor wants their Lab before (Order = 0) or after (Order = 1) Lecture. *); end PPOrder; object PatternPreference = ppref: PatternPref*; object PatternPref = ppcp: PPClassPattern and ppp: PPPreference and pplp: PPLabPreference description: (* The pattern preference database contains the pattern preference assigned by the instructors for the current Phase (defined in ScheduleDB). PPClassPattern is used to describe the 'pattern' that an instructor wishes to teach on (ie: MWF or TR or MWTRF), PPLabPreference indicates the lab pattern that they instructor wishes to teach on (following the same nomenclature as PPClassPattern), and the PPPreference is an integer representing their desire to teach on the specific pattern (0-10, explained in Requirements 2.2). *); end PatternPref; object PPClassPattern = string description: (* PPClassPattern is used to describe the 'pattern' that an instructor wishes to teach on (ie: MWF or TR or MWTRF). *); end PPClassPattern; object PPLabPreference = string description: (* PPLabPreference indicates the lab pattern that they instructor wishes to teach on (following the same nomenclature as PPClassPattern) *); end PPLabPreference; object PPPreference = integer description: (* PPPreference is an integer representing an instructors desire to teach on the specific pattern (0-10). *); end PPPreference; operation SaveTime inputs: tp: TimePreference, old_tps: TimePref*, new_tps: TimePref*; outputs: tp': TimePreference; description: (* SaveTime saves whatever is in the TimePrefs. The operation will make sure that if a value is entered into a TPPreference that it is between 0 and 10 and if there is no value in it (nil) then upon completion all nils have been filled the value of 5. *); precondition: (* All of the TimePrefs of old_tp should be contained in the input TimePreference. * By the setup of the matrix, the TPHours and TPDays will never be nil, however, * TPPreference is allowed to be nil, but it does not effect the precondition. *) (forall (i:integer | (i > 0 ) and (i <= #(tp.timepref))) (old_tps[i] in tp)) and (* The collection of TimePrefs for old_tps should be exactly identical * to the input TimePreferences. *) (old_tps = tp); postcondition: (* The given number of TimePrefs of the out TimePreference match up to * the number of TimePrefs in new_tps because fundamently they should be * the same thing (which is checked later in the postcondition). *) (#(tp'.timepref) = #new_tps) and (* All the TimePrefs in the output TimePreference should have a TPPreference value * from 0 to 10. After that all the TPDays should only be a day of the week. The * TPHours should can be anything from the range of 08:00 to 18:00 as described * for TPHours. No value in the output TimePreference's TPPreference should be nil * because all nil values have been defaulted to be filled in with 5. If there was * a nil value from the input TimePrefernce that nth TimePref in the output * TimePreference should be 5. And finally all of the TimePrefs of new_tp should * be contained in the out TimePreference. *) (forall (i:integer | (i > 0 ) and (i <= #(tp'.timepref))) ((tp'.timepref[i].tpp > -1) and (tp'.timepref[i].tpp < 11)) and (("Monday" in tp'.timepref[i].tpd) or ("Tuesday" in tp'.timepref[i].tpd) or ("Wednesday" in tp'.timepref[i].tpd) or ("Thursday" in tp'.timepref[i].tpd) or ("Friday" in tp'.timepref[i].tpd) or ("Saturday" in tp'.timepref[i].tpd) or ("Sunday" in tp'.timepref[i].tpd)) and (("08:00" in tp'.timepref[i].tpg) or ("09:00" in tp'.timepref[i].tpg) or ("10:00" in tp'.timepref[i].tpg) or ("11:00" in tp'.timepref[i].tpg) or ("12:00" in tp'.timepref[i].tpg) or ("13:00" in tp'.timepref[i].tpg) or ("14:00" in tp'.timepref[i].tpg) or ("15:00" in tp'.timepref[i].tpg) or ("16:00" in tp'.timepref[i].tpg) or ("17:00" in tp'.timepref[i].tpg) or ("18:00" in tp'.timepref[i].tpg)) and (tp'.timepref[i].tpp != nil) and (if(tp.timepref[i].tpp = nil) then(tp'.timepref[i].tpp = 5) else(tp'.timepref[i].tpp = tp.timepref[i].tpp)) and (new_tps[i] in tp')) and (* The collection of TimePrefs for new_tps should be exactly identical * to the output TimePreferences. *) (new_tps = tp'); end SaveTime; operation SaveCourse inputs: cp: CoursePreference, old_cpref: CoursePref*, new_cpref: CoursePref*; outputs: cp': CoursePreference; description: (* SaveCourse saves whatever is in the CoursePref. The operation will make sure that if a value is entered into a CPPreference that it is between 0 and 10 and if there is no value in it (nil) then upon completion all nils have been filled the value of 5. *); precondition: (* All of the CoursePrefs of old_cpref should be contained in the input CoursePreference. * With the set up of the courses, there cannot be edits to the course name. The only value * that is important is that of the CPPreference. In that case, it can be edit and nil is a * valid value for CPPreference because it will be handled in the operation, and the post- * condition will check it. *) (forall (i:integer | (i > 0 ) and (i <= #(cp.cpref))) (new_cpref[i] in cp)) and (* The collection of CoursePrefs for old_cpref should be exactly identical * to the input CoursePreference. *) (old_cpref = cp); postcondition: (* The given number of CoursePrefs of the out CoursePreference match up to * the number of CoursePrefs in new_cpref because fundamently they should be * the same thing (which is checked later in the postcondition). *) (#(cp'.cpref) = #new_cpref) and (* All the CoursePref in the output CoursePreference should have a CPPreference value * from 0 to 10. No value in the output CoursePreference's CPPreference should be nil * because all nil values have been defaulted to be filled in with 5. If there was * a nil value from the input CoursePreference that nth CoursePref in the output * CoursePreference should be 5. And finally all of the CoursePrefs of new_cpref should * be contained in the out CoursePeference. *) (forall (i:integer | (i > 0 ) and (i <= #(cp'.cpref))) ((cp'.cpref[i].cpp > -1) and (cp'.cpref[i].cpp < 11)) and (cp'.cpref[i].cpp != nil) and (if(cp.cpref[i].cpp = nil) then(cp'.cpref[i].cpp = 5) else(cp'.cpref[i].cpp = cp.cpref[i].cpp)) and (new_cpref[i] in cp')) and (* The collection of CoursePrefs for new_cpref should be exactly identical * to the output CoursePreference. *) (new_cpref = cp'); end SaveCourse; operation SaveProximal inputs: prp: ProximalPreference; outputs: prp': ProximalPreference; description: (* SaveProximal saves the ProximalPreference to it's new settings. No value except PPTemporal can be nil, but lucky us, there is no way to have any of the other components have nil because the format of each one in the GUI is a multiple choice. *); precondition: (* No precondition based on the fact that all the components are defined as not * being nil upon creation (GUI/code based) and that the only nil possibility * (PPTPemporal) can be nil *); postcondition: (* * The PPPreference can be nonexistant or it can be of any value higher than 0. *) ((prp'.ppt = nil) or (prp'.ppt >= 0)) and (* As defined for PPDistance, it can be 1 out of 5 different values: * 100, 250, 500, 1000, or 10000000000. There is no possibility for it * being nil because the user can only select from 5 different distances. *) ((prp'.ppd = 100) or (prp'.ppd = 250) or (prp'.ppd = 500) or (prp'.ppd = 1000) or (prp'.ppd = 10000000000)) and (* Since PPOrder is a boolean expression, there is no other way to * check to make sure that this values are correct. Just make sure it's * true or false *) ((prp'.ppo and true) or (prp'.ppo and false)); end SaveProximal; operation SavePattern inputs: pap: PatternPreference, old_ppref: PatternPref*, new_ppref: PatternPref*; outputs: pap': PatternPreference; description: (* SavePattern saves whatever is in the PatternPrefs. The operation will make sure that if a value is entered into a PatternPreference that it is between 0 and 10 and if there is no value in it (nil) then upon completion all nils have been filled the value of 5. *); precondition: (* All of the PatternPrefs of old_ppref should be contained in the input PatternPreference. * By the setup of the patterns, the PPClassPattern and PPLabPreference will never be nil, * however, PPPreference is allowed to be nil, but it does not effect the precondition. But * it will be addressed in the post condition. *) (forall (i:integer | (i > 0 ) and (i <= #(pap.ppref))) (old_ppref[i] in pap)) and (* The collection of PatternPrefs for old_ppref should be exactly identical * to the input PatternPreference. *) (old_ppref = pap); postcondition: (* The given number of PatternPrefs of the out PatternPreference match up to * the number of PatternPrefs in new_ppref because fundamently they should be * the same thing (which is checked later in the postcondition). *) (#(pap'.ppref) = #new_ppref) and (* All the PatternPref in the output PatternPreference should have a PPPreference value * from 0 to 10. No value in the output PatternPreference's PPPreference should be nil * because all nil values have been defaulted to be filled in with 5. If there was * a nil value from the input PatternPreference that nth PatternPref in the output * PatternPreference should be 5. And finally all of the PatternPrefs of new_cpref should * be contained in the out PatternPeference. *) (forall (i:integer | (i > 0 ) and (i <= #(pap'.ppref))) ((pap'.ppref[i].ppp > -1) and (pap'.ppref[i].ppp < 11)) and (pap'.ppref[i].ppp != nil) and (if(pap.ppref[i].ppp = nil) then(pap'.ppref[i].ppp = 5) else(pap'.ppref[i].ppp = pap.ppref[i].ppp)) and (new_ppref[i] in pap')) and (* The collection of PatternPrefs for new_cpref should be exactly identical * to the output PatternPreference. *) (new_ppref = pap'); end SavePattern; end InstructorPref;