package code.term.visitor;

import code.symbols.DataSymbol;
import code.table.MapTable;
import code.term.*;

/**
 * @author Stephen Johnson
 * @since Jul 6, 2004
 *
 * Generics-ized on 4/11/05
 */
public class OccurCheckTermVisitor implements TermVisitor<Boolean,TermImpl> {

    public static OccurCheckTermVisitor singleton
	= new OccurCheckTermVisitor();

    public static final Boolean FALSE = new Boolean(false);
    public static final Boolean TRUE = new Boolean(true);

    private OccurCheckTermVisitor() {}

    public Boolean visit(TermImplChar t, TermImpl var) { return FALSE; }

    public Boolean visit(TermImplFloat t, TermImpl var) { return FALSE; }

    public Boolean visit(TermImplInt t, TermImpl var) { return FALSE; }

    public Boolean visit(TermImplString t, TermImpl var) { return FALSE; }

    public Boolean visit(TermImplOpaque t, TermImpl var) { return FALSE; }

    public Boolean visit(TermImplUser t, TermImpl var) {
        int root = t.getRoot();
        if (MapTable.getSymbol(root).kind == DataSymbol.Operation) {
            return FALSE;
        } else {
	    for (Term arg : t.getArgument()) {
		if (arg.getRepresentation().accept(this, var) == TRUE)
		    return TRUE;
            }		
            return FALSE;
        }
    }

    public Boolean visit(Variable v, TermImpl var) {
	// OK, but less efficient
	// return v == var;
	return v == var ? TRUE : FALSE;
    }

    public boolean checkOccur(Term t, Variable v) {
        return t.getRepresentation().accept(this, v) == TRUE;
    }
}

