public Operation exec()

in src/builtin/PRED_functor_3.java [34:98]


    public Operation exec(Prolog engine) {
        engine.setB0();
	Term a1, a2, a3;
	a1 = arg1;
	a2 = arg2;
	a3 = arg3;

	// functor(?X,+Y,+Z)
	a1 = a1.dereference();
	if (a1 instanceof VariableTerm) {
	    a2 = a2.dereference();
	    if (a2 instanceof VariableTerm)
		throw new PInstantiationException(this, 2);
	    if (!(a2 instanceof SymbolTerm) &&  !((a2 instanceof IntegerTerm) || (a2 instanceof DoubleTerm)) && !(a2 instanceof JavaObjectTerm) && !(a2 instanceof ClosureTerm))
		throw new IllegalTypeException(this, 2, "atomic", a2);
	    a3 = a3.dereference();
	    if (a3 instanceof VariableTerm)
		throw new PInstantiationException(this, 3);
	    if (! (a3 instanceof IntegerTerm))
		throw new IllegalTypeException(this, 3, "integer", a3);
	    int n = ((IntegerTerm)a3).intValue();
	    if (n < 0)
		throw new IllegalDomainException(this, 3, "not_less_than_zero", a3);
	    if (n == 0) {
		if(! a1.unify(a2, engine.trail))
		    return engine.fail();
		return cont;
	    }
	    if (! (a2 instanceof SymbolTerm))
		throw new IllegalTypeException(this, 2, "atom", a2);
	    if (n == 2  &&  a2.equals(SYM_DOT)) {
		Term t = new ListTerm(new VariableTerm(engine), new VariableTerm(engine));
		if(! a1.unify(t, engine.trail))
		    return engine.fail();
		return cont;
	    }
	    Term[] args = new Term[n];
	    for(int i=0; i<n; i++)
		args[i] = new VariableTerm(engine);
	    SymbolTerm sym = SymbolTerm.create(((SymbolTerm)a2).name(), n);
	    if(! a1.unify(new StructureTerm(sym, args), engine.trail))
		return engine.fail();
	    return cont;
	}
	// functor(+X,?Y,?Z)
	Term functor;
	IntegerTerm arity;
	if (a1 instanceof SymbolTerm || ((a1 instanceof IntegerTerm) || (a1 instanceof DoubleTerm)) || a1 instanceof JavaObjectTerm || a1 instanceof ClosureTerm) {
	    functor = a1;
	    arity   = new IntegerTerm(0);
	} else if (a1 instanceof ListTerm) {
	    functor = SYM_DOT;
	    arity   = new IntegerTerm(2);
	} else if (a1 instanceof StructureTerm) {
	    functor = SymbolTerm.create(((StructureTerm)a1).name());
	    arity   = new IntegerTerm(((StructureTerm)a1).arity());
	} else {
	    return engine.fail();
	}
	if(! a2.unify(functor, engine.trail)) 
	    return engine.fail();
	if(! a3.unify(arity, engine.trail)) 
	    return engine.fail();
	return cont;
    }