Skip to content

Commit

Permalink
notoneof and reverse operators.
Browse files Browse the repository at this point in the history
  • Loading branch information
gkellogg committed May 9, 2015
1 parent ea20c5a commit 58f21a7
Show file tree
Hide file tree
Showing 4 changed files with 365 additions and 106 deletions.
2 changes: 1 addition & 1 deletion lib/sparql/algebra/operator/notin.rb
Expand Up @@ -6,7 +6,7 @@ class Operator
# Used for filters with more than one expression.
#
# @example
# (ask (filter (notin 2) (bgp)))
# (ask (filter (notin ?o 1 2) (bgp)))
#
# @see http://www.w3.org/TR/sparql11-query/#func-notin
class NotIn < Operator
Expand Down
20 changes: 18 additions & 2 deletions lib/sparql/algebra/operator/notoneof.rb
Expand Up @@ -13,8 +13,12 @@ class NotOneOf < Operator
NAME = :notoneof

##
# XXX
#
# Equivalant to:
#
# (path (:x (noteoneof :p :q) :y))
# => (filter (notin ??p :p :q) (bgp (:x ??p :y)))
#
# @note all operands are terms, and not operators, so this can be done by filtering results usin
#
# @param [RDF::Queryable] queryable
# the graph or repository to query
Expand All @@ -30,6 +34,18 @@ class NotOneOf < Operator
def execute(queryable, options = {}, &block)
debug(options) {"NotOneOf #{operands.to_sse}"}
subject, object = options[:subject], options[:object]

v = RDF::Query::Variable.new
v.distinguished = false
bgp = RDF::Query.new do |q|
q.pattern [subject, v, object]
end
query = Filter.new(NotIn.new(v, *operands), bgp)
queryable.query(query, options.merge(depth: options[:depth].to_i + 1)) do |solution|
solution.bindings.delete(v.to_sym)
debug(options) {"(solution)-> #{solution.to_hash.to_sse}"}
block.call(solution)
end
end
end # NotOneOf
end # Operator
Expand Down
20 changes: 19 additions & 1 deletion lib/sparql/algebra/operator/reverse.rb
Expand Up @@ -13,7 +13,10 @@ class Reverse < Operator::Unary
NAME = :reverse

##
# XXX
# Equivliant to:
#
# (path (:a (reverse :p) :b))
# => (bgp (:b :p :a))
#
#
# @param [RDF::Queryable] queryable
Expand All @@ -30,6 +33,21 @@ class Reverse < Operator::Unary
def execute(queryable, options = {}, &block)
debug(options) {"Reverse #{operands.to_sse}"}
subject, object = options[:subject], options[:object]

# Solutions where predicate exists
query = if operand.is_a?(RDF::Term)
RDF::Query.new do |q|
q.pattern [object, operand, subject]
end
else
operand(0)
end
queryable.query(query, options.merge(
subject: object,
object: subject,
depth: options[:depth].to_i + 1
), &block)

end
end # Reverse
end # Operator
Expand Down

0 comments on commit 58f21a7

Please sign in to comment.