package jp.ac.kobe_u.cs.prolog.lang;
/**
 * Compound term. <br>
 * The <code>StructureTerm</code> class represents a compound term but list.<br>
 *
 * <pre>
 *  % father(abraham, X)
 *  Term a1 = SymbolTerm.makeSymbol("abraham");
 *  Term a2 = new VariableTerm();
 *  Term[] a3 = {a1, a2};
 *  Term a4 = SymbolTerm.makeSymbol("father", 2);
 *  Term  t = new StructureTerm(a4, a3);
 *  
 *  Term functor = ((StructureTerm)t).functor();
 *  Term[]  args = ((StructureTerm)t).args();
 *  int    arity = ((StructureTerm)t).arity();
 * </pre>
 *
 * @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
 * @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
 * @version 1.0
 */
public class StructureTerm extends Term {
    /** Holds the functor symbol of this <code>StructureTerm</code>. */
    protected SymbolTerm functor;

    /** Holds the argument terms of this <code>StructureTerm</code>. */
    protected Term[] args;

    /** Holds the arity of this <code>StructureTerm</code>. */
    protected int arity;

    /**
     * Constructs a new Prolog compound term
     * such that <code>_functor</code> is the functor symbol, and 
     * <code>_args</code> is the argument terms respectively.
     */
    public StructureTerm(SymbolTerm _functor, Term[] _args){
	functor = _functor;
	arity = functor.arity();
	args = _args;
	if (arity != args.length)
	    throw new InternalException("Invalid argument length in StructureTerm");
    }

    /** Returns the functor symbol of this <code>StructureTerm</code>.
     * @return the value of <code>functor</code>.
     * @see #functor
     */
    public SymbolTerm functor(){ return functor; }

    /** Returns the arity of this <code>StructureTerm</code>.
     * @return the value of <code>arity</code>.
     * @see #arity
     */
    public int arity(){ return arity; }

    /** Returns the argument terms of this <code>StructureTerm</code>.
     * @return the value of <code>args</code>.
     * @see #args
     */
    public Term[] args(){ return args; }

    /** Returns the string representation of functor symbol of this <code>StructureTerm</code>.
     * @return a <code>String</code> whose value is <code>functor.name()</code>.
     * @see #functor
     * @see SymbolTerm#name
     */
    public String name(){ return functor.name(); }

    /* Term
    public boolean unify(Term t, Trail trail) {
	if (t.isVariable())
	    return t.unify(this, trail);
	if (! t.isStructure())
	    return false;
	if (! functor.equals(((StructureTerm)t).functor()))
	    return false;
	for (int i=0; i<arity; i++) {
	    if (! args[i].unify(((StructureTerm)t).args[i], trail))
		return false;
	}
	return true;
    } */


    public boolean unify(Term t, Trail trail) {
	t = t.dereference();
	if (t.isVariable()) {
	    ((VariableTerm) t).bind(this, trail);
	    return true;
	}
	if (! t.isStructure())
	    return false;
	if (! functor.equals(((StructureTerm)t).functor()))
	    return false;
	for (int i=0; i<arity; i++) {
	    if (! args[i].unify(((StructureTerm)t).args[i], trail))
		return false;
	}
	return true;
    }

    //    public boolean unify(Term t, Trail trail) {
    //	return trail.engine.unify(this, t);
    //    }


    protected Term copy(Prolog engine) {
	Term[] a = new Term[arity];
	for (int i=0; i<arity; i++)
	    a[i] = args[i].copy(engine);
	return new StructureTerm(functor, a);
    }

    public boolean isGround() {
	for (int i=0; i<arity; i++) {
	    if (! args[i].isGround())
		return false;
	}
	return true;
    }

    public String toQuotedString() {
	String delim = "";
	String s = functor.toQuotedString() + "(";
	for (int i=0; i<arity; i++) {
	    s += delim + args[i].toQuotedString();
	    delim = ",";
	}
	s += ")";
	return s;
    }

    /* Object */
    /**
     * Checks <em>term equality</em> of two terms.
     * The result is <code>true</code> if and only if the argument is an instance of
     * <code>StructureTerm</code>, has the same functor symbol and arity, and
     * all corresponding pairs of arguments in the two compound terms are <em>term-equal</em>.
     * @param obj the object to compare with. This must be dereferenced.
     * @return <code>true</code> if the given object represents a Prolog compound term
     * equivalent to this <code>StructureTerm</code>, false otherwise.
     * @see #compareTo
     */
    public boolean equals(Object obj) {
	if (! (obj instanceof StructureTerm))
	    return false;
	if (! functor.equals(((StructureTerm)obj).functor()))
	    return false;
	for (int i=0; i<arity; i++) {
	    if (! args[i].equals(((StructureTerm)obj).args[i].dereference()))
		return false;
	}
	return true;
    }

    public int hashCode() {
	int h = 1;
	h = 31*h + functor.hashCode();
	for(int i=0; i<arity; i++)
	    h = 31*h + args[i].dereference().hashCode();
	return h;
    }

    /** Returns a string representation of this <code>StructureTerm</code>. */
    public String toString() {
	String delim = "";
	String s = functor.toString() + "(";
	for (int i=0; i<arity; i++) {
	    s += delim + args[i].toString();
	    delim = ",";
	}
	s += ")";
	return s;
    }

    /* Comparable */
    /** 
     * Compares two terms in <em>Prolog standard order of terms</em>.<br>
     * It is noted that <code>t1.compareTo(t2) == 0</code> has the same
     * <code>boolean</code> value as <code>t1.equals(t2)</code>.
     * @param anotherTerm the term to compared with. It must be dereferenced.
     * @return the value <code>0</code> if two terms are identical; 
     * a value less than <code>0</code> if this term is <em>before</em> the <code>anotherTerm</code>;
     * and a value greater than <code>0</code> if this term is <em>after</em> the <code>anotherTerm</code>.
     */
    public int compareTo(Term anotherTerm) { // anotherTerm must be dereferenced.
	SymbolTerm functor2;
	Term[] args2;
	int arity2, rc;

	if (anotherTerm.isVariable() || anotherTerm.isNumber() || anotherTerm.isSymbol())
	    return AFTER;
	if (anotherTerm.isList()) {
	    functor2 = ListTerm.SYM_DOT;
	    args2    = new Term[2];
	    args2[0] = ((ListTerm)anotherTerm).car();
	    args2[1] = ((ListTerm)anotherTerm).cdr();
	    arity2   = 2;
	} else if (anotherTerm.isStructure()) {
	    functor2 = ((StructureTerm)anotherTerm).functor();
	    args2    = ((StructureTerm)anotherTerm).args();
	    arity2   = ((StructureTerm)anotherTerm).arity();
	} else {
	    return BEFORE;
	}
	if (arity != arity2)
	    return (arity - arity2);
	if (! functor.equals(functor2))
	    return functor.compareTo(functor2);
	for (int i=0; i<arity; i++) {
	    rc = args[i].compareTo(args2[i].dereference());
	    if (rc != EQUAL) 
		return rc;
	}
	return EQUAL;
    }
}
