swish-0.9.0.7: A semantic web toolkit.

Portability | H98
Stability | experimental
Maintainer | Douglas Burke
Safe Haskell | None

Swish.RDF.Query

Contents

- Utility routines
- Exported for testing

Description

This module defines functions for querying an RDF graph to obtain a set of variable substitutions, and to apply a set of variable substitutions to a query pattern to obtain a new graph.

It also defines a few primitive graph access functions.

A minimal example is shown below, where we query a very simple graph:

    >>> :m + Swish.RDF Swish.RDF.Parser.N3 Swish.RDF.Query
    >>> :set -XOverloadedStrings
    >>> let qparse = either error id . parseN3fromText
    >>> let igr = qparse "@prefix a: <http://example.com/>. a:a a a:A ; a:foo a:bar. a:b a a:B ; a:foo a:bar."
    >>> let qgr = qparse "?node a ?type."
    >>> rdfQueryFind qgr igr
    [[(?type,a:B),(?node,a:b)],[(?type,a:A),(?node,a:a)]]
    >>> let bn = (toRDFLabel . Data.Maybe.fromJust . Network.URI.parseURI) "http://example.com/B"
    >>> rdfFindArcs (rdfObjEq bn) igr
    [(a:b,rdf:type,a:B)]
    >>> Data.Maybe.mapMaybe (flip Swish.RDF.VarBinding.vbMap (Var "type")) $ rdfQueryFind qgr igr
    [a:B,a:A]

Synopsis

- rdfQueryFind :: RDFGraph -> RDFGraph -> [RDFVarBinding]
- rdfQueryFilter :: RDFVarBindingFilter -> [RDFVarBinding] -> [RDFVarBinding]
- rdfQueryBack :: RDFGraph -> RDFGraph -> [[RDFVarBinding]]
- rdfQueryBackFilter :: RDFVarBindingFilter -> [[RDFVarBinding]] -> [[RDFVarBinding]]
- rdfQueryBackModify :: VarBindingModify a b -> [[VarBinding a b]] -> [[VarBinding a b]]
- rdfQueryInstance :: RDFGraph -> RDFGraph -> [RDFVarBinding]
- rdfQuerySubs :: [RDFVarBinding] -> RDFGraph -> [RDFGraph]
- rdfQueryBackSubs :: [[RDFVarBinding]] -> RDFGraph -> [[(RDFGraph, [RDFLabel])]]
- rdfQuerySubsAll :: [RDFVarBinding] -> RDFGraph -> [(RDFGraph, [RDFLabel])]
- rdfQuerySubsBlank :: [RDFVarBinding] -> RDFGraph -> [RDFGraph]
- rdfQueryBackSubsBlank :: [[RDFVarBinding]] -> RDFGraph -> [[RDFGraph]]
- rdfFindArcs :: (RDFTriple -> Bool) -> RDFGraph -> [RDFTriple]
- rdfSubjEq :: RDFLabel -> RDFTriple -> Bool
- rdfPredEq :: RDFLabel -> RDFTriple -> Bool
- rdfObjEq :: RDFLabel -> RDFTriple -> Bool
- rdfFindPredVal :: RDFLabel -> RDFLabel -> RDFGraph -> [RDFLabel]
- rdfFindPredInt :: RDFLabel -> RDFLabel -> RDFGraph -> [Integer]
- rdfFindValSubj :: RDFLabel -> RDFLabel -> RDFGraph -> [RDFLabel]
- rdfFindList :: RDFGraph -> RDFLabel -> [RDFLabel]
- allp :: [a -> Bool] -> a -> Bool
- anyp :: [a -> Bool] -> a -> Bool
- rdfQuerySubs2 :: RDFVarBinding -> RDFGraph -> (RDFGraph, [RDFLabel])

# Documentation

rdfQueryFind Source

Arguments

:: RDFGraph | The query graph.
-> RDFGraph | The target graph.
-> [RDFVarBinding] | Each element represents a set of variable bindings that make the query graph a subgraph of the target graph. The list can be empty.

Basic graph-query function.

The triples of the query graph are matched sequentially against the target graph, each taking account of any variable bindings that have already been determined, and adding new variable bindings as triples containing query variables are matched against the graph.

rdfQueryFilter :: RDFVarBindingFilter -> [RDFVarBinding] -> [RDFVarBinding]Source

RDF query filter.

This function applies a supplied query binding filter to the result from a call of `rdfQueryFind`.

If none of the query bindings found satisfy the filter, a null list is returned (which is what `rdfQueryFind` returns if the query cannot be satisfied).

(Because of lazy evaluation, this should be as efficient as applying the filter as the search proceeds. I started to build the filter logic into the query function itself, with consequent increase in complexity, until I remembered lazy evaluation lets me keep things separate.)

rdfQueryBack Source

Arguments

:: RDFGraph | Query graph
-> RDFGraph | Target graph
-> [[RDFVarBinding]] |

Reverse graph-query function.

Similar to `rdfQueryFind`, but with different success criteria. The query graph is matched against the supplied graph, but not every triple of the query is required to be matched. Rather, every triple of the target graph must be matched, and substitutions for just the variables thus bound are returned. In effect, these are subsitutions in the query that entail the target graph (where `rdfQueryFind` returns substitutions that are entailed by the target graph).

Multiple substitutions may be used together, so the result returned is a list of lists of query bindings. Each inner list contains several variable bindings that must all be applied separately to the closure antecendents to obtain a collection of expressions that together are antecedent to the supplied conclusion. A null list of bindings returned means the conclusion can be inferred without any antecedents.

Note: in back-chaining, the conditions required to prove each target triple are derived independently, using the inference rule for each such triple, so there are no requirements to check consistency with previously determined variable bindings, as there are when doing forward chaining. A result of this is that there may be redundant triples generated by the back-chaining process. Any process using back-chaining should deal with the results returned accordingly.

An empty outer list is returned if no combination of substitutions can infer the supplied target.

rdfQueryBackFilter :: RDFVarBindingFilter -> [[RDFVarBinding]] -> [[RDFVarBinding]]Source

RDF back-chaining query filter. This function applies a supplied query binding filter to the result from a call of `rdfQueryBack`.

Each inner list contains bindings that must all be used to satisfy the backchain query, so if any query binding does not satisfy the filter, the entire corresponding row is removed

rdfQueryBackModify :: VarBindingModify a b -> [[VarBinding a b]] -> [[VarBinding a b]]Source

RDF back-chaining query modifier. This function applies a supplied query binding modifier to the result from a call of `rdfQueryBack`.

Each inner list contains bindings that must all be used to satisfy a backchaining query, so if any query binding does not satisfy the filter, the entire corresponding row is removed

rdfQueryInstance :: RDFGraph -> RDFGraph -> [RDFVarBinding]Source

Simple entailment (instance) graph query.

This function queries a graph to find instances of the query graph in the target graph. It is very similar to the normal forward chaining query `rdfQueryFind`, except that blank nodes rather than query variable nodes in the query graph are matched against nodes in the target graph. Neither graph should contain query variables.

An instance is defined by the RDF semantics specification, per http://www.w3.org/TR/rdf-mt/, and is obtained by replacing blank nodes with URIs, literals or other blank nodes. RDF simple entailment can be determined in terms of instances. This function looks for a subgraph of the target graph that is an instance of the query graph, which is a necessary and sufficient condition for RDF entailment (see the Interpolation Lemma in RDF Semantics, section 1.2).

It is anticipated that this query function can be used in conjunction with backward chaining to determine when the search for sufficient antecendents to determine some goal has been concluded.

rdfQuerySubs :: [RDFVarBinding] -> RDFGraph -> [RDFGraph]Source

Graph substitution function.

Uses the supplied variable bindings to substitute variables in a supplied graph, returning a list of result graphs corresponding to each set of variable bindings applied to the input graph. This function is used for formward chaining substitutions, and returns only those result graphs for which all query variables are bound.

rdfQueryBackSubs :: [[RDFVarBinding]] -> RDFGraph -> [[(RDFGraph, [RDFLabel])]]Source

Graph back-substitution function.

Uses the supplied variable bindings from `rdfQueryBack` to perform a series of variable substitutions in a supplied graph, returning a list of lists of result graphs corresponding to each set of variable bindings applied to the input graphs.

The outer list of the result contains alternative antecedent lists that satisfy the query goal. Each inner list contains graphs that must all be inferred to satisfy the query goal.

rdfQuerySubsAll :: [RDFVarBinding] -> RDFGraph -> [(RDFGraph, [RDFLabel])]Source

Graph substitution function.

This function performs the substitutions and returns a list of result graphs each paired with a list unbound variables in each.

rdfQuerySubsBlank :: [RDFVarBinding] -> RDFGraph -> [RDFGraph]Source

Graph substitution function.

This function performs each of the substitutions in `vars`, and replaces any nodes corresponding to unbound query variables with new blank nodes.

rdfQueryBackSubsBlank :: [[RDFVarBinding]] -> RDFGraph -> [[RDFGraph]]Source

Graph back-substitution function, replacing variables with bnodes.

Uses the supplied variable bindings from `rdfQueryBack` to perform a series of variable substitutions in a supplied graph, returning a list of lists of result graphs corresponding to each set of variable bindings applied to the input graphs.

The outer list of the result contains alternative antecedent lists that satisfy the query goal. Each inner list contains graphs that must all be inferred to satisfy the query goal.

rdfFindArcs :: (RDFTriple -> Bool) -> RDFGraph -> [RDFTriple]Source

Take a predicate on an RDF statement and a graph, and returns all statements in the graph satisfying that predicate.

Use combinations of these as follows:

- find all statements with given subject: `rdfFindArcs (rdfSubjEq s)`
- find all statements with given property: `rdfFindArcs (rdfPredEq p)`
- find all statements with given object: `rdfFindArcs (rdfObjEq o)`
- find all statements matching conjunction of these conditions: `rdfFindArcs (`allp` [...])`
- find all statements matching disjunction of these conditions: `rdfFindArcs (`anyp` [...])`

Custom predicates can also be used.

rdfSubjEq :: RDFLabel -> RDFTriple -> Bool Source

Test if statement has given subject

rdfPredEq :: RDFLabel -> RDFTriple -> Bool Source

Test if statement has given predicate

rdfObjEq :: RDFLabel -> RDFTriple -> Bool Source

Test if statement has given object

rdfFindPredVal Source

Arguments

:: RDFLabel | subject
-> RDFLabel | predicate
-> RDFGraph |
-> [RDFLabel] |

Find values of given predicate for a given subject

rdfFindPredInt Source

Arguments

:: RDFLabel | subject
-> RDFLabel | predicate
-> RDFGraph |
-> [Integer] |

Find integer values of a given predicate for a given subject

rdfFindValSubj Source

Arguments

:: RDFLabel | predicate
-> RDFLabel | object
-> RDFGraph |
-> [RDFLabel] |

Find all subjects that match (subject, predicate, object) in the graph.

rdfFindList :: RDFGraph -> RDFLabel -> [RDFLabel]Source

Return a list of nodes that comprise an rdf:collection value, given the head element of the collection. If the list is ill-formed then an arbitrary value is returned.

# Utility routines

allp :: [a -> Bool] -> a -> Bool Source

Test if a value satisfies all predicates in a list

anyp :: [a -> Bool] -> a -> Bool Source

Test if a value satisfies any predicate in a list

# Exported for testing

rdfQuerySubs2 :: RDFVarBinding -> RDFGraph -> (RDFGraph, [RDFLabel])Source

This function applies a substitution for a single set of variable bindings, returning the result and a list of unbound variables. It uses a state transformer monad to collect the list of unbound variables.

Adding an empty graph forces elimination of duplicate arcs.