options {
STATIC=false; // change to true for static instance of kbparser
DEBUG_PARSER=true; // change to false to remove method trace
}
PARSER_BEGIN(RuleCompiler)
package infosapient.rulecompiler;
/*
* Copyright (c) 2001,2002 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.
*/
import infosapient.opr.*;
import infosapient.hdg.*;
import infosapient.resolution.*;
import infosapient.system.*;
import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Observable;
import java.util.Stack;
import java.util.Vector;
/**
*
Created by Sun Microsystems JavaCC(java compiler compiler version 2.1) from isrulegrammar.jj.
* WARNING: Do NOT modify RuleCompiler, RuleCompilerTokenManager, RuleCompilerConstants as they are machine generated. Code is subject to change without notice.
* Limitations: currently does not support creation of unconditional rules.
*
* If you find it necessary to change RuleCompiler, RuleCompilerTokenManager, or RuleCompilerConstants:
* modify isrulegrammar.jj and then re-generate the RuleCompiler.java classes. Even though the license does not require it -- I would appreciate your sending me the changes you made.
* JavaCC is now supported by and, can be obtained from: "Metamata"
* @author Michael McConnell - delta-vee@users.sourceforge.net
* @version $Revision: 1.1 $
*
* Change log:
* 20020109 - brought isrulegrammar.jj into compilance with JavaCC v2.1
* - Corrected references to FzyKnowledgebase
* - Removed duplicate references to trace_enabled, trace_indent, trace_token(),
* trace_scan(),trace_call(),trace_return()
*
*/
public class RuleCompiler
{
private Observable handler;
private int errors = 0;
private String kbName;
private FzyKnowledgebase theKB;
private Vector hedgeCollection = null;
private Vector setNames = new Vector();
private Vector attribNames = new Vector();
private Vector ruleNames = new Vector();
private Hashtable referringRules = new Hashtable(4);
private Hashtable deducingRules = new Hashtable(4);
private Hashtable solutionSetDict = new Hashtable(4);
public void setKB(FzyKnowledgebase kb) {
theKB = kb;
}
/**
* Reinitialize the compiler without having to create a new one.
* (Creates a new TokenManager).
* @param String - rule represented as a String.
*/
public void ReInit(String aRule){
SimpleCharStream stream =
new SimpleCharStream( new ByteArrayInputStream(aRule.getBytes()),
1,
1);
RuleCompilerTokenManager tm = new RuleCompilerTokenManager(stream);
ReInit(tm);
}
public FzyKnowledgebase getKB() {
return theKB;
}
public Observable getHandler() {
if (handler == null) handler = new Observable();
return handler;
}
public void addObserver(java.util.Observer o) {
getHandler().addObserver(o);
}
/**
* Factory method to create a new ruleCompiler
* @param FzyKnowledgebase - the existing knowledgebase
* @param String - string representation of a rule.
* @return RuleCompiler
*/
public static RuleCompiler newCompiler(infosapient.system.FzyKnowledgebase kb, String ruleAsString) {
SimpleCharStream stream =
new SimpleCharStream( new ByteArrayInputStream(ruleAsString.getBytes()),
1,
1);
RuleCompilerTokenManager tm = new RuleCompilerTokenManager(stream);
return (new RuleCompiler(kb, tm));
}
public RuleCompiler(infosapient.system.FzyKnowledgebase kb, RuleCompilerTokenManager tm) {
this(tm);
setKB(kb);
referringRules = kb.referringRules();
deducingRules = kb.getDeducingRules();
}
private void addReferringRule(FzyRule r, FzyAttribute aac2) {
Vector refList = null;
boolean f = true;
refList = (Vector)referringRules.get(aac2.getName());
if (refList == null) {
refList = new Vector(2);
referringRules.put(aac2.getName(), refList);
} else {
for (Enumeration dl = refList.elements(); dl.hasMoreElements();)
if (r.equals((FzyRule)dl.nextElement())) f = false;
}
if (f) {
refList.addElement(r);
referringRules.put(aac2.getName(), refList);
}
}
private void addDeducingRule(FzyRule r, FzyAttribute aac) {
Vector dedList = null;
boolean f = true;
dedList = (Vector)deducingRules.get(aac.getName());
if (dedList == null) {
dedList = new Vector(2);
} else {
for (Enumeration dl = dedList.elements(); dl.hasMoreElements();) {
FzyRule re = (FzyRule)dl.nextElement();
if ((r == re) || (r.equals(re))) f = false;
}
}
if (f) {
dedList.addElement(r);
deducingRules.put(aac.getName(), dedList);
}
}
}
PARSER_END(RuleCompiler)
SKIP :
{
" "
|
"\r"
|
"\t"
|
"\n"
|
"//" : IN_LINE_COMMENT
|
"/*" : IN_COMMENT
}
SKIP:
{
"\n" : DEFAULT
}
MORE:
{
< ~[] >
}
SKIP:
{
"*/" : DEFAULT
}
MORE:
{
< ~[] >
}
TOKEN :
{
< ABOUT: "about" > |
< ABOVE: "above" > |
< ADDAGGREGATION: "addAggregation" > |
< AFTER: "after" > |
< ALPHACUT: "alphaCut" > |
< AND: "and" > |
< ARE: "are" > |
< AROUND: "around" > |
< ATTRIBUTES: "attributes" > |
< AVERAGEMAX: "averageMaximum" > |
< AVERAGEACE: "averageace" > |
< AVERAGESUPPORT: "averageSupport" > |
< BACKWARDCHAIN: "backwardChain" > |
< BE: "be" > |
< BEFORE: "before" > |
< BELOW: "below" > |
< BETA: "beta" > |
< BETAWEIGHT: "betaWeight" > |
< BESTEVIDENCE: "bestEvidence" > |
< BOOLEANATTRIBUTE: "booleanAttribute" > |
< BOUNDED_ADD: "boundedAdd" > |
< BOUNDED_AND: "boundedAnd" > |
< BOUNDED_MEAN: "boundedMean" > |
< CENTROID: "centroid" > |
< CENTER: "center" > |
< CLOSE: "closeTo" > |
< CMEMBERSHIP: "100%Membership" > |
< CORRELATIONMETHOD: "correlationMethod" > |
< COSINE_NOT: "cosineNot" > |
< CURRENTVALUE: "currentValue" > |
< DECIMALPT: "." > |
< DECREASED: "decreased" > |
< DEFINITELY: "definitely" > |
< ELSE: "else" > |
< EXTREMELY: "extremely" > |
< FLEXPOINT: "flexPoint" > |
< GAUSSIAN: "gaussian" > |
< GENERALLY: "generally" > |
< GTOREQLS: ">=" > |
< HIGHDOMAIN: "highDomain" > |
< IF: "if" > |
< IMPLICATIONMETHOD: "implicationMethod" > |
< INCREASED: "increased" > |
< VICINITY: "in the vicinity of" > |
< IS: "is" > |
< KNOWLEDGEBASE: "knowledgeBase" > |
< LEAST_ENTROPY: "leastEntropy" > |
< LESSTHANOREQLS: "<=" > |
< LOWDOMAIN: "lowDomain" > |
< MAXIMUM: "maximum" > |
< MEAN_AND: "meanAnd" > |
< MEAN_OR: "meanOr" > |
< MINUS: "-" > |
< MINIMUM: "minimum" > |
< MINMAX: "minMax" > |
< MOSTLY: "mostly" > |
< MUST: "must" > |
< MY: "my" > |
< NEAR: "near" > |
< NEGATIVE: "negative" > |
< NEGATIVELY: "negatively" > |
< NOT: "not" > |
< OR: "or" > |
< OUR: "our" > |
< PI: "pi" > |
< PLUS: "+" > |
< POSITIVE: "positive" > |
< POSITIVELY: "positively" > |
< PRODUCT: "product" > |
< PRODUCT_AND: "productAnd" > |
< PRODUCT_OR: "productOr" > |
< RESOLUTIONMETHOD: "resolutionMethod" > |
< ROUGHLY: "roughly" > |
< RULES: "rules" > |
< RUNUNCONDITIONALS: "runUnconditionalRulesBefore" > |
< SC: ";" > |
< SETTYPE: "setType" > |
< SHOULD: "should" > |
< SINGLETON: "singleton" > |
< SINUSOIDAL: "sinusoidal" > |
< SLASH: "/" > |
< SLIGHTLY: "slightly" > |
< SOMEWHAT: "somewhat" > |
< LAT: "*" > |
< SUGENO_NOT: "sugenoNot" > |
< THE: "the" > |
< THEN: "then" > |
< THRESHOLD_NOT: "thresholdNot" > |
< TO: "to" > |
< TRIANGLE: "triangle" > |
< VERY: "very" > |
< VOTE_BOUNDED: "voteBounded" > |
< WEIGHTEDBETA: "weightedBeta" > |
< WIDTH: "width" > |
< YAGER_AND: "yagerAnd" > |
< YAGER_NOT: "yagerNot" > |
< YAGER_OR: "yagerOr" >
}
TOKEN : /* LITERALS */
{
< FP_LITERAL: | | | >
|
< NPN: ( "-" )? (["0"-"9"])+ "." (["0"-"9"])+ >
|
< PN: ( "-" )? "." (["0"-"9"])+ >
|
< NP: ( "-" )? (["0"-"9"])+ "." >
|
< N: ( "-" )? (["0"-"9"])+ >
}
TOKEN : /* IDENTIFIERS */
{
< IDENTIFIER: (|)* >
|
< LETTER: [ "a"-"z", "A"-"Z", "_", "$", "@" ] >
|
< DIGIT: [ "0"-"9" ] >
}
/**
* Build a fuzzy rule by visiting each node.
* @return FzyRule - the rule as object
*/
FzyRule compileRule() :
{
String rName = null;
String rText = null;
FzyRule r = new FzyRule();
FzyPremise tPremise = null;
FzyConsequent tConseq = null;
FzyConsequent tAltConseq = null;
}
{
rName=ruleId()
tPremise = premise(r) { r.addPremise(tPremise);
rText = tPremise.toText();
}
tConseq = consequent(r) { r.addConsequent(tConseq);
rText = rText + " " + tConseq.toText();
}
";" { rText = rText + ";";
r.setName(rName);
r.setText(rText);
getKB().setDeducingRules(deducingRules);
getKB().referringRules(referringRules);
return r;
}
}
FzyPremise premise(FzyRule r) :
{
Token t = null;
StringBuffer premiseTxt = null;
FzyPremise premise = new FzyPremise(r);
FzyClauseComponent eClause = null;
}
{
t = "if" { premiseTxt = new StringBuffer(t.image);}
eClause = expression(r) { premiseTxt = premiseTxt.append(" ").append(eClause.toText());
premise.setComponent(eClause);
}
{
premise.setText(premiseTxt.toString());
return premise;
}
}
FzyConsequent consequent(FzyRule r) :
{
boolean f = true;
Object[] array = null;
Token t = null;
String conseqTxt = null;
FzyConsequent conseq = new FzyConsequent(r);
infosapient.system.FzyAttribute fa = null;
infosapient.hdg.FzyHedge rh = null;
FzyAttribClause aac = null;
}
{
t = { conseqTxt = " " + t.image;}
aac
= attributeClause(r) { conseqTxt = conseqTxt + " " +aac.toText();
conseq.setConsequentGoal(aac);
theKB.addConseqClause(aac);
}
{
addDeducingRule(r, aac.getAttribute());
infosapient.system.FzySolutionSet fss = (infosapient.system.FzySolutionSet)solutionSetDict.get(aac.getAttribute());
if (fss != null) aac.setSolutionSet(fss);
else {
fss = new infosapient.system.FzySolutionSet(aac.getAttribute());
solutionSetDict.put(aac.getAttribute(), fss);
}
}
(
t = { conseqTxt = conseqTxt + " " + t.image;}
aac
= attributeClause(r) { conseqTxt = conseqTxt + " " + aac.toText();
conseq.setAltConseqGoal(aac);
}
)?
{
addDeducingRule(r, aac.getAttribute());
fss = (infosapient.system.FzySolutionSet)solutionSetDict.get(aac.getAttribute());
if (fss != null) aac.setSolutionSet(fss);
else {
fss = new infosapient.system.FzySolutionSet(aac.getAttribute());
solutionSetDict.put(aac.getAttribute(), fss);
}
conseq.setText(conseqTxt);
return conseq;
}
}
FzyClauseComponent expression(FzyRule r) :
{
boolean f = false;
infosapient.opr.FzyOperator opr = null;
Stack stack = new Stack();
FzyClauseComponent fcc = null;
Token t = null;
}
{
fcc = parenClause(r) {
stack.push(fcc);
}
(((t = "and") | (t="or") ) { try {opr = FzyOperator.CreateOperatorFor(t.image);}
catch(FzySystemException fse) {}
if (!stack.isEmpty()) {
opr.setLeftChild((infosapient.system.FzyClauseComponent)stack.pop());
stack.push(opr);
}
}
fcc =parenClause(r) {
if (!stack.isEmpty()) {
if (stack.peek() instanceof infosapient.opr.FzyOperator) {
((infosapient.opr.FzyOperator)stack.peek()).setRightChild(fcc);
}
}
}
)*
{
return((FzyClauseComponent)stack.pop());
}
}
FzyClauseComponent parenClause(FzyRule r) :
{
FzyClauseComponent fcc;
StringBuffer text = new StringBuffer(10);
}
{
("("
{
text.append("(");
}
fcc = expression(r) {
text.append(fcc.toText());
}
")" {
text.append(")");
fcc.setText(text);
return fcc;
}
)
|
(fcc = attributeClause(r) ) { addReferringRule( r,((FzyAttribClause)fcc).getAttribute()); }
{
return fcc;
}
}
FzyAttribClause attributeClause(FzyRule r) :
{
Double n = null;
FzyAttribClause fac = new FzyAttribClause();
FzyHedge rh = null;
Object[] array = null;
Token t = null;
Vector hedges = null;
}
{
array = id(null) { fac.append((String) array[0]);
if (array[1] instanceof FzyAttribute){
fac.setName((String) array[0]);
fac.setAttribute((infosapient.system.FzyAttribute) array[1]);
} else throw new ParseException("Expected attribute name.");
}
(t = "is" | t="are" ) {
fac.append(" ").append(t.image);
}
(hedges = hedgeCollection())?
{
if ((hedges != null)&&(!hedges.isEmpty())){
fac.setHedges(hedges);
for (Enumeration e = hedges.elements(); e.hasMoreElements();){
fac.append(" ").append(((FzyHedge) e.nextElement()).getName());
}
}
}
(
array = id(fac.getAttribute())
{ fac.append(" ").append(array[0]);
if (array[1] instanceof FzyAttribute) {
fac.setGoalAttribute((FzyAttribute) array[1]);
} else {
if (fac.getAttribute() != null) {
if (fac.getAttribute().containsSetNamed((String)array[0])) {
fac.setGoal(fac.getAttribute().getSetNamed((String)array[0]));
} else throw new ParseException(" There is no set within attribute '"
+ fac.getAttribute().getName() + "' named '"
+ (String)array[0] + "'.");
} else throw new ParseException(" There is no attribute defined as name '"
+ fac.getAttribute().getName() + "'.");
}
}
|
n=nLiteral()
{
fac.append(" ").append(n.toString());
try {
fac.setGoal(new FzySingleton(fac.getAttribute(), n.doubleValue()));
try {
fac.getGoal().setName(n.toString());
} catch (CloneNotSupportedException cnse) {
throw new ParseException(cnse.getMessage());
}
} catch (infosapient.system.FzySystemException fse) {
throw new ParseException(fse.getMessage());
}
}
|
rh =
restrictionHedge() { fac.append(" " + rh.getName());}
)
{return fac;}
}
Vector hedgeCollection() :
{
FzyHedge h;
hedgeCollection = null;
}
{
( h=hedge() )+
{
if (hedgeCollection instanceof Vector) hedgeCollection.addElement(h);
else {
hedgeCollection = new Vector();
hedgeCollection.addElement(h);
}
return hedgeCollection;
}
}
FzyHedge restrictionHedge() :
{
FzyHedge h;
}
{
(
"increased" { h = new FzyHdgINCREASE();}
|
"decreased" { h = new FzyHdgDECREASE();}
)
{ return h; }
}
FzyHedge hedge() :
{
Token t;
FzyHedge h;
}
{
(
"about" { h = new FzyHdgABOUT();} |
"above" { h = new FzyHdgABOVE();} |
"after" { h = new FzyHdgAFTER();} |
"around" {h = new FzyHdgAROUND();} |
"before" {h = new FzyHdgBEFORE(); } |
"below" { h = new FzyHdgBELOW(); } |
"closeTo" { h = new FzyHdgCLOSE(); } |
"definitely" { h = new FzyHdgDEFINITELY(); } |
"extremely" {h = new FzyHdgEXTREMELY(); } |
"generally" { h = new FzyHdgGENERALLY(); } |
"inVicinityOf" { h = new FzyHdgVICINITY();} |
"mostly" { h = new FzyHdgMOSTLY(); } |
"must" { h = new FzyHdgEXTREMELY(); } |
"near" { h = new FzyHdgNEAR(); } |
( "negative" | "negatively" ) { h = new FzyHdgNEGATIVE(); } |
"not" { h = new FzyHdgNOT(); } |
( "positive" | "positively" ) { h = new FzyHdgPOSITIVE(); } |
"roughly" { h = new FzyHdgROUGHLY(); } |
"should" { h = new FzyHdgSOMEWHAT(); } |
"slightly" { h = new FzyHdgSLIGHTLY(); } |
"somewhat" { h = new FzyHdgSOMEWHAT(); } |
"very" { h = new FzyHdgVERY(); }
)
{
return h;
}
}
FzyOperator operator() :
{
Token t;
FzyOperator o;
}
{
(
"and" { o = new FzyOprAND(); }
|
"or" { o = new FzyOprOR(); }
)
{
return o;
}
}
Double nLiteral() :
{
Token t = null;
Double d = null;
}
{
( t = )
{
try {
d = new Double(t.image);
if (d == null) throw new ParseException(" Error encountered attempting to convert '"
+t.image+ "' to Double. ");
} catch (Exception nfe) {
System.out.println(nfe.getMessage());
throw new ParseException(nfe.getMessage());
}
return d;
}
}
/**
* Return an identifier of some sort.
* If FzyAttribute is null, then I expect the identifier to be an attribute name.
* If FzyAttribute is not null, then I expect the identifier to be a fzyset name within the attribute ecified.
* @param FzyAttribute fa - the fuzzy attribute
* @return Object[] - an array with 2 values: the actual name found as a string, and the object that is named. (FzyAttribute or FzySet).
* @exception ParseException
*/
Object[] id(FzyAttribute fa) :
{
Object array[] = new Object[2];
FzySet fs;
Token t;
Enumeration e;
}
{
t =
{
e = getKB().ruleKeys();
for (; e.hasMoreElements(); ) {
String rname = (String) e.nextElement();
if (rname.equalsIgnoreCase(t.image)) {
ParseException pe = new ParseException(" Expected a set name. The rule name '"
+ t.image
+ "' cannot be used within an attribute expression.");
throw pe;
}
}
e = getKB().attributeKeys();
for (; e.hasMoreElements(); ) {
String sname = (String) e.nextElement();
if (sname.equals(t.image)) {
array[0] = t.image;
array[1] = theKB.getAttribute(t.image);
return array;
}
}
e = getKB().getAttributeSetNames();
for (; e.hasMoreElements(); ) {
String sname = (String) e.nextElement();
if (sname.equals(t.image)) {
if(fa instanceof FzyAttribute){
String n = fa.getName();
if (fa.containsSetNamed(t.image)){
array[0] = t.image;
array[1] = fa.getSetNamed(t.image);
return array;
} else {
throw new ParseException(" Expected a set named '"
+ t.image
+ "' within the attribute '"
+ n
+ "', but did not find it. ");
}
}else throw new ParseException ("Unable to proceed. Have found an existing set '" + t.image
+ "' without a correonding attribute. ");
}
}
if (kbName.equals(t.image)) throw
new ParseException(" The name '" + t.image + "' has been previously defined as the knowledgeBase name.");
return array;
}
}
String setId() :
{
Token t;
boolean snfound = false;
}
{
t =
{
Enumeration e = getKB().getAttributeSetNames();
for ( ; e.hasMoreElements(); ) {
String name = (String) e.nextElement();
if (name.equalsIgnoreCase(t.image)) throw new
ParseException("Duplicate set declaration. The name of this set is used as another set definition '" + t.image + "'.");
}
if (!snfound) setNames.addElement(t.image);
return t.image;
}
}
String attribId() :
{
Token t;
boolean anfound = false;
}
{
t =
{
Enumeration e = attribNames.elements();
for ( ; e.hasMoreElements(); ) {
try {
String name = (String) e.nextElement();
if (name.equalsIgnoreCase(t.image)) throw new
ParseException(" Duplicate attribute declaration. The name '" + t.image + "'; of this attribute has been previously defined. ");
} catch(ParseException see) {
anfound = true;
throw new ParseException(see.getMessage());
}
}
if (!anfound) attribNames.addElement(t.image);
return t.image;
}
}
String kbId() :
{
Token t;
boolean kbnfound = false;
}
{
t =
{
if (!kbnfound) kbnfound = true;
else throw new ParseException("Duplicate Knowledgebase declaration. Found " + t.image + " as a knowledgebase name./n"
+" The knowledgeBase name has already been declared.");
return t.image;
}
}
String ruleId() :
{
Token t;
boolean rnfound = false;
}
{
t =
{
Enumeration e = ruleNames.elements();
for ( ; e.hasMoreElements(); ) {
String name = (String) e.nextElement();
if (name.equalsIgnoreCase(t.image)) throw new
ParseException("Duplicate rule declaration. The name of this rule is used for another rule definition: " + t.image);
}
if (!rnfound) ruleNames.addElement(t.image);
return t.image;
}
}