AS.hs revision 47589c2d80dabefc0cd8e2ee5e7331e3db677c68
9d0567bda351efa4286f38e85fb3e41ecd3683eaChristian Maeder{-# LANGUAGE DeriveDataTypeable #-}
9d0567bda351efa4286f38e85fb3e41ecd3683eaChristian Maeder{- |
9d0567bda351efa4286f38e85fb3e41ecd3683eaChristian MaederModule : $Header$
9d0567bda351efa4286f38e85fb3e41ecd3683eaChristian MaederCopyright : (c) C. Maeder, Felix Gabriel Mance
9d0567bda351efa4286f38e85fb3e41ecd3683eaChristian MaederLicense : GPLv2 or higher, see LICENSE.txt
9d0567bda351efa4286f38e85fb3e41ecd3683eaChristian Maeder
9d0567bda351efa4286f38e85fb3e41ecd3683eaChristian MaederMaintainer : Christian.Maeder@dfki.de
9d0567bda351efa4286f38e85fb3e41ecd3683eaChristian MaederStability : provisional
9d0567bda351efa4286f38e85fb3e41ecd3683eaChristian MaederPortability : portable
9d0567bda351efa4286f38e85fb3e41ecd3683eaChristian Maeder
9d0567bda351efa4286f38e85fb3e41ecd3683eaChristian MaederOWL 2 Functional Syntax constructs
20bd79f8844604c145510c616fecdaf47eba2fdbChristian Maeder
20bd79f8844604c145510c616fecdaf47eba2fdbChristian MaederReferences:
20bd79f8844604c145510c616fecdaf47eba2fdbChristian Maeder <http://www.w3.org/TR/2009/REC-owl2-syntax-20091027/#Functional-Style_Syntax>
9f93b2a8b552789cd939d599504d39732672dc84Christian Maeder <http://www.w3.org/TR/owl2-manchester-syntax/>
9f93b2a8b552789cd939d599504d39732672dc84Christian Maeder-}
20bd79f8844604c145510c616fecdaf47eba2fdbChristian Maeder
20bd79f8844604c145510c616fecdaf47eba2fdbChristian Maedermodule OWL2.AS where
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder
ab0274ab68a174d3e92235b4c4ca865c03901583Christian Maederimport Common.Id
20bd79f8844604c145510c616fecdaf47eba2fdbChristian Maederimport Common.Keywords (stringS)
d3f192025f2836285d9705a959542350e057f281Christian Maeder
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maederimport Common.Result
3b48e17c1da54ee669e70b626d9fbc32ce495b2cChristian Maeder
20bd79f8844604c145510c616fecdaf47eba2fdbChristian Maederimport OWL2.ColonKeywords
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maederimport OWL2.Keywords
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maederimport Data.Char (intToDigit)
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maederimport Data.Data
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maederimport Data.List
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maederimport Data.Maybe
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maederimport qualified Data.Map as Map
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maederimport qualified Data.Set as Set
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maederdata IRIType = Full | Abbreviated | NodeID
20bd79f8844604c145510c616fecdaf47eba2fdbChristian Maeder deriving (Show, Eq, Ord, Typeable, Data)
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maeder
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maeder{- | full or abbreviated IRIs with a possible uri for the prefix
20bd79f8844604c145510c616fecdaf47eba2fdbChristian Maeder or a local part following a hash sign -}
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maederdata QName = QN
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maeder { namePrefix :: String
20bd79f8844604c145510c616fecdaf47eba2fdbChristian Maeder -- ^ the name prefix part of a qualified name \"namePrefix:localPart\"
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maeder , localPart :: String
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maeder -- ^ the local part of a qualified name \"namePrefix:localPart\"
20bd79f8844604c145510c616fecdaf47eba2fdbChristian Maeder , iriType :: IRIType
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maeder , expandedIRI :: String
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maeder -- ^ the associated namespace uri (not printed)
20bd79f8844604c145510c616fecdaf47eba2fdbChristian Maeder , iriPos :: Range
20bd79f8844604c145510c616fecdaf47eba2fdbChristian Maeder } deriving (Show, Typeable, Data)
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maeder
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maederinstance Eq QName where
20bd79f8844604c145510c616fecdaf47eba2fdbChristian Maeder p == q = compare p q == EQ
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maeder
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maederinstance Ord QName where
3b48e17c1da54ee669e70b626d9fbc32ce495b2cChristian Maeder compare (QN p1 l1 b1 n1 _) (QN p2 l2 b2 n2 _) =
ab0274ab68a174d3e92235b4c4ca865c03901583Christian Maeder if null n1 || null n2 then compare (b1, p1, l1) (b2, p2, l2) else
ab0274ab68a174d3e92235b4c4ca865c03901583Christian Maeder compare n1 n2 -- compare fully expanded names only
ab0274ab68a174d3e92235b4c4ca865c03901583Christian Maeder
ab0274ab68a174d3e92235b4c4ca865c03901583Christian MaederqNameRange :: QName -> [Pos]
ab0274ab68a174d3e92235b4c4ca865c03901583Christian MaederqNameRange q = let Range rs = iriPos q in case rs of
9f93b2a8b552789cd939d599504d39732672dc84Christian Maeder [p] -> let
ab0274ab68a174d3e92235b4c4ca865c03901583Christian Maeder p0 = if iriType q == Full then incSourceColumn p (-1) else p
ab0274ab68a174d3e92235b4c4ca865c03901583Christian Maeder in tokenRange $ Token (showQN q) $ Range [p0]
ab0274ab68a174d3e92235b4c4ca865c03901583Christian Maeder _ -> rs
ab0274ab68a174d3e92235b4c4ca865c03901583Christian Maeder
3b48e17c1da54ee669e70b626d9fbc32ce495b2cChristian Maederinstance GetRange QName where
9f93b2a8b552789cd939d599504d39732672dc84Christian Maeder getRange = iriPos
9f93b2a8b552789cd939d599504d39732672dc84Christian Maeder rangeSpan = qNameRange
9f93b2a8b552789cd939d599504d39732672dc84Christian Maeder
9f93b2a8b552789cd939d599504d39732672dc84Christian MaedershowQN :: QName -> String
9f93b2a8b552789cd939d599504d39732672dc84Christian MaedershowQN q = (if iriType q == Full then showQI else showQU) q
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maeder
9f93b2a8b552789cd939d599504d39732672dc84Christian Maeder-- | show QName as abbreviated iri
9f93b2a8b552789cd939d599504d39732672dc84Christian MaedershowQU :: QName -> String
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian MaedershowQU (QN pre local _ _ _) =
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian Maeder if null pre then local else pre ++ ":" ++ local
9f93b2a8b552789cd939d599504d39732672dc84Christian Maeder
9f93b2a8b552789cd939d599504d39732672dc84Christian Maeder-- | show QName in angle brackets as full iris
9f93b2a8b552789cd939d599504d39732672dc84Christian MaedershowQI :: QName -> String
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian MaedershowQI n = '<' : showQU n ++ ">"
ab0274ab68a174d3e92235b4c4ca865c03901583Christian Maeder
9f93b2a8b552789cd939d599504d39732672dc84Christian MaedernullQName :: QName
23a0d43ca980983c7d7aebaa9f03bfe120be7de8Christian MaedernullQName = QN "" "" Abbreviated "" nullRange
ab0274ab68a174d3e92235b4c4ca865c03901583Christian Maeder
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian MaederisNullQName :: QName -> Bool
d3f192025f2836285d9705a959542350e057f281Christian MaederisNullQName qn = case qn of
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder QN "" "" _ "" _ -> True
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder _ -> False
d3f192025f2836285d9705a959542350e057f281Christian Maeder
df15a183ca8bf1c25db69775979905198d7cc8bbChristian MaederunamedS :: String
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian MaederunamedS = "//www." ++ dnamedS
d3f192025f2836285d9705a959542350e057f281Christian Maeder
df15a183ca8bf1c25db69775979905198d7cc8bbChristian MaederdnamedS :: String
df15a183ca8bf1c25db69775979905198d7cc8bbChristian MaederdnamedS = "dfki.de/sks/hets/ontology/unamed"
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder
d3f192025f2836285d9705a959542350e057f281Christian MaederdummyQName :: QName
df15a183ca8bf1c25db69775979905198d7cc8bbChristian MaederdummyQName = QN "http" unamedS Full ("http:" ++ unamedS) nullRange
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder
df15a183ca8bf1c25db69775979905198d7cc8bbChristian MaedermkQName :: String -> QName
df15a183ca8bf1c25db69775979905198d7cc8bbChristian MaedermkQName s = nullQName { localPart = s }
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder
df15a183ca8bf1c25db69775979905198d7cc8bbChristian MaedersetQRange :: Range -> QName -> QName
d3f192025f2836285d9705a959542350e057f281Christian MaedersetQRange r q = q { iriPos = r }
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder
df15a183ca8bf1c25db69775979905198d7cc8bbChristian MaedersetPrefix :: String -> QName -> QName
d3f192025f2836285d9705a959542350e057f281Christian MaedersetPrefix s q = q { namePrefix = s }
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian MaedersetFull :: QName -> QName
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian MaedersetFull q = q {iriType = Full}
d3f192025f2836285d9705a959542350e057f281Christian Maeder
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maedertype IRI = QName
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder-- | checks if an IRI is an anonymous individual
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian MaederisAnonymous :: IRI -> Bool
df15a183ca8bf1c25db69775979905198d7cc8bbChristian MaederisAnonymous iri = iriType iri == NodeID || namePrefix iri == "_"
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder-- | checks if a string (bound to be localPart of an IRI) contains \":\/\/\"
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian MaedercssIRI :: String -> IRIType
df15a183ca8bf1c25db69775979905198d7cc8bbChristian MaedercssIRI iri = if isInfixOf "://" iri then Full else Abbreviated
d3f192025f2836285d9705a959542350e057f281Christian Maeder
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder-- | prefix -> localname
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maedertype PrefixMap = Map.Map String String
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian MaederpredefPrefixes :: PrefixMap
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian MaederpredefPrefixes = Map.fromList
d3f192025f2836285d9705a959542350e057f281Christian Maeder [ ("owl", "http://www.w3.org/2002/07/owl#")
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder , ("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#")
d3f192025f2836285d9705a959542350e057f281Christian Maeder , ("rdfs", "http://www.w3.org/2000/01/rdf-schema#")
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder , ("xsd", "http://www.w3.org/2001/XMLSchema#")
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder , ("", showQU dummyQName ++ "#") ]
d3f192025f2836285d9705a959542350e057f281Christian Maeder
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maedertype LexicalForm = String
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maedertype LanguageTag = String
d3f192025f2836285d9705a959542350e057f281Christian Maedertype ImportIRI = IRI
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maedertype OntologyIRI = IRI
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maedertype Class = IRI
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maedertype Datatype = IRI
d3f192025f2836285d9705a959542350e057f281Christian Maedertype ObjectProperty = IRI
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maedertype DataProperty = IRI
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maedertype AnnotationProperty = IRI
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maedertype Individual = IRI
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maederdata EquivOrDisjoint = Equivalent | Disjoint
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder deriving (Show, Eq, Ord, Typeable, Data)
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian MaedershowEquivOrDisjoint :: EquivOrDisjoint -> String
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian MaedershowEquivOrDisjoint ed = case ed of
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder Equivalent -> equivalentToC
d3f192025f2836285d9705a959542350e057f281Christian Maeder Disjoint -> disjointWithC
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maederdata DomainOrRange = ADomain | ARange
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder deriving (Show, Eq, Ord, Typeable, Data)
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian MaedershowDomainOrRange :: DomainOrRange -> String
d3f192025f2836285d9705a959542350e057f281Christian MaedershowDomainOrRange dr = case dr of
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder ADomain -> domainC
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder ARange -> rangeC
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maederdata SameOrDifferent = Same | Different
d3f192025f2836285d9705a959542350e057f281Christian Maeder deriving (Show, Eq, Ord, Typeable, Data)
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian MaedershowSameOrDifferent :: SameOrDifferent -> String
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian MaedershowSameOrDifferent sd = case sd of
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder Same -> sameAsC
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder Different -> differentFromC
d3f192025f2836285d9705a959542350e057f281Christian Maeder
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maederdata Relation =
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder EDRelation EquivOrDisjoint
2119c0874c93fc1cdfea381bcfea69e8fdb8b6e2Christian Maeder | SubPropertyOf
df15a183ca8bf1c25db69775979905198d7cc8bbChristian Maeder | InverseOf
| SubClass
| Types
| DRRelation DomainOrRange
| SDRelation SameOrDifferent
deriving (Show, Eq, Ord, Typeable, Data)
showRelation :: Relation -> String
showRelation r = case r of
EDRelation ed -> showEquivOrDisjoint ed
SubPropertyOf -> subPropertyOfC
InverseOf -> inverseOfC
SubClass -> subClassOfC
Types -> typesC
DRRelation dr -> showDomainOrRange dr
SDRelation sd -> showSameOrDifferent sd
getED :: Relation -> EquivOrDisjoint
getED r = case r of
EDRelation ed -> ed
_ -> error "not domain or range"
getDR :: Relation -> DomainOrRange
getDR r = case r of
DRRelation dr -> dr
_ -> error "not domain or range"
getSD :: Relation -> SameOrDifferent
getSD s = case s of
SDRelation sd -> sd
_ -> error "not same or different"
data Character =
Functional
| InverseFunctional
| Reflexive
| Irreflexive
| Symmetric
| Asymmetric
| Antisymmetric
| Transitive
deriving (Enum, Bounded, Show, Eq, Ord, Typeable, Data)
data PositiveOrNegative = Positive | Negative
deriving (Show, Eq, Ord, Typeable, Data)
data QuantifierType = AllValuesFrom | SomeValuesFrom
deriving (Show, Eq, Ord, Typeable, Data)
showQuantifierType :: QuantifierType -> String
showQuantifierType ty = case ty of
AllValuesFrom -> onlyS
SomeValuesFrom -> someS
-- * Predefined IRI checkings
thingMap :: PreDefMaps
thingMap = makeOWLPredefMaps predefClass
isThing :: IRI -> Bool
isThing = checkPredef thingMap
makePredefObjProp :: PreDefMaps
makePredefObjProp = makeOWLPredefMaps predefObjProp
isPredefObjProp :: IRI -> Bool
isPredefObjProp = checkPredef makePredefObjProp
makePredefDataProp :: PreDefMaps
makePredefDataProp = makeOWLPredefMaps predefDataProp
isPredefDataProp :: IRI -> Bool
isPredefDataProp = checkPredef makePredefDataProp
makePredefRDFSAnnoProp :: PreDefMaps
makePredefRDFSAnnoProp = preDefMaps predefRDFSAnnoProps "rdfs"
isPredefRDFSAnnoProp :: IRI -> Bool
isPredefRDFSAnnoProp = checkPredef makePredefRDFSAnnoProp
makePredefOWLAnnoProp :: PreDefMaps
makePredefOWLAnnoProp = makeOWLPredefMaps predefOWLAnnoProps
isPredefOWLAnnoProp :: IRI -> Bool
isPredefOWLAnnoProp = checkPredef makePredefOWLAnnoProp
isPredefAnnoProp :: IRI -> Bool
isPredefAnnoProp iri = isPredefOWLAnnoProp iri || isPredefRDFSAnnoProp iri
isPredefPropOrClass :: IRI -> Bool
isPredefPropOrClass iri = isPredefAnnoProp iri || isPredefDataProp iri
|| isPredefObjProp iri || isThing iri
predefIRIs :: Set.Set IRI
predefIRIs = Set.fromList $ map (setPrefix "xsd" . mkQName) xsdKeys
++ map (setPrefix "owl" . mkQName) owlNumbers
++ map (setPrefix "rdf" . mkQName) [rdfsLiteral, stringS]
++ [setPrefix "rdfs" $ mkQName xmlLiteral]
isDatatypeKey :: IRI -> Bool
isDatatypeKey = not . null . isDatatypeKeyAux
xsdMap :: PreDefMaps
xsdMap = makeXsdMap xsdKeys
owlNumbersMap :: PreDefMaps
owlNumbersMap = makeOWLPredefMaps owlNumbers
rdfMap :: PreDefMaps
rdfMap = preDefMaps [xmlLiteral, stringS] "rdf"
rdfsMap :: PreDefMaps
rdfsMap = preDefMaps [rdfsLiteral] "rdfs"
isDatatypeKeyAux :: IRI -> [(String, String)]
isDatatypeKeyAux iri = mapMaybe (`checkPredefAux` iri)
[ xsdMap, owlNumbersMap, rdfMap, rdfsMap ]
type PreDefMaps = ([String], String, String)
preDefMaps :: [String] -> String -> PreDefMaps
preDefMaps sl pref = let
Just puri = Map.lookup pref predefPrefixes
Just sp = stripPrefix "http://www.w3.org/" puri
in (sl, pref, sp)
checkPredefAux :: PreDefMaps -> IRI -> Maybe (String, String)
checkPredefAux (sl, pref, exPref) u = let lp = localPart u in
case namePrefix u of
"http" -> case stripPrefix "//www." lp of
Just q -> case stripPrefix "w3.org/" q of
Just r -> case stripPrefix exPref r of
Just s | elem s sl -> Just (pref, s)
_ -> Nothing
Nothing -> case stripPrefix (dnamedS ++ "#") q of
Just s | elem s sl -> Just (pref, s)
_ -> Nothing
Nothing -> Nothing
pu | elem pu ["", pref] && elem lp sl -> Just (pref, lp)
_ -> Nothing
checkPredef :: PreDefMaps -> IRI -> Bool
checkPredef ms = isJust . checkPredefAux ms
makeOWLPredefMaps :: [String] -> PreDefMaps
makeOWLPredefMaps sl = preDefMaps sl "owl"
-- | sets the correct prefix for the predefined datatypes
setDatatypePrefix :: IRI -> IRI
setDatatypePrefix iri = case isDatatypeKeyAux iri of
(p, l) : _ -> setPrefix p $ mkQName l
_ -> error $ showQU iri ++ " is not a predefined datatype"
-- | checks if the IRI is part of the built-in ones and puts the correct prefix
setReservedPrefix :: IRI -> IRI
setReservedPrefix iri
| isDatatypeKey iri && null (namePrefix iri) = setDatatypePrefix iri
| (isThing iri || isPredefDataProp iri || isPredefOWLAnnoProp iri
|| isPredefObjProp iri) && null (namePrefix iri) = setPrefix "owl" iri
| isPredefRDFSAnnoProp iri = setPrefix "rdfs" iri
| otherwise = iri
stripReservedPrefix :: IRI -> IRI
stripReservedPrefix = mkQName . getPredefName
{- | returns the name of the predefined IRI (e.g <xsd:string> returns "string"
or <http://www.w3.org/2002/07/owl#real> returns "real") -}
getPredefName :: IRI -> String
getPredefName iri =
if namePrefix iri `elem` ["", "xsd", "rdf", "rdfs", "owl"]
then localPart iri
else case mapMaybe (`stripPrefix` showQU iri)
$ Map.elems predefPrefixes of
[s] -> s
_ -> showQN iri
-- | Extracts Token from IRI
uriToTok :: IRI -> Token
uriToTok urI = mkSimpleId $ getPredefName urI
-- | Extracts Id from IRI
uriToId :: IRI -> Id
uriToId = simpleIdToId . uriToTok
-- | Extracts Id from Entities
entityToId :: Entity -> Id
entityToId = uriToId . cutIRI
printDatatype :: IRI -> String
printDatatype dt = showQU $
if isDatatypeKey dt then stripReservedPrefix dt else dt
data DatatypeCat = OWL2Number | OWL2String | OWL2Bool | Other
deriving (Show, Eq, Ord, Typeable, Data)
getDatatypeCat :: IRI -> DatatypeCat
getDatatypeCat iri = case isDatatypeKey iri of
True
| checkPredef xsdBooleanMap iri -> OWL2Bool
| checkPredef xsdNumbersMap iri || checkPredef owlNumbersMap iri
-> OWL2Number
| checkPredef xsdStringsMap iri -> OWL2String
| otherwise -> Other
False -> Other
makeXsdMap :: [String] -> PreDefMaps
makeXsdMap sl = preDefMaps sl "xsd"
xsdBooleanMap :: PreDefMaps
xsdBooleanMap = makeXsdMap [booleanS]
xsdNumbersMap :: PreDefMaps
xsdNumbersMap = makeXsdMap xsdNumbers
xsdStringsMap :: PreDefMaps
xsdStringsMap = makeXsdMap xsdStrings
facetToIRI :: DatatypeFacet -> ConstrainingFacet
facetToIRI = setPrefix "xsd" . mkQName . showFacet
-- * Cardinalities
data CardinalityType = MinCardinality | MaxCardinality | ExactCardinality
deriving (Show, Eq, Ord, Typeable, Data)
showCardinalityType :: CardinalityType -> String
showCardinalityType ty = case ty of
MinCardinality -> minS
MaxCardinality -> maxS
ExactCardinality -> exactlyS
data Cardinality a b = Cardinality CardinalityType Int a (Maybe b)
deriving (Show, Eq, Ord, Typeable, Data)
data JunctionType = UnionOf | IntersectionOf
deriving (Show, Eq, Ord, Typeable, Data)
type ConstrainingFacet = IRI
type RestrictionValue = Literal
-- * ENTITIES
data Entity = Entity
{ label :: Maybe String
, entityKind :: EntityType
, cutIRI :: IRI }
deriving (Show, Typeable, Data)
mkEntity :: EntityType -> IRI -> Entity
mkEntity = Entity Nothing
mkEntityLbl :: String -> EntityType -> IRI -> Entity
mkEntityLbl = Entity . Just
instance Ord Entity where
compare (Entity _ ek1 ir1) (Entity _ ek2 ir2) = compare (ek1, ir1) (ek2, ir2)
instance Eq Entity where
e1 == e2 = compare e1 e2 == EQ
instance GetRange Entity where
getRange = iriPos . cutIRI
rangeSpan = qNameRange . cutIRI
data EntityType =
Datatype
| Class
| ObjectProperty
| DataProperty
| AnnotationProperty
| NamedIndividual
deriving (Enum, Bounded, Show, Read, Eq, Ord, Typeable, Data)
showEntityType :: EntityType -> String
showEntityType e = case e of
Datatype -> datatypeC
Class -> classC
ObjectProperty -> objectPropertyC
DataProperty -> dataPropertyC
AnnotationProperty -> annotationPropertyC
NamedIndividual -> individualC
entityTypes :: [EntityType]
entityTypes = [minBound .. maxBound]
pairSymbols :: Entity -> Entity -> Result Entity -- TODO: improve!
pairSymbols (Entity lb1 k1 i1) (Entity lb2 k2 i2) =
if k1 /= k2 then
error "can't pair symbols of different kind"
else do
let rest x = drop 1 $ dropWhile (/= '#') x
pairLables lbl1 lbl2 = case (lbl1, lbl2) of
(Nothing, _) -> pairLables lbl2 lbl1
(Just l1, Just l2) | l1 /= l2 -> Just $ l1 ++ ", " ++ l2
_ -> lbl1
pairIRIs (QN p1 l1 t1 _e1 r1)
(QN _p2 l2 _t2 _e2 _r2) =
QN
{ namePrefix = p1
, localPart = if rest l1 == rest l2 then l1 else l1 ++ "_" ++ rest l2
, iriType = t1
, expandedIRI = ""
, iriPos = r1
}
return $ Entity (pairLables lb1 lb2) k1 $ pairIRIs i1 i2
-- * LITERALS
data TypedOrUntyped = Typed Datatype | Untyped (Maybe LanguageTag)
deriving (Show, Eq, Ord, Typeable, Data)
data Literal = Literal LexicalForm TypedOrUntyped | NumberLit FloatLit
deriving (Show, Eq, Ord, Typeable, Data)
-- | non-negative integers given by the sequence of digits
data NNInt = NNInt [Int] deriving (Eq, Ord, Typeable, Data)
instance Show NNInt where
show (NNInt l) = map intToDigit l
zeroNNInt :: NNInt
zeroNNInt = NNInt []
isZeroNNInt :: NNInt -> Bool
isZeroNNInt (NNInt l) = null l
data IntLit = IntLit
{ absInt :: NNInt
, isNegInt :: Bool }
deriving (Eq, Ord, Typeable, Data)
instance Show IntLit where
show (IntLit n b) = (if b then ('-' :) else id) $ show n
zeroInt :: IntLit
zeroInt = IntLit zeroNNInt False
isZeroInt :: IntLit -> Bool
isZeroInt (IntLit n _) = isZeroNNInt n
negNNInt :: Bool -> NNInt -> IntLit
negNNInt b n = IntLit n b
negInt :: IntLit -> IntLit
negInt (IntLit n b) = IntLit n $ not b
data DecLit = DecLit
{ truncDec :: IntLit
, fracDec :: NNInt }
deriving (Eq, Ord, Typeable, Data)
instance Show DecLit where
show (DecLit t f) = show t
++ if isZeroNNInt f then "" else
'.' : show f
isDecInt :: DecLit -> Bool
isDecInt = isZeroNNInt . fracDec
negDec :: Bool -> DecLit -> DecLit
negDec b (DecLit t f) = DecLit (if b then negInt t else t) f
data FloatLit = FloatLit
{ floatBase :: DecLit
, floatExp :: IntLit }
deriving (Eq, Ord, Typeable, Data)
instance Show FloatLit where
show (FloatLit b e) = show b
++ if isZeroInt e then "" else
'E' : show e ++ "F"
isFloatDec :: FloatLit -> Bool
isFloatDec = isZeroInt . floatExp
isFloatInt :: FloatLit -> Bool
isFloatInt f = isFloatDec f && isDecInt (floatBase f)
floatToInt :: FloatLit -> IntLit
floatToInt = truncDec . floatBase
intToDec :: IntLit -> DecLit
intToDec i = DecLit i zeroNNInt
decToFloat :: DecLit -> FloatLit
decToFloat d = FloatLit d zeroInt
intToFloat :: IntLit -> FloatLit
intToFloat = decToFloat . intToDec
abInt :: IntLit -> IntLit
abInt int = int {isNegInt = False}
abDec :: DecLit -> DecLit
abDec dec = dec {truncDec = abInt $ truncDec dec}
abFloat :: FloatLit -> FloatLit
abFloat f = f {floatBase = abDec $ floatBase f}
isNegDec :: DecLit -> Bool
isNegDec d = isNegInt $ truncDec d
numberName :: FloatLit -> String
numberName f
| isFloatInt f = integerS
| isFloatDec f = decimalS
| otherwise = floatS
cTypeS :: String
cTypeS = "^^"
-- * PROPERTY EXPRESSIONS
type InverseObjectProperty = ObjectPropertyExpression
data ObjectPropertyExpression = ObjectProp ObjectProperty
| ObjectInverseOf InverseObjectProperty
deriving (Show, Eq, Ord, Typeable, Data)
objPropToIRI :: ObjectPropertyExpression -> Individual
objPropToIRI opExp = case opExp of
ObjectProp u -> u
ObjectInverseOf objProp -> objPropToIRI objProp
type DataPropertyExpression = DataProperty
-- * DATA RANGES
data DataRange =
DataType Datatype [(ConstrainingFacet, RestrictionValue)]
| DataJunction JunctionType [DataRange]
| DataComplementOf DataRange
| DataOneOf [Literal]
deriving (Show, Eq, Ord, Typeable, Data)
-- * CLASS EXPERSSIONS
data ClassExpression =
Expression Class
| ObjectJunction JunctionType [ClassExpression]
| ObjectComplementOf ClassExpression
| ObjectOneOf [Individual]
| ObjectValuesFrom QuantifierType ObjectPropertyExpression ClassExpression
| ObjectHasValue ObjectPropertyExpression Individual
| ObjectHasSelf ObjectPropertyExpression
| ObjectCardinality (Cardinality ObjectPropertyExpression ClassExpression)
| DataValuesFrom QuantifierType DataPropertyExpression DataRange
| DataHasValue DataPropertyExpression Literal
| DataCardinality (Cardinality DataPropertyExpression DataRange)
deriving (Show, Eq, Ord, Typeable, Data)
-- * ANNOTATIONS
data Annotation = Annotation [Annotation] AnnotationProperty AnnotationValue
deriving (Show, Eq, Ord, Typeable, Data)
data AnnotationValue = AnnValue IRI | AnnValLit Literal
deriving (Show, Eq, Ord, Typeable, Data)