package infosapient.opr;
/*
* Copyright (c) 2001, Workplace Performance Tools, All Rights Reserved.
*
* LICENSE TO USE THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THE COMMON PUBLIC LICENSE 0.5
* ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
* RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
* The license may be viewed at:
* http://www.opensource.org/licenses/cpl.html
*/
import infosapient.system.FzyAttribClause;
import infosapient.system.FzySet;
import infosapient.system.FzyClauseComponent;
import infosapient.system.FzySystemException;
import java.rmi.server.ObjID;
import java.io.Serializable;
/**
*
*
*
* Class FzyOperator embodies the behavior of a fuzzy operator
* <ul> <li> @see FzyOprAND</li>
* <li> @see FzyOprOR</li>
* </ul>
*<p>Usage:<nl>
* FzyOperators are used to combine (optional) multiple clauses
* within a premise.
*
* IF < FzyAttribClause > [ < FzyOperator > < FzyAttribClause >]
* <p>THEN < FzyAttribClause >
* <p>ELSE < FzyAttribClause >";"
*<p>Example:
* <code> if (( manufacturingCosts are ELEVATED ) <b><i>AND</b></i>
* ( spoilageRates are LARGE ) ) then ( price must be around PREMIUM ); </code>
* (Note: <i>must, around</i> are keywords known as hedges. (@see FzyHedge))
*<p>
* @see infosapient.system.FzyRule
* @see infosapient.system.FzyPremise
*
* @author: Michael McConnell
* @version $Revision: 1.1.1.1 $
*/
public
abstract
class
FzyOperator
extends
infosapient.system.FzyClauseComponent
implements
Serializable,
infosapient.util.XMLOutput,
infosapient.util.TextOutput {
static final long serialVersionUID = -8791087645834238023L;
protected double currentSolution = Double.NaN;
protected infosapient.system.FzyClauseComponent rightChild = null;
protected infosapient.system.FzyClauseComponent leftChild = null;
private final static String CN = "infosapient.opr.FzyOpr";
public abstract void apply(double value0, double value1)
throws infosapient.system.FzySystemException;
/**
* Factory method for FzyOperator. Provide the operator name as string, will return the appropriate
* FzyOperator object.
* Creation date: (1/4/00 3:25:53 PM)
* @author: Michael McConnell
*
* @return infosapient.opr.FzyOperator
* @param name java.lang.String
* @exception infosapient.system.FzySystemException --The exception description.
*/
public static FzyOperator CreateOperatorFor(String name) throws infosapient.system.FzySystemException {
try {
String oprName = name.toUpperCase();
Class oprClass = Class.forName(CN + oprName);
FzyOperator o = (infosapient.opr.FzyOperator) oprClass.newInstance();
return o;
} catch (ClassNotFoundException cnfe) {
throw new FzySystemException("Invalid name: " + name + "; Appropriate operator class not found. " + cnfe.getMessage());
} catch (InstantiationException ie) {
throw new FzySystemException("Instantiation exception when trying to create: " + name + " as a fzyoperator.");
} catch (IllegalAccessException iae) {
throw new FzySystemException("Illegal Access exception encountered when attempting to instantiate: " + name + "; " + iae.getMessage());
}
}
public infosapient.system.FzyClauseComponent getLeftChild() {
return leftChild;
}
public infosapient.system.FzyClauseComponent getRightChild() {
return rightChild;
}
public double getSolutionDOM() {
return currentSolution;
}
/**
* Return the status of the current solution. True - hasSolution
* @return boolean
*/
public boolean hasSolution() {
return !(Double.isNaN(currentSolution));
}
/**
* return true if the operator is in a valid state,
* ie. left child == FzyAttribClause | FzyOperator
right == FzyAttribClause
* @author Michael McConnell Creation date: (1/20/00 2:21:15 PM)
* @return boolean
* @exception java.lang.IllegalStateException detailing which child is not valid.
*/
public boolean isValid() throws java.lang.IllegalStateException {
boolean leftChild = true;
boolean rightChild = true;
FzyOperator cOpr = this;
outer:
while (rightChild) {
if (!(cOpr.getRightChild() instanceof FzyAttribClause)) rightChild=false;
while(leftChild) {
if (cOpr.getLeftChild() instanceof FzyOperator) {
cOpr = (FzyOperator)cOpr.getLeftChild();
break;
}else
if (cOpr.getLeftChild() == null) {
leftChild = false;
break outer;
} else {
break outer;
}
}
}
if (rightChild&leftChild) return true;
else
throw new IllegalStateException(" The operator is invalid: " );
}
public void reset() {
currentSolution = Double.NaN;
if ( getRightChild()!= null) getRightChild().reset();
if ( getLeftChild() != null) getLeftChild().reset();
}
/**
* @param infosapient.system.FzyClauseComponent -- the ClauseComponent to be added
* @throws IllegalStateException -- if the right side is already occupied.
*/
public void setLeftChild(infosapient.system.FzyClauseComponent fcc) throws IllegalStateException {
if (!((fcc instanceof FzyOperator) || (fcc instanceof infosapient.system.FzyAttribClause)))
throw new IllegalStateException(fcc.getClass().getName() + " Attempt to set a child of this operator that is not an FzyAttribClause or an Operator.");
else
leftChild = fcc;
}
/**
* @param infosapient.system.FzyClauseComponent -- the ClauseComponent to be added
* @throws IllegalStateException -- if the right side is already occupied.
*/
public void setRightChild(infosapient.system.FzyClauseComponent fcc) throws IllegalStateException {
if (rightChild != null)
throw new IllegalStateException(fcc.getClass().getName() + " Attempt to set the right child of this operator when already occupied.");
else
rightChild = fcc;
}
/**
* Set the solution degree of membership (DOM)
* @param double - degree of membership
*/
public void setSolutionDOM(double s) {
currentSolution = s;
}
/**
* Method to convert the operator clause to human readable string.
* Creation date: (2/24/00 1:59:41 PM)
* @return java.lang.String
*/
public String toString() {
return toText();
}
/**
* Represent this Operator (and its children) as a StringBuffer with operator/children text.
* Creation date: (2/1/00 5:47:46 PM)
* @return java.lang.StringBuffer
*/
public String toText() {
StringBuffer oprSB = new StringBuffer(" ( ");
oprSB.append(getLeftChild().toText());
oprSB.append(" " + getName() + " ");
oprSB.append(getRightChild().toText());
oprSB.append(" ) ");
return oprSB.toString();
}
/**
* Represent this operator (and this operators children) as xml tags.
* Creation date: (1/31/00 8:19:36 AM)
* @param int - number of tabs required to maintain correct indentation.
* @return java.lang.StringBuffer
*/
public StringBuffer toXML(int nTabs) {
StringBuffer xmlSB= new StringBuffer(20);
FzyOperator theOpr= this;
// do simple case first
if ((theOpr.getLeftChild() instanceof FzyAttribClause)
&& (theOpr.getRightChild() instanceof FzyAttribClause)) {
for (int i= 0; i < nTabs; i++)
xmlSB.append("\t");
xmlSB.append("<expr>\n" + getLeftChild().toXML(nTabs + 1));
for (int i= 0; i < nTabs + 1; i++)
xmlSB.append("\t");
xmlSB.append("<opr id=\"" + getName() + "\" />\n");
xmlSB.append(theOpr.getRightChild().toXML(nTabs + 1) );
for (int i= 0; i < nTabs; i++)
xmlSB.append("\t");
xmlSB.append("</expr>\n");
return xmlSB;
} else {
if (theOpr.getLeftChild() instanceof FzyOperator) {
FzyClauseComponent leftChild= theOpr.getLeftChild();
while (leftChild instanceof FzyOperator) {
leftChild= ((FzyOperator) leftChild).getLeftChild();
xmlSB.append(leftChild.toXML(nTabs + 1));
}
xmlSB.append(leftChild.toXML(nTabs+1));
} else if (theOpr.getRightChild() instanceof FzyOperator) {
FzyClauseComponent rightChild= theOpr.getRightChild();
while (rightChild instanceof FzyOperator) {
rightChild= ((FzyOperator) rightChild).getRightChild();
xmlSB.append(rightChild.toXML(nTabs + 1));
}
xmlSB.append(rightChild.toXML(nTabs + 1));
}
}
return xmlSB;
}
}