blob: 4433263d1ff15043f3d384e9be8325e1a65773a7 [file] [log] [blame]
package com.googlecode.prolog_cafe.lang;
import java.io.Serializable;
/**
* Choice point frame.<br>
*
* @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
* @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
* @version 1.0
*/
class CPFEntry implements Serializable {
public long timeStamp;
public Operation cont; // continuation goal
public Operation bp; // next clause
public int tr; // trail pointer
public int b0; // cut point
static CPFEntry S0(Operation cont) {
CPFEntry r = new CPFEntry();
r.cont = cont;
return r;
}
void restore(Prolog engine) {
engine.cont = this.cont;
}
public String toString() {
String t = " time:" + timeStamp + "\n" ;
t = t + " cont:" + cont + "\n";
t = t + " bp:" + bp + "\n";
t = t + " tr:" + tr + "\n";
t = t + " b0:" + b0 + "\n";
return t;
}
static final class S1 extends CPFEntry {
private Term areg1;
S1(Prolog engine) {
this.cont = engine.cont;
this.areg1 = engine.areg1;
}
void restore(Prolog engine) {
engine.cont = this.cont;
engine.areg1 = this.areg1;
}
}
static final class S2 extends CPFEntry {
private Term areg1, areg2;
S2(Prolog engine) {
this.cont = engine.cont;
this.areg1 = engine.areg1;
this.areg2 = engine.areg2;
}
void restore(Prolog engine) {
engine.cont = this.cont;
engine.areg1 = this.areg1;
engine.areg2 = this.areg2;
}
}
static final class S3 extends CPFEntry {
private Term areg1, areg2, areg3;
S3(Prolog engine) {
this.cont = engine.cont;
this.areg1 = engine.areg1;
this.areg2 = engine.areg2;
this.areg3 = engine.areg3;
}
void restore(Prolog engine) {
engine.cont = this.cont;
engine.areg1 = this.areg1;
engine.areg2 = this.areg2;
engine.areg3 = this.areg3;
}
}
static final class S4 extends CPFEntry {
private Term areg1, areg2, areg3, areg4;
S4(Prolog engine) {
this.cont = engine.cont;
this.areg1 = engine.areg1;
this.areg2 = engine.areg2;
this.areg3 = engine.areg3;
this.areg4 = engine.areg4;
}
void restore(Prolog engine) {
engine.cont = this.cont;
engine.areg1 = this.areg1;
engine.areg2 = this.areg2;
engine.areg3 = this.areg3;
engine.areg4 = this.areg4;
}
}
static final class S5 extends CPFEntry {
private Term areg1, areg2, areg3, areg4, areg5;
S5(Prolog engine) {
this.cont = engine.cont;
this.areg1 = engine.areg1;
this.areg2 = engine.areg2;
this.areg3 = engine.areg3;
this.areg4 = engine.areg4;
this.areg5 = engine.areg5;
}
void restore(Prolog engine) {
engine.cont = this.cont;
engine.areg1 = this.areg1;
engine.areg2 = this.areg2;
engine.areg3 = this.areg3;
engine.areg4 = this.areg4;
engine.areg5 = this.areg5;
}
}
static final class S6 extends CPFEntry {
private Term areg1, areg2, areg3, areg4, areg5, areg6;
S6(Prolog engine) {
this.cont = engine.cont;
this.areg1 = engine.areg1;
this.areg2 = engine.areg2;
this.areg3 = engine.areg3;
this.areg4 = engine.areg4;
this.areg5 = engine.areg5;
this.areg6 = engine.areg6;
}
void restore(Prolog engine) {
engine.cont = this.cont;
engine.areg1 = this.areg1;
engine.areg2 = this.areg2;
engine.areg3 = this.areg3;
engine.areg4 = this.areg4;
engine.areg5 = this.areg5;
engine.areg6 = this.areg6;
}
}
static final class S7 extends CPFEntry {
private Term areg1, areg2, areg3, areg4, areg5, areg6, areg7;
S7(Prolog engine) {
this.cont = engine.cont;
this.areg1 = engine.areg1;
this.areg2 = engine.areg2;
this.areg3 = engine.areg3;
this.areg4 = engine.areg4;
this.areg5 = engine.areg5;
this.areg6 = engine.areg6;
this.areg7 = engine.areg7;
}
void restore(Prolog engine) {
engine.cont = this.cont;
engine.areg1 = this.areg1;
engine.areg2 = this.areg2;
engine.areg3 = this.areg3;
engine.areg4 = this.areg4;
engine.areg5 = this.areg5;
engine.areg6 = this.areg6;
engine.areg7 = this.areg7;
}
}
static class S8 extends CPFEntry {
private Term areg1, areg2, areg3, areg4, areg5, areg6, areg7, areg8;
S8(Prolog engine) {
this.cont = engine.cont;
this.areg1 = engine.areg1;
this.areg2 = engine.areg2;
this.areg3 = engine.areg3;
this.areg4 = engine.areg4;
this.areg5 = engine.areg5;
this.areg6 = engine.areg6;
this.areg7 = engine.areg7;
this.areg8 = engine.areg8;
}
void restore(Prolog engine) {
engine.cont = this.cont;
engine.areg1 = this.areg1;
engine.areg2 = this.areg2;
engine.areg3 = this.areg3;
engine.areg4 = this.areg4;
engine.areg5 = this.areg5;
engine.areg6 = this.areg6;
engine.areg7 = this.areg7;
engine.areg8 = this.areg8;
}
}
static final class S9 extends S8 {
private Term[] aregs;
S9(int arity, Prolog engine) {
super(engine);
aregs = new Term[arity - 8];
System.arraycopy(engine.aregs, 0, aregs, 0, aregs.length);
}
void restore(Prolog engine) {
System.arraycopy(aregs, 0, engine.aregs, 0, aregs.length);
super.restore(engine);
}
}
}
/**
* Choice point frame stack.<br>
* The <code>CPFStack</code> class represents a stack
* of choice point frames.<br>
* Each choice point frame has the following fields:
* <ul>
* <li><em>arguments</em>
* <li><em>continuation goal</em>
* <li><em>next clause</em>
* <li><em>trail pointer</em>
* <li><em>cut point</em>
* <li><em>time stamp</em>
* </ul>
*
* @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
* @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
* @version 1.0
*/
public class CPFStack implements Serializable {
/** Maximum size of enties. Initial size is <code>20000</code>. */
protected int maxContents = 20000;
/** An array of choice point frames. */
protected CPFEntry[] buffer;
/** the top index of this <code>CPFStack</code>. */
protected int top;
/** Holds the Prolog engine that this <code>CPFStack</code> belongs to. */
protected Prolog engine;
/** Constructs a new choice point frame stack. */
public CPFStack(Prolog _engine) {
engine = _engine;
buffer = new CPFEntry[maxContents];
top = -1;
}
/** Constructs a new choice point frame stack with the given size. */
public CPFStack(Prolog _engine, int n) {
engine = _engine;
maxContents = n;
buffer = new CPFEntry[maxContents];
top = -1;
}
/** Create a new choice point frame.
* @param entry <em>entry to save</em>
*/
void push(CPFEntry entry){
try {
buffer[++top] = entry;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("{expanding choice point stack...}");
int len = buffer.length;
CPFEntry[] new_buffer = new CPFEntry[len+10000];
for(int i=0; i<len; i++) {
new_buffer[i] = buffer[i];
}
buffer = new_buffer;
buffer[top] = entry;
maxContents = len+10000;
}
}
/** Discards all choice points. */
public void deleteAll() {
while (! empty()) {
buffer[top--] = null;
}
}
/** Discards all choice points after the value of <code>i</code>. */
public void cut(int i) {
while (top > i) {
buffer[top--] = null;
}
}
/** Discards the top of choice points. */
public void delete() { buffer[top--] = null; }
/** Discards all choice points. */
public void init() { deleteAll(); }
/** Tests if this stack has no entry. */
public boolean empty() { return top == -1; }
/** Returns the value of <code>top</code>.
* @see #top
*/
public int top() { return top; }
/** Returns the value of <code>maxContents</code>.
* @see #maxContents
*/
public int max() { return maxContents; }
CPFEntry topEntry() { return buffer[top]; }
void restore() { buffer[top].restore(engine); }
/** Returns the <em>time stamp</em> of current choice point frame. */
public long getTimeStamp() { return buffer[top].timeStamp; }
/** Shows the contents of this <code>CPFStack</code>. */
public void show() {
if (empty()) {
System.out.println("{choice point stack is empty!}");
return;
}
for (int i=0; i<=top; i++) {
System.out.print("stack[" + i + "]: ");
System.out.println(buffer[i]);
}
}
}