Class: ShEx::Algebra::TripleConstraint

Inherits:
Operator
  • Object
show all
Includes:
TripleExpression
Defined in:
lib/shex/algebra/triple_constraint.rb

Constant Summary collapse

NAME =
:tripleConstraint

Constants inherited from Operator

Operator::ARITY

Instance Attribute Summary

Attributes inherited from Operator

#id, #logger, #operands, #options, #schema

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TripleExpression

#maximum, #minimum, #triple_expression?, #validate_expressions!

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

Class Method Details

.from_shexj(operator, **options) ⇒ Operator

Creates an operator instance from a parsed ShExJ representation

Returns:

Raises:

  • (ArgumentError)


11
12
13
14
15
# File 'lib/shex/algebra/triple_constraint.rb', line 11

def self.from_shexj(operator, **options)
  raise ArgumentError unless operator.is_a?(Hash) && operator['type'] == 'TripleConstraint'
  raise ArgumentError unless operator.has_key?('predicate')
  super
end

Instance Method Details

#inverse?Boolean

Returns:

  • (Boolean)


112
113
114
# File 'lib/shex/algebra/triple_constraint.rb', line 112

def inverse?
  operands.include?(:inverse)
end

#matches(arcs_in, arcs_out, depth: 0) ⇒ TripleExpression

In this case, we accept an array of statements, and match based on cardinality.

Parameters:

  • arcs_in (Array<RDF::Statement>)
  • arcs_out (Array<RDF::Statement>)

Returns:

Raises:

  • (ShEx::NotMatched)

    with expression accessor to access matched and unmatched statements along with satisfied and unsatisfied operations.



23
24
25
26
27
28
29
30
31
32
33
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
# File 'lib/shex/algebra/triple_constraint.rb', line 23

def matches(arcs_in, arcs_out, depth: 0)
  status "predicate #{predicate}", depth: depth
  results, unmatched, satisfied, unsatisfied = [], [], [], []
  num_iters, max = 0, maximum

  statements = inverse? ? arcs_in : arcs_out
  statements.select {|st| st.predicate == predicate}.each do |statement|
    break if num_iters == max # matched enough

    focus = inverse? ? statement.subject : statement.object

    begin
      matched_shape = if expression.is_a?(RDF::Resource)
        schema.enter_shape(expression, focus) do |shape|
          if shape
            shape.satisfies?(focus, depth: depth + 1)
          else
            status "Satisfy as #{expression} was re-entered for #{focus}", depth: depth
            nil
          end
        end
      elsif expression
        expression.satisfies?(focus, depth: depth + 1)
      end
      status "matched #{statement.to_sxp}", depth: depth
      if matched_shape
        matched_shape.matched = [statement]
        statement = statement.dup.extend(ReferencedStatement)
        statement.referenced = matched_shape
        satisfied << matched_shape
      end
      results << statement
      num_iters += 1
    rescue ShEx::NotSatisfied => e
      status "not satisfied: #{e.message}", depth: depth
      unsatisfied << e.expression
      statement = statement.dup.extend(ReferencedStatement)
      statement.referenced = expression
      unmatched << statement
    end
  end

  # Max violations handled in Shape
  if results.length < minimum
    raise ShEx::NotMatched, "Minimum Cardinality Violation: #{results.length} < #{minimum}"
  end

  # Last, evaluate semantic acts
  semantic_actions.each do |op|
    op.satisfies?(results, matched: results, depth: depth + 1)
  end unless results.empty?

  satisfy matched:   results,   unmatched:   unmatched,
          satisfied: satisfied, unsatisfied: unsatisfied, depth: depth
rescue ShEx::NotMatched, ShEx::NotSatisfied => e
  not_matched e.message,
              matched:   results,   unmatched:   unmatched,
              satisfied: satisfied, unsatisfied: unsatisfied, depth: depth
end

#predicateObject



83
84
85
# File 'lib/shex/algebra/triple_constraint.rb', line 83

def predicate
  @predicate ||= operands.detect {|o| o.is_a?(Array) && o.first == :predicate}.last
end

#triple_constraintsArray<TripleConstraints>

Included TripleConstraints

Returns:

  • (Array<TripleConstraints>)


108
109
110
# File 'lib/shex/algebra/triple_constraint.rb', line 108

def triple_constraints
  [self]
end

#validate!Operator

expression must be a ShapeExpression

Returns:

Raises:



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/shex/algebra/triple_constraint.rb', line 92

def validate!
  case expression
  when nil, ShapeExpression
  when RDF::Resource
    ref = schema.find(expression)
    ref.is_a?(ShapeExpression) ||
    structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
  else
    structure_error("#{json_type} must be a ShapeExpression or reference: #{expresson.to_sxp}")
  end
  super
end