# Identify the independent variable in an expression [duplicate]

Suppose that you write something like this for your students. This is just the beginning of something I would like to write to help them with the formal definition of a limit, but I am puzzled by the first output.

formalLimit[expr_, a_, L_, ϵ_] := Module[{f},
f[x_] := expr;
f[2]
]


So, my first question is, when I enter

formalLimit[x^2, 2, 4, .1]


Why do I get the output $x^2$?

Once I get past this problem, my next question is, suppose a student enters an expression $\sqrt{4-t^2}$, not using my choice of $x$ as the independent variable. How can I identify their choice of independent variable in the expr_, then change it to $x$ when using f[x_]:=expr ?

Update: I'd like to thank all of my colleagues for their kind responses. Here is what I was able to do thanks to your help. Students will get a question (yes, it can be answered much more quickly using Mathematica techniques such as Reduce, etc, but I want a visual introduction to the formal definition of a limit) such as "Use a graph to find a number $\delta$ such that

$$|f(x)-L|<\epsilon\qquad\text{whenever}\qquad0<|x-a|<\delta.$$

As an example, find a $\delta$ such that

$$|\sqrt{x}-1|<0.5\qquad\text{whenever}\qquad0<|x-1|<\delta$$

I've written this function:

formalLimit[expr_, var_, a_, L_, ϵ_] :=
DynamicModule[{f, δ},
f = (expr /. var -> #) &;
Manipulate[
δ = Min[Abs[p[[1]] - a], Abs[q[[1]] - a]];
Show[
Plot[f[x], {x, a - zoom, a + zoom},
PlotRange -> {{a - zoom, a + zoom}, {L - 2 ϵ, L + 2 ϵ}},
Epilog ->
Arrow[{{a, L - 2 ϵ}, {a, f[a]}, {a - 1.5 δ, L}}],
{Red, Dashed,
InfiniteLine[{{p[[1]], L - ϵ}, {p[[1]], L + ϵ}}],
InfiniteLine[{{q[[1]], L - ϵ}, {q[[1]], L + ϵ}}]}},
AxesLabel -> {ToString[var], "y"},
PlotLabel -> "δ = " <> ToString[δ],
AxesOrigin -> {a - 1.5 δ, L - 2 ϵ},
Ticks -> {{p[[1]], a, q[[1]]}, {L - ϵ, L, L + ϵ}}],
Plot[{L - ϵ, L + ϵ}, {x, a - zoom, a + zoom},
PlotStyle -> Directive[Dashed, GrayLevel[0.8]],
Filling -> {1 -> {2}}]],
{{zoom, 3}, 0.0001, 3, Appearance -> "Labeled"},
{{p, {a - 1, L - ϵ}}, Locator, Appearance -> None},
{{q, {a + 1, L + ϵ}}, Locator, Appearance -> None}]]


Then the students can enter:

formalLimit[Sqrt[x], x, 1, 1, .5]


And they get this image, where they can use their mouse to drag the dashed vertical lines to help determine $\delta$. There is also a slider for some zooming to adjust the horizontal size of the window.

This function has only been slightly tested, so I wouldn't mind hearing warnings and suggestions.

• It's an issue of scoping: the x in expr is not the same as the locally scoped pattern variable in f[x_]. The result from Trace[formalLimit[x^2, 2, 4, .1]] should help in understanding this. – Daniel Lichtblau Jan 2 '16 at 20:20
• @DanielLichtblau The Trace command returns a bunch of stuff I don't understand, but I focused on the part Module[{f$}, f$[x$_] := x^2, which I think you are referring to. – David Jan 2 '16 at 22:42 • Yes, it was exactly that "variable renaming" that I had meant. It shows that there is alocalized scoping of the pattern variable. – Daniel Lichtblau Jan 2 '16 at 23:40 • @Jens So I've been trying to figure out exactly why all the answers here are so different from the great answer you gave me to the question you referenced in your comment above. – rogerl Jan 3 '16 at 1:29 • Scoping issues aside, I will say I like this means of illustrating limits. Also there may be some very good approaches in Wolfram Demonstrations. Okay, I think I got that mandatory advertising itch out of my system. – Daniel Lichtblau Jan 3 '16 at 3:53 ## 4 Answers As Daniel Lichtblau points out in the comments, it's a scoping problem. From the documentation: The named formal parameters xi in Function[{x1,...}, body] are treated as local, and are renamed xi$ when necessary to avoid confusion with actual arguments supplied to the function.

You can get around this in several ways:

1. Although I don't recommend it, you can explicitly supply x$ as the variable in expr: formalLimit[x$^2, 2, 4, .1]


4

This will not solve your second problem.

2. A better way is to rewrite formalLimit to take an extra argument specifying the variable for which the limit is being taken:

formalLimitMk2[expr_, var_, a_, L_, \[Epsilon]_] := Module[{f},
f = (expr /. var -> Slot[]) &;
f[2]
]

formalLimitMk2[x^2, x, 2, 4, .1]


4

3. If your functions will all have only one variable, you can use Variables to extract it:

formalLimitMk3[expr_, a_, L_, \[Epsilon]_] := Module[{f},
f = (expr /. First@Variables@expr -> Slot[]) &;
f[2]
]

formalLimitMk3[Sqrt[4 - t^2], x, 2, 4, .1]


0

Variables is described in the documentation as working for polynomials.

Use an optional argument for the variable with a default of x

Clear[formalLimit]

formalLimit[expr_, a_, L_, ϵ_, sym : _Symbol : x] :=
Module[{f}, f[y_] := expr /. sym -> y;
f[2]]

formalLimit[x^2, 2, 4, .1]

(*  4  *)

formalLimit[z^2, 2, 4, .1, z]

(*  4  *)

• That default for the formal argument sym is dangerous. Consider With[{x = 42}, formalLimit[x^2, 2, 4, .1]]; it does not return 4. – m_goldberg Jan 2 '16 at 21:41

I would approach of problem of giving students a formal limit evaluator from a different point of view. I would write a multivariate formal limit evaluator and specialize for the single variable case. Since I have a version of Mathematica that is later than V10.1, I would make use of the fairly new ContainsAll function.

formalLimit[expr_, x_Symbol -> val_] := formalLimit[expr, {x -> val}]
formalLimit[expr_, rules : {(_Symbol -> _) ..}] :=
(expr /. rules) /; ContainsAll[Cases[expr, _, ∞], rules[[All, 1]]]


With these definitions, the following evaluations succeed.

formalLimit[1/x, x -> ∞]


0

formalLimit[Sqrt[x^2 + y^2], {x -> 3, y -> 4}]


5

But these evaluations fail as they should,

formalLimit[Sqrt[x^2 + z^2], {x -> 3, y -> 4}]


formalLimit[Sqrt[x^2 + z^2], {x -> 3, y -> 4}]

formalLimit[Sqrt[x^2 + y^2], {x -> 3, z -> 4}]


formalLimit[Sqrt[x^2 + y^2], {x -> 3, z -> 4}]

With[{x = 42}, formalLimit[Sqrt[x^2 + y^2], {x -> 3, y -> 4}]]


formalLimit[Sqrt[1764 + y^2], {42 -> 3, y -> 4}]

• A problem with multivariate limit handling is that you have to be clear as to what exactly is the limit you are taking. (Something like "y before z except after c"?) – Daniel Lichtblau Jan 3 '16 at 0:04
• @DanielLichtblau. I don't think David (the OP) is really trying to take real limits, but your point it well-taken. – m_goldberg Jan 3 '16 at 0:17

This solution works for any variable identifier consisting of one character

formalLimit[expr_, a_, L_, eps_] :=
Block[{f, x$, p}, p = Position[expr, s_Symbol /; StringLength@ToString@s == 1]; f[x_] := ReplacePart[expr, p -> x$];
f[2]]

formalLimit[Sqrt[4 - t^2], 2, 4, .1]


0

• Exactly, thanks for noticing :) – eldo Jan 2 '16 at 21:53