Previous topic  Top  Next topic  Print this Topic
 

Developing Your Own Rewriters

 

When OntoBroker evaluates a query, it checks which rules are relevant for the query and then rewrites the relevant rules (e.g. for performance reasons). It is also possible to develop your own rewriters which then are applied during the reasoning process. The following example rewriter exchanges "less" built-ins with "greater" built-ins (of course it doesn't make any sense, but it helps illustrating the power of rewriters):

package com.ontoprise.rewriter.example;

 

import org.semanticweb.kaon2.api.KAON2Manager;

import org.semanticweb.kaon2.api.logic.Literal;

import org.semanticweb.kaon2.api.logic.PredicateSymbol;

import org.semanticweb.kaon2.api.logic.Rule;

import org.semanticweb.kaon2.api.logic.Term;

 

import com.ontoprise.exception.DataModelException;

import com.ontoprise.obfuscation.ExcludePublicMembers;

import com.ontoprise.rewriter.AbstractRuleRewriter;

 

 

 

public class ExampleRuleRewriter extends AbstractRuleRewriter {

 

  /**

    * This is the method which is called during the rewriting process. This method is called for each

    * of the rules which are relevant for the current query.

    * <p>

    * If you do not want to touch a rule just return the original rule.

    * </p>

    */

  public Rule rewrite(Rule rule) throws DataModelException {

      Rule result = rule;

      if (containsLessLiterals(rule)) {

          result = exchangeBodyByGreater(rule);

      }

      return result;

  }

 

  /**

    * Checks if the given rule contains a "less" literal.

    *

    * @param rule          the rule to be checked

    * @return              <tt>true</tt> if it contains a "less" literal, <tt>false</tt> otherwise.

    */

  private boolean containsLessLiterals(Rule rule) {

      for (Literal bodyLiteral: rule.getBodyLiterals()) {

          if (isLessLiteral(bodyLiteral)) {

              return true;

          }

      }

      return false;

  }

 

  /**

    * Is the given literal a "less" literal?

    *

    * @param literal       the literal to be checked

    * @return              <tt>true</tt> if the given literal is a "less" literal, <tt>false</tt> otherwise.

    */

  private boolean isLessLiteral(Literal literal) {

      PredicateSymbol predicate = literal.getPredicateSymbol();

      if (predicate.getName().equals("less") && predicate.getArity() == 2) {

          return true;

      } else {

          return false;

      }

  }

 

  /**

    * Returns a new rule where all occurences of "less" are replaced with "greater".

    *

    * @param rule          the rule with the "less" literals

    * @return              the new rule (with the "greater" literals)

    */

  private Rule exchangeBodyByGreater(Rule rule) {

      Literal[] newBodyLiterals = new Literal[rule.getBodyLength()];

      int index = 0;

      for (Literal bodyLiteral: rule.getBodyLiterals()) {

          if (isLessLiteral(bodyLiteral)) {

              // Create a new "greater" literal.

              PredicateSymbol greaterPredicate = KAON2Manager.factory().predicateSymbol("greater", 2);

              Term[] newArguments = bodyLiteral.getArguments().clone();

              Literal greaterLiteral = KAON2Manager.factory().literal(bodyLiteral.isPositive(), greaterPredicate, newArguments);

              newBodyLiterals[index] = greaterLiteral;

          } else {

              // Just reuse the old literal.

              newBodyLiterals[index] = bodyLiteral;

          }

          index++;

      }

      Rule newRule = KAON2Manager.factory().rule(rule.getAxiomID(), rule.getHeadLiterals(), rule.isHeadConjunctive(), newBodyLiterals);

      return newRule;

  }

}

After you have developed your own rewriter you can try it out by compiling it, putting it into a JAR library and placing that library to the "rewriters" folder of your OntoBroker installation. When OntoBroker starts you should see a message that the rewriter was loaded and initialized.