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
matchables
be the triples inouts
whose predicate appears in a TripleConstraint inexpression
. -
#outs ⇒ Array<RDF::Statement>
Let
outs
be thearcsOut
inremainder
:outs = remainder ∩ arcsOut(G, n)
. -
#unmatchables ⇒ Array<RDF::Statement>
Let
unmatchables
be the triples inouts
which 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
satisfies
semantics for aShape
depend 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 |