Class: RDF::N3::Reasoner
- Inherits:
-
Object
- Object
- RDF::N3::Reasoner
- Includes:
- Enumerable, Mutable, Util::Logger
- Defined in:
- lib/rdf/n3/reasoner.rb
Overview
A Notation-3/Turtle reasoner in Ruby
Takes either a parsed formula or an ‘RDF::Queryable` and updates it by reasoning over formula defined within the queryable.
Instance Attribute Summary collapse
-
#formula ⇒ RDF::N3::Algebra::Formula
readonly
Returns the top-level formula for this file.
Attributes included from Enumerable
Class Method Summary collapse
-
.open(file) {|reasoner| ... } ⇒ RDF::N3::Reasoner
Opens a Notation-3 file, and parses it to initialize the reasoner.
Instance Method Summary collapse
-
#conclusions {|statement| ... } ⇒ RDF::Enumerator
(also: #each_conclusion)
Yields conclusions, excluding formulae and those statements in the original dataset, or returns an enumerator over the conclusions.
-
#data {|statement| ... } ⇒ RDF::Enumerator
(also: #each_datum)
Yields data, excluding formulae or variables and statements referencing formulae or variables.
-
#dup ⇒ Object
Returns a copy of this reasoner.
-
#each(&block) ⇒ Object
Yields each statement in the datastore.
-
#enum_conclusions ⇒ Enumerator<RDF::Statement>
Returns an enumerator for #conclusions.
-
#enum_data ⇒ Enumerator<RDF::Statement>
Returns an enumerator for #data.
-
#execute(**options) {|statement| ... } ⇒ RDF::N3::Reasoner
(also: #reason!)
Updates the datastore by reasoning over the formula, optionally yielding each conclusion; uses triples from the graph associated with this formula as the dataset over which to reason.
-
#initialize(input, **options) {|reasoner| ... } ⇒ RDF::N3::Reasoner
constructor
Initializes a new reasoner.
-
#insert_statement(statement) ⇒ void
Inserts an RDF statement the datastore, resets ‘formula`.
-
#reason(**options, &block) ⇒ Object
Reason with results in a duplicate datastore.
-
#strings ⇒ String
Returns the concatenated strings from log:outputString.
-
#to_sxp_bin ⇒ Array
Returns the SPARQL S-Expression (SSE) representation of the parsed formula.
Constructor Details
#initialize(input, **options) {|reasoner| ... } ⇒ RDF::N3::Reasoner
Initializes a new reasoner. If input is an IO or string, it is taken as n3 source and parsed first. Otherwise, it is a parsed formula.
It returns the evaluated formula, or yields triples.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/rdf/n3/reasoner.rb', line 62 def initialize(input, **, &block) @options = .merge(strings: {}) # for --strings and log:outputString @mutable = case input when RDF::Mutable then input when RDF::Enumerable then RDF::N3::Repository.new {|r| r << input} else RDF::N3::Repository.new end @formula = input if input.is_a?(RDF::N3::Algebra::Formula) log_debug("reasoner: expression") {SXP::Generator.string(formula.to_sxp_bin)} if block_given? case block.arity when 0 then instance_eval(&block) else block.call(self) end end end |
Instance Attribute Details
#formula ⇒ RDF::N3::Algebra::Formula (readonly)
Returns the top-level formula for this file.
Transforms an RDF dataset into a recursive formula structure.
16 17 18 |
# File 'lib/rdf/n3/reasoner.rb', line 16 def formula @formula end |
Class Method Details
Instance Method Details
#conclusions {|statement| ... } ⇒ void #conclusions ⇒ Enumerator<RDF::Statement> Also known as: each_conclusion
Yields conclusions, excluding formulae and those statements in the original dataset, or returns an enumerator over the conclusions
226 227 228 229 230 231 232 |
# File 'lib/rdf/n3/reasoner.rb', line 226 def conclusions(&block) if block_given? # Invoke {#each} in the containing class: each_statement {|s| block.call(s) if s.inferred?} end enum_conclusions end |
#data {|statement| ... } ⇒ void #data ⇒ Enumerator<RDF::Statement> Also known as: each_datum
Yields data, excluding formulae or variables and statements referencing formulae or variables
184 185 186 187 188 189 190 191 192 193 |
# File 'lib/rdf/n3/reasoner.rb', line 184 def data(&block) if block_given? project_graph(nil) do |statement| block.call(statement) unless statement.variable? || has_graph?(statement.subject) || has_graph?(statement.object) end end enum_data end |
#dup ⇒ Object
Returns a copy of this reasoner
84 85 86 87 88 89 90 |
# File 'lib/rdf/n3/reasoner.rb', line 84 def dup repo = RDF::N3::Repository.new {|r| r << @mutable} self.class.new(repo) do |reasoner| reasoner.instance_variable_set(:@options, @options.dup) reasoner.instance_variable_set(:@formula, @formula.dup) if @formula end end |
#each(&block) ⇒ Object
Yields each statement in the datastore
@yieldparam [RDF::Statement] statement
@yieldreturn [void] ignored
@return [void]
165 166 167 |
# File 'lib/rdf/n3/reasoner.rb', line 165 def each(&block) @mutable.each(&block) end |
#enum_conclusions ⇒ Enumerator<RDF::Statement>
Returns an enumerator for #conclusions. FIXME: enum_for doesn’t seem to be working properly in JRuby 1.7, so specs are marked pending
242 243 244 245 246 247 248 |
# File 'lib/rdf/n3/reasoner.rb', line 242 def enum_conclusions # Ensure that statements are queryable, countable and enumerable this = self RDF::Queryable::Enumerator.new do |yielder| this.send(:each_conclusion) {|y| yielder << y} end end |
#enum_data ⇒ Enumerator<RDF::Statement>
Returns an enumerator for #data. FIXME: enum_for doesn’t seem to be working properly in JRuby 1.7, so specs are marked pending
203 204 205 206 207 208 209 |
# File 'lib/rdf/n3/reasoner.rb', line 203 def enum_data # Ensure that statements are queryable, countable and enumerable this = self RDF::Queryable::Enumerator.new do |yielder| this.send(:each_datum) {|y| yielder << y} end end |
#execute(**options) {|statement| ... } ⇒ RDF::N3::Reasoner Also known as: reason!
Updates the datastore by reasoning over the formula, optionally yielding each conclusion; uses triples from the graph associated with this formula as the dataset over which to reason.
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/rdf/n3/reasoner.rb', line 112 def execute(**, &block) @options[:logger] = [:logger] if .has_key?(:logger) # The knowledge base is the non-variable portions of formula knowledge_base = RDF::N3::Repository.new {|r| r << formula} log_debug("reasoner: knowledge_base") {SXP::Generator.string(knowledge_base.statements.to_sxp_bin)} # If thinking, continuously execute until results stop growing count = -1 log_info("reasoner: start") { "count: #{count}"} solutions = RDF::Query::Solutions(RDF::Query::Solution.new) while knowledge_base.count > count log_info("reasoner: do") { "count: #{count}"} count = knowledge_base.count log_depth {formula.execute(knowledge_base, solutions: solutions, **)} knowledge_base << formula solutions = RDF::Query::Solutions(RDF::Query::Solution.new) if solutions.empty? log_debug("reasoner: solutions") {SXP::Generator.string solutions.to_sxp_bin} log_debug("reasoner: datastore") {SXP::Generator.string knowledge_base.statements.to_sxp_bin} log_info("reasoner: inferred") {SXP::Generator.string knowledge_base.statements.select(&:inferred?).to_sxp_bin} log_info("reasoner: formula") do SXP::Generator.string RDF::N3::Algebra::Formula.from_enumerable(knowledge_base).to_sxp_bin end @formula = nil # cause formula to be re-calculated from knowledge-base unless [:think] count = knowledge_base.count break end end log_info("reasoner: end") { "count: #{count}"} # Add updates back to mutable, containg builtins and variables. @mutable << knowledge_base each(&block) if block_given? self end |
#insert_statement(statement) ⇒ void
This method returns an undefined value.
Inserts an RDF statement the datastore, resets ‘formula`.
97 98 99 100 |
# File 'lib/rdf/n3/reasoner.rb', line 97 def insert_statement(statement) @formula = nil @mutable.insert_statement(statement) end |
#reason(**options, &block) ⇒ Object
Reason with results in a duplicate datastore
155 156 157 |
# File 'lib/rdf/n3/reasoner.rb', line 155 def reason(**, &block) self.dup.reason!(**, &block) end |
#strings ⇒ String
Returns the concatenated strings from log:outputString
254 255 256 257 258 259 |
# File 'lib/rdf/n3/reasoner.rb', line 254 def strings @options[:strings]. sort_by {|k, v| k}. map {|(k,v)| v.join("")}. join("") end |
#to_sxp_bin ⇒ Array
Returns the SPARQL S-Expression (SSE) representation of the parsed formula. Formulae are represented as subjects and objects in the containing graph, along with their universals and existentials
277 278 279 |
# File 'lib/rdf/n3/reasoner.rb', line 277 def to_sxp_bin formula.to_sxp_bin end |