Re: Re: Re: Mathematica language issues

*To*: mathgroup at smc.vnet.net*Subject*: [mg53142] Re: [mg53112] Re: [mg53050] Re: Mathematica language issues*From*: DrBob <drbob at bigfoot.com>*Date*: Sat, 25 Dec 2004 04:00:35 -0500 (EST)*References*: <200412241058.FAA05777@smc.vnet.net>*Reply-to*: drbob at bigfoot.com*Sender*: owner-wri-mathgroup at wolfram.com

Fred, At several points you made statements I simply don't understand. The examples clarify what you meant for the most part, but I'm still wondering, so here goes: >> Unevaluated is meant to pass unevaluated arguments to a function >> body and as such it works perfectly. No one in practice is interested >> in (1+1)*Unevaluated[2+2]. Do you mean a Function body? If not, Times in that example qualifies as a function body. (I think.) >> If now no rules for f can be applied, Mathematica returns the result >> so far, with Unevaluated wrapped again around the labeled arguments. So it's only rules FOR F that matter? Does the distributive property count as a rule for Times? >> If a rule for f can be applied, the administration of arguments >> that come from Unevaluated is completely skipped. I don't get any meaning from the phrase "administration of arguments". >> I first formulate my assumption (only WRI and maybe a few others >> know if I am right!) Even if your assumption is correct (as I suspect it is), this statement doesn't really square with a later claim that there's no mystery. >> But when I ask for this result without copying and pasting >> it does NOT evaluate to 2 (1+Sqrt[3])^2. How do you "ask for this result without copying and pasting"? Maybe you meant writing Sqrt[2]*Unevaluated[Sqrt[3] + 1]*(1 + Sqrt[3])*Unevaluated[Sqrt[2]] in an input cell (manually) and evaluating. When I enter it in InputForm like that, it doesn't evaluate to 2 (1+Sqrt[3])^2. But when I enter it in the more visual form, with radicals, it DOES evaluate. THIS IS VERY STRANGE. But is that what you meant? Bobby On Fri, 24 Dec 2004 05:58:58 -0500 (EST), Fred Simons <f.h.simons at tue.nl> wrote: > > > So far I could resist the temptation to participate in this discussion. > However, in his mail Maxim Rytin presents some examples of which he thinks > the result is unpredictable. > > Maybe there is some interest in how I predict the results of simple commands > in which Unevaluated occurs. Of course these examples are of no practical > interest. Unevaluated is meant to pass unevaluated arguments to a function > body and as such it works perfectly. No one in practice is interested in > (1+1)*Unevaluated[2+2]. > > The basic principle has been clearly explained by Andrzej Kozlowsky. Suppose > we have a function f that we call with one or more Unevaluated arguments. > The first step in the evaluation procedure is that arguments are evaluated > as far as allowed and attributes such as Orderless and Flat are applied. In > this step Unevaluated is unwrapped from the argument, but Mathematica has > labeled the arguments which come from Unevaluated. If now no rules for f can > be applied, Mathematica returns the result so far, with Unevaluated wrapped > again around the labeled arguments. If a rule for f can be applied, the > administration of arguments that come from Unevaluated is completely > skipped. > > Here are three illustrative examples. Try to predict the result! > > In[1] := > ClearAll[f] > Attributes[f]={Orderless}; > > f[b, Unevaluated[a]] // Trace > > Out[3]= > {f[b,a],f[a,b],f[Unevaluated[a],b]} > > In[4]:= > ClearAll[f] > Attributes[f]={Orderless}; > f[x__]:= {x}[[1]]; > f[b, Unevaluated[a]] // Trace > > Out[7]= > {f[b,a],f[a,b],{a,b}[[1]],a} > > In[8]:= > ClearAll[f] > Attributes[f]={Orderless, Flat}; > f[b, Unevaluated[f[a,c]]] // Trace > > Out[10]= > {f[b,f[a,c]],f[b,a,c],f[a,b,c],f[Unevaluated[a],b,Unevaluated[c]]} > > The second example equals the first example, but now a rule for f is applied > so the result is a instead of Unevaluated[a]. The third example demonstrates > the labeling: the arguments a and c come from an Unevaluated argument in the > function call. Since no rule for f is applied, they are wrapped with > Unevaluated in the result, which is rather different from the original > command. > > With respect to the functions Plus and Times the results seem to different. > When we consider e.g. Times[Unevaluated[z], 2], we expect that in the first > step of the evaluation due to the attribute Orderless of Times we arrive at > Times[2, z] with z labeled as coming from an Unevaluated argument. Since no > rules for Times can be applied, we expect the result to be 2*Unevaluated[z]. > But the result is 2*z. > > In order to understand what is going on here, we must have a closer look at > the functions Plus and Times. I first formulate my assumption (only WRI and > maybe a few others know if I am right!) and then I will explain and > demonstrate it by some examples. Finally, using this hypothesis I will > explain Maxim's counterexamples. > > Hypothesis: When Mathematica has to evaluate an expression with head Plus or > Times, then immediately after the evaluation of the head, so before the use > of the attributes, Mathematica calls a function that adds or multiplies all > numerical arguments. If there are no other arguments, this result is the > outcome of the evaluation. Otherwise Plus or Times is called with this > numerical result as first argument followed by the remaining arguments. > > To illustrate the hypothesis we slightly modify the function Plus (the same > can be done with Times) so that Mathematica tells us when and how Plus is > called during the evaluation. Moreover, and that can be dangerous, we remove > the attribute Orderless of Plus. > > In[13]:= > Unprotect[Plus]; > Attributes[Plus]= Complement[Attributes[Plus], {Orderless}]; > Plus[x___] /; (Print["Plus"[x]];False) := 12 > > In[16]:= > 3 + c - 5 + b - a + 6 > >> From In[16]:= > Plus[4,c,b,-a] > > Out[16]= > 4+c+b-a > > In[17]:= > 2-5+10 > > Out[17]= > 7 > > In the first example we see from the printed message that the first time > Plus is called all numerical arguments are already added, the remaining > arguments are not sorted. In the second example we see that Plus is not > called at all. > > That indeed Mathematica automatically calls another function when an > expression with head Plus or Times is met can be seen from the following > example, for which we start with a fresh kernel. > > In[18]:= > Quit[] > > In[1]:= > Block[{Plus}, > Plus[a__]:= {a}[[1]]; > {Plus[x,1], Plus[1+12], Plus[12,x,-12]}] > > Out[1]= > {1,13,x} > > Despite the fact that within the block we have a local variable Plus with a > very different definition of the outside function Plus, the pre-evaluation > mentioned in the hypothesis takes place! (I do not consider this as a bug in > scoping but as a feature of the system names Plus and Times). > > So let us accept the hypothesis, let PrePlus and PreTimes be our names for > the functions mentioned in the hypothesis and let us consider some example's > of the type of Maxim's counterexamples. > > 1. Times[Unevaluated[z], 2]. PreTimes[Unevaluated[z], 2] applies a rule for > PreTimes, so the labeling of arguments from Unevaluated disappears and we > arrive at Times[2, z] with z not wrapped by Unevaluated. > > 2. 1 + 1 + Unevaluated[z]. PrePlus[1,1,Unevaluated[z]] applies a rule to > arrive at Plus[2, z], so z is not wrapped with Unevaluated. > > 3. 2 + Unevaluated[z]. PrePlus[2, Unevaluated[z]] has no rules to apply so > we arrive at Plus[2, z] with z still marked as coming from an Unevaluated > argument, so the result is Plus[2, Unevaluated[z]] (a different result from > the previous example!) > > 4. Unevaluated[2]/Sqrt[2]. PreTimes does not apply a rule, so we arrive at > Times[2, 1/Sqrt[2]] with the first argument still marked. Now Times applies > a rule and the result has no Unevaluated arguments. > > 5. Unevaluated[Sqrt[2] + Sqrt[2]]/Sqrt[2]. PreTimes does not apply a rule, > so we arrive at Times[1/Sqrt[2], Sqrt[2]+Sqrt[2]] with the second argument > labeled. Times has no rules for these arguments, so the outcome is > Unevaluated[Sqrt[2] + Sqrt[2]]/Sqrt[2]. > > 6. Unevaluated[Sqrt[2]*(Sqrt[3] + 1)]*Csc[Pi/12]. PreTimes does not apply a > rule so due to the attribute Flat of Times we arrive at Times[Sqrt[2], > Sqrt[3] + 1, 1 + Sqrt[3], Sqrt[2]], where the first two arguments are > labeled. Mathematica 5.1 now returns Sqrt[2] Unevaluated[Sqrt[3] + 1] (1 + > Sqrt[3]) Unevaluated[Sqrt[2]]. > > That is correct, but it puzzles me. When I copy and paste this result in an > Input cell and evaluate, the result now becomes 2 (1 + Sqrt[3])^2 . That is > what I had expected and which is Maxim's result. But when I ask for this > result without copying and pasting it does NOT evaluate to 2 (1+Sqrt[3])^2. > This is more an evaluation problem (bug?) in version 5.1 than that is has to > do with the basic properties of Unevaluated as discussed above. > > 7. Unevaluated[Sqrt[6]+Sqrt[2]]*Csc[Pi/12]. PreTimes does not apply a rule > so we arrive at Times[Sqrt[2], 1 + Sqrt[3], Sqrt[6] + Sqrt[2]] with the last > argument labeled. There are no rules for Times to be used, so Mathematica > returns Sqrt[2]*(1 + Sqrt[3]) Unevaluated[Sqrt[6] + Sqrt[2]]. > > Hence, despite the problem mentioned in example 6, my feeling is that there > is nothing mysterious and unpredictable in the behaviour of Unevaluated in > the examples discussed so far. > > Fred Simons > > Eindhoven University of Technology > > > > > -- DrBob at bigfoot.com www.eclecticdreams.net

**Follow-Ups**:**Re: Re: Re: Re: Mathematica language issues***From:*Andrzej Kozlowski <akoz@mimuw.edu.pl>

**References**:**Re: Re: Re: Mathematica language issues***From:*"Fred Simons" <f.h.simons@tue.nl>