| 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; |
| |
| /** |
| * 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); |
| |
| /** |
| * Check whether this term is a logical variable. |
| * @return <code>true</code> if <code>this instanceof VariableTerm</code>, |
| * otherwise <code>false</code>. |
| * @see VariableTerm |
| */ |
| public final boolean isVariable() { return this instanceof VariableTerm; } |
| |
| /** |
| * Check whether this term is an integer. |
| * @return <code>true</code> if <code>this instanceof IntegerTerm</code>, |
| * otherwise <code>false</code>. |
| * @see IntegerTerm |
| */ |
| public final boolean isInteger() { return this instanceof IntegerTerm; } |
| |
| /** |
| * Check whether this term is a float. |
| * @return <code>true</code> if <code>this instanceof DoubleTerm</code>, |
| * otherwise <code>false</code>. |
| * @see DoubleTerm |
| */ |
| public final boolean isDouble() { return this instanceof DoubleTerm; } |
| |
| /** |
| * Check whether this term is a number. |
| * @return <code>true</code> if <code>this instanceof IntegerTerm || this instanceof DoubleTerm</code>, |
| * otherwise <code>false</code>. |
| * @see IntegerTerm |
| * @see DoubleTerm |
| */ |
| public final boolean isNumber() { return ((this instanceof IntegerTerm) || (this instanceof DoubleTerm)); } |
| |
| /** |
| * Check whether this term is an atom. |
| * @return <code>true</code> if <code>this instanceof SymbolTerm</code>, |
| * otherwise <code>false</code>. |
| * @see SymbolTerm |
| */ |
| public final boolean isSymbol() { return this instanceof SymbolTerm; } |
| |
| /** Check whether this term is an empty list. */ |
| public final boolean isNil() { return Prolog.Nil.equals(this); } |
| |
| /** |
| * Check whether this term is a list structure. |
| * @return <code>true</code> if <code>this instanceof ListTerm</code>, |
| * otherwise <code>false</code>. |
| * @see ListTerm |
| */ |
| public final boolean isList() { return this instanceof ListTerm; } |
| |
| /** |
| * Check whether this term is a compound term. |
| * @return <code>true</code> if <code>this instanceof StructureTerm</code>, |
| * otherwise <code>false</code>. |
| * @see StructureTerm |
| */ |
| public final boolean isStructure() { return this instanceof StructureTerm; } |
| |
| /** |
| * Check whether this term is a java term. |
| * @return <code>true</code> if <code>this instanceof JavaObjectTerm</code>, |
| * otherwise <code>false</code>. |
| * @see JavaObjectTerm |
| */ |
| public final boolean isJavaObject() { return this instanceof JavaObjectTerm; } |
| |
| /** |
| * Check whether this term is a closure term. |
| * @return <code>true</code> if <code>this instanceof ClosureTerm</code>, |
| * otherwise <code>false</code>. |
| * @see ClosureTerm |
| */ |
| public final boolean isClosure() { return this instanceof ClosureTerm; } |
| |
| /** @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. */ |
| 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; |
| } |
| } |