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
}
}
}