module Syncing; from QuestionManagement import all; export all; object SyncCriteria is components: crit:Criteria*; description: (* Contains all of the criteria for searching for questions to sync. *); end SyncCriteria; obj RemoteAddress is string; object Criteria is components: au:Author or cl:Class or ty:Type or dif:Difficulty or Keyword*; description: (* a criteria that a question can be checked against *); end Criteria; object QuestionsToRetrieve is components: q:Question* ; description: (* The list of questions to retrieve from question db server *); end QuestionsToRetrieve; object QuestionsToSend is components: q:Question* ; description: (* The list of questions to be sent to the question db server *); end QuestionstoSend; operation FindQuestionsToRetrieve is inputs: syncCrit:SyncCriteria, qdb:QuestionDatabase, orig_qdb:QuestionDatabase; outputs: qtr:QuestionsToRetrieve ; description: (* finds the questions that match the search criteria on the central qdb server *); precondition: ; postcondition: (forall(q in qdb.qs) q in qtr.q iff (forall(crit in syncCrit.crit) meetsCriteria(crit, q))) and (forall (q' in qtr.q) (q' in qdb.qs)) and (forall (q' in qtr.q) (not(q' in orig_qdb.qs))); end FindQuestionsToRetrieve; operation FindQuestionsToSend is inputs: syncCrit:SyncCriteria, qdb:QuestionDatabase, remote_qdb:QuestionDatabase; outputs: qts:QuestionsToSend ; description: (* seaches local question DB for questions to load to server *); precondition: ; postcondition: (forall(q in qdb.qs) q in qts.q iff (forall(crit in syncCrit.crit) meetsCriteria(crit, q))) and (forall (q' in qts.q) q' in qdb.qs) and (forall (q' in qts.q) not(q' in remote_qdb.qs)); end FindQuestionsToSend; operation RetrieveQuestions is inputs: qtr:QuestionsToRetrieve, qdb:QuestionDatabase; outputs: qdb':QuestionDatabase; description: (* adds the retrieved questions to the local question database *); precondition: forall(q in qtr.q) not(q in qdb.qs) ; postcondition: (forall (q in qdb.qs) (q in qdb'.qs)) and (forall (q in qtr.q) (q in qdb'.qs)) and (forall (q' in qdb'.qs) (q' in qdb.qs or q' in qtr.q)) and (#qdb'.qs = #qtr.q + #qdb.qs); end RetrieveQuestions; operation SendQuestions is inputs: qts:QuestionsToSend, RemoteAddress, qdb:QuestionDatabase; outputs: qdb':QuestionDatabase; description: (* adds the sent questions to the remote question database *); precondition: forall(q in qts.q) not(q in qdb.qs); postcondition: (forall (q in qdb.qs) (q in qdb'.qs)) and (forall (q in qts.q) (q in qdb'.qs)) and (forall (q' in qdb'.qs) (q' in qdb.qs or q' in qts.q)) and (#qdb'.qs = #qts.q + #qdb.qs); end SendQuestions; function meetsCriteria(Criteria, Question) (* I'm unsure how to do this in RSL because I or'ed the different categories of criteria, but this means true if the given questions meets the given criteria*) end meetsCriteria; function questionEquality(q:Question, q':Question)= q.author = q'.author and q.t = q'.t and q.qt = q'.qt and q.qa = q'.qa and q.time = q'.time and q.diff = q'.diff and q.keywords = q'.keywords and q.class = q'.class; end Syncing;