@Override
    public Expression<T> simplify(T type) {
        for (int k = 0; k < SIMPLIFY_RATE; k++) {
            for (int i = 0; i < arguments.size(); i++) { //simplify all the arguments
                arguments.set(i, arguments.get(i).simplify(type));
            }
            for (int i = 0; i < arguments.size(); i++) {
                for (int j = i + 1; j < arguments.size(); j++) {
                    if (arguments.size() > 1) {
                        Expression<T> left = arguments.get(i);
                        Expression<T> right = arguments.get(j);
                        Expression<T> res = simplifyTwo(left, right, type);
                        if (res != null) {
                            arguments.remove(left);
                            arguments.remove(right);
                            arguments.add(res);
                        }
                    } else return this;
                }
            }
        }
        return this;
    }