java/com/googlecode/prolog_cafe/lang/ListTerm.java [34:267]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public class ListTerm extends Term {
    /** A functor <code>'.' /2</code>. */
    protected static final SymbolTerm SYM_DOT = SymbolTerm.intern(".", 2);

    /** Holds the first element of this <code>ListTerm</code>. */
    protected Term car;

    /**
     * Holds the list consisting of all the rest of the elements of 
     * this <code>ListTerm</code> but the first one.
     */
    protected Term cdr;

    /**
     * Constructs a new Prolog list structure
     * such that <code>_car</code> is the first element of this list, and 
     * <code>_cdr</code> is the list consisting of all the rest of the 
     * elements of this list but the first one.
     */
    public ListTerm(Term _car, Term _cdr) { 
	car = _car;
	cdr = _cdr; 
    }

    /** Returns the value of <code>car</code>.
     * @see #car
     */
    public Term car() { return car; }

    /** Returns the value of <code>cdr</code>.
     * @see #cdr
     */
    public Term cdr() { return cdr; }

    /** Sets the value to <code>car</code>.
     * @see #car
     */
    public void setCar(Term t) { car = t; }

    /** Sets the value to <code>cdr</code>.
     * @see #cdr
     */
    public void setCdr(Term t) { cdr = t; }

    @Override
    public int type() {
      return TYPE_LIST;
    }

    /* Term */
    @Override
    public boolean unify(Term t, Trail trail) {
	t = t.dereference();
	if (t instanceof VariableTerm) {
	    ((VariableTerm) t).bind(this, trail);
	    return true;
	}
	if (! (t instanceof ListTerm))
	    return false;
	return car.unify(((ListTerm)t).car(), trail) 
	    && cdr.unify(((ListTerm)t).cdr(), trail);
    }

    /** 
     * @return the <code>boolean</code> whose value is
     * <code>convertible(List.class, type)</code>.
     * @see Term#convertible(Class, Class)
     */
    @Override
    public boolean convertible(Class<?> type) { 
	return convertible(List.class, type); 
    }

    @Override
    protected Term copy(Prolog engine) { 
	return new ListTerm(car.copy(engine), cdr.copy(engine)); 
    }

    @Override
    public boolean isGround() {
	if (! car.isGround())
	    return false;
	if (! cdr.isGround())
	    return false;
	return true;
    }

    @Override
    public String name() { return SYM_DOT.name(); }

    @Override
    public Term arg(int nth) {
      Term t = this;
      int old_nth = nth;
      while (t instanceof ListTerm && 0 < nth) {
        nth--;
        t = ((ListTerm)t).cdr.dereference();
      }
      if (t instanceof ListTerm)
        return ((ListTerm)t).car;
      throw new ArrayIndexOutOfBoundsException(old_nth);
    }

    /** Returns the length of this <code>ListTerm</code>. */
    public int length() {
	int count = 0;
	Term t = this;
	while(t instanceof ListTerm) {
	    count++;
	    t = ((ListTerm)t).cdr().dereference();
	}
	return count;
    }

    /** 
     * Returns a {@code java.util.List} corresponds to this <code>ListTerm</code>
     * according to <em>Prolog Cafe interoperability with Java</em>.
     * @return a {@link java.util.List} object equivalent to
     * this <code>IntegerTerm</code>.
     */
    @Override
    public List<?> toJava() { 
	List<Object> vec = new ArrayList<>();
	Term t = this;
	while(t instanceof ListTerm) {
	    vec.add(((ListTerm)t).car().dereference().toJava());
	    t = ((ListTerm)t).cdr().dereference();  
	}
	return vec;	
    }

    @Override
    public String toQuotedString() {
	Term x = this;
	String s = "[";
	for (;;) {
	    s += ((ListTerm)x).car.dereference().toQuotedString();
	    x  = ((ListTerm)x).cdr.dereference();
	    if (! (x instanceof ListTerm))
		break;
	    s += ",";
	}
	if (! Prolog.Nil.equals(x))
	    s += "|" + x.toQuotedString();
	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>ListTerm</code>, and 
     * all corresponding pairs of elements in the two lists 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 list
     * equivalent to this <code>ListTerm</code>, false otherwise.
     * @see #compareTo
     */
    @Override
    public boolean equals(Object obj) {
    	if (! (obj instanceof ListTerm))
    	    return false;
	return car.equals(((ListTerm)obj).car().dereference()) 
	    && cdr.equals(((ListTerm)obj).cdr().dereference());
    }

    @Override
    public int hashCode() {
	int h = 1;
	h = 31*h + SYM_DOT.hashCode();
	h = 31*h + car.dereference().hashCode();
	h = 31*h + cdr.dereference().hashCode();
	return h;
    }

    /** Returns a string representation of this <code>ListTerm</code>. */
    @Override
    public String toString() {
	Term x = this;	
	String s = "[";
	for (;;) {
	    s += ((ListTerm)x).car.dereference().toString();
	    x  = ((ListTerm)x).cdr.dereference();
	    if (! (x instanceof ListTerm))
		break;
	    s += ",";
	}
	if (! Prolog.Nil.equals(x))
	    s += "|" + x.toString();
	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>.
     */
    @Override
    public int compareTo(Term anotherTerm) { // anotherTerm must be dereferenced.
	if (anotherTerm instanceof VariableTerm || ((anotherTerm instanceof IntegerTerm) || (anotherTerm instanceof DoubleTerm)) || anotherTerm instanceof SymbolTerm)
	    return AFTER;
	if (anotherTerm instanceof StructureTerm) {
	    int arity = ((StructureTerm)anotherTerm).arity();
	    if (2 != arity)
		return (2 - arity);
	    SymbolTerm functor = ((StructureTerm)anotherTerm).functor();
	    if (! SYM_DOT.equals(functor))
		return SYM_DOT.compareTo(functor);
	}
	Term[] args = new Term[2];
	if (anotherTerm instanceof ListTerm) {
	    args[0] = ((ListTerm)anotherTerm).car();
	    args[1] = ((ListTerm)anotherTerm).cdr();
	} else if (anotherTerm instanceof StructureTerm) {
	    args = ((StructureTerm)anotherTerm).args();
	} else {
	    return BEFORE;
	}
	Term tmp = car;
	int rc;
	for (int i=0; i<2; i++) {
	    rc = tmp.compareTo(args[i].dereference());
	    if (rc != EQUAL) 
		return rc;
	    tmp = cdr;
	}
	return EQUAL;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



src/lang/ListTerm.java [34:267]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public class ListTerm extends Term {
    /** A functor <code>'.' /2</code>. */
    protected static final SymbolTerm SYM_DOT = SymbolTerm.intern(".", 2);

    /** Holds the first element of this <code>ListTerm</code>. */
    protected Term car;

    /**
     * Holds the list consisting of all the rest of the elements of 
     * this <code>ListTerm</code> but the first one.
     */
    protected Term cdr;

    /**
     * Constructs a new Prolog list structure
     * such that <code>_car</code> is the first element of this list, and 
     * <code>_cdr</code> is the list consisting of all the rest of the 
     * elements of this list but the first one.
     */
    public ListTerm(Term _car, Term _cdr) { 
	car = _car;
	cdr = _cdr; 
    }

    /** Returns the value of <code>car</code>.
     * @see #car
     */
    public Term car() { return car; }

    /** Returns the value of <code>cdr</code>.
     * @see #cdr
     */
    public Term cdr() { return cdr; }

    /** Sets the value to <code>car</code>.
     * @see #car
     */
    public void setCar(Term t) { car = t; }

    /** Sets the value to <code>cdr</code>.
     * @see #cdr
     */
    public void setCdr(Term t) { cdr = t; }

    @Override
    public int type() {
      return TYPE_LIST;
    }

    /* Term */
    @Override
    public boolean unify(Term t, Trail trail) {
	t = t.dereference();
	if (t instanceof VariableTerm) {
	    ((VariableTerm) t).bind(this, trail);
	    return true;
	}
	if (! (t instanceof ListTerm))
	    return false;
	return car.unify(((ListTerm)t).car(), trail) 
	    && cdr.unify(((ListTerm)t).cdr(), trail);
    }

    /** 
     * @return the <code>boolean</code> whose value is
     * <code>convertible(List.class, type)</code>.
     * @see Term#convertible(Class, Class)
     */
    @Override
    public boolean convertible(Class<?> type) { 
	return convertible(List.class, type); 
    }

    @Override
    protected Term copy(Prolog engine) { 
	return new ListTerm(car.copy(engine), cdr.copy(engine)); 
    }

    @Override
    public boolean isGround() {
	if (! car.isGround())
	    return false;
	if (! cdr.isGround())
	    return false;
	return true;
    }

    @Override
    public String name() { return SYM_DOT.name(); }

    @Override
    public Term arg(int nth) {
      Term t = this;
      int old_nth = nth;
      while (t instanceof ListTerm && 0 < nth) {
        nth--;
        t = ((ListTerm)t).cdr.dereference();
      }
      if (t instanceof ListTerm)
        return ((ListTerm)t).car;
      throw new ArrayIndexOutOfBoundsException(old_nth);
    }

    /** Returns the length of this <code>ListTerm</code>. */
    public int length() {
	int count = 0;
	Term t = this;
	while(t instanceof ListTerm) {
	    count++;
	    t = ((ListTerm)t).cdr().dereference();
	}
	return count;
    }

    /** 
     * Returns a {@code java.util.List} corresponds to this <code>ListTerm</code>
     * according to <em>Prolog Cafe interoperability with Java</em>.
     * @return a {@link java.util.List} object equivalent to
     * this <code>IntegerTerm</code>.
     */
    @Override
    public List<?> toJava() { 
	List<Object> vec = new ArrayList<>();
	Term t = this;
	while(t instanceof ListTerm) {
	    vec.add(((ListTerm)t).car().dereference().toJava());
	    t = ((ListTerm)t).cdr().dereference();  
	}
	return vec;	
    }

    @Override
    public String toQuotedString() {
	Term x = this;
	String s = "[";
	for (;;) {
	    s += ((ListTerm)x).car.dereference().toQuotedString();
	    x  = ((ListTerm)x).cdr.dereference();
	    if (! (x instanceof ListTerm))
		break;
	    s += ",";
	}
	if (! Prolog.Nil.equals(x))
	    s += "|" + x.toQuotedString();
	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>ListTerm</code>, and 
     * all corresponding pairs of elements in the two lists 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 list
     * equivalent to this <code>ListTerm</code>, false otherwise.
     * @see #compareTo
     */
    @Override
    public boolean equals(Object obj) {
    	if (! (obj instanceof ListTerm))
    	    return false;
	return car.equals(((ListTerm)obj).car().dereference()) 
	    && cdr.equals(((ListTerm)obj).cdr().dereference());
    }

    @Override
    public int hashCode() {
	int h = 1;
	h = 31*h + SYM_DOT.hashCode();
	h = 31*h + car.dereference().hashCode();
	h = 31*h + cdr.dereference().hashCode();
	return h;
    }

    /** Returns a string representation of this <code>ListTerm</code>. */
    @Override
    public String toString() {
	Term x = this;	
	String s = "[";
	for (;;) {
	    s += ((ListTerm)x).car.dereference().toString();
	    x  = ((ListTerm)x).cdr.dereference();
	    if (! (x instanceof ListTerm))
		break;
	    s += ",";
	}
	if (! Prolog.Nil.equals(x))
	    s += "|" + x.toString();
	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>.
     */
    @Override
    public int compareTo(Term anotherTerm) { // anotherTerm must be dereferenced.
	if (anotherTerm instanceof VariableTerm || ((anotherTerm instanceof IntegerTerm) || (anotherTerm instanceof DoubleTerm)) || anotherTerm instanceof SymbolTerm)
	    return AFTER;
	if (anotherTerm instanceof StructureTerm) {
	    int arity = ((StructureTerm)anotherTerm).arity();
	    if (2 != arity)
		return (2 - arity);
	    SymbolTerm functor = ((StructureTerm)anotherTerm).functor();
	    if (! SYM_DOT.equals(functor))
		return SYM_DOT.compareTo(functor);
	}
	Term[] args = new Term[2];
	if (anotherTerm instanceof ListTerm) {
	    args[0] = ((ListTerm)anotherTerm).car();
	    args[1] = ((ListTerm)anotherTerm).cdr();
	} else if (anotherTerm instanceof StructureTerm) {
	    args = ((StructureTerm)anotherTerm).args();
	} else {
	    return BEFORE;
	}
	Term tmp = car;
	int rc;
	for (int i=0; i<2; i++) {
	    rc = tmp.compareTo(args[i].dereference());
	    if (rc != EQUAL) 
		return rc;
	    tmp = cdr;
	}
	return EQUAL;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



