{- |
Module      :  ./RDF/StaticAnalysis.hs
Copyright   :  Felix Gabriel Mance
License     :  GPLv2 or higher, see LICENSE.txt

Maintainer  :  f.mance@jacobs-university.de
Stability   :  provisional
Portability :  portable

Static analysis for RDF
-}

module RDF.StaticAnalysis where

import qualified OWL2.AS as AS
import Common.IRI
import OWL2.Parse ()
import RDF.AS
import RDF.Sign
import RDF.Parse (predefinedPrefixes)

import Data.Maybe
import qualified Data.Map as Map
import qualified Data.Set as Set

import Text.ParserCombinators.Parsec ()

import Common.AS_Annotation hiding (Annotation)
import Common.Id
import Common.Result
import Common.GlobalAnnotations
import Common.ExtSign
import Common.Lib.State

-- * URI Resolution

resolveFullIRI :: IRI -> IRI -> IRI
resolveFullIRI :: IRI -> IRI -> IRI
resolveFullIRI _absol :: IRI
_absol rel :: IRI
rel = IRI
rel
 {-if isAbsoluteIRI rel then rel else
    let r = fromJust $ parseIRIReference $ fromJust $ expandCurie Map.empty rel
        a = fromJust $ parseIRI $ fromJust $ expandCurie Map.empty absol
        Just ra = IRI.relativeTo r a
        resolved = IRI.iriToStringUnsecure ra
        Right new = parse uriQ "" $ "<" ++ resolved ++ ">"
    in rel {expandedIRI = expandedIRI new}
 -}

resolveAbbreviatedIRI :: RDFPrefixMap -> IRI -> IRI
resolveAbbreviatedIRI :: RDFPrefixMap -> IRI -> IRI
resolveAbbreviatedIRI pm :: RDFPrefixMap
pm new :: IRI
new = Maybe IRI -> IRI
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe IRI -> IRI) -> Maybe IRI -> IRI
forall a b. (a -> b) -> a -> b
$ RDFPrefixMap -> IRI -> Maybe IRI
expandCurie RDFPrefixMap
pm IRI
new
  {-case Map.lookup (namePrefix new) pm of
    Nothing -> error $ namePrefix new ++ ": prefix not declared"
    Just iri -> let new2 = if null (namePrefix new)
                                        {- FIXME: If null (localPart new)
                                                  then head will fail! -}
                                        && null (localPart new)
                                        && head (localPart new) == ':'
                            then new {localPart = tail $ localPart new}
                            else new
                in new2 {expandedIRI = expandedIRI iri ++ localPart new2}
 -}

resolveIRI :: Base -> RDFPrefixMap -> IRI -> IRI
resolveIRI :: Base -> RDFPrefixMap -> IRI -> IRI
resolveIRI (Base current :: IRI
current) pm :: RDFPrefixMap
pm new :: IRI
new 
    | IRI -> Bool
hasFullIRI IRI
new = IRI -> IRI -> IRI
resolveFullIRI IRI
current IRI
new
    | IRI -> Bool
isBlankNode IRI
new = IRI
new
    | Bool
otherwise = RDFPrefixMap -> IRI -> IRI
resolveAbbreviatedIRI RDFPrefixMap
pm IRI
new

resolveBase :: Base -> RDFPrefixMap -> Base -> Base
resolveBase :: Base -> RDFPrefixMap -> Base -> Base
resolveBase b :: Base
b pm :: RDFPrefixMap
pm (Base new :: IRI
new) = IRI -> Base
Base (IRI -> Base) -> IRI -> Base
forall a b. (a -> b) -> a -> b
$ Base -> RDFPrefixMap -> IRI -> IRI
resolveIRI Base
b RDFPrefixMap
pm IRI
new

resolvePrefix :: Base -> RDFPrefixMap -> Prefix -> (Prefix, RDFPrefixMap)
resolvePrefix :: Base -> RDFPrefixMap -> Prefix -> (Prefix, RDFPrefixMap)
resolvePrefix b :: Base
b pm :: RDFPrefixMap
pm (PrefixR s :: String
s new :: IRI
new) = let res :: IRI
res = Base -> RDFPrefixMap -> IRI -> IRI
resolveIRI Base
b RDFPrefixMap
pm IRI
new
    in (String -> IRI -> Prefix
PrefixR String
s IRI
res, String -> IRI -> RDFPrefixMap -> RDFPrefixMap
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert String
s IRI
res RDFPrefixMap
pm)

resolvePredicate :: Base -> RDFPrefixMap -> Predicate -> Predicate
resolvePredicate :: Base -> RDFPrefixMap -> Predicate -> Predicate
resolvePredicate b :: Base
b pm :: RDFPrefixMap
pm (Predicate p :: IRI
p) = IRI -> Predicate
Predicate (IRI -> Predicate) -> IRI -> Predicate
forall a b. (a -> b) -> a -> b
$
    if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (IRI -> String
prefixName IRI
p) Bool -> Bool -> Bool
&& Id -> String
forall a. Show a => a -> String
show (IRI -> Id
iriPath IRI
p) String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== "a" then
        IRI
p { iriScheme :: String
iriScheme = "http:",
            iriPath :: Id
iriPath = String -> Id
stringToId "//www.w3.org/1999/02/22-rdf-syntax-ns#type"
          }
    else Base -> RDFPrefixMap -> IRI -> IRI
resolveIRI Base
b RDFPrefixMap
pm IRI
p

resolveSubject :: Base -> RDFPrefixMap -> Subject -> Subject
resolveSubject :: Base -> RDFPrefixMap -> Subject -> Subject
resolveSubject b :: Base
b pm :: RDFPrefixMap
pm s :: Subject
s = case Subject
s of
    Subject iri :: IRI
iri -> IRI -> Subject
Subject (IRI -> Subject) -> IRI -> Subject
forall a b. (a -> b) -> a -> b
$ Base -> RDFPrefixMap -> IRI -> IRI
resolveIRI Base
b RDFPrefixMap
pm IRI
iri
    SubjectList ls :: [PredicateObjectList]
ls -> [PredicateObjectList] -> Subject
SubjectList ([PredicateObjectList] -> Subject)
-> [PredicateObjectList] -> Subject
forall a b. (a -> b) -> a -> b
$ (PredicateObjectList -> PredicateObjectList)
-> [PredicateObjectList] -> [PredicateObjectList]
forall a b. (a -> b) -> [a] -> [b]
map (Base -> RDFPrefixMap -> PredicateObjectList -> PredicateObjectList
resolvePOList Base
b RDFPrefixMap
pm) [PredicateObjectList]
ls
    SubjectCollection ls :: [Object]
ls -> [Object] -> Subject
SubjectCollection ([Object] -> Subject) -> [Object] -> Subject
forall a b. (a -> b) -> a -> b
$ (Object -> Object) -> [Object] -> [Object]
forall a b. (a -> b) -> [a] -> [b]
map (Base -> RDFPrefixMap -> Object -> Object
resolveObject Base
b RDFPrefixMap
pm) [Object]
ls

resolvePOList :: Base -> RDFPrefixMap -> PredicateObjectList
    -> PredicateObjectList
resolvePOList :: Base -> RDFPrefixMap -> PredicateObjectList -> PredicateObjectList
resolvePOList b :: Base
b pm :: RDFPrefixMap
pm (PredicateObjectList p :: Predicate
p ol :: [Object]
ol) =
    Predicate -> [Object] -> PredicateObjectList
PredicateObjectList (Base -> RDFPrefixMap -> Predicate -> Predicate
resolvePredicate Base
b RDFPrefixMap
pm Predicate
p) ([Object] -> PredicateObjectList)
-> [Object] -> PredicateObjectList
forall a b. (a -> b) -> a -> b
$ (Object -> Object) -> [Object] -> [Object]
forall a b. (a -> b) -> [a] -> [b]
map (Base -> RDFPrefixMap -> Object -> Object
resolveObject Base
b RDFPrefixMap
pm) [Object]
ol

resolveObject :: Base -> RDFPrefixMap -> Object -> Object
resolveObject :: Base -> RDFPrefixMap -> Object -> Object
resolveObject b :: Base
b pm :: RDFPrefixMap
pm o :: Object
o = case Object
o of
    Object s :: Subject
s -> Subject -> Object
Object (Subject -> Object) -> Subject -> Object
forall a b. (a -> b) -> a -> b
$ Base -> RDFPrefixMap -> Subject -> Subject
resolveSubject Base
b RDFPrefixMap
pm Subject
s
    ObjectLiteral lit :: RDFLiteral
lit -> case RDFLiteral
lit of
        RDFLiteral bool :: Bool
bool lf :: String
lf (AS.Typed dt :: IRI
dt) ->
                RDFLiteral -> Object
ObjectLiteral (RDFLiteral -> Object) -> RDFLiteral -> Object
forall a b. (a -> b) -> a -> b
$ Bool -> String -> TypedOrUntyped -> RDFLiteral
RDFLiteral Bool
bool String
lf (TypedOrUntyped -> RDFLiteral) -> TypedOrUntyped -> RDFLiteral
forall a b. (a -> b) -> a -> b
$ IRI -> TypedOrUntyped
AS.Typed (IRI -> TypedOrUntyped) -> IRI -> TypedOrUntyped
forall a b. (a -> b) -> a -> b
$ Base -> RDFPrefixMap -> IRI -> IRI
resolveIRI Base
b RDFPrefixMap
pm IRI
dt
        _ -> Object
o

resolveTriples :: Base -> RDFPrefixMap -> Triples -> Triples
resolveTriples :: Base -> RDFPrefixMap -> Triples -> Triples
resolveTriples b :: Base
b pm :: RDFPrefixMap
pm (Triples s :: Subject
s ls :: [PredicateObjectList]
ls) =
    Subject -> [PredicateObjectList] -> Triples
Triples (Base -> RDFPrefixMap -> Subject -> Subject
resolveSubject Base
b RDFPrefixMap
pm Subject
s) ([PredicateObjectList] -> Triples)
-> [PredicateObjectList] -> Triples
forall a b. (a -> b) -> a -> b
$ (PredicateObjectList -> PredicateObjectList)
-> [PredicateObjectList] -> [PredicateObjectList]
forall a b. (a -> b) -> [a] -> [b]
map (Base -> RDFPrefixMap -> PredicateObjectList -> PredicateObjectList
resolvePOList Base
b RDFPrefixMap
pm) [PredicateObjectList]
ls

resolveStatements :: Base -> RDFPrefixMap -> [Statement] -> [Statement]
resolveStatements :: Base -> RDFPrefixMap -> [Statement] -> [Statement]
resolveStatements b :: Base
b pm :: RDFPrefixMap
pm ls :: [Statement]
ls = case [Statement]
ls of
    [] -> []
    BaseStatement base :: Base
base : t :: [Statement]
t -> let newBase :: Base
newBase = Base -> RDFPrefixMap -> Base -> Base
resolveBase Base
b RDFPrefixMap
pm Base
base
            in Base -> Statement
BaseStatement Base
newBase Statement -> [Statement] -> [Statement]
forall a. a -> [a] -> [a]
: Base -> RDFPrefixMap -> [Statement] -> [Statement]
resolveStatements Base
newBase RDFPrefixMap
pm [Statement]
t
    PrefixStatement pref :: Prefix
pref : t :: [Statement]
t -> let (newPref :: Prefix
newPref, newPrefMap :: RDFPrefixMap
newPrefMap) = Base -> RDFPrefixMap -> Prefix -> (Prefix, RDFPrefixMap)
resolvePrefix Base
b RDFPrefixMap
pm Prefix
pref
            in Prefix -> Statement
PrefixStatement Prefix
newPref Statement -> [Statement] -> [Statement]
forall a. a -> [a] -> [a]
: Base -> RDFPrefixMap -> [Statement] -> [Statement]
resolveStatements Base
b RDFPrefixMap
newPrefMap [Statement]
t
    Statement triples :: Triples
triples : t :: [Statement]
t ->
            Triples -> Statement
Statement (Base -> RDFPrefixMap -> Triples -> Triples
resolveTriples Base
b RDFPrefixMap
pm Triples
triples) Statement -> [Statement] -> [Statement]
forall a. a -> [a] -> [a]
: Base -> RDFPrefixMap -> [Statement] -> [Statement]
resolveStatements Base
b RDFPrefixMap
pm [Statement]
t

extractPrefixMap :: RDFPrefixMap -> [Statement] -> RDFPrefixMap
extractPrefixMap :: RDFPrefixMap -> [Statement] -> RDFPrefixMap
extractPrefixMap pm :: RDFPrefixMap
pm ls :: [Statement]
ls = case [Statement]
ls of
    [] -> RDFPrefixMap
pm
    h :: Statement
h : t :: [Statement]
t -> case Statement
h of
        PrefixStatement (PrefixR p :: String
p iri :: IRI
iri) -> RDFPrefixMap -> [Statement] -> RDFPrefixMap
extractPrefixMap (String -> IRI -> RDFPrefixMap -> RDFPrefixMap
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert String
p IRI
iri RDFPrefixMap
pm) [Statement]
t
        _ -> RDFPrefixMap -> [Statement] -> RDFPrefixMap
extractPrefixMap RDFPrefixMap
pm [Statement]
t

resolveDocument :: TurtleDocument -> TurtleDocument
resolveDocument :: TurtleDocument -> TurtleDocument
resolveDocument doc :: TurtleDocument
doc = let newStatements :: [Statement]
newStatements = Base -> RDFPrefixMap -> [Statement] -> [Statement]
resolveStatements
                            (IRI -> Base
Base (IRI -> Base) -> IRI -> Base
forall a b. (a -> b) -> a -> b
$ TurtleDocument -> IRI
documentName TurtleDocument
doc) RDFPrefixMap
predefinedPrefixes ([Statement] -> [Statement]) -> [Statement] -> [Statement]
forall a b. (a -> b) -> a -> b
$ TurtleDocument -> [Statement]
statements TurtleDocument
doc
    in TurtleDocument
doc { statements :: [Statement]
statements = [Statement]
newStatements
           , prefixMap :: RDFPrefixMap
prefixMap = RDFPrefixMap -> RDFPrefixMap -> RDFPrefixMap
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union RDFPrefixMap
predefinedPrefixes (RDFPrefixMap -> RDFPrefixMap) -> RDFPrefixMap -> RDFPrefixMap
forall a b. (a -> b) -> a -> b
$
                                RDFPrefixMap -> [Statement] -> RDFPrefixMap
extractPrefixMap RDFPrefixMap
forall k a. Map k a
Map.empty [Statement]
newStatements }

-- * Axiom extraction

generateBNode :: Int -> IRI
generateBNode :: Int -> IRI
generateBNode i :: Int
i = IRI
nullIRI { iriPath :: Id
iriPath = String -> Id
stringToId ("bnode" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i)
                          , isAbbrev :: Bool
isAbbrev = Bool
True 
                          , isBlankNode :: Bool
isBlankNode = Bool
True}

collectionToPOList :: [Object] -> [PredicateObjectList]
collectionToPOList :: [Object] -> [PredicateObjectList]
collectionToPOList objs :: [Object]
objs = case [Object]
objs of
    [] -> []
    h :: Object
h : t :: [Object]
t -> [ Predicate -> [Object] -> PredicateObjectList
PredicateObjectList (IRI -> Predicate
Predicate IRI
rdfFirst) [Object
h]
             , Predicate -> [Object] -> PredicateObjectList
PredicateObjectList (IRI -> Predicate
Predicate IRI
rdfRest) [Subject -> Object
Object (Subject -> Object) -> Subject -> Object
forall a b. (a -> b) -> a -> b
$ if [Object] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Object]
t
                then IRI -> Subject
Subject IRI
rdfNil else [PredicateObjectList] -> Subject
SubjectList ([PredicateObjectList] -> Subject)
-> [PredicateObjectList] -> Subject
forall a b. (a -> b) -> a -> b
$ [Object] -> [PredicateObjectList]
collectionToPOList [Object]
t]]

expandPOList1 :: Triples -> [Triples]
expandPOList1 :: Triples -> [Triples]
expandPOList1 (Triples s :: Subject
s pols :: [PredicateObjectList]
pols) = (PredicateObjectList -> Triples)
-> [PredicateObjectList] -> [Triples]
forall a b. (a -> b) -> [a] -> [b]
map (\ pol :: PredicateObjectList
pol -> Subject -> [PredicateObjectList] -> Triples
Triples Subject
s [PredicateObjectList
pol]) [PredicateObjectList]
pols

-- | this assumes exactly one subject and one predicate
expandPOList2 :: Triples -> [Triples]
expandPOList2 :: Triples -> [Triples]
expandPOList2 (Triples s :: Subject
s pols :: [PredicateObjectList]
pols) = case [PredicateObjectList]
pols of
    [PredicateObjectList p :: Predicate
p objs :: [Object]
objs] ->
        (Object -> Triples) -> [Object] -> [Triples]
forall a b. (a -> b) -> [a] -> [b]
map (\ obj :: Object
obj -> Subject -> [PredicateObjectList] -> Triples
Triples Subject
s [Predicate -> [Object] -> PredicateObjectList
PredicateObjectList Predicate
p [Object
obj]]) [Object]
objs
    _ -> String -> [Triples]
forall a. HasCallStack => String -> a
error "unexpected ; abbreviated triple"

-- | converts a triple to a list of triples with one predicate and one object
expandPOList :: Triples -> [Triples]
expandPOList :: Triples -> [Triples]
expandPOList = (Triples -> [Triples]) -> [Triples] -> [Triples]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Triples -> [Triples]
expandPOList2 ([Triples] -> [Triples])
-> (Triples -> [Triples]) -> Triples -> [Triples]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Triples -> [Triples]
expandPOList1

-- | this assumes exactly one subject, one predicate and one object
expandObject1 :: Int -> Triples -> (Int, [Triples])
expandObject1 :: Int -> Triples -> (Int, [Triples])
expandObject1 i :: Int
i t :: Triples
t@(Triples s :: Subject
s ls :: [PredicateObjectList]
ls) = case [PredicateObjectList]
ls of
    [PredicateObjectList p :: Predicate
p [obj :: Object
obj]] -> case Object
obj of
        ObjectLiteral _ -> (Int
i, [Triples
t])
        Object (Subject _) -> (Int
i, [Triples
t])
        Object (SubjectList pol :: [PredicateObjectList]
pol) ->
            let bnode :: Subject
bnode = IRI -> Subject
Subject (IRI -> Subject) -> IRI -> Subject
forall a b. (a -> b) -> a -> b
$ Int -> IRI
generateBNode Int
i
                newTriple :: Triples
newTriple = Subject -> [PredicateObjectList] -> Triples
Triples Subject
s [Predicate -> [Object] -> PredicateObjectList
PredicateObjectList Predicate
p [Subject -> Object
Object Subject
bnode]]
                connectedTriples :: [Triples]
connectedTriples = Triples -> [Triples]
expandPOList (Triples -> [Triples]) -> Triples -> [Triples]
forall a b. (a -> b) -> a -> b
$ Subject -> [PredicateObjectList] -> Triples
Triples Subject
bnode [PredicateObjectList]
pol
                (j :: Int
j, expandedTriples :: [Triples]
expandedTriples) = Int -> [Triples] -> (Int, [Triples])
expandObject2 (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) [Triples]
connectedTriples
            in (Int
j, Triples
newTriple Triples -> [Triples] -> [Triples]
forall a. a -> [a] -> [a]
: [Triples]
expandedTriples)
        Object (SubjectCollection col :: [Object]
col) -> let pol :: [PredicateObjectList]
pol = [Object] -> [PredicateObjectList]
collectionToPOList [Object]
col
            in if [PredicateObjectList] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [PredicateObjectList]
pol then
                (Int
i, [Subject -> [PredicateObjectList] -> Triples
Triples Subject
s [Predicate -> [Object] -> PredicateObjectList
PredicateObjectList Predicate
p [Subject -> Object
Object (Subject -> Object) -> Subject -> Object
forall a b. (a -> b) -> a -> b
$ IRI -> Subject
Subject IRI
rdfNil]]])
               else Int -> Triples -> (Int, [Triples])
expandObject1 Int
i (Triples -> (Int, [Triples])) -> Triples -> (Int, [Triples])
forall a b. (a -> b) -> a -> b
$ Subject -> [PredicateObjectList] -> Triples
Triples Subject
s [Predicate -> [Object] -> PredicateObjectList
PredicateObjectList Predicate
p [Subject -> Object
Object (Subject -> Object) -> Subject -> Object
forall a b. (a -> b) -> a -> b
$ [PredicateObjectList] -> Subject
SubjectList [PredicateObjectList]
pol]]
    _ -> String -> (Int, [Triples])
forall a. HasCallStack => String -> a
error "unexpected , or ; abbreviated triple"

-- | this assumes each triple has one subject, one predicate and one object
expandObject2 :: Int -> [Triples] -> (Int, [Triples])
expandObject2 :: Int -> [Triples] -> (Int, [Triples])
expandObject2 i :: Int
i tl :: [Triples]
tl = case [Triples]
tl of
    [] -> (Int
i, [])
    h :: Triples
h : t :: [Triples]
t -> let (j :: Int
j, triples1 :: [Triples]
triples1) = Int -> Triples -> (Int, [Triples])
expandObject1 Int
i Triples
h
                 (k :: Int
k, triples2 :: [Triples]
triples2) = Int -> [Triples] -> (Int, [Triples])
expandObject2 Int
j [Triples]
t
             in (Int
k, [Triples]
triples1 [Triples] -> [Triples] -> [Triples]
forall a. [a] -> [a] -> [a]
++ [Triples]
triples2)

expandObject :: Int -> Triples -> (Int, [Triples])
expandObject :: Int -> Triples -> (Int, [Triples])
expandObject i :: Int
i t :: Triples
t = Int -> [Triples] -> (Int, [Triples])
expandObject2 Int
i ([Triples] -> (Int, [Triples])) -> [Triples] -> (Int, [Triples])
forall a b. (a -> b) -> a -> b
$ Triples -> [Triples]
expandPOList Triples
t

expandSubject :: Int -> Triples -> (Int, [Triples])
expandSubject :: Int -> Triples -> (Int, [Triples])
expandSubject i :: Int
i t :: Triples
t@(Triples s :: Subject
s ls :: [PredicateObjectList]
ls) = case Subject
s of
    Subject _ -> (Int
i, [Triples
t])
    SubjectList pol :: [PredicateObjectList]
pol -> let bnode :: Subject
bnode = IRI -> Subject
Subject (IRI -> Subject) -> IRI -> Subject
forall a b. (a -> b) -> a -> b
$ Int -> IRI
generateBNode Int
i
        in (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1, ([PredicateObjectList] -> Triples)
-> [[PredicateObjectList]] -> [Triples]
forall a b. (a -> b) -> [a] -> [b]
map (Subject -> [PredicateObjectList] -> Triples
Triples Subject
bnode) [[PredicateObjectList]
ls, [PredicateObjectList]
pol])
    SubjectCollection col :: [Object]
col -> let pol :: [PredicateObjectList]
pol = [Object] -> [PredicateObjectList]
collectionToPOList [Object]
col
        in if [Object] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Object]
col then (Int
i, [Subject -> [PredicateObjectList] -> Triples
Triples (IRI -> Subject
Subject IRI
rdfNil) [PredicateObjectList]
ls])
           else Int -> Triples -> (Int, [Triples])
expandSubject Int
i (Triples -> (Int, [Triples])) -> Triples -> (Int, [Triples])
forall a b. (a -> b) -> a -> b
$ Subject -> [PredicateObjectList] -> Triples
Triples ([PredicateObjectList] -> Subject
SubjectList [PredicateObjectList]
pol) [PredicateObjectList]
ls

expandTriple :: Int -> Triples -> (Int, [Triples])
expandTriple :: Int -> Triples -> (Int, [Triples])
expandTriple i :: Int
i t :: Triples
t = let (j :: Int
j, sst :: [Triples]
sst) = Int -> Triples -> (Int, [Triples])
expandSubject Int
i Triples
t in case [Triples]
sst of
    [triple :: Triples
triple] -> Int -> Triples -> (Int, [Triples])
expandObject Int
j Triples
triple
    [triple :: Triples
triple, connectedTriple :: Triples
connectedTriple] ->
        let (k :: Int
k, tl1 :: [Triples]
tl1) = Int -> Triples -> (Int, [Triples])
expandObject Int
j Triples
triple
            (l :: Int
l, tl2 :: [Triples]
tl2) = Int -> Triples -> (Int, [Triples])
expandObject Int
k Triples
connectedTriple
        in (Int
l, [Triples]
tl1 [Triples] -> [Triples] -> [Triples]
forall a. [a] -> [a] -> [a]
++ [Triples]
tl2)
    _ -> String -> (Int, [Triples])
forall a. HasCallStack => String -> a
error "expanding triple before expanding subject"

expandTripleList :: Int -> [Triples] -> (Int, [Triples])
expandTripleList :: Int -> [Triples] -> (Int, [Triples])
expandTripleList i :: Int
i tl :: [Triples]
tl = case [Triples]
tl of
    [] -> (Int
i, [])
    h :: Triples
h : t :: [Triples]
t -> let (j :: Int
j, tl1 :: [Triples]
tl1) = Int -> Triples -> (Int, [Triples])
expandTriple Int
i Triples
h
                 (k :: Int
k, tl2 :: [Triples]
tl2) = Int -> [Triples] -> (Int, [Triples])
expandTripleList Int
j [Triples]
t
             in (Int
k, [Triples]
tl1 [Triples] -> [Triples] -> [Triples]
forall a. [a] -> [a] -> [a]
++ [Triples]
tl2)

simpleTripleToAxiom :: Triples -> Axiom
simpleTripleToAxiom :: Triples -> Axiom
simpleTripleToAxiom (Triples s :: Subject
s pol :: [PredicateObjectList]
pol) = case (Subject
s, [PredicateObjectList]
pol) of
    (Subject sub :: IRI
sub, [PredicateObjectList (Predicate pr :: IRI
pr) [o :: Object
o]]) ->
        Term -> Term -> Term -> Axiom
Axiom (IRI -> Term
SubjectTerm IRI
sub) (IRI -> Term
PredicateTerm IRI
pr) (Term -> Axiom) -> Term -> Axiom
forall a b. (a -> b) -> a -> b
$ Either IRI RDFLiteral -> Term
ObjectTerm (Either IRI RDFLiteral -> Term) -> Either IRI RDFLiteral -> Term
forall a b. (a -> b) -> a -> b
$ case Object
o of
            ObjectLiteral lit :: RDFLiteral
lit -> RDFLiteral -> Either IRI RDFLiteral
forall a b. b -> Either a b
Right RDFLiteral
lit
            Object (Subject obj :: IRI
obj) -> IRI -> Either IRI RDFLiteral
forall a b. a -> Either a b
Left IRI
obj
            _ -> String -> Either IRI RDFLiteral
forall a. HasCallStack => String -> a
error "object should be an URI"
    _ -> String -> Axiom
forall a. HasCallStack => String -> a
error "subject should be an URI or triple should not be abbreviated"

createAxioms :: TurtleDocument -> [Axiom]
createAxioms :: TurtleDocument -> [Axiom]
createAxioms doc :: TurtleDocument
doc = (Triples -> Axiom) -> [Triples] -> [Axiom]
forall a b. (a -> b) -> [a] -> [b]
map Triples -> Axiom
simpleTripleToAxiom ([Triples] -> [Axiom]) -> [Triples] -> [Axiom]
forall a b. (a -> b) -> a -> b
$ (Int, [Triples]) -> [Triples]
forall a b. (a, b) -> b
snd ((Int, [Triples]) -> [Triples]) -> (Int, [Triples]) -> [Triples]
forall a b. (a -> b) -> a -> b
$ Int -> [Triples] -> (Int, [Triples])
expandTripleList 1
                                    ([Triples] -> (Int, [Triples])) -> [Triples] -> (Int, [Triples])
forall a b. (a -> b) -> a -> b
$ TurtleDocument -> [Triples]
triplesOfDocument (TurtleDocument -> [Triples]) -> TurtleDocument -> [Triples]
forall a b. (a -> b) -> a -> b
$ TurtleDocument -> TurtleDocument
resolveDocument TurtleDocument
doc

-- | takes an entity and modifies the sign according to the given function
modEntity :: (Term -> Set.Set Term -> Set.Set Term) -> RDFEntity -> State Sign ()
modEntity :: (Term -> Set Term -> Set Term) -> RDFEntity -> State Sign ()
modEntity f :: Term -> Set Term -> Set Term
f (RDFEntity ty :: RDFEntityType
ty u :: Term
u) = do
  Sign
s <- State Sign Sign
forall s. State s s
get
  let chg :: Set Term -> Set Term
chg = Term -> Set Term -> Set Term
f Term
u
  Sign -> State Sign ()
forall s. s -> State s ()
put (Sign -> State Sign ()) -> Sign -> State Sign ()
forall a b. (a -> b) -> a -> b
$ case RDFEntityType
ty of
    SubjectEntity -> Sign
s { subjects :: Set Term
subjects = Set Term -> Set Term
chg (Set Term -> Set Term) -> Set Term -> Set Term
forall a b. (a -> b) -> a -> b
$ Sign -> Set Term
subjects Sign
s }
    PredicateEntity -> Sign
s { predicates :: Set Term
predicates = Set Term -> Set Term
chg (Set Term -> Set Term) -> Set Term -> Set Term
forall a b. (a -> b) -> a -> b
$ Sign -> Set Term
predicates Sign
s }
    ObjectEntity -> Sign
s { objects :: Set Term
objects = Set Term -> Set Term
chg (Set Term -> Set Term) -> Set Term -> Set Term
forall a b. (a -> b) -> a -> b
$ Sign -> Set Term
objects Sign
s }

-- | adding entities to the signature
addEntity :: RDFEntity -> State Sign ()
addEntity :: RDFEntity -> State Sign ()
addEntity = (Term -> Set Term -> Set Term) -> RDFEntity -> State Sign ()
modEntity Term -> Set Term -> Set Term
forall a. Ord a => a -> Set a -> Set a
Set.insert

collectEntities :: Axiom -> State Sign ()
collectEntities :: Axiom -> State Sign ()
collectEntities (Axiom sub :: Term
sub pre :: Term
pre obj :: Term
obj) = do
    RDFEntity -> State Sign ()
addEntity (RDFEntityType -> Term -> RDFEntity
RDFEntity RDFEntityType
SubjectEntity Term
sub)
    RDFEntity -> State Sign ()
addEntity (RDFEntityType -> Term -> RDFEntity
RDFEntity RDFEntityType
PredicateEntity Term
pre)
    RDFEntity -> State Sign ()
addEntity (RDFEntityType -> Term -> RDFEntity
RDFEntity RDFEntityType
ObjectEntity Term
obj)

-- | collects all entites from the axioms
createSign :: TurtleDocument -> State Sign ()
createSign :: TurtleDocument -> State Sign ()
createSign = (Axiom -> State Sign ()) -> [Axiom] -> State Sign ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Axiom -> State Sign ()
collectEntities ([Axiom] -> State Sign ())
-> (TurtleDocument -> [Axiom]) -> TurtleDocument -> State Sign ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TurtleDocument -> [Axiom]
createAxioms

anaAxiom :: Axiom -> Named Axiom
anaAxiom :: Axiom -> Named Axiom
anaAxiom = String -> Axiom -> Named Axiom
forall a s. a -> s -> SenAttr s a
makeNamed ""

-- | static analysis of document with incoming sign.
basicRDFAnalysis :: (TurtleDocument, Sign, GlobalAnnos)
    -> Result (TurtleDocument, ExtSign Sign RDFEntity, [Named Axiom])
basicRDFAnalysis :: (TurtleDocument, Sign, GlobalAnnos)
-> Result (TurtleDocument, ExtSign Sign RDFEntity, [Named Axiom])
basicRDFAnalysis (doc :: TurtleDocument
doc, inSign :: Sign
inSign, _) = do
    let syms :: Set RDFEntity
syms = Set RDFEntity -> Set RDFEntity -> Set RDFEntity
forall a. Ord a => Set a -> Set a -> Set a
Set.difference (Sign -> Set RDFEntity
symOf Sign
accSign) (Set RDFEntity -> Set RDFEntity) -> Set RDFEntity -> Set RDFEntity
forall a b. (a -> b) -> a -> b
$ Sign -> Set RDFEntity
symOf Sign
inSign
        accSign :: Sign
accSign = State Sign () -> Sign -> Sign
forall s a. State s a -> s -> s
execState (TurtleDocument -> State Sign ()
createSign TurtleDocument
doc) Sign
inSign
        axioms :: [Named Axiom]
axioms = (Axiom -> Named Axiom) -> [Axiom] -> [Named Axiom]
forall a b. (a -> b) -> [a] -> [b]
map Axiom -> Named Axiom
anaAxiom ([Axiom] -> [Named Axiom]) -> [Axiom] -> [Named Axiom]
forall a b. (a -> b) -> a -> b
$ TurtleDocument -> [Axiom]
createAxioms TurtleDocument
doc
    (TurtleDocument, ExtSign Sign RDFEntity, [Named Axiom])
-> Result (TurtleDocument, ExtSign Sign RDFEntity, [Named Axiom])
forall (m :: * -> *) a. Monad m => a -> m a
return (TurtleDocument
doc, Sign -> Set RDFEntity -> ExtSign Sign RDFEntity
forall sign symbol. sign -> Set symbol -> ExtSign sign symbol
ExtSign Sign
accSign Set RDFEntity
syms, [Named Axiom]
axioms)