package code.instr;

import code.space.Client;
import code.space.Computation;
import code.space.ComputationFactory;
import code.space.Space;
import code.stuff.Logger;
import code.stuff.Tracer;
import code.subst.Subst;
import code.term.Term;

import java.util.Vector;

/**
 * Execute a non-deterministic step. This instruction is executed when
 * a narrex has multiple replacements.  All the replacements are on
 * the pre-term stack at the time the instruction is executed.  The
 * current computation is abandoned. A new computation is created and
 * started for each replacement.
 *
 * @author Sergio Antoy
 * @since June 17, 2003
 */

public class Choice implements Instruction {

    private Choice() {}
    public final static Choice singleton = new Choice();

    public void execute(Computation computation) {
        Term term = computation.getTerm();
        Subst subst = computation.getSubst();
        Computation top = computation.getTop();
        Client client = top.client;
        Term topLevel = top.getResult();
        int counter = Space.instance.preTerm.size();
        for (int i = 0; i < counter; i++) {
            Term reduct = (Term) Space.instance.preTerm.pop();
            if (Tracer.instruction) {
                Logger.logln(computation.getIdString() +
                        ": Choice: " + reduct);
            }
	    if (Tracer.reduction) 
		Tracer.traceRewrite(computation, term, reduct);
	    // Maybe it should count this as a ND step
	    Tracer.steps++;
            Term newTerm = topLevel.cloneWithReplace(term, reduct);
            ComputationFactory.create(newTerm, subst, client);
        }
        computation.selfSetState(Computation.ABANDONED);
    }

    public String printAsTxtLoadable() { return "Choice"; }
}
