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

This class is abstract.

A SPARQL operator.

Defined Under Namespace

Classes: Abs, Add, Adjust, 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, PathRange, PathStar, PathZero, Plus, Predicate, Prefix, Project, Quaternary, Rand, Reduced, Regex, Replace, Reverse, Round, SHA1, SHA256, SHA384, SHA512, SameTerm, Sample, Seconds, Seq, Sequence, Service, Slice, Str, StrAfter, StrBefore, StrDT, StrEnds, StrLang, StrLen, StrStarts, StrUUID, SubStr, Subject, Subtract, Sum, TZ, Table, Ternary, Timezone, Triple, UCase, UUID, Unary, Union, Update, Using, With, Year

Constant Summary collapse

ARITY =

variable arity

-1 # variable arity
URI =
IRI
IsURI =
IsIRI

Constants included from Expression

Expression::PATTERN_PARENTS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Expression

cast, #evaluate, 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



476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
# File 'lib/sparql/algebra/operator.rb', line 476

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:



569
570
571
# File 'lib/sparql/algebra/operator.rb', line 569

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)



344
345
346
# File 'lib/sparql/algebra/operator.rb', line 344

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

.base_uriRDF::URI

Base URI used for reading data sources with relative URIs

Returns:

  • (RDF::URI)


523
524
525
# File 'lib/sparql/algebra/operator.rb', line 523

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)


533
534
535
# File 'lib/sparql/algebra/operator.rb', line 533

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

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

Parameters:

Returns:

See Also:



329
330
331
# File 'lib/sparql/algebra/operator.rb', line 329

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



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
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/sparql/algebra/operator.rb', line 166

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 :adjust          then Adjust
    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 :path0           then PathZero
    when :path?           then PathOpt
    when :"path+"         then PathPlus
    when :"path*"         then PathStar
    when :pathrange       then PathRange
    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 :service         then Service
    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 Triple
    when :qtriple         then RDF::Query::Pattern
    when :quad            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



551
552
553
# File 'lib/sparql/algebra/operator.rb', line 551

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})


561
562
563
# File 'lib/sparql/algebra/operator.rb', line 561

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

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

Generate a top-level Grammar, using collected options

Parameters:

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

    ([])

  • distinct (Operator) (defaults to: false)

    (false)

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

    Variable bindings

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

    ([]) Filter Operations

  • limit (Integer) (defaults to: nil)

    (nil)

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

    ([])

  • having_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)

  • values_clause (Operator) (defaults to: nil)

    (nil) Top-level Values clause

  • where_clause (Operator) (defaults to: true)

    (true) Emit ‘WHERE’ before GroupGraphPattern

  • options (Hash{Symbol => Object})

Returns:

  • (String)


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
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
# File 'lib/sparql/algebra/operator.rb', line 373

def self.to_sparql(content,
                   datasets: [],
                   distinct: false,
                   extensions: {},
                   filter_ops: [],
                   group_ops: [],
                   having_ops: [],
                   limit: nil,
                   offset: nil,
                   order_ops: [],
                   project: %i(*),
                   reduced: false,
                   values_clause: nil,
                   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.to_s)
        v = expr.to_sparql(**options)
        pp = RDF::Query::Variable.new(p).to_sparql(**options)
        # Replace projected variables with their extension, if any
        '(' + v + ' AS ' + pp + ')'
      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|
    v = expression.to_sparql(**options)
    pp = RDF::Query::Variable.new(as).to_sparql(**options)
    content << "\nBIND (" << v << " AS " << pp << ") ."
  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
  unless having_ops.empty?
    str << "HAVING #{having_ops.to_sparql(**options)}"
  end

  # 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?

  # Values Clause
  str << values_clause.to_sparql(top_level: false, **options) if values_clause
  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



636
637
638
# File 'lib/sparql/algebra/operator.rb', line 636

def aggregate?
  respond_to?(:aggregate)
end

#base_uriRDF::URI

Base URI used for reading data sources with relative URIs

Returns:

  • (RDF::URI)


515
516
517
# File 'lib/sparql/algebra/operator.rb', line 515

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)


506
507
508
509
# File 'lib/sparql/algebra/operator.rb', line 506

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:



824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
# File 'lib/sparql/algebra/operator.rb', line 824

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:



626
627
628
# File 'lib/sparql/algebra/operator.rb', line 626

def constant?
  !(variable?)
end

#deep_dupObject

Deep duplicate operands



497
498
499
# File 'lib/sparql/algebra/operator.rb', line 497

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)


755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
# File 'lib/sparql/algebra/operator.rb', line 755

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)


731
732
733
# File 'lib/sparql/algebra/operator.rb', line 731

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



607
608
609
# File 'lib/sparql/algebra/operator.rb', line 607

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



616
617
618
# File 'lib/sparql/algebra/operator.rb', line 616

def executable?
  respond_to?(:execute)
end

#first_ancestor(klass) ⇒ Operator

First ancestor operator of type klass

Parameters:

  • klass (Class)

Returns:



794
795
796
# File 'lib/sparql/algebra/operator.rb', line 794

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)


724
725
726
# File 'lib/sparql/algebra/operator.rb', line 724

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



739
740
741
# File 'lib/sparql/algebra/operator.rb', line 739

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

#node?Boolean

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

Returns:

  • (Boolean)


596
597
598
599
600
# File 'lib/sparql/algebra/operator.rb', line 596

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:



577
578
579
# File 'lib/sparql/algebra/operator.rb', line 577

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


653
654
655
656
657
658
659
660
661
# File 'lib/sparql/algebra/operator.rb', line 653

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!


669
670
671
672
673
674
# File 'lib/sparql/algebra/operator.rb', line 669

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

#parentOperator

Parent expression, if any

Returns:



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

def parent; @options[:parent]; end

#parent=(operator) ⇒ Operator

Parent operator, if any

Returns:



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

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

#prefixesHash{Symbol => RDF::URI}

Prefixes useful for future serialization

Returns:

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

    Prefix definitions



542
543
544
# File 'lib/sparql/algebra/operator.rb', line 542

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:



684
685
686
687
688
689
690
# File 'lib/sparql/algebra/operator.rb', line 684

def rewrite(&block)
  @operands = @operands.map do |op|
    new_op = block.call(op)
    new_op.respond_to?(:rewrite) ? new_op.rewrite(&block) : 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:



862
863
864
865
866
867
868
869
870
871
872
873
874
# File 'lib/sparql/algebra/operator.rb', line 862

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)


716
717
718
# File 'lib/sparql/algebra/operator.rb', line 716

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)


708
709
710
# File 'lib/sparql/algebra/operator.rb', line 708

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:



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

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



802
803
804
805
# File 'lib/sparql/algebra/operator.rb', line 802

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:



587
588
589
# File 'lib/sparql/algebra/operator.rb', line 587

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

#variablesHash{Symbol => RDF::Query::Variable}

The variables used in this query.

Returns:



811
812
813
# File 'lib/sparql/algebra/operator.rb', line 811

def variables
  operands.inject({}) {|hash, o| o.respond_to?(:variables) ? hash.merge(o.variables) : hash}
end

#varsArray<RDF::Query::Variable>

Return the variables contained within this operator



746
747
748
# File 'lib/sparql/algebra/operator.rb', line 746

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