|  | package jp.ac.kobe_u.cs.prolog.lang; | 
|  | import java.io.Serializable; | 
|  | /** | 
|  | * Trail stack.<br> | 
|  | * The class <code>Trail</code> represents a trail stack.<br> | 
|  | * Entries pushed to this trail stack must implement | 
|  | * the <code>Undoable</code> interface. | 
|  | * @see Undoable | 
|  | * @author Mutsunori Banbara (banbara@kobe-u.ac.jp) | 
|  | * @author Naoyuki Tamura (tamura@kobe-u.ac.jp) | 
|  | * @version 1.0 | 
|  | */ | 
|  | public class Trail implements Serializable { | 
|  | /** Maximum size of enties. Initial size is <code>20000</code>. */ | 
|  | protected int maxContents = 20000; | 
|  |  | 
|  | /** An array of <code>Undoable</code> entries. */ | 
|  | protected Undoable[] buffer; | 
|  |  | 
|  | /** the top index of this <code>Trail</code>. */ | 
|  | protected int top; | 
|  |  | 
|  | /** Holds the Prolog engine that this <code>Trail</code> belongs to. */ | 
|  | protected Prolog engine; | 
|  |  | 
|  | /** Constructs a new trail stack. */ | 
|  | public Trail(Prolog _engine) { | 
|  | engine = _engine; | 
|  | buffer = new Undoable[maxContents]; | 
|  | top = -1; | 
|  | } | 
|  |  | 
|  | /** Constructs a new trail stack with the given size. */ | 
|  | public Trail(Prolog _engine, int n) { | 
|  | engine = _engine; | 
|  | maxContents = n; | 
|  | buffer = new Undoable[maxContents]; | 
|  | top = -1; | 
|  | } | 
|  |  | 
|  | /** Discards all entries. */ | 
|  | public void init() { deleteAll(); } | 
|  |  | 
|  | /** Pushs an entry to this <code>Trail</code>. */ | 
|  | public void push(Undoable t) { | 
|  | try { | 
|  | buffer[++top] = t; | 
|  | } catch (ArrayIndexOutOfBoundsException e) { | 
|  | System.out.println("{expanding trail...}"); | 
|  | int len = buffer.length; | 
|  | Undoable[] new_buffer = new Undoable[len+20000]; | 
|  | for(int i=0; i<len; i++){ | 
|  | new_buffer[i] = buffer[i]; | 
|  | } | 
|  | buffer = new_buffer; | 
|  | buffer[top] = t; | 
|  | maxContents = len+20000; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** Pops an entry from this <code>Trail</code>. */ | 
|  | public Undoable pop() { | 
|  | Undoable t = buffer[top]; | 
|  | buffer[top--] = null; | 
|  | return t; | 
|  | } | 
|  |  | 
|  | /** Discards all entries. */ | 
|  | protected void deleteAll() { | 
|  | while (! empty()) { | 
|  | buffer[top--] = null; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** Tests if this stack has no entry. */ | 
|  | public boolean empty() { | 
|  | return top == -1; | 
|  | } | 
|  |  | 
|  | /** Returns the value of <code>maxContents</code>. | 
|  | * @see #maxContents | 
|  | */ | 
|  | public int max() { return maxContents; } | 
|  |  | 
|  | /** Returns the value of <code>top</code>. | 
|  | * @see #top | 
|  | */ | 
|  | public int top() { return top; } | 
|  |  | 
|  | /** Unwinds all entries after the value of <code>i</code>. */ | 
|  | public void unwind(int i) { | 
|  | Undoable t; | 
|  | while (top > i) { | 
|  | t = pop(); | 
|  | t.undo(); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** Shows the contents of this <code>Trail</code>. */ | 
|  | public void show() { | 
|  | if (empty()) { | 
|  | System.out.println("{trail stack is empty!}"); | 
|  | return; | 
|  | } | 
|  | for (int i=0; i<=top; i++) { | 
|  | System.out.print("trail[" + i + "]: "); | 
|  | System.out.println(buffer[i]); | 
|  | } | 
|  | } | 
|  | } | 
|  |  |