Class: SPARQL::Algebra::Operator Abstract

Inherits:
Object
  • Object
show all
Includes:
Evaluatable, Expression
Defined in:
lib/sparql/algebra/operator.rb,
lib/sparql/algebra/operator/or.rb,
lib/sparql/algebra/operator/and.rb,
lib/sparql/algebra/operator/asc.rb,
lib/sparql/algebra/operator/ask.rb,
lib/sparql/algebra/operator/not.rb,
lib/sparql/algebra/operator/str.rb,
lib/sparql/algebra/operator/add.rb,
lib/sparql/algebra/operator/bgp.rb,
lib/sparql/algebra/operator/desc.rb,
lib/sparql/algebra/operator/join.rb,
lib/sparql/algebra/operator/lang.rb,
lib/sparql/algebra/operator/plus.rb,
lib/sparql/algebra/operator/base.rb,
lib/sparql/algebra/operator/union.rb,
lib/sparql/algebra/operator/bound.rb,
lib/sparql/algebra/operator/regex.rb,
lib/sparql/algebra/operator/minus.rb,
lib/sparql/algebra/operator/slice.rb,
lib/sparql/algebra/operator/equal.rb,
lib/sparql/algebra/operator/order.rb,
lib/sparql/algebra/operator/graph.rb,
lib/sparql/algebra/operator/divide.rb,
lib/sparql/algebra/operator/is_iri.rb,
lib/sparql/algebra/operator/prefix.rb,
lib/sparql/algebra/operator/filter.rb,
lib/sparql/algebra/operator/project.rb,
lib/sparql/algebra/operator/reduced.rb,
lib/sparql/algebra/operator/compare.rb,
lib/sparql/algebra/operator/dataset.rb,
lib/sparql/algebra/operator/subtract.rb,
lib/sparql/algebra/operator/is_blank.rb,
lib/sparql/algebra/operator/multiply.rb,
lib/sparql/algebra/operator/datatype.rb,
lib/sparql/algebra/operator/distinct.rb,
lib/sparql/algebra/operator/describe.rb,
lib/sparql/algebra/operator/exprlist.rb,
lib/sparql/algebra/operator/less_than.rb,
lib/sparql/algebra/operator/not_equal.rb,
lib/sparql/algebra/operator/same_term.rb,
lib/sparql/algebra/operator/left_join.rb,
lib/sparql/algebra/operator/construct.rb,
lib/sparql/algebra/operator/is_literal.rb,
lib/sparql/algebra/operator/lang_matches.rb,
lib/sparql/algebra/operator/greater_than.rb,
lib/sparql/algebra/operator/less_than_or_equal.rb,
lib/sparql/algebra/operator/greater_than_or_equal.rb

Overview

This class is abstract.

A SPARQL operator.

Direct Known Subclasses

BGP, Binary, Exprlist, LeftJoin, Nullary, Ternary, Unary

Defined Under Namespace

Classes: Add, And, Asc, Ask, BGP, Base, Binary, Bound, Compare, Construct, Dataset, Datatype, Desc, Describe, Distinct, Divide, Equal, Exprlist, Filter, Graph, GreaterThan, GreaterThanOrEqual, IsBlank, IsIRI, IsLiteral, Join, Lang, LangMatches, LeftJoin, LessThan, LessThanOrEqual, Minus, Multiply, Not, NotEqual, Nullary, Or, Order, Plus, Prefix, Project, Reduced, Regex, SameTerm, Slice, Str, Subtract, Ternary, Unary, Union

Constant Summary

ARITY =

variable arity

1

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Evaluatable

#apply, #evaluate, #memoize

Methods included from Expression

cast, #evaluate, new, open, parse

Constructor Details

#initialize(*operands) ⇒ Operator

Initializes a new operator instance.

Raises:

  • (TypeError)

    if any operand is invalid



169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/sparql/algebra/operator.rb', line 169

def initialize(*operands)
  @options  = operands.last.is_a?(Hash) ? operands.pop.dup : {}
  @operands = operands.map! do |operand|
    case operand
      when Operator, Variable, RDF::Term, RDF::Query, RDF::Query::Pattern, Array, Symbol
        operand
      when TrueClass, FalseClass, Numeric, String, DateTime, Date, Time
        RDF::Literal(operand)
      else raise TypeError, "invalid SPARQL::Algebra::Operator operand: #{operand.inspect}"
    end
  end
end

Instance Attribute Details

#operandsArray (readonly)

The operands to this operator.



246
247
248
# File 'lib/sparql/algebra/operator.rb', line 246

def operands
  @operands
end

#optionsHash (readonly)

Any additional options for this operator.



240
241
242
# File 'lib/sparql/algebra/operator.rb', line 240

def options
  @options
end

Class Method Details

.arityInteger

Returns the arity of this operator class.

Examples:

Operator.arity           #=> -1
Operator::Nullary.arity  #=> 0
Operator::Unary.arity    #=> 1
Operator::Binary.arity   #=> 2
Operator::Ternary.arity  #=> 3


154
155
156
# File 'lib/sparql/algebra/operator.rb', line 154

def self.arity
  self.const_get(:ARITY)
end

.base_uriRDF::URI

Base URI used for reading data sources with relative URIs



194
195
196
# File 'lib/sparql/algebra/operator.rb', line 194

def self.base_uri
  @base_uri
end

.base_uri=(uri) ⇒ RDF::URI

Set Base URI associated with SPARQL document, typically done when reading SPARQL from a URI



204
205
206
# File 'lib/sparql/algebra/operator.rb', line 204

def self.base_uri=(uri)
  @base_uri = RDF::URI(uri)
end

.evaluate(*operands) ⇒ RDF::Term

See Also:

  • Operator#evaluate


139
140
141
# File 'lib/sparql/algebra/operator.rb', line 139

def self.evaluate(*operands)
  self.new(*operands).evaluate(RDF::Query::Solution.new)
end

.for(name, arity = nil) ⇒ Class

Returns an operator class for the given operator name.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/sparql/algebra/operator.rb', line 70

def self.for(name, arity = nil)
  # TODO: refactor this to dynamically introspect loaded operator classes.
  case (name.to_s.downcase.to_sym rescue nil)
    when :<=>         then Compare # non-standard
    when :='         then Equal
    when :!='        then NotEqual
    when :<           then LessThan
    when :>           then GreaterThan
    when :<=          then LessThanOrEqual
    when :>=          then GreaterThanOrEqual
    when :*           then Multiply
    when :/'         then Divide
    when :+           then arity.eql?(1) ? Plus  : Add
    when :-           then arity.eql?(1) ? Minus : Subtract
    when :not, :!'   then Not
    when :plus        then Plus
    when :minus       then Minus
    when :bound       then Bound
    when :isblank     then IsBlank
    when :isiri       then IsIRI
    when :isuri       then IsIRI # alias
    when :isliteral   then IsLiteral
    when :str         then Str
    when :lang        then Lang
    when :datatype    then Datatype
    when :or, :||'   then Or
    when :and, :&&'  then And
    when :multiply    then Multiply
    when :divide      then Divide
    when :add         then Add
    when :subtract    then Subtract
    when :sameterm    then SameTerm
    when :langmatches then LangMatches
    when :regex       then Regex
    
    # Miscellaneous
    when :asc         then Asc
    when :desc        then Desc
    when :exprlist    then Exprlist

    # Datasets
    when :dataset     then Dataset
    
    # Query forms
    when :ask         then Ask
    when :base        then Base
    when :bgp         then BGP
    when :construct   then Construct
    when :describe    then Describe
    when :distinct    then Distinct
    when :filter      then Filter
    when :graph       then Graph
    when :join        then Join
    when :leftjoin    then LeftJoin
    when :order       then Order
    when :prefix      then Prefix
    when :project     then Project
    when :reduced     then Reduced
    when :slice       then Slice
    when :triple      then RDF::Query::Pattern
    when :union       then Union
    else nil # not found
  end
end

.prefixesHash{Symbol => RDF::URI}

Prefixes useful for future serialization



222
223
224
# File 'lib/sparql/algebra/operator.rb', line 222

def self.prefixes
  @prefixes
end

.prefixes=(hash) ⇒ Hash{Symbol => RDF::URI}

Prefixes useful for future serialization



232
233
234
# File 'lib/sparql/algebra/operator.rb', line 232

def self.prefixes=(hash)
  @prefixes = hash
end

Instance Method Details

#base_uriRDF::URI

Base URI used for reading data sources with relative URIs



186
187
188
# File 'lib/sparql/algebra/operator.rb', line 186

def base_uri
  Operator.base_uri
end

#boolean(literal) ⇒ RDF::Literal::Boolean (protected)

Returns the effective boolean value (EBV) of the given literal.

Raises:

  • (TypeError)

    if the literal could not be coerced to an RDF::Literal::Boolean

See Also:



370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
# File 'lib/sparql/algebra/operator.rb', line 370

def boolean(literal)
  case literal
    when FalseClass then RDF::Literal::FALSE
    when TrueClass  then RDF::Literal::TRUE
    # If the argument is a typed literal with a datatype of
    # `xsd:boolean`, the EBV is the value of that argument.
    # However, the EBV of any literal whose type is `xsd:boolean` is
    # false if the lexical form is not valid for that datatype.
    when RDF::Literal::Boolean
      RDF::Literal(literal.valid? && literal.true?)
    # If the argument is a numeric type or a typed literal with a
    # datatype derived from a numeric type, the EBV is false if the
    # operand value is NaN or is numerically equal to zero; otherwise
    # the EBV is true.
    # However, the EBV of any literal whose type is numeric is
    # false if the lexical form is not valid for that datatype.
    when RDF::Literal::Numeric
      RDF::Literal(literal.valid? && !(literal.zero?) && !(literal.respond_to?(:nan?) && literal.nan?))
    # If the argument is a plain literal or a typed literal with a
    # datatype of `xsd:string`, the EBV is false if the operand value
    # has zero length; otherwise the EBV is true.
    else case
      when literal.is_a?(RDF::Literal) && (literal.plain? || literal.datatype.eql?(RDF::XSD.string))
        RDF::Literal(!(literal.value.empty?))
    # All other arguments, including unbound arguments, produce a type error.
      else raise TypeError, "could not coerce #{literal.inspect} to an RDF::Literal::Boolean"
    end
  end
end

#constant?Boolean

Returns true if none of the operands are variables, false otherwise.

See Also:



295
296
297
# File 'lib/sparql/algebra/operator.rb', line 295

def constant?
  !(variable?)
end

#eql?(other) ⇒ Boolean Also known as: ==



357
358
359
# File 'lib/sparql/algebra/operator.rb', line 357

def eql?(other)
  other.class == self.class && other.operands == self.operands
end

#evaluatable?Boolean

Returns true if this is evaluatable (i.e., returns values for a binding), false otherwise.



276
277
278
# File 'lib/sparql/algebra/operator.rb', line 276

def evaluatable?
  respond_to?(:evaluate)
end

#executable?Boolean

Returns true if this is executable (i.e., contains a graph patterns), false otherwise.



285
286
287
# File 'lib/sparql/algebra/operator.rb', line 285

def executable?
  respond_to?(:execute)
end

#inspectString

Returns a developer-friendly representation of this operator.



350
351
352
# File 'lib/sparql/algebra/operator.rb', line 350

def inspect
  sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, operands.map(&:inspect).join(', '))
end

#operand(index = 0) ⇒ RDF::Term

Returns the operand at the given index.



254
255
256
# File 'lib/sparql/algebra/operator.rb', line 254

def operand(index = 0)
  operands[index]
end

#optimizeSPARQL::Algebra::Expression

Returns an optimized version of this expression.

For constant expressions containing no variables, returns the result of evaluating the expression with empty bindings; otherwise returns self.

Optimization is not possible if the expression raises an exception, such as a TypeError or ZeroDivisionError, which must be conserved at runtime.



311
312
313
314
315
316
317
318
319
# File 'lib/sparql/algebra/operator.rb', line 311

def optimize
  if constant?
    # Note that if evaluation results in a `TypeError` or other error,
    # we must return `self` so that the error is conserved at runtime:
    evaluate rescue self
  else
    super # returns `self`
  end
end

#prefixesHash{Symbol => RDF::URI}

Prefixes useful for future serialization



213
214
215
# File 'lib/sparql/algebra/operator.rb', line 213

def prefixes
  Operator.prefixes
end

#to_sseArray

Returns the SPARQL S-Expression (SSE) representation of this operator.



326
327
328
329
# File 'lib/sparql/algebra/operator.rb', line 326

def to_sse
  operator = [self.class.const_get(:NAME)].flatten.first
  [operator, *(operands || []).map(&:to_sse)]
end

#to_sxpString

Returns an S-Expression (SXP) representation of this operator



335
336
337
338
339
340
341
342
343
344
# File 'lib/sparql/algebra/operator.rb', line 335

def to_sxp
  begin
    require 'sxp' # @see http://rubygems.org/gems/sxp
  rescue LoadError
    abort "SPARQL::Algebra::Operator#to_sxp requires the SXP gem (hint: `gem install sxp')."
  end
  require 'sparql/algebra/sxp_extensions'
  
  to_sse.to_sxp
end

#variable?Boolean

Returns true if any of the operands are variables, false otherwise.

See Also:



264
265
266
267
268
269
# File 'lib/sparql/algebra/operator.rb', line 264

def variable?
  operands.any? do |operand|
    operand.is_a?(Variable) ||
      (operand.respond_to?(:variable?) && operand.variable?)
  end
end