content: {-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
  
  {- |
  Module      :  ./RDF/Function.hs
  Copyright   :  (c) Felix Gabriel Mance
  License     :  GPLv2 or higher, see LICENSE.txt
  
  Maintainer  :  f.mance@jacobs-university.de
  Stability   :  provisional
  Portability :  portable
  
  Instances for some of the functions used in RDF
  -}
  
  module RDF.Function where
  import Common.IRI
  import RDF.AS
  -- import RDF.Sign
  
  import qualified Data.Map as Map
  {- import qualified Data.Set as Set
  }
  {- | this class contains general functions which operate on the ontology
      document, such as prefix renaming, IRI expansion or Morphism mapping -}
  class Function a where
      function :: AMap -> a -> a
  
  data Action = Rename | Expand
      deriving (Show, Eq, Ord)
  -}
  type StringMap = Map.Map String String
  type MorphMap = Map.Map RDFEntity IRI
  {- }
  data AMap =
        StringMap StringMap
      | PrefixMap RDFPrefixMap
      | MorphMap MorphMap
      deriving (Show, Eq, Ord)
  {-}
  maybeDo :: (Function a) => Action -> AMap -> Maybe a -> Maybe a
  maybeDo t mp = fmap $ function t mp
  -}
  
  instance Function IRI where
      function m iri = case m of
          StringMap sm -> let pre = namePrefix iri in
                      iri { namePrefix = Map.findWithDefault pre pre sm}
          PrefixMap pm ->
              let np = namePrefix iri
                  lp = localPart iri
              in case iriType iri of
                      NodeID -> iri {expandedIRI = np ++ ":" ++ lp}
                      Abbreviated -> let miri = Map.lookup np pm
                           in case miri of
                              Just rp -> if isAbsoluteIRI rp
                                  then iri {expandedIRI = expandedIRI rp ++ lp}
                                  else iri
                              Nothing -> error $ np ++ ": prefix not found"
                      _ -> iri
          _ -> iri
  
  instance Function Predicate where
      function m (Predicate iri) = Predicate $ function m iri
  
  instance Function Subject where
      function m sub = case sub of
          Subject iri -> Subject $ function m iri
          SubjectList ls -> SubjectList $ map (function m) ls
          SubjectCollection ls -> SubjectCollection $ map (function m) ls
  
  instance Function Object where
      function m obj = case obj of
          Object s -> Object $ function m s
          ObjectLiteral l -> ObjectLiteral $ function m l
  
  instance Function PredicateObjectList where
      function m (PredicateObjectList p ol) = PredicateObjectList (function m p)
          $ map (function m) ol
  
  instance Function RDFLiteral where
      function m lit = case lit of
          RDFLiteral b lf (Typed dt) -> RDFLiteral b lf $ Typed $ function m dt
          _ -> lit
  
  instance Function Triples where
      function m (Triples s ls) = Triples (function m s) $ map (function m) ls
  
  instance Function Statement where
      function m s = case s of
          Statement t -> Statement $ function m t
          Base iri -> Base $ function m iri
          Prefix p iri -> case m of
              StringMap sm -> Prefix (fromJust $ Map.lookup p sm) iri
              _ -> s
  
  instance Function RDFPrefixMap where
      function m prefMap = case m of
          StringMap sm -> Map.mapKeys
                              (\ pref -> fromJust $ Map.lookup pref sm) prefMap
          _ -> prefMap
  
  instance Function TurtleDocument where
      function m doc = emptyTurtleDocument
                          { statements = map (function m) $ statements doc
                          , prefixMap = function m $ prefixMap doc }
  
  
  getIri :: RDFEntityType -> IRI -> Map.Map RDFEntity IRI -> IRI
  getIri ty u = fromMaybe u . Map.lookup (RDFEntity ty u)
  
  instance Function Sign where
     function t mp (Sign p1 p2 p3) = case mp of
      StringMap _ ->
          Sign (Set.map (function t mp) p1)
              (Set.map (function t mp) p2)
              (Set.map (function t mp) p3)
      _ -> error "cannot perform operation"
  
  instance Function RDFEntity where
      function t pm (RDFEntity ty ent) = case pm of
          StringMap _ -> RDFEntity ty $ function t pm ent
          MorphMap m -> RDFEntity ty $ getIri ty ent m
  
  instance Function Literal where
      function _ _ l = l
  
  instance Function Object where
      function t pm obj = case obj of
          Left iri -> Left $ function t pm iri
          Right lit -> Right $ function t pm lit
  
  valueOfKey :: RDFEntityType -> IRI -> MorphMap -> IRI
  valueOfKey ty iri mm =
      let ent = RDFEntity ty iri
      in fromMaybe iri $ Map.lookup ent mm
  
  instance Function Axiom where
      function t mp (Axiom sub pre obj) = case mp of
          StringMap _ -> Axiom (function t mp sub) (function t mp pre)
              (function t mp obj)
          MorphMap mm ->
              let nsub = valueOfKey Subject sub mm
                  npre = valueOfKey Predicate pre mm
              in Axiom nsub npre $ case obj of
                      Left iri -> Left $ valueOfKey Object iri mm
                      _ -> obj
  
  instance Function RDFGraph where
    function t mp (RDFGraph l) = RDFGraph $ map (function t mp) l
    -}
  