1a38107941725211e7c3f051f7a8f5e12199f03acmaeder{-# LANGUAGE DeriveDataTypeable #-}
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiuDescription : OWL Morphisms
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel ManceCopyright : (c) Dominik Luecke, 2008, Felix Gabriel Mance, 2011
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiuLicense : GPLv2 or higher, see LICENSE.txt
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel ManceMaintainer : f.mance@jacobs-university.de
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiuStability : provisional
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiuPortability : portable
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiuMorphisms for OWL
0dd6e7830de0887c9a12356447975a826b3b3db2Christian Maederimport Common.Utils (composeMap)
424860079d47bf490fa98d5d7498096a0447c569mcodescuimport Common.Id(nullRange)
32bbac77828be0233953f8fe476edb0a9585408dChristian Maederimport Data.List (stripPrefix)
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiuimport qualified Data.Map as Map
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiuimport qualified Data.Set as Set
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiudata OWLMorphism = OWLMorphism
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu { osource :: Sign
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu , otarget :: Sign
27fdf879983dd28e211b41f3be6c0e930b7c816bFelix Gabriel Mance , mmaps :: MorphMap
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel Mance , pmap :: StringMap
1a38107941725211e7c3f051f7a8f5e12199f03acmaeder } deriving (Show, Eq, Ord, Typeable, Data)
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiuinclOWLMorphism :: Sign -> Sign -> OWLMorphism
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiuinclOWLMorphism s t = OWLMorphism
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiuisOWLInclusion :: OWLMorphism -> Bool
be00381168b3f10192afabbba136fb06d3a9f358Christian MaederisOWLInclusion m = Map.null (pmap m)
be00381168b3f10192afabbba136fb06d3a9f358Christian Maeder && Map.null (mmaps m) && isSubSign (osource m) (otarget m)
27fdf879983dd28e211b41f3be6c0e930b7c816bFelix Gabriel MancesymMap :: MorphMap -> Map.Map Entity Entity
7852de3551fc797566ee71165bafe05b6d81728cnotanartistsymMap = Map.mapWithKey (\ (Entity lb ty _) -> Entity lb ty)
27fdf879983dd28e211b41f3be6c0e930b7c816bFelix Gabriel ManceinducedElems :: MorphMap -> [Entity]
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiuinducedElems = Map.elems . symMap
27fdf879983dd28e211b41f3be6c0e930b7c816bFelix Gabriel ManceinducedSign :: MorphMap -> StringMap -> Sign -> Sign
d0f58d27c2536eba454d8f77de8617bc6a2c99cdFelix Gabriel ManceinducedSign m t s =
d0f58d27c2536eba454d8f77de8617bc6a2c99cdFelix Gabriel Mance let new = execState (do
d0f58d27c2536eba454d8f77de8617bc6a2c99cdFelix Gabriel Mance mapM_ (modEntity Set.delete) $ Map.keys m
d0f58d27c2536eba454d8f77de8617bc6a2c99cdFelix Gabriel Mance mapM_ (modEntity Set.insert) $ inducedElems m) s
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel Mance in function Rename (StringMap t) new
27fdf879983dd28e211b41f3be6c0e930b7c816bFelix Gabriel ManceinducedPref :: String -> String -> Sign -> (MorphMap, StringMap)
424860079d47bf490fa98d5d7498096a0447c569mcodescu -> Result (MorphMap, StringMap)
60f30f0eeeacdfc1e0dfe39664373ddf5a0675adFelix Gabriel ManceinducedPref v u sig (m, t) =
60f30f0eeeacdfc1e0dfe39664373ddf5a0675adFelix Gabriel Mance let pm = prefixMap sig
424860079d47bf490fa98d5d7498096a0447c569mcodescu then if u == v then return (m, t) else return (m, Map.insert v u t)
424860079d47bf490fa98d5d7498096a0447c569mcodescu plain_error (Map.empty, Map.empty) ("unknown symbol: " ++ showDoc v "\nin signature:\n" ++ showDoc sig "") nullRange
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiuinducedFromMor :: Map.Map RawSymb RawSymb -> Sign -> Result OWLMorphism
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiuinducedFromMor rm sig = do
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu let syms = symOf sig
60f30f0eeeacdfc1e0dfe39664373ddf5a0675adFelix Gabriel Mance (mm, tm) <- foldM (\ (m, t) p -> case p of
7852de3551fc797566ee71165bafe05b6d81728cnotanartist (ASymbol s@(Entity _ _ v), ASymbol (Entity _ _ u)) ->
60f30f0eeeacdfc1e0dfe39664373ddf5a0675adFelix Gabriel Mance then return $ if u == v then (m, t) else (Map.insert s u m, t)
9475501a6acf48434052d9e6f4a05ed6681eaaabFrancisc Nicolae Bungiu else fail $ "unknown symbol: " ++ showDoc s "\n" ++ shows sig ""
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu (AnUri v, AnUri u) -> case filter (`Set.member` syms)
7852de3551fc797566ee71165bafe05b6d81728cnotanartist $ map (`mkEntity` v) entityTypes of
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski [] -> let v2 = showIRICompact v
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski u2 = showIRICompact u
424860079d47bf490fa98d5d7498096a0447c569mcodescu in inducedPref v2 u2 sig (m, t)
0dd6e7830de0887c9a12356447975a826b3b3db2Christian Maeder l -> return $ if u == v then (m, t) else
0dd6e7830de0887c9a12356447975a826b3b3db2Christian Maeder (foldr (`Map.insert` u) m l, t)
424860079d47bf490fa98d5d7498096a0447c569mcodescu (APrefix v, APrefix u) -> inducedPref v u sig (m, t)
0dd6e7830de0887c9a12356447975a826b3b3db2Christian Maeder _ -> error "OWL2.Morphism.inducedFromMor") (Map.empty, Map.empty)
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu return OWLMorphism
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu { osource = sig
d0f58d27c2536eba454d8f77de8617bc6a2c99cdFelix Gabriel Mance , otarget = inducedSign mm tm sig
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiusymMapOf :: OWLMorphism -> Map.Map Entity Entity
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiusymMapOf mor = Map.union (symMap $ mmaps mor) $ setToMap $ symOf $ osource mor
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiuinstance Pretty OWLMorphism where
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu srcD = specBraces $ space <> pretty s
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder in fsep $ if isOWLInclusion m then
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu if isSubSign t s then
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder [text "identity morphism over", srcD]
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu [ text "inclusion morphism of"
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu , text "extended with"
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu , pretty $ Set.difference (symOf t) $ symOf s ]
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu [ pretty $ mmaps m
31e9d2a02e15b7dbc157e0d3fb3b84f6c8666482Christian Maeder , pretty $ pmap m
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu , colon <+> srcD, mapsto <+> specBraces (space <> pretty t) ]
656f17ae9b7610ff2de1b6eedeeadea0c3bcdc8dChristian MaederlegalMor :: OWLMorphism -> Result ()
d3cb3401882f6956de016f8eecbec1cd3b868acbFelix Gabriel MancelegalMor m = let mm = mmaps m in unless
d3cb3401882f6956de016f8eecbec1cd3b868acbFelix Gabriel Mance (Set.isSubsetOf (Map.keysSet mm) (symOf $ osource m)
d3cb3401882f6956de016f8eecbec1cd3b868acbFelix Gabriel Mance && Set.isSubsetOf (Set.fromList $ inducedElems mm) (symOf $ otarget m))
d3cb3401882f6956de016f8eecbec1cd3b868acbFelix Gabriel Mance $ fail "illegal OWL2 morphism"
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiucomposeMor :: OWLMorphism -> OWLMorphism -> Result OWLMorphism
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiucomposeMor m1 m2 =
7852de3551fc797566ee71165bafe05b6d81728cnotanartist let nm = Set.fold (\ s@(Entity _ ty u) -> let
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu t = getIri ty u $ mmaps m1
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu r = getIri ty t $ mmaps m2
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu in if r == u then id else Map.insert s r) Map.empty
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu . symOf $ osource m1
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu { otarget = otarget m2
0dd6e7830de0887c9a12356447975a826b3b3db2Christian Maeder , pmap = composeMap (prefixMap $ osource m1) (pmap m1) $ pmap m2
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiucogeneratedSign :: Set.Set Entity -> Sign -> Result OWLMorphism
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiucogeneratedSign s sign =
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu let sig2 = execState (mapM_ (modEntity Set.delete) $ Set.toList s) sign
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu in if isSubSign sig2 sign then return $ inclOWLMorphism sig2 sign else
06acd8a23b2f06e7b2373d53f738cf56c7f03223Francisc Nicolae Bungiu fail "non OWL2 subsignatures for (co)generatedSign"
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiugeneratedSign :: Set.Set Entity -> Sign -> Result OWLMorphism
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiugeneratedSign s sign = cogeneratedSign (Set.difference (symOf sign) s) sign
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiumatchesSym :: Entity -> RawSymb -> Bool
7852de3551fc797566ee71165bafe05b6d81728cnotanartistmatchesSym e@(Entity _ _ u) r = case r of
32bbac77828be0233953f8fe476edb0a9585408dChristian Maeder ASymbol s -> s == e
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski AnUri s -> s == u -- || expandedIRI s == expandedIRI u
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski stripPrefix (reverse $ show $ iriPath s) (reverse $ show $ iriPath u) of
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski Just (c : _) | null (prefixName s) -> elem c "/#"
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski APrefix p -> p == prefixName u
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian MaederstatSymbItems :: Sign -> [SymbItems] -> [RawSymb]
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian MaederstatSymbItems sig = map (function Expand . StringMap $ prefixMap sig)
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder (\ (SymbItems m us) -> case m of
b84c87f199dc287d235d7dad6ea344f6912ef531Christian Maeder AnyEntity -> map AnUri us
7852de3551fc797566ee71165bafe05b6d81728cnotanartist EntityType ty -> map (ASymbol . mkEntity ty) us
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski PrefixO -> map (APrefix . showIRI) us)
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian MaederstatSymbMapItems :: Sign -> Maybe Sign -> [SymbMapItems]
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder -> Result (Map.Map RawSymb RawSymb)
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian MaederstatSymbMapItems sig mtsig =
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder fmap (Map.fromList . map (\ (r1, r2) ->
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder let f = function Expand . StringMap . prefixMap
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder f2 = f $ fromMaybe sig mtsig
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder in (f1 r1, f2 r2)) . Map.toList)
cf0439f74f1d55a9840d38a88f9b0f4fc00d5547Christian Maeder . foldM (\ m (s, t) -> case Map.lookup s m of
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu Nothing -> return $ Map.insert s t m
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu Just u -> case (u, t) of
7852de3551fc797566ee71165bafe05b6d81728cnotanartist (AnUri su, ASymbol (Entity _ _ tu)) | su == tu ->
7852de3551fc797566ee71165bafe05b6d81728cnotanartist (ASymbol (Entity _ _ su), AnUri tu) | su == tu -> return m
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski (AnUri su, APrefix tu) | showIRICompact su == tu ->
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski (APrefix su, AnUri tu) | su == showIRICompact tu -> return m
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu _ -> if u == t then return m else
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu fail $ "differently mapped symbol: " ++ showDoc s "\nmapped to "
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu ++ showDoc u " and " ++ showDoc t "")
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu . concatMap (\ (SymbMapItems m us) ->
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae Bungiu let ps = map (\ (u, v) -> (u, fromMaybe u v)) us in
b84c87f199dc287d235d7dad6ea344f6912ef531Christian Maeder AnyEntity -> map (\ (s, t) -> (AnUri s, AnUri t)) ps
624f8c31bd8d6746b93f4b5966aa6fc7680fefc5Felix Gabriel Mance EntityType ty ->
7852de3551fc797566ee71165bafe05b6d81728cnotanartist let mS = ASymbol . mkEntity ty
624f8c31bd8d6746b93f4b5966aa6fc7680fefc5Felix Gabriel Mance in map (\ (s, t) -> (mS s, mS t)) ps
80875f917d741946a39d0ec0b5721e46ba609823Till Mossakowski map (\ (s, t) -> (APrefix (showIRICompact s), APrefix $ showIRICompact t)) ps)
ee93ea764a2b8189253e912c8447f9419033f6d4Francisc Nicolae BungiumapSen :: OWLMorphism -> Axiom -> Result Axiom
d0f58d27c2536eba454d8f77de8617bc6a2c99cdFelix Gabriel MancemapSen m a = do
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel Mance let new = function Rename (MorphMap $ mmaps m) a
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel Mance return $ function Rename (StringMap $ pmap m) new
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescumorphismUnion :: OWLMorphism -> OWLMorphism -> Result OWLMorphism
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescumorphismUnion mor1 mor2 = do
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu let ssig1 = osource mor1
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu tsig1 = otarget mor1
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu ssig2 = osource mor2
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu tsig2 = otarget mor2
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu ssig = addSign ssig1 ssig2
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu tsig = addSign tsig1 tsig2
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu m1 = mmaps mor1
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu m2 = mmaps mor2
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu pairs = filter (\(a,b) -> a /= b)
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu $ map (\x -> (Map.findWithDefault (error "1") x m1,
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu Map.findWithDefault (error "2") x m2))
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu case pairs of
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu return $ OWLMorphism {
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu osource = ssig,
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu otarget = tsig,
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu mmaps = Map.union m1 m2,
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu pmap = Map.union (pmap mor1) $ pmap mor2}
b90f0b7fd6ccfbdd7e5adb65b1f6c02c7758ff5cmcodescu _ -> fail $ "can't unite morphisms:" ++ show pairs