Class: RuleBase::Rule
- Inherits:
-
Object
- Object
- RuleBase::Rule
- Defined in:
- lib/activerdf_rules/rule_base.rb
Overview
A rule for adding information to an ActiveRDF store. A rule consists of a set of conditions and a single conclusion. Each condition consists of a triple (with variables) that is matched against the database. When all of the conditions are satisfied, then the conclusion is introduced into the database substituting for any variables that may appear in the conclusion.
Variables are simply ruby symbols and they can be used within both the conditions and the conclusion with the following caveat: any variable that appears in the conclusion must also appear in at least one condition.
Example:
r = RuleBase::Rule.new
r.condition :x, :y, :z
r.conclusion :z, :y, :x
Instance Attribute Summary collapse
-
#conditions ⇒ Object
readonly
Returns the value of attribute conditions.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Instance Method Summary collapse
-
#conclusion(s, p, o) ⇒ Object
Sets the conclusion of the rule where s, p, and o are the subject, predicate, and object (respectively).
-
#condition(s, p, o) ⇒ Object
Adds a condition to the rule where s, p, and o are the subject, predicate, and object (respectively).
-
#initialize(name) ⇒ Rule
constructor
A new instance of Rule.
-
#instantiate(var, row, lookup) ⇒ Object
Returns either the value for
var
by usinglookup
, the value ofrow
, if the query resulted in a single value, or the value ofvar
since in this case it must be either anRDFS::Resource
or a literal. -
#process ⇒ Object
Processes this rule by converting it to a query, if the query is successful, then the conclusion is introduced into the data store after substituting for any variables.
-
#to_s ⇒ Object
Returns the name of this rule.
-
#validate ⇒ Object
Checks that every variable in the conclusion also appears in at least on condition.
Constructor Details
#initialize(name) ⇒ Rule
Returns a new instance of Rule.
99 100 101 102 103 |
# File 'lib/activerdf_rules/rule_base.rb', line 99 def initialize(name) @name = name @conditions = [] @conclusion = nil end |
Instance Attribute Details
#conditions ⇒ Object (readonly)
Returns the value of attribute conditions.
97 98 99 |
# File 'lib/activerdf_rules/rule_base.rb', line 97 def conditions @conditions end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
97 98 99 |
# File 'lib/activerdf_rules/rule_base.rb', line 97 def name @name end |
Instance Method Details
#conclusion(s, p, o) ⇒ Object
Sets the conclusion of the rule where s, p, and o are the subject, predicate, and object (respectively).
117 118 119 120 121 122 123 124 |
# File 'lib/activerdf_rules/rule_base.rb', line 117 def conclusion(s, p, o) raise "Conclusion already set" unless @conclusion.nil? raise "Conclusion subject #{s} must be a Symbol or an RDFS::Resource" unless [Symbol, RDFS::Resource].include?(s.class) raise "Conclusion subject #{p} must be a Symbol or an RDFS::Resource" unless [Symbol, RDFS::Resource].include?(p.class) c = [s, p, o] @conclusion = c $activerdflog.debug("Setting conclusion #{c.inspect} for '#{self}'") end |
#condition(s, p, o) ⇒ Object
Adds a condition to the rule where s, p, and o are the subject, predicate, and object (respectively).
107 108 109 110 111 112 113 |
# File 'lib/activerdf_rules/rule_base.rb', line 107 def condition(s, p, o) raise "Condition subject #{s} must be a Symbol or an RDFS::Resource" unless [Symbol, RDFS::Resource].include?(s.class) raise "Condition subject #{p} must be a Symbol or an RDFS::Resource" unless [Symbol, RDFS::Resource].include?(p.class) c = [s, p, o] @conditions << c $activerdflog.debug("Adding condition #{c.inspect} to '#{self}'") end |
#instantiate(var, row, lookup) ⇒ Object
Returns either the value for var
by using lookup
, the value of row
, if the query resulted in a single value, or the value of var
since in this case it must be either an RDFS::Resource
or a literal.
183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/activerdf_rules/rule_base.rb', line 183 def instantiate(var, row, lookup) if var.is_a?(Symbol) if lookup.size == 1 && !row.is_a?(Array) row else row[lookup.index(var)] end else var end end |
#process ⇒ Object
Processes this rule by converting it to a query, if the query is successful, then the conclusion is introduced into the data store after substituting for any variables.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/activerdf_rules/rule_base.rb', line 146 def process $activerdflog.debug("processing '#{self}'") q = Query.new lookup = @conclusion.select{|c| c.is_a?(Symbol)}.uniq q.select(*lookup) @conditions.each do |c| q.where(*c) end change = false q.execute.each do |row| triple = nil begin triple = @conclusion.collect {|t| instantiate(t, row, lookup) } old = ConnectionPool.write_adapter.size $activerdflog.debug("concluding #{triple.inspect}") ConnectionPool.write_adapter.add(*triple) # TODO HACK This should be changed # What I should be able to do is something like below, but the below is # broken for redland, and the above condition query is broken in # rdflite (because of ambiguous column names). For now this works. # Query.new.ask.where(*triple).execute if old < ConnectionPool.write_adapter.size change = true end rescue => e $activerdflog.debug("could not add #{triple.inspect} because of #{e}") end end change end |
#to_s ⇒ Object
Returns the name of this rule
196 197 198 |
# File 'lib/activerdf_rules/rule_base.rb', line 196 def to_s @name end |
#validate ⇒ Object
Checks that every variable in the conclusion also appears in at least on condition. If this condition is not satisfied, then an exception is thrown.
129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/activerdf_rules/rule_base.rb', line 129 def validate # for each conclusion variable verify that it appears in one of the conditions @conclusion.each do |x| if x.is_a?(Symbol) catch(:done) do @conditions.each do |c| throw :done if c.include?(x) end raise "Unbound variable :#{x} in conclusion" end end end end |