Student.als

module Student

sig Time {}

sig Name {}

fact { all n : Name | lone name.n }

sig Course {
    labs : some Lab
}

sig Lab {}

fact { all l : Lab | lone labs.l }

enum Grade { A,B,C,D,E }

sig Student {
    name : one Name,
    approved : Course -> Time,
    current : Course lone -> Time,
    donelabs : Lab -> Time,
    exams : Course -> Grade lone -> Time
}

fact { all t : Time | all s : Student | s.current.t not in s.approved.t }

fact { all t : Time | all s : Student | all c : s.approved.t | 
    c.labs in s.donelabs.t and c.(s.exams.t) in A+B+C+D
}

fact { all t : Time | all s : Student | 
    (s.current.t + s.approved.t + (s.exams.t).Grade) in ((students.t).s).courses 
}

sig College {
    students : Student -> Time,
    courses : set Course
}

fact { all t : Time | all s : Student | one (students.t).s }

run {} for 4 but exactly 1 Student, exactly 1 Time

pred newstudent [c : College, s : Student, t,t' : Time] {
    no (students.t).s
    no s.approved.t
    no s.current.t
    no s.donelabs.t
    no s.exams.t

    students.t' = students.t + c -> s
}

pred enroll [s : Student, c : Course, t,t' : Time] {
    no s.current.t
    c not in s.approved.t

    current.t' = current.t + s -> c
}

pred lab [s : Student, l : Lab, t,t' : Time] {
    some s.current.t
    l not in (s.donelabs.t)
    l in (s.current.t).labs

    donelabs.t' = donelabs.t + s -> l
}

pred exam [s : Student, g : Grade, t,t' : Time] {
    some s.current.t
    s.current.t not in (s.exams.t).Grade

    exams.t' = exams.t + s -> s.current.t -> g
}

pred approve [s : Student, t,t' : Time] {
    some s.current.t
    (s.current.t).(s.exams.t) in A+B+C+D
    (s.current.t).labs in s.donelabs.t

    approved.t' = approved.t + s -> s.current.t
    current.t' = current.t - s -> Course
}

pred quit [s : Student, t,t' : Time] {
    some s.current.t

    exams.t' = exams.t - s -> s.current.t -> Grade
    donelabs.t' = donelabs.t - s -> (s.current.t).labs
    current.t' = current.t - s -> Course
}

Related

Wiki: Home

MongoDB Logo MongoDB