Previous topic  Top  Next topic  Print this Topic
 

The Multiply Example Built-in

 

The ternary built-in multiply takes two numbers (the first two arguments) multiplies them and returns the result in the third argument. In addition to the other examples a new resulting atom must be generated which returns the result. This built-in has three arguments and has the string representation <multiply> in ObjectLogic programs:

package com.ontoprise.builtin.functionalbuiltin;

 

import java.util.BitSet;

 

import org.apache.log4j.Logger;

import org.semanticweb.kaon2.api.KAON2Exception;

import org.semanticweb.kaon2.api.KAON2Manager;

import org.semanticweb.kaon2.api.OntologyLanguage;

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

 

import com.ontoprise.builtin.BuiltinContext;

import com.ontoprise.builtin.BuiltinSpec;

import com.ontoprise.builtin.Grounds;

import com.ontoprise.builtin.builtin.BuiltinServices;

import com.ontoprise.builtin.interfaces.IFunctionalBuiltin;

import com.ontoprise.builtin.interfaces.IGrounds;

import com.ontoprise.util.OntopriseConstants;

 

/**

* Example built-in which multiplies two numbers.

*

*/

public class MultiplyDemoBuiltin implements IFunctionalBuiltin {

  protected static Logger _log =

Logger.getLogger(OntopriseConstants.CORE_LOG);

 

  /**

    * Provide a no-argument constructor which needs nothing to do for this built-in.

    */

  public MultiplyDemoBuiltin() { // Empty as nothing is to do for this built-in

  }

 

  /**

    * This method is called during the evaluation. We must first check which of our four possible signatures applies and then either calculate the result or

    * check if a result is valid

    *

    * @param tuple the tuple which must be checked

    * @throws InterruptedException if the process was interrupted

    * @throws KAON2Exception if an error occurs

    */

  @Override

  public boolean evaluate(Term[] input, IGrounds grounds) throws KAON2Exception, InterruptedException {

      try {

          switch (grounds.getInt()) {

              case IGrounds.FIRSTSECONDTHIRD:

                  // All three positions are ground. This means we must check if "position 0" multiplied with "position 1"

                  // equals the "position 2" value. If this is true we send away the received tuple.

                  double op1 = BuiltinServices.getNumber(input[0]);

                  double op2 = BuiltinServices.getNumber(input[1]);

                  double result = BuiltinServices.getNumber(input[2]);

                  if (op1 * op2 == result) {

                      return true; // return true to signal there is a result in the buffer

                  }

                  break;

              case IGrounds.FIRSTSECOND: {

                  // First and second position is ground. We must multiply the first with the second position

                  // and send away the result tuple.

                  op1 = BuiltinServices.getNumber(input[0]);

                  op2 = BuiltinServices.getNumber(input[1]);

                  // third argument must be filled with the result

                  result = op1 * op2;

                  // Create and send away the new tuple.

                  input[2] =

KAON2Manager.factory().constantDouble(result); // write the result into the buffer

                  return true; // return true to signal there is a result in the buffer

              }

              case IGrounds.FIRSTTHIRD: {

                  // First and third position is ground. First position multiplied with second position

                  // must be equal to the third position. We need to calculate the second position.

                  op1 = BuiltinServices.getNumber(input[0]);

                  op2 = BuiltinServices.getNumber(input[2]);

                  // third argument must be filled with the result

                  result = op2 / op1;

                  // Create and send away the new tuple.

                  input[1] =

KAON2Manager.factory().constantDouble(result); // write the result into the buffer

                  return true; // return true to signal there is a result in the buffer

              }

              case IGrounds.SECONDTHIRD: {

                  // Second and third position is ground. We must calculate the first position.

                  op1 = BuiltinServices.getNumber(input[1]);

                  op2 = BuiltinServices.getNumber(input[2]);

                  // third argument must be filled with the result

                  result = op2 / op1;

                  // Create and send away the new tuple.

                  input[0] =

KAON2Manager.factory().constantDouble(result); // write the result into the buffer

                  return true; // return true to signal there is a result in the buffer

              }

          }

      } catch (Exception e) {

          _log.error("Invalid input", e);// catch exception for wrong input values. This is logical handled as false.

      }

      return false; // return false to signal there no valid result in the buffer

  }

 

  /**

    * This method will be called after evaluation for cleanup purposes.

    *

    * NOTE: It is possible that this operator will be used again when the same query object is openened again.

    * init() won't be called a second time.

    *

    * @throws KAON2Exception Is thrown on Error

    * @throws InterruptedException Is thrown on Interruption

    */

  public void evaluationFinished() throws KAON2Exception, InterruptedException {

      // This built-in has just one state, no need to set it back.

      // It is used to set a built-in to the post-init() state.

  }

 

  /**

    * Method to get informations about this built-in. This method has to deliver a valid BuiltinSpec object

    * after the constructor finishes, before init() has be called.

    *

    * @return BuiltinSpec object with informations about this built-in.

    */

  public BuiltinSpec getInfo() {

      BuiltinSpec.Builder builder = new BuiltinSpec.Builder(this, "multiplydemo", 3);

      builder.setAllowedOntologyLanguages(OntologyLanguage.F_LOGIC);

      builder.setDescription("multiplydemo");

      builder.setParameters("first parameter", "second parameter", "result");

      return builder.build();

  }

 

  /**

    * Initialisation of this built-in. This is done for the instance before evaluation.

    *

    * @param context Contains additional Informations needed for some built-ins

    * @param args Term[] that contains the literal arguments.

    * @throws KAON2Exception Is thrown on Error

    * @throws InterruptedException Is thrown on Interruption

    */

  public void init(BuiltinContext context, Term[] args) throws KAON2Exception, InterruptedException {

      // Nothing to do, as this built-in does not need any initialization.

  }

 

  /**

    * Method to determine if a certain grounds configuration is evaluable.

    * This method has to be usable context free, init() is called in an other instance as

    * isEvaluable will be called. All needed information should be provided by the current

    * method arguments.

    *

    * @param grounds Object with grounding informations.

    * @param variableInstantiations This BitSets has the instantiation of all variables that occurs. Needed especially if partial-ground functions are used.

    * @param builtinContext BuiltinContext with additional context informations

    * @param args Literal arguments

    * @return if this grounds are evaluable or not.

    * @throws KAON2Exception Is thrown on Error

    */

  public boolean isEvaluable(IGrounds grounds, BitSet variableInstantiations, BuiltinContext builtinContext, Term[] args) throws KAON2Exception {

      // There are four different signatures that can be evaluated by this built-in.

      // It is just necessary that at least three of the arguments are ground.

      // This method has not to check the input type, just the grounds.

      switch (grounds.getInt()) {

          case Grounds.FIRSTSECONDTHIRD: {

              return true; // all arguments are ground

          }

          case Grounds.FIRSTSECOND: {

              return true; // the third argument is not ground

          }

          case Grounds.FIRSTTHIRD: {

              return true; // the second argument is not ground

          }

          case Grounds.SECONDTHIRD: {

              return true; // the first argument is not ground

          }

          default:

              return false; // cannot be evaluated

      }

  }

 

}