Class: RDF::N3::Algebra::Log::Implies

Inherits:
SPARQL::Algebra::Operator::Binary
  • Object
show all
Includes:
Builtin, SPARQL::Algebra::Query, SPARQL::Algebra::Update
Defined in:
lib/rdf/n3/algebra/log/implies.rb

Overview

Logical implication.

This is the relation between the antecedent (subject) and conclusion (object) of a rule. The application of a rule to a knowledge-base is as follows. For every substitution which, applied to the antecedent, gives a formula which is a subset of the knowledge-base, then the result of applying that same substitution to the conclusion may be added to the knowledge-base.

related: See log:conclusion.

Constant Summary collapse

NAME =
:logImplies
URI =
RDF::N3::Log.implies

Instance Attribute Summary

Attributes included from Enumerable

#existentials, #universals

Instance Method Summary collapse

Methods included from Builtin

#evaluate, #hash, #input_operand, #rank, #to_uri

Instance Method Details

#clear_solutionsObject

Clear out any cached solutions. This principaly is for log:conclusions



63
64
65
66
# File 'lib/rdf/n3/algebra/log/implies.rb', line 63

def clear_solutions
  super
  @solutions = nil
end

#each(solutions: RDF::Query::Solutions()) {|statement| ... } ⇒ Object

Yields statements from the object based on solutions determined from the subject. Each solution formed by querying ‘queryable` from the subject is used to create a graph, which must be a subgraph of `queryable`. If so, that solution is used to generate triples from the object formula which are yielded.

Yields:

  • (statement)

    each matching statement

Yield Parameters:

Yield Returns:

  • (void)

    ignored



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rdf/n3/algebra/log/implies.rb', line 75

def each(solutions: RDF::Query::Solutions(), &block)
  # Merge solutions in with those for the evaluation of this implication
  # Clear out solutions so they don't get remembered erroneously.
  solutions, @solutions = Array(@solutions), nil
  log_depth do
    super(solutions: RDF::Query::Solutions(RDF::Query::Solution.new), &block)

    solutions.each do |solution|
      log_info("(logImplies each) solution") {SXP::Generator.string solution.to_sxp_bin}
      object = operand(1).evaluate(solution.bindings, formulae: formulae)
      log_info("(logImplies each) object") {SXP::Generator.string object.to_sxp_bin}

      # Yield inferred statements
      log_depth do
        object.each(solutions: RDF::Query::Solutions(solution)) do |statement|
          log_debug(("(logImplies each) infer\s")) {statement.to_sxp}
          block.call(RDF::Statement.from(statement.to_quad, inferred: true))
        end
      end
    end
  end
end

#execute(queryable, solutions:, **options) ⇒ RDF::Solutions

Returns solutions from subject. Solutions are created by evaluating subject against ‘queryable`.

Solutions are kept within this instance, and used for conclusions. Note that the evaluated solutions do not affect that of the invoking formula, as the solution spaces are disjoint.

Parameters:

  • queryable (RDF::Queryable)

    the graph or repository to query

  • options (Hash{Symbol => Object})

    any additional keyword options

Options Hash (**options):

  • solutions (RDF::Query::Solutions)

    optional initial solutions for chained queries

Returns:

  • (RDF::Solutions)

    distinct solutions



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
# File 'lib/rdf/n3/algebra/log/implies.rb', line 28

def execute(queryable, solutions:, **options)
  @queryable = queryable
  @solutions = RDF::Query::Solutions(solutions.map do |solution|
    log_debug(NAME, "solution") {SXP::Generator.string(solution.to_sxp_bin)}
    subject = operand(0).evaluate(solution.bindings, formulae: formulae)
    object = operand(1).evaluate(solution.bindings, formulae: formulae)
    log_info(NAME,  "subject") {SXP::Generator.string(subject.to_sxp_bin)}
    log_info(NAME, "object") {SXP::Generator.string(object.to_sxp_bin)}

    # Nothing to do if variables aren't resolved.
    next unless subject && object

    solns = log_depth {subject.execute(queryable, solutions: RDF::Query::Solutions(solution), **options)}

    # Execute object as well (typically used for log:outputString)
    solns.each do |soln|
      log_depth {object.execute(queryable, solutions: RDF::Query::Solutions(soln), **options)}
    end

    # filter solutions where not all variables in antecedant are bound.
    vars = subject.universal_vars
    solns = RDF::Query::Solutions(solns.to_a.select do |soln|
      vars.all? {|v| soln.bound?(v)}
    end)
    solns
  end.flatten.compact.uniq)
  log_info(NAME) {SXP::Generator.string(@solutions.to_sxp_bin)}

  # Return original solutions, without bindings
  solutions
end

#graph_nameRDF::Resource

Graph name associated with this operation, using the name of the parent

Returns:

  • (RDF::Resource)


100
# File 'lib/rdf/n3/algebra/log/implies.rb', line 100

def graph_name; parent.graph_name; end