lib/shex/algebra/each_of.rb in shex-0.2.0 vs lib/shex/algebra/each_of.rb in shex-0.3.0
- old
+ new
@@ -3,59 +3,72 @@
class EachOf < Operator
include TripleExpression
NAME = :eachOf
##
+ # Creates an operator instance from a parsed ShExJ representation
+ # @param (see Operator#from_shexj)
+ # @return [Operator]
+ def self.from_shexj(operator, options = {})
+ raise ArgumentError unless operator.is_a?(Hash) && operator['type'] == 'EachOf'
+ raise ArgumentError, "missing expressions in #{operator.inspect}" unless operator.has_key?('expressions')
+ super
+ end
+
+ ##
# expr is an EachOf and there is some partition of T into T1, T2,… such that for every expression expr1, expr2,… in shapeExprs, matches(Tn, exprn, m)...
#
- # @param [Array<RDF::Statement>] statements
- # @return [Array<RDF::Statement>]
- # @raise [ShEx::NotMatched]
- def matches(statements)
- status ""
+ # @param (see TripleExpression#matches)
+ # @return (see TripleExpression#matches)
+ # @raise (see TripleExpression#matches)
+ def matches(arcs_in, arcs_out, depth: 0)
+ status "", depth: depth
results, satisfied, unsatisfied = [], [], []
num_iters, max = 0, maximum
+ # enter semantic acts
+ semantic_actions.each {|op| op.enter(arcs_in: arcs_in, arcs_out: arcs_out, depth: depth + 1)}
+
while num_iters < max
begin
matched_this_iter = []
operands.select {|o| o.is_a?(TripleExpression)}.all? do |op|
begin
- matched_op = op.matches(statements - matched_this_iter)
+ matched_op = op.matches(arcs_in - matched_this_iter, arcs_out - matched_this_iter, depth: depth + 1)
satisfied << matched_op
matched_this_iter += matched_op.matched
rescue ShEx::NotMatched => e
- status "not matched: #{e.message}"
- op = op.dup
- op.unmatched = statements - matched_this_iter
- unsatisfied << op
+ status "not matched: #{e.message}", depth: depth
+ unsatisfied << e.expression
raise
end
end
results += matched_this_iter
- statements -= matched_this_iter
+ arcs_in -= matched_this_iter
+ arcs_out -= matched_this_iter
num_iters += 1
- status "matched #{results.length} statements after #{num_iters} iterations"
+ status "matched #{results.length} statements after #{num_iters} iterations", depth: depth
rescue ShEx::NotMatched => e
- status "no match after #{num_iters} iterations (ignored)"
+ status "no match after #{num_iters} iterations (ignored)", depth: depth
break
end
end
# Max violations handled in Shape
if num_iters < minimum
raise ShEx::NotMatched, "Minimum Cardinality Violation: #{results.length} < #{minimum}"
end
# Last, evaluate semantic acts
- semantic_actions.all? do |op|
- op.satisfies?(results)
- end unless results.empty?
+ semantic_actions.each {|op| op.satisfies?(nil, matched: results, depth: depth + 1)}
- satisfy matched: results, satisfied: satisfied
+ satisfy matched: results, satisfied: satisfied, depth: depth
rescue ShEx::NotMatched, ShEx::NotSatisfied => e
not_matched e.message,
- matched: results, unmatched: (statements - results),
- satisfied: satisfied, unsatisfied: unsatisfied
+ matched: results, unmatched: ((arcs_in + arcs_out).uniq - results),
+ satisfied: satisfied, unsatisfied: unsatisfied,
+ depth: depth
+ ensure
+ semantic_actions.each {|op| op.exit(matched: matched, depth: depth + 1)}
end
end
end