hxt-7.1: doc/cookbook/SPARQLFunctions.hs
{- |
Module : SPARQLFunctions
Author : Manuel Ohlendorf
Maintainer : Manuel Ohlendorf
Stability : experimental
Portability: portable
Version :
Several functions used for query processing.
-}
module SPARQLFunctions
(
normalizeQuery
,showResult
,getSPARQLQuery
)
where
import SPARQLDataTypes
import RDFDataTypes
import SPARQLParser
import Text.ParserCombinators.Parsec (parse)
import Text.XML.HXT.Arrow
-- | normalises the Triple Patterns
normalizeTripleP :: TriplePattern -> [TriplePattern]
normalizeTripleP (TriplePatN s p o ) = [TriplePatN s p o]
normalizeTripleP (TriplePat _ []) = []
normalizeTripleP (TriplePat _ ((_,[]):_)) = []
normalizeTripleP (TriplePat s ((p,[o]):xs)) = (TriplePatN s p o) : normalizeTripleP(TriplePat s xs)
normalizeTripleP (TriplePat s ((p,(x:xs)):ys)) = (TriplePatN s p x) : normalizeTripleP (TriplePat s [(p,xs)])
++ normalizeTripleP (TriplePat s ys)
-- | normalises the Pattern elements
normalizePatternElement :: PatternElement -> [TriplePattern]
normalizePatternElement (PET t) = normalizeTripleP t
normalizePatternElement (PEG []) = []
normalizePatternElement (PEG (x:xs)) = normalizePatternElement x ++ normalizePatternElement' xs
normalizePatternElement' :: [PatternElement] -> [TriplePattern]
normalizePatternElement' [] = []
normalizePatternElement' (x:xs) = normalizePatternElement x ++ normalizePatternElement' xs
-- | normalises the graph patterns
normalizeGraphPattern :: GraphPattern -> [TriplePattern]
normalizeGraphPattern (GraphPattern []) = []
normalizeGraphPattern (GraphPattern (x:xs)) = normalizePatternElement x ++ normalizePatternElement' xs
-- | normalises a 'Query' by removing all abbreviations.
-- The result is a 'Query' containing a list of simple triple patterns.
-- This function has to be called be for query evaluation.
normalizeQuery :: Query -> Query
normalizeQuery Empty = Empty
normalizeQuery (QueryN _ []) = Empty
normalizeQuery (QueryN v (x:xs)) = QueryN v (x:xs)
normalizeQuery (Query v gp) = QueryN v (normalizeGraphPattern gp)
showIt :: [(Either RDFTerm URI)] -> String
showIt [] = ""
showIt ((Right u) :xs) = '|' : "<" ++ u ++">|\n" ++ showIt xs
showIt ((Left r) :xs) = '|' : show r ++"|\n" ++ showIt xs
-- | The show function for printing out the result of the query evaluation
showResult :: [(Var,[(Either RDFTerm URI)])] -> String
showResult [] = ""
showResult ((var, xs):ys)
= if (xs /=[])
then '\t' : '?':var ++ "\n" ++ (showIt xs) ++"\n"++ (showResult ys)
else ""
-- | The main entry point, when combining the SPARQL parser with a arrow based programme.
-- Executes the SPARQL parser and returns a 'Query'.
--
-- Raises an error if the parsing fails and returns a empty 'Query'.
--
-- The extra parameter is the query string which will be parsed.
-- The arrow input is ignored, the output is the parsed query.
getSPARQLQuery :: String -> IOSArrow a Query
getSPARQLQuery queryStr
= case (parse parseSPARQL "" queryStr) of
Left parseError
-> (issueFatal ("Syntax error in SPARQL query "
++ show queryStr
++ ": " ++ show parseError) >>> constA (Empty))
Right theQuery
-> constA (theQuery)