Module: RDF::Queryable

Defined in:
lib/sparql/algebra/extensions.rb,
lib/sparql/extensions.rb

Overview

Extensions for RDF::Queryable

Instance Method Summary collapse

Instance Method Details

#concise_bounded_description(*terms, **options, &block) ⇒ RDF::Graph

Concise Bounded Description

Given a particular node (the starting node) in a particular RDF graph (the source graph), a subgraph of that particular graph, taken to comprise a concise bounded description of the resource denoted by the starting node, can be identified as follows:

  1. Include in the subgraph all statements in the source graph where the subject of the statement is the starting node;

  2. Recursively, for all statements identified in the subgraph thus far having a blank node object, include in the subgraph all statements in the source graph where the subject of the statement is the blank node in question and which are not already included in the subgraph.

  3. Recursively, for all statements included in the subgraph thus far, for all reifications of each statement in the source graph, include the concise bounded description beginning from the rdf:Statement node of each reification. (we skip this step)

This results in a subgraph where the object nodes are either URI references, literals, or blank nodes not serving as the subject of any statement in the graph.

Used to implement the SPARQL DESCRIBE operator.

Parameters:

Options Hash (**options):

  • :non_subjects (Boolean) — default: false

    If term is not a subject within self then add all subjects referencing the term as a predicate or object.

  • graph (RDF::Graph)

    Graph containing statements already considered.

Yields:

  • (statement)

Yield Parameters:

Yield Returns:

  • (void)

    ignored

Returns:

  • (RDF::Graph)

See Also:



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
# File 'lib/sparql/extensions.rb', line 43

def concise_bounded_description(*terms, **options, &block)
  graph = options[:graph] || RDF::Graph.new

  if options[:non_subjects]
    query_terms = terms.dup

    # Find terms not in self as a subject and recurse with their subjects
    terms.reject {|term| self.first({subject: term})}.each do |term|
      self.query({predicate: term}) do |statement|
        query_terms << statement.subject
      end

      self.query({object: term}) do |statement|
        query_terms << statement.subject
      end
    end
    
    terms = query_terms.uniq
  end

  # Don't consider term if already in graph
  terms.reject {|term| graph.first({subject: term})}.each do |term|
    # Find statements from queryiable with term as a subject
    self.query({subject: term}) do |statement|
      yield(statement) if block_given?
      graph << statement
      
      # Include reifications of this statement
      RDF::Query.new({
        s: {
          RDF.type => RDF["Statement"],
          RDF.subject => statement.subject,
          RDF.predicate => statement.predicate,
          RDF.object => statement.object,
        }
      }, **{}).execute(self).each do |solution|
        # Recurse to include this subject
        recurse_opts = options.merge(non_subjects: false, graph: graph)
        self.concise_bounded_description(solution[:s], **recurse_opts, &block)
      end

      # Recurse if object is a BNode and it is not already in subjects
      if statement.object.node?
        recurse_opts = options.merge(non_subjects: false, graph: graph)
        self.concise_bounded_description(statement.object, **recurse_opts, &block)
      end
    end
  end
  
  graph
end

#query(pattern, **options) {|statement| ... } ⇒ Enumerator

Queries self for RDF statements matching the given pattern.

Monkey patch to RDF::Queryable#query to execute a SPARQL::Algebra::Operator in addition to an RDF::Query object.

Examples:

queryable.query([nil, RDF::DOAP.developer, nil])
queryable.query({predicate: RDF::DOAP.developer})

op = SPARQL::Algebra::Expression.parse(%q((bgp (triple ?a doap:developer ?b))))
queryable.query(op)

Parameters:

Yields:

  • (statement)

    each matching statement

Yield Parameters:

Yield Returns:

  • (void)

    ignored

Returns:

  • (Enumerator)

Raises:

  • (TypeError)

See Also:

  • #query_pattern


320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/sparql/algebra/extensions.rb', line 320

def query(pattern, **options, &block)
  raise TypeError, "#{self} is not queryable" if respond_to?(:queryable?) && !queryable?

  if pattern.is_a?(SPARQL::Algebra::Operator) && pattern.respond_to?(:execute)
    before_query(pattern) if respond_to?(:before_query)
    solutions = if method(:query_execute).arity == 1
      query_execute(pattern, &block)
    else
      query_execute(pattern, **options, &block)
    end
    after_query(pattern) if respond_to?(:after_query)

    if !pattern.respond_to?(:query_yeilds_solutions?) || pattern.query_yields_solutions?
      # Just return solutions
      solutions
    else
      # Return an enumerator
      enum_for(:query, pattern, **options)
    end
  else
    query_without_sparql(pattern, **options, &block)
  end
end

#query_without_sparqlObject



299
# File 'lib/sparql/algebra/extensions.rb', line 299

alias_method :query_without_sparql, :query

#to_sparql(**options) ⇒ String

Returns a partial SPARQL grammar for this term.

Returns:

  • (String)

Raises:

  • (NotImplementedError)


349
350
351
# File 'lib/sparql/algebra/extensions.rb', line 349

def to_sparql(**options)
  raise NotImplementedError, "SPARQL::Algebra '#{first}' operator not implemented"
end