--needed objects:
module StudentFeedback;

from Databases import CourseDB, Course, CourseTitle;



object StudentCourseRequestDB is StudentCourseRequest*;

object StudentCourseRequest is 

   description: (* *);

   components: student_ID:string and title:CourseTitle and qrtr:Quarter;

end StudentCourseRequest;



object Quarter is

   description: (* *);

   components: season:Season and year:integer;



end Quarter;



object Season is Winter or Spring or Summer or Fall;

object Winter;

object Spring;

object Summer;

object Fall;


object StudentCourseCommentDB is StudentCourseComment*;

object StudentCourseComment is

   description: (* *);

   components: student_ID:string and title:CourseTitle and comment:string;

end StudentCourseComment;



operation AddStudentCourseRequest is

   inputs: rDB:StudentCourseRequestDB, r:StudentCourseRequest;

   outputs: rDB':StudentCourseRequestDB;

   pre: (* The student may not already have a course request for
           this course in the database for the selected quarter*)

        forall (rec in rDB)
         (rec != r);

   post: 

        rDB' = rDB + r;

end AddStudentCourseRequest;



operation AddStudentCourseComment is

   inputs: rDB:StudentCourseCommentDB, c:StudentCourseComment;

   outputs: rDB':StudentCourseCommentDB;



   pre: (* The student may not already have a comment for
         * this course in the database *)

        forall (cr in rDB)
        (  (c.student_ID != cr.student_ID) and
           (c.title != cr.title)
        );

   post: 

        rDB' = rDB + c;

end AddStudentCourseComment;



object CourseRequestViewRow is

components: crs:CourseTitle and crl:CourseRequestsPerQuarter*;

end StudentCourseRequestViewRow;



object CourseRequestsPerQuarter is

components: qrtr:Quarter and requests:integer;

end CourseRequestsPerQuarter;



operation ViewStudentCourseRequests is

   inputs: rdb:StudentCourseRequestDB, cdb:CourseDB, 
           temp_list:StudentCourseRequest*;

   outputs: rl':CourseRequestViewRow*;

   pre: (* None *);

   post: 
       forall (crs in cdb)
       (  exists (r in rl')
          (  (r.crs = crs.title)
       )  ) and
       
       (* for all rows in the output list *)
       forall (r in rl')
       (  
          (* for all quarters in the row *)
          forall (q in r.crl)
          (  
             (* for all requests in the request DB, if the course matches
              * the row and the quarter matches the column, then the request
              * is in a list and the number of requests is equal to the length
              * of that list *)
             forall (rqst in rdb)
             (  if ((rqst.title = r.crs) and (rqst.qrtr = q.qrtr))
                then 
                (  exists (rqst2 in temp_list)
                   (  rqst = rqst2 )
                )
             ) and
             q.requests = #temp_list
          )
       );

end ViewStudentCourseRequests;



operation ViewStudentCourseComment is

   inputs: rDB:StudentCourseCommentDB, r:StudentCourseComment;

   outputs: rDB':StudentCourseCommentDB;



   pre: (* *);

   post: (* *);


end ViewStudentCourseComment;

end StudentFeedback;