Module: SPARQL::Algebra

Includes:
RDF
Defined in:
lib/sparql/algebra.rb,
lib/sparql/algebra/query.rb,
lib/sparql/algebra/update.rb,
lib/sparql/algebra/version.rb,
lib/sparql/algebra/operator.rb,
lib/sparql/algebra/aggregate.rb,
lib/sparql/algebra/expression.rb,
lib/sparql/algebra/evaluatable.rb,
lib/sparql/algebra/operator/if.rb,
lib/sparql/algebra/operator/in.rb,
lib/sparql/algebra/operator/or.rb,
lib/sparql/algebra/operator/tz.rb,
lib/sparql/algebra/operator/abs.rb,
lib/sparql/algebra/operator/add.rb,
lib/sparql/algebra/operator/alt.rb,
lib/sparql/algebra/operator/and.rb,
lib/sparql/algebra/operator/asc.rb,
lib/sparql/algebra/operator/ask.rb,
lib/sparql/algebra/operator/avg.rb,
lib/sparql/algebra/operator/bgp.rb,
lib/sparql/algebra/operator/day.rb,
lib/sparql/algebra/operator/iri.rb,
lib/sparql/algebra/operator/max.rb,
lib/sparql/algebra/operator/md5.rb,
lib/sparql/algebra/operator/min.rb,
lib/sparql/algebra/operator/not.rb,
lib/sparql/algebra/operator/now.rb,
lib/sparql/algebra/operator/seq.rb,
lib/sparql/algebra/operator/str.rb,
lib/sparql/algebra/operator/sum.rb,
lib/sparql/algebra/operator/base.rb,
lib/sparql/algebra/operator/ceil.rb,
lib/sparql/algebra/operator/copy.rb,
lib/sparql/algebra/operator/desc.rb,
lib/sparql/algebra/operator/drop.rb,
lib/sparql/algebra/operator/join.rb,
lib/sparql/algebra/operator/lang.rb,
lib/sparql/algebra/operator/load.rb,
lib/sparql/algebra/operator/move.rb,
lib/sparql/algebra/operator/path.rb,
lib/sparql/algebra/operator/plus.rb,
lib/sparql/algebra/operator/rand.rb,
lib/sparql/algebra/operator/sha1.rb,
lib/sparql/algebra/operator/uuid.rb,
lib/sparql/algebra/operator/with.rb,
lib/sparql/algebra/operator/year.rb,
lib/sparql/algebra/operator/bnode.rb,
lib/sparql/algebra/operator/bound.rb,
lib/sparql/algebra/operator/clear.rb,
lib/sparql/algebra/operator/count.rb,
lib/sparql/algebra/operator/equal.rb,
lib/sparql/algebra/operator/floor.rb,
lib/sparql/algebra/operator/graph.rb,
lib/sparql/algebra/operator/group.rb,
lib/sparql/algebra/operator/hours.rb,
lib/sparql/algebra/operator/lcase.rb,
lib/sparql/algebra/operator/minus.rb,
lib/sparql/algebra/operator/month.rb,
lib/sparql/algebra/operator/notin.rb,
lib/sparql/algebra/operator/order.rb,
lib/sparql/algebra/operator/regex.rb,
lib/sparql/algebra/operator/round.rb,
lib/sparql/algebra/operator/slice.rb,
lib/sparql/algebra/operator/strdt.rb,
lib/sparql/algebra/operator/table.rb,
lib/sparql/algebra/operator/ucase.rb,
lib/sparql/algebra/operator/union.rb,
lib/sparql/algebra/operator/using.rb,
lib/sparql/algebra/operator/adjust.rb,
lib/sparql/algebra/operator/concat.rb,
lib/sparql/algebra/operator/create.rb,
lib/sparql/algebra/operator/delete.rb,
lib/sparql/algebra/operator/divide.rb,
lib/sparql/algebra/operator/exists.rb,
lib/sparql/algebra/operator/extend.rb,
lib/sparql/algebra/operator/filter.rb,
lib/sparql/algebra/operator/insert.rb,
lib/sparql/algebra/operator/is_iri.rb,
lib/sparql/algebra/operator/modify.rb,
lib/sparql/algebra/operator/negate.rb,
lib/sparql/algebra/operator/object.rb,
lib/sparql/algebra/operator/prefix.rb,
lib/sparql/algebra/operator/sample.rb,
lib/sparql/algebra/operator/sha256.rb,
lib/sparql/algebra/operator/sha384.rb,
lib/sparql/algebra/operator/sha512.rb,
lib/sparql/algebra/operator/strlen.rb,
lib/sparql/algebra/operator/substr.rb,
lib/sparql/algebra/operator/triple.rb,
lib/sparql/algebra/operator/update.rb,
lib/sparql/algebra/operator/compare.rb,
lib/sparql/algebra/operator/dataset.rb,
lib/sparql/algebra/operator/minutes.rb,
lib/sparql/algebra/operator/project.rb,
lib/sparql/algebra/operator/reduced.rb,
lib/sparql/algebra/operator/replace.rb,
lib/sparql/algebra/operator/reverse.rb,
lib/sparql/algebra/operator/seconds.rb,
lib/sparql/algebra/operator/service.rb,
lib/sparql/algebra/operator/strends.rb,
lib/sparql/algebra/operator/strlang.rb,
lib/sparql/algebra/operator/struuid.rb,
lib/sparql/algebra/operator/subject.rb,
lib/sparql/algebra/operator/coalesce.rb,
lib/sparql/algebra/operator/contains.rb,
lib/sparql/algebra/operator/datatype.rb,
lib/sparql/algebra/operator/describe.rb,
lib/sparql/algebra/operator/distinct.rb,
lib/sparql/algebra/operator/exprlist.rb,
lib/sparql/algebra/operator/is_blank.rb,
lib/sparql/algebra/operator/multiply.rb,
lib/sparql/algebra/operator/notoneof.rb,
lib/sparql/algebra/operator/path_opt.rb,
lib/sparql/algebra/operator/sequence.rb,
lib/sparql/algebra/operator/strafter.rb,
lib/sparql/algebra/operator/subtract.rb,
lib/sparql/algebra/operator/timezone.rb,
lib/sparql/algebra/operator/construct.rb,
lib/sparql/algebra/operator/is_triple.rb,
lib/sparql/algebra/operator/left_join.rb,
lib/sparql/algebra/operator/less_than.rb,
lib/sparql/algebra/operator/not_equal.rb,
lib/sparql/algebra/operator/notexists.rb,
lib/sparql/algebra/operator/path_plus.rb,
lib/sparql/algebra/operator/path_star.rb,
lib/sparql/algebra/operator/path_zero.rb,
lib/sparql/algebra/operator/predicate.rb,
lib/sparql/algebra/operator/same_term.rb,
lib/sparql/algebra/operator/strbefore.rb,
lib/sparql/algebra/operator/strstarts.rb,
lib/sparql/algebra/operator/is_literal.rb,
lib/sparql/algebra/operator/is_numeric.rb,
lib/sparql/algebra/operator/path_range.rb,
lib/sparql/algebra/operator/delete_data.rb,
lib/sparql/algebra/operator/insert_data.rb,
lib/sparql/algebra/operator/delete_where.rb,
lib/sparql/algebra/operator/greater_than.rb,
lib/sparql/algebra/operator/group_concat.rb,
lib/sparql/algebra/operator/lang_matches.rb,
lib/sparql/algebra/operator/function_call.rb,
lib/sparql/algebra/operator/encode_for_uri.rb,
lib/sparql/algebra/operator/less_than_or_equal.rb,
lib/sparql/algebra/operator/greater_than_or_equal.rb

Overview

A SPARQL algebra for RDF.rb.

Parses Sparql S-Expressions (SSE) into SPARQL Algebra operators.

Operators implementing Query#execute may directly execute an object implementing RDF::Queryable, and so may be treated equivalently to RDF::Query.

Operators implementing Expression#evaluate may be evaluated with RDF::Query::Solution bindings to yield an appropriate result.

An entire SSE expression is parsed into a recursive set of Operator instances, with each operand representing an additional operator.

RDF::Query and RDF::Query::Pattern are used as primitives for bgp and triple expressions.

Background

The SPARQL Algebra, and the S-Expressions used to represent it, are based on those of Jena. Generally, an S-Expression generated by this Gem can be used as an SSE input to Jena, or an SSE output from Jena can also be used as input to this Gem.

S-Expressions generally follow a standardized nesting resulting from parsing the original SPARQL Grammar. The individual operators map to SPARQL Grammar productions, and in most cases, the SPARQL Grammar can be reproduced by turning the S-Expression back into SPARQL (see Operator#to_sparql). The order of operations will typically be as follows:

Queries

require 'sparql/algebra'

include SPARQL::Algebra

Basic Query

BASE <http://example.org/x/> 
PREFIX : <>

SELECT * WHERE { :x ?p ?v } 

is equivalent to

(base <http://example.org/x/>
  (prefix ((: <>))
    (bgp (triple :x ?p ?v))))

Prefixes

PREFIX ns: <http://example.org/ns#>
PREFIX x:  <http://example.org/x/>

SELECT * WHERE { x:x ns:p ?v } 

is equivalent to

(prefix ((ns: <http://example.org/ns#>)
         (x: <http://example.org/x/>))
  (bgp (triple x:x ns:p ?v)))

Ask

PREFIX :  <http://example/>

ASK WHERE { :x :p ?x } 

is equivalent to

(prefix ((: <http://example/>))
  (ask
    (bgp (triple :x :p ?x))))

Datasets

PREFIX : <http://example/> 

SELECT * 
FROM <data-g1.ttl>
FROM NAMED <data-g2.ttl>
{ ?s ?p ?o }

is equivalent to

(prefix ((: <http://example/>))
  (dataset (<data-g1.ttl> (named <data-g2.ttl>))
    (bgp (triple ?s ?p ?o))))

Join

PREFIX : <http://example/> 

SELECT * 
{ 
   ?s ?p ?o
   GRAPH ?g { ?s ?q ?v }
}

is equivalent to

(prefix ((: <http://example/>))
  (join
    (bgp (triple ?s ?p ?o))
    (graph ?g
      (bgp (triple ?s ?q ?v)))))

Union

PREFIX : <http://example/> 

SELECT * 
{ 
   { ?s ?p ?o }
  UNION
   { GRAPH ?g { ?s ?p ?o } }
}

is equivalent to

(prefix ((: <http://example/>))
  (union
    (bgp (triple ?s ?p ?o))
    (graph ?g
      (bgp (triple ?s ?p ?o)))))

LeftJoin

PREFIX :    <http://example/>

SELECT *
{ 
  ?x :p ?v .
  OPTIONAL
  { 
    ?y :q ?w .
    FILTER(?v=2)
  }
}

is equivalent to

(prefix ((: <http://example/>))
  (leftjoin
    (bgp (triple ?x :p ?v))
    (bgp (triple ?y :q ?w))
    (= ?v 2)))

Expressions

Constructing operator expressions manually

Operator(:isBlank).new(RDF::Node(:foobar)).to_sxp                        #=> "(isBlank _:foobar)"
Operator(:isIRI).new(RDF::URI('https://rubygems.org/gems/rdf/')).to_sxp       #=> "(isIRI <https://rubygems.org/gems/rdf/>)"
Operator(:isLiteral).new(RDF::Literal(3.1415)).to_sxp                    #=> "(isLiteral 3.1415e0)"
Operator(:str).new(Operator(:datatype).new(RDF::Literal(3.1415))).to_sxp #=> "(str (datatype 3.1415e0))"

Constructing operator expressions using SSE forms

SPARQL::Algebra::Expression[:isBlank, RDF::Node(:foobar)].to_sxp                          #=> "(isBlank _:foobar)"
SPARQL::Algebra::Expression[:isIRI, RDF::URI('https://rubygems.org/gems/rdf/')].to_sxp         #=> "(isIRI <https://rubygems.org/gems/rdf/>)"
SPARQL::Algebra::Expression[:isLiteral, RDF::Literal(3.1415)].to_sxp                      #=> "(isLiteral 3.1415e0)"
SPARQL::Algebra::Expression[:str, [:datatype, RDF::Literal(3.1415)]].to_sxp               #=> "(str (datatype 3.1415e0))"

Constructing operator expressions using SSE strings

SPARQL::Algebra::Expression.parse('(isBlank _:foobar)')
SPARQL::Algebra::Expression.parse('(isIRI <https://rubygems.org/gems/rdf/>)')
SPARQL::Algebra::Expression.parse('(isLiteral 3.1415)')
SPARQL::Algebra::Expression.parse('(str (datatype 3.1415))')

Evaluating operators standalone

Operator(:isBlank).evaluate(RDF::Node(:foobar))                          #=> RDF::Literal::TRUE
Operator(:isIRI).evaluate(RDF::Vocab::DC.title)                                 #=> RDF::Literal::TRUE
Operator(:isLiteral).evaluate(RDF::Literal(3.1415))                      #=> RDF::Literal::TRUE

Evaluating expressions on a solution sequence

# Find all people and their names & e-mail addresses:
solutions = RDF::Query.execute(RDF::Graph.load('etc/doap.ttl')) do |query|
  query.pattern [:person, RDF.type,  RDF::Vocab::FOAF.Person]
  query.pattern [:person, RDF::Vocab::FOAF.name, :name]
  query.pattern [:person, RDF::Vocab::FOAF.mbox, :email], optional: true
end

# Find people who have a name but don't have a known e-mail address:
expression = SPARQL::Algebra::Expression[:not, [:bound, Variable(:email)]]    # ...or just...
expression = SPARQL::Algebra::Expression.parse('(not (bound ?email))')
solutions.filter!(expression)

Some very simple optimizations are currently implemented for FILTER expressions. Use the following to obtain optimized SSE forms:

SPARQL::Algebra::Expression.parse(sse).optimize.to_sxp_bin

Constant comparison folding

(sameTerm ?x ?x)   #=> true

Constant arithmetic folding

(!= ?x (+ 123))    #=> (!= ?x 123)
(!= ?x (- -1.0))   #=> (!= ?x 1.0)
(!= ?x (+ 1 2))    #=> (!= ?x 3)
(!= ?x (- 4 5))    #=> (!= ?x -1)
(!= ?x (* 6 7))    #=> (!= ?x 42)
(!= ?x (/ 0 0.0))  #=> (!= ?x NaN)

Memoization

Expressions can optionally be memoized, which can speed up repeatedly executing the expression on a solution sequence:

SPARQL::Algebra::Expression.parse(sse, memoize: true)
Operator.new(*operands, memoize: true)

Memoization is implemented using RDF.rb's RDF::Util::Cache utility library, a weak-reference cache that allows values contained in the cache to be garbage collected. This allows the cache to dynamically adjust to changing memory conditions, caching more objects when memory is plentiful, but evicting most objects if memory pressure increases to the point of scarcity.

Documentation

Defined Under Namespace

Modules: Aggregate, Evaluatable, Expression, Query, Update, VERSION Classes: Operator

Constant Summary collapse

Variable =
RDF::Query::Variable

Class Method Summary collapse

Class Method Details

.Expression(*sse) ⇒ SPARQL::Algebra::Expression

Examples:

Expression(:isLiteral, RDF::Literal(3.1415))

Parameters:

  • sse (Array)

    a SPARQL S-Expression (SSE) form

Returns:



436
437
438
# File 'lib/sparql/algebra.rb', line 436

def Expression(*sse)
  Expression.for(*sse)
end

.open(sse, **options) {|expression| ... } ⇒ Expression

Parses input from the given file name or URL.

Parameters:

Options Hash (**options):

  • :base_uri (RDF::URI, #to_s)

    Base URI used for loading relative URIs.

Yields:

  • (expression)

Yield Parameters:

Yield Returns:

  • (void)

    ignored

Returns:



424
425
426
# File 'lib/sparql/algebra.rb', line 424

def open(sse, **options)
  Expression.open(sse, **options)
end

.Operator(name, arity = nil) ⇒ Class

Examples:

Operator(:isLiteral)

Parameters:

  • name (Symbol, #to_sym)

Returns:

  • (Class)


447
448
449
# File 'lib/sparql/algebra.rb', line 447

def Operator(name, arity = nil)
  Operator.for(name, arity)
end

.parse(sse, **options) ⇒ SPARQL::Algebra::Operator

Examples:

sse = (prefix ((foaf: <http://xmlns.com/foaf/0.1/>))
        (project (?name ?mbox)
          (join
            (bgp (triple ?x foaf:name ?name))
            (bgp (triple ?x foaf:mbox ?mbox)))))
}

Parameters:

Returns:



406
407
408
# File 'lib/sparql/algebra.rb', line 406

def parse(sse, **options)
  Expression.parse(sse, **options)
end

.Variable(name) ⇒ Variable

Examples:

Variable(:foobar)

Parameters:

  • name (Symbol, #to_sym)

Returns:

See Also:



459
460
461
# File 'lib/sparql/algebra.rb', line 459

def Variable(name)
  Variable.new(name)
end