{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE ScopedTypeVariables #-}

-- |A graph implementation mapping hashed S to a mapping of
--  hashed P to hashed O, backed by 'Data.HashMap'.

module Data.RDF.Graph.AdjHashMap (AdjHashMap) where

import Prelude hiding (pred)
#if MIN_VERSION_base(4,9,0)
#if !MIN_VERSION_base(4,11,0)
import Data.Semigroup
#else
#endif
#else
#endif
import Data.List
import Data.Binary (Binary)
import Data.RDF.Types
import Data.RDF.Query
import Data.Hashable ()
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap
import Data.HashSet (HashSet)
import qualified Data.HashSet as Set
import Control.Monad (mfilter)
import Control.DeepSeq (NFData)
import GHC.Generics

-- |A map-based graph implementation.
--
-- This instance of 'RDF' is an adjacency map with each subject
-- mapping to a mapping from a predicate node to the adjacent nodes
-- via that predicate.
--
-- Given the following triples graph::
--
-- @
--   (http:\/\/example.com\/s1,http:\/\/example.com\/p1,http:\/\/example.com\/o1)
--   (http:\/\/example.com\/s1,http:\/\/example.com\/p1,http:\/\/example.com\/o2)
--   (http:\/\/example.com\/s1,http:\/\/example.com\/p2,http:\/\/example.com\/o1)
--   (http:\/\/example.com\/s2,http:\/\/example.com\/p3,http:\/\/example.com\/o3)
-- @
--
-- where
--
-- > hash "http://example.com/s1" = 1600134414
-- > hash "http://example.com/s2" = 1600134413
-- > hash "http://example.com/p1" = 1616912099
-- > hash "http://example.com/p2" = 1616912096
-- > hash "http://example.com/p3" = 1616912097
-- > hash "http://example.com/o1" = 1935686794
-- > hash "http://example.com/o2" = 1935686793
-- > hash "http://example.com/o3" = 1935686792
--
-- the in-memory hashmap representation of the triples graph is:
--
-- @
-- key:1600134414, value:(key:1616912099, value:[1935686794    -- (..\/s1,..\/p1,..\/o1)
--                                              ,1935686793];  -- (..\/s1,..\/p1,..\/o2)
--                        key:1616912096, value:[1935686794]); -- (..\/s1,..\/p2,..\/o1)
-- key:1600134413, value:(key:1616912097, value:[1935686792])  -- (..\/s1,..\/p3,..\/o3)
-- @
--
-- Worst-case time complexity of the graph functions, with respect
-- to the number of triples, are:
--
--  * 'empty'    : O(1)
--
--  * 'mkRdf'  : O(n)
--
--  * 'triplesOf': O(n)
--
--  * 'select'   : O(n)
--
--  * 'query'    : O(log n)
-- newtype HashS = HashS (TMaps, Maybe BaseUrl, PrefixMappings)
--                  deriving (NFData)

data AdjHashMap deriving ((forall x. AdjHashMap -> Rep AdjHashMap x)
-> (forall x. Rep AdjHashMap x -> AdjHashMap) -> Generic AdjHashMap
forall x. Rep AdjHashMap x -> AdjHashMap
forall x. AdjHashMap -> Rep AdjHashMap x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. AdjHashMap -> Rep AdjHashMap x
from :: forall x. AdjHashMap -> Rep AdjHashMap x
$cto :: forall x. Rep AdjHashMap x -> AdjHashMap
to :: forall x. Rep AdjHashMap x -> AdjHashMap
Generic)

instance Binary AdjHashMap
instance NFData AdjHashMap

data instance RDF AdjHashMap = AdjHashMap (TMaps, Maybe BaseUrl, PrefixMappings)
                 deriving (RDF AdjHashMap -> ()
(RDF AdjHashMap -> ()) -> NFData (RDF AdjHashMap)
forall a. (a -> ()) -> NFData a
$crnf :: RDF AdjHashMap -> ()
rnf :: RDF AdjHashMap -> ()
NFData,(forall x. RDF AdjHashMap -> Rep (RDF AdjHashMap) x)
-> (forall x. Rep (RDF AdjHashMap) x -> RDF AdjHashMap)
-> Generic (RDF AdjHashMap)
forall x. Rep (RDF AdjHashMap) x -> RDF AdjHashMap
forall x. RDF AdjHashMap -> Rep (RDF AdjHashMap) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. RDF AdjHashMap -> Rep (RDF AdjHashMap) x
from :: forall x. RDF AdjHashMap -> Rep (RDF AdjHashMap) x
$cto :: forall x. Rep (RDF AdjHashMap) x -> RDF AdjHashMap
to :: forall x. Rep (RDF AdjHashMap) x -> RDF AdjHashMap
Generic)

instance Rdf AdjHashMap where
  baseUrl :: RDF AdjHashMap -> Maybe BaseUrl
baseUrl           = RDF AdjHashMap -> Maybe BaseUrl
baseUrl'
  prefixMappings :: RDF AdjHashMap -> PrefixMappings
prefixMappings    = RDF AdjHashMap -> PrefixMappings
prefixMappings'
  addPrefixMappings :: RDF AdjHashMap -> PrefixMappings -> Bool -> RDF AdjHashMap
addPrefixMappings = RDF AdjHashMap -> PrefixMappings -> Bool -> RDF AdjHashMap
addPrefixMappings'
  empty :: RDF AdjHashMap
empty             = RDF AdjHashMap
empty'
  mkRdf :: Triples -> Maybe BaseUrl -> PrefixMappings -> RDF AdjHashMap
mkRdf             = Triples -> Maybe BaseUrl -> PrefixMappings -> RDF AdjHashMap
mkRdf'
  triplesOf :: RDF AdjHashMap -> Triples
triplesOf         = RDF AdjHashMap -> Triples
triplesOf'
  uniqTriplesOf :: RDF AdjHashMap -> Triples
uniqTriplesOf     = RDF AdjHashMap -> Triples
uniqTriplesOf'
  select :: RDF AdjHashMap
-> NodeSelector -> NodeSelector -> NodeSelector -> Triples
select            = RDF AdjHashMap
-> NodeSelector -> NodeSelector -> NodeSelector -> Triples
select'
  query :: RDF AdjHashMap -> Maybe Node -> Maybe Node -> Maybe Node -> Triples
query             = RDF AdjHashMap -> Maybe Node -> Maybe Node -> Maybe Node -> Triples
query'
  showGraph :: RDF AdjHashMap -> [Char]
showGraph         = RDF AdjHashMap -> [Char]
showGraph'
  addTriple :: RDF AdjHashMap -> Triple -> RDF AdjHashMap
addTriple         = RDF AdjHashMap -> Triple -> RDF AdjHashMap
addTriple'
  removeTriple :: RDF AdjHashMap -> Triple -> RDF AdjHashMap
removeTriple      = RDF AdjHashMap -> Triple -> RDF AdjHashMap
removeTriple'

-- instance Show (AdjHashMap) where
--   show (AdjHashMap ((spoMap, _), _, _)) =
--     let ts = concatMap (uncurry tripsSubj) subjPredMaps
--           where subjPredMaps = HashMap.toList spoMap
--     in concatMap (\t -> show t <> "\n") ts

showGraph' :: RDF AdjHashMap -> String
showGraph' :: RDF AdjHashMap -> [Char]
showGraph' ((AdjHashMap ((TMap
spoMap, TMap
_), Maybe BaseUrl
_, PrefixMappings
_))) =
    let ts :: Triples
ts = ((Node, HashMap Node Adjacencies) -> Triples)
-> [(Node, HashMap Node Adjacencies)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Node -> HashMap Node Adjacencies -> Triples)
-> (Node, HashMap Node Adjacencies) -> Triples
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Node -> HashMap Node Adjacencies -> Triples
tripsSubj) [(Node, HashMap Node Adjacencies)]
subjPredMaps
          where subjPredMaps :: [(Node, HashMap Node Adjacencies)]
subjPredMaps = TMap -> [(Node, HashMap Node Adjacencies)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList TMap
spoMap
    in (Triple -> [Char]) -> Triples -> [Char]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\Triple
t -> Triple -> [Char]
forall a. Show a => a -> [Char]
show Triple
t [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"\n") Triples
ts

-- instance Show (RDF AdjHashMap) where
--   show gr = concatMap (\t -> show t <> "\n")  (triplesOf gr)

-- some convenience type alias for readability

-- An adjacency map for a subject, mapping from a predicate node to
-- to the adjacent nodes via that predicate.
type AdjacencyMap = HashMap Predicate Adjacencies
type Adjacencies = HashSet Node

type TMap   = HashMap Node AdjacencyMap
type TMaps  = (TMap, TMap)

baseUrl' :: RDF AdjHashMap -> Maybe BaseUrl
baseUrl' :: RDF AdjHashMap -> Maybe BaseUrl
baseUrl' (AdjHashMap (TMaps
_, Maybe BaseUrl
baseURL, PrefixMappings
_)) = Maybe BaseUrl
baseURL

prefixMappings' :: RDF AdjHashMap -> PrefixMappings
prefixMappings' :: RDF AdjHashMap -> PrefixMappings
prefixMappings' (AdjHashMap (TMaps
_, Maybe BaseUrl
_, PrefixMappings
pms)) = PrefixMappings
pms

addPrefixMappings' :: RDF AdjHashMap -> PrefixMappings -> Bool -> RDF AdjHashMap
addPrefixMappings' :: RDF AdjHashMap -> PrefixMappings -> Bool -> RDF AdjHashMap
addPrefixMappings' (AdjHashMap (TMaps
ts, Maybe BaseUrl
baseURL, PrefixMappings
pms)) PrefixMappings
pms' Bool
replace =
  let merge :: PrefixMappings -> PrefixMappings -> PrefixMappings
merge = if Bool
replace then (PrefixMappings -> PrefixMappings -> PrefixMappings)
-> PrefixMappings -> PrefixMappings -> PrefixMappings
forall a b c. (a -> b -> c) -> b -> a -> c
flip PrefixMappings -> PrefixMappings -> PrefixMappings
forall a. Semigroup a => a -> a -> a
(<>) else PrefixMappings -> PrefixMappings -> PrefixMappings
forall a. Semigroup a => a -> a -> a
(<>)
  in  (TMaps, Maybe BaseUrl, PrefixMappings) -> RDF AdjHashMap
AdjHashMap (TMaps
ts, Maybe BaseUrl
baseURL, PrefixMappings -> PrefixMappings -> PrefixMappings
merge PrefixMappings
pms PrefixMappings
pms')

empty' :: RDF AdjHashMap
empty' :: RDF AdjHashMap
empty' = (TMaps, Maybe BaseUrl, PrefixMappings) -> RDF AdjHashMap
AdjHashMap ((TMap
forall a. Monoid a => a
mempty, TMap
forall a. Monoid a => a
mempty), Maybe BaseUrl
forall a. Maybe a
Nothing, Map Text Text -> PrefixMappings
PrefixMappings Map Text Text
forall a. Monoid a => a
mempty)

mkRdf' :: Triples -> Maybe BaseUrl -> PrefixMappings -> RDF AdjHashMap
mkRdf' :: Triples -> Maybe BaseUrl -> PrefixMappings -> RDF AdjHashMap
mkRdf' Triples
ts Maybe BaseUrl
baseURL PrefixMappings
pms = (TMaps, Maybe BaseUrl, PrefixMappings) -> RDF AdjHashMap
AdjHashMap (TMaps -> Triples -> TMaps
mergeTs (TMap
forall a. Monoid a => a
mempty, TMap
forall a. Monoid a => a
mempty) Triples
ts, Maybe BaseUrl
baseURL, PrefixMappings
pms)

addTriple' :: RDF AdjHashMap -> Triple -> RDF AdjHashMap
addTriple' :: RDF AdjHashMap -> Triple -> RDF AdjHashMap
addTriple' (AdjHashMap (TMaps
tmaps, Maybe BaseUrl
baseURL, PrefixMappings
pms)) Triple
t =
  let newTMaps :: TMaps
newTMaps = TMaps -> Triples -> TMaps
mergeTs TMaps
tmaps [Triple
t]
  in (TMaps, Maybe BaseUrl, PrefixMappings) -> RDF AdjHashMap
AdjHashMap (TMaps
newTMaps, Maybe BaseUrl
baseURL, PrefixMappings
pms)

removeTriple' :: RDF AdjHashMap -> Triple -> RDF AdjHashMap
removeTriple' :: RDF AdjHashMap -> Triple -> RDF AdjHashMap
removeTriple' (AdjHashMap ((TMap
spo, TMap
ops), Maybe BaseUrl
baseURL, PrefixMappings
pms)) (Triple Node
s Node
p Node
o) =
  (TMaps, Maybe BaseUrl, PrefixMappings) -> RDF AdjHashMap
AdjHashMap (TMaps
new_tmaps, Maybe BaseUrl
baseURL, PrefixMappings
pms)
  where
    new_tmaps :: TMaps
new_tmaps = (Node -> Node -> Node -> TMap -> TMap
forall {k} {k} {a}.
(Hashable k, Hashable k, Hashable a) =>
k
-> k
-> a
-> HashMap k (HashMap k (HashSet a))
-> HashMap k (HashMap k (HashSet a))
removeT Node
s Node
p Node
o TMap
spo, Node -> Node -> Node -> TMap -> TMap
forall {k} {k} {a}.
(Hashable k, Hashable k, Hashable a) =>
k
-> k
-> a
-> HashMap k (HashMap k (HashSet a))
-> HashMap k (HashMap k (HashSet a))
removeT Node
o Node
p Node
s TMap
ops)
    removeT :: k
-> k
-> a
-> HashMap k (HashMap k (HashSet a))
-> HashMap k (HashMap k (HashSet a))
removeT k
s' k
p' a
o' = (Maybe (HashMap k (HashSet a)) -> Maybe (HashMap k (HashSet a)))
-> k
-> HashMap k (HashMap k (HashSet a))
-> HashMap k (HashMap k (HashSet a))
forall k v.
(Eq k, Hashable k) =>
(Maybe v -> Maybe v) -> k -> HashMap k v -> HashMap k v
HashMap.alter (k
-> a
-> Maybe (HashMap k (HashSet a))
-> Maybe (HashMap k (HashSet a))
forall {m :: * -> *} {k} {a}.
(MonadPlus m, Hashable k, Hashable a) =>
k -> a -> m (HashMap k (HashSet a)) -> m (HashMap k (HashSet a))
removePO k
p' a
o') k
s'
    removePO :: k -> a -> m (HashMap k (HashSet a)) -> m (HashMap k (HashSet a))
removePO k
p' a
o' m (HashMap k (HashSet a))
po = (HashMap k (HashSet a) -> Bool)
-> m (HashMap k (HashSet a)) -> m (HashMap k (HashSet a))
forall (m :: * -> *) a. MonadPlus m => (a -> Bool) -> m a -> m a
mfilter (Bool -> Bool
not (Bool -> Bool)
-> (HashMap k (HashSet a) -> Bool) -> HashMap k (HashSet a) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap k (HashSet a) -> Bool
forall a. HashMap k a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null) (m (HashMap k (HashSet a)) -> m (HashMap k (HashSet a)))
-> m (HashMap k (HashSet a)) -> m (HashMap k (HashSet a))
forall a b. (a -> b) -> a -> b
$ (Maybe (HashSet a) -> Maybe (HashSet a))
-> k -> HashMap k (HashSet a) -> HashMap k (HashSet a)
forall k v.
(Eq k, Hashable k) =>
(Maybe v -> Maybe v) -> k -> HashMap k v -> HashMap k v
HashMap.alter (a -> Maybe (HashSet a) -> Maybe (HashSet a)
forall {m :: * -> *} {a}.
(MonadPlus m, Hashable a) =>
a -> m (HashSet a) -> m (HashSet a)
removeO a
o') k
p' (HashMap k (HashSet a) -> HashMap k (HashSet a))
-> m (HashMap k (HashSet a)) -> m (HashMap k (HashSet a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (HashMap k (HashSet a))
po
    removeO :: a -> m (HashSet a) -> m (HashSet a)
removeO a
o' m (HashSet a)
os = (HashSet a -> Bool) -> m (HashSet a) -> m (HashSet a)
forall (m :: * -> *) a. MonadPlus m => (a -> Bool) -> m a -> m a
mfilter (Bool -> Bool
not (Bool -> Bool) -> (HashSet a -> Bool) -> HashSet a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashSet a -> Bool
forall a. HashSet a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null) (m (HashSet a) -> m (HashSet a)) -> m (HashSet a) -> m (HashSet a)
forall a b. (a -> b) -> a -> b
$ a -> HashSet a -> HashSet a
forall a. (Eq a, Hashable a) => a -> HashSet a -> HashSet a
Set.delete a
o' (HashSet a -> HashSet a) -> m (HashSet a) -> m (HashSet a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (HashSet a)
os

mergeTs :: TMaps -> Triples -> TMaps
mergeTs :: TMaps -> Triples -> TMaps
mergeTs = (TMaps -> Triple -> TMaps) -> TMaps -> Triples -> TMaps
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' TMaps -> Triple -> TMaps
mergeT
  where
    mergeT :: TMaps -> Triple -> TMaps
    mergeT :: TMaps -> Triple -> TMaps
mergeT (TMap
spo, TMap
ops) (Triple Node
s Node
p Node
o) = (Node -> Node -> Node -> TMap -> TMap
insertT Node
s Node
p Node
o TMap
spo, Node -> Node -> Node -> TMap -> TMap
insertT Node
o Node
p Node
s TMap
ops)
    insertT :: Node -> Predicate -> Node -> TMap -> TMap
    insertT :: Node -> Node -> Node -> TMap -> TMap
insertT Node
s Node
p Node
o = let newPO :: HashMap Node Adjacencies
newPO = Node -> Adjacencies -> HashMap Node Adjacencies
forall k v. Hashable k => k -> v -> HashMap k v
HashMap.singleton Node
p (Node -> Adjacencies
forall a. Hashable a => a -> HashSet a
Set.singleton Node
o)
                    in (HashMap Node Adjacencies
 -> HashMap Node Adjacencies -> HashMap Node Adjacencies)
-> Node -> HashMap Node Adjacencies -> TMap -> TMap
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
HashMap.insertWith ((Adjacencies -> Adjacencies -> Adjacencies)
-> HashMap Node Adjacencies
-> HashMap Node Adjacencies
-> HashMap Node Adjacencies
forall k v.
Eq k =>
(v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v
HashMap.unionWith Adjacencies -> Adjacencies -> Adjacencies
forall a. Monoid a => a -> a -> a
mappend) Node
s HashMap Node Adjacencies
newPO

-- 3 following functions support triplesOf
triplesOf' :: RDF AdjHashMap -> Triples
triplesOf' :: RDF AdjHashMap -> Triples
triplesOf' (AdjHashMap ((TMap
spoMap, TMap
_), Maybe BaseUrl
_, PrefixMappings
_)) = ((Node, HashMap Node Adjacencies) -> Triples)
-> [(Node, HashMap Node Adjacencies)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Node -> HashMap Node Adjacencies -> Triples)
-> (Node, HashMap Node Adjacencies) -> Triples
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Node -> HashMap Node Adjacencies -> Triples
tripsSubj) [(Node, HashMap Node Adjacencies)]
subjPredMaps
  where subjPredMaps :: [(Node, HashMap Node Adjacencies)]
subjPredMaps = TMap -> [(Node, HashMap Node Adjacencies)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList TMap
spoMap

-- naive implementation for now
uniqTriplesOf' :: RDF AdjHashMap -> Triples
uniqTriplesOf' :: RDF AdjHashMap -> Triples
uniqTriplesOf' = Triples -> Triples
forall a. Eq a => [a] -> [a]
nub (Triples -> Triples)
-> (RDF AdjHashMap -> Triples) -> RDF AdjHashMap -> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RDF AdjHashMap -> Triples
forall a. Rdf a => RDF a -> Triples
expandTriples

tripsSubj :: Subject -> AdjacencyMap -> Triples
tripsSubj :: Node -> HashMap Node Adjacencies -> Triples
tripsSubj Node
s HashMap Node Adjacencies
adjMap = ((Node, Adjacencies) -> Triples)
-> [(Node, Adjacencies)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Node -> (Node, Adjacencies) -> Triples
tfsp Node
s) (HashMap Node Adjacencies -> [(Node, Adjacencies)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList HashMap Node Adjacencies
adjMap)
  where tfsp :: Node -> (Node, Adjacencies) -> Triples
tfsp Node
s' (Node
p, Adjacencies
m) = Node -> Node -> Node -> Triple
Triple Node
s' Node
p (Node -> Triple) -> [Node] -> Triples
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Adjacencies -> [Node]
forall a. HashSet a -> [a]
Set.toList Adjacencies
m

-- supports select
select' :: RDF AdjHashMap -> NodeSelector -> NodeSelector -> NodeSelector -> Triples
select' :: RDF AdjHashMap
-> NodeSelector -> NodeSelector -> NodeSelector -> Triples
select' RDF AdjHashMap
r NodeSelector
Nothing NodeSelector
Nothing NodeSelector
Nothing = RDF AdjHashMap -> Triples
forall a. Rdf a => RDF a -> Triples
triplesOf RDF AdjHashMap
r
select' (AdjHashMap ((TMap
_, TMap
ops),Maybe BaseUrl
_,PrefixMappings
_)) NodeSelector
Nothing NodeSelector
p NodeSelector
o = NodeSelector
-> NodeSelector
-> NodeSelector
-> (Node -> Node -> Node -> Triple)
-> TMap
-> Triples
selectSPO NodeSelector
o NodeSelector
p NodeSelector
forall a. Maybe a
Nothing (\Node
a Node
b Node
c -> Node -> Node -> Node -> Triple
Triple Node
c Node
b Node
a) TMap
ops
select' (AdjHashMap ((TMap
spo, TMap
_),Maybe BaseUrl
_,PrefixMappings
_)) NodeSelector
s       NodeSelector
p NodeSelector
o = NodeSelector
-> NodeSelector
-> NodeSelector
-> (Node -> Node -> Node -> Triple)
-> TMap
-> Triples
selectSPO NodeSelector
s NodeSelector
p NodeSelector
o       Node -> Node -> Node -> Triple
Triple                   TMap
spo

selectSPO :: NodeSelector -> NodeSelector -> NodeSelector -> (Node -> Node -> Node -> Triple) -> TMap -> Triples
selectSPO :: NodeSelector
-> NodeSelector
-> NodeSelector
-> (Node -> Node -> Node -> Triple)
-> TMap
-> Triples
selectSPO NodeSelector
Nothing  NodeSelector
p NodeSelector
o Node -> Node -> Node -> Triple
t = ((Node, HashMap Node Adjacencies) -> Triples)
-> [(Node, HashMap Node Adjacencies)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (NodeSelector
-> NodeSelector
-> (Node -> Node -> Node -> Triple)
-> (Node, HashMap Node Adjacencies)
-> Triples
selectPO NodeSelector
p NodeSelector
o Node -> Node -> Node -> Triple
t) ([(Node, HashMap Node Adjacencies)] -> Triples)
-> (TMap -> [(Node, HashMap Node Adjacencies)]) -> TMap -> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMap -> [(Node, HashMap Node Adjacencies)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList
selectSPO (Just Node -> Bool
s) NodeSelector
p NodeSelector
o Node -> Node -> Node -> Triple
t = ((Node, HashMap Node Adjacencies) -> Triples)
-> [(Node, HashMap Node Adjacencies)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (NodeSelector
-> NodeSelector
-> (Node -> Node -> Node -> Triple)
-> (Node, HashMap Node Adjacencies)
-> Triples
selectPO NodeSelector
p NodeSelector
o Node -> Node -> Node -> Triple
t) ([(Node, HashMap Node Adjacencies)] -> Triples)
-> (TMap -> [(Node, HashMap Node Adjacencies)]) -> TMap -> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Node, HashMap Node Adjacencies) -> Bool)
-> [(Node, HashMap Node Adjacencies)]
-> [(Node, HashMap Node Adjacencies)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Node -> Bool
s (Node -> Bool)
-> ((Node, HashMap Node Adjacencies) -> Node)
-> (Node, HashMap Node Adjacencies)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Node, HashMap Node Adjacencies) -> Node
forall a b. (a, b) -> a
fst) ([(Node, HashMap Node Adjacencies)]
 -> [(Node, HashMap Node Adjacencies)])
-> (TMap -> [(Node, HashMap Node Adjacencies)])
-> TMap
-> [(Node, HashMap Node Adjacencies)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMap -> [(Node, HashMap Node Adjacencies)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList

selectPO :: NodeSelector -> NodeSelector -> (Node -> Node -> Node -> Triple) -> (Node, AdjacencyMap) -> Triples
selectPO :: NodeSelector
-> NodeSelector
-> (Node -> Node -> Node -> Triple)
-> (Node, HashMap Node Adjacencies)
-> Triples
selectPO NodeSelector
Nothing  NodeSelector
o Node -> Node -> Node -> Triple
t (Node
s, HashMap Node Adjacencies
po) = ((Node, Adjacencies) -> Triples)
-> [(Node, Adjacencies)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (NodeSelector
-> (Node -> Node -> Node -> Triple)
-> Node
-> (Node, Adjacencies)
-> Triples
selectO NodeSelector
o Node -> Node -> Node -> Triple
t Node
s) ([(Node, Adjacencies)] -> Triples)
-> (HashMap Node Adjacencies -> [(Node, Adjacencies)])
-> HashMap Node Adjacencies
-> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap Node Adjacencies -> [(Node, Adjacencies)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList (HashMap Node Adjacencies -> Triples)
-> HashMap Node Adjacencies -> Triples
forall a b. (a -> b) -> a -> b
$ HashMap Node Adjacencies
po
selectPO (Just Node -> Bool
p) NodeSelector
o Node -> Node -> Node -> Triple
t (Node
s, HashMap Node Adjacencies
po) = ((Node, Adjacencies) -> Triples)
-> [(Node, Adjacencies)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (NodeSelector
-> (Node -> Node -> Node -> Triple)
-> Node
-> (Node, Adjacencies)
-> Triples
selectO NodeSelector
o Node -> Node -> Node -> Triple
t Node
s) ([(Node, Adjacencies)] -> Triples)
-> (HashMap Node Adjacencies -> [(Node, Adjacencies)])
-> HashMap Node Adjacencies
-> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Node, Adjacencies) -> Bool)
-> [(Node, Adjacencies)] -> [(Node, Adjacencies)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Node -> Bool
p (Node -> Bool)
-> ((Node, Adjacencies) -> Node) -> (Node, Adjacencies) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Node, Adjacencies) -> Node
forall a b. (a, b) -> a
fst) ([(Node, Adjacencies)] -> [(Node, Adjacencies)])
-> (HashMap Node Adjacencies -> [(Node, Adjacencies)])
-> HashMap Node Adjacencies
-> [(Node, Adjacencies)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap Node Adjacencies -> [(Node, Adjacencies)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList (HashMap Node Adjacencies -> Triples)
-> HashMap Node Adjacencies -> Triples
forall a b. (a -> b) -> a -> b
$ HashMap Node Adjacencies
po

selectO :: NodeSelector -> (Node -> Node -> Node -> Triple) -> Node -> (Node, Adjacencies) -> Triples
selectO :: NodeSelector
-> (Node -> Node -> Node -> Triple)
-> Node
-> (Node, Adjacencies)
-> Triples
selectO NodeSelector
o Node -> Node -> Node -> Triple
t Node
s (Node
p, Adjacencies
os) = Node -> Node -> Node -> Triple
t Node
s Node
p (Node -> Triple) -> [Node] -> Triples
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Adjacencies -> [Node]
forall a. HashSet a -> [a]
Set.toList Adjacencies
os'
  where os' :: Adjacencies
os' = Adjacencies
-> ((Node -> Bool) -> Adjacencies) -> NodeSelector -> Adjacencies
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Adjacencies
os ((Node -> Bool) -> Adjacencies -> Adjacencies
forall a. (a -> Bool) -> HashSet a -> HashSet a
`Set.filter` Adjacencies
os) NodeSelector
o

-- support query
query' :: RDF AdjHashMap -> Maybe Subject -> Maybe Predicate -> Maybe Object -> Triples
query' :: RDF AdjHashMap -> Maybe Node -> Maybe Node -> Maybe Node -> Triples
query' RDF AdjHashMap
r Maybe Node
Nothing Maybe Node
Nothing Maybe Node
Nothing = RDF AdjHashMap -> Triples
forall a. Rdf a => RDF a -> Triples
triplesOf RDF AdjHashMap
r
query' (AdjHashMap ((TMap
_, TMap
ops), Maybe BaseUrl
_, PrefixMappings
_)) Maybe Node
Nothing Maybe Node
p Maybe Node
o = Maybe Node
-> Maybe Node
-> Maybe Node
-> (Node -> Node -> Node -> Triple)
-> TMap
-> Triples
querySPO Maybe Node
o Maybe Node
p Maybe Node
forall a. Maybe a
Nothing (\Node
a Node
b Node
c -> Node -> Node -> Node -> Triple
Triple Node
c Node
b Node
a)  TMap
ops
query' (AdjHashMap ((TMap
spo, TMap
_), Maybe BaseUrl
_, PrefixMappings
_)) Maybe Node
s       Maybe Node
p Maybe Node
o = Maybe Node
-> Maybe Node
-> Maybe Node
-> (Node -> Node -> Node -> Triple)
-> TMap
-> Triples
querySPO Maybe Node
s Maybe Node
p Maybe Node
o       Node -> Node -> Node -> Triple
Triple                    TMap
spo

querySPO :: Maybe Node -> Maybe Node -> Maybe Node -> (Node -> Node -> Node -> Triple) -> TMap -> Triples
querySPO :: Maybe Node
-> Maybe Node
-> Maybe Node
-> (Node -> Node -> Node -> Triple)
-> TMap
-> Triples
querySPO Maybe Node
Nothing  Maybe Node
p Maybe Node
o Node -> Node -> Node -> Triple
t = ((Node, HashMap Node Adjacencies) -> Triples)
-> [(Node, HashMap Node Adjacencies)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Node -> HashMap Node Adjacencies -> Triples)
-> (Node, HashMap Node Adjacencies) -> Triples
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((Node -> HashMap Node Adjacencies -> Triples)
 -> (Node, HashMap Node Adjacencies) -> Triples)
-> (Node -> HashMap Node Adjacencies -> Triples)
-> (Node, HashMap Node Adjacencies)
-> Triples
forall a b. (a -> b) -> a -> b
$ Maybe Node
-> Maybe Node
-> (Node -> Node -> Node -> Triple)
-> Node
-> HashMap Node Adjacencies
-> Triples
queryPO Maybe Node
p Maybe Node
o Node -> Node -> Node -> Triple
t) ([(Node, HashMap Node Adjacencies)] -> Triples)
-> (TMap -> [(Node, HashMap Node Adjacencies)]) -> TMap -> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMap -> [(Node, HashMap Node Adjacencies)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList
querySPO (Just Node
s) Maybe Node
p Maybe Node
o Node -> Node -> Node -> Triple
t = Triples
-> (HashMap Node Adjacencies -> Triples)
-> Maybe (HashMap Node Adjacencies)
-> Triples
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Triples
forall a. Monoid a => a
mempty (Maybe Node
-> Maybe Node
-> (Node -> Node -> Node -> Triple)
-> Node
-> HashMap Node Adjacencies
-> Triples
queryPO Maybe Node
p Maybe Node
o Node -> Node -> Node -> Triple
t Node
s) (Maybe (HashMap Node Adjacencies) -> Triples)
-> (TMap -> Maybe (HashMap Node Adjacencies)) -> TMap -> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Node -> TMap -> Maybe (HashMap Node Adjacencies)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup Node
s

queryPO :: Maybe Node -> Maybe Node -> (Node -> Node -> Node -> Triple) -> Node -> AdjacencyMap -> Triples
queryPO :: Maybe Node
-> Maybe Node
-> (Node -> Node -> Node -> Triple)
-> Node
-> HashMap Node Adjacencies
-> Triples
queryPO Maybe Node
Nothing  Maybe Node
o Node -> Node -> Node -> Triple
t Node
s HashMap Node Adjacencies
po = ((Node, Adjacencies) -> Triples)
-> [(Node, Adjacencies)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Node -> Adjacencies -> Triples) -> (Node, Adjacencies) -> Triples
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((Node -> Adjacencies -> Triples)
 -> (Node, Adjacencies) -> Triples)
-> (Node -> Adjacencies -> Triples)
-> (Node, Adjacencies)
-> Triples
forall a b. (a -> b) -> a -> b
$ Maybe Node
-> (Node -> Node -> Node -> Triple)
-> Node
-> Node
-> Adjacencies
-> Triples
queryO Maybe Node
o Node -> Node -> Node -> Triple
t Node
s) ([(Node, Adjacencies)] -> Triples)
-> (HashMap Node Adjacencies -> [(Node, Adjacencies)])
-> HashMap Node Adjacencies
-> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap Node Adjacencies -> [(Node, Adjacencies)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList (HashMap Node Adjacencies -> Triples)
-> HashMap Node Adjacencies -> Triples
forall a b. (a -> b) -> a -> b
$ HashMap Node Adjacencies
po
queryPO (Just Node
p) Maybe Node
o Node -> Node -> Node -> Triple
t Node
s HashMap Node Adjacencies
po = Triples -> (Adjacencies -> Triples) -> Maybe Adjacencies -> Triples
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Triples
forall a. Monoid a => a
mempty (Maybe Node
-> (Node -> Node -> Node -> Triple)
-> Node
-> Node
-> Adjacencies
-> Triples
queryO Maybe Node
o Node -> Node -> Node -> Triple
t Node
s Node
p) (Maybe Adjacencies -> Triples) -> Maybe Adjacencies -> Triples
forall a b. (a -> b) -> a -> b
$ Node -> HashMap Node Adjacencies -> Maybe Adjacencies
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup Node
p HashMap Node Adjacencies
po

queryO :: Maybe Node -> (Node -> Node -> Node -> Triple) -> Node -> Node -> Adjacencies -> Triples
queryO :: Maybe Node
-> (Node -> Node -> Node -> Triple)
-> Node
-> Node
-> Adjacencies
-> Triples
queryO Maybe Node
Nothing  Node -> Node -> Node -> Triple
t Node
s Node
p Adjacencies
os = Node -> Node -> Node -> Triple
t Node
s Node
p (Node -> Triple) -> [Node] -> Triples
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Adjacencies -> [Node]
forall a. HashSet a -> [a]
Set.toList Adjacencies
os
queryO (Just Node
o) Node -> Node -> Node -> Triple
t Node
s Node
p Adjacencies
os
  | Node
o Node -> Adjacencies -> Bool
forall a. (Eq a, Hashable a) => a -> HashSet a -> Bool
`Set.member` Adjacencies
os = [Node -> Node -> Node -> Triple
t Node
s Node
p Node
o]
  | Bool
otherwise         = Triples
forall a. Monoid a => a
mempty