// OO jDREW - An Object Oriented extension of the Java Deductive Reasoning Engine for the Web
// Copyright (C) 2005 Marcel Ball
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
package org.ruleml.oojdrew.util;
import java.io.ByteArrayOutputStream;
import java.util.Vector;
import nu.xom.Attribute;
import nu.xom.Document;
import nu.xom.Element;
import org.ruleml.oojdrew.Config;
import org.ruleml.oojdrew.parsing.RuleMLFormat;
import org.ruleml.oojdrew.parsing.RuleMLTagNames;
/**
* An object that represents a logic term (Ind, Var, Cterm Plex, Atom). For a
* simple term (ind or variable) the subTerms array is set to null, for
* non-simple terms (atoms, complex terms, plexs) the subTerms array contains
* the parameters for that term.
*
* <p>
* Title: OO jDREW
* </p>
*
* <p>
* Description: A deductive reasoning engine for Object-Oriented Knowledge in OO
* RuleML
* </p>
*
* <p>
* Copyright: Copyright (c) 2005
* </p>
*
* @author Marcel Ball
* @version 0.89
*/
public class Term implements Comparable {
/**
* This is a regular expression to test against to see if a symbol needs to
* be quoted when producing POSL format output.
*/
public static final String regex = "^(-)?[a-zA-Z0-9\\$][a-zA-Z0-9_\\$\\.]*$";
/**
* The symbol code to be used for this term, for a variable this is a
* negative number - and the variable name is stored in the variableNames
* array of the DefiniteClause object, for a ind this is a positive number
* and the symbol text is stored in the SymbolTable.
*/
public int symbol;
/**
* The role name code to be used for this term, for a positional argument
* this is equal to the INOROLE member of the SymbolTable. For slotted
* arguments the name of the role is stored in the SymbolTable.
*/
public int role;
/**
* The type code to be used for this term, the types for the engine are
* defined by an RDFS file, and are parsed by the RDFSParser object into the
* Types system.
*/
public int type;
/**
* The symbol code for the URI for this term; The actual URI is stored in
* the SymbolTable.
*/
public int href = -1;
/**
* subTerms Term[] An array containing the terms that will be the parameters
* of this atom, cterm or plex that is being created.
*/
public Term[] subTerms = null;
/**
* This is used to tell if the Term is an atom or not.
*/
public boolean atom = false;
/**
* -1 is assigned as the rest if this is a simple term or a complex term
* with no slotted rest parameter.
*/
public int rest = -1;
/**
* -1 is assigned as the positional rest if this is a simple term or a
* complex term with no positional slotted rest parameter.
*/
public int prest = -1;
/**
* Used by the unification process to check what clause a term belongs to
* when doing unification. This is not used elsewhere.
*/
int side;
/**
* This is used to distinguish between Data and Ind
*/
private boolean isData = false;
/**
* This is used to distinguish between Data and Ind, when using slots
*/
private boolean dataSlot = false;
/**
* Creates a new simple term (variable or ind).
*
* @param symbol
* The symbol code to be used for this term, for a variable this
* is a negative number - and the variable name is stored in the
* variableNames array of the DefiniteClause object, for a ind
* this is a positive number and the symbol text is stored in the
* SymbolTable.
*
* @param role
* The role name code to be used for this term, for a positional
* argument this is equal to the INOROLE member of the
* SymbolTable. For slotted arguments the name of the role is
* stored in the SymbolTable.
*
* @param type
* The type code to be used for this term, the types for the
* engine are defined by an RDFS file, and are parsed by the
* RDFSParser object into the Types system.
*/
public Term(int symbol, int role, int type) {
this.symbol = symbol;
this.role = role;
this.type = type;
}
/**
* Create a new simple term with a URI reference or label (must be ind)
*
* @param symbol
* The symbol code to be used for this term, for a variable this
* is a negative number - and the variable name is stored in the
* variableNames array of the DefiniteClause object, for a ind
* this is a positive number and the symbol text is stored in the
* SymbolTable.
*
* @param role
* The role name code to be used for this term, for a positional
* argument this is equal to the INOROLE member of the
* SymbolTable. For a slotted parameter the role name is stored
* in the SymbolTable.
*
* @param type
* The type code to be used for this term, the types for the
* engine are defined by an RDFS file, and are parsed by the
* RDFSParser object into the Types system.
*
* @param href
* The symbol code for the URI for this term; The actual URI is
* stored in the SymbolTable.
*/
public Term(int symbol, int role, int type, int href) {
this.symbol = symbol;
this.role = role;
this.type = type;
this.href = href;
}
/**
* Creates a new complex term (atom, expr, plex).
*
* @param symbol
* The symbol code to be used for the relation or constructor of
* this term, this is always a positive number and the symbol
* text is stored in the SymbolTable.
*
* @param role
* The role name code to be used for this term, for a positional
* argument this is equal to the INOROLE member of the
* SymbolTable. For a slotted parameter the role name is stored
* in the SymbolTable.
*
* @param type
* The type code to be used for this term, the types for the
* engine are defined by an RDFS file, and are parsed by the
* RDFSParser object into the Types system.
*
* @param subTerms
* An array containing the terms that will be the parameters of
* this atom, expr or plex that is being created.
*/
public Term(int symbol, int role, int type, Term[] subTerms) {
this(symbol, role, type);
Vector st = this.sort(subTerms);
this.subTerms = new Term[st.size()];
for (int i = 0; i < st.size(); i++) {
this.subTerms[i] = (Term) st.get(i);
if (this.subTerms[i].getRole() == SymbolTable.IREST) {
rest = i;
}
if (this.subTerms[i].getRole() == SymbolTable.IPREST) {
prest = i;
}
}
}
/**
* Creates a new complex term (atom, expr, plex).
*
* @param symbol
* The symbol code to be used for the relation or constructor of
* this term, this is always a positive number and the symbol
* text is stored in the SymbolTable.
*
* @param role
* The role name code to be used for this term, for a positional
* argument this is equal to the INOROLE member of the
* SymbolTable. For a slotted parameter the role name is stored
* in the SymbolTable.
*
* @param type
* The type code to be used for this term, the types for the
* engine are defined by an RDFS file, and are parsed by the
* RDFSParser object into the Types system.
*
* @param subTerms
* Vector value An array containing the terms that will be the
* parameters of this atom, expr or plex that is being created.
*/
public Term(int symbol, int role, int type, Vector subTerms) {
this(symbol, role, type);
Vector st = this.sort(subTerms);
this.subTerms = new Term[st.size()];
for (int i = 0; i < st.size(); i++) {
this.subTerms[i] = (Term) st.get(i);
if (this.subTerms[i].getRole() == SymbolTable.IREST) {
rest = i;
}
if (this.subTerms[i].getRole() == SymbolTable.IPREST) {
prest = i;
}
}
}
/**
* A method to get the symbol for a role within a complex term. If the r
* value is "" this will return the first positional argument. Also if there
* is more than one value of a role name this will return the first one.
*
* @param r
* String A string containing the name of the role to retrieve
* the symbol for.
*
* @return A string containing the symbol associated with the passed role.
* If this is a variable it will be returned as ?Varx, were x is the
* variable id, for for complex term this will contain the
* constructor symbol. Values are not enclosed within " even if this
* would be required for POSL Syntax.
*
*/
public String getSymbolForRole(String r) {
int role = SymbolTable.internRole(r);
for (int i = 0; i < this.subTerms.length; i++) {
if (subTerms[i].getRole() == role) {
return subTerms[i].getSymbolString();
}
}
return null;
}
/**
* Gets the symbol code for this term. If it is a complex term this gives
* the symbol code for the predicate/constructor. If this value is a
* negative number then this term is a variable.
*
* @return The symbol code for this term.
*/
public int getSymbol() {
return symbol;
}
/**
* Sets the symbol code for this term.
*
* @param symbol
* The value to set symbol to.
*/
public void setSymbol(int symbol) {
this.symbol = symbol;
}
/**
* Gets the symbol for this term. If it is a complex term this gives the
* symbol for the predicate/constructor. If it is a variable then the symbol
* is prefixed with a ?.
*
* @return The symbol for this term.
*/
public String getSymbolString() {
if (symbol > 0) {
return SymbolTable.symbol(symbol);
} else {
return "?Var" + (-(symbol + 1));
}
}
/**
* Gets the role name code for this term. If this is a rest paramater it
* will be equal to the IREST member of the associated SymbolTable. If this
* is a positional argument it will be equal to the INOROLE member of the
* associated SymbolTable.
*
* @return The role code for this term.
*/
public int getRole() {
return role;
}
/**
* Sets the role code for this term.
*
* @param role
* The value to set role to.
*/
public void setRole(int role) {
this.role = role;
}
/**
* Gets the role name for this term. If this is a positional argument this
* will be an empty string, for a rest parameter it will be '$REST',
* otherwise it is the name of the role.
*
* @return The role name for this term.
*/
public String getRoleString() {
return SymbolTable.role(role);
}
/**
* Gets the type code for this term. For an untyped term this will be equal
* to the IOBJECT member of the TypeHierarchy associated with the clause.
*
* @return The type code for this term.
*/
public int getType() {
return type;
}
/**
* Sets the type code for this term.
*
* @param type
* The value to set type to.
*/
public void setType(int type) {
this.type = type;
}
/**
* Gets the value of the side member variable - this is used by the
* unification process to keep track of terms.
*
* @return The current value of the side member.
*/
public int getSide() {
return side;
}
/**
* Sets the value of the side member variable.
*
* @param side
* The value to set side to.
*/
public void setSide(int side) {
this.side = side;
}
/**
* Gets the index of the slotted rest parameter.
*
* @return The index of the slotted rest parameter within this term, or -1
* if this is a simple term or a complex term with no slotted rest
* parameter.
*/
public int getRest() {
return rest;
}
/**
* Gets the index of the positional rest parameter.
*
* @return The index of the position rest parameter within this term, or -1
* if this is a simple term or a complex term with no positional
* rest parameter.
*/
public int getPosRest() {
return prest;
}
/**
* Gets an array of the arguments for this term.
*
* @return A Term[] array of the parameters for this term. Returns null if
* this is a simple term (variable or ind).
*/
public Term[] getSubTerms() {
return subTerms;
}
/**
* Tests if a term is a complex term.
*
* @return True if this term is a complex term (atom, expr, tup) false
* otherwise.
*/
public boolean isExpr() {
return (subTerms != null);
}
/**
* Test if this term is an atom.
*
* @return boolean value - true if this term is an atom, false otherwise.
* This is used only by the output routines, for other things Expr
* and Atoms can be treated the same.
*/
public boolean isAtom() {
return (subTerms != null && atom);
}
/**
* Sets the boolean atom flag to the passed value, if the atom member
* variable is set to true and it is not a complex term (subTerms array is
* set to null) isAtom() will still return false.
*
* @param atom
* The value that the atom member should be set to.
*/
public void setAtom(boolean atom) {
this.atom = atom;
}
/**
* Sets the isData flag to the passed value, if isData variable is set to
* true then it is a data element if not it is a Ind
*
* @param data
* The value that the isData member should be set to.
*/
public void setData(boolean data) {
isData = data;
}
/**
* Gets the isData vaule
*
* @return The value of the isData member
*/
public boolean getData() {
return isData;
}
/**
* Sets the isDataSlot flag to the passed value, if isDataSlot variable is
* set to true then it is a data element if not it is a Ind inside the slot.
*
* @param data
* The value that the isDataSlot member should be set to.
*/
public void setDataSlot(boolean data) {
dataSlot = data;
}
/**
* Gets the isDataSlot value
*
* @return The value that the isDataSlot member
*/
public boolean getDataSlot() {
return dataSlot;
}
/**
* Returns a string representation of this term. The format of this string
* is determined by the value of the PRPRINT static variable in the
* org.ruleml.oojdrew.Config class. If this is true, this will produce a
* string in POSL syntax, otherwise it will produce a string in OO RuleML
* XML syntax.
*
* This method is used when you do not have access to the variable names;
* variables are output as ?Varx - where x is the variable id.
*
* @param rmlFormat
* RuleMLFormat, to determine which RuleML version to use.
*
* @return The String representation of this term.
*/
public String toString(RuleMLFormat rmlFormat) {
if (Config.PRPRINT) {
return this.toPOSLString(true);
} else {
return this.toRuleMLString(rmlFormat);
}
}
/**
* Returns a string representation of this term. The format of this string
* is determined by the value of the PRPRINT static variable in the
* org.ruleml.oojdrew.Config class. If this is true, this will produce a
* string in POSL syntax, otherwise it will produce a string in OO RuleML
* XML syntax.
*
* @param rmlFormat
* RuleMLFormat, to determine which RuleML version to use.
*
* @param varNames
* String array containing the variable names
*
* @return The String representation of this term.
*/
public String toString(String[] varNames, RuleMLFormat rmlFormat) {
if (Config.PRPRINT) {
return this.toPOSLString(varNames, true);
} else {
return this.toRuleMLString(varNames, rmlFormat);
}
}
/**
* Returns a string representation of this term in POSL syntax. This method
* is used in cases where you do not have access to the variable names
* associated with the clause - variable names will be output as ?Varx where
* x is the variable id.
*
* @return The POSL syntax representation of this term.
*/
public String toPOSLString(boolean head) {
String s = "";
if (this.role != SymbolTable.INOROLE && this.role != SymbolTable.IREST
&& this.role != SymbolTable.IPREST) {
String rs = SymbolTable.role(this.role);
if (!rs.matches(regex)) {
rs = "\"" + rs + "\"";
}
s += rs + "->";
}
if (this.symbol < 0) {
s += "?Var" + (-(symbol + 1));
} else {
if (this.symbol != SymbolTable.INAF
&& this.symbol != SymbolTable.IPLEX
&& this.symbol != SymbolTable.IASSERT) {
String sym = SymbolTable.symbol(this.symbol);
if (sym.startsWith("$gensym")
&& !org.ruleml.oojdrew.Config.PRINTGENSYMS) {
int idx = sym.indexOf("$", 7);
if (idx > -1) {
String skoname = sym.substring(idx + 1);
if (!sym.matches(regex)) {
skoname = "\"" + skoname + "\"";
}
sym = "_" + skoname;
} else
sym = "_";
} else if (!sym.matches(regex)) {
sym = "\"" + sym + "\"";
}
s += sym;
}
}
if (this.isAtom() && this.symbol == SymbolTable.INAF) {
s += "naf(";
for (int i = 0; i < this.subTerms.length; i++) {
s += this.subTerms[i].toPOSLString(head);
if ((i + 1) < this.subTerms.length) {
s += ",";
}
}
s += ")";
} else if (this.isAtom() && this.symbol == SymbolTable.IASSERT) {
s += "assert( ";
s += this.subTerms[0].toPOSLString(true);
if (this.subTerms.length > 1) {
s += " :- ";
for (int i = 1; i < this.subTerms.length; i++) {
s += this.subTerms[i].toPOSLString(false);
if (i + 1 < this.subTerms.length) {
s += ", ";
}
}
}
s += ". )";
} else if (this.isExpr()) {
String sb;
String eb;
if (this.isAtom()) {
sb = "(";
eb = ")";
} else {
sb = "[";
eb = "]";
}
s += sb;
for (int i = 0; i < this.subTerms.length; i++) {
if (this.subTerms[i].role == SymbolTable.IREST) {
s += " !"; // handle printout if term is a slotted rest term
} else if (this.subTerms[i].role == SymbolTable.IPREST) {
s += " |"; // handle printout if term is a positional rest
// term
}
if (this.subTerms[i].role == SymbolTable.IOID
&& !org.ruleml.oojdrew.Config.PRINTGENOIDS && head) {
if (this.subTerms[i].getSymbolString()
.startsWith("$gensym"))
continue;
}
// get rid of blank oid here
s += this.subTerms[i].toPOSLString(head);
if (this.subTerms[i].role == SymbolTable.IOID) {
s += "^ ";
}
if ((i + 1) < this.subTerms.length) {
if (this.subTerms[i].role != SymbolTable.IOID
&& this.subTerms[i + 1].role == SymbolTable.INOROLE) {
s += ", ";
} else if (this.subTerms[i + 1].role == SymbolTable.IREST) {
} else if (this.subTerms[i + 1].role == SymbolTable.IPREST) {
} else if (this.subTerms[i].role != SymbolTable.IOID) {
s += "; ";
}
}
}
s += eb;
}
if (this.type != Types.IOBJECT) {
String ts = Types.typeName(this.type);
if (!ts.matches(regex)) {
ts = "\"" + ts + "\"";
}
s += " : " + ts;
}
return s;
}
/**
* Returns a string representation of this term in POSL syntax.
*
* @param varNames
* A string array containing the variable names to use when
* outputting the string. These are stored in the DefiniteClause
* that the term is part of.
*
* @return The POSL syntax representation of the term.
*/
public String toPOSLString(String[] varNames) {
return toPOSLString(varNames, false, true);
}
public String toPOSLString(String[] varNames, boolean head) {
return toPOSLString(varNames, false, head);
}
/**
* Returns a string representation of this term in POSL syntax, with the
* option of omitting the role name. This is used by the mechanism for
* saving variable bindings.
*
* @param varNames
* A string array containing the variable names to use when
* outputting the string. These are stored in the DefiniteClause
* that the term is part of.
*
* @param skiprole
* If true then the role name is omitted from the string output,
* otherwise the role name is included.
*
* @param head
* If true then the atom is the head of a rule.
*
* @return String The POSL syntax representation of the term.
*/
public String toPOSLString(String[] varNames, boolean skiprole, boolean head) {
String s = "";
if (!skiprole) {
if (this.role != SymbolTable.INOROLE
&& this.role != SymbolTable.IREST
&& this.role != SymbolTable.IPREST
&& this.role != SymbolTable.IOID) {
String rs = SymbolTable.role(this.role);
if (!rs.matches(regex)) {
rs = "\"" + rs + "\"";
}
s += rs + "->";
}
}
if (this.symbol < 0) {
if (varNames[-(symbol + 1)].startsWith("$ANON")
&& !org.ruleml.oojdrew.Config.PRINTANONVARNAMES) {
s += "?";
} else {
s += "?" + varNames[-(symbol + 1)];
if (org.ruleml.oojdrew.Config.PRINTVARID) {
s += "_" + (-(symbol + 1));
}
}
} else {
if (this.symbol != SymbolTable.INAF
&& this.symbol != SymbolTable.IPLEX
&& this.symbol != SymbolTable.IASSERT) {
String sym = SymbolTable.symbol(this.symbol);
if (sym.startsWith("$gensym")
&& !org.ruleml.oojdrew.Config.PRINTGENSYMS) {
int idx = sym.indexOf("$", 7);
if (idx > -1) {
String skoname = sym.substring(idx + 1);
if (!sym.matches(regex)) {
skoname = "\"" + skoname + "\"";
}
sym = "_" + skoname;
} else
sym = "_";
} else if (!sym.matches(regex)) {
sym = "\"" + sym + "\"";
}
s += sym;
}
}
if (this.isAtom() && this.symbol == SymbolTable.INAF) {
s += "naf( ";
for (int i = 0; i < this.subTerms.length; i++) {
s += this.subTerms[i].toPOSLString(varNames, head);
if ((i + 1) < this.subTerms.length) {
s += ",";
}
}
s += " )";
} else if (this.isAtom() && this.symbol == SymbolTable.IASSERT) {
s += "assert( ";
s += this.subTerms[0].toPOSLString(varNames, true);
if (this.subTerms.length > 1) {
s += " :- ";
for (int i = 1; i < this.subTerms.length; i++) {
s += this.subTerms[i].toPOSLString(varNames, false);
if (i + 1 < this.subTerms.length) {
s += ", ";
}
}
}
s += ". )";
} else if (this.isExpr()) {
String sb;
String eb;
if (this.isAtom()) {
sb = "(";
eb = ")";
} else {
sb = "[";
eb = "]";
}
s += sb;
for (int i = 0; i < this.subTerms.length; i++) {
if (this.subTerms[i].role == SymbolTable.IREST) {
s += "!"; // handle printout if first term is a slotted rest
// term
} else if (this.subTerms[i].role == SymbolTable.IPREST) {
s += "|"; // handle printout if first term is a positional
// rest term
}
if (this.subTerms[i].role == SymbolTable.IOID
&& !org.ruleml.oojdrew.Config.PRINTGENOIDS) {
if (this.subTerms[i].symbol > 0
&& this.subTerms[i].getSymbolString().startsWith(
"$gensym") && head)
continue;
if (this.subTerms[i].symbol < 0
&& varNames[-(this.subTerms[i].symbol + 1)]
.startsWith("$ANON") && !head)
continue;
}
s += this.subTerms[i].toPOSLString(varNames, head);
if (this.subTerms[i].role == SymbolTable.IOID) {
s += "^ ";
}
if ((i + 1) < this.subTerms.length) {
if (this.subTerms[i].role != SymbolTable.IOID
&& this.subTerms[i + 1].role == SymbolTable.INOROLE) {
s += ", ";
} else if (this.subTerms[i + 1].role == SymbolTable.IREST) {
} else if (this.subTerms[i + 1].role == SymbolTable.IPREST) {
} else if (this.subTerms[i].role != SymbolTable.IOID) {
s += "; ";
}
}
}
s += eb;
}
if (this.type != Types.IOBJECT) {
String ts = Types.typeName(this.type);
if (!ts.matches(regex)) {
ts = "\"" + ts + "\"";
}
s += " : " + ts;
}
return s;
}
// String solution to print instantiated facts
public String toPOSLStringAll(String[] varNames, boolean skiprole,
boolean head) {
String s = "";
if (!skiprole) {
if (this.role != SymbolTable.INOROLE
&& this.role != SymbolTable.IREST
&& this.role != SymbolTable.IPREST
&& this.role != SymbolTable.IOID) {
String rs = SymbolTable.role(this.role);
if (!rs.matches(regex)) {
rs = "\"" + rs + "\"";
}
s += rs + "->";
}
}
if (this.symbol < 0) {
if (varNames[-(symbol + 1)].startsWith("$ANON")
&& !org.ruleml.oojdrew.Config.PRINTANONVARNAMES) {
s += "?";
} else {
s += "?" + varNames[-(symbol + 1)];
if (org.ruleml.oojdrew.Config.PRINTVARID) {
s += "" + (-(symbol + 1));
}
}
} else {
if (this.symbol != SymbolTable.INAF
&& this.symbol != SymbolTable.IPLEX
&& this.symbol != SymbolTable.IASSERT) {
String sym = SymbolTable.symbol(this.symbol);
if (sym.startsWith("$gensym")
&& !org.ruleml.oojdrew.Config.PRINTGENSYMS) {
int idx = sym.indexOf("$", 7);
if (idx > -1) {
String skoname = sym.substring(idx + 1);
if (!sym.matches(regex)) {
skoname = "\"" + skoname + "\"";
}
sym = "" + skoname;
} else
sym = "";
} else if (!sym.matches(regex)) {
sym = "\"" + sym + "\"";
}
s += sym;
}
}
if (this.isAtom() && this.symbol == SymbolTable.INAF) {
s += "naf( ";
for (int i = 0; i < this.subTerms.length; i++) {
s += this.subTerms[i].toPOSLString(varNames, head);
if ((i + 1) < this.subTerms.length) {
s += ",";
}
}
s += " )";
} else if (this.isAtom() && this.symbol == SymbolTable.IASSERT) {
s += "assert( ";
s += this.subTerms[0].toPOSLString(varNames, true);
if (this.subTerms.length > 1) {
s += " :- ";
for (int i = 1; i < this.subTerms.length; i++) {
s += this.subTerms[i].toPOSLString(varNames, false);
if (i + 1 < this.subTerms.length) {
s += ", ";
}
}
}
s += ". )";
} else if (this.isExpr()) {
String sb;
String eb;
if (this.isAtom()) {
sb = "(";
eb = ")";
} else {
sb = "[";
eb = "]";
}
s += sb;
for (int i = 0; i < this.subTerms.length; i++) {
if (this.subTerms[i].role == SymbolTable.IREST) {
s += "!"; // handle printout if first term is a slotted rest
// term
} else if (this.subTerms[i].role == SymbolTable.IPREST) {
s += "|"; // handle printout if first term is a positional
// rest term
}
if (this.subTerms[i].role == SymbolTable.IOID
&& !org.ruleml.oojdrew.Config.PRINTGENOIDS) {
if (this.subTerms[i].symbol > 0
&& this.subTerms[i].getSymbolString().startsWith(
"$gensym") && head)
continue;
if (this.subTerms[i].symbol < 0
&& varNames[-(this.subTerms[i].symbol + 1)]
.startsWith("$ANON") && !head)
continue;
}
// get rid of blank oid here
String s2 = "";
s2 = this.subTerms[i].toPOSLString(varNames, head);
if (s2.compareTo("_") != 0) {
s += s2;
}
if (this.subTerms[i].role == SymbolTable.IOID) {
// s += "^ ";
}
if ((i + 1) < this.subTerms.length) {
if (this.subTerms[i].role != SymbolTable.IOID
&& this.subTerms[i + 1].role == SymbolTable.INOROLE) {
s += ", ";
} else if (this.subTerms[i + 1].role == SymbolTable.IREST) {
} else if (this.subTerms[i + 1].role == SymbolTable.IPREST) {
} else if (this.subTerms[i].role != SymbolTable.IOID) {
s += "; ";
}
}
}
s += eb;
}
if (this.type != Types.IOBJECT) {
String ts = Types.typeName(this.type);
if (!ts.matches(regex)) {
ts = "\"" + ts + "\"";
}
s += " : " + ts;
}
return s;
}
/**
* Produces an OO RuleML XML syntax representation of this term, stored in a
* string.
*
* This version is for the case where you do not have access to the variable
* names for the term.
*
* @param rmlFormat
* RuleMLFormat, to determine which RuleML version to use.
*
* @return The OO RuleML syntax representation of this, stored as a
* "pretty printed" string.
*/
public String toRuleMLString(RuleMLFormat rmlFormat) {
Element rml = this.toRuleML(true, rmlFormat);
ByteArrayOutputStream os = new ByteArrayOutputStream();
nu.xom.Serializer sl = new nu.xom.Serializer(os);
sl.setIndent(3);
sl.setLineSeparator("\n");
try {
Document doc = new Document(rml);
sl.write(doc);
} catch (java.io.IOException e) {
System.err.println(e.getMessage());
}
return os.toString();
}
/**
* Produces an OO RuleML XML syntax representation of this term, stored in a
* string.
*
* @param varNames
* A string array containing the variable names to use when
* outputting - these are stored in the DefiniteClause object
* associated with the term.
*
* @param rmlFormat
* RuleMLFormat, to determine which RuleML version to use.
*
* @return A string containing the OO RuleML XML representation of this
* term.
*/
public String toRuleMLString(String[] varNames, RuleMLFormat version) {
Element rml = this.toRuleML(varNames, true, version);
ByteArrayOutputStream os = new ByteArrayOutputStream();
nu.xom.Serializer sl = new nu.xom.Serializer(os);
sl.setIndent(3);
sl.setLineSeparator("\n");
try {
Document doc = new Document(rml);
sl.write(doc);
} catch (java.io.IOException e) {
System.err.println(e.getMessage());
}
return os.toString();
}
/**
* Produces an OO RuleML XML syntax representation of this term, stored in a
* nu.xom.Element object.
*
* This version is for when you do not have access to the variable names.
*
* @see toRuleML(String[] varNames, boolean head, RuleMLFormat rmlFormat)
*/
public Element toRuleML(boolean head, RuleMLFormat rmlFormat) {
return toRuleML(null, head, rmlFormat);
}
/**
* Produces an OO RuleML XML syntax representation of this term, stored in a
* nu.xom.Element object.
*
* @param varNames
* The variable names associated with the term; these are stored
* in the DefiniteClause object associated with the term.
*
* @param rmlFormat
* RuleMLFormat, to determine which RuleML version to use.
*
* @return The OO RuleML syntax representation of this, as an Element value.
*/
public Element toRuleML(String[] varNames, boolean head, RuleMLFormat rmlFormat) {
RuleMLTagNames rmlTagNames = new RuleMLTagNames(rmlFormat);
// Printing the Clauses in RuleML Format
Element el = null;
boolean dst = false;
if (this.isExpr()) {
if (this.isAtom() && this.symbol == SymbolTable.INAF) {
el = new Element(rmlTagNames.NAF);
} else if (this.isAtom() && this.symbol == SymbolTable.IASSERT) {
el = new Element(rmlTagNames.ASSERT);
if (this.subTerms.length == 1) {
el.insertChild(subTerms[0].toRuleML(varNames, true, rmlFormat), 0);
} else {
Element implies = new Element(rmlTagNames.IMPLIES);
if (this.subTerms.length > 2) {
Element and = new Element(rmlTagNames.AND);
for (int i = 1; i < this.subTerms.length; i++) {
and.appendChild(this.subTerms[i].toRuleML(varNames, false, rmlFormat));
}
implies.appendChild(and);
} else {
implies.appendChild(this.subTerms[1].toRuleML(varNames, false, rmlFormat));
}
implies.appendChild(this.subTerms[0].toRuleML(varNames, true, rmlFormat));
el.appendChild(implies);
}
dst = true;
} else if (this.isAtom()) {
el = new Element(rmlTagNames.ATOM);
Element rel = new Element(rmlTagNames.REL);
el.insertChild(rel, el.getChildCount());
rel.insertChild(SymbolTable.symbol(this.symbol), 0);
} else if (this.symbol == SymbolTable.IPLEX) {
el = new Element(rmlTagNames.PLEX);
} else {
el = new Element(rmlTagNames.EXPR);
Element fun = new Element(rmlTagNames.FUN);
el.insertChild(fun, el.getChildCount());
fun.insertChild(SymbolTable.symbol(this.symbol), 0);
}
Element subElement;
for (int i = 0; i < this.subTerms.length && !dst; i++) {
subElement = this.subTerms[i].toRuleML(varNames, head, rmlFormat);
if (subElement != null) {
el.insertChild(subElement, el.getChildCount());
}
}
} else {
if (this.role == SymbolTable.IOID
&& !org.ruleml.oojdrew.Config.PRINTGENOIDS) {
if (this.symbol > 0
&& this.getSymbolString().startsWith("$gensym") && head)
return null;
else if (varNames != null && this.symbol < 0
&& varNames[-(this.symbol + 1)].startsWith("$ANON")
&& !head)
return null;
}
if (this.symbol < 0) {
el = new Element(rmlTagNames.VAR);
if (varNames != null
&& (!varNames[-(symbol + 1)].startsWith("$ANON") || org.ruleml.oojdrew.Config.PRINTANONVARNAMES)) {
String varName = varNames[-(symbol + 1)];
if (org.ruleml.oojdrew.Config.PRINTVARID) {
varName += -(symbol + 1);
}
el.insertChild(varName, 0);
} else {
el.insertChild(rmlTagNames.VAR + (-(symbol + 1)), 0);
}
} else {
String sym = SymbolTable.symbol(this.symbol);
if (sym.startsWith("$gensym")
&& !org.ruleml.oojdrew.Config.PRINTGENSYMS) {
el = new Element(rmlTagNames.SKOLEM);
int idx = sym.indexOf("$", 7);
if (idx > -1) {
String skoname = sym.substring(idx + 1);
el.appendChild(skoname);
}
} else {
if (isData) {
el = new Element(rmlTagNames.DATA);
el.insertChild(sym, 0);
}
if (!isData) {
el = new Element(rmlTagNames.IND);
el.insertChild(sym, 0);
}
}
}
}
if (this.type != Types.IOBJECT) {
Attribute typeAttribute = new Attribute(rmlTagNames.TYPE, Types.typeName(type));
el.addAttribute(typeAttribute);
}
if (this.role == SymbolTable.IREST) {
Element resl = new Element(rmlTagNames.RESL);
resl.insertChild(el, 0);
return resl;
} else if (this.role == SymbolTable.IPREST) {
Element repo = new Element(rmlTagNames.REPO);
repo.insertChild(el, 0);
return repo;
} else if (this.role == SymbolTable.IOID) {
Element oid = new Element(rmlTagNames.OID);
oid.insertChild(el, 0);
return oid;
} else if (this.role == SymbolTable.INOROLE) {
return el;
} else {
Element slot = new Element(rmlTagNames.SLOT);
Element child = null;
// If isData is true then change it here
if (dataSlot) {
child = new Element(rmlTagNames.DATA);
} else {
child = new Element(rmlTagNames.IND);
}
child.appendChild(SymbolTable.role(this.role));
slot.appendChild(child);
slot.appendChild(el);
return slot;
}
}
/**
* Make an identical deep (recursive) copy of this term. This is used when
* unifying to avoid making changes to the original data structures that
* represent clauses.
*
* @return A full copy of this term.
*/
public Term deepCopy() {
// False indicates not to change the original side values
return deepCopy(0, false);
}
/**
* Produces a deep (recursive) copy of this term, with the side member set
* to the specified value. This is used when Unifying to avoid making
* changes to the original data structures that represent clauses.
*
* @param pside
* The side value that should be stored in the copy.
*
* @return A full copy of this term.
*/
public Term deepCopy(int pside) {
// True indicates to change the original side values to pside
return deepCopy(pside, true);
}
/**
* @see deepCopy()
* @see deepCopy(int pside)
*/
private Term deepCopy(int newSideValue, boolean useNewSide) {
Term term;
if (this.subTerms != null) {
Term[] sterms = new Term[this.subTerms.length];
for (int i = 0; i < this.subTerms.length; i++) {
sterms[i] = this.subTerms[i].deepCopy(newSideValue, useNewSide);
}
term = new Term(this.symbol, this.role, this.type, sterms);
term.atom = this.atom;
} else {
term = new Term(this.symbol, this.role, this.type);
}
term.side = useNewSide ? newSideValue : this.side;
if (isData) {
term.setData(true);
}
return term;
}
/**
* Sorts a Vector of term objects by the role code.
*
* @param toSort
* A Vector containing only Term objects - to be sorted by the
* role name code.
*
* @return Vector A Vector containing the sorted terms.
*/
public static Vector sort(Vector toSort) {
Vector sorted = new Vector();
for (int i = 0; i < toSort.size(); i++) {
Term c = (Term) toSort.get(i);
int j = 0;
while (j < sorted.size()) {
Term chk = (Term) sorted.get(j);
if (c.getRole() >= chk.getRole()) {
j++;
} else {
break;
}
}
sorted.add(j, c);
}
return sorted;
}
/**
* Sorts an array of org.ruleml.oojdrew.util.Term values by the role code.
*
* @param toSort
* An array of Term objects to be sorted by the role name code.
*
* @return A Vector containing the sorted terms.
*/
public static Vector sort(Term[] toSort) {
Vector ts = new Vector();
for (int i = 0; i < toSort.length; i++) {
ts.add(toSort[i]);
}
return sort(ts);
}
/**
* Compares one term to another object. If this object is a Term object, it
* will compare first by the symbol code, then the role name code, the
* number of parameters, and finally by the actual parameters themselves. If
* the other object is not a Term, then this always returns 1.
*
* @param toCompare
* The object to compare this term to.
*
* @return The result of the comparison 1 if the other term is "less than",
* 0 if they are equal, or -1 if the other term is "greater than".
*/
public int compareTo(Object toCompare) {
if (this.getClass() != toCompare.getClass()) {
return 1;
}
Term o = (Term) toCompare;
if (this.symbol < o.symbol) {
return 1;
} else if (this.symbol > o.symbol) {
return -1;
} else {
if (this.role < o.role) {
return 1;
} else if (this.role > o.role) {
return -1;
} else {
if (this.subTerms == null) {
return 0;
}
if (this.subTerms.length < o.subTerms.length) {
return 1;
} else if (this.subTerms.length > o.subTerms.length) {
return -1;
} else {
for (int i = 0; i < this.subTerms.length; i++) {
int cmp = this.subTerms[i].compareTo(o.subTerms[i]);
if (cmp != 0) {
return cmp;
}
}
return 0;
}
}
}
}
}