Class: RDF::Query::Pattern
- Defined in:
- lib/rdf/query/pattern.rb
Overview
An RDF query pattern.
Instance Attribute Summary collapse
-
#cost ⇒ Numeric
The estimated cost of this pattern (for query optimization).
-
#options ⇒ Hash
readonly
Any additional options for this pattern.
Attributes inherited from Statement
#graph_name, #id, #object, #predicate, #subject
Instance Method Summary collapse
-
#bind(solution) ⇒ self
Binds the pattern to a solution, making it no longer variable if all variables are resolved to bound variables.
-
#binding_count ⇒ Integer
Returns the number of bindings in this pattern.
-
#bindings ⇒ Hash{Symbol => RDF::Term}
Returns all bindings in this pattern.
-
#bindings? ⇒ Boolean
Returns
trueif this pattern contains bindings. -
#blank? ⇒ Boolean
Returns
trueif this is a blank pattern, with all terms beingnil. -
#bound? ⇒ Boolean
Returns
trueif all variables in this pattern are bound. -
#bound_variables ⇒ Hash{Symbol => Variable}
Returns all bound variables in this pattern.
-
#dup ⇒ Object
Create a new pattern from the quads, recursivly dupping sub-patterns.
-
#eql?(other) ⇒ Boolean
Checks pattern equality against a statement, considering nesting.
-
#execute(queryable, bindings = {}) {|statement| ... } ⇒ Enumerable<RDF::Query::Pattern>
Executes this query pattern on the given
queryableobject. -
#initialize(subject = nil, predicate = nil, object = nil, options = {}) ⇒ Pattern
constructor
A new instance of Pattern.
-
#optional? ⇒ Boolean
Returns
trueif this is an optional pattern. -
#solution(statement) ⇒ RDF::Query::Solution
Returns a query solution constructed by binding any variables in this pattern with the corresponding terms in the given
statement. -
#to_s ⇒ String
Returns a string representation of this pattern.
-
#unbound? ⇒ Boolean
Returns
trueif all variables in this pattern are unbound. -
#unbound_variables ⇒ Hash{Symbol => Variable}
Returns all unbound variables in this pattern.
-
#valid? ⇒ Boolean
Is this pattern composed only of valid components?.
-
#var_values(var, statement) ⇒ Array<RDF::Term>
Returns all values the statement in the same pattern position.
-
#variable_count ⇒ Integer
(also: #cardinality, #arity)
Returns the number of variables in this pattern.
-
#variable_terms(name = nil) ⇒ Array<Symbol>
deprecated
Deprecated.
use #var_values instead
-
#variables ⇒ Hash{Symbol => Variable}
Returns all variables in this pattern.
-
#variables? ⇒ Boolean
(also: #has_variables?)
Returns
trueif this pattern contains any variables.
Methods inherited from Statement
#==, #===, #[], #[]=, #asserted?, #canonicalize, #canonicalize!, #complete?, #embedded?, #graph?, #hash, #incomplete?, #inferred?, #invalid?, #node?, #object?, #predicate?, #reified, #statement?, #subject?, #terms, #to_h, #to_quad, #to_triple, #tripleTerm?, #variable?
Methods included from Resource
Methods included from Term
#<=>, #==, #compatible?, #escape, #term?, #terms, #to_base, #to_term
Methods included from Value
#anonymous?, #canonicalize, #canonicalize!, #constant?, #graph?, #inspect, #inspect!, #invalid?, #iri?, #list?, #literal?, #node?, #resource?, #start_with?, #statement?, #term?, #to_nquads, #to_ntriples, #to_rdf, #to_term, #type_error, #uri?, #validate!, #variable?
Constructor Details
#initialize(options = {}) ⇒ Pattern #initialize(subject, predicate, object, options = {}) ⇒ Pattern
Statement treats symbols as interned Node instances, in a RDF::Query::Pattern, they are treated as Variable.
Returns a new instance of Pattern.
39 40 41 |
# File 'lib/rdf/query/pattern.rb', line 39 def initialize(subject = nil, predicate = nil, object = nil, = {}) super end |
Instance Attribute Details
#cost ⇒ Numeric
The estimated cost of this pattern (for query optimization).
78 79 80 |
# File 'lib/rdf/query/pattern.rb', line 78 def cost @cost end |
#options ⇒ Hash (readonly)
Any additional options for this pattern.
72 73 74 |
# File 'lib/rdf/query/pattern.rb', line 72 def @options end |
Instance Method Details
#bind(solution) ⇒ self
Binds the pattern to a solution, making it no longer variable if all variables are resolved to bound variables
298 299 300 301 302 303 304 305 306 307 |
# File 'lib/rdf/query/pattern.rb', line 298 def bind(solution) self.to_quad.each_with_index do |term, index| if term.is_a?(Variable) && solution[term] self[index] = solution[term] elsif term.is_a?(Pattern) term.bind(solution) end end self end |
#binding_count ⇒ Integer
Returns the number of bindings in this pattern.
321 322 323 |
# File 'lib/rdf/query/pattern.rb', line 321 def binding_count bindings.size end |
#bindings ⇒ Hash{Symbol => RDF::Term}
Returns all bindings in this pattern.
329 330 331 332 333 334 335 336 |
# File 'lib/rdf/query/pattern.rb', line 329 def bindings bindings = {} bindings.merge!(subject.bindings) if subject && subject.variable? bindings.merge!(predicate.bindings) if predicate && predicate.variable? bindings.merge!(object.bindings) if object && object.variable? bindings.merge!(graph_name.bindings) if graph_name && graph_name.variable? bindings end |
#bindings? ⇒ Boolean
Returns true if this pattern contains bindings.
313 314 315 |
# File 'lib/rdf/query/pattern.rb', line 313 def bindings? !bindings.empty? end |
#blank? ⇒ Boolean
Returns true if this is a blank pattern, with all terms being nil.
85 86 87 |
# File 'lib/rdf/query/pattern.rb', line 85 def blank? subject.nil? && predicate.nil? && object.nil? && graph_name.nil? end |
#bound? ⇒ Boolean
Returns true if all variables in this pattern are bound.
342 343 344 |
# File 'lib/rdf/query/pattern.rb', line 342 def bound? !variables.empty? && variables.values.all?(&:bound?) end |
#bound_variables ⇒ Hash{Symbol => Variable}
Returns all bound variables in this pattern.
350 351 352 |
# File 'lib/rdf/query/pattern.rb', line 350 def bound_variables variables.reject { |name, variable| variable.unbound? } end |
#dup ⇒ Object
Create a new pattern from the quads, recursivly dupping sub-patterns.
64 65 66 |
# File 'lib/rdf/query/pattern.rb', line 64 def dup self.class.from(self.to_quad.map {|t| t.is_a?(RDF::Query::Pattern) ? t.dup : t}) end |
#eql?(other) ⇒ Boolean
Checks pattern equality against a statement, considering nesting.
- A pattern which has a pattern as a subject or an object, matches a statement having a statement as a subject or an object using #eql?.
141 142 143 144 145 146 147 |
# File 'lib/rdf/query/pattern.rb', line 141 def eql?(other) return false unless other.is_a?(Statement) && (self.graph_name || false) == (other.graph_name || false) predicate == other.predicate && (subject.is_a?(Pattern) ? subject.eql?(other.subject) : subject == other.subject) && (object.is_a?(Pattern) ? object.eql?(other.object) : object == other.object) end |
#execute(queryable, bindings = {}) {|statement| ... } ⇒ Enumerable<RDF::Query::Pattern>
Executes this query pattern on the given queryable object.
Values are matched using using Queryable#query_pattern.
If the optional bindings are given, variables will be substituted with their values when executing the query.
To match triples only in the default graph, set graph_name to false.
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 |
# File 'lib/rdf/query/pattern.rb', line 173 def execute(queryable, bindings = {}, &block) bindings = bindings.to_h if bindings.is_a?(Solution) query = { subject: subject.is_a?(Variable) && bindings[subject.to_sym] ? bindings[subject.to_sym] : subject, predicate: predicate.is_a?(Variable) && bindings[predicate.to_sym] ? bindings[predicate.to_sym] : predicate, object: object.is_a?(Variable) && bindings[object.to_sym] ? bindings[object.to_sym] : object, graph_name: graph_name.is_a?(Variable) && bindings[graph_name.to_sym] ? bindings[graph_name.to_sym] : graph_name, }.delete_if{|k,v| v.nil?} # Do all the variable terms refer to distinct variables? variables = self.variables if variable_count == variables.size # If so, we can just let the repository implementation handle # everything and yield matching statements directly: queryable.query(query, &block) # No, some terms actually refer to the same variable... else # Considering embedding, figure out if variables that may appear more than once resolve to the same value. vars = variables.keys queryable.query(query).select do |statement| if vars.all? {|var| self.var_values(var, statement).uniq.size == 1} yield statement if block_given? true end end end end |
#optional? ⇒ Boolean
Returns true if this is an optional pattern.
111 112 113 |
# File 'lib/rdf/query/pattern.rb', line 111 def optional? !![:optional] end |
#solution(statement) ⇒ RDF::Query::Solution
Returns a query solution constructed by binding any variables in this
pattern with the corresponding terms in the given statement.
218 219 220 221 222 223 224 225 226 227 |
# File 'lib/rdf/query/pattern.rb', line 218 def solution(statement) RDF::Query::Solution.new do |solution| solution[subject.to_sym] = statement.subject if subject.is_a?(Variable) solution[predicate.to_sym] = statement.predicate if predicate.is_a?(Variable) solution[object.to_sym] = statement.object if object.is_a?(Variable) solution[graph_name.to_sym] = statement.graph_name if graph_name.is_a?(Variable) solution.merge!(subject.solution(statement.subject)) if subject.respond_to?(:solution) solution.merge!(object.solution(statement.object)) if object.respond_to?(:solution) end end |
#to_s ⇒ String
Returns a string representation of this pattern.
374 375 376 |
# File 'lib/rdf/query/pattern.rb', line 374 def to_s (optional? ? 'OPTIONAL ' : '') + super end |
#unbound? ⇒ Boolean
Returns true if all variables in this pattern are unbound.
358 359 360 |
# File 'lib/rdf/query/pattern.rb', line 358 def unbound? !variables.empty? && variables.values.all?(&:unbound?) end |
#unbound_variables ⇒ Hash{Symbol => Variable}
Returns all unbound variables in this pattern.
366 367 368 |
# File 'lib/rdf/query/pattern.rb', line 366 def unbound_variables variables.reject { |name, variable| variable.bound? } end |
#valid? ⇒ Boolean
Is this pattern composed only of valid components?
119 120 121 122 123 124 125 126 |
# File 'lib/rdf/query/pattern.rb', line 119 def valid? (subject? ? (subject.resource? || subject.variable?) && subject.valid? : true) && (predicate? ? (predicate.uri? || predicate.variable?) && predicate.valid? : true) && (object? ? (object.term? || object.variable?) && object.valid? : true) && (graph? ? (graph_name.resource? || graph_name.variable?) && graph_name.valid? : true) rescue NoMethodError false end |
#var_values(var, statement) ⇒ Array<RDF::Term>
Returns all values the statement in the same pattern position
257 258 259 260 261 262 263 |
# File 'lib/rdf/query/pattern.rb', line 257 def var_values(var, statement) %i(subject predicate object graph_name).map do |position| po = self.send(position) so = statement.send(position) po.var_values(var, so) if po.respond_to?(:var_values) end.flatten.compact end |
#variable_count ⇒ Integer Also known as: cardinality, arity
Returns the number of variables in this pattern.
Note: this does not count distinct variables, and will therefore e.g. return 3 even if two terms are actually the same variable.
272 273 274 275 276 277 |
# File 'lib/rdf/query/pattern.rb', line 272 def variable_count [subject, predicate, object, graph_name].inject(0) do |memo, term| memo += (term.is_a?(Variable) ? 1 : (term.respond_to?(:variable_count) ? term.variable_count : 0)) end end |
#variable_terms(name = nil) ⇒ Array<Symbol>
use #var_values instead
Returns the variable terms in this pattern.
240 241 242 243 244 245 246 247 248 249 |
# File 'lib/rdf/query/pattern.rb', line 240 def variable_terms(name = nil) warn "[DEPRECATION] RDF::Query::Pattern#variable_terms is deprecated and will be removed in a future version.\n" + "Called from #{Gem.location_of_caller.join(':')}" terms = [] terms << :subject if subject.is_a?(Variable) && (!name || name.eql?(subject.name)) terms << :predicate if predicate.is_a?(Variable) && (!name || name.eql?(predicate.name)) terms << :object if object.is_a?(Variable) && (!name || name.eql?(object.name)) terms << :graph_name if graph_name.is_a?(Variable) && (!name || name.eql?(graph_name.name)) terms end |
#variables ⇒ Hash{Symbol => Variable}
Returns all variables in this pattern.
Note: this returns a hash containing distinct variables only.
287 288 289 290 291 |
# File 'lib/rdf/query/pattern.rb', line 287 def variables [subject, predicate, object, graph_name].inject({}) do |memo, term| term && term.variable? ? memo.merge(term.variables) : memo end end |
#variables? ⇒ Boolean Also known as: has_variables?
Returns true if this pattern contains any variables.
94 95 96 97 98 99 |
# File 'lib/rdf/query/pattern.rb', line 94 def variables? subject && subject.variable? || predicate && predicate.variable? || object && object.variable? || graph_name && graph_name.variable? end |