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

    • :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 '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 '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:



335
336
337
338
# File '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 '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:

  • index (Integer)

Returns:



378
379
380
381
382
383
384
385
386
# File '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 '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 '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 '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 '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 '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 '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 'lib/rdf/model/statement.rb', line 189

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

#eql?(other) ⇒ Boolean

Checks statement equality as a quad.

Parameters:

Returns:

  • (Boolean)

See Also:



315
316
317
# File '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

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

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

#inferred?Boolean

Returns:

  • (Boolean)


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

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

#initialize!Object



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
139
140
# File 'lib/rdf/model/statement.rb', line 110

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)


195
196
197
# File '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 '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 'lib/rdf/model/statement.rb', line 289

def object?
  !!object
end

#predicate?Boolean Also known as: has_predicate?

Returns:

  • (Boolean)


282
283
284
# File '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 '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 '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 '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 '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 '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 '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 '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:

  • (String)


476
477
478
479
480
481
482
483
484
485
486
# File '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_tripleArray(RDF::Term) Also known as: to_a

Returns:



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

def to_triple
  [subject, predicate, object]
end

#tripleTerm?Boolean

Returns:

  • (Boolean)


216
217
218
# File 'lib/rdf/model/statement.rb', line 216

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

#valid?Boolean

Returns:

  • (Boolean)


201
202
203
204
205
206
# File '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

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


171
172
173
174
175
176
177
178
179
180
181
182
# File '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