Consider the built-in function FunctionDomain to find a domain of a composite function f(f(x)) where f(x)=1/x.

FunctionDomain[Composition[f, f][x], x]
FunctionDomain[1/(1/x), x]

The output is True in both cases.

Apparently Mathematica simplifies the argument before applying the FunctionDomain. That's why it gives mathematically incorrect output (x=0 should be excluded). Composition[f,f][x]=f(f(x)) = 1/(1/x)= x. And the domain of x is all real numbers. In case when Hold function is applied to 1/(1/x) the output is x < 0 || x > 0 as it should be.

FunctionDomain[Hold[1/(1/x)], x]

Output: x < 0 || x > 0

But when Hold is applied to Composition[f, f][x] The result is completely different. FunctionDomain[Hold[Composition[f, f][x]], x] returns the input as output.

Why doesn't it work? What am I missing?


2 Answers 2


One idea is to convert the Composition into a form that partially evaluates its arguments, something like:

freezeComposition[c_Composition] := Composition[
    ReplaceRepeated[#, Hold[x_]->x]&,

Then, we can do:

FunctionDomain[freezeComposition[Composition[f,f]][x], x]


  • $\begingroup$ @ CarlWoll the function that you have defined works perfectly! However I'm not able to understand the syntax as I am a beginner user of Mathematica. $\endgroup$
    – user45937
    Jan 18, 2017 at 13:59
  • $\begingroup$ I'm wondering if it's possible to achieve the same result using any of built-in Hold functions? I noticed that not only FunctionDomain but functions like Reduce and ReplaceAll return mathematically incorrect results. f[x_] := 1/x; {Reduce[1/(1/x) == 0, x, Reals],Reduce[f[f[x]] == 0, x, Reals],Solve[1/(1/x) == 0, x, Reals],Solve[1/(1/x) == 0, x, Reals],FunctionDomain[1/(1/x), x],FunctionDomain[f[f[x]], x],1/(1/x) /. x -> 0,f[f[x]] /. x -> 0} How can I prevent (partial) evaluation of the first argument? $\endgroup$
    – user45937
    Jan 18, 2017 at 14:25
  • 1
    $\begingroup$ @roman465. All of these simplifications occur because Mathematica always attempts to find a general solution to the problem while (sort of) ignoring special (or corner) cases. $\endgroup$
    – march
    Jan 18, 2017 at 16:21

You could use StrictFunctionDomain function from Domains` package which evaluates given expression in special environment that prevents removal of removable singularities:

f // ClearAll
f[x_] := 1/x

StrictFunctionDomain[Composition[f, f][x], x]
(* x < 0 || x > 0 *)
StrictFunctionDomain[1/(1/x), x]
(* x < 0 || x > 0 *)
StrictFunctionDomain[Hold[1/(1/x)], x]
(* x < 0 || x > 0 *)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.