(**** * * Module StudentDB defines the database of students and associated data * *) module StudentDB; export StudentDB; object StudentDB is components: studreclst:StudentRecord*; description: (* The Student Database is comprised of user records (which includes name, UID, classes taken, comments, etc, and StudentReport, which is a report generated from all student input.

UML diagram. *); end; object StudentRecord is components: name:StudentName and id:StudentID and cdb:CourseTried* and comments:StudentComments; description: (* The UserRecord is all information pertaining to one student user. *); end; object StudentName is string; object StudentID is integer; object CourseTried is components: CourseName and Reason; description: (* Describes a class that a student attempted to take and was unsuccessful. *); end; object CourseName is string; object Reason is components: Reason_Full or Reason_TimeConflict or Reason_Instructor or Reason_OtherString; description: (* Reason why class was not available. *); end; object Reason_Full is boolean; object Reason_TimeConflict is boolean; object Reason_Instructor is boolean; object Reason_OtherString is components: string and boolean; end; object StudentComments is string; operation AddStudent is inputs: sr:StudentRecord, sdb:StudentDB; outputs: sdb':StudentDB; precondition: (* There is no student record in the input database (StudentDB) with the same id as the record to be added. *) (not (exists (sr' in sdb) sr'.id = sr.id)) and (* The id of the given student record is not empty and 32 characters or less. *) (sr.id != nil) and (#(sr.id) <= 32); postcondition: (* A student record is in the output database iff it is the new record to be added or it is in the input database *) forall (sr':StudentRecord) (sr' in sdb') iff ((sr' = sr) or (sr' in sdb)); description: (* Adds a student record to the database if its ID is a suitable number of characters and a record does not already exist with the same ID. *); end AddStudent; operation RemoveStudent is inputs: sr:StudentRecord, sdb:StudentDB; outputs: sdb':StudentDB; precondition: (* The given student record is in the given database *) sr in sdb; postcondition: (* A user record is in the output db iff it is not the input record and it is in the input db. *) (forall (sr':StudentRecord) (sr' in sdb') iff ((sr' != sr) and (sr' in sdb))); description: (* Removes a specific student record from the database, if it exists in the database. *); end RemoveStudent; operation ChangeStudent is inputs: old_sr:StudentRecord, new_sr:StudentRecord, sdb:StudentDB; outputs: sdb':StudentDB; precondition: (* The old and new records are not the same *) (old_sr != new_sr) and (* The old record is in the input database *) (old_sr in sdb) and (* There is no user record in the input database with the same id as the new record unless it is the old record *) (exists (sr' in sdb) (sr'.id = new_sr.id)) iff (exists (sr' in sdb) (sr' = old_sr)) and (* The id of the new record is not empty and is 32 characters or less *) (new_sr.id != nil) and (#(new_sr.id) <= 32); postcondition: (* A student record is in the output database iff it is the new record to be added or it is in the input database, and it is not the old record *) forall (sr':StudentRecord) (sr' in sdb') iff (((sr' = new_sr) or (sr' in sdb)) and (sr' != old_sr)); description: (* Finds a specific student record in the input database and replaces it with the new input record. The two input records must not be the same. The old record must be in the input database. The new record must meet the conditions for adding a record (AddStudent). *); end ChangeStudent; operation FindStudent is inputs: name:StudentName, sdb:StudentDB; outputs: srl:StudentRecord*; precondition: (* name is not empty *) (name != nil); postcondition: (* The output list contains all records with the input name in the input database *) (forall (sr' in srl) (sr' in sdb) and (sr'.name = name)) and (* The output list is sorted alphabetically by id (courtesy of Dr. Gene Fisher) *) (forall (i:integer | (i >= 1) and (i < #srl)) srl[i].id < srl[i+1].id); description: (* Searches the student database for records with matching student name. If more than one is found, the output list is sorted by id. *); end FindStudent; operation FindStudent is inputs: id:StudentID, sdb:StudentDB; outputs: sr':StudentRecord; precondition: (* id is not empty, and is 32 characters or less *) (id != nil) and (#id <= 32); postcondition: (* If there is a record with the given id in the input database, then the output record is equal to it, otherwise the output record is empty. *) (exists (sr in sdb) (sr.id = id) and (sr' = sr)) or (sr' = nil); description: (* Searches the student database for a record with matching student ID number *); end FindStudent; operation ImportDatabase is inputs: xdb:XExternalDatabase; outputs: sdb':StudentDB; precondition: (* The input database is readable as full of student records *) xdb.conv; postcondition: (* All student records in the output database are also in the input database *) (forall (sr:StudentRecord) (sr in xdb.srl) iff (sr in sdb')); description: (* Replaces the current student database with the contents of an external database. *); end ImportDatabase; object XExternalDatabase is components: conv:CanBeConverted, srl:StudentRecord*; description: (* Contains student records in a format that can be read by the system. *); end; object CanBeConverted is boolean; operation GenerateReport is inputs: sdb:StudentDB; outputs: rv:ReportView; precondition: (* none ... works even if StudentDB is empty *) ; postcondition: (* ReportView contains all comments in the database, as well as all courseTried objects *) forall (sr:StudentRecord | sr in sdb.studreclst) (if sr.comments != nil then (exists(com':StudentComments | com' in rv.comlst) (com' = sr.comments))) and forall (sr:StudentRecord | sr in sdb.studreclst) (if #(sdb.studreclst) != 0 then (exists(ct:CourseTried | ct in rv.cselst) ((forall(ct':CourseTried | ct' in sr.cdb) ct' = ct)))); description: (* Generates a dialog to display detailed information about student statistics. *); end GenerateReport; object ReportView is components: comlst:StudentComments*, cselst:CourseTried*; description: (* Generate a list of comments and attempted courses from the student database in order to generate a report. *); end; end StudentDB;