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/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/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/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/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/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.

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

TODO

  • Operator#optimize needs to be completed and tested.

Examples:

Optimizations

See Also:

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:


401
402
403
# File 'lib/sparql/algebra.rb', line 401

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:


389
390
391
# File 'lib/sparql/algebra.rb', line 389

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

.Operator(name, arity = nil) ⇒ Class

Examples:

Operator(:isLiteral)

Parameters:

  • name (Symbol, #to_sym)

Returns:

  • (Class)

412
413
414
# File 'lib/sparql/algebra.rb', line 412

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:


371
372
373
# File 'lib/sparql/algebra.rb', line 371

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

.Variable(name) ⇒ Variable

Examples:

Variable(:foobar)

Parameters:

  • name (Symbol, #to_sym)

Returns:

See Also:


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

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