module RDF::RDFa::Expansion

The Expansion module performs a subset of OWL entailment rules on the base class, which implementes RDF::Readable.

Constants

FOLDING_RULES
REMOVAL_RULES
RULES

Public Instance Methods

copy_properties(repository) click to toggle source

Perform property copying on the resulting default graph.

For all objects of type rdfa:Pattern that are the target of an rdfa:copy property, load the IRI into a repository.

Subsequently, remove reference rdfa:Pattern objects.

@param [RDF::Repository] repository @see [HTML+RDFa](www.w3.org/TR/rdfa-in-html/#rdfa-reference-folding)

# File lib/rdf/rdfa/expansion.rb, line 49
def copy_properties(repository)
  add_debug("expand") {"Repository has #{repository.size} statements"}
  fold(repository)
end
expand(repository) click to toggle source

Perform vocabulary expansion on the resulting default graph.

Vocabulary expansion uses the built-in reasoner using included vocabularies from RDF.rb.

@param [RDF::Repository] repository @see [OWL2 PROFILES](www.w3.org/TR/2009/REC-owl2-profiles-20091027/#Reasoning_in_OWL_2_RL_and_RDF_Graphs_using_Rules)

# File lib/rdf/rdfa/expansion.rb, line 16
def expand(repository)
  add_debug("expand") {"Repository has #{repository.count} statements"}

  # Load missing vocabularies
  vocabs = repository.query({predicate: RDF::RDFA.usesVocabulary}).to_a.map(&:object)
  vocabs.map! do |vocab|
    begin
      # Create the name with a predictable name so that it is enumerated and can be found
      v = RDF::Vocabulary.find(vocab) || begin
        vg = RDF::Graph.load(vocab)
        RDF::Vocabulary.from_graph(vg, url: vocab, class_name: "D#{Digest::MD5.hexdigest vocab}") unless vg.empty?
      end
    rescue Exception => e
      # indicate the warning if the vocabulary fails to laod
      add_warning("expand", "Error loading vocabulary #{vocab}: #{e.message}", RDF::RDFA.UnresolvedVocabulary)
      nil
    end
  end.compact

  entailment(repository, vocabs)
  add_debug("expand") {"Repository now has #{repository.count} statements"}

end
rule(name, &block) click to toggle source
# File lib/rdf/rdfa/expansion.rb, line 54
def rule(name, &block)
  Rule.new(name, block)
end

Private Instance Methods

entailment(repository, vocabs) click to toggle source

Perform OWL entailment rules on repository @param [RDF::Repository] repository @return [RDF::Repository]

# File lib/rdf/rdfa/expansion.rb, line 196
def entailment(repository, vocabs)
  old_count = 0

  # Create an aggregate repo containing base repository and relevant entailment rules from the included vocabularies
  v_repo = RDF::Repository.new do |r|
    vocabs.each do |v|
      v.each_statement do |statement|
        r << statement if [
          RDF::OWL.equivalentProperty,
          RDF::OWL.equivalentClass,
          RDF::RDFS.subPropertyOf,
          RDF::RDFS.subClassOf
        ].include?(statement.predicate)
      end
    end
  end

  ag_repo = RDF::MergeGraph.new do
    source repository, false
    source v_repo, false
  end

  # Continue as long as new statements are added to repository
  while old_count < (count = repository.count)
    #add_debug("entailment") {"old: #{old_count} count: #{count}"}
    old_count = count
    to_add = []

    RULES.each do |rule|
      rule.execute(ag_repo) do |statement|
        #add_debug("entailment(#{rule.name})") {statement.inspect}
        to_add << statement
      end
    end

    repository.insert(*to_add)
  end
end
fold(repository) click to toggle source

Perform RDFa folding rules on repository @param [RDF::Repository] repository

# File lib/rdf/rdfa/expansion.rb, line 238
def fold(repository)
  old_count = 0

  # Continue as long as new statements are added to repository
  while old_count < (count = repository.count)
    #add_debug("fold") {"old: #{old_count} count: #{count}"}
    old_count = count
    to_add = []

    FOLDING_RULES.each do |rule|
      rule.execute(repository) do |statement|
        #add_debug("fold(#{rule.name})") {statement.inspect}
        to_add << statement
      end
    end

    repository.insert(*to_add)
  end

  # Remove statements matched by removal rules
  to_remove = []
  REMOVAL_RULES.each do |rule|
    rule.execute(repository) do |statement|
      #add_debug("removal(#{rule.name})") {statement.inspect}
      to_remove << statement
    end
  end
  repository.delete(*to_remove)

  add_debug("fold", "final count: #{count}")
end