class RDF::Statement

An RDF statement.

@example 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)

@example Creating an RDF statement with a graph_name

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

@example 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"),
})

@example Creating an RDF statement with interned nodes

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

@example Creating an RDF statement with a string

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

Attributes

graph_name[RW]

@return [RDF::Resource]

id[RW]

@return [Object]

object[RW]

@return [RDF::Term]

options[RW]

@return [Hash{Symbol => Object}]

predicate[RW]

@return [RDF::URI]

subject[RW]

@return [RDF::Resource]

Public Class Methods

from(statement, graph_name: nil, **options) click to toggle source

@private @since 0.2.2

# 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
new(subject = nil, predicate = nil, object = nil, options = {}) click to toggle source

@overload initialize(**options)

@param  [Hash{Symbol => Object}] options
@option options [RDF::Term]  :subject   (nil)
  A symbol is converted to an interned {Node}.
@option options [RDF::URI]       :predicate (nil)
@option options [RDF::Resource]      :object    (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}.
@option options [RDF::Term]  :graph_name   (nil)
  Note, in RDF 1.1, a graph name MUST be an {Resource}.
@option options [Boolean] :inferred used as a marker to record that this statement was inferred based on semantic relationships (T-Box).
@option options [Boolean] :tripleTerm used as a marker to record that this statement appears as the object of another RDF::Statement.
@option options [Boolean] :quoted used as a marker to record that this statement quoted and appears as the subject or object of another RDF::Statement (deprecated).
@return [RDF::Statement]

@overload initialize(subject, predicate, object, **options)

@param  [RDF::Term]          subject
  A symbol is converted to an interned {Node}.
@param  [RDF::URI]           predicate
@param  [RDF::Resource]      object
  if not a {Resource}, it is coerced to {Literal} or {Node} depending on if it is a symbol or something other than a {Term}.
@param  [Hash{Symbol => Object}] options
@option options [RDF::Term]  :graph_name   (nil)
  Note, in RDF 1.1, a graph name MUST be an {Resource}.
@option options [Boolean] :inferred used as a marker to record that this statement was inferred based on semantic relationships (T-Box).
@option options [Boolean] :tripleTerm used as a marker to record that this statement appears as the object of another RDF::Statement.
@option options [Boolean] :quoted used as a marker to record that this statement quoted and appears as the subject or object of another RDF::Statement (deprecated).
@return [RDF::Statement]
# 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

Public Instance Methods

==(other) click to toggle source

Checks statement equality as a triple.

@param [Object] other @return [Boolean]

@see RDF::URI#== @see RDF::Node#== @see RDF::Literal#== @see RDF::Query::Variable#==

# File lib/rdf/model/statement.rb, line 335
def ==(other)
  to_a == Array(other) &&
    !(other.is_a?(RDF::Value) && other.list?)
end
===(other) click to toggle source

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.

@example

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)

@param [Statement] other @return [Boolean]

@see RDF::URI#eql? @see RDF::Node#eql? @see RDF::Literal#eql? @see RDF::Query::Variable#eql?

# 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) click to toggle source

@param [Integer] index @return [RDF::Term]

# 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) click to toggle source

@param [Integer] index @param [RDF::Term] value @return [RDF::Term]

# 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?() click to toggle source

@return [Boolean]

# File lib/rdf/model/statement.rb, line 210
def asserted?
  !quoted?
end
canonicalize() click to toggle source

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

@return [RDF::Statement] ‘self` or nil if statement cannot be canonicalized @since 1.0.8

# File lib/rdf/model/statement.rb, line 443
def canonicalize
  self.dup.canonicalize!
rescue ArgumentError
  nil
end
canonicalize!() click to toggle source

Canonicalizes each unfrozen term in the statement.

@return [RDF::Statement] ‘self` @since 1.0.8 @raise [ArgumentError] if any element cannot be canonicalized.

# 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?() click to toggle source

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

@return [Boolean] @since 3.0

# File lib/rdf/model/statement.rb, line 247
def complete?
  !incomplete?
end
dup() click to toggle source

New statement with duplicated components (other than blank nodes)

@return [RDF::Statement]

# 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?() click to toggle source

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

Note: Nomenclature is evolving, alternatives could include ‘#complex?` and `#nested?` @return [Boolean]

# File lib/rdf/model/statement.rb, line 189
def embedded?
  subject && subject.statement? || object && object.statement?
end
eql?(other) click to toggle source

Checks statement equality as a quad.

@param [Statement] other @return [Boolean]

@see RDF::URI#== @see RDF::Node#== @see RDF::Literal#== @see RDF::Query::Variable#==

# 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?(*args) click to toggle source

@overload graph?

Returns `true` if the statement has a graph name.

@return [Boolean]

@overload graph?(name)

Returns `true` if `self` contains the given RDF graph_name.

@param  [RDF::Resource, false] graph_name
  Use value `false` to query for the default graph_name
@return [Boolean]
# 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
Also aliased as: name?, has_graph?, has_name?
has_blank_nodes?()
Alias for: node?
has_graph?(*args)
Alias for: graph?
has_name?(*args)
Alias for: graph?
has_object?()
Alias for: object?
has_predicate?()
Alias for: predicate?
has_subject?()
Alias for: subject?
hash() click to toggle source

Generates a Integer hash value as a quad.

# File lib/rdf/model/statement.rb, line 321
def hash
  @hash ||= to_quad.hash
end
incomplete?() click to toggle source

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

@return [Boolean] @since 3.0

# File lib/rdf/model/statement.rb, line 238
def incomplete?
  to_triple.any?(&:nil?)
end
inferred?() click to toggle source

@return [Boolean]

# File lib/rdf/model/statement.rb, line 229
def inferred?
  !!@options[:inferred]
end
initialize!() click to toggle source

@private

# 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?() click to toggle source

@return [Boolean]

# File lib/rdf/model/statement.rb, line 195
def invalid?
  !valid?
end
name?(*args)
Alias for: graph?
node?() click to toggle source

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

@return [Boolean] @since 2.0

# File lib/rdf/model/statement.rb, line 300
def node?
  to_quad.compact.any?(&:node?)
end
Also aliased as: has_blank_nodes?
object?() click to toggle source

@return [Boolean]

# File lib/rdf/model/statement.rb, line 289
def object?
  !!object
end
Also aliased as: has_object?
predicate?() click to toggle source

@return [Boolean]

# File lib/rdf/model/statement.rb, line 282
def predicate?
  !!predicate
end
Also aliased as: has_predicate?
quoted?() click to toggle source

@return [Boolean] @deprecated Quoted triples are now deprecated

# File lib/rdf/model/statement.rb, line 223
def quoted?
  !!@options[:quoted]
end
reified(subject: nil, id: nil, graph_name: nil) click to toggle source

Returns a graph containing this statement in reified form.

@param [RDF::Term] subject (nil)

Subject of reification.

@param [RDF::Term] id (nil)

Node identifier, when subject is anonymous

@param [RDF::Term] graph_name (nil)

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

@return [RDF::Graph] @see www.w3.org/TR/rdf-primer/#reification

# 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?(*args) click to toggle source

@overload statement?

Returns `true` if `self` is a {RDF::Statement}.

@return [Boolean]

@overload statement?(statement)

Returns `true` if `self` contains the given {RDF::Statement}.

@param  [RDF::Statement] statement
@return [Boolean]
# 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?() click to toggle source

@return [Boolean]

# File lib/rdf/model/statement.rb, line 275
def subject?
  !!subject
end
Also aliased as: has_subject?
terms() click to toggle source

Returns an array of all the non-nil non-statement terms. @return [Array(RDF::Term)]

# 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_a()
Alias for: to_triple
to_h(subject_key = :subject, predicate_key = :predicate, object_key = :object, graph_key = :graph_name) click to toggle source

Returns the terms of this statement as a ‘Hash`.

@param [Symbol] subject_key @param [Symbol] predicate_key @param [Symbol] object_key @return [Hash{Symbol => RDF::Term}]

# 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_quad() click to toggle source

@return [Array(RDF::Term)]

# File lib/rdf/model/statement.rb, line 404
def to_quad
  [subject, predicate, object, graph_name]
end
to_s() click to toggle source

Returns a string representation of this statement.

@return [String]

# 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_triple() click to toggle source

@return [Array(RDF::Term)]

# File lib/rdf/model/statement.rb, line 410
def to_triple
  [subject, predicate, object]
end
Also aliased as: to_a
tripleTerm?() click to toggle source

@return [Boolean]

# File lib/rdf/model/statement.rb, line 216
def tripleTerm?
  !!@options[:tripleTerm]
end
valid?() click to toggle source

@return [Boolean]

# 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?(*args) click to toggle source

@overload variable?

Returns `true` if any element of the statement is not a

URI, Node or Literal.

@return [Boolean]

@overload variable?(variables)

Returns `true` if this statement contains any of the variables.

@param  [Array<Symbol, #to_sym>] variables
@return [Boolean]
# 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