<commit_before>-- |"AvlGraph" contains a graph implementation backed by a 'Data.Map.AVL'.
module AvlGraph(AvlGraph,
                empty, mkGraph, triplesOf, select, query)

where

import RDF
import Namespace

import Data.Map.AVL (Map)
import qualified Data.Map.AVL as Map

import Data.Set.AVL (Set)
import qualified Data.Set.AVL as Set

import Data.List

-- |An AVL map-based graph implementation.
--
-- Worst-case time complexity of the graph functions, with respect
-- to the number of triples, are:
--
--  * 'empty'    : O(1)
--
--  * 'mkGraph'  : O(n)
--
--  * 'triplesOf': O(n)
--
--  * 'select'   : O(n)
--
--  * 'query'    : O(log n)
newtype AvlGraph = AvlGraph (SPOMap, Maybe BaseUrl, PrefixMappings)

instance Graph AvlGraph where
  baseUrl                 = baseUrl'
  empty                   = empty'
  mkGraph                 = mkGraph'
  triplesOf               = triplesOf'
  select                  = select'
  query                   = query'

-- 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 = Map Predicate Adjacencies

-- 
type Adjacencies = Set Object
type SPOMap    = Map Subject AdjacencyMap

baseUrl' :: AvlGraph -> Maybe BaseUrl
baseUrl' (AvlGraph (_, baseUrl, _)) = baseUrl

empty' :: AvlGraph 
empty' = AvlGraph (Map.empty, Nothing, Map.empty)

mkGraph' :: Triples -> Maybe BaseUrl -> PrefixMappings -> IO AvlGraph
mkGraph' ts baseUrl pms = return $ AvlGraph ((mergeTs Map.empty ts), baseUrl, pms)

mergeTs :: SPOMap -> [Triple] -> SPOMap
mergeTs = foldl' mergeT
  where
    mergeT :: SPOMap -> Triple -> SPOMap
    mergeT m t = mergeT' m (subjectOf t) (predicateOf t) (objectOf t)

mergeT' :: SPOMap -> Subject -> Predicate -> Object -> SPOMap
mergeT' m s p o = 
  case s `Map.member` m of
    False -> Map.insert s (newPredMap p o) m
    True  -> case p `Map.member` adjs of
               False -> Map.insert s (addNewPredObjMap p o adjs) m
               True  -> Map.insert s (addPredObj p o adjs) m
  where
    adjs = get s m
    newPredMap :: Predicate -> Object -> Map Predicate (Set Object)
    newPredMap p o = Map.singleton p (Set.singleton o)
    addNewPredObjMap :: Predicate -> Object -> Map Predicate (Set Object) ->
                       Map Predicate (Set Object)
    addNewPredObjMap p o = Map.insert p (Set.singleton o)
    addPredObj :: Predicate -> Object -> Map Predicate (Set Object) -><commit_msg>AvlGraph.hs: added prefixMappings function to AvlGraph.<commit_after>-- |"AvlGraph" contains a graph implementation backed by a 'Data.Map.AVL'.
module AvlGraph(AvlGraph,
                empty, mkGraph, triplesOf, select, query)

where

import RDF
import Namespace

import Data.Map.AVL (Map)
import qualified Data.Map.AVL as Map

import Data.Set.AVL (Set)
import qualified Data.Set.AVL as Set

import Data.List

-- |An AVL map-based graph implementation.
--
-- Worst-case time complexity of the graph functions, with respect
-- to the number of triples, are:
--
--  * 'empty'    : O(1)
--
--  * 'mkGraph'  : O(n)
--
--  * 'triplesOf': O(n)
--
--  * 'select'   : O(n)
--
--  * 'query'    : O(log n)
newtype AvlGraph = AvlGraph (SPOMap, Maybe BaseUrl, PrefixMappings)

instance Graph AvlGraph where
  baseUrl         = baseUrl'
  prefixMappings  = prefixMappings'
  empty           = empty'
  mkGraph         = mkGraph'
  triplesOf       = triplesOf'
  select          = select'
  query           = query'

-- 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 = Map Predicate Adjacencies

-- 
type Adjacencies = Set Object
type SPOMap    = Map Subject AdjacencyMap

baseUrl' :: AvlGraph -> Maybe BaseUrl
baseUrl' (AvlGraph (_, baseUrl, _)) = baseUrl

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

empty' :: AvlGraph 
empty' = AvlGraph (Map.empty, Nothing, Map.empty)

mkGraph' :: Triples -> Maybe BaseUrl -> PrefixMappings -> IO AvlGraph
mkGraph' ts baseUrl pms = return $ AvlGraph ((mergeTs Map.empty ts), baseUrl, pms)

mergeTs :: SPOMap -> [Triple] -> SPOMap
mergeTs = foldl' mergeT
  where
    mergeT :: SPOMap -> Triple -> SPOMap
    mergeT m t = mergeT' m (subjectOf t) (predicateOf t) (objectOf t)

mergeT' :: SPOMap -> Subject -> Predicate -> Object -> SPOMap
mergeT' m s p o = 
  case s `Map.member` m of
    False -> Map.insert s (newPredMap p o) m
    True  -> case p `Map.member` adjs of
               False -> Map.insert s (addNewPredObjMap p o adjs) m
               True  -> Map.insert s (addPredObj p o adjs) m
  where
    adjs = get s m
    newPredMap :: Predicate -> Object -> Map Predicate (Set Object)
    newPredMap p o = Map.singleton p (Set.singleton o)
    addNewPredObjMap :: Predicate -> Object -> Map Predicate (Set Object) ->
                       Map Predicate (Set Object)
    addNewPredObjMap p o = Map.insert p (Set.singleton o)
    addPredObj :: Predicate -> Object -> Map Predicate (Set Object) ->
{'fraction_non_alphanumeric': 0.11058638331365604, 'fraction_numerical': 0.0003935458480913026, 'mean_word_length': 2.6203703703703702, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 52, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3565060', 'n_tokens_mistral': 1694, 'n_tokens_neox': 1662, 'n_words': 570}