blob: 76cd75f98ba60f68e74501b8fc03ac197dc4e8c3 [file] [log] [blame]
package com.googlecode.prolog_cafe.lang;
/**
* The superclass of classes for term structures.
* The subclasses of <code>Term</code> must override
* the <code>unify</code> method.
*
* @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
* @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
* @version 1.0
*/
public abstract class Term implements Comparable<Term> {
/** Holds an integer value <code>0</code>. */
public static final int EQUAL = 0;
/** Holds an integer value <code>1</code>. */
public static final int AFTER = 1;
/** Holds an integer value <code>-1</code>. */
public static final int BEFORE = -1;
public static final int TYPE_VARIABLE = 0;
public static final int TYPE_INTEGER = 1;
public static final int TYPE_DOUBLE = 2;
public static final int TYPE_SYMBOL = 3;
public static final int TYPE_STRUCTURE = 4;
public static final int TYPE_LIST = 5;
public static final int TYPE_CLOSURE = 6;
public static final int TYPE_JAVA_OBJECT = 7;
/** One of the {@code TYPE_*} constants from {@code Term}. */
public abstract int type();
/**
* Checks whether the argument term is unified with this one.
* @param t the term to be unified with.
* @param trail Trail Stack.
* @return <code>true</code> if succeeds, otherwise <code>false</code>.
*/
abstract public boolean unify(Term t, Trail trail);
/** @return the name of this Term, if {@link #isStructure()}. */
public abstract String name();
/** @return the arity of this Term, if {@link #isStructure()}. */
public int arity() { return 0; }
/** @return get the nth argument of {@link #isStructure()} or {@link #isList()}. */
public Term arg(int nth) { throw new ArrayIndexOutOfBoundsException(nth); }
/**
* Check whether this object is convertible with the given Java class type.
* @param type the Java class type to compare with.
* @return <code>true</code> if this is convertible with
* <code>type</code>. Otherwise <code>false</code>.
* @see #convertible(Class, Class)
*/
public boolean convertible(Class<?> type) { return convertible(getClass(), type); }
/**
* Returns a copy of this object.
* @param engine the engine.
*
*/
protected Term copy(Prolog engine) { return this; }
/** Returns the dereference value of this term. */
public Term dereference() { return this; }
/**
* Check whether this term is a ground term.
* @return <code>true</code> if ground, otherwise <code>false</code>.
*/
public boolean isGround() { return true; }
/**
* Returns a Java object that corresponds to this term
* if defined in <em>Prolog Cafe interoperability with Java</em>.
* Otherwise, returns <code>this</code>.
* @return a Java object if defined in <em>Prolog Cafe interoperability with Java</em>,
* otherwise <code>this</code>.
*/
public Object toJava() {
return this;
}
/** Returns a quoted string representation of this term. */
public String toQuotedString() { return this.toString(); }
/**
* Check whether there is a widening conversion from <code>from</code> to <code>to</code>.
*/
protected static boolean convertible(Class<?> from, Class<?> to) {
if (from == null)
return ! to.isPrimitive();
if (to.isAssignableFrom(from)) {
return true;
} else if (to.isPrimitive()) {
if (from.equals(Boolean.class)) {
return to.equals(Boolean.TYPE);
} else if (from.equals(Byte.class)) {
return to.equals(Byte.TYPE)
|| to.equals(Short.TYPE)
|| to.equals(Integer.TYPE)
|| to.equals(Long.TYPE)
|| to.equals(Float.TYPE)
|| to.equals(Double.TYPE);
} else if (from.equals(Short.class)) {
return to.equals(Short.TYPE)
|| to.equals(Integer.TYPE)
|| to.equals(Long.TYPE)
|| to.equals(Float.TYPE)
|| to.equals(Double.TYPE);
} else if (from.equals(Character.class)) {
return to.equals(Character.TYPE)
|| to.equals(Integer.TYPE)
|| to.equals(Long.TYPE)
|| to.equals(Float.TYPE)
|| to.equals(Double.TYPE);
} else if (from.equals(Integer.class)) {
return to.equals(Integer.TYPE)
|| to.equals(Long.TYPE)
|| to.equals(Float.TYPE)
|| to.equals(Double.TYPE);
} else if (from.equals(Long.class)) {
return to.equals(Long.TYPE)
|| to.equals(Float.TYPE)
|| to.equals(Double.TYPE);
} else if (from.equals(Float.class)) {
return to.equals(Float.TYPE)
|| to.equals(Double.TYPE);
} else if (from.equals(Double.class)) {
return to.equals(Double.TYPE);
}
}
return false;
}
/** Checks whether a given object is an instance of Prolog term. */
public static boolean instanceOfTerm(Object obj) {
return obj instanceof VariableTerm ||
obj instanceof IntegerTerm ||
obj instanceof DoubleTerm ||
obj instanceof SymbolTerm ||
obj instanceof ListTerm ||
obj instanceof StructureTerm ||
obj instanceof JavaObjectTerm ||
obj instanceof ClosureTerm;
}
}