Class: RuleEngine

Inherits:
Object
  • Object
show all
Defined in:
lib/activerdf_rules/rule_engine.rb

Overview

A RuleEngine will use a collection of RuleBases to add new data to an ActiveRDF data store by processing the rules.

Constant Summary collapse

RDFSRuleBase =

A rule base including rules for RDFS reasoning.

RuleBase.new('RDFSRuleBase') {
  type = Namespace.lookup(:rdf, 'type')
  rdfclass = Namespace.lookup(:rdfs, 'Class')
  subClassOf = Namespace.lookup(:rdfs, 'subClassOf')
  property = Namespace.lookup(:rdf, 'Property')
  subPropertyOf = Namespace.lookup(:rdfs, 'subPropertyOf')
  range = Namespace.lookup(:rdfs, 'range')
  domain = Namespace.lookup(:rdfs, 'domain')
  resource = Namespace.lookup(:rdfs, 'Resource')
  container = Namespace.lookup(:rdfs, 'ContainerMembershipProperty')
  member = Namespace.lookup(:rdfs, 'member')
  datatype = Namespace.lookup(:rdfs, 'Datatype')
  literal = Namespace.lookup(:rdfs, 'Literal')
  
  # The following reasoning rules were taken from the RDF Semantics document
  # http://www.w3.org/TR/rdf-mt/#RDFRules
  # http://www.w3.org/TR/rdf-mt/#RDFSRules
  
  rule "rdf1" do
    condition :s, :p, :o
    
    conclusion :p, type, property
  end
  
  rule 'rdfs2' do
    condition :teaches, domain, :Teacher
    condition :Bob, :teaches, :Scooter
    
    conclusion :Bob, type, :Teacher
  end
  
  rule 'rdfs3' do
    condition :teaches, range, :Student
    condition :Bob, :teaches, :Scooter
    
    conclusion :Scooter, type, :Student
  end
  
  rule 'rdfs4a' do
    condition :s, :p, :o
    
    conclusion :s, type, resource
  end
  
  rule 'rdfs4b' do
    condition :s, :p, :o
    
    conclusion :o, type, resource
  end
  
  rule 'rdfs5' do
    condition :parent, subPropertyOf, :ancestor
    condition :ancestor, subPropertyOf, :relative
    
    conclusion :parent, subPropertyOf, :relative
  end
  
  rule 'rdfs6' do
    condition :p, type, property
    
    conclusion :p, subPropertyOf, :p
  end
  
  rule 'rdfs7' do
    condition :parent, subPropertyOf, :ancestor
    condition :Paul, :parent, :Lester
    
    conclusion :Paul, :ancestor, :Lester
  end
  
  rule 'rdfs8' do
    condition :c, type, rdfclass
    
    conclusion :c, subClassOf, resource
  end
  
  rule 'rdfs9' do
    condition :Morris, type, :Cat
    condition :Cat, subClassOf, :Mammal
    
    conclusion :Morris, type, :Mammal
  end
  
  rule 'rdfs10' do
    condition :p, type, rdfclass
    
    conclusion :p, subClassOf, :p
  end
  
  rule 'rdfs11' do
    condition :Dog, subClassOf, :Mammal
    condition :Mammal, subClassOf, :Animal
    
    conclusion :Dog, subClassOf, :Animal
  end
  
  rule 'rdfs12' do
    condition :p, type, container
    
    conclusion :p, subClassOf, member
  end
  
  rule 'rdfs13' do
    condition :p, type, datatype
    
    conclusion :p, subClassOf, literal
  end
}
RDFSExtRuleBase =

A rule base including rules for “stronger extensional semantic conditions” according to the RDF Semantics document.

RuleBase.new('RDFSExtRuleBase') {
  domain = Namespace.lookup(:rdfs, 'domain')
  subClassOf = Namespace.lookup(:rdfs, 'subClassOf')
  range = Namespace.lookup(:rdfs, 'range')
  subPropertyOf = Namespace.lookup(:rdfs, 'subPropertyOf')
  type = Namespace.lookup(:rdf, 'type')
  resource = Namespace.lookup(:rdfs, 'Resource')
  property = Namespace.lookup(:rdf, 'Property')
  rdfsclass = Namespace.lookup(:rdfs, 'Class')
  
  # The following reasoning rules were taken from the RDF Semantics document
  # http://www.w3.org/TR/rdf-mt/#RDFSExtRules
  
  rule 'ext1' do
    condition :uuu, domain, :vvv
    condition :vvv, subClassOf, :zzz
    
    conclusion :uuu, domain, :zzz
  end
  
  rule 'ext2' do
    condition :uuu, range, :vvv
    condition :vvv, subClassOf, :zzz
    
    conclusion :uuu, range, :zzz
  end
  
  rule 'ext3' do
    condition :uuu, domain, :vvv
    condition :www, subPropertyOf, :uuu
    
    conclusion :www, domain, :vvv
  end
  
  rule 'ext4' do
    condition :uuu, range, :vvv
    condition :www, subPropertyOf, :uuu
    
    conclusion :www, range, :vvv
  end
  
  rule 'ext5' do
    condition type, subPropertyOf, :www
    condition :www, domain, :vvv
    
    conclusion resource, subClassOf, :vvv
  end
  
  rule 'ext6' do
    condition subClassOf, subPropertyOf, :www
    condition :www, domain, :vvv
    
    conclusion rdfsclass, subClassOf, :vvv
  end
  
  rule 'ext7' do
    condition subPropertyOf, subPropertyOf, :www
    condition :www, domain, :vvv
    
    conclusion property, subClassOf, :vvv
  end
  
  rule 'ext8' do
    condition subClassOf, subPropertyOf, :www
    condition :www, range, :vvv
    
    conclusion rdfsclass, subClassOf, :vvv
  end
  
  rule 'ext9' do
    condition subPropertyOf, subPropertyOf, :www
    condition :www, range, :vvv
    
    conclusion property, subClassOf, :vvv
  end
}
OWLRuleBase =

A preliminary (alpha) rule base for OWL reasoning.

RuleBase.new('OWLRuleBase') {
  type = Namespace.lookup(:rdf, 'type')
  transProp = Namespace.lookup(:owl, 'TransitiveProperty')
  symProp = Namespace.lookup(:owl, 'SymmetricProperty')
  inverseOf = Namespace.lookup(:owl, 'inverseOf')
  disjointWith = Namespace.lookup(:owl, 'disjointWith')
  subClassOf = Namespace.lookup(:rdfs, 'subClassOf')
  sameAs = Namespace.lookup(:owl, 'sameAs')
  rdfclass = Namespace.lookup(:rdfs, 'Class')
  equivClass = Namespace.lookup(:owl, 'equivalentClass')
  complementOf = Namespace.lookup(:owl, 'complementOf')
  funcProp = Namespace.lookup(:owl, 'FunctionalProperty')
  invFuncProp = Namespace.lookup(:owl, 'InverseFunctionalProperty')
  onProperty = Namespace.lookup(:owl, 'onProperty')
  hasValue = Namespace.lookup(:owl, 'hasValue')
  allValuesFrom = Namespace.lookup(:owl, 'allValuesFrom')
  someValuesFrom = Namespace.lookup(:owl, 'someValuesFrom')
  
  # The following reasoning rules where taken from
  # http://www-ksl.stanford.edu/software/jtp/doc/owl-reasoning.html
  
  # Enforcing transitivity of owl:TransitiveProperty.
  rule do
    condition :ancestor, type, transProp
    condition :Sue, :ancestor, :Mary
    condition :Mary, :ancestor, :Anne

    conclusion :Sue, :ancestor, :Anne
  end

  # Semantics of owl:SymmetricProperty is enforced.
  rule do
    condition :relative, type, symProp
    condition :Sue, :relative, :Mary

    conclusion :Mary, :relative, :Sue
  end
  
  # Reasoning with owl:inverseOf.
  rule do
    condition :parentOf, inverseOf, :hasParent
    condition :Goldie, :parentOf, :Kate

    conclusion :Kate, :hasParent, :Goldie
  end

  # Inheritance of disjointness constraints.
  rule do
    condition :Plant, disjointWith, :Animal
    condition :Mammal, subClassOf, :Animal

    conclusion :Plant, disjointWith, :Mammal
  end

  # When an owl:sameAs relationship is asserted or inferred between two
  # entities that are known to be classes, an owl:equivalentClass
  # relationship is inferred between the classes. Similarly, when an
  # owl:sameAs relationship is asserted or inferred between two entities that
  # are known to be properties, an owl:equivalentProperty relationship is
  # inferred between the classes.
  rule do
    condition :Human, sameAs, :Person
    condition :Human, type, rdfclass
    condition :Person, type, rdfclass

    conclusion :Human, equivClass, :Person
  end

  # All the subclasses of a given class are disjoint with the class's
  # complement.
  rule do
    condition :Animal, complementOf, :NonAnimals
    condition :Mammal, subClassOf, :Animal

    conclusion :Mammal, disjointWith, :NonAnimals
  end

  # A complicated bit of reasoning about owl:complementOf captured by
  # following KIF axiom.
  rule do
    condition :c1, complementOf, :c2
    condition :c3, subClassOf, :c1
    condition :c4, subClassOf, :c2
    condition :c4, complementOf, :c5
    
    conclusion :c3, subClassOf, :c5
  end

  # Inferring owl:sameAs relationships via owl:FunctionalProperty and
  # owl:InverseFunctionalProperty.
  rule do
    condition :mother, type, funcProp
    condition :Joe, :mother, :Margaret
    condition :Joe, :mother, :Maggie

    conclusion :Margaret, sameAs, :Maggie
  end

  rule do
    condition :motherOf, type, invFuncProp
    condition :Margaret, :motherOf, :Joe
    condition :Maggie, :motherOf, :Joe

    conclusion :Margaret, sameAs, :Maggie
  end

  # TODO If a class A is owl:oneOf a list of objects, say X, Y, and Z, then
  # each of X, Y, and Z has rdf:type A.
  
  # If an object is rdf:type an owl:hasValue owl:Restriction, then the object
  # has the specified value for the specified property.
  rule do
    condition :RestrictionOrangeSkin, onProperty, :skinColor
    condition :RestrictionOrangeSkin, hasValue, :Orange
    condition :MrOompaLoompa, type, :RestrictionOrangeSkin

    conclusion :MrOompaLoompa, :skinColor, :Orange
  end

  # If an owl:hasValue owl:Restriction restricts a particular property to a
  # particular value, and an object has that value for that property, then
  # the object has the Restriction as a type.
  rule do
    condition :RestrictionOrangeSkin, onProperty, :skinColor
    condition :RestrictionOrangeSkin, hasValue, :Orange
    condition :MrOompaLoompa, :skinColor, :Orange

    conclusion :MrOompaLoompa, type, :RestrictionOrangeSkin
  end

  # If an object is a rdf:type an owl:allValuesFrom owl:Restriction, and the
  # object has values for the specified property, then the values are of the
  # specified type.
  rule do
    condition :RestrictionCatChildren, onProperty, :child
    condition :RestrictionCatChildren, allValuesFrom, :Cat
    condition :Fluffy, type, :RestrictionCatChildren
    condition :Fluffy, :child, :Cupcake

    conclusion :Cupcake, type, :Cat
  end

  # If an owl:someValuesFrom owl:Restriction restricts a particular property
  # to a particular type, and if an object has some values of the specificied
  # type for the specified property, then that object has the Restriction as
  # a type.
  rule do
    condition :RestrictionIvyLeagueDegree, onProperty, :degree
    condition :RestrictionIvyLeagueDegree, someValuesFrom, :IvyLeagueSchool
    condition :Mary, :degree, :Harvard
    condition :Harvard, type, :IvyLeagueSchool

    conclusion :Mary, type, :RestrictionIvyLeagueDegree
  end

  # TODO If a property Q is owl:inverseOf of a property P, and P is an
  # owl:TransitiveProperty, then Q is also an owl:TransitiveProperty.
  
  # TODO All of the elements of an owl:AllDifferent are owl:differentFrom each other.
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(values = {}) ⇒ RuleEngine

A RuleBase can be specified using the hash key :rule_base.

Example:

RuleEngine.new :rule_base => RuleEngine::RDFSRuleBase


10
11
12
13
# File 'lib/activerdf_rules/rule_engine.rb', line 10

def initialize(values = {})
  @rule_bases = []
  @rule_bases << values[:rule_base] if values[:rule_base]
end

Instance Attribute Details

#rule_basesObject (readonly)

Returns the value of attribute rule_bases.



4
5
6
# File 'lib/activerdf_rules/rule_engine.rb', line 4

def rule_bases
  @rule_bases
end

Instance Method Details

#define_rules(&b) ⇒ Object

Creates a new RuleBase, adds it to the array of rule bases, and passes the block to the RuleBase constructor. This allows use of the RuleBase DSL.



17
18
19
20
# File 'lib/activerdf_rules/rule_engine.rb', line 17

def define_rules(&b)
  rb = RuleBase.new(&b)
  self.rule_bases << rb
end

#process_rulesObject

Loops through all of the rule bases and processes each rule in each rule base. Returns true if any of the rules have added information to the database.



25
26
27
28
29
30
31
32
33
34
# File 'lib/activerdf_rules/rule_engine.rb', line 25

def process_rules
  $activerdflog.debug("processing '#{@rule_base}'")
  change = false
  @rule_bases.each do |rb|
    rb.rules.each do |r|
      change |= r.process
    end
  end
  change
end