Class: RDF::N3::Algebra::List::Iterate
- Inherits:
-
RDF::N3::Algebra::ListOperator
- Object
- SPARQL::Algebra::Operator::Binary
- RDF::N3::Algebra::ListOperator
- RDF::N3::Algebra::List::Iterate
- Defined in:
- lib/rdf/n3/algebra/list/iterate.rb
Overview
Generates a list of lists when each constituent list is composed of the index and value of each element in the subject.
Binds variables in the object list.
Constant Summary collapse
Instance Attribute Summary
Attributes included from Enumerable
Instance Method Summary collapse
-
#execute(queryable, solutions:, **options) ⇒ RDF::Query::Solutions
Evaluates this operator using the given variable
bindings
.
Methods inherited from RDF::N3::Algebra::ListOperator
#as_literal, #input_operand, #resolve, #validate
Methods included from Builtin
#each, #evaluate, #hash, #input_operand, #rank, #to_uri
Instance Method Details
#execute(queryable, solutions:, **options) ⇒ RDF::Query::Solutions
Evaluates this operator using the given variable bindings
. The subject MUST evaluate to a list and the object to a list composed of two components: index and value.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/rdf/n3/algebra/list/iterate.rb', line 34 def execute(queryable, solutions:, **) RDF::Query::Solutions(solutions.map do |solution| subject = operand(0).evaluate(solution.bindings, formulae: formulae) || operand(0) # Might be a variable or node evaluating to a list in queryable, or might be a list with variables # If subject evaluated to a BNode, re-expand as a list subject = RDF::N3::List.try_list(subject, queryable).evaluate(solution.bindings, formulae: formulae) next unless validate(subject) object = operand(1).evaluate(solution.bindings, formulae: formulae) || operand(1) next unless object # If object evaluated to a BNode, re-expand as a list object = RDF::N3::List.try_list(object, queryable).evaluate(solution.bindings, formulae: formulae) || object if object.list? && object.variable? # Create a solution for those entries in subject that match object if object.length != 2 log_error(NAME) {"object is not a list with two entries: #{object.to_sxp}"} next end if object.first.variable? && object.last.variable? solutions = RDF::Query::Solutions.new subject.each_with_index do |r, i| s = solution.merge(object.first.to_sym => RDF::Literal(i), object.last.to_sym => r) log_debug(self.class.const_get(:NAME), "result: #{s.to_sxp}") solutions << s end solutions elsif object.first.variable? # Solution binds indexes to all matching values solutions = RDF::Query::Solutions.new subject.each_with_index do |r, i| next unless r == object.last s = solution.merge(object.first.to_sym => RDF::Literal(i)) log_debug(self.class.const_get(:NAME), "result: #{s.to_sxp}") solutions << s end solutions elsif object.last.variable? # Solution binds value at specified index next unless v = subject.at(object.first) s = solution.merge(object.last.to_sym => v) log_debug(self.class.const_get(:NAME), "result: #{s.to_sxp}") s end elsif object.variable? # Create a solution for each index/value pair in subject solutions = RDF::Query::Solutions.new subject.each_with_index do |r, i| s = solution.merge(object.to_sym => RDF::N3::List[RDF::Literal(i), r]) log_debug(self.class.const_get(:NAME), "result: #{s.to_sxp}") solutions << s end solutions else # Evaluates to true if the subject has a matching entry same = subject.at(object.first) == object.last log_debug(self.class.const_get(:NAME), "result: #{same.inspect}") solution if same end end.flatten.compact.uniq) end |