hCM-0.1.0.0: app/Example.hs
{-# LANGUAGE RecordWildCards #-}
module Example where
import Data.Maybe
import CM.Metamodel
import CM.Visualization
import CM.Validity
import CM.Helpers
wrapString :: String -> String
wrapString x = "\"" ++ x ++ "\""
shortenString :: String -> String
shortenString x = if length x < 35 then x else take 32 x ++ "..."
toInts :: [String] -> [Int]
toInts = map read
data Student = Student { stUsername :: String
, stFirstname :: String
, stLastname :: String
}
deriving (Show, Read)
instance Identifiable Student where
identifier = stUsername
instance CMElement Student where
toMeta = toMetaEntity
instance Entity Student where
entityAttributes Student {..} =
map tupleToAttribute
[ ("username", "String", wrapString stUsername)
, ("firstname", "String", wrapString stFirstname)
, ("lastname", "String", wrapString stLastname)
, ("email", "String", wrapString $ stUsername ++ "@fit.cvut.cz")
]
data Course = Course { crsCode :: String
, crsCredits :: Int
, crsName :: String
, crsDesc :: String
}
deriving (Show, Read)
instance Identifiable Course where
identifier = crsCode
creditsNonNegative :: Course -> Validity
creditsNonNegative Course {..} =
newConstraint (crsCredits >= 0) "Negative credits"
instance CMElement Course where
toMeta = toMetaEntity
simpleConstraints = [creditsNonNegative]
instance Entity Course where
entityAttributes Course {..} =
map tupleToAttribute
[ ("code", "String", wrapString crsCode)
, ("name", "String", wrapString crsName)
, ("credits", "Int", show crsCredits)
, ("descrition", "String", wrapString . shortenString $ crsDesc)
]
data Enrollment = Enrollment { enrlSince :: (Int, Int, Int)
, enrlUntil :: Maybe (Int, Int, Int)
}
deriving (Show, Read)
instance Identifiable Enrollment
toDateStr :: (Int, Int, Int) -> String
toDateStr (d,m,y) = show d ++ "/" ++ show m ++ "/" ++ show y
sinceBeforeUntil :: Enrollment -> Validity
sinceBeforeUntil Enrollment {enrlUntil = Nothing, ..} = Valid
sinceBeforeUntil Enrollment {enrlSince = a, enrlUntil = Just b} =
newConstraint (a < b) "Since is not before until"
instance CMElement Enrollment where
toMeta = toMetaEntity
simpleConstraints = [sinceBeforeUntil]
instance Entity Enrollment where
entityAttributes Enrollment {..} =
map tupleToAttribute
[ ("since", "DateTime", toDateStr enrlSince)
, ("until", "Maybe DateTime", maybe "N/A" toDateStr enrlUntil)
]
data IsEnrolled = IsEnrolled { ieWho :: Student
, ieWhat :: Course
, ieTruth :: Enrollment
}
deriving (Show, Read)
instance Identifiable IsEnrolled
max2Enrollments :: (ConceptualModel m) => m -> IsEnrolled -> Validity
max2Enrollments model r =
newConstraint (same <= 2) "Student can enroll same course only twice"
where same = length . filter areSame $ enrolledRelationships
areSame e = (sameCourse e) && (sameStudent e)
sameCourse e = (getCourseId e) == (identifier . ieWhat $ r)
sameStudent e = (getStudentId e) == (identifier . ieWho $ r)
enrolledRelationships = filter isIsEnrolled $ cmodelElements model
getCourseId MetaRelationship {..} = findParticipantId mrParticipations "Course"
getCourseId _ = ""
getStudentId MetaRelationship {..} = findParticipantId mrParticipations "Student"
getStudentId _ = ""
isIsEnrolled MetaRelationship {mrName = "IsEnrolled", ..} = True
isIsEnrolled _ = False
instance CMElement IsEnrolled where
toMeta = toMetaRelationship
complexConstaints = [max2Enrollments]
instance Relationship IsEnrolled where
relationshipName _ = "enrolled"
relationshipParticipations IsEnrolled {..} =
map tupleToParticipation
[ ("who", "Student", identifier ieWho, Optional Unlimited)
, ("what", "Course", identifier ieWhat, Optional Unlimited)
, ("truthmaker", "Enrollment", identifier ieTruth, Mandatory Unique)
]
studM = Student { stUsername = "suchama4"
, stFirstname = "Marek"
, stLastname = "Suchánek"
}
courseDIP = Course { crsCode = "MI-DIP"
, crsCredits = 23
, crsName = "Diploma Project"
, crsDesc = ""
}
courseRRI = Course { crsCode = "MI-RRI.0"
, crsCredits = -5
, crsName = "Risk Management in Informatics"
, crsDesc = "Information security is very often considered as one of main objectives to secure targets of information processing. "
}
enrlMxDIP = Enrollment { enrlSince = (20,2,2017)
, enrlUntil = Just (1,6,2016)
}
enrlMxRRI = Enrollment { enrlSince = (20,2,2017)
, enrlUntil = Nothing
}
ienrlMxDIP = IsEnrolled { ieWho = studM, ieWhat = courseDIP, ieTruth = enrlMxDIP }
ienrlMxRRI = IsEnrolled { ieWho = studM, ieWhat = courseRRI, ieTruth = enrlMxRRI }
data ExampleModel = ExampleModel { mStudents :: [Student]
, mCourses :: [Course]
, mEnrollments :: [Enrollment]
, mIsEnrolled :: [IsEnrolled]
}
deriving (Show, Read)
instance CMElement ExampleModel where
toMeta = toMetaModel
instance ConceptualModel ExampleModel where
cmodelElements m = (map (toMeta m) $ mStudents m)
++ (map (toMeta m) $ mCourses m)
++ (map (toMeta m) $ mEnrollments m)
++ (map (toMeta m) $ mIsEnrolled m)
model = ExampleModel { mStudents = [studM]
, mCourses = [courseDIP, courseRRI]
, mEnrollments = [enrlMxDIP, enrlMxRRI]
, mIsEnrolled = [ienrlMxDIP, ienrlMxRRI]
}