Class: ShEx::Algebra::Shape
- Includes:
- ShapeExpression
- Defined in:
- lib/shex/algebra/shape.rb
Constant Summary collapse
- NAME =
:shape
Constants inherited from Operator
Instance Attribute Summary collapse
-
#matchables ⇒ Array<RDF::Statement>
Let
matchablesbe the triples inoutswhose predicate appears in a TripleConstraint inexpression. -
#outs ⇒ Array<RDF::Statement>
Let
outsbe thearcsOutinremainder:outs = remainder ∩ arcsOut(G, n). -
#unmatchables ⇒ Array<RDF::Statement>
Let
unmatchablesbe the triples inoutswhich are not inmatchables.
Attributes inherited from Operator
#id, #logger, #operands, #options, #schema
Class Method Summary collapse
-
.from_shexj(operator, **options) ⇒ Operator
Creates an operator instance from a parsed ShExJ representation.
Instance Method Summary collapse
-
#satisfies?(focus, depth: 0) ⇒ Boolean, ShapeExpression
The
satisfiessemantics for aShapedepend on a matches function defined below. -
#validate! ⇒ Operator
expression must be a TripleExpression and must not reference itself recursively.
Methods included from ShapeExpression
#validate_expressions!, #validate_self_references!
Methods inherited from Operator
#base_uri, #closed?, #dup, #each_descendant, #eql?, #expression, #expressions, #find, #focus, #focus=, #initialize, #inspect, #iri, iri, #json_type, #matched, #matched=, #message, #message=, #not_matched, #not_satisfied, #operand, #parent, #parent=, #references, #satisfied, #satisfied=, #satisfy, #semact?, #semantic_actions, #serialize_value, #status, #structure_error, #to_h, #to_json, #to_sxp, #to_sxp_bin, #triple_expression?, #unmatched, #unmatched=, #unsatisfied, #unsatisfied=, #value, value
Constructor Details
This class inherits a constructor from ShEx::Algebra::Operator
Instance Attribute Details
#matchables ⇒ Array<RDF::Statement>
Let matchables be the triples in outs whose predicate appears in a TripleConstraint in expression. If expression is absent, matchables = Ø (the empty set).
15 16 17 |
# File 'lib/shex/algebra/shape.rb', line 15 def matchables @matchables end |
#outs ⇒ Array<RDF::Statement>
Let outs be the arcsOut in remainder: outs = remainder ∩ arcsOut(G, n).
10 11 12 |
# File 'lib/shex/algebra/shape.rb', line 10 def outs @outs end |
#unmatchables ⇒ Array<RDF::Statement>
Let unmatchables be the triples in outs which are not in matchables. matchables ∪ unmatchables = outs.
20 21 22 |
# File 'lib/shex/algebra/shape.rb', line 20 def unmatchables @unmatchables end |
Class Method Details
.from_shexj(operator, **options) ⇒ Operator
Creates an operator instance from a parsed ShExJ representation
26 27 28 29 |
# File 'lib/shex/algebra/shape.rb', line 26 def self.from_shexj(operator, **) raise ArgumentError unless operator.is_a?(Hash) && operator['type'] == "Shape" super end |
Instance Method Details
#satisfies?(focus, depth: 0) ⇒ Boolean, ShapeExpression
The satisfies semantics for a Shape depend on a matches function defined below. For a node n, shape S, graph G, and shapeMap m, satisfies(n, S, G, m).
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 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/shex/algebra/shape.rb', line 35 def satisfies?(focus, depth: 0) # neigh(G, n) is the neighbourhood of the node n in the graph G. # # neigh(G, n) = arcsOut(G, n) ∪ arcsIn(G, n) arcs_in = schema.graph.query({object: focus}).to_a.sort_by(&:to_sxp) arcs_out = schema.graph.query({subject: focus}).to_a.sort_by(&:to_sxp) neigh = (arcs_in + arcs_out).uniq # `matched` is the subset of statements which match `expression`. status("arcsIn: #{arcs_in.count}, arcsOut: #{arcs_out.count}", depth: depth) matched_expression = case expression when RDF::Resource ref.matches(arcs_in, arcs_out, depth: depth + 1) when TripleExpression expression.matches(arcs_in, arcs_out, depth: depth + 1) end matched = Array(matched_expression && matched_expression.matched) # `remainder` is the set of unmatched statements remainder = neigh - matched # Let `outs` be the `arcsOut` in `remainder`: `outs = remainder ∩ arcsOut(G, n)`. @outs = remainder.select {|s| s.subject == focus} # Let `matchables` be the triples in `outs` whose predicate appears in a `TripleConstraint` in `expression`. If `expression` is absent, `matchables = Ø` (the empty set). predicates = expression ? expression.triple_constraints.map(&:predicate).uniq : [] @matchables = outs.select {|s| predicates.include?(s.predicate)} # Let `unmatchables` be the triples in `outs` which are not in `matchables`. @unmatchables = outs - matchables # No matchable can be matched by any TripleConstraint in expression unmatched = matchables.select do |statement| expression.triple_constraints.any? do |expr| begin statement.predicate == expr.predicate && expr.matches([], [statement], depth: depth + 1) rescue ShEx::NotMatched false # Expected not to match end end if expression end unless unmatched.empty? not_satisfied "Statements remain matching TripleConstraints", matched: matched, unmatched: unmatched, satisfied: expression, depth: depth end # There is no triple in matchables whose predicate does not appear in extra. unmatched = matchables.reject {|st| extra.include?(st.predicate)} unless unmatched.empty? not_satisfied "Statements remains with predicate #{unmatched.map(&:predicate).compact.join(',')} not in extra", matched: matched, unmatched: unmatched, satisfied: expression, depth: depth end # closed is false or unmatchables is empty. not_satisfied "Unmatchables remain on a closed shape", depth: depth unless !closed? || unmatchables.empty? # Presumably, to be satisfied, there must be some triples in matches semantic_actions.each do |op| op.satisfies?(matched, matched: matched, depth: depth + 1) end unless matched.empty? # FIXME: also record matchables, outs and others? satisfy focus: focus, matched: matched, depth: depth rescue ShEx::NotMatched => e not_satisfied e., focus: focus, unsatisfied: e.expression, depth: depth end |
#validate! ⇒ Operator
expression must be a TripleExpression and must not reference itself recursively.
113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/shex/algebra/shape.rb', line 113 def validate! case expression when nil, TripleExpression when RDF::Resource ref = schema.find(expression) ref.is_a?(TripleExpression) || structure_error("#{json_type} must reference a TripleExpression: #{ref}") else structure_error("#{json_type} must be a TripleExpression or reference: #{expression.to_sxp}") end # FIXME: this runs afoul of otherwise legitamate self-references, through a TripleExpression. #!validate_self_references! super end |