package jp.ac.kobe_u.cs.prolog.lang;
import java.io.Serializable;
/**
 * Tracks current evaluation goal and results.
 * <p>
 * On success/1 or fail/1 the corresponding methods in this class are invoked,
 * allowing the implementation to message the results to the application. During
 * any reduction loops the {@link #isEngineStopped()} method is consulted to
 * determine if the loop should terminate.
 *
 * @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
 * @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
 * @version 1.2
 */
public abstract class PrologControl {
    /** Holds a Prolog engine. */
    public Prolog engine;

    /** Holds a Prolog goal to be executed. */
    public Predicate code;

    /** Constructs a new <code>PrologControl</code>. */
    public PrologControl() {
	engine = new Prolog(this);
	code = null;
    }

    /** Sets a goal and its arguments to this Prolog thread. 
     * An initial continuation goal (a <code>Success</code> object)
     * is set to the <code>cont</code> field of goal <code>p</code> as continuation.
     */
    public void setPredicate(Predicate p, Term[] args) {
	code = p;
	code.setArgument(args, new Success(this));
    }

    /** Sets a goal <code>call(t)</code> to this Prolog thread. 
     * An initial continuation goal (a <code>Success</code> object)
     * is set to the <code>cont</code> field of <code>call(t)</code> as continuation.
     */
    public void setPredicate(Term t)  {
	try {
	    Class clazz = engine.pcl.loadPredicateClass("jp.ac.kobe_u.cs.prolog.builtin", "call", 1, true);
	    Term[] args = {engine.copy(t)};
	    code = (Predicate)(clazz.newInstance());
	    code.setArgument(args, new Success(this));
	} catch (Exception e){
	    e.printStackTrace();
	}
    }

    /**
     * Is invoked when the system succeeds to find a solution.<br>
     *
     * This method is invoked from the initial continuation goal
     * (a <code>Success</code> object).
     */
    protected abstract void success();

    /** Is invoked after failure of all trials. */
    protected abstract void fail();

    /**
     * Check if evaluation should continue.
     * <p>
     * This method gets invoked on every predicate reduction. If the control class
     * wants to halt execution (for example sufficient results were obtained, or a
     * limit on running time or reduction count has been reached) the method must
     * return true to stop execution.
     *
     * @return true if the engine is no longer supposed to execute; false if
     *         another predicate reduction can take place.
     */
    public abstract boolean isEngineStopped();

    /**
     * Execute the predicate on the current thread.
     * <p>
     * This method does not return until {@link #isEngineStopped()} returns true.
     * Implementors of the class are expected to invoke this method to perform
     * evaluation, and terminate out of the loop at the proper time based on an
     * invocation to {@link #success()} or {@link #fail()}.
     *
     * @throws PrologException
     * @throws JavaInterruptedException
     */
    protected void executePredicate()
      throws PrologException, JavaInterruptedException {
	    engine.init();
	    main_loop:while(true) {
		while (engine.exceptionRaised == 0) {
		    if (isEngineStopped())
			break main_loop;
		    code = code.exec(engine);
		}
		switch (engine.exceptionRaised) {
		case 1:  // halt/0
		    break main_loop;
		case 2:  // freeze/2
		    throw new SystemException("freeze/2 is not supported yet");
		    // Do something here
		    // engine.exceptionRaised = 0 ;
		    // break;
		default:
		    throw new SystemException("Invalid value of exceptionRaised");
		}
	    }
    }

    /** @param err stack trace to print (or log). */
    public void printStackTrace(Throwable err) {
      err.printStackTrace();
    }
}
