public interface Reasoner {
    public void clearClauses();
    public void loadClauses(Iterator iterator);
}
 public class AbsBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("abs");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();

        if (p2.getSymbol() < 0) {
            return null;
        }

        String p2s = p2.getSymbolString();
        Term r1;
        Term roid= new Term(SymbolTable.internSymbol("$jdrew-abs-" + p2s),
                            SymbolTable.IOID, Types.ITHING);

        if (p2.getType() == Types.IINTEGER) {
            long i;
            try {
                i = Long.parseLong(p2s);
            } catch (Exception e) {
                return null;
            }
            i = Math.abs(i);
            String results = "" + i;
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IINTEGER);
        } else if (p2.getType() == Types.IFLOAT) {
            double d;
            try {
                d = Double.parseDouble(p2s);
            } catch (Exception e) {
                return null;
            }
            d = Math.abs(d);
            String results = "" + d;
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IFLOAT);
        } else {
            return null;
        }

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class AddBuiltin implements Builtin {
    private int sym = SymbolTable.internSymbol("add");

    public DefiniteClause buildResult(Term t) {
    	//System.out.println("Top OF Add");
        if (t.getSymbol() != sym) {
            return null;
        }

        Term r1;

        boolean allint = true;

        double sum = 0;

        Vector v = new Vector();
        String oid = "$jdrew-add";
        for (int i = 2; i < t.subTerms.length; i++) {
            Term ti = t.subTerms[i].deepCopy();
            if (ti.getSymbol() < 0) {
                return null;
            }

            if (ti.getType() != Types.IINTEGER && ti.getType() != Types.IFLOAT) {
                return null;
            }
            if (ti.getType() == Types.IFLOAT) {
                allint = false;
            }


            double d;
            try {
                d = Double.parseDouble(ti.getSymbolString());
            } catch (Exception e) {
                return null;
            }

            oid += "+" + ti.getSymbolString();
            sum += d;
            v.add(ti);
        }

        if (allint) {
            String results = "" + (long) sum;
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IINTEGER);
        } else {
            String results = "" + sum;
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IFLOAT);
        }
        v.add(0, r1);
        v.add(0, new Term(SymbolTable.internSymbol(oid),
                          SymbolTable.IOID, Types.ITHING));


        Term atm = new Term(sym, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        //System.out.println("In add");
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return this.sym;
    }
}
 public interface Builtin {
    public abstract DefiniteClause buildResult(Term t);

    public abstract int getSymbol();
}
 public class CeilingBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("ceiling");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();

        if (p2.getSymbol() < 0) {
            return null;
        }

        String p2s = p2.getSymbolString();
        Term r1;
        Term roid = new Term(SymbolTable.internSymbol("$jdrew-ceiling-" + p2s),
                             SymbolTable.IOID, Types.ITHING);
        if (p2.getType() == Types.IINTEGER || p2.getType() == Types.IFLOAT) {
            double d;
            try {
                d = Double.parseDouble(p2s);
            } catch (Exception e) {
                return null;
            }

            String results = "" + (int) Math.ceil(d);
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IINTEGER);
        } else {
            return null;
        }

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class ContainsBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("contains");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p1 = t.subTerms[1].deepCopy();
        Term p2 = t.subTerms[2].deepCopy();

        if (p1.getSymbol() < 0 || p2.getSymbol() < 0) {
            return null;
        }

        if (p1.getType() != Types.ISTRING || p2.getType() != Types.ISTRING) {
            return null;
        }

        String p1s = p1.getSymbolString();
        String p2s = p2.getSymbolString();

        if (p1s.indexOf(p2s) == -1) {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-contains-" + p1s
                                                      + "-" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(p1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }
}
 public class ContainsIgnoreCaseBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("containsIgnoreCase");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p1 = t.subTerms[1].deepCopy();
        Term p2 = t.subTerms[2].deepCopy();

        if (p1.getSymbol() < 0 || p1.getSymbol() < 0) {
            return null;
        }

        if (p1.getType() != Types.ISTRING || p2.getType() != Types.ISTRING) {
            return null;
        }

        String p1s = p1.getSymbolString().toLowerCase();
        String p2s = p2.getSymbolString().toLowerCase();

        if (p1s.indexOf(p2s) == -1) {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-containsIC-"
                                                      + p1s + "-" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(p1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());

    }

    public int getSymbol() {
        return symbol;
    }


}
 public class CosBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("cos");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();

        if (p2.getSymbol() < 0) {
            return null;
        }

        if (p2.getType() != Types.IFLOAT && p2.getType() != Types.IINTEGER) {
            return null;
        }

        String p2s = p2.getSymbolString();

        double p2d;
        try {
            p2d = Double.parseDouble(p2s);
        } catch (Exception e) {
            return null;
        }

        double result = Math.cos(p2d);
        String results = "" + result;

        Term r1 = new Term(SymbolTable.internSymbol(results),
                           SymbolTable.INOROLE, Types.IFLOAT);
        Term roid = new Term(SymbolTable.internSymbol("$jdrew-cos-" + p2s),
                             SymbolTable.IOID, Types.ITHING);
        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class DateBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("date");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length == 6) {
            Term p2 = t.subTerms[2].deepCopy();
            Term p3 = t.subTerms[3].deepCopy();
            Term p4 = t.subTerms[4].deepCopy();
            Term p5 = t.subTerms[5].deepCopy();

            if (p2.getSymbol() < 0 || p3.getSymbol() < 0 || p4.getSymbol() < 0 || p5.getSymbol() < 0) {
                return null;
            }

            if (p2.getType() != Types.IINTEGER ||  p3.getType() != Types.IINTEGER || p4.getType() != Types.IINTEGER || p5.getType() != Types.ISTRING ){
                return null;
            }
            

            String p2s = p2.getSymbolString();
            String p3s = p3.getSymbolString();
            String p4s = p4.getSymbolString();
            String p5s = p5.getSymbolString();
            
            //negative year
            if(Integer.parseInt(p2s) < 0){
            	return null;
            }
            
            //invalid month
            if(Integer.parseInt(p3s)<0 || Integer.parseInt(p3s)>12){
            	return null;
            }
            
            //invalid day
            if(Integer.parseInt(p4s)<0 || Integer.parseInt(p4s)>31){
            	return null;
            }
            
            //check for proper syntax of timezone
            if(!p5s.matches("[+-][0-1][0-9](:)[0-5][0-9]")){
            	return null;
            }
            
            int h;
            if(p5s.charAt(0)=='+'){
            	h = Integer.parseInt(p5s.split(":")[0].substring(1));
            } else {
            	h = -Integer.parseInt(p5s.split(":")[0]);
            }            int m = Integer.parseInt(p5s.split(":")[1]);
            
            if(h<-12 || h>14 || !(m!=30 || m!=45 || m!=0)){
            	return null;
            }
    
        
        
        String results = p2s + "-" + p3s + "-" + p4s  + p5s;

            Term r1 = new Term(SymbolTable.internSymbol(results),
                               SymbolTable.INOROLE, Types.ISTRING);
            Term roid = new Term(SymbolTable.internSymbol("$jdrew-date-"
                                                          + p2s + "-" + p3s + "-" + p4s + "-" + p5s),
                                 SymbolTable.IOID, Types.ITHING);
            Vector v = new Vector();
            v.add(roid);
            v.add(r1);
            v.add(p2);
            v.add(p3);
            v.add(p4);
            v.add(p5);

            Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
            atm.setAtom(true);
            Vector v2 = new Vector();
            v2.add(atm);
            return new DefiniteClause(v2, new Vector());
        
        } else {
            return null;
        }
    }

    public int getSymbol() {
        return this.symbol;
    }
} public class DateTimeBuiltin implements Builtin {
	private int symbol = SymbolTable.internSymbol("dateTime");

	public DefiniteClause buildResult(Term t) {
		if (t.getSymbol() != symbol) {
			return null;
		}

		if (t.subTerms.length == 9) {
			Term p2 = t.subTerms[2].deepCopy();
			Term p3 = t.subTerms[3].deepCopy();
			Term p4 = t.subTerms[4].deepCopy();
			Term p5 = t.subTerms[5].deepCopy();
			Term p6 = t.subTerms[6].deepCopy();
			Term p7 = t.subTerms[7].deepCopy();
			Term p8 = t.subTerms[8].deepCopy();

			if (p2.getSymbol() < 0 || p3.getSymbol() < 0 || p4.getSymbol() < 0 || p5.getSymbol() < 0 || p6.getSymbol() < 0|| p7.getSymbol() < 0|| p8.getSymbol() < 0) {
				return null;
			}

			if (p2.getType() != Types.IINTEGER ||  p3.getType() != Types.IINTEGER || p4.getType() != Types.IINTEGER || p5.getType() != Types.IINTEGER || p6.getType() != Types.IINTEGER || p7.getType() != Types.IINTEGER || p8.getType() != Types.ISTRING ){
				return null;
			}


			String year = p2.getSymbolString();
			String month = p3.getSymbolString();
			String day = p4.getSymbolString();
			String hours = p5.getSymbolString();
			String minutes = p6.getSymbolString();
			String seconds  = p7.getSymbolString();
			String timezone = p8.getSymbolString();


			//negative year
			if(Integer.parseInt(year) < 0){
				return null;
			}

			//invalid month
			if(Integer.parseInt(month)<0 || Integer.parseInt(month)>12){
				return null;
			}

			//invalid day
			if(Integer.parseInt(day)<0 || Integer.parseInt(day)>31){
				return null;
			}

			//invalid hours
			if(Integer.parseInt(hours) < 0 || Integer.parseInt(hours)>=24){
				return null;
			}

			//invalid minutes
			if(Integer.parseInt(minutes)<0 || Integer.parseInt(minutes)>=60){
				return null;
			}

			//invalid seconds
			if(Integer.parseInt(seconds)<0 || Integer.parseInt(seconds)>=60){
				return null;
			}

			//check for proper syntax of timezone
			if(!timezone.matches("[+-][0-1][0-9](:)[0-5][0-9]")){
				return null;
			}

            int h;
            if(timezone.charAt(0)=='+'){
            	h = Integer.parseInt(timezone.split(":")[0].substring(1));
            } else {
            	h = -Integer.parseInt(timezone.split(":")[0]);
            }			
            int m = Integer.parseInt(timezone.split(":")[1]);

			if(h<-12 || h>14 || !(m!=30 || m!=45 || m!=0)){
				return null;
			}



			String results = year + "-" + month + "-" + day +"- "+ hours + "-" + minutes + "-" + seconds + timezone;

			Term r1 = new Term(SymbolTable.internSymbol(results),
					SymbolTable.INOROLE, Types.ISTRING);
			Term roid = new Term(SymbolTable.internSymbol("$jdrew-dateTime-"
					+ year + "-" + month + "-" + day + "-" + hours  + "-" + minutes + "-" + seconds + timezone),
					SymbolTable.IOID, Types.ITHING);
			Vector v = new Vector();
			v.add(roid);
			v.add(r1);
			v.add(p2);
			v.add(p3);
			v.add(p4);
			v.add(p5);
			v.add(p6);
			v.add(p7);
			v.add(p8);

			Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
			atm.setAtom(true);
			Vector v2 = new Vector();
			v2.add(atm);
			return new DefiniteClause(v2, new Vector());

		} else {
			return null;
		}
	}

	public int getSymbol() {
		return this.symbol;
	}
} public class DivideBuiltin implements Builtin {
    private int sym = SymbolTable.internSymbol("divide");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != sym) {
            return null;
        }

        if (t.subTerms.length != 4) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();
        Term p3 = t.subTerms[3].deepCopy();

        if (p2.getSymbol() < 0 || p3.getSymbol() < 0) {
            return null;
        }

        String p2s = p2.getSymbolString();
        String p3s = p3.getSymbolString();
        Term r1;

        if (p2.getType() == Types.IINTEGER && p3.getType() == Types.IINTEGER) {
            long p2i;
            long p3i;
            try {
                p2i = Long.parseLong(p2s);
                p3i = Long.parseLong(p3s);
            } catch (Exception e) {
                return null;
            }
            String results = "" + ((double) (p2i) / p3i);
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IFLOAT);
        } else if ((p2.getType() == Types.IFLOAT &&
                    p3.getType() == Types.IINTEGER) ||
                   (p2.getType() == Types.IINTEGER &&
                    p3.getType() == Types.IFLOAT) ||
                   (p2.getType() == Types.IFLOAT &&
                    p3.getType() == Types.IFLOAT)) {
            double p2d;
            double p3d;
            try {
                p2d = Double.parseDouble(p2s);
                p3d = Double.parseDouble(p3s);
            } catch (Exception e) {
                return null;
            }
            String results = "" + (p2d / p3d);
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IFLOAT);
        } else {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-divide-"
                                                      + p2s + "/" + p3s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);
        v.add(p3);

        Term atm = new Term(sym, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return this.sym;
    }
}
 public class EndsWithBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("endsWith");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p1 = t.subTerms[1].deepCopy();
        Term p2 = t.subTerms[2].deepCopy();

        if (p1.getSymbol() < 0 || p2.getSymbol() < 0) {
            return null;
        }

        if (p1.getType() != Types.ISTRING || p2.getType() != Types.ISTRING) {
            return null;
        }

        String p1s = p1.getSymbolString();
        String p2s = p2.getSymbolString();

        if (!p1s.endsWith(p2s)) {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-endswith-" + p1s
                                                      + "-" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(p1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class EqualBuiltin implements Builtin {
    private int sym = SymbolTable.internSymbol("equal");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != sym) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p1 = t.subTerms[1].deepCopy();
        Term p2 = t.subTerms[2].deepCopy();

        if (p1.getSymbol() < 0 || p2.getSymbol() < 0) {
            return null;
        }

        String p1s = p1.getSymbolString();
        String p2s = p2.getSymbolString();

        if ((p1.getType() == Types.IFLOAT || p1.getType() == Types.IINTEGER)
            && (p2.getType() == Types.IFLOAT || p2.getType() == Types.IINTEGER)) {

            double d1;
            double d2;

            try {
                d1 = Double.parseDouble(p1s);
                d2 = Double.parseDouble(p2s);
            } catch (Exception e) {
                return null;
            }

            if (d1 != d2) {
                return null;
            }
        } else {
            if (p1.symbol != p2.symbol) {
                return null;
            }
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-equals-"
                                                      + p1s + "-" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(p1);
        v.add(p2);

        Term atm = new Term(sym, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return this.sym;
    }
}
 public class FloorBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("floor");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();

        if (p2.getSymbol() < 0) {
            return null;
        }

        String p2s = p2.getSymbolString();
        Term r1;

        if (p2.getType() == Types.IINTEGER || p2.getType() == Types.IFLOAT) {
            double d;
            try {
                d = Double.parseDouble(p2s);
            } catch (Exception e) {
                return null;
            }

            String results = "" + (long) Math.floor(d);
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IINTEGER);
        } else {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-floor-" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class GreaterThanBuiltin implements Builtin {
    private int sym = SymbolTable.internSymbol("greaterThan");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != sym) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p1 = t.subTerms[1].deepCopy();
        Term p2 = t.subTerms[2].deepCopy();

        if (p1.getSymbol() < 0 || p2.getSymbol() < 0) {
            return null;
        }

        String p1s = p1.getSymbolString();
        String p2s = p2.getSymbolString();

        if ((p1.getType() == Types.IFLOAT || p1.getType() == Types.IINTEGER) &&
            (p2.getType() == Types.IFLOAT || p2.getType() == Types.IINTEGER)) {
            double d1;
            double d2;
            try {
                d1 = Double.parseDouble(p1s);
                d2 = Double.parseDouble(p2s);
            } catch (Exception e) {
                return null;
            }
            if (d1 <= d2) {
                return null;
            }
        } else if (p1.getType() == Types.ISTRING &&
                   p2.getType() == Types.ISTRING) {
            if (p1s.compareTo(p2s) <= 0) {
                return null;
            }
        } else {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-gt-"
                                                      + p1s + ">" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(p1);
        v.add(p2);

        Term atm = new Term(sym, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return this.sym;
    }
}
 public class GreaterThanOrEqualBuiltin implements Builtin {
    private int sym = SymbolTable.internSymbol("greaterThanOrEqual");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != sym) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p1 = t.subTerms[1].deepCopy();
        Term p2 = t.subTerms[2].deepCopy();

        if (p1.getSymbol() < 0 || p2.getSymbol() < 0) {
            return null;
        }

        String p1s = p1.getSymbolString();
        String p2s = p2.getSymbolString();

        if ((p1.getType() == Types.IFLOAT || p1.getType() == Types.IINTEGER) &&
            (p2.getType() == Types.IFLOAT || p2.getType() == Types.IINTEGER)) {
            double d1;
            double d2;
            try {
                d1 = Double.parseDouble(p1s);
                d2 = Double.parseDouble(p2s);
            } catch (Exception e) {
                return null;
            }
            if (d1 < d2) {
                return null;
            }
        } else if (p1.getType() == Types.ISTRING &&
                   p2.getType() == Types.ISTRING) {
            if (p1s.compareTo(p2s) < 0) {
                return null;
            }
        } else {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-gte-"
                                                      + p1s + ">=" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(p1);
        v.add(p2);

        Term atm = new Term(sym, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return this.sym;
    }
}
 public class IntegerDivideBuiltin implements Builtin {
    private int sym = SymbolTable.internSymbol("integerDivide");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != sym) {
            return null;
        }

        if (t.subTerms.length != 4) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();
        Term p3 = t.subTerms[3].deepCopy();

        if (p2.getSymbol() < 0 || p3.getSymbol() < 0) {
            return null;
        }

        String p2s = p2.getSymbolString();
        String p3s = p3.getSymbolString();
        Term r1;

        if (p2.getType() == Types.IINTEGER && p3.getType() == Types.IINTEGER) {
            long p2i;
            long p3i;
            try {
                p2i = Long.parseLong(p2s);
                p3i = Long.parseLong(p3s);
            } catch (Exception e) {
                return null;
            }
            String results = "" + (p2i / p3i);
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IINTEGER);
        } else {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-idivide-"
                                                      + p2s + "//" + p3s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);
        v.add(p3);

        Term atm = new Term(sym, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return this.sym;
    }
}
 public class LessThanBuiltin implements Builtin {
    private int sym = SymbolTable.internSymbol("lessThan");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != sym) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p1 = t.subTerms[1].deepCopy();
        Term p2 = t.subTerms[2].deepCopy();

        if (p1.getSymbol() < 0 || p2.getSymbol() < 0) {
            return null;
        }

        String p1s = p1.getSymbolString();
        String p2s = p2.getSymbolString();

        if ((p1.getType() == Types.IFLOAT || p1.getType() == Types.IINTEGER) &&
            (p2.getType() == Types.IFLOAT || p2.getType() == Types.IINTEGER)) {
            double d1;
            double d2;
            try {
                d1 = Double.parseDouble(p1s);
                d2 = Double.parseDouble(p2s);
            } catch (Exception e) {
                return null;
            }
            if (d1 >= d2) {
                return null;
            }
        } else if (p1.getType() == Types.ISTRING &&
                   p2.getType() == Types.ISTRING) {
            if (p1s.compareTo(p2s) >= 0) {
                return null;
            }
        } else {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-lt-"
                                                      + p1s + "<" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(p1);
        v.add(p2);

        Term atm = new Term(sym, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return this.sym;
    }
}
 public class LessThanOrEqualBuiltin implements Builtin {
    private int sym = SymbolTable.internSymbol("lessThanOrEqual");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != sym) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p1 = t.subTerms[1].deepCopy();
        Term p2 = t.subTerms[2].deepCopy();

        if (p1.getSymbol() < 0 || p2.getSymbol() < 0) {
            return null;
        }

        String p1s = p1.getSymbolString();
        String p2s = p2.getSymbolString();

        if ((p1.getType() == Types.IFLOAT || p1.getType() == Types.IINTEGER) &&
            (p2.getType() == Types.IFLOAT || p2.getType() == Types.IINTEGER)) {
            double d1;
            double d2;
            try {
                d1 = Double.parseDouble(p1s);
                d2 = Double.parseDouble(p2s);
            } catch (Exception e) {
                return null;
            }
            if (d1 > d2) {
                return null;
            }
        } else if (p1.getType() == Types.ISTRING &&
                   p2.getType() == Types.ISTRING) {
            if (p1s.compareTo(p2s) > 0) {
                return null;
            }
        } else {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-lte-"
                                                      + p1s + "<=" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(p1);
        v.add(p2);

        Term atm = new Term(sym, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return this.sym;
    }
}
 public class ModBuiltin implements Builtin {
    private int sym = SymbolTable.internSymbol("mod");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != sym) {
            return null;
        }

        if (t.subTerms.length != 4) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();
        Term p3 = t.subTerms[3].deepCopy();

        if (p2.getSymbol() < 0 || p3.getSymbol() < 0) {
            return null;
        }

        String p2s = p2.getSymbolString();
        String p3s = p3.getSymbolString();
        Term r1;

        if (p2.getType() == Types.IINTEGER && p3.getType() == Types.IINTEGER) {
            long p2i;
            long p3i;
            try {
                p2i = Long.parseLong(p2s);
                p3i = Long.parseLong(p3s);
            } catch (Exception e) {
                return null;
            }
            String results = "" + (p2i % p3i);
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IINTEGER);
        } else if ((p2.getType() == Types.IFLOAT &&
                    p3.getType() == Types.IINTEGER) ||
                   (p2.getType() == Types.IINTEGER &&
                    p3.getType() == Types.IFLOAT) ||
                   (p2.getType() == Types.IFLOAT &&
                    p3.getType() == Types.IFLOAT)) {
            double p2d;
            double p3d;
            try {
                p2d = Double.parseDouble(p2s);
                p3d = Double.parseDouble(p3s);
            } catch (Exception e) {
                return null;
            }
            String results = "" + (p2d % p3d);
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IFLOAT);
        } else {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-mod-"
                                                      + p2s + "%" + p3s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);
        v.add(p3);

        Term atm = new Term(sym, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return this.sym;
    }
}
 public class MultiplyBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("multiply");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        Term r1;

        boolean allint = true;

        double sum = 0;

        Vector v = new Vector();
        String oid = "$jdrew-mul-";
        for (int i = 2; i < t.subTerms.length; i++) {
            Term ti = t.subTerms[i].deepCopy();
            if (ti.getSymbol() < 0) {
                return null;
            }
            if (ti.getType() != Types.IINTEGER && ti.getType() != Types.IFLOAT) {
                return null;
            }
            if (ti.getType() == Types.IFLOAT) {
                allint = false;
            }

            double d;
            try {
                d = Double.parseDouble(ti.getSymbolString());
                //System.out.print(d);
            } catch (Exception e) {
                return null;
            }
            if (i == 2) {
                sum = d;
                oid += d;
            } else {
                sum *= d;
                oid += "x" + d;
            }

            v.add(ti);
        }

        //System.out.println("Sum: " + sum);

        if (allint) {
            String results = "" + (long) sum;
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IINTEGER);
        } else {
            String results = "" + sum;
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IFLOAT);
        }

        Term roid = new Term(SymbolTable.internSymbol(oid), SymbolTable.IOID,
                             Types.ITHING);

        v.add(0, r1);
        v.add(0, roid);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return this.symbol;
    }
}
 public class NotEqualBuiltin implements Builtin {
    private int sym = SymbolTable.internSymbol("notEqual");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != sym) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p1 = t.subTerms[1].deepCopy();
        Term p2 = t.subTerms[2].deepCopy();

        if (p1.getSymbol() < 0 || p2.getSymbol() < 0) {
            return null;
        }

        String p1s = p1.getSymbolString();
        String p2s = p2.getSymbolString();

        if ((p1.getType() == Types.IFLOAT || p1.getType() == Types.IINTEGER)
            && (p2.getType() == Types.IFLOAT || p2.getType() == Types.IINTEGER)) {

            double d1;
            double d2;

            try {
                d1 = Double.parseDouble(p1s);
                d2 = Double.parseDouble(p2s);
            } catch (Exception e) {
                return null;
            }

            if (d1 == d2) {
                return null;
            }
        } else {
            if (p1.symbol == p2.symbol) {
                return null;
            }
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-notequal-"
                                                      + p1s + "!=" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(p1);
        v.add(p2);

        Term atm = new Term(sym, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return this.sym;
    }
}
 public class PowBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("pow");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 4) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();
        Term p3 = t.subTerms[3].deepCopy();

        if (p2.getSymbol() < 0 || p3.getSymbol() < 0) {
            return null;
        }

        String p2s = p2.getSymbolString();
        String p3s = p3.getSymbolString();
        Term r1;

        int d1;
        double d2;

        if (p2.getType() == Types.IINTEGER && p3.getType() == Types.IINTEGER) {
            long p2i;
            long p3i;
            try {
                p2i = Long.parseLong(p2s);
                p3i = Long.parseLong(p3s);
            } catch (Exception e) {
                return null;
            }
            String results = "" + (long) (Math.pow(p2i, p3i));
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IINTEGER);
        } else if ((p2.getType() == Types.IFLOAT &&
                    p3.getType() == Types.IFLOAT)
                   ||
                   (p2.getType() == Types.IINTEGER &&
                    p3.getType() == Types.IFLOAT)
                   ||
                   (p2.getType() == Types.IFLOAT &&
                    p3.getType() == Types.IINTEGER)) {
            double p2d;
            double p3d;
            try {
                p2d = Double.parseDouble(p2s);
                p3d = Double.parseDouble(p3s);
            } catch (Exception e) {
                return null;
            }
            String results = "" + (Math.pow(p2d, p3d));
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IFLOAT);

        } else {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-pow-"
                                                      + p2s + "^" + p3s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);
        v.add(p3);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class ReplaceBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("replace");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        
        if (t.subTerms.length != 5) {
            return null;
        }
        
        Vector v = new Vector();

        Term p2 = t.subTerms[2].deepCopy();
        Term p3 = t.subTerms[3].deepCopy();
        Term p4 = t.subTerms[4].deepCopy();

        if (p2.getSymbol() < 0||p3.getSymbol()<0|| p4.getSymbol()<0) {
            return null;
        }
        
        if (p2.getType() != Types.ISTRING || p3.getType() != Types.ISTRING || p4.getType() != Types.ISTRING) {
            return null;
        }
        

        String p2s = p2.getSymbolString();
        String p3s = p3.getSymbolString();
        String p4s = p4.getSymbolString();
        v.add(p2);
        v.add(p3);
        v.add(p4);
        String results = p2s.replaceAll(p3s, p4s);
        
        if(results.equals("")) {
        	return null;
        }
        
        Term tr = new Term(SymbolTable.internSymbol(results),
                SymbolTable.INOROLE, Types.ISTRING);

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-replace-" + p3s),
              SymbolTable.IOID, Types.ITHING);
        v.add(0, tr);
        v.add(0, roid);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
        
        
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class RoundBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("round");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();

        if (p2.getSymbol() < 0) {
            return null;
        }

        String p2s = p2.getSymbolString();
        Term r1;

        if (p2.getType() == Types.IINTEGER) {
            long i;
            try {
                i = Long.parseLong(p2s);
            } catch (Exception e) {
                return null;
            }
            r1 = new Term(p2.getSymbol(), SymbolTable.INOROLE, Types.IINTEGER);
        } else if (p2.getType() == Types.IFLOAT) {
            double d;
            try {
                d = Double.parseDouble(p2s);
            } catch (Exception e) {
                return null;
            }
            String results = "" + Math.round(d);
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IINTEGER);
        } else {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-round-" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class SinBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("sin");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();

        if (p2.getSymbol() < 0) {
            return null;
        }

        if (p2.getType() != Types.IFLOAT && p2.getType() != Types.IINTEGER) {
            return null;
        }

        String p2s = p2.getSymbolString();

        double p2d;
        try {
            p2d = Double.parseDouble(p2s);
        } catch (Exception e) {
            return null;
        }

        double result = Math.sin(p2d);
        String results = "" + result;

        Term r1 = new Term(SymbolTable.internSymbol(results),
                           SymbolTable.INOROLE, Types.IFLOAT);

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-sin-" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class StartsWithBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("startsWith");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p1 = t.subTerms[1].deepCopy();
        Term p2 = t.subTerms[2].deepCopy();

        if (p1.getSymbol() < 0 || p1.getSymbol() < 0) {
            return null;
        }

        if (p1.getType() != Types.ISTRING || p2.getType() != Types.ISTRING) {
            return null;
        }

        String p1s = p1.getSymbolString();
        String p2s = p2.getSymbolString();

        if (!p1s.startsWith(p2s)) {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-startswith-"
                                                      + p1s + "-" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(p1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class StringConcatBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("stringConcat");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        Vector v = new Vector();
        StringBuffer sb = new StringBuffer();
        String oid = "$jdrew-strconcat";
        for (int i = 2; i < t.subTerms.length; i++) {
            Term ti = t.subTerms[i].deepCopy();
            if (ti.getSymbol() < 0) {
                return null;
            }
            if (ti.getType() != Types.ISTRING) {
                return null;
            }
            String tis = ti.getSymbolString();
            sb.append(tis);
            oid += "-" + tis;
            v.add(ti);
        }

        String results = sb.toString();
        Term tr = new Term(SymbolTable.internSymbol(results),
                           SymbolTable.INOROLE, Types.ISTRING);

        Term roid = new Term(SymbolTable.internSymbol(oid), SymbolTable.IOID,
                             Types.ITHING);
        v.add(0, tr);
        v.add(0, roid);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class StringEqualIgnoreCaseBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("stringEqualIgnoreCase");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p1 = t.subTerms[1].deepCopy();
        Term p2 = t.subTerms[2].deepCopy();

        if (p1.getSymbol() < 0 || p2.getSymbol() < 0) {
            return null;
        }

        if (p1.getType() != Types.ISTRING || p2.getType() != Types.ISTRING) {
            return null;
        }

        String p1s = p1.getSymbolString();
        String p2s = p2.getSymbolString();

        if (!p1s.equalsIgnoreCase(p2s)) {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-strequalIC-"
                                                      + p1s + "=" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(p1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class StringLengthBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("stringLength");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();

        if (p2.getSymbol() < 0) {
            return null;
        }

        if (p2.getType() != Types.ISTRING) {
            return null;
        }

        String p2s = p2.getSymbolString();

        String results = "" + p2s.length();

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-strlen-" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Term r1 = new Term(SymbolTable.internSymbol(results),
                           SymbolTable.INOROLE, Types.IINTEGER);

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class StringLowerCaseBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("stringLowerCase");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();

        if (p2.getSymbol() < 0) {
            return null;
        }

        if (p2.getType() != Types.ISTRING) {
            return null;
        }

        String p2s = p2.getSymbolString();

        String results = p2s.toLowerCase();

        Term r1 = new Term(SymbolTable.internSymbol(results),
                           SymbolTable.INOROLE, Types.ISTRING);

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-strlower-" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class StringUpperCaseBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("stringUpperCase");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();

        if (p2.getSymbol() < 0) {
            return null;
        }

        if (p2.getType() != Types.ISTRING) {
            return null;
        }

        String p2s = p2.getSymbolString();

        String results = p2s.toUpperCase();

        Term r1 = new Term(SymbolTable.internSymbol(results),
                           SymbolTable.INOROLE, Types.ISTRING);
        Term roid = new Term(SymbolTable.internSymbol("$jdrew-strupper-" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class SubstringAfterBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("substringAfter");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        
        if (t.subTerms.length != 4) {
            return null;
        }
        
        Vector v = new Vector();

        Term p2 = t.subTerms[2].deepCopy();
        Term p3 = t.subTerms[3].deepCopy();

        if (p2.getSymbol() < 0||p3.getSymbol()<0) {
            return null;
        }
        
        if (p2.getType() != Types.ISTRING || p3.getType() != Types.ISTRING) {
            return null;
        }
        

        String p2s = p2.getSymbolString();
        String p3s = p3.getSymbolString();
        v.add(p2);
        v.add(p3);
        String results = p2s.contains(p3s) ? p2s.substring( p2s.indexOf(p3s)+p3s.length(),p2s.length()):p2s.substring(p2s.length()) ;
        
        if(results.equals("")) {
        	return null;
        }
        
        Term tr = new Term(SymbolTable.internSymbol(results),
                SymbolTable.INOROLE, Types.ISTRING);

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-substringafter-" + p3s),
              SymbolTable.IOID, Types.ITHING);
        v.add(0, tr);
        v.add(0, roid);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
        
        
    }

    public int getSymbol() {
        return symbol;
    }


} public class SubstringBeforeBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("substringBefore");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        
        if (t.subTerms.length != 4) {
            return null;
        }
        
        Vector v = new Vector();

        Term p2 = t.subTerms[2].deepCopy();
        Term p3 = t.subTerms[3].deepCopy();

        if (p2.getSymbol() < 0||p3.getSymbol()<0) {
            return null;
        }
        
        if (p2.getType() != Types.ISTRING || p3.getType() != Types.ISTRING) {
            return null;
        }
        

        String p2s = p2.getSymbolString();
        String p3s = p3.getSymbolString();
        v.add(p2);
        v.add(p3);
        String results = p2s.contains(p3s) ? p2s.substring(0, p2s.indexOf(p3s)):p2s.substring(p2s.length()) ;
        
        if(results.equals("")) {
        	return null;
        }
        
        Term tr = new Term(SymbolTable.internSymbol(results),
                SymbolTable.INOROLE, Types.ISTRING);

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-substringbefore-" + p3s),
              SymbolTable.IOID, Types.ITHING);
        v.add(0, tr);
        v.add(0, roid);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
        
        
    }

    public int getSymbol() {
        return symbol;
    }


} public class SubstringBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("substring");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length == 4) {
            Term p2 = t.subTerms[2].deepCopy();
            Term p3 = t.subTerms[3].deepCopy();

            if (p2.getSymbol() < 0 || p3.getSymbol() < 0) {
                return null;
            }

            if (p2.getType() != Types.ISTRING || p3.getType() != Types.IINTEGER) {
                return null;
            }

            String p2s = p2.getSymbolString();
            String p3s = p3.getSymbolString();
            int p3i;
            try {
                p3i = Integer.parseInt(p3s);
            } catch (Exception e) {
                return null;
            }

            String results = p2s.substring(p3i);

            Term r1 = new Term(SymbolTable.internSymbol(results),
                               SymbolTable.INOROLE, Types.ISTRING);
            Term roid = new Term(SymbolTable.internSymbol("$jdrew-substring-"
                                                          + p2s + "-" + p3s),
                                 SymbolTable.IOID, Types.ITHING);
            Vector v = new Vector();
            v.add(roid);
            v.add(r1);
            v.add(p2);
            v.add(p3);

            Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
            atm.setAtom(true);
            Vector v2 = new Vector();
            v2.add(atm);
            return new DefiniteClause(v2, new Vector());
        } else if (t.subTerms.length == 5) {
            Term p2 = t.subTerms[2].deepCopy();
            Term p3 = t.subTerms[3].deepCopy();
            Term p4 = t.subTerms[4].deepCopy();
            if (p2.getSymbol() < 0 || p3.getSymbol() < 0 || p4.getSymbol() < 0) {
                return null;
            }

            if (p2.getType() != Types.ISTRING || p3.getType() != Types.IINTEGER ||
                p4.getType() != Types.IINTEGER) {
                return null;
            }

            String p2s = p2.getSymbolString();
            String p3s = p3.getSymbolString();
            String p4s = p4.getSymbolString();

            int p3i;
            int p4i;
            try {
                p3i = Integer.parseInt(p3s);
                p4i = Integer.parseInt(p4s);
            } catch (Exception e) {
                return null;
            }

            String results = p2s.substring(p3i, p4i);

            Term r1 = new Term(SymbolTable.internSymbol(results),
                               SymbolTable.INOROLE, Types.ISTRING);
            Term roid = new Term(SymbolTable.internSymbol("$jdrew-substring-" + p2s + "-" + p3s + "-" + p4s),
                                 SymbolTable.IOID, Types.ITHING);
            Vector v = new Vector();
            v.add(roid);
            v.add(r1);
            v.add(p2);
            v.add(p3);
            v.add(p4);

            Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
            atm.setAtom(true);
            Vector v2 = new Vector();
            v2.add(atm);
            return new DefiniteClause(v2, new Vector());
        } else {
            return null;
        }
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class SubtractBuiltin implements Builtin {
    private int sym = SymbolTable.internSymbol("subtract");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != sym) {
            return null;
        }

        if (t.subTerms.length != 4) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();
        Term p3 = t.subTerms[3].deepCopy();

        if (p2.getSymbol() < 0 || p3.getSymbol() < 0) {
            return null;
        }

        String p2s = p2.getSymbolString();
        String p3s = p3.getSymbolString();
        Term r1;

        if (p2.getType() == Types.IINTEGER && p3.getType() == Types.IINTEGER) {
            long p2i;
            long p3i;
            try {
                p2i = Long.parseLong(p2s);
                p3i = Long.parseLong(p3s);
            } catch (Exception e) {
                return null;
            }
            String results = "" + (p2i - p3i);
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IINTEGER);
        } else if ((p2.getType() == Types.IFLOAT &&
                    p3.getType() == Types.IINTEGER) ||
                   (p2.getType() == Types.IINTEGER &&
                    p3.getType() == Types.IFLOAT) ||
                   (p2.getType() == Types.IFLOAT &&
                    p3.getType() == Types.IFLOAT)) {
            double p2d;
            double p3d;
            try {
                p2d = Double.parseDouble(p2s);
                p3d = Double.parseDouble(p3s);
            } catch (Exception e) {
                return null;
            }
            String results = "" + (p2d - p3d);
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IFLOAT);
        } else {
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-subtract-"
                                                      + p2s + "-" + p3s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);
        v.add(p3);

        Term atm = new Term(sym, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return this.sym;
    }
}
 public class TanBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("tan");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();

        if (p2.getSymbol() < 0) {
            return null;
        }

        if (p2.getType() != Types.IFLOAT && p2.getType() != Types.IINTEGER) {
            return null;
        }

        String p2s = p2.getSymbolString();

        double p2d;
        try {
            p2d = Double.parseDouble(p2s);
        } catch (Exception e) {
            return null;
        }

        double result = Math.tan(p2d);
        String results = "" + result;

        Term r1 = new Term(SymbolTable.internSymbol(results),
                           SymbolTable.INOROLE, Types.IFLOAT);

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-tan-" + p2s),
                             SymbolTable.IOID, Types.ITHING);

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


}
 public class TimeBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("time");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length == 6) {
            Term p2 = t.subTerms[2].deepCopy();
            Term p3 = t.subTerms[3].deepCopy();
            Term p4 = t.subTerms[4].deepCopy();
            Term p5 = t.subTerms[5].deepCopy();

            if (p2.getSymbol() < 0 || p3.getSymbol() < 0 || p4.getSymbol() < 0 || p5.getSymbol() < 0) {
                return null;
            }

            if (p2.getType() != Types.IINTEGER ||  p3.getType() != Types.IINTEGER || p4.getType() != Types.IINTEGER || p5.getType() != Types.ISTRING ){
                return null;
            }
            

            String p2s = p2.getSymbolString();
            String p3s = p3.getSymbolString();
            String p4s = p4.getSymbolString();
            String p5s = p5.getSymbolString();
            
            //invalid hours
            if(Integer.parseInt(p2s) < 0 || Integer.parseInt(p2s)>=24){
            	return null;
            }
            
            //invalid minutes
            if(Integer.parseInt(p3s)<0 || Integer.parseInt(p3s)>=60){
            	return null;
            }
            
            //invalid seconds
            if(Integer.parseInt(p4s)<0 || Integer.parseInt(p4s)>=60){
            	return null;
            }
            
            //check for proper syntax of timezone
            if(!p5s.matches("[+-][0-1][0-9](:)[0-5][0-9]")){
            	return null;
            }
            
            int h;
            if(p5s.charAt(0)=='+'){
            	h = Integer.parseInt(p5s.split(":")[0].substring(1));
            } else {
            	h = -Integer.parseInt(p5s.split(":")[0]);
            }
            int m = Integer.parseInt(p5s.split(":")[1]);
            
            if(h<-12 || h>14 || !(m!=30 || m!=45 || m!=0)){
            	return null;
            }
    
        
        
        String results = p2s + "-" + p3s + "-" + p4s  + p5s;

            Term r1 = new Term(SymbolTable.internSymbol(results),
                               SymbolTable.INOROLE, Types.ISTRING);
            Term roid = new Term(SymbolTable.internSymbol("$jdrew-date-"
                                                          + p2s + "-" + p3s + "-" + p4s + "-" + p5s),
                                 SymbolTable.IOID, Types.ITHING);
            Vector v = new Vector();
            v.add(roid);
            v.add(r1);
            v.add(p2);
            v.add(p3);
            v.add(p4);
            v.add(p5);

            Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
            atm.setAtom(true);
            Vector v2 = new Vector();
            v2.add(atm);
            return new DefiniteClause(v2, new Vector());
        
        } else {
            return null;
        }
    }

    public int getSymbol() {
        return this.symbol;
    }
} public class UnaryMinusBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("unaryMinus");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();

        if (p2.getSymbol() < 0) {
            return null;
        }

        String p2s = p2.getSymbolString();
        Term r1;
        Term roid= new Term(SymbolTable.internSymbol("$jdrew-unaryminus-" + p2s),
                            SymbolTable.IOID, Types.ITHING);

        if (p2.getType() == Types.IINTEGER) {
            long i;
            try {
                i = Long.parseLong(p2s);
            } catch (Exception e) {
                return null;
            }
            i = i*-1;
            String results = "" + i;
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IINTEGER);
        } else if (p2.getType() == Types.IFLOAT) {
            double d;
            try {
                d = Double.parseDouble(p2s);
            } catch (Exception e) {
                return null;
            }
            d = d*-1.0;
            String results = "" + d;

        
        //        if (p2.getType() == Types.IINTEGER || p2.getType() == Types.IFLOAT) {
//            double d;
//            try {
//                d = Double.parseDouble(p2s);
//            } catch (Exception e) {
//                return null;
//            }
//
//            String results = "" + (long) (d*-1);
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IFLOAT);
        } else {
            return null;
        }

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


} public class UnaryPlusBuiltin implements Builtin {
    private int symbol = SymbolTable.internSymbol("unaryPlus");

    public DefiniteClause buildResult(Term t) {
        if (t.getSymbol() != symbol) {
            return null;
        }

        if (t.subTerms.length != 3) {
            return null;
        }

        Term p2 = t.subTerms[2].deepCopy();

        if (p2.getSymbol() < 0) {
            return null;
        }

        String p2s = p2.getSymbolString();
        Term r1;
        Term roid= new Term(SymbolTable.internSymbol("$jdrew-unaryplus-" + p2s),
                            SymbolTable.IOID, Types.ITHING);

        if (p2.getType() == Types.IINTEGER) {
            long i;
            try {
                i = Long.parseLong(p2s);
            } catch (Exception e) {
                return null;
            }
            //i = i*-1;
            String results = "" + i;
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IINTEGER);
        } else if (p2.getType() == Types.IFLOAT) {
            double d;
            try {
                d = Double.parseDouble(p2s);
            } catch (Exception e) {
                return null;
            }
            //d = d*-1.0;
            String results = "" + d;

        
        //        if (p2.getType() == Types.IINTEGER || p2.getType() == Types.IFLOAT) {
//            double d;
//            try {
//                d = Double.parseDouble(p2s);
//            } catch (Exception e) {
//                return null;
//            }
//
//            String results = "" + (long) (d*-1);
            r1 = new Term(SymbolTable.internSymbol(results),
                          SymbolTable.INOROLE, Types.IFLOAT);
        } else {
            return null;
        }

        Vector v = new Vector();
        v.add(roid);
        v.add(r1);
        v.add(p2);

        Term atm = new Term(symbol, SymbolTable.INOROLE, Types.IOBJECT, v);
        atm.setAtom(true);
        Vector v2 = new Vector();
        v2.add(atm);
        return new DefiniteClause(v2, new Vector());
    }

    public int getSymbol() {
        return symbol;
    }


} public class AssertBuiltin extends TDBuiltin {
    private BackwardReasoner br;
    private int symbol = SymbolTable.internSymbol("assert");

    /**
     * Constructs a new object to implement the assert built-in relation. This
     * constructor must be passed a reference to the backward reasoner object
     * that the built-in will be registered in.
     *
     * @param br BackwardReasoner - The backward reasoner engine that will
     * register this built-in relationship.
     */
    public AssertBuiltin(BackwardReasoner br) {
        super();
        this.br = br;
    }

    /**
     * Access the symbol code for the assert built-in relation.
     *
     * @return int The symbol code for the assert built-in relation.
     */
    public int getSymbol() {
        return symbol;
    }

    /**
     * This method performs the actions necessary to implement the assert
     * built-in relation. This will assert the clause that is the parameter to
     * the assert into the running knowledge base and cause the goal to succeed.
     *
     * @param gl GoalList goal list that contains the call to the assert
     * built-in relation.
     *
     * @param term int An index into the atoms (array) of the clause (0 is the
     * head, i = 1..n is the ith atom of the body of the clause) to the atom
     * that is the call to the assert built-in relation.
     *
     * @return DefiniteClause A clause that will successfully unify with the call
     * to the built-in if it should succeed. null or a fact that will not unify
     * (null is preferred as it is more efficient) should be returned if the
     * call to built-in relation should not succeed.
     */
    public DefiniteClause buildResult(BackwardReasoner.GoalList gl, int term) {
        Term t = gl.getAtom(term);
        Vector natoms = new Vector();
        for (int i = 0; i < t.subTerms.length; i++) {
            Term t2 = t.subTerms[i].deepCopy();
            t2.setAtom(true);
            natoms.add(t2);
        }
        String[] variableNames = gl.getVariableNames();
        Vector vnames = new Vector();
        for (int i = 0; i < variableNames.length; i++) {
            vnames.add(variableNames[i]);
        }
        DefiniteClause newdc = new DefiniteClause(natoms, vnames);
        Vector v = new Vector();
        v.add(newdc);
        br.loadClauses(v.iterator());

        Term t2 = t.deepCopy();
        v = new Vector();
        v.add(t2);
        return new DefiniteClause(v, vnames);
    }

}
 public class RegisterBuiltin extends TDBuiltin {
    private BackwardReasoner br;
    private int sym;
   
    /**
     * Constructs a new object to implement the register built-in relation. This
     * constructor must be passed a reference to the backward reasoner object
     * that the built-in will be registered in.
     *
     * @param br BackwardReasoner - The backward reasoner engine that will
     * register this built-in relationship.
     *
     * @param symbol String - the symbol string
     */
        public RegisterBuiltin(BackwardReasoner br, String symbol){
        this.br = br;
        sym = SymbolTable.internSymbol(symbol);
    }
    /**
     * Access the symbol code for the assert built-in relation.
     *
     * @return int The symbol code for the assert built-in relation.
     */
    public int getSymbol(){
        return sym;
    }
   
    /**
     * This method performs the actions necessary to implement the register
     * built-in relation. This will assert the clause that is the parameter to
     * the assert into the running knowledge base and cause the goal to succeed.
     *
     * @param gl GoalList goal list that contains the call to the assert
     * built-in relation.
     *
     * @param term int An index into the atoms (array) of the clause (0 is the
     * head, i = 1..n is the ith atom of the body of the clause) to the atom
     * that is the call to the assert built-in relation.
     *
     * @return DefiniteClause A clause that will successfully unify with the call
     * to the built-in if it should succeed. null or a fact that will not unify
     * (null is preferred as it is more efficient) should be returned if the
     * call to built-in relation should not succeed.
     */
    public DefiniteClause buildResult(BackwardReasoner.GoalList gl, int term) {
        Term t = gl.getAtom(term);

        if(t.getSymbol() != sym)
            return null;

        if(t.subTerms.length != 2)
            return null;

        Term p1 = t.subTerms[1].deepCopy();

        if(p1.getSymbol() < 0 || p1.isExpr())
            return null;

        String cname = p1.getSymbolString();

        try{
            Class c = Class.forName(cname);
            Object b = c.newInstance();
            if(b instanceof org.ruleml.oojdrew.Builtins.Builtin){ // handle generic Builtin subclass
                org.ruleml.oojdrew.Builtins.Builtin bb = (org.ruleml.oojdrew.Builtins.Builtin) b;
                Hashtable bins = br.getBuiltins();
                Integer sym = bb.getSymbol();
                if(bins.containsKey(sym)){
                    Object o = bins.get(sym);
                    if(!bb.getClass().equals(o.getClass()))
                        return null; //something else is already registered - fail
                }
                else
                    br.registerBuiltin(bb); //register built-in
            }
            else if(b instanceof org.ruleml.oojdrew.TopDown.Builtins.TDBuiltin){ //handle TDBuiltin subclass
                org.ruleml.oojdrew.TopDown.Builtins.TDBuiltin bb = (org.ruleml.oojdrew.TopDown.Builtins.TDBuiltin) b;
                Hashtable bins = br.getBuiltins();
                Integer sym = bb.getSymbol();
                if(bins.containsKey(sym)){
                    Object o = bins.get(sym);
                    if(!bb.getClass().equals(o.getClass()))
                        return null; //something else is already registered - fail
                }
                else
                    br.registerBuiltin(bb); //register built-in
            }
            else
                return null;
        }catch(Exception e){
            return null;
        }

        Term roid = new Term(SymbolTable.internSymbol("$jdrew-rb-" + cname),
                             SymbolTable.IOID, Types.ITHING);
        Vector v = new Vector();
        v.add(roid);
        v.add(p1);

        Term atom = new Term(sym, SymbolTable.INOROLE, Types.ITHING, v);
        Vector v2 = new Vector();
        v2.add(atom);

        return new DefiniteClause(v2, new Vector());
    }

}
 public class TDBuiltin {
      
        /**
         * A reference to the object that implements the generic built-in
         * relation. This object must implement the org.ruleml.oojdrew.builtins.Builtin
         * Interface correctly.
         */
    
    org.ruleml.oojdrew.Builtins.Builtin builtin;
   
    /**
     * Constructs a new empty Top-down built-in. This is provided only for
     * compatability reasons.
     */
    
    public TDBuiltin() {
        builtin = null;
    }

    /**
     * Constructs a new Top-Down built-in. The user should pass an instance of
     * the Class that implements the generic built-in relation.
     *
     * @param b Builtin A generic built-in implementation class, this must
     * implement the org.ruleml.oojdrew.builtins.Builtin Interface.
     */
     
    public TDBuiltin(org.ruleml.oojdrew.Builtins.Builtin b) {
        builtin = b;
    }

    /**
     * Gets the integer symbol code for the built-in relation symbol. This
     * method simply calls the getSymbol() method of the generic built-in
     * implementation that is referenced by this TDBuiltin object.
     *
     * @return int The integer code for the built-in relation symbol
     */
    public int getSymbol() {
        return builtin.getSymbol();
    }

    /**
     * Builds the resulting fact from the call to this built-in if it exists.
     * This method extracts the appropriate Term object that represents the call
     * to the built-in relation and passes to the generic built-in's
     * builtResult() method.
     *
     * @param gl GoalList the goal list that contains the call to the
     * built-in
     *
     * @param term int The index into the atoms of the clause for the call to
     * the built-in relation represented by this TDBuiltin object.
     *
     * @return DefiniteClause a DC containing a fact that will unify with the call
     * to the built-in if it should succeed. null or a fact that will not unify
     * (null is preferred as it is more efficient) should be returned if the
     * call to built-in relation should not succeed.
     */
     
    public DefiniteClause buildResult(BackwardReasoner.GoalList gl, int term) {
        //System.out.println("In TDBuiltin...");
        return builtin.buildResult(gl.getAtom(term));
    }

}
 public class POSLParser {
    Vector clauses = new Vector();

    public POSLParser() {
    }

    /**
     * Returns an interator over the clauses that are stored in the parsers
     * internal buffer; the buffer is not automatically cleared after a call
     * to iterator(). To clear the buffer a call to reset() must be invoked.
     * @return Iterator
     */
    public Iterator iterator() {
        return clauses.iterator();
    }

    /**
     * Clears the parsers internal clause buffer.
     */
    public void reset() {
        clauses = new Vector();
    }

    /**
     * This method is used to parse a single definite clause, stored in a
     * String. The DefiniteClause object that represents the parsed clause is
     * returned directly to the user and not added to the internal clause
     * buffer.
     *
     * @param clause String A string containing the clause to be parsed. If the
     * string contains multiple clauses only the first clause will be parsed.
     *
     * @return DefiniteClause The DefiniteClause object that represents the
     * parsed clause.
     *
     * @throws RecognitionException
     * @throws TokenStreamException
     */
    public DefiniteClause parseDefiniteClause(String clause) throws RecognitionException, TokenStreamException{
        StringReader sr = new StringReader(clause);
        POSLLexer lex = new POSLLexer(sr);
        org.ruleml.oojdrew.parsing.generated.POSLParser pp = new org.ruleml.oojdrew.parsing.generated.POSLParser(lex);
        return pp.clause(true);
    }

    /**
     * This method is used to parse a query - stored in a String. The
     * DefiniteClause object that represents the parsed query is returned
     * directly to the user and not added to the internal clause buffer.
     *
     * @param query String A string containing the query to be parsed. If the
     * string contains multiple queries only the first query will be parsed.
     *
     * @return DefiniteClause The DefiniteClause object that represents the
     * parsed query.
     *
     * @throws RecognitionException
     * @throws TokenStreamException
     */
    public DefiniteClause parseQueryString(String query) throws RecognitionException, TokenStreamException{
        return parseDefiniteClause("$top():-" + query + ".");
    }
	//used for parsing a Type Query String
 	public DefiniteClause parseQueryStringT(String query) throws RecognitionException, TokenStreamException{
        return parseDefiniteClause(query + ".");
    }

    /**
     * This method is used to parse a group of clauses, stored in a String. The
     * parsed clauses (DefiniteClause objects) are added to the internal clause
     * buffer and not returned directly to the caller. The an iterator over the
     * clauses can be retrieved by invoking the iterator() method.
     *
     * @param clauses String A string containing one or more clauses.
     *
     * @throws RecognitionException
     * @throws TokenStreamException
     */
    public void parseDefiniteClauses(String clauses) throws RecognitionException, TokenStreamException{
        StringReader sr = new StringReader(clauses);
        parseReader(sr);
    }

    /**
     * This method is used to parse a group of clauses stored in a local file.
     * The full path to the filename should be used. A FileReader object is
     * created using the filename as the path; then the reader is passed to
     * the parseReader(Reader) method.
     *
     * @param filename String A string containing the complete path to the file.
     *
     * @throws FileNotFoundException
     * @throws RecognitionException
     * @throws TokenStreamException
     */
    public void parseDCFile(String filename) throws FileNotFoundException, RecognitionException, TokenStreamException{
        FileReader fr = new FileReader(filename);
        parseReader(fr);
    }

    /**
     * This method is used to parse a group of clauses read from an InputStream
     * (keyboard, socket, etc.). A InputStreamReader is created using the
     * InputStream and passed to the parseReader(Reader) method. Clauses are
     * parsed until a End of File (EOF) character is reached (Typically CTRL-D
     * on Unix-like systems and CTRL-Z on Windows).
     *
     * @param is InputStream The input stream to read clauses from.
     *
     * @throws RecognitionException
     * @throws TokenStreamException
     */
    public void parseInputStream(InputStream is) throws RecognitionException, TokenStreamException {
        InputStreamReader isr = new InputStreamReader(is);
        parseReader(isr);
    }

    /**
     * This method is used by parseInputStream(), parseDCFile() and
     * parseDefiniteClauses() to perform the parsing, using the reader that is
     * created in each of those methods.
     *
     * This method creates a POSLLexer (Lexcographical Analyzer) object on the
     * Reader. Once this is done a org.ruleml.oojdrew.util.parsing.POSLParser object
     * created on the lexer and the rulebase(Vector) method is invoked to parse
     * the rulebase that is read from the reader.
     *
     * @param r Reader The reader to read the input from.
     *
     * @throws RecognitionException
     * @throws TokenStreamException
     */
    private void parseReader(Reader r) throws RecognitionException, TokenStreamException {
        POSLLexer lex = new POSLLexer(r);
        org.ruleml.oojdrew.parsing.generated.POSLParser pp = new org.ruleml.oojdrew.parsing.generated.POSLParser(lex);
        pp.rulebase(this.clauses);
    }
}
 public class DefiniteClause {

    /**
     * Contains the Term objects that represent the Atoms of the clause. The
     * term at index 0 is the head of the clause. The atoms at indices 1 .. n-1
     * are the Atoms of the body of the clause if they exist.
     */
    public Term[] atoms;

    /**
     * Contains the variable names for this clause. Since OO jDREW uses local
     * shallow binding the variables have a local scope and are stored with the
     * clause instead of in the global symbol table.
     */
    public String[] variableNames;

    /**
     * Creates a new clause representation using the a Vector of atoms and a
     * Vector of variable names. This constructor assumes that the types for a
     * variable are correct (i.e. a variable doesn't have a type that doesn't
     * exist and a variable doesn't have two different types at two places in
     * the clause).
     * 
     * A definite Clause Needs A Vector Of Term Objects that represent The atoms
     * of the clause to be constructed. The first object(Index 0) is the head of
     * the clause, while any remaining objects are the body atoms
     * (conjunctively)joined The VariableNames vector contains the names for the
     * variable names for the clause to be constructed.
     * 
     * @param atoms
     *            Vector A vector of Term objects that represent the Atoms of
     *            the clause to be constructed. The first object (index 0) is
     *            the head of the clause, while any remaining objects are the
     *            body atoms (conjunctively) joined.
     * 
     * @param variableNames
     *            Vector A vector containing the variable names for the clause
     *            to be constructed.
     */
    public DefiniteClause(Vector atoms, Vector variableNames) {
        this.atoms = new Term[atoms.size()];
        for (int i = 0; i < this.atoms.length; i++) {
            this.atoms[i] = (Term) atoms.get(i);
        }

        this.variableNames = new String[variableNames.size()];
        for (int i = 0; i < this.variableNames.length; i++) {
            this.variableNames[i] = (String) variableNames.get(i);
        }
    }

    /**
     * Creates and returns a string representation of the clause in either POSL
     * or RuleML format. The format is determined by the
     * org.ruleml.oojdrew.Config.PRPRINT variable. If PRPRINT is true - then the
     * POSL format is used for output, otherwise RuleML (0.88 +) is used.
     * 
     * @return The string representation of the clause.
     */
    public String toString() {
        if (org.ruleml.oojdrew.Config.PRPRINT) {
            return toPOSLString();
        } else {
            // TODO remove constant version
            return toRuleMLString(RuleMLFormat.RuleML88); 
        }
    }

    /**
     * Creates and returns a string representation of the clause in either POSL
     * or RuleML format. The format is determined by the
     * org.ruleml.oojdrew.Config.PRPRINT variable. If PRPRINT is true - then the
     * POSL format is used for output, otherwise RuleML (0.88 + rests or 0.91)
     * is used.
     * 
     * @param rmlFormat
     *            RuleMLFormat, to determine which RuleML version to use.
     * 
     * @return The string representation of the clause.
     */
    public String toString(RuleMLFormat version) {
        if (org.ruleml.oojdrew.Config.PRPRINT) {
            return toPOSLString();
        } else {
            return toRuleMLString(version);
        }
    }

    /**
     * Builds and returns a POSL string representation of the clause. This is
     * used by the toString() method if the org.ruleml.oojdrew.Config.PRPRINT
     * variable is true, and can also be called directly by the user code.
     * 
     * @return The POSL representation of the clause stored in a Java String
     *         object.
     */
    public String toPOSLString() {
        String s = "";
        s += atoms[0].toPOSLString(variableNames, true);

        if (atoms.length > 1) {
            s += " :- ";
            for (int i = 1; i < atoms.length; i++) {
                s += atoms[i].toPOSLString(variableNames, false) + ", ";
            }

            s = s.substring(0, s.length() - 2);
        }
        s += ".";

        return s;
    }

    /**
     * Builds and returns a RuleML (0.88 + rests or 0.91) string representation
     * of the object. The output is "pretty printed" with indentation set to 3
     * spaces and new-lines enabled. "\n" is used for newlines, therefore the
     * output may not appear properly on MS Windows based operating systems.
     * 
     * This method is called by the toString() method if
     * org.ruleml.oojdrew.Config.PRPRINT is false, and can be called by user
     * code.
     * 
     * @param rmlFormat
     *            RuleMLFormat, to determine which RuleML version to use.
     * 
     * @return The RuleML representation stored in a Java String object.
     */
    public String toRuleMLString(RuleMLFormat rmlFormat) {
        Element rmlElement = this.toRuleML(rmlFormat);
        return XmlUtils.elementToString(rmlElement);
    }

    /**
     * Builds and returns a RuleML (0.88 + rests or 0.91) representation of the
     * object as a XOM tree. Users can then manipulate this object using regular
     * calls to the XOM library routines.
     * 
     * This method is called by the toRuleMLString() method, and can be called
     * by user code.
     * 
     * @param rmlFormat
     *            RuleMLFormat, to determine which RuleML version to use.
     * 
     * @return The RuleML representation of the clause stored as a XOM tree.
     */
    public Element toRuleML(RuleMLFormat rmlFormat) {
        RuleMLTagNames rmlTagNames = new RuleMLTagNames(rmlFormat);

        Element element;
        if (atoms.length == 1) {
            element = atoms[0].toRuleML(variableNames, true, rmlFormat);
        } else {
            element = new Element(rmlTagNames.IMPLIES);
            if (atoms.length > 2) {
                Element el2 = new Element(rmlTagNames.AND);
                for (int i = 1; i < atoms.length; i++) {

                    el2.appendChild(atoms[i].toRuleML(variableNames, false,
                            rmlFormat));
                }
                element.appendChild(el2);
            } else {
                element.appendChild(atoms[1].toRuleML(variableNames, false,
                        rmlFormat));
            }

            element.appendChild(atoms[0].toRuleML(variableNames, true,
                    rmlFormat));
        }

        return element;
    }

    /**
     * Tests to see if the clause represented by this clause is a fact - this is
     * determined by checking to see if the clause only has one atom (the head).
     * 
     * @return Returns true if the clause represents a fact, otherwise false.
     */
    public boolean isFact() {
        return (atoms.length == 1);
    }
}
 public class EngineException extends RuntimeException {
    public EngineException() {
        super();
    }

    public EngineException(String message) {
        super(message);
    }

    public EngineException(Throwable cause) {
        super(cause);
    }

    public EngineException(String message, Throwable cause) {
        super(message, cause);
    }
}
 public class SymbolTable {

    /**
     * This vector stores all known symbols. The index of the symbol within
     * this vector is the integer code that is used to represent this symbol.
     */
    public static Vector symbols = new Vector();

    /**
     * This vector stores all known roles. The index of the role within this
     * vector is the integer code that is used to represent this role.
     */
    public static Vector roles = new Vector();

    /**
     * This is used to generate new Skolem constants; ensuring uniqueness of
     * all generated constants.
     */
    public static int genid = 100000;

    /**
     * This integer stores the integer code that is used for the system oid
     * role.
     */
    public static final int IOID = internRole("$oid$");

    /**
     * This integer stores the integer code that is used for the role of
     * positional parameters.
     */
    public static final int INOROLE = internRole("");

    /**
     * This integer stores the integer code that is used for the role of
     * positional rest parameters.
     */
    public static final int IPREST = internRole("|");

    /**
     * This integer stores the integer code that is used for the role of
     * slotted rest parameters. This is set equal to Integer.MAX_VALUE to
     * ensure that it will always be the final parameter in the normalized
     * parameter lists.
     */
    public static final int IREST = Integer.MAX_VALUE;

    /**
     * This symbol takes up the first slot in the symbol table - as we ensure
     * that the integer code 0 is never used. This is not else where.
     */
    public static final int INOSYM = internSymbol("");

    /**
     * This integer stores the code for a NAF term.
     */
    public static final int INAF = internSymbol("naf");

    /**
     * This integer stores the code for the "constructor" of a plex term.
     */
    public static final int IPLEX = internSymbol("$PLEX");

    /**
     * This integer stores the code for an assert term.
     */
    public static final int IASSERT = internSymbol("assert");

    /**
     *
     */
    public static final int IINCONSISTENT = internSymbol("$inconsistent");

    /**
     *
     */
    public static final int INEG = internSymbol("neg");

    /**
     * This method is used to reset the symbol table. Data structures that
     * were created previous to this should no longer be used.
     */
    public static void reset() {
        symbols = new Vector();
        roles = new Vector();
        internRole("$oid$");
        internRole("");
        internRole("|");
        internSymbol("");
        internSymbol("naf");
        internSymbol("$PLEX");
        internSymbol("assert");
        internSymbol("$inconsistent");
        internSymbol("neg");
    }

    /**
     * This method is used to initalize a symbol and assign it an integer code
     * if it has not been used before; or retrieve the integer code of a symbol
     * if it already has been encountered.
     *
     * @param sym String A string containing the symbol.
     *
     * @return int The integer code of the symbol.
     */
     
    public static int internSymbol(String sym) {
        if (symbols.contains(sym)) {
            return symbols.indexOf(sym);
        } else {
            int id = symbols.size();
            symbols.add(sym);
            return id;
        }
    }

    /**
     * This method is used to initalize a role and assign it an integer code if
     * it has not been used before; or retrieve the integer code of a role if
     * it already has been encountered.
     *
     * @param role String A string containing the role name.
     *
     * @return int The integer code of the role.
     */
    public static int internRole(String role) {
        if (roles.contains(role)) {
            return roles.indexOf(role);
        } else {
            int id = roles.size();
            roles.add(role);
            return id;
        }
    }

    /**
     * This method gets the string representation of a symbol for the integer
     * code. This is commonly used by output routines.
     *
     * @param idx int The integer code to get the symbol string for.
     *
     * @return String The symbol string.
     */
    public static String symbol(int idx) {
        if (idx < 0 || idx >= symbols.size()) {
            return null;
        } else {
            return (String) symbols.get(idx);
        }
    }

    /**
     * This method gets the string representation of a role for the integer
     * code. This is commonly used by output routines.
     *
     * @param idx int The integer code to get the role string for.
     *
     * @return String The role string.
     */
    public static String role(int idx) {
        if (idx < 0 || idx >= roles.size()) {
            return null;
        } else {
            return (String) roles.get(idx);
        }
    }
}
 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;
                }
            }
        }
    }
}

import java.util.Hashtable;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Stack;
import java.util.Vector;
import javax.swing.tree.DefaultMutableTreeNode;
import org.ruleml.oojdrew.Reasoner;
import org.ruleml.oojdrew.Builtins.AbsBuiltin;
import org.ruleml.oojdrew.Builtins.AddBuiltin;
import org.ruleml.oojdrew.Builtins.Builtin;
import org.ruleml.oojdrew.Builtins.CeilingBuiltin;
import org.ruleml.oojdrew.Builtins.ContainsBuiltin;
import org.ruleml.oojdrew.Builtins.ContainsIgnoreCaseBuiltin;
import org.ruleml.oojdrew.Builtins.CosBuiltin;
import org.ruleml.oojdrew.Builtins.DateBuiltin;
import org.ruleml.oojdrew.Builtins.DateTimeBuiltin;
import org.ruleml.oojdrew.Builtins.DivideBuiltin;
import org.ruleml.oojdrew.Builtins.EndsWithBuiltin;
import org.ruleml.oojdrew.Builtins.EqualBuiltin;
import org.ruleml.oojdrew.Builtins.FloorBuiltin;
import org.ruleml.oojdrew.Builtins.GreaterThanBuiltin;
import org.ruleml.oojdrew.Builtins.GreaterThanOrEqualBuiltin;
import org.ruleml.oojdrew.Builtins.IntegerDivideBuiltin;
import org.ruleml.oojdrew.Builtins.LessThanBuiltin;
import org.ruleml.oojdrew.Builtins.LessThanOrEqualBuiltin;
import org.ruleml.oojdrew.Builtins.ModBuiltin;
import org.ruleml.oojdrew.Builtins.MultiplyBuiltin;
import org.ruleml.oojdrew.Builtins.NotEqualBuiltin;
import org.ruleml.oojdrew.Builtins.PowBuiltin;
import org.ruleml.oojdrew.Builtins.ReplaceBuiltin;
import org.ruleml.oojdrew.Builtins.RoundBuiltin;
import org.ruleml.oojdrew.Builtins.SinBuiltin;
import org.ruleml.oojdrew.Builtins.StartsWithBuiltin;
import org.ruleml.oojdrew.Builtins.StringConcatBuiltin;
import org.ruleml.oojdrew.Builtins.StringEqualIgnoreCaseBuiltin;
import org.ruleml.oojdrew.Builtins.StringLengthBuiltin;
import org.ruleml.oojdrew.Builtins.StringLowerCaseBuiltin;
import org.ruleml.oojdrew.Builtins.StringUpperCaseBuiltin;
import org.ruleml.oojdrew.Builtins.SubstringAfterBuiltin;
import org.ruleml.oojdrew.Builtins.SubstringBeforeBuiltin;
import org.ruleml.oojdrew.Builtins.SubstringBuiltin;
import org.ruleml.oojdrew.Builtins.SubtractBuiltin;
import org.ruleml.oojdrew.Builtins.TanBuiltin;
import org.ruleml.oojdrew.Builtins.TimeBuiltin;
import org.ruleml.oojdrew.Builtins.UnaryMinusBuiltin;
import org.ruleml.oojdrew.Builtins.UnaryPlusBuiltin;
import org.ruleml.oojdrew.TopDown.Builtins.AssertBuiltin;
import org.ruleml.oojdrew.TopDown.Builtins.RegisterBuiltin;
import org.ruleml.oojdrew.TopDown.Builtins.TDBuiltin;
import org.ruleml.oojdrew.parsing.POSLParser;
import org.ruleml.oojdrew.util.DefiniteClause;
import org.ruleml.oojdrew.util.EngineException;
import org.ruleml.oojdrew.util.SymbolTable;
import org.ruleml.oojdrew.util.Term;

// 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.TopDown;




/**
 * Based upon the backward reasoner from the original jDREW by Bruce Spencer.
 *
 * <p>Title: OO jDREW</p>
 *
 * <p>Description: Reasoning Engine for the Semantic Web - Supporting OO RuleML
 * 0.88</p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * @author Marcel A. Ball
 * @version 0.89
 */

public class BackwardReasoner implements Reasoner {

    /**
     *
     */
    private static final int REPORT_EVERY_N_INFERENCES = 5000;

    /**
     *
     */
    public Hashtable clauses;

    public Hashtable oids;

    public int count = 0;
    
    /**
     *
     */
    private Hashtable builtins;

    public Hashtable getBuiltins(){
        return builtins;
    }

    /**
     *
     */
    private Stack choicePoints;
    /**
     *
     */
    private int nExtensions;
    /**
     *
     */
    private int nInferences;
    /**
     *
     */
    private GoalList top;

    /**
     *
     */
    //Logger logger = Logger.getLogger("jdrew.oo.td.BackwardReasoner");

    /**
     *
     */
    public BackwardReasoner() {
        this(new Hashtable(), new Hashtable());
        oids.put(-1, new Vector());
    }

    /**
     *
     * @param clauses Hashtable
     */
    public BackwardReasoner(Hashtable clauses, Hashtable oids) {
        this.clauses = clauses;
        this.oids = oids;
        choicePoints = new Stack();
        nExtensions = 0;
        nInferences = 0;
        builtins = new Hashtable();
        registerBuiltins();
    }

    /**
     *
     */
    public void registerBuiltins() {
        this.registerBuiltin(new AssertBuiltin(this));
        this.registerBuiltin(new RegisterBuiltin(this, "registerBuiltin"));
        this.registerBuiltin(new AbsBuiltin());
        this.registerBuiltin(new AddBuiltin());
        this.registerBuiltin(new CeilingBuiltin());
        this.registerBuiltin(new ContainsBuiltin());
        this.registerBuiltin(new ContainsIgnoreCaseBuiltin());
        this.registerBuiltin(new CosBuiltin());
        this.registerBuiltin(new DivideBuiltin());
        this.registerBuiltin(new EndsWithBuiltin());
        this.registerBuiltin(new EqualBuiltin());
        this.registerBuiltin(new FloorBuiltin());
        this.registerBuiltin(new GreaterThanBuiltin());
        this.registerBuiltin(new GreaterThanOrEqualBuiltin());
        this.registerBuiltin(new IntegerDivideBuiltin());
        this.registerBuiltin(new LessThanBuiltin());
        this.registerBuiltin(new LessThanOrEqualBuiltin());
        this.registerBuiltin(new ModBuiltin());
        this.registerBuiltin(new MultiplyBuiltin());
        this.registerBuiltin(new NotEqualBuiltin());
        this.registerBuiltin(new PowBuiltin());
        this.registerBuiltin(new RoundBuiltin());
        this.registerBuiltin(new SinBuiltin());
        this.registerBuiltin(new StartsWithBuiltin());
        this.registerBuiltin(new StringConcatBuiltin());
        this.registerBuiltin(new StringEqualIgnoreCaseBuiltin());
        this.registerBuiltin(new StringLengthBuiltin());
        this.registerBuiltin(new StringLowerCaseBuiltin());
        this.registerBuiltin(new StringUpperCaseBuiltin());
        this.registerBuiltin(new SubstringBuiltin());
        this.registerBuiltin(new SubtractBuiltin());
        this.registerBuiltin(new TanBuiltin());
        this.registerBuiltin(new DateBuiltin());
        this.registerBuiltin(new TimeBuiltin());
        this.registerBuiltin(new DateTimeBuiltin());
        this.registerBuiltin(new SubstringAfterBuiltin());
        this.registerBuiltin(new SubstringBeforeBuiltin());
        this.registerBuiltin(new ReplaceBuiltin());
        this.registerBuiltin(new UnaryPlusBuiltin());

        this.registerBuiltin(new UnaryMinusBuiltin());
