//tabstop=4 //*****************************************************************************/ // Project: jpl // // File: $Id$ // Date: $Date$ // Author: Fred Dushin // // // Description: // // // ------------------------------------------------------------------------- // Copyright (c) 1998 Fred Dushin // All rights reserved. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library Public License // as published by the Free Software Foundation; either version 2 // 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 Library Public License for more details. // ------------------------------------------------------------------------- // $Id$ //*****************************************************************************/ package jpl; //----------------------------------------------------------------------/ // List /** * A List is a Compound, but with just two args, a head and a tail. * Use this class to create representations of Prolog lists: *
 * List el = 
 *     new List(
 *         new Atom( "a" ),
 *         new List(
 *             new Atom( "b" ),
 *             new List(
 *                 new Atom( "c" ),
 *                 List.NIL ) ) );
 * 
* This constructor (somewhat longwindedly) creates a List that * corresponds to the Prolog list [a,b,c], or more accurately, * [a|[b|[c|[]]]].

* * Note the following: *

*
  • The special Term (static instance) List.NIL is of type * List.Nil, which extends Atom, not List. So the terminus * of a List is an Atom, not a List. This is consistent * with the Prolog representation.
  • *
  • The List class provides 11 (convenience) list() methods for * creating Listing without the long-windedness of the above * constructor
  • *
    * *
    * Copyright (C) 1998 Fred Dushin

    * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library Public License * as published by the Free Software Foundation; either version 2 * 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 Library Public License for more details.

    *


    * @author Fred Dushin * @version $Revision$ */ // Implementation notes: // //----------------------------------------------------------------------/ public class List extends Compound { /** * @return the head of the List */ public final Term head() { return args_[0]; } /** * @return the tail of the List */ public final Term tail() { return args_[1]; } //==================================================================/ // Contructors and Initialization //==================================================================/ // We only need one reference to this guy private static final Atom DOT = new Atom( "." ); //------------------------------------------------------------------/ // List /** * This constructor is used to create a List. Typically, the * "last" item in a List is the List.NIL instance, or at least * an instance of the List.Nil type, though as in Prolog, * this need not necessarily be the case. Lists are therefore * usually built "inside-out", or from the tail to the head, though * you can also use any of the 11 factory list() methods for creating * Lists if the elements of the List are known beforehand. * * @param head the List's head * @param tail the List's tail */ // Implementation notes: // //------------------------------------------------------------------/ public List( Term head, Term tail ) { super( DOT, Util.toTermArray( head, tail ) ); } //==================================================================/ // //==================================================================/ //------------------------------------------------------------------/ // tailIsNil /** * @return true if tail of this List is an instance of Nil; false o/w */ // Implementation notes: // //------------------------------------------------------------------/ public final boolean tailIsNil() { return args_[1] instanceof Nil; } //------------------------------------------------------------------/ // toString /** * @return the String representation of this List. In this case, * we use the simplest Prolog represenation [H|T]. For example, * the list [a,b,c] is represented [a|[b|[c|[]]]]. */ // Implementation notes: // //------------------------------------------------------------------/ public java.lang.String toString() { return "[" + args_[0] + " | " + args_[1] + "]"; } public java.lang.String debugString() { return "(List " + Term.debugString( args_ ) + ")"; } //------------------------------------------------------------------/ // list /** * @return a jpl.List representing [] (i.e., the Atom List.NIL. */ // Implementation notes: // //------------------------------------------------------------------/ public static Atom list() { return List.NIL; } //------------------------------------------------------------------/ // list /** * @return a jpl.List representing [t0] */ // Implementation notes: // //------------------------------------------------------------------/ public static List list( Term t0 ) { return new List( t0, list() ); } //------------------------------------------------------------------/ // list /** * @return a jpl.List representing [t0,t1] */ // Implementation notes: // //------------------------------------------------------------------/ public static List list( Term t0, Term t1 ) { return new List( t0, list( t1 ) ); } //------------------------------------------------------------------/ // list /** * @return a jpl.List representing [t0,t1,t2,t3] */ // Implementation notes: // //------------------------------------------------------------------/ public static List list( Term t0, Term t1, Term t2 ) { return new List( t0, list( t1, t2 ) ); } //------------------------------------------------------------------/ // list /** * @return a jpl.List representing [t0,t1,t2,t3] */ // Implementation notes: // //------------------------------------------------------------------/ public static List list( Term t0, Term t1, Term t2, Term t3 ) { return new List( t0, list( t1, t2, t3 ) ); } //------------------------------------------------------------------/ // list /** * @return a jpl.List representing [t0,t1,t2,t3,t4] */ // Implementation notes: // //------------------------------------------------------------------/ public static List list( Term t0, Term t1, Term t2, Term t3, Term t4 ) { return new List( t0, list( t1, t2, t3, t4 ) ); } //------------------------------------------------------------------/ // list /** * @return a jpl.List representing [t0,t1,t2,t3,t4,t5] */ // Implementation notes: // //------------------------------------------------------------------/ public static List list( Term t0, Term t1, Term t2, Term t3, Term t4, Term t5 ) { return new List( t0, list( t1, t2, t3, t4, t5 ) ); } //------------------------------------------------------------------/ // list /** * @return a jpl.List representing [t0,t1,t2,t3,t4,t5,t6] */ // Implementation notes: // //------------------------------------------------------------------/ public static List list( Term t0, Term t1, Term t2, Term t3, Term t4, Term t5, Term t6 ) { return new List( t0, list( t1, t2, t3, t4, t5, t6 ) ); } //------------------------------------------------------------------/ // list /** * @return a jpl.List representing [t0,t1,t2,t3,t4,t5,t6,t7] */ // Implementation notes: // //------------------------------------------------------------------/ public static List list( Term t0, Term t1, Term t2, Term t3, Term t4, Term t5, Term t6, Term t7 ) { return new List( t0, list( t1, t2, t3, t4, t5, t6, t7 ) ); } //------------------------------------------------------------------/ // list /** * @return a jpl.List representing [t0,t1,t2,t3,t4,t5,t6,t7,t8] */ // Implementation notes: // //------------------------------------------------------------------/ public static List list( Term t0, Term t1, Term t2, Term t3, Term t4, Term t5, Term t6, Term t7, Term t8 ) { return new List( t0, list( t1, t2, t3, t4, t5, t6, t7, t8 ) ); } //------------------------------------------------------------------/ // list /** * @return a jpl.List representing [t0,t1,t2,t3,t4,t5,t6,t7,t8,t9] */ // Implementation notes: // //------------------------------------------------------------------/ public static List list( Term t0, Term t1, Term t2, Term t3, Term t4, Term t5, Term t6, Term t7, Term t8, Term t9 ) { return new List( t0, list( t1, t2, t3, t4, t5, t6, t7, t8, t9 ) ); } //------------------------------------------------------------------/ // length /** * This method returns the length of a List. It assumes that * the List is List.Nil terminated. * * @return the length of the List */ // Implementation notes: // //------------------------------------------------------------------/ public int length() { java.util.Enumeration e = elements(); int i = 0; while ( e.hasMoreElements() ){ e.nextElement(); ++i; } return i; } //------------------------------------------------------------------/ // toTermArray /** * This method returns an array containg the Terms in * the List. It assumes that the List is List.Nil terminated. * * @return a Term array containing the Terms in the List */ // Implementation notes: // //------------------------------------------------------------------/ public Term[] toTermArray() { Term[] terms = new Term[length()]; java.util.Enumeration e = elements(); for ( int i = 0; e.hasMoreElements(); ++i ){ terms[i] = (Term) e.nextElement(); } return terms; } //==================================================================/ // Nil /** * The Nil class is used to terminate a List. */ // Implementation notes: NOTE: Nil is not a List! It would be // nice if it was, but it's not a list in Prolog, either. //==================================================================/ public static class Nil extends Atom { public Nil() { super( "[]" ); } } public static final Atom NIL = new Nil(); //------------------------------------------------------------------/ // /** * @return */ // Implementation notes: // //------------------------------------------------------------------/ protected boolean nil_terminated() { List cons = this; Term tail = cons.tail(); while ( tail instanceof List ){ cons = (List) tail; tail = cons.tail(); } return cons.tailIsNil(); } //==================================================================/ // ListEnumerator /** * A ListEnumerator enumerates the elements of a List. Note that * trying to construct one of these on a List that is not nil-terminated * will cause a JPLException to be thrown */ // Implementation notes: // //==================================================================/ private class ListEnumerator implements java.util.Enumeration { private List cons_ = List.this; protected ListEnumerator() { if ( !nil_terminated() ){ throw new JPLException( "List is not a nil-terminated List" ); } } public boolean hasMoreElements() { return cons_ != null; } public Object nextElement() { Term ret = cons_.head(); Term tail = cons_.tail(); if ( tail instanceof List ){ cons_ = (List)tail; } else { cons_ = null; } return ret; } } //------------------------------------------------------------------/ // elements /** * This method return an enumeration of a nil-terminated List. * Calling this method on a List whose last cdr is not an instance of * List.Nil will cause a JPLException to be thrown. * * @return A java.util.Enumeration of all the elements of the List */ // Implementation notes: // //------------------------------------------------------------------/ public java.util.Enumeration elements() { return new ListEnumerator(); } } //345678901234567890123456789012346578901234567890123456789012345678901234567890