Morphism.hs revision 386bd8214f3137fe84c392cd58338130d2f80607
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu{- |
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae BungiuModule : $Header$
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae BungiuDescription : RDF Morphism
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel ManceCopyright : (c) Francisc-Nicolae Bungiu, Felix Gabriel Mance, 2011
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae BungiuLicense : GPLv2 or higher, see LICENSE.txt
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae BungiuMaintainer : f.bungiu@jacobs-university.de
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae BungiuStability : provisional
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae BungiuPortability : portable
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae BungiuMorphisms for RDF
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu-}
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu
ed1b8e97e72b2e3e92edaf2eb22a4b5373d705f1Felix Gabriel Mancemodule RDF.Morphism where
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu
386bd8214f3137fe84c392cd58338130d2f80607Felix Gabriel Manceimport Common.DocUtils
386bd8214f3137fe84c392cd58338130d2f80607Felix Gabriel Manceimport Common.Doc
386bd8214f3137fe84c392cd58338130d2f80607Felix Gabriel Manceimport Common.Lib.State
386bd8214f3137fe84c392cd58338130d2f80607Felix Gabriel Manceimport Common.Lib.MapSet (setToMap)
386bd8214f3137fe84c392cd58338130d2f80607Felix Gabriel Manceimport Common.Result
386bd8214f3137fe84c392cd58338130d2f80607Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Manceimport OWL2.AS
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Manceimport RDF.AS
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiuimport RDF.Sign
8dd62da91d8ac7cfa80cfaff34dc87bb4c2c855bFelix Gabriel Manceimport RDF.Function
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Manceimport RDF.StaticAnalysis
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Manceimport RDF.Print
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Manceimport RDF.Symbols
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu
386bd8214f3137fe84c392cd58338130d2f80607Felix Gabriel Manceimport Control.Monad
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Manceimport Data.Maybe
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Manceimport qualified Data.Set as Set
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiuimport qualified Data.Map as Map
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiudata RDFMorphism = RDFMorphism
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu { osource :: Sign
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu , otarget :: Sign
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu , mmaps :: MorphMap
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu } deriving (Show, Eq, Ord)
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae BungiuinclRDFMorphism :: Sign -> Sign -> RDFMorphism
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae BungiuinclRDFMorphism s t = RDFMorphism
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu { osource = s
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu , otarget = t
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu , mmaps = Map.empty }
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae Bungiu
5efb71382fdcce83a76a6d40e5f8def0462bf8a8Francisc Nicolae BungiuisRDFInclusion :: RDFMorphism -> Bool
386bd8214f3137fe84c392cd58338130d2f80607Felix Gabriel ManceisRDFInclusion m = Map.null (mmaps m) && isSubSign (osource m) (otarget m)
67fc6fe7ffa26acdf15b246a26161a5872aff8bcFelix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancesymMap :: MorphMap -> Map.Map RDFEntity RDFEntity
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancesymMap = Map.mapWithKey (\ (RDFEntity ty _) -> RDFEntity ty)
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel ManceinducedElems :: MorphMap -> [RDFEntity]
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel ManceinducedElems = Map.elems . symMap
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel ManceinducedSign :: MorphMap -> StringMap -> Sign -> Sign
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel ManceinducedSign m t s =
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance let new = execState (do
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance mapM_ (modEntity Set.delete) $ Map.keys m
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance mapM_ (modEntity Set.insert) $ inducedElems m) s
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance in function Rename (StringMap t) new
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel ManceinducedPref :: String -> String -> Sign -> (MorphMap, StringMap)
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance -> (MorphMap, StringMap)
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel ManceinducedPref v u sig (m, t) =
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance let pm = Map.empty
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance in if Set.member v $ Map.keysSet pm
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance then if u == v then (m, t) else (m, Map.insert v u t)
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance else error $ "unknown symbol: " ++ showDoc v "\n" ++ shows sig ""
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel ManceinducedFromMor :: Map.Map RawSymb RawSymb -> Sign -> Result RDFMorphism
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel ManceinducedFromMor rm sig = do
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance let syms = symOf sig
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance (mm, tm) <- foldM (\ (m, t) p -> case p of
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance (ASymbol s@(RDFEntity _ v), ASymbol (RDFEntity _ u)) ->
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance if Set.member s syms
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance then return $ if u == v then (m, t) else (Map.insert s u m, t)
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance else fail $ "unknown symbol: " ++ showDoc s "\n" ++ shows sig ""
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance (AnUri v, AnUri u) -> case filter (`Set.member` syms)
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance $ map (`RDFEntity` v) rdfEntityTypes of
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance [] -> let v2 = showQU v
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance u2 = showQU u
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance in return $ inducedPref v2 u2 sig (m, t)
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance l -> return $ if u == v then (m, t) else
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance (foldr (`Map.insert` u) m l, t)
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance _ -> error "RDF.Morphism.inducedFromMor") (Map.empty, Map.empty)
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance $ Map.toList rm
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance return RDFMorphism
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance { osource = sig
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance , otarget = inducedSign mm tm sig
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance , mmaps = mm }
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancesymMapOf :: RDFMorphism -> Map.Map RDFEntity RDFEntity
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancesymMapOf mor = Map.union (symMap $ mmaps mor) $ setToMap $ symOf $ osource mor
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Manceinstance Pretty RDFMorphism where
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance pretty m = let
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance s = osource m
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance srcD = specBraces $ space <> pretty s
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance t = otarget m
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance in if isRDFInclusion m then
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance if isSubSign t s then
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance fsep [text "identity morphism over", srcD]
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance else fsep
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance [ text "inclusion morphism of"
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance , srcD
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance , text "extended with"
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance , pretty $ Set.difference (symOf t) $ symOf s ]
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance else fsep
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance [ pretty $ mmaps m
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance , colon <+> srcD, mapsto <+> specBraces (space <> pretty t) ]
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancelegalMor :: RDFMorphism -> Result ()
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancelegalMor m = let mm = mmaps m in unless
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance (Set.isSubsetOf (Map.keysSet mm) (symOf $ osource m)
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance && Set.isSubsetOf (Set.fromList $ inducedElems mm) (symOf $ otarget m))
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance $ fail "illegal RDF morphism"
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancecomposeMor :: RDFMorphism -> RDFMorphism -> Result RDFMorphism
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancecomposeMor m1 m2 =
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance let nm = Set.fold (\ s@(RDFEntity ty u) -> let
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance t = getIri ty u $ mmaps m1
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance r = getIri ty t $ mmaps m2
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance in if r == u then id else Map.insert s r) Map.empty
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance . symOf $ osource m1
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance in return m1
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance { otarget = otarget m2
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance , mmaps = nm }
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancecogeneratedSign :: Set.Set RDFEntity -> Sign -> Result RDFMorphism
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancecogeneratedSign s sign =
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance let sig2 = execState (mapM_ (modEntity Set.delete) $ Set.toList s) sign
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance in if isSubSign sig2 sign then return $ inclRDFMorphism sig2 sign else
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance fail "non RDF subsignatures for (co)generatedSign"
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancegeneratedSign :: Set.Set RDFEntity -> Sign -> Result RDFMorphism
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancegeneratedSign s sign = cogeneratedSign (Set.difference (symOf sign) s) sign
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancematchesSym :: RDFEntity -> RawSymb -> Bool
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancematchesSym e@(RDFEntity _ u) r = case r of
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance ASymbol s -> s == e
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance AnUri s -> s == u || namePrefix u == localPart s && null (namePrefix s)
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancestatSymbItems :: [SymbItems] -> [RawSymb]
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancestatSymbItems = concatMap
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance $ \ (SymbItems m us) -> case m of
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance Nothing -> map AnUri us
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance Just ty -> map (ASymbol . RDFEntity ty) us
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancestatSymbMapItems :: [SymbMapItems] -> Result (Map.Map RawSymb RawSymb)
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancestatSymbMapItems =
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance foldM (\ m (s, t) -> case Map.lookup s m of
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance Nothing -> return $ Map.insert s t m
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance Just u -> case (u, t) of
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance (AnUri su, ASymbol (RDFEntity _ tu)) | su == tu ->
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance return $ Map.insert s t m
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance (ASymbol (RDFEntity _ su), AnUri tu) | su == tu -> return m
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance _ -> if u == t then return m else
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance fail $ "differently mapped symbol: " ++ showDoc s "\nmapped to "
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance ++ showDoc u " and " ++ showDoc t "")
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance Map.empty
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance . concatMap (\ (SymbMapItems m us) ->
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance let ps = map (\ (u, v) -> (u, fromMaybe u v)) us in
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance case m of
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance Nothing -> map (\ (s, t) -> (AnUri s, AnUri t)) ps
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance Just ty ->
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance let mS = ASymbol . RDFEntity ty
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance in map (\ (s, t) -> (mS s, mS t)) ps)
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel Mance
e5ea4eeaeefd3521ae3475719e18c96cf91637d5Felix Gabriel MancemapSen :: RDFMorphism -> Axiom -> Result Axiom
386bd8214f3137fe84c392cd58338130d2f80607Felix Gabriel MancemapSen m a = return $ function Rename (MorphMap $ mmaps m) a
386bd8214f3137fe84c392cd58338130d2f80607Felix Gabriel Mance