{-# LANGUAGE DeriveGeneric
, DeriveAnyClass
#-}
module Data.RDF.Graph (
GNode(..)
, GEdge
, rdfGraph
, triplesGraph
, graphRDF
, graphTriples
) where
import Control.DeepSeq
import qualified Data.Graph.Inductive.Graph as G
import qualified Data.Graph.Inductive.NodeMap as G
import Data.Maybe
import Data.RDF.Types
import GHC.Generics
data GNode = IRIGNode !IRI
| BlankGNode !BlankNode
| LiteralGNode !Literal
deriving ( GNode -> GNode -> Bool
(GNode -> GNode -> Bool) -> (GNode -> GNode -> Bool) -> Eq GNode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GNode -> GNode -> Bool
$c/= :: GNode -> GNode -> Bool
== :: GNode -> GNode -> Bool
$c== :: GNode -> GNode -> Bool
Eq
, Eq GNode
Eq GNode
-> (GNode -> GNode -> Ordering)
-> (GNode -> GNode -> Bool)
-> (GNode -> GNode -> Bool)
-> (GNode -> GNode -> Bool)
-> (GNode -> GNode -> Bool)
-> (GNode -> GNode -> GNode)
-> (GNode -> GNode -> GNode)
-> Ord GNode
GNode -> GNode -> Bool
GNode -> GNode -> Ordering
GNode -> GNode -> GNode
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: GNode -> GNode -> GNode
$cmin :: GNode -> GNode -> GNode
max :: GNode -> GNode -> GNode
$cmax :: GNode -> GNode -> GNode
>= :: GNode -> GNode -> Bool
$c>= :: GNode -> GNode -> Bool
> :: GNode -> GNode -> Bool
$c> :: GNode -> GNode -> Bool
<= :: GNode -> GNode -> Bool
$c<= :: GNode -> GNode -> Bool
< :: GNode -> GNode -> Bool
$c< :: GNode -> GNode -> Bool
compare :: GNode -> GNode -> Ordering
$ccompare :: GNode -> GNode -> Ordering
$cp1Ord :: Eq GNode
Ord
, ReadPrec [GNode]
ReadPrec GNode
Int -> ReadS GNode
ReadS [GNode]
(Int -> ReadS GNode)
-> ReadS [GNode]
-> ReadPrec GNode
-> ReadPrec [GNode]
-> Read GNode
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [GNode]
$creadListPrec :: ReadPrec [GNode]
readPrec :: ReadPrec GNode
$creadPrec :: ReadPrec GNode
readList :: ReadS [GNode]
$creadList :: ReadS [GNode]
readsPrec :: Int -> ReadS GNode
$creadsPrec :: Int -> ReadS GNode
Read
, Int -> GNode -> ShowS
[GNode] -> ShowS
GNode -> String
(Int -> GNode -> ShowS)
-> (GNode -> String) -> ([GNode] -> ShowS) -> Show GNode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GNode] -> ShowS
$cshowList :: [GNode] -> ShowS
show :: GNode -> String
$cshow :: GNode -> String
showsPrec :: Int -> GNode -> ShowS
$cshowsPrec :: Int -> GNode -> ShowS
Show
, (forall x. GNode -> Rep GNode x)
-> (forall x. Rep GNode x -> GNode) -> Generic GNode
forall x. Rep GNode x -> GNode
forall x. GNode -> Rep GNode x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep GNode x -> GNode
$cfrom :: forall x. GNode -> Rep GNode x
Generic
, GNode -> ()
(GNode -> ()) -> NFData GNode
forall a. (a -> ()) -> NFData a
rnf :: GNode -> ()
$crnf :: GNode -> ()
NFData
)
type GEdge = Predicate
subjectNode :: Subject -> GNode
subjectNode :: Subject -> GNode
subjectNode (IRISubject IRI
i) = IRI -> GNode
IRIGNode IRI
i
subjectNode (BlankSubject BlankNode
b) = BlankNode -> GNode
BlankGNode BlankNode
b
objectNode :: Object -> GNode
objectNode :: Object -> GNode
objectNode (IRIObject IRI
i) = IRI -> GNode
IRIGNode IRI
i
objectNode (BlankObject BlankNode
b) = BlankNode -> GNode
BlankGNode BlankNode
b
objectNode (LiteralObject Literal
l) = Literal -> GNode
LiteralGNode Literal
l
nodeSubject :: GNode -> Either String Subject
nodeSubject :: GNode -> Either String Subject
nodeSubject (IRIGNode IRI
i) = Subject -> Either String Subject
forall a b. b -> Either a b
Right (IRI -> Subject
IRISubject IRI
i)
nodeSubject (BlankGNode BlankNode
b) = Subject -> Either String Subject
forall a b. b -> Either a b
Right (BlankNode -> Subject
BlankSubject BlankNode
b)
nodeSubject GNode
_ = String -> Either String Subject
forall a b. a -> Either a b
Left String
"nodeSubject: subject must IRI or blank node."
nodeObject :: GNode -> Object
nodeObject :: GNode -> Object
nodeObject (IRIGNode IRI
i) = IRI -> Object
IRIObject IRI
i
nodeObject (BlankGNode BlankNode
b) = BlankNode -> Object
BlankObject BlankNode
b
nodeObject (LiteralGNode Literal
l) = Literal -> Object
LiteralObject Literal
l
rdfGraph :: G.DynGraph g => RDFGraph -> (g GNode GEdge, G.NodeMap GNode)
rdfGraph :: RDFGraph -> (g GNode GEdge, NodeMap GNode)
rdfGraph (RDFGraph Maybe IRI
_ [Triple]
ts) = [Triple] -> (g GNode GEdge, NodeMap GNode)
forall (g :: * -> * -> *).
DynGraph g =>
[Triple] -> (g GNode GEdge, NodeMap GNode)
triplesGraph [Triple]
ts
triplesGraph :: G.DynGraph g => [Triple] -> (g GNode GEdge, G.NodeMap GNode)
triplesGraph :: [Triple] -> (g GNode GEdge, NodeMap GNode)
triplesGraph [Triple]
triples = [GNode]
-> [(GNode, GNode, GEdge)] -> (g GNode GEdge, NodeMap GNode)
forall a (g :: * -> * -> *) b.
(Ord a, DynGraph g) =>
[a] -> [(a, a, b)] -> (g a b, NodeMap a)
G.mkMapGraph [GNode]
nodes [(GNode, GNode, GEdge)]
edges
where ([GNode]
nodes, [(GNode, GNode, GEdge)]
edges) = ([GNode], [(GNode, GNode, GEdge)])
-> [Triple] -> ([GNode], [(GNode, GNode, GEdge)])
go ([],[]) [Triple]
triples
go :: ([GNode], [(GNode, GNode, GEdge)])
-> [Triple] -> ([GNode], [(GNode, GNode, GEdge)])
go ([GNode]
ns, [(GNode, GNode, GEdge)]
es) [] = ([GNode]
ns, [(GNode, GNode, GEdge)]
es)
go ([GNode]
ns, [(GNode, GNode, GEdge)]
es) (Triple Subject
s GEdge
p Object
o:[Triple]
ts) = let s' :: GNode
s' = Subject -> GNode
subjectNode Subject
s
o' :: GNode
o' = Object -> GNode
objectNode Object
o
in ([GNode], [(GNode, GNode, GEdge)])
-> [Triple] -> ([GNode], [(GNode, GNode, GEdge)])
go (GNode
s'GNode -> [GNode] -> [GNode]
forall a. a -> [a] -> [a]
:GNode
o'GNode -> [GNode] -> [GNode]
forall a. a -> [a] -> [a]
:[GNode]
ns, (GNode
s', GNode
o', GEdge
p)(GNode, GNode, GEdge)
-> [(GNode, GNode, GEdge)] -> [(GNode, GNode, GEdge)]
forall a. a -> [a] -> [a]
:[(GNode, GNode, GEdge)]
es) [Triple]
ts
graphRDF :: G.Graph g => Maybe IRI -> g GNode GEdge -> Either String RDFGraph
graphRDF :: Maybe IRI -> g GNode GEdge -> Either String RDFGraph
graphRDF Maybe IRI
l = (Maybe IRI -> [Triple] -> RDFGraph
RDFGraph Maybe IRI
l ([Triple] -> RDFGraph)
-> Either String [Triple] -> Either String RDFGraph
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Either String [Triple] -> Either String RDFGraph)
-> (g GNode GEdge -> Either String [Triple])
-> g GNode GEdge
-> Either String RDFGraph
forall b c a. (b -> c) -> (a -> b) -> a -> c
. g GNode GEdge -> Either String [Triple]
forall (g :: * -> * -> *).
Graph g =>
g GNode GEdge -> Either String [Triple]
graphTriples
graphTriples :: G.Graph g => g GNode GEdge -> Either String [Triple]
graphTriples :: g GNode GEdge -> Either String [Triple]
graphTriples g GNode GEdge
g = [(Int, Int, GEdge)] -> Either String [Triple]
go (g GNode GEdge -> [(Int, Int, GEdge)]
forall (gr :: * -> * -> *) a b. Graph gr => gr a b -> [LEdge b]
G.labEdges g GNode GEdge
g)
where go :: [(Int, Int, GEdge)] -> Either String [Triple]
go [] = [Triple] -> Either String [Triple]
forall a b. b -> Either a b
Right []
go ((Int
si, Int
oi, GEdge
p):[(Int, Int, GEdge)]
ts) = let s :: Either String Subject
s = GNode -> Either String Subject
nodeSubject (Maybe GNode -> GNode
forall a. HasCallStack => Maybe a -> a
fromJust (g GNode GEdge -> Int -> Maybe GNode
forall (gr :: * -> * -> *) a b.
Graph gr =>
gr a b -> Int -> Maybe a
G.lab g GNode GEdge
g Int
si))
o :: Object
o = GNode -> Object
nodeObject (Maybe GNode -> GNode
forall a. HasCallStack => Maybe a -> a
fromJust (g GNode GEdge -> Int -> Maybe GNode
forall (gr :: * -> * -> *) a b.
Graph gr =>
gr a b -> Int -> Maybe a
G.lab g GNode GEdge
g Int
oi))
in ((\Subject
s' -> (Subject -> GEdge -> Object -> Triple
Triple Subject
s' GEdge
p Object
oTriple -> [Triple] -> [Triple]
forall a. a -> [a] -> [a]
:)) (Subject -> [Triple] -> [Triple])
-> Either String Subject -> Either String ([Triple] -> [Triple])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either String Subject
s) Either String ([Triple] -> [Triple])
-> Either String [Triple] -> Either String [Triple]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [(Int, Int, GEdge)] -> Either String [Triple]
go [(Int, Int, GEdge)]
ts