5
$\begingroup$

In the standard evaluation process, innermost parts are evaluated first. For example:

In[0]:= (a/a + 1) * 0

The evaluation process gives:

(a/a + 1) * 0 = (1 + 1) * 0 = 2 * 0 = 0

In that case, this evaluation doesn't make sense because the result will always be 0. I'd like to write a rule where the left member "x" is never evaluated:

Multiply[x_, 0] := 0

For example:

In[1]:= Multiply[Simplify[D[Cos[x]^(x + 1)/x^4, {x, 5}], 0]
Out[1]:= 0

without evaluating Simplify[D[Cos[x]^(x + 1)/x^4, {x, 5}] which is time consuming.

The built-in rule of Mathematica is very slow too (about 2s on my machine), so it means innermost parts are evaluated first:

In[2]:= 0 * Simplify[D[Cos[x]^(x + 1)/x^4, {x, 5}]]
Out[2]:= 0

I'm not sure this kind of concept exists in Mathematica. Any suggestions?

Thanks for the help!

$\endgroup$
1
  • 2
    $\begingroup$ The reason it's defined this way is so that (1/(1-1))*0 properly gives an error message. $\endgroup$
    – QuantumDot
    May 24, 2020 at 1:51

2 Answers 2

6
$\begingroup$

We can use the attribute HoldAll:

SetAttributes[Multiply, HoldAll]

Multiply[___, 0, ___] = 0;
Multiply[args___] := Times[args]

Multiply[Pause[1000], 0] // AbsoluteTiming
{4.*10^-6, 0}
$\endgroup$
1
  • $\begingroup$ Funny, I read this as wanting to modify the behavior of Times, but reading it again that may not have been the intent at all. +1 I think you have an error though, with HoldFirst. $\endgroup$
    – Mr.Wizard
    May 23, 2020 at 23:18
2
$\begingroup$

Interesting question. I don't have time today to address this in depth but this kind of evaluation can be controlled by attributes, specifically HoldAll. One cannot change the attributes of core functions without risking serious problems however, but just to illustrate:

Internal`InheritedBlock[{Times},
  SetAttributes[Times, HoldAll];
  0*Simplify[D[Cos[x]^(x + 1)/x^4, {x, 5}]]
]

This is basically like using Unevaluated (below) but it does not require foreknowledge of which part to apply it to.

0*Unevaluated[Simplify[D[Cos[x]^(x + 1)/x^4, {x, 5}]]]
$\endgroup$
2
  • $\begingroup$ Thank you for these answers.<br/>But how to override the Times function globally for all my computations (not locally with InheritedBlock) without risking problems? $\endgroup$
    – BP75
    May 24, 2020 at 10:23
  • $\begingroup$ @BP75 I don't believe you can as modifying a deeply integrated System function could have many unforeseen consequences. The best I can offer would be an automatic replacement of all Times expressions in user input with a separate function like Chip Hurst's Multiply, but I don't know what your actual application is and this may not help. See: (117), (7223), (16652), (63147) $\endgroup$
    – Mr.Wizard
    May 24, 2020 at 12:23

Your Answer

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

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