5.5. Courses Database (Courses Database)

(****
 *
 * This file defines objects and operations related to the courses database.
 *)

object CourseDB
   components: CourseRecord* and SubjectList;
   operations: AddCourse, AddSubject, EditCourse, DeleteCourse, ViewCourse;
   description: (*
      CourseDB is the database containing the course records that provide information 
      about the courses that can be scheduled. It is a collection of CourseRecords.  
   *);                                     
end CourseDB;

object CourseRecord
   components: sub:Subject and title:Title and num:Number and type:Type and 
      max:MaxEnrollment and wtu:WTU and scu:SCU and equip:Equipment
      and num_comp:NumComputers and desc:Descrip;
   description: (*
      A CourseRecord is the information stored about a course that can
      be scheduled. It has a Subject, Title, and Number which identify
      what the course is. The Subject and Title are both free-form strings.
      The Type indicates whether it is a Lecture or a Lab. The MaxEnrollment
      component is an integer representing the maximum number of students that
      can be enrolled in the class. The WTU component represents the work
      time units the course is worth. The SCU component represents the 
      student course units the course is worth. These last three components are
      all integers. The Equipment component contains the equipment that are
      required for the course. The NumComputers is the number of computers needed
      for a course, if any. The Descrip component is the full description of the
      course found in the school's course catalog.
   *);
end CourseRecord;

object SubjectList
   components: Subject*;
   description: (*
      A SubjectList is a list of all the subjects that a course can be listed under.
   *);
end SubjectList;

object Subject
   components: name:Name, abv:Abbreviation;
   description: (* The subject of the course contains a name and an abbreviation. *);
end Subject;

object Name = string
   description: (* The name of the subject. *);
end Name;

object Abbreviation = string
   description: (*The abbreviation of the subject.*);
end Abbreviation;

object Title = string
   description: (* The title of the course. *);
end Title;

object Number = integer
   description: (* The course number. *);
end Number;

object Type = Lecture or Lab
   description: (* Indicates if the course is a Lecture or a Lab. *);
end Type;

object Lecture = boolean
   description: (* Indicates if the course is a Lecture. *);
end Lecture;

object Lab = boolean
   description: (* Indicates if the course is a lab. *);
end Lab;

object MaxEnrollment = integer
   description: (*
      The maximum number of students that can be enrolled in a
      section of this course.
   *);
end MaxEnrollment;

object WTU = integer
   description: (* The work time units of the course. *);
end WTU;

object SCU = integer
   description: (* The student course units of the course. *);
end SCU;

object Equipment
   components: Computers and Projector and TV and DVDPlayer and Other;
   description: (*
      The list of equipment required for the course. There are five 
      possible choices for equipment that is required for the course.
   *);   
end Equipment;

object Computers = boolean
   description: (* Indicates if the course requires computers. *);
end Computers;

object NumComputers = integer
   description: (* The number of computers are needed for the course, if any. *);
end NumComputers;

object Projector = boolean
   description: (* Indicates if the course requires a projector. *);
end Projector;

object TV = boolean
   description: (* Indicates if the course requires a TV. *);
end TV;

object DVDPlayer = boolean
   description: (* Indicates if the course requires a DVD player. *);
end DVDPlayer;

object Other = boolean
   description: (* Indicates if the course requires equipment that is not listed. *);
end Other;

object Descrip = string
   description: (*
      Descrip is a plain text string describing the course.
   *);   
end Descrip;

operation AddCourse
   inputs: cdb:CourseDB, cr:CourseRecord;
   outputs: cdb':CourseDB;
   description: (*
      Add the given CourseRecord to the given CourseDB.
      The Title of the given course record must not be 
      the same as a course record already in the CourseDB.
   *);

   precondition:
      (*
       * There is no course record in the input CourseDB with 
       * the same title as the record to be added.
       *)
      (not (exists (cr' in cdb) cr'.title = cr.title))

         and

      (*
       * There is no course record in the input CourseDB with
       * the same combination of Subject and Number.
       *)
      (not (exists (cr' in cdb) (cr'.subject = cr.subject and cr'.num = cr.num)))

         and

      (*
       * The subject is not empty.
       *)
      (cr.subject != nil)

         and

      (*
       * The title is not empty.
       *)
      (cr.title != nil)

         and
      (*
       * The course number is not empty.
       *)
      (cr.num != nil)

         and
      (*
       * The type is not empty. 
       *)
      (cr.type != nil)

         and
      (*
       * The WTU is not empty.
       *)
      (cr.wtu != nil)

         and
      (*
       * The SCU is not empty.
       *)
      (cr.scu != nil);

   postcondition:
      (*
       * A course record in the output db if and only if it is the new
       * record to be added or it is in the input db.
       *)
      forall (cr':CourseRecord)
         (cr' in cdb') iff ((cr' = cr) or (cr' in cdb));

end AddCourse;

operation AddSubject
   inputs: sub:Subject, sl:SubjectList;
   outputs: sl':SubjectList;
   description: (*
      Add the given Subject to the given SubjectList.
   *);
   precondition:
      (*
       * There is no subject in the input SubjectList with 
       * the same name or abbreviation as the subject to be added.
       *)
      (not (exists (sub' in sl) (sub'.name = sub.name) or (sub'.abv = sub.abv)))

         and


      (*
       * The name is not empty.
       *)
      (sub.name != nil)

         and

      (*
       * The abbreviation is not empty.
       *)
      (sub.abv != nil);

   postcondition:
      (*
       * A subject is in the output subject list if and only if it is the new
       * subject to be added or it is in the input subject list.
       *)
      forall (sub':Subject)
         (sub' in sl') iff ((sub' = sub) or (sub' in sl));
end AddSubject;

operation EditSubject
   inputs: sl:SubjectList, old_sub:Subject, new_sub:Subject;
   outputs: sl':SubjectList;
   description: (*
      Change the given old Subject to the given new subject.
      The old subject must already be in the input list. The new
      subject must meet the same conditions as for the input to the
      AddSubject operation. 
   *);

   precondition:
      (*
       * The old subject is in the given subject list.
       *)
      (old_sub in sl)

	     and
		 
      (*
       * There is no subject in the input SubjectList with 
       * the same name or abbreviation as the subject to be added.
       *)
      (not (exists (new_sub' in sl) (new_sub'.name = new_sub.name) or (new_sub'.abv = new_sub.abv)))

         and

      (*
       * The name is not empty.
       *)
      (new_sub.name != nil)

         and

      (*
       * The abbreviation is not empty.
       *)
      (new_sub.abv != nil);

   postcondition:
      (*
       * A subject is in the output list if and only if it is the 
       * new  subject to be added or it is in the input list.
       *)
      forall (sub':Subject)
         (sub' in sl') iff (((sub' = new_sub) or (sub' in sl)));

end EditSubject;

operation DeleteSubject
   inputs: sl:SubjectList, sub:Subject;
   outputs: sl':SubjectList;
   description: (*
      Delete the given subject from the given SubjectList.
      The given record must already be in the input list.
   *);

   precondition:
      (*
       * The given Subject is in the given SubjectList.
       *)
      sub in sl;

   postcondition:
      (*
       * A subject is in the output list if and only if it is
       * not the existing subject to be deleted and it is in the input
       * list.
       *)
      (forall (sub':Subject)
         (sub' in sl') iff ((sub' != sub) and (sub' in sl)));
		 
end DeleteSubject;

operation EditCourse
   inputs: cdb:CourseDB, old_cr:CourseRecord, new_cr:CourseRecord;
   outputs: cdb':CourseDB;
   description: (*
      Change the given old CourseRecord to the given new record.
      The old record must already be in the input db. The new
      record must meet the same conditions as for the input to the
      AddCourse operation. 
   *);

   precondition:
      (*
       * The old record is in the given db.
       *)
      old_cr in cdb
		
         and

      (*
       * There is no course record in the input CourseDB with 
       * the same title as the record to be added.
       *)
      (not (exists (new_cr' in cdb) new_cr'.title = new_cr.title))

         and

      (*
       * There is no course record in the input CourseDB with
       * the same combination of Subject and Number.
       *)
      (not (exists (new_cr' in cdb) (new_cr'.subject = new_cr.subject and new_cr'.num = new_cr.num)))

         and

      (*
       * The subject is not empty.
       *)
      (new_cr.subject != nil)

         and

      (*
       * The title is not empty.
       *)
      (new_cr.title != nil)

         and
      (*
       * The course number is not empty.
       *)
      (new_cr.num != nil)

         and
      (*
       * The type is not empty. 
       *)
      (new_cr.type != nil)

         and
      (*
       * The WTU is not empty.
       *)
      (new_cr.wtu != nil)

         and
		 
      (*
       * The SCU is not empty.
       *)
      (new_cr.scu != nil);

   postcondition:
      (*
       * A course record is in the output db if and only if it is the 
       * new record to be added or it is in the input db.
       *)
      (forall (cr':CourseRecord)
         (cr' in cdb') iff ((cr' = new_cr) or (cr' in cdb)));

end EditCourse;

operation DeleteCourse
   inputs: cdb:CourseDB, cr:CourseRecord;
   outputs: cdb':CourseDB;
   description: (*
      Delete the given course record from the given CourseDB.
      The given record must already be in the input db.
   *);

   precondition:
      (*
       * The given CourseRecord is in the given CourseDB.
       *)
      cr in cdb;

   postcondition:
      (*
       * A course record is in the output db if and only if it is
       * not the existing record to be deleted and it is in the input
       * db.
       *)
      (forall (cr':CourseRecord)
         (cr' in cdb') iff ((cr' != cr) and (cr' in cdb)));
		 
end DeleteCourse;

operation ViewCourse
   inputs: cdb:CourseDB, cr:CourseRecord;
   outputs: cdb':CourseDB;
   description: (*
      View the given course record in the given CourseDB.
      The given record must already be in the input db.
   *);

   precondition:
      (*
       * The given CourseRecord is in the given CourseDB.
       *)
      cr in cdb;

   postcondition: ;
end ViewCourse;

operation FilterCourses
   inputs: cdb:CourseDB, sub:Subject;
   outputs: crl:CourseRecord*;
    description: (*
        Find a course or courses by subject. If more than one is found,
        the output list is sorted by course number.
    *);

    precondition: ;

    postcondition:
        (*
         * The output list consists of all records of the given subject in the
         * input db.
         *)
        (forall (cr' in crl) (cr' in cdb) and (cr'.sub = sub))

            and

        (*
         * The output list is sorted by Course Number.
         *)
        (forall (i:integer | (i >= 1) and (i < #crl))
            crl[i].num < crl[i+1].num);

end FilterCourses;

operation FilterCourses
   inputs: cdb:CourseDB, type:Type;
   outputs: crl:CourseRecord*;
    description: (*
        Find a course or courses by Type.  If more than one is found,
        the output list is sorted  alphabetically by Course Title.
    *);

    precondition: ;

    postcondition:
        (*
         * The output list consists of all records of the given type in the
         * input db.
         *)
        (forall (cr' in crl) (cr' in cdb) and (cr'.type = type))

            and

        (*
         * The output list is sorted alphabetically by Course Title.
         *)
        (forall (i:integer | (i >= 1) and (i < #crl))
            crl[i].title < crl[i+1].title);

end FilterCourses;

operation FilterCourses
   inputs: cdb:CourseDB, num:Number;
   outputs: crl:CourseRecord*;
    description: (*
        Find a course or courses by Course Number.  If more than one is found,
        the output list is sorted alphabetically by subject.
    *);

    precondition: ;

    postcondition:
        (*
         * The output list consists of all records of the given course number in the
         * input db.
         *)
        (forall (cr' in crl) (cr' in cdb) and (cr'.num = num))

            and

        (*
         * The output list is sorted alphabetically by subject.
         *)
        (forall (i:integer | (i >= 1) and (i < #crl))
            crl[i].sub < crl[i+1].sub);

end FilterCourses;










Prev: schedule.sl | Next: admin.sl | Up: spec | Top: index