Class: RDF::Statement

Inherits:
Object
  • Object
show all
Includes:
Resource
Defined in:
lib/rdf/model/statement.rb

Overview

An RDF statement.

Examples:

Creating an RDF statement

s = RDF::URI.new("https://rubygems.org/gems/rdf")
p = RDF::Vocab::DC.creator
o = RDF::URI.new("http://ar.to/#self")
RDF::Statement(s, p, o)

Creating an RDF statement with a graph_name

uri = RDF::URI("http://example/")
RDF::Statement(s, p, o, graph_name: uri)

Creating an RDF statement from a ‘Hash`

RDF::Statement({
  subject:   RDF::URI.new("https://rubygems.org/gems/rdf"),
  predicate: RDF::Vocab::DC.creator,
  object:    RDF::URI.new("http://ar.to/#self"),
})

Creating an RDF statement with interned nodes

RDF::Statement(:s, p, :o)

Creating an RDF statement with a string

RDF::Statement(s, p, "o")

Direct Known Subclasses

Query::Pattern

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Resource

new, #resource?

Methods included from Term

#<=>, #compatible?, #term?, #to_base, #to_term

Methods included from Value

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

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{Symbol => Object})

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

    • :quoted (Boolean)

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

  • #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).

    • :quoted (Boolean)

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



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/rdf/model/statement.rb', line 89

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 'lib/rdf/model/statement.rb', line 49

def graph_name
  @graph_name
end

#idObject

Returns:

  • (Object)


46
47
48
# File 'lib/rdf/model/statement.rb', line 46

def id
  @id
end

#objectRDF::Term

Returns:



58
59
60
# File 'lib/rdf/model/statement.rb', line 58

def object
  @object
end

#optionsHash{Symbol => Object}

Returns:

  • (Hash{Symbol => Object})


61
62
63
# File 'lib/rdf/model/statement.rb', line 61

def options
  @options
end

#predicateRDF::URI

Returns:



55
56
57
# File 'lib/rdf/model/statement.rb', line 55

def predicate
  @predicate
end

#subjectRDF::Resource

Returns:



52
53
54
# File 'lib/rdf/model/statement.rb', line 52

def subject
  @subject
end

Class Method Details

.from(statement, graph_name: nil, **options) ⇒ Object

Since:

  • 0.2.2



34
35
36
37
38
39
40
41
42
43
# File 'lib/rdf/model/statement.rb', line 34

def self.from(statement, graph_name: nil, **options)
  case statement
    when Array, Query::Pattern
      graph_name ||= statement[3] == false ? nil : statement[3]
      self.new(statement[0], statement[1], statement[2], graph_name: graph_name, **options)
    when Statement then statement
    when Hash      then self.new(options.merge(statement))
    else raise ArgumentError, "expected RDF::Statement, Hash, or Array, but got #{statement.inspect}"
  end
end

Instance Method Details

#==(other) ⇒ Boolean

Checks statement equality as a triple.

Parameters:

  • other (Object)

Returns:

  • (Boolean)

See Also:



326
327
328
329
# File 'lib/rdf/model/statement.rb', line 326

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:



358
359
360
361
362
363
364
# File 'lib/rdf/model/statement.rb', line 358

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:

  • index (Integer)

Returns:



369
370
371
372
373
374
375
376
377
# File 'lib/rdf/model/statement.rb', line 369

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:



383
384
385
386
387
388
389
390
391
# File 'lib/rdf/model/statement.rb', line 383

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)


208
209
210
# File 'lib/rdf/model/statement.rb', line 208

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



434
435
436
437
438
# File 'lib/rdf/model/statement.rb', line 434

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



419
420
421
422
423
424
425
426
427
# File 'lib/rdf/model/statement.rb', line 419

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



238
239
240
# File 'lib/rdf/model/statement.rb', line 238

def complete?
  !incomplete?
end

#dupRDF::Statement

New statement with duplicated components (other than blank nodes)

Returns:



443
444
445
446
447
448
449
450
# File 'lib/rdf/model/statement.rb', line 443

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)


187
188
189
# File 'lib/rdf/model/statement.rb', line 187

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

#eql?(other) ⇒ Boolean

Checks statement equality as a quad.

Parameters:

Returns:

  • (Boolean)

See Also:



306
307
308
# File 'lib/rdf/model/statement.rb', line 306

def eql?(other)
  other.is_a?(Statement) && self.to_a.eql?(other.to_a) && (self.graph_name || false) == (other.graph_name || 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)


253
254
255
256
257
258
259
# File 'lib/rdf/model/statement.rb', line 253

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.



312
313
314
# File 'lib/rdf/model/statement.rb', line 312

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



229
230
231
# File 'lib/rdf/model/statement.rb', line 229

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

#inferred?Boolean

Returns:

  • (Boolean)


220
221
222
# File 'lib/rdf/model/statement.rb', line 220

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

#initialize!Object



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
134
135
136
137
138
# File 'lib/rdf/model/statement.rb', line 108

def initialize!
  @graph_name   = Node.intern(@graph_name)   if @graph_name.is_a?(Symbol)
  @subject   = if @subject.is_a?(Value)
    @subject.to_term
  elsif @subject.is_a?(Symbol)
    Node.intern(@subject)
  elsif @subject.nil?
    nil
  else
    raise ArgumentError, "expected subject to be nil or a resource, was #{@subject.inspect}"
  end
  @predicate = Node.intern(@predicate) if @predicate.is_a?(Symbol)
  @object    = if @object.is_a?(Value)
    @object.to_term
  elsif @object.is_a?(Symbol)
    Node.intern(@object)
  elsif @object.nil?
    nil
  else
    Literal.new(@object)
  end
  @graph_name = if @graph_name.is_a?(Value)
    @graph_name.to_term
  elsif @graph_name.is_a?(Symbol)
    Node.intern(@graph_name)
  elsif !@graph_name
    @graph_name
  else
    raise ArgumentError, "expected graph_name to be nil or a resource, was #{@graph_name.inspect}"
  end
end

#invalid?Boolean

Returns:

  • (Boolean)


193
194
195
# File 'lib/rdf/model/statement.rb', line 193

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



291
292
293
# File 'lib/rdf/model/statement.rb', line 291

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

#object?Boolean Also known as: has_object?

Returns:

  • (Boolean)


280
281
282
# File 'lib/rdf/model/statement.rb', line 280

def object?
  !!object
end

#predicate?Boolean Also known as: has_predicate?

Returns:

  • (Boolean)


273
274
275
# File 'lib/rdf/model/statement.rb', line 273

def predicate?
  !!predicate
end

#quoted?Boolean

Returns:

  • (Boolean)


214
215
216
# File 'lib/rdf/model/statement.rb', line 214

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:



490
491
492
493
494
495
496
497
498
# File 'lib/rdf/model/statement.rb', line 490

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)


150
151
152
153
154
155
156
# File 'lib/rdf/model/statement.rb', line 150

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)


266
267
268
# File 'lib/rdf/model/statement.rb', line 266

def subject?
  !!subject
end

#termsArray(RDF::Term)

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

Returns:



409
410
411
# File 'lib/rdf/model/statement.rb', line 409

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:



459
460
461
# File 'lib/rdf/model/statement.rb', line 459

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:



395
396
397
# File 'lib/rdf/model/statement.rb', line 395

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

#to_sString

Returns a string representation of this statement.

Returns:

  • (String)


467
468
469
470
471
472
473
474
475
476
477
# File 'lib/rdf/model/statement.rb', line 467

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_tripleArray(RDF::Term) Also known as: to_a

Returns:



401
402
403
# File 'lib/rdf/model/statement.rb', line 401

def to_triple
  [subject, predicate, object]
end

#valid?Boolean

Returns:

  • (Boolean)


199
200
201
202
203
204
# File 'lib/rdf/model/statement.rb', line 199

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

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

    • variables (Array<Symbol, #to_sym>)

    Returns:

    • (Boolean)


169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/rdf/model/statement.rb', line 169

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