Class: RDF::Statement

Inherits:
Object show all
Includes:
Resource
Defined in:
vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb,
vendor/bundler/ruby/3.3.0/bundler/gems/json-ld-fcd3aedd310a/lib/json/ld/extensions.rb,
vendor/bundler/ruby/3.3.0/bundler/gems/rdf-n3-a6ef81a7e1ce/lib/rdf/n3/refinements.rb,
vendor/bundler/ruby/3.3.0/bundler/gems/rdf-reasoner-e77a80426b61/lib/rdf/reasoner/extensions.rb,
vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb

Overview

Refinements on RDF::Statement

Direct Known Subclasses

Query::Pattern

Constant Summary collapse

@@entailments =
{}

Constants included from SPARQL::Algebra::Expression

SPARQL::Algebra::Expression::PATTERN_PARENTS

Constants included from Util::Logger

Util::Logger::IOWrapper

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Resource

new, #resource?

Methods included from Term

#<=>, #aggregate?, #as_datetime, #as_number, #compatible?, #escape, #ndvars, #sameTerm?, #term?, #to_base, #to_term, #vars

Methods included from SPARQL::Algebra::Expression

cast, #constant?, extension, extension?, extensions, for, new, open, #optimize!, parse, register_extension

Methods included from Util::Logger

#log_debug, #log_depth, #log_error, #log_fatal, #log_info, #log_recover, #log_recovering?, #log_statistics, #log_warn, #logger

Methods included from Value

#anonymous?, #constant?, #formula?, #inspect, #inspect!, #iri?, #list?, #literal?, #resource?, #start_with?, #term?, #to_ndvar, #to_nquads, #to_ntriples, #to_rdf, #to_term, #type_error, #uri?

Constructor Details

#initialize(**options) ⇒ RDF::Statement #initialize(subject, predicate, object, **options) ⇒ RDF::Statement

Returns a new instance of Statement.

Overloads:

  • #initialize(**options) ⇒ RDF::Statement

    Parameters:

    Options Hash (**options):

    • :subject (RDF::Term) — default: nil

      A symbol is converted to an interned Node.

    • :predicate (RDF::URI) — default: nil
    • :object (RDF::Resource) — default: nil

      if not a Resource, it is coerced to Literal or Node depending on if it is a symbol or something other than a Term.

    • :graph_name (RDF::Term) — default: nil

      Note, in RDF 1.1, a graph name MUST be an Resource.

    • :inferred (Boolean)

      used as a marker to record that this statement was inferred based on semantic relationships (T-Box).

    • :tripleTerm (Boolean)

      used as a marker to record that this statement appears as the object of another RDF::Statement.

    • :quoted (Boolean)

      used as a marker to record that this statement quoted and appears as the subject or object of another RDF::Statement (deprecated).

  • #initialize(subject, predicate, object, **options) ⇒ RDF::Statement

    Parameters:

    Options Hash (**options):

    • :graph_name (RDF::Term) — default: nil

      Note, in RDF 1.1, a graph name MUST be an Resource.

    • :inferred (Boolean)

      used as a marker to record that this statement was inferred based on semantic relationships (T-Box).

    • :tripleTerm (Boolean)

      used as a marker to record that this statement appears as the object of another RDF::Statement.

    • :quoted (Boolean)

      used as a marker to record that this statement quoted and appears as the subject or object of another RDF::Statement (deprecated).



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 91

def initialize(subject = nil, predicate = nil, object = nil, options = {})
  if subject.is_a?(Hash)
    @options   = Hash[subject] # faster subject.dup
    @subject   = @options.delete(:subject)
    @predicate = @options.delete(:predicate)
    @object    = @options.delete(:object)
  else
    @options   = !options.empty? ? Hash[options] : {}
    @subject   = subject
    @predicate = predicate
    @object    = object
  end
  @id          = @options.delete(:id) if @options.key?(:id)
  @graph_name  = @options.delete(:graph_name)
  initialize!
end

Instance Attribute Details

#graph_nameRDF::Resource

Returns:



49
50
51
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 49

def graph_name
  @graph_name
end

#idObject

Returns:



46
47
48
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 46

def id
  @id
end

#objectRDF::Term

Returns:



58
59
60
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 58

def object
  @object
end

#optionsHash{Symbol => Object}

Returns:



61
62
63
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 61

def options
  @options
end

#predicateRDF::URI

Returns:



55
56
57
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 55

def predicate
  @predicate
end

#subjectRDF::Resource

Returns:



52
53
54
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 52

def subject
  @subject
end

Class Method Details

.add_entailment(method, proc) ⇒ Object

Add an entailment method. The method accepts no arguments, and returns or yields an array of values associated with the particular entailment method

Parameters:



123
124
125
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-reasoner-e77a80426b61/lib/rdf/reasoner/extensions.rb', line 123

def add_entailment(method, proc)
  @@entailments[method] = proc
end

Instance Method Details

#==(other) ⇒ Boolean

Checks statement equality as a triple.

Parameters:

Returns:

  • (Boolean)

See Also:



335
336
337
338
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 335

def ==(other)
  to_a == Array(other) &&
    !(other.is_a?(RDF::Value) && other.list?)
end

#===(other) ⇒ Boolean

Checks statement equality with patterns.

Uses #eql? to compare each of #subject, #predicate, #object, and #graph_name to those of other. Any statement part which is not present in self is ignored.

Examples:

statement = RDF::Statement.new(RDF::URI('s'), RDF::URI('p'), RDF::URI('o'))
pattern   = RDF::Statement.new(RDF::URI('s'), RDF::URI('p'), RDF::Query::Variable.new)

# true
statement === statement
pattern   === statement
RDF::Statement.new(nil, nil, nil) === statement

# false
statement === pattern
statement === RDF::Statement.new(nil, nil, nil)

Parameters:

Returns:

  • (Boolean)

See Also:



367
368
369
370
371
372
373
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 367

def ===(other)
  return false if object?    && !object.eql?(other.object)
  return false if predicate? && !predicate.eql?(other.predicate)
  return false if subject?   && !subject.eql?(other.subject)
  return false if graph?     && !graph_name.eql?(other.graph_name)
  return true
end

#[](index) ⇒ RDF::Term

Parameters:

Returns:



378
379
380
381
382
383
384
385
386
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 378

def [](index)
  case index
    when 0 then self.subject
    when 1 then self.predicate
    when 2 then self.object
    when 3 then self.graph_name
    else nil
  end
end

#[]=(index, value) ⇒ RDF::Term

Parameters:

Returns:



392
393
394
395
396
397
398
399
400
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 392

def []=(index, value)
  case index
    when 0 then self.subject   = value
    when 1 then self.predicate = value
    when 2 then self.object    = value
    when 3 then self.graph_name   = value
    else nil
  end
end

#asserted?Boolean

Returns:

  • (Boolean)


210
211
212
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 210

def asserted?
  !quoted?
end

#canonicalizeRDF::Statement

Returns a version of the statement with each position in canonical form

Returns:

  • (RDF::Statement)

    self or nil if statement cannot be canonicalized

Since:

  • 1.0.8



443
444
445
446
447
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 443

def canonicalize
  self.dup.canonicalize!
rescue ArgumentError
  nil
end

#canonicalize!RDF::Statement

Canonicalizes each unfrozen term in the statement.

Returns:

Raises:

  • (ArgumentError)

    if any element cannot be canonicalized.

Since:

  • 1.0.8



428
429
430
431
432
433
434
435
436
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 428

def canonicalize!
  self.subject.canonicalize!    if subject? && !self.subject.frozen?
  self.predicate.canonicalize!  if predicate? && !self.predicate.frozen?
  self.object.canonicalize!     if object? && !self.object.frozen?
  self.graph_name.canonicalize! if graph? && !self.graph_name.frozen?
  self.validate!
  @hash = nil
  self
end

#complete?Boolean

Determines if the statement is complete, vs. invalid. A complete statement is one in which none of subject, predicate, or object, are nil.

Returns:

  • (Boolean)

Since:

  • 3.0



247
248
249
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 247

def complete?
  !incomplete?
end

#dupRDF::Statement

New statement with duplicated components (other than blank nodes)

Returns:



452
453
454
455
456
457
458
459
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 452

def dup
  options = Hash[@options]
  options[:subject] = subject.is_a?(RDF::Node) ? subject : subject.dup
  options[:predicate] = predicate.dup
  options[:object] = object.is_a?(RDF::Node) ? object : object.dup
  options[:graph_name] = graph_name.is_a?(RDF::Node) ? graph_name : graph_name.dup if graph_name
  RDF::Statement.new(options)
end

#embedded?Boolean

Returns true if any element of the statement is, itself, a statement.

Note: Nomenclature is evolving, alternatives could include #complex? and #nested?

Returns:

  • (Boolean)


189
190
191
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 189

def embedded?
  subject && subject.statement? || object && object.statement?
end

#entail(method) {|term| ... } ⇒ Array<Term>

Perform an entailment on this term.

Parameters:

  • method (Symbol)

    A registered entailment method

Yields:

  • term

Yield Parameters:

Returns:



135
136
137
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-reasoner-e77a80426b61/lib/rdf/reasoner/extensions.rb', line 135

def entail(method, &block)
  self.send(@@entailments.fetch(method), &block)
end

#eql?(other) ⇒ Boolean

Checks statement equality as a quad.

Parameters:

Returns:

  • (Boolean)

See Also:



315
316
317
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 315

def eql?(other)
  other.is_a?(Statement) && self.to_a.eql?(other.to_a) && (self.graph_name || false) == (other.graph_name || false)
end

#evaluate(bindings, formulae:, **options) ⇒ RDF::Statement

As a statement is constant, this returns itself.

Parameters:

Returns:

See Also:

  • SPARQL::Algebra::Expression.evaluate


25
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-n3-a6ef81a7e1ce/lib/rdf/n3/refinements.rb', line 25

def evaluate(bindings, formulae:, **options); end

#executable?Boolean

Returns:

  • (Boolean)


396
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 396

def executable?; false; end

#graph?Boolean #graph?(name) ⇒ Boolean Also known as: name?, has_graph?, has_name?

Overloads:

  • #graph?Boolean

    Returns true if the statement has a graph name.

    Returns:

    • (Boolean)
  • #graph?(name) ⇒ Boolean

    Returns true if self contains the given RDF graph_name.

    Parameters:

    • graph_name (RDF::Resource, false)

      Use value false to query for the default graph_name

    Returns:

    • (Boolean)


262
263
264
265
266
267
268
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 262

def graph?(*args)
  case args.length
  when 0 then !!graph_name
  when 1 then graph_name == args.first
  else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
  end
end

#hashObject

Generates a Integer hash value as a quad.



321
322
323
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 321

def hash
  @hash ||= to_quad.hash
end

#incomplete?Boolean

Determines if the statement is incomplete, vs. invalid. An incomplete statement is one in which any of subject, predicate, or object, are nil.

Returns:

  • (Boolean)

Since:

  • 3.0



238
239
240
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 238

def incomplete?
  to_triple.any?(&:nil?)
end

#inferred?Boolean

Returns:

  • (Boolean)


229
230
231
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 229

def inferred?
  !!@options[:inferred]
end

#invalid?Boolean

Refines invalid? to allow literal subjects and BNode predicates.

Returns:

  • (Boolean)


195
196
197
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 195

def invalid?
  !valid?
end

#node?Boolean Also known as: has_blank_nodes?

Returns true if any resource of this statement is a blank node or has an embedded statement including a blank node.

Returns:

  • (Boolean)

Since:

  • 2.0



300
301
302
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 300

def node?
  to_quad.compact.any?(&:node?)
end

#object?Boolean Also known as: has_object?

Returns:

  • (Boolean)


289
290
291
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 289

def object?
  !!object
end

#optimize(**options) ⇒ RDF::Statement

A duplicate of this Statement.

Returns:

See Also:



392
393
394
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 392

def optimize(**options)
  self.dup
end

#predicate?Boolean Also known as: has_predicate?

Returns:

  • (Boolean)


282
283
284
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 282

def predicate?
  !!predicate
end

#quoted?Boolean

Deprecated.

Quoted triples are now deprecated

Returns:

  • (Boolean)


223
224
225
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 223

def quoted?
  !!@options[:quoted]
end

#reified(subject: nil, id: nil, graph_name: nil) ⇒ RDF::Graph

Returns a graph containing this statement in reified form.

Parameters:

  • subject (RDF::Term) (defaults to: nil)

    (nil) Subject of reification.

  • id (RDF::Term) (defaults to: nil)

    (nil) Node identifier, when subject is anonymous

  • graph_name (RDF::Term) (defaults to: nil)

    (nil) Note, in RDF 1.1, a graph name MUST be an Resource.

Returns:

See Also:



499
500
501
502
503
504
505
506
507
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 499

def reified(subject: nil, id: nil, graph_name: nil)
  RDF::Graph.new(graph_name: graph_name) do |graph|
    subject = subject || RDF::Node.new(id)
    graph << [subject, RDF.type,      RDF[:Statement]]
    graph << [subject, RDF.subject,   self.subject]
    graph << [subject, RDF.predicate, self.predicate]
    graph << [subject, RDF.object,    self.object]
  end
end

#statement?Boolean #statement?(statement) ⇒ Boolean

Overloads:

  • #statement?Boolean

    Returns true if self is a RDF::Statement.

    Returns:

    • (Boolean)
  • #statement?(statement) ⇒ Boolean

    Returns true if self contains the given RDF::Statement.

    Parameters:

    Returns:

    • (Boolean)


152
153
154
155
156
157
158
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 152

def statement?(*args)
  case args.length
  when 0 then true
  when 1 then self == args.first || subject.statement?(*args) || object.statement?(*args)
  else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
  end
end

#subject?Boolean Also known as: has_subject?

Returns:

  • (Boolean)


275
276
277
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 275

def subject?
  !!subject
end

#termsArray(RDF::Term)

Returns an array of all the non-nil non-statement terms.

Returns:



418
419
420
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 418

def terms
  to_quad.map {|t| t.respond_to?(:terms) ? t.terms : t}.flatten.compact
end

#to_h(subject_key = :subject, predicate_key = :predicate, object_key = :object, graph_key = :graph_name) ⇒ Hash{Symbol => RDF::Term}

Returns the terms of this statement as a Hash.

Parameters:

  • subject_key (Symbol) (defaults to: :subject)
  • predicate_key (Symbol) (defaults to: :predicate)
  • object_key (Symbol) (defaults to: :object)

Returns:



468
469
470
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 468

def to_h(subject_key = :subject, predicate_key = :predicate, object_key = :object, graph_key = :graph_name)
  {subject_key => subject, predicate_key => predicate, object_key => object, graph_key => graph_name}
end

#to_quadArray(RDF::Term)

Returns:



404
405
406
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 404

def to_quad
  [subject, predicate, object, graph_name]
end

#to_sString

Returns a string representation of this statement.

Returns:



476
477
478
479
480
481
482
483
484
485
486
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 476

def to_s
  (graph_name ? to_quad : to_triple).map do |term|
    if term.is_a?(Statement)
      "<<#{term.to_s[0..-3]}>>"
    elsif term.respond_to?(:to_base)
      term.to_base
    else
      term.inspect
    end
  end.join(" ") + " ."
end

#to_sparql(**options) ⇒ String

Returns a partial SPARQL grammar for this term.

Returns:



382
383
384
385
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 382

def to_sparql(**options)
  str = to_triple.map {|term| term.to_sparql(**options)}.join(" ")
  quoted? ? ('<<' + str + '>>') : str
end

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

Returns an S-Expression (SXP) representation

Parameters:

Returns:



373
374
375
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 373

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

#to_sxp_binArray

Transform Statement Pattern into an SXP

Returns:



357
358
359
360
361
362
363
364
365
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 357

def to_sxp_bin
  [ (has_graph? ? :quad : (quoted? ? :qtriple : :triple)),
    (:inferred if inferred?),
    subject,
    predicate,
    object,
    graph_name
  ].compact.map(&:to_sxp_bin)
end

#to_tripleArray(RDF::Term) Also known as: to_a

Returns:



410
411
412
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 410

def to_triple
  [subject, predicate, object]
end

#tripleTerm?Boolean

Returns:

  • (Boolean)


216
217
218
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 216

def tripleTerm?
  !!@options[:tripleTerm]
end

#valid?Boolean

Refines valid? to allow literal subjects and BNode predicates.

Returns:

  • (Boolean)


201
202
203
204
205
206
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 201

def valid?
  subject?    && subject.resource? && subject.valid? &&
  predicate?  && predicate.uri? && predicate.valid? &&
  object?     && object.term? && object.valid? &&
  (graph?      ? (graph_name.resource? && graph_name.valid?) : true)
end

#valid_extended?Boolean

Validate extended RDF

Returns:

  • (Boolean)


13
14
15
16
17
18
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/json-ld-fcd3aedd310a/lib/json/ld/extensions.rb', line 13

def valid_extended?
  subject? && subject.resource? && subject.valid_extended? &&
    predicate?  && predicate.resource? && predicate.valid_extended? &&
    object?     && object.term? && object.valid_extended? &&
    (graph? ? (graph_name.resource? && graph_name.valid_extended?) : true)
end

#validate!RDF::Value

Refines validate! to allow literal subjects and BNode predicates.

Returns:

Raises:

  • (ArgumentError)

    if the value is invalid



14
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-n3-a6ef81a7e1ce/lib/rdf/n3/refinements.rb', line 14

def validate!; end

#variable?Object #variable?(variables) ⇒ Boolean

URI, Node or Literal.

@return [Boolean]

Overloads:

  • #variable?Object

    Returns true if any element of the statement is not a

  • #variable?(variables) ⇒ Boolean

    Returns true if this statement contains any of the variables.

    Parameters:

    Returns:

    • (Boolean)


171
172
173
174
175
176
177
178
179
180
181
182
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/model/statement.rb', line 171

def variable?(*args)
  case args.length
  when 0
    !(subject?    && subject.constant? &&
      predicate?  && predicate.constant? &&
      object?     && object.constant? &&
      (graph?     ? graph_name.constant? : true))
  when 1
    to_quad.any? {|t| t.respond_to?(:variable?) && t.variable?(*args)}
  else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
  end
end