ClassAna.hs revision 15bb922b665fcd44c6230a1202785d0c7890e90c
faf8ae9e57aecf780f77f114de886af4c1a0f0ccChristian Maeder{- |
faf8ae9e57aecf780f77f114de886af4c1a0f0ccChristian MaederModule : $Header$
faf8ae9e57aecf780f77f114de886af4c1a0f0ccChristian MaederCopyright : (c) Christian Maeder and Uni Bremen 2003
faf8ae9e57aecf780f77f114de886af4c1a0f0ccChristian MaederLicence : similar to LGPL, see HetCATS/LICENCE.txt or LIZENZ.txt
faf8ae9e57aecf780f77f114de886af4c1a0f0ccChristian Maeder
aa1c971871ba8f793a9e2e62189369cbfbbe0054Christian MaederMaintainer : hets@tzi.de
9db48b4604636bfdf03e60890fc094b7bec775dcChristian MaederStability : experimental
9db48b4604636bfdf03e60890fc094b7bec775dcChristian MaederPortability : portable
9db48b4604636bfdf03e60890fc094b7bec775dcChristian Maeder
faf8ae9e57aecf780f77f114de886af4c1a0f0ccChristian Maeder auxiliary functions for raw kinds
-}
module HasCASL.ClassAna where
import HasCASL.As
import HasCASL.AsUtils
import Common.Id
import HasCASL.Le
import Common.PrettyPrint
import qualified Common.Lib.Map as Map
import qualified Common.Lib.Set as Set
import Common.Result
anaClassId :: ClassId -> ClassMap -> Result Kind
anaClassId ci cMap =
case Map.lookup ci cMap of
Nothing -> mkError "undeclared class" ci
Just (ClassInfo l) -> return $ ClassKind ci $ toIntersection l []
toIntersection :: [Kind] -> [Pos] -> Kind
toIntersection l ps = case Set.toList $ mkIntersection l of
[] -> Intersection [] ps
[h] -> h
is -> Intersection is ps
mkIntersection :: [Kind] -> Set.Set Kind
mkIntersection = Set.unions . map ( \ k -> case k of
Intersection lk _ -> mkIntersection lk
_ -> Set.single k)
rawKind :: Kind -> Kind
rawKind c =
case c of
MissingKind -> error "rawKind"
ClassKind _ rk -> rawKind rk
Downset _ _ rk _ -> rawKind rk
Intersection l _ -> if null l then c
else rawKind $ head l
FunKind e k ps -> FunKind (rawKind e) (rawKind k) ps
ExtKind k v ps -> ExtKind (rawKind k) v ps
checkIntersection :: Kind -> [Kind] -> [Diagnosis]
checkIntersection _ [] = []
checkIntersection k (f:r) =
case k == rawKind f of
False ->
Diag Error ("incompatible kind of: " ++ showPretty f ""
++ "\n for raw kind: " ++ showPretty k "")
(posOf [f]) : checkIntersection k r
True -> checkIntersection k r
diffKindDiag :: (PosItem a, PrettyPrint a) =>
a -> Kind -> Kind -> [Diagnosis]
diffKindDiag a k1 k2 =
[ Diag Error
("incompatible kind of: " ++ showPretty a "" ++ expected k1 k2)
$ posOf [a] ]
checkKinds :: (PosItem a, PrettyPrint a) =>
a -> Kind -> Kind -> [Diagnosis]
checkKinds p k1 k2 =
do let k3 = rawKind k1
k4 = rawKind k2
if k3 == k4 then []
else diffKindDiag p k1 k2
cyclicClassId :: ClassId -> Kind -> Bool
cyclicClassId ci k =
case k of
FunKind k1 k2 _ -> cyclicClassId ci k1 || cyclicClassId ci k2
ExtKind ek _ _ -> cyclicClassId ci ek
ClassKind cj ck -> cj == ci || cyclicClassId ci ck
Downset _ _ dk _ -> cyclicClassId ci dk
Intersection l _ -> any (cyclicClassId ci) l
_ -> False