Class: SPARQL::Algebra::Operator Abstract

Inherits:
Object
  • Object
show all
Includes:
Expression
Defined in:
lib/sparql/algebra/operator.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

This class is abstract.

A SPARQL operator.

Defined Under Namespace

Classes: Abs, Add, Alt, And, Asc, Ask, Avg, BGP, BNode, Base, Binary, Bound, Ceil, Clear, Coalesce, Compare, Concat, Construct, Contains, Copy, Count, Create, Dataset, Datatype, Day, Delete, DeleteData, DeleteWhere, Desc, Describe, Distinct, Divide, Drop, EncodeForURI, Equal, Exists, Exprlist, Extend, Filter, Floor, FunctionCall, Graph, GreaterThan, GreaterThanOrEqual, Group, GroupConcat, Hours, IRI, If, In, Insert, InsertData, IsBlank, IsIRI, IsLiteral, IsNumeric, IsTriple, Join, LCase, Lang, LangMatches, LeftJoin, LessThan, LessThanOrEqual, Load, MD5, Max, Min, Minus, Minutes, Modify, Month, Move, Multiply, Negate, Not, NotEqual, NotExists, NotIn, NotOneOf, Now, Nullary, Object, Or, Order, Path, PathOpt, PathPlus, PathStar, Plus, Predicate, Prefix, Project, Quaternary, Rand, Reduced, Regex, Replace, Reverse, Round, SHA1, SHA256, SHA384, SHA512, SameTerm, Sample, Seconds, Seq, Sequence, Slice, Str, StrAfter, StrBefore, StrDT, StrEnds, StrLang, StrLen, StrStarts, StrUUID, SubStr, Subject, Subtract, Sum, TZ, Table, Ternary, Timezone, UCase, UUID, Unary, Union, Update, Using, With, Year

Constant Summary collapse

ARITY =

variable arity

-1 # variable arity
URI =
IRI
IsURI =
IsIRI

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Expression

cast, extension, extension?, extensions, #invalid?, new, open, parse, register_extension, #valid?

Constructor Details

#initialize(*operands) ⇒ Operator #initialize(*operands, **options) ⇒ Operator

Initializes a new operator instance.

Overloads:

  • #initialize(*operands) ⇒ Operator

    Parameters:

  • #initialize(*operands, **options) ⇒ Operator

    Parameters:

    Options Hash (**options):

    • :memoize (Boolean) — default: false

      whether to memoize results for particular operands

Raises:

  • (TypeError)

    if any operand is invalid


454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
# File 'lib/sparql/algebra/operator.rb', line 454

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

Instance Attribute Details

#operandsArray (readonly)

The operands to this operator.

Returns:


547
548
549
# File 'lib/sparql/algebra/operator.rb', line 547

def operands
  @operands
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

Returns:

  • (Integer)

    an integer in the range (-1..3)


333
334
335
# File 'lib/sparql/algebra/operator.rb', line 333

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

.base_uriRDF::URI

Base URI used for reading data sources with relative URIs

Returns:

  • (RDF::URI)

501
502
503
# File 'lib/sparql/algebra/operator.rb', line 501

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

Parameters:

  • uri (RDF::URI)

Returns:

  • (RDF::URI)

511
512
513
# File 'lib/sparql/algebra/operator.rb', line 511

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

.evaluate(*operands, **options) ⇒ RDF::Term

Parameters:

Returns:

See Also:


318
319
320
# File 'lib/sparql/algebra/operator.rb', line 318

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

.for(name, arity = nil) ⇒ Class

Returns an operator class for the given operator name.

Parameters:

  • name (Symbol, #to_s)
  • arity (Integer) (defaults to: nil)

Returns:

  • (Class)

    an operator class, or nil if an operator was not found


161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/sparql/algebra/operator.rb', line 161

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 NotEqual
    when :'/'             then Divide
    when :'='             then Equal
    when :*               then Multiply
    when :+               then Plus
    when :-               then arity.eql?(1) ? Negate : Subtract
    when :<               then LessThan
    when :<=              then LessThanOrEqual
    when :<=>             then Compare # non-standard
    when :>               then GreaterThan
    when :>=              then GreaterThanOrEqual
    when :abs             then Abs
    when :alt             then Alt
    when :and, :'&&'      then And
    when :avg             then Avg
    when :bnode           then BNode
    when :bound           then Bound
    when :coalesce        then Coalesce
    when :ceil            then Ceil
    when :concat          then Concat
    when :contains        then Contains
    when :count           then Count
    when :datatype        then Datatype
    when :day             then Day
    when :encode_for_uri  then EncodeForURI
    when :divide          then Divide
    when :exists          then Exists
    when :floor           then Floor
    when :group_concat    then GroupConcat
    when :hours           then Hours
    when :if              then If
    when :in              then In
    when :iri, :uri       then IRI
    when :isblank         then IsBlank
    when :isiri           then IsIRI
    when :isliteral       then IsLiteral
    when :isnumeric       then IsNumeric
    when :isuri           then IsIRI # alias
    when :lang            then Lang
    when :langmatches     then LangMatches
    when :lcase           then LCase
    when :md5             then MD5
    when :max             then Max
    when :min             then Min
    when :minutes         then Minutes
    when :month           then Month
    when :multiply        then Multiply
    when :not, :'!'       then Not
    when :notexists       then NotExists
    when :notin           then NotIn
    when :notoneof        then NotOneOf
    when :now             then Now
    when :or, :'||'       then Or
    when :path            then Path
    when :path?           then PathOpt
    when :"path*"         then PathStar
    when :"path+"         then PathPlus
    when :plus            then Plus
    when :rand            then Rand
    when :regex           then Regex
    when :replace         then Replace
    when :reverse         then Reverse
    when :round           then Round
    when :sameterm        then SameTerm
    when :sample          then Sample
    when :seconds         then Seconds
    when :seq             then Seq
    when :sequence        then Sequence
    when :sha1            then SHA1
    when :sha256          then SHA256
    when :sha384          then SHA384
    when :sha512          then SHA512
    when :str             then Str
    when :strafter        then StrAfter
    when :strbefore       then StrBefore
    when :strdt           then StrDT
    when :strends         then StrEnds
    when :strlang         then StrLang
    when :strlen          then StrLen
    when :strstarts       then StrStarts
    when :struuid         then StrUUID
    when :substr          then SubStr
    when :subtract        then Subtract
    when :sum             then Sum
    when :timezone        then Timezone
    when :tz              then TZ
    when :ucase           then UCase
    when :uuid            then UUID
    when :year            then Year

    # Miscellaneous
    when :asc             then Asc
    when :desc            then Desc
    when :exprlist        then Exprlist
    when :function_call   then FunctionCall

    # 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 :extend          then Extend
    when :filter          then Filter
    when :graph           then Graph
    when :group           then Group
    when :join            then Join
    when :leftjoin        then LeftJoin
    when :order           then Order
    when :minus           then Minus
    when :prefix          then Prefix
    when :project         then Project
    when :reduced         then Reduced
    when :slice           then Slice
    when :table           then Table
    when :union           then Union

    # Update forms
    when :add             then Add
    when :clear           then Clear
    when :copy            then Copy
    when :create          then Create
    when :delete          then Delete
    when :deletedata      then DeleteData
    when :deletewhere     then DeleteWhere
    when :drop            then Drop
    when :insert          then Insert
    when :insertdata      then InsertData
    when :load            then Load
    when :modify          then Modify
    when :move            then Move
    when :update          then Update
    when :using           then Using
    when :with            then With

    # RDF-star
    when :istriple        then IsTriple
    when :triple          then RDF::Query::Pattern
    when :subject         then Subject
    when :predicate       then Predicate
    when :object          then Object

    else                       nil # not found
  end
end

.prefixesHash{Symbol => RDF::URI}

Prefixes useful for future serialization

Returns:

  • (Hash{Symbol => RDF::URI})

    Prefix definitions


529
530
531
# File 'lib/sparql/algebra/operator.rb', line 529

def self.prefixes
  @prefixes
end

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

Prefixes useful for future serialization

Parameters:

  • hash (Hash{Symbol => RDF::URI})

    Prefix definitions

Returns:

  • (Hash{Symbol => RDF::URI})

539
540
541
# File 'lib/sparql/algebra/operator.rb', line 539

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

.to_sparql(content, datasets: [], distinct: false, extensions: {}, filter_ops: [], group_ops: [], limit: nil, offset: nil, order_ops: [], project: %i(*), reduced: false, where_clause: true, **options) ⇒ String

Generate a top-level Grammar, using collected options

Parameters:

  • content (String)
  • extensions (Hash{Symbol => Operator}) (defaults to: {})

    Variable bindings

  • datasets (Operator) (defaults to: [])

    ([])

  • distinct (Operator) (defaults to: false)

    (false)

  • filter_ops (Array<Operator>) (defaults to: [])

    ([]) Filter Operations

  • limit (Integer) (defaults to: nil)

    (nil)

  • group_ops (Array<Operator>) (defaults to: [])

    ([])

  • offset (Integer) (defaults to: nil)

    (nil)

  • order_ops (Array<Operator>) (defaults to: [])

    ([]) Order Operations

  • project (Array<Symbol,Operator>) (defaults to: %i(*))

    (%i(*)) Terms to project

  • reduced (Operator) (defaults to: false)

    (false)

  • where_clause (Operator) (defaults to: true)

    (true) Emit 'WHERE' before GroupGraphPattern

  • options (Hash{Symbol => Object})

Returns:

  • (String)

359
360
361
362
363
364
365
366
367
368
369
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
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
# File 'lib/sparql/algebra/operator.rb', line 359

def self.to_sparql(content,
                   datasets: [],
                   distinct: false,
                   extensions: {},
                   filter_ops: [],
                   group_ops: [],
                   limit: nil,
                   offset: nil,
                   order_ops: [],
                   project: %i(*),
                   reduced: false,
                   where_clause: true,
                   **options)
  str = ""

  # Projections
  if project
    str << "SELECT "
    str << "DISTINCT " if distinct
    str << "REDUCED " if reduced

    str << project.map do |p|
      if expr = extensions.delete(p)
        # Replace projected variables with their extension, if any
        "(" + [expr, :AS, p].to_sparql(**options) + ")"
      else
        p.to_sparql(**options)
      end
    end.join(" ") + "\n"
  end

  # DatasetClause
  datasets.each do |ds|
    str << "FROM #{ds.to_sparql(**options)}\n"
  end

  # Bind
  extensions.each do |as, expression|
    content << "\nBIND (" <<
      expression.to_sparql(**options) <<
      " AS " <<
      as.to_sparql(**options) <<
      ") ."
  end

  # Filter
  filter_ops.each do |f|
    content << "\nFILTER (#{f.to_sparql(**options)}) ."
  end

  # WhereClause / GroupGraphPattern
  str << (where_clause ? "WHERE {\n#{content}\n}\n" : "{\n#{content}\n}\n")

  ##
  # SolutionModifier
  #
  # GroupClause
  unless group_ops.empty?
    ops = group_ops.map do |o|
      # Replace projected variables with their extension, if any
      o.is_a?(Array) ? 
        "(" + [o.last, :AS, o.first].to_sparql(**options) + ")" :
        o.to_sparql(**options)
    end
    str << "GROUP BY #{ops.join(' ')}\n"
  end

  # HavingClause

  # OrderClause
  unless order_ops.empty?
    str << "ORDER BY #{order_ops.to_sparql(**options)}\n"
  end

  # LimitOffsetClauses
  str << "OFFSET #{offset}\n" unless offset.nil?
  str << "LIMIT #{limit}\n" unless limit.nil?
  str
end

Instance Method Details

#aggregate?Boolean

Returns true if this is an aggregate

Overridden in evaluatables which are aggregates

Returns:

  • (Boolean)

    true or false


614
615
616
# File 'lib/sparql/algebra/operator.rb', line 614

def aggregate?
  respond_to?(:aggregate)
end

#base_uriRDF::URI

Base URI used for reading data sources with relative URIs

Returns:

  • (RDF::URI)

493
494
495
# File 'lib/sparql/algebra/operator.rb', line 493

def base_uri
  Operator.base_uri
end

#bind(solution) ⇒ self

Binds the pattern to a solution, making it no longer variable if all variables are resolved to bound variables

Parameters:

Returns:

  • (self)

484
485
486
487
# File 'lib/sparql/algebra/operator.rb', line 484

def bind(solution)
  @operands.each {|op| op.bind(solution)}
  self
end

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

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

Parameters:

  • literal (RDF::Literal)

Returns:

  • (RDF::Literal::Boolean)

    true or false

Raises:

  • (TypeError)

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

See Also:


797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
# File 'lib/sparql/algebra/operator.rb', line 797

def boolean(literal)
  case literal
    when FalseClass then RDF::Literal::FALSE
    when TrueClass  then RDF::Literal::TRUE
    when RDF::Literal::Boolean
      # 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.
      RDF::Literal(literal.valid? && literal.true?)
    when RDF::Literal::Numeric
      # 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.
      RDF::Literal(literal.valid? && !(literal.zero?) && !(literal.respond_to?(:nan?) && literal.nan?))
    else case
      when literal.is_a?(RDF::Literal) && literal.plain?
        # 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.
        RDF::Literal(!(literal.value.empty?))
      else
        # All other arguments, including unbound arguments, produce a type error.
        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.

Returns:

  • (Boolean)

    true or false

See Also:


604
605
606
# File 'lib/sparql/algebra/operator.rb', line 604

def constant?
  !(variable?)
end

#deep_dupObject

Deep duplicate operands


475
476
477
# File 'lib/sparql/algebra/operator.rb', line 475

def deep_dup
  self.class.new(*operands.map(&:deep_dup), **@options)
end

#each_descendant {|operator| ... } ⇒ Enumerator Also known as: descendants, each

Enumerate via depth-first recursive descent over operands, yielding each operator

Yields:

  • operator

Yield Parameters:

Returns:

  • (Enumerator)

737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
# File 'lib/sparql/algebra/operator.rb', line 737

def each_descendant(&block)
  if block_given?
    operands.each do |operand|
      case operand
      when Array
        operand.each do |op|
          op.each_descendant(&block) if op.respond_to?(:each_descendant)
          block.call(op)
        end
      else
        operand.each_descendant(&block) if operand.respond_to?(:each_descendant)
      end
      block.call(operand)
    end
  end
  enum_for(:each_descendant)
end

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

Parameters:

  • other (Statement)

Returns:

  • (Boolean)

713
714
715
# File 'lib/sparql/algebra/operator.rb', line 713

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.

Returns:

  • (Boolean)

    true or false


585
586
587
# File 'lib/sparql/algebra/operator.rb', line 585

def evaluatable?
  respond_to?(:evaluate)
end

#executable?Boolean

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

Returns:

  • (Boolean)

    true or false


594
595
596
# File 'lib/sparql/algebra/operator.rb', line 594

def executable?
  respond_to?(:execute)
end

#first_ancestor(klass) ⇒ Operator

First ancestor operator of type klass

Parameters:

  • klass (Class)

Returns:


776
777
778
# File 'lib/sparql/algebra/operator.rb', line 776

def first_ancestor(klass)
  parent.is_a?(klass) ? parent : parent.first_ancestor(klass) if parent
end

#inspectString

Returns a developer-friendly representation of this operator.

Returns:

  • (String)

706
707
708
# File 'lib/sparql/algebra/operator.rb', line 706

def inspect
  sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, operands.to_sse.gsub(/\s+/m, ' '))
end

#ndvarsArray<RDF::Query::Variable>

Return the non-destinguished variables contained within this operator


721
722
723
# File 'lib/sparql/algebra/operator.rb', line 721

def ndvars
  vars.reject(&:distinguished?)
end

#node?Boolean

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

Returns:

  • (Boolean)

574
575
576
577
578
# File 'lib/sparql/algebra/operator.rb', line 574

def node?
  operands.any? do |operand|
    operand.respond_to?(:node?) ? operand.node? : operand.node?
  end
end

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

Returns the operand at the given index.

Parameters:

  • index (Integer) (defaults to: 0)

    an operand index in the range (0...(operands.count))

Returns:


555
556
557
# File 'lib/sparql/algebra/operator.rb', line 555

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

#optimize(**options) ⇒ SPARQL::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 a copy of self.

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

Returns:

See Also:

  • RDF::Query#optimize

631
632
633
634
635
636
637
638
639
# File 'lib/sparql/algebra/operator.rb', line 631

def optimize(**options)
  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(RDF::Query::Solution.new) rescue self
  else
    super # returns a copy of `self`
  end
end

#optimize!(**options) ⇒ self

Optimizes this query by optimizing its constituent operands according to their cost estimates.

Returns:

  • (self)

See Also:

  • RDF::Query#optimize!

647
648
649
650
651
652
# File 'lib/sparql/algebra/operator.rb', line 647

def optimize!(**options)
  @operands.map! do |op|
    op.optimize(**options) if op.respond_to?(:optimize)
  end
  self
end

#parentOperator

Parent expression, if any

Returns:


761
# File 'lib/sparql/algebra/operator.rb', line 761

def parent; @options[:parent]; end

#parent=(operator) ⇒ Operator

Parent operator, if any

Returns:


767
768
769
# File 'lib/sparql/algebra/operator.rb', line 767

def parent=(operator)
  @options[:parent]= operator
end

#prefixesHash{Symbol => RDF::URI}

Prefixes useful for future serialization

Returns:

  • (Hash{Symbol => RDF::URI})

    Prefix definitions


520
521
522
# File 'lib/sparql/algebra/operator.rb', line 520

def prefixes
  Operator.prefixes
end

#rewrite {|[]| ... } ⇒ SPARQL::Algebra::Expression

Rewrite operands by yielding each operand. Recursively descends through operands implementing this method.

Yields:

  • operand

Yield Parameters:

  • []

    operand

Yield Returns:

Returns:


662
663
664
665
666
667
668
669
670
671
672
# File 'lib/sparql/algebra/operator.rb', line 662

def rewrite(&block)
  @operands = @operands.map do |op|
    # Rewrite the operand
    unless new_op = block.call(op)
      # Not re-written, rewrite
      new_op = op.respond_to?(:rewrite) ? op.rewrite(&block) : op
    end
    new_op
  end
  self
end

#to_binary(klass, *expressions) ⇒ SPARQL::Algebra::Expression (protected)

Transform an array of expressions into a recursive set of binary operations e.g.: a || b || c => (|| a (|| b c))

Parameters:

Returns:


835
836
837
838
839
840
841
842
843
844
845
846
847
# File 'lib/sparql/algebra/operator.rb', line 835

def to_binary(klass, *expressions)
  case expressions.length
  when 0
    # Oops!
    raise "Operator#to_binary requires two or more expressions"
  when 1
    expressions.first
  when 2
    klass.new(*expressions)
  else
    klass.new(expressions.shift, to_binary(klass, *expressions))
  end
end

#to_sparql(**options) ⇒ String

Returns a partial SPARQL grammar for this operator.

Returns:

  • (String)

698
699
700
# File 'lib/sparql/algebra/operator.rb', line 698

def to_sparql(**options)
  raise NotImplementedError, "#{self.class}#to_sparql(#{operands.map(&:class).join(', ')})"
end

#to_sxp(prefixes: nil, base_uri: nil) ⇒ String

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

Parameters:

  • prefixes (Hash{Symbol => RDF::URI}) (defaults to: nil)

    (nil)

  • base_uri (RDF::URI) (defaults to: nil)

    (nil)

Returns:

  • (String)

690
691
692
# File 'lib/sparql/algebra/operator.rb', line 690

def to_sxp(prefixes: nil, base_uri: nil)
  to_sxp_bin.to_sxp(prefixes: prefixes, base_uri: base_uri)
end

#to_sxp_binArray

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

Returns:

See Also:


679
680
681
682
# File 'lib/sparql/algebra/operator.rb', line 679

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

#validate!SPARQL::Algebra::Expression

Validate all operands, operator specific classes should override for operator-specific validation

Returns:

Raises:

  • (ArgumentError)

    if the value is invalid


784
785
786
787
# File 'lib/sparql/algebra/operator.rb', line 784

def validate!
  operands.each {|op| op.validate! if op.respond_to?(:validate!)}
  self
end

#variable?Boolean

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

Returns:

  • (Boolean)

    true or false

See Also:


565
566
567
# File 'lib/sparql/algebra/operator.rb', line 565

def variable?
  operands.any? {|op| op.respond_to?(:variable?) && op.variable?}
end

#varsArray<RDF::Query::Variable>

Return the variables contained within this operator


728
729
730
# File 'lib/sparql/algebra/operator.rb', line 728

def vars
  operands.select {|o| o.respond_to?(:vars)}.map(&:vars).flatten
end