void ExprCopy::visit(const ExprApply& e) {
	for (int i=0; i<e.nb_args; i++)
		visit(e.arg(i));

	if (fold) {
		int i=0;
		for (; i<e.nb_args; i++) {
			if (!dynamic_cast<const ExprConstant*>(&ARG(i))) break;
		}
		if (i==e.nb_args) {
			Array<const Domain> d(e.nb_args);
			for (i=0; i<e.nb_args; i++) {
				d.set_ref(i,((const ExprConstant&) ARG(i)).get());
			}
			clone.insert(e, &ExprConstant::new_(Eval().eval(e.func,d)));
			return;
		}
	}

	Array<const ExprNode> args2(e.nb_args);
	for (int i=0; i<e.nb_args; i++) {
		args2.set_ref(i,ARG(i));
		// don't remove this node even if it is a constant because
		// it is an argument of this function call.
		mark(e.arg(i));
	}

	clone.insert(e, &ExprApply::new_(e.func, args2));
}
void ConstantGenerator::visit(const ExprApply& e) {
	// TODO: test
	Domain* d= new Domain(e.dim);
	Array<const Domain> args(e.nb_args);

	for (int i=0; i<e.nb_args; i++) {
		visit(e.arg(i));
		NOT_INF;
		const Domain* di=map[e.arg(i)];
		args.set_ref(i,*di);
	}
	*d=e.func.basic_evaluator().eval(args);
	for (int i=0; i<e.nb_args; i++) {
		delete &args[i];
	}
	map.insert(e,d);
}