Theory Prelim

(* Preliminaries concerning the involved data types and auxiliary functions  *)
theory Prelim
  imports "Fresh_Identifiers.Fresh_String" "Bounded_Deducibility_Security.Trivia"
begin


subsection ‹The basic types›

(*  This version of string is needed for code generation: *)
type_synonym string = String.literal
definition "emptyStr = STR ''''"

type_synonym phase = nat

(* Conference phases: no phase, setup, submission, bidding, reviewing, discussion, notification, closed *)
abbreviation "noPH ≡ (0::nat)"    abbreviation "setPH ≡ Suc noPH"  abbreviation "subPH ≡ Suc setPH"
abbreviation "bidPH ≡ Suc subPH"  abbreviation "revPH ≡ Suc bidPH" abbreviation "disPH ≡ Suc revPH"
abbreviation "notifPH ≡ Suc disPH"  abbreviation "closedPH ≡ Suc notifPH"

fun SucPH where
"SucPH ph = (if ph = closedPH then closedPH else Suc ph)"

(* The users of the system: *)
datatype user = User string string string
fun nameUser where "nameUser (User name info email) = name"
fun infoUser where "infoUser (User name info email) = info"
fun emailUser where "emailUser (User name info email) = email"
definition "emptyUser ≡ User emptyStr emptyStr emptyStr"

typedecl raw_data
code_printing type_constructor raw_data ⇀ (Scala) "java.io.File"

(* paper content: *)
datatype pcontent = NoPContent | PContent raw_data

datatype score = NoScore | MinusThree | MinusTwo | MinusOne | Zero | One | Two | Three

fun scoreAsInt :: "score ⇒ int" where
 "scoreAsInt MinusThree = -3"
|"scoreAsInt MinusTwo = -2"
|"scoreAsInt MinusOne = -1"
|"scoreAsInt Zero = 0"
|"scoreAsInt One = 1"
|"scoreAsInt Two = 2"
|"scoreAsInt Three = 3"

datatype exp = NoExp | Zero | One | Two | Three | Four (* expertise *)
(* A review content consists of an expertise, a score and the review text *)
(* review content: *)
type_synonym rcontent = "exp * score * string"
fun scoreOf :: "rcontent ⇒ score" where "scoreOf (exp,sc,txt) = sc"
(* A review is a list of review contents, with the first (i.e., the head) being the most recent. *)
type_synonym review = "rcontent list"
(* A reviewer may change the expertise, score and the review (multiple times) during the discussion phase,
   but all changes should be transparent, i.e., history of changes should be recorded;
   this is why a review is a list of review contents rather than a single review content.
*)

abbreviation emptyReview :: review where "emptyReview ≡ []"
datatype discussion = Dis "string list"
definition "emptyDis ≡ Dis []"
datatype decision = NoDecision | Accept | Reject

(* A paper consists of strings for title and abstract,
the paper content, the associated reviews, a discussion and an (updatable) decision.
 *)
datatype paper = Paper string string pcontent "review list" discussion "decision list"

fun titlePaper where "titlePaper (Paper title abstract content reviews dis decs) = title"
fun abstractPaper where "abstractPaper (Paper title abstract content reviews dis decs) = abstract"
fun contentPaper where "contentPaper (Paper title abstract content reviews dis decs) = content"
fun reviewsPaper where "reviewsPaper (Paper title abstract content reviews dis decs) = reviews"
fun disPaper where "disPaper (Paper title abstract content reviews dis decs) = dis"
(* all successive decisions for a paper, listed historically: *)
fun decsPaper where "decsPaper (Paper title abstract content reviews dis decs) = decs"
(* the current decision: *)
fun decPaper where "decPaper pap = hd (decsPaper pap)"



definition emptyPaper :: paper where
"emptyPaper ≡ Paper emptyStr emptyStr NoPContent [] emptyDis []"

(* Data (info) associated to a conference: *)
datatype conf = Conf string string
fun nameConf where "nameConf (Conf name info) = name"
fun infoConf where "infoConf (Conf name info) = info"
definition "emptyConf ≡ Conf emptyStr emptyStr"

datatype password = Password string
definition "emptyPass ≡ Password emptyStr"

datatype preference = NoPref | Want | Would | WouldNot | Conflict


subsection ‹Conference, user and paper IDs›

datatype userID = UserID string
datatype paperID = PaperID string
datatype confID = ConfID string

definition "emptyUserID ≡ UserID emptyStr"
definition "voronkovUserID ≡ UserID (STR ''voronkov'')"
definition "emptyPaperID ≡ PaperID emptyStr"
definition "emptyConfID ≡ ConfID emptyStr"

(* Roles: author, reviewer (owner of the nth review of a paper), program committee (PC) member, chair *)
datatype role = Aut paperID | Rev paperID nat | PC | Chair
fun isRevRole where "isRevRole (Rev _ _ ) = True" | "isRevRole _ = False"

fun isRevRoleFor :: "paperID ⇒ role ⇒ bool" where
 "isRevRoleFor papID (Rev papID' n) ⟷ papID = papID'"
|"isRevRoleFor papID _ ⟷ False"

(* *)
fun userIDAsStr where "userIDAsStr (UserID str) = str"

definition "getFreshUserID userIDs ≡ UserID (fresh (set (map userIDAsStr userIDs)) (STR ''1''))"

lemma UserID_userIDAsStr[simp]: "UserID (userIDAsStr userID) = userID"
by (cases userID) auto

lemma member_userIDAsStr_iff[simp]: "str ∈ userIDAsStr ` (set userIDs) ⟷ UserID str ∈∈ userIDs"
by (metis UserID_userIDAsStr image_iff userIDAsStr.simps)

lemma getFreshUserID: "¬ getFreshUserID userIDs ∈∈ userIDs"
  using fresh_notIn[of "set (map userIDAsStr userIDs)" "STR ''1''"]
  by (auto simp: getFreshUserID_def)

instantiation userID :: linorder
begin
definition le_userID_def: "uid ≤ uid' ≡ case (uid,uid') of (UserID str, UserID str') ⇒ str ≤ str'"
definition lt_userID_def: "uid < uid' ≡ case (uid,uid') of (UserID str, UserID str') ⇒ str < str'"
instance by standard (auto simp: le_userID_def lt_userID_def split: userID.splits)
end

(*  *)
fun paperIDAsStr where "paperIDAsStr (PaperID str) = str"

definition "getFreshPaperID paperIDs ≡ PaperID (fresh (set (map paperIDAsStr paperIDs)) (STR ''2''))"

lemma PaperID_paperIDAsStr[simp]: "PaperID (paperIDAsStr paperID) = paperID"
by (cases paperID) auto

lemma member_paperIDAsStr_iff[simp]: "str ∈ paperIDAsStr ` paperIDs ⟷ PaperID str ∈ paperIDs"
by (metis PaperID_paperIDAsStr image_iff paperIDAsStr.simps)

lemma getFreshPaperID: "¬ getFreshPaperID paperIDs ∈∈ paperIDs"
  using fresh_notIn[of "set (map paperIDAsStr paperIDs)" "STR ''2''"]
  by (auto simp: getFreshPaperID_def)

instantiation paperID :: linorder
begin
definition le_paperID_def: "uid ≤ uid' ≡ case (uid,uid') of (PaperID str, PaperID str') ⇒ str ≤ str'"
definition lt_paperID_def: "uid < uid' ≡ case (uid,uid') of (PaperID str, PaperID str') ⇒ str < str'"
instance by standard (auto simp: le_paperID_def lt_paperID_def split: paperID.splits)
end

(*  *)
fun confIDAsStr where "confIDAsStr (ConfID str) = str"

definition "getFreshConfID confIDs ≡ ConfID (fresh (set (map confIDAsStr confIDs)) (STR ''2''))"

lemma ConfID_confIDAsStr[simp]: "ConfID (confIDAsStr confID) = confID"
by (cases confID) auto

lemma member_confIDAsStr_iff[simp]: "str ∈ confIDAsStr ` (set confIDs) ⟷ ConfID str ∈∈ confIDs"
by (metis ConfID_confIDAsStr image_iff confIDAsStr.simps)

lemma getFreshConfID: "¬ getFreshConfID confIDs ∈∈ confIDs"
  using fresh_notIn[of "set (map confIDAsStr confIDs)" "STR ''2''"]
  by (auto simp: getFreshConfID_def)

instantiation confID :: linorder
begin
definition le_confID_def: "uid ≤ uid' ≡ case (uid,uid') of (ConfID str, ConfID str') ⇒ str ≤ str'"
definition lt_confID_def: "uid < uid' ≡ case (uid,uid') of (ConfID str, ConfID str') ⇒ str < str'"
instance by standard (auto simp: le_confID_def lt_confID_def split: confID.splits)
end


end