{-# 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
$cto :: forall x. Rep AdjHashMap x -> AdjHashMap
$cfrom :: forall x. AdjHashMap -> Rep AdjHashMap x
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
rnf :: RDF AdjHashMap -> ()
$crnf :: 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
$cto :: forall x. Rep (RDF AdjHashMap) x -> RDF AdjHashMap
$cfrom :: forall x. RDF AdjHashMap -> Rep (RDF AdjHashMap) x
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 -> String
showGraph         = RDF AdjHashMap -> String
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 -> String
showGraph' ((AdjHashMap ((spoMap, _), _, _))) =
    let ts :: Triples
ts = ((Node, AdjacencyMap) -> Triples)
-> [(Node, AdjacencyMap)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Node -> AdjacencyMap -> Triples)
-> (Node, AdjacencyMap) -> Triples
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Node -> AdjacencyMap -> Triples
tripsSubj) [(Node, AdjacencyMap)]
subjPredMaps
          where subjPredMaps :: [(Node, AdjacencyMap)]
subjPredMaps = HashMap Node AdjacencyMap -> [(Node, AdjacencyMap)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList HashMap Node AdjacencyMap
spoMap
    in (Triple -> String) -> Triples -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\Triple
t -> Triple -> String
forall a. Show a => a -> String
show Triple
t String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"\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 (_, baseURL, _)) = Maybe BaseUrl
baseURL

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

addPrefixMappings' :: RDF AdjHashMap -> PrefixMappings -> Bool -> RDF AdjHashMap
addPrefixMappings' :: RDF AdjHashMap -> PrefixMappings -> Bool -> RDF AdjHashMap
addPrefixMappings' (AdjHashMap (ts, baseURL, 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 ((HashMap Node AdjacencyMap
forall a. Monoid a => a
mempty, HashMap Node AdjacencyMap
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 (HashMap Node AdjacencyMap
forall a. Monoid a => a
mempty, HashMap Node AdjacencyMap
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, baseURL, 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 ((spo, ops), baseURL, 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
-> HashMap Node AdjacencyMap
-> HashMap Node AdjacencyMap
forall k k a.
(Eq k, Eq k, Eq 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 HashMap Node AdjacencyMap
spo, Node
-> Node
-> Node
-> HashMap Node AdjacencyMap
-> HashMap Node AdjacencyMap
forall k k a.
(Eq k, Eq k, Eq 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 HashMap Node AdjacencyMap
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, Eq k, Eq a, 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 (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, Eq a, 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 (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 (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 (HashMap Node AdjacencyMap
spo, HashMap Node AdjacencyMap
ops) (Triple Node
s Node
p Node
o) = (Node
-> Node
-> Node
-> HashMap Node AdjacencyMap
-> HashMap Node AdjacencyMap
insertT Node
s Node
p Node
o HashMap Node AdjacencyMap
spo, Node
-> Node
-> Node
-> HashMap Node AdjacencyMap
-> HashMap Node AdjacencyMap
insertT Node
o Node
p Node
s HashMap Node AdjacencyMap
ops)
    insertT :: Node -> Predicate -> Node -> TMap -> TMap
    insertT :: Node
-> Node
-> Node
-> HashMap Node AdjacencyMap
-> HashMap Node AdjacencyMap
insertT Node
s Node
p Node
o = let newPO :: AdjacencyMap
newPO = Node -> HashSet Node -> AdjacencyMap
forall k v. Hashable k => k -> v -> HashMap k v
HashMap.singleton Node
p (Node -> HashSet Node
forall a. Hashable a => a -> HashSet a
Set.singleton Node
o)
                    in (AdjacencyMap -> AdjacencyMap -> AdjacencyMap)
-> Node
-> AdjacencyMap
-> HashMap Node AdjacencyMap
-> HashMap Node AdjacencyMap
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
HashMap.insertWith ((HashSet Node -> HashSet Node -> HashSet Node)
-> AdjacencyMap -> AdjacencyMap -> AdjacencyMap
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v
HashMap.unionWith HashSet Node -> HashSet Node -> HashSet Node
forall a. Monoid a => a -> a -> a
mappend) Node
s AdjacencyMap
newPO

-- 3 following functions support triplesOf
triplesOf' :: RDF AdjHashMap -> Triples
triplesOf' :: RDF AdjHashMap -> Triples
triplesOf' (AdjHashMap ((spoMap, _), _, _)) = ((Node, AdjacencyMap) -> Triples)
-> [(Node, AdjacencyMap)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Node -> AdjacencyMap -> Triples)
-> (Node, AdjacencyMap) -> Triples
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Node -> AdjacencyMap -> Triples
tripsSubj) [(Node, AdjacencyMap)]
subjPredMaps
  where subjPredMaps :: [(Node, AdjacencyMap)]
subjPredMaps = HashMap Node AdjacencyMap -> [(Node, AdjacencyMap)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList HashMap Node AdjacencyMap
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 -> AdjacencyMap -> Triples
tripsSubj Node
s AdjacencyMap
adjMap = ((Node, HashSet Node) -> Triples)
-> [(Node, HashSet Node)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Node -> (Node, HashSet Node) -> Triples
tfsp Node
s) (AdjacencyMap -> [(Node, HashSet Node)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList AdjacencyMap
adjMap)
  where tfsp :: Node -> (Node, HashSet Node) -> Triples
tfsp Node
s' (Node
p, HashSet Node
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
<$> HashSet Node -> [Node]
forall a. HashSet a -> [a]
Set.toList HashSet Node
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 ((_, ops),_,_)) NodeSelector
Nothing NodeSelector
p NodeSelector
o = NodeSelector
-> NodeSelector
-> NodeSelector
-> (Node -> Node -> Node -> Triple)
-> HashMap Node AdjacencyMap
-> 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) HashMap Node AdjacencyMap
ops
select' (AdjHashMap ((spo, _),_,_)) NodeSelector
s       NodeSelector
p NodeSelector
o = NodeSelector
-> NodeSelector
-> NodeSelector
-> (Node -> Node -> Node -> Triple)
-> HashMap Node AdjacencyMap
-> Triples
selectSPO NodeSelector
s NodeSelector
p NodeSelector
o       Node -> Node -> Node -> Triple
Triple                   HashMap Node AdjacencyMap
spo

selectSPO :: NodeSelector -> NodeSelector -> NodeSelector -> (Node -> Node -> Node -> Triple) -> TMap -> Triples
selectSPO :: NodeSelector
-> NodeSelector
-> NodeSelector
-> (Node -> Node -> Node -> Triple)
-> HashMap Node AdjacencyMap
-> Triples
selectSPO NodeSelector
Nothing  NodeSelector
p NodeSelector
o Node -> Node -> Node -> Triple
t = ((Node, AdjacencyMap) -> Triples)
-> [(Node, AdjacencyMap)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (NodeSelector
-> NodeSelector
-> (Node -> Node -> Node -> Triple)
-> (Node, AdjacencyMap)
-> Triples
selectPO NodeSelector
p NodeSelector
o Node -> Node -> Node -> Triple
t) ([(Node, AdjacencyMap)] -> Triples)
-> (HashMap Node AdjacencyMap -> [(Node, AdjacencyMap)])
-> HashMap Node AdjacencyMap
-> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap Node AdjacencyMap -> [(Node, AdjacencyMap)]
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, AdjacencyMap) -> Triples)
-> [(Node, AdjacencyMap)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (NodeSelector
-> NodeSelector
-> (Node -> Node -> Node -> Triple)
-> (Node, AdjacencyMap)
-> Triples
selectPO NodeSelector
p NodeSelector
o Node -> Node -> Node -> Triple
t) ([(Node, AdjacencyMap)] -> Triples)
-> (HashMap Node AdjacencyMap -> [(Node, AdjacencyMap)])
-> HashMap Node AdjacencyMap
-> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Node, AdjacencyMap) -> Bool)
-> [(Node, AdjacencyMap)] -> [(Node, AdjacencyMap)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Node -> Bool
s (Node -> Bool)
-> ((Node, AdjacencyMap) -> Node) -> (Node, AdjacencyMap) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Node, AdjacencyMap) -> Node
forall a b. (a, b) -> a
fst) ([(Node, AdjacencyMap)] -> [(Node, AdjacencyMap)])
-> (HashMap Node AdjacencyMap -> [(Node, AdjacencyMap)])
-> HashMap Node AdjacencyMap
-> [(Node, AdjacencyMap)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap Node AdjacencyMap -> [(Node, AdjacencyMap)]
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, AdjacencyMap)
-> Triples
selectPO NodeSelector
Nothing  NodeSelector
o Node -> Node -> Node -> Triple
t (Node
s, AdjacencyMap
po) = ((Node, HashSet Node) -> Triples)
-> [(Node, HashSet Node)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (NodeSelector
-> (Node -> Node -> Node -> Triple)
-> Node
-> (Node, HashSet Node)
-> Triples
selectO NodeSelector
o Node -> Node -> Node -> Triple
t Node
s) ([(Node, HashSet Node)] -> Triples)
-> (AdjacencyMap -> [(Node, HashSet Node)])
-> AdjacencyMap
-> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyMap -> [(Node, HashSet Node)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList (AdjacencyMap -> Triples) -> AdjacencyMap -> Triples
forall a b. (a -> b) -> a -> b
$ AdjacencyMap
po
selectPO (Just Node -> Bool
p) NodeSelector
o Node -> Node -> Node -> Triple
t (Node
s, AdjacencyMap
po) = ((Node, HashSet Node) -> Triples)
-> [(Node, HashSet Node)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (NodeSelector
-> (Node -> Node -> Node -> Triple)
-> Node
-> (Node, HashSet Node)
-> Triples
selectO NodeSelector
o Node -> Node -> Node -> Triple
t Node
s) ([(Node, HashSet Node)] -> Triples)
-> (AdjacencyMap -> [(Node, HashSet Node)])
-> AdjacencyMap
-> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Node, HashSet Node) -> Bool)
-> [(Node, HashSet Node)] -> [(Node, HashSet Node)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Node -> Bool
p (Node -> Bool)
-> ((Node, HashSet Node) -> Node) -> (Node, HashSet Node) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Node, HashSet Node) -> Node
forall a b. (a, b) -> a
fst) ([(Node, HashSet Node)] -> [(Node, HashSet Node)])
-> (AdjacencyMap -> [(Node, HashSet Node)])
-> AdjacencyMap
-> [(Node, HashSet Node)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyMap -> [(Node, HashSet Node)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList (AdjacencyMap -> Triples) -> AdjacencyMap -> Triples
forall a b. (a -> b) -> a -> b
$ AdjacencyMap
po

selectO :: NodeSelector -> (Node -> Node -> Node -> Triple) -> Node -> (Node, Adjacencies) -> Triples
selectO :: NodeSelector
-> (Node -> Node -> Node -> Triple)
-> Node
-> (Node, HashSet Node)
-> Triples
selectO NodeSelector
o Node -> Node -> Node -> Triple
t Node
s (Node
p, HashSet Node
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
<$> HashSet Node -> [Node]
forall a. HashSet a -> [a]
Set.toList HashSet Node
os'
  where os' :: HashSet Node
os' = HashSet Node
-> ((Node -> Bool) -> HashSet Node) -> NodeSelector -> HashSet Node
forall b a. b -> (a -> b) -> Maybe a -> b
maybe HashSet Node
os ((Node -> Bool) -> HashSet Node -> HashSet Node
forall a. (a -> Bool) -> HashSet a -> HashSet a
`Set.filter` HashSet Node
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 ((_, ops), _, _)) Maybe Node
Nothing Maybe Node
p Maybe Node
o = Maybe Node
-> Maybe Node
-> Maybe Node
-> (Node -> Node -> Node -> Triple)
-> HashMap Node AdjacencyMap
-> 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)  HashMap Node AdjacencyMap
ops
query' (AdjHashMap ((spo, _), _, _)) Maybe Node
s       Maybe Node
p Maybe Node
o = Maybe Node
-> Maybe Node
-> Maybe Node
-> (Node -> Node -> Node -> Triple)
-> HashMap Node AdjacencyMap
-> Triples
querySPO Maybe Node
s Maybe Node
p Maybe Node
o       Node -> Node -> Node -> Triple
Triple                    HashMap Node AdjacencyMap
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)
-> HashMap Node AdjacencyMap
-> Triples
querySPO Maybe Node
Nothing  Maybe Node
p Maybe Node
o Node -> Node -> Node -> Triple
t = ((Node, AdjacencyMap) -> Triples)
-> [(Node, AdjacencyMap)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Node -> AdjacencyMap -> Triples)
-> (Node, AdjacencyMap) -> Triples
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((Node -> AdjacencyMap -> Triples)
 -> (Node, AdjacencyMap) -> Triples)
-> (Node -> AdjacencyMap -> Triples)
-> (Node, AdjacencyMap)
-> Triples
forall a b. (a -> b) -> a -> b
$ Maybe Node
-> Maybe Node
-> (Node -> Node -> Node -> Triple)
-> Node
-> AdjacencyMap
-> Triples
queryPO Maybe Node
p Maybe Node
o Node -> Node -> Node -> Triple
t) ([(Node, AdjacencyMap)] -> Triples)
-> (HashMap Node AdjacencyMap -> [(Node, AdjacencyMap)])
-> HashMap Node AdjacencyMap
-> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap Node AdjacencyMap -> [(Node, AdjacencyMap)]
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
-> (AdjacencyMap -> Triples) -> Maybe AdjacencyMap -> 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
-> AdjacencyMap
-> Triples
queryPO Maybe Node
p Maybe Node
o Node -> Node -> Node -> Triple
t Node
s) (Maybe AdjacencyMap -> Triples)
-> (HashMap Node AdjacencyMap -> Maybe AdjacencyMap)
-> HashMap Node AdjacencyMap
-> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Node -> HashMap Node AdjacencyMap -> Maybe AdjacencyMap
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
-> AdjacencyMap
-> Triples
queryPO Maybe Node
Nothing  Maybe Node
o Node -> Node -> Node -> Triple
t Node
s AdjacencyMap
po = ((Node, HashSet Node) -> Triples)
-> [(Node, HashSet Node)] -> Triples
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Node -> HashSet Node -> Triples)
-> (Node, HashSet Node) -> Triples
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((Node -> HashSet Node -> Triples)
 -> (Node, HashSet Node) -> Triples)
-> (Node -> HashSet Node -> Triples)
-> (Node, HashSet Node)
-> Triples
forall a b. (a -> b) -> a -> b
$ Maybe Node
-> (Node -> Node -> Node -> Triple)
-> Node
-> Node
-> HashSet Node
-> Triples
queryO Maybe Node
o Node -> Node -> Node -> Triple
t Node
s) ([(Node, HashSet Node)] -> Triples)
-> (AdjacencyMap -> [(Node, HashSet Node)])
-> AdjacencyMap
-> Triples
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AdjacencyMap -> [(Node, HashSet Node)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList (AdjacencyMap -> Triples) -> AdjacencyMap -> Triples
forall a b. (a -> b) -> a -> b
$ AdjacencyMap
po
queryPO (Just Node
p) Maybe Node
o Node -> Node -> Node -> Triple
t Node
s AdjacencyMap
po = Triples
-> (HashSet Node -> Triples) -> Maybe (HashSet Node) -> 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
-> HashSet Node
-> Triples
queryO Maybe Node
o Node -> Node -> Node -> Triple
t Node
s Node
p) (Maybe (HashSet Node) -> Triples)
-> Maybe (HashSet Node) -> Triples
forall a b. (a -> b) -> a -> b
$ Node -> AdjacencyMap -> Maybe (HashSet Node)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup Node
p AdjacencyMap
po

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