Redefinition of DirectedInfinity
One way would be to add a DownValue to DirectedInfinity (the final form suggested by MicahelE2):
Unprotect[DirectedInfinity];
Clear[DirectedInfinity];
DirectedInfinity::infy = "Infinite Expression encountered";
DirectedInfinity /: call_DirectedInfinity /; ! TrueQ[inInf] :=
Block[{inInf = True},
Update[DirectedInfinity];
Message[DirectedInfinity::infy];
call
];
Protect[DirectedInfinity];
So that, for example
1 + 1/(1 + Log[0])
During evaluation of In[67]:= DirectedInfinity::infy: Infinite Expression encountered >>
During evaluation of In[67]:= DirectedInfinity::infy: Infinite Expression encountered >>
1
The call to Update is necessary to prevent an internal optimization, that would otherwise result in the messages being suppressed on subsequent calls of DirectedInfinity.
A safer version using local environment
Note that this isn't a safe modification, since it globally modifies a built-in function. As such, it may have unanticipated consequences. A safer way to do this would be to use Internal`InheritedBlock, and a dynamic environment to wrap around a piece of code you want to evaluate in this mode.
First, we have to remove the changes we made:
Unprotect[DirectedInfinity];
Clear[DirectedInfinity];
Protect[DirectedInfinity];
Here is a reasonably general generator of such dynamic environments:
ClearAll[withRedefined];
SetAttributes[withRedefined, HoldRest];
withRedefined[f_Symbol,beforeCall_,afterCall_, extraCode_]:=
Function[code,
Internal`InheritedBlock[{f},
Module[{inF, dv=DownValues[f]},
With[{protected = Unprotect[f]},
DownValues[f]={};
extraCode;
(call:f[args___])/;!TrueQ[inF]:=
Block[{inF=True},
beforeCall[args];
With[{res = call},
afterCall[args, res];
res
]
];
DownValues[f]=Join[DownValues[f],dv];
Protect[protected];
];
code
]
],
HoldAll
];
With this function, we can create our custom dynamic environment easily:
withMessageOnInfinity =
withRedefined[
DirectedInfinity
,
Function[
Update[DirectedInfinity];
Message[DirectedInfinity::infy]
]
,
Function[Null]
,
DirectedInfinity::infy = "Infinite Expression encountered";
];
So now we have without dynamic environment just the usual behavior:
1 + 1/(1 + Log[0])
(* 1 *)
while using the environment we get:
withMessageOnInfinity[1 + 1/(1 + Log[0])]
During evaluation of In[21]:= DirectedInfinity::infy: Infinite Expression encountered >>
1
Limit[Cos[x]/Sin[x], x -> 0]orFullSimplify[Cos[x]/Sin[x]] /. x -> 0? No errors. – David G. Stork Mar 09 '16 at 16:28Log[ ]states Zero and infinite arguments give symbolic results: So if you want error messages you'll need to redefine to your own functions – Dr. belisarius Mar 09 '16 at 16:33Unprotect[DirectedInfinity]; DirectedInfinity::infy = "Infinite expression encountered"; DirectedInfinity /: call : _[___, _DirectedInfinity, ___] /; ! TrueQ[inInf] := Block[{inInf = True},Message[DirectedInfinity::infy];call]; Protect[DirectedInfinity]. Can wrap that in a dynamic environment usingInternal`InheritedBlock, to avoid global redefinitions. This surely isn't remotely as nice as would be a built-in mechanism, but it may work. – Leonid Shifrin Mar 09 '16 at 16:35TraceScan[]to find instances ofDirectedInfinity[]during evaluation, and throw an appropriate message if it finds one? – J. M.'s missing motivation Mar 09 '16 at 16:44Cot[0]. If I change the declaration tocall : _DirectedInfinity /; ! TrueQ[inInf] :=..., it catches a top-level infinity. – Michael E2 Mar 09 '16 at 16:57DownValueonDirectedInfinity, which is much better / safer thanUpValueof such a general form as I suggested. – Leonid Shifrin Mar 09 '16 at 17:111/0gives a symbolic result, too, doesn't it? I'm not sure a symbolic result means there's no built-in message, off by default, that could be turned on. The more convincing evidence is that no one who has commented, including you and me, seems to know of one. – Michael E2 Mar 09 '16 at 17:26