Re: Defining a flat, orderless, one-identical function?
- To: mathgroup at smc.vnet.net
- Subject: [mg28071] Re: [mg28046] Defining a flat, orderless, one-identical function?
- From: Andrzej Kozlowski <andrzej at platon.c.u-tokyo.ac.jp>
- Date: Fri, 30 Mar 2001 04:12:23 -0500 (EST)
- Sender: owner-wri-mathgroup at wolfram.com
This is a rather complex issue tha thas been already discussed in some detail a number of times so you shoudl search the archives to understand more. Here is just one solution to your problem, the main idea of which, if I remeber correctly, was once suggested by Carl Woll: In[1]:= SetAttributes[max, {Flat, OneIdentity, Orderless, NumericFunction}] In[2]:= max[a_?NumericQ, b_?NumericQ] := Max[a, b]; max[a_ b_, a_ c_] := a max[b, c]; (x_max/;True):=Hold[x][[1,1]] This should now work correctly, e.g.: In[3]:= max[1,3] Out[3]= 3 In[4]:= max[a,a] Out[4]= a In[5]:= max[a] Out[5]= a -- Andrzej Kozlowski Toyama International University JAPAN http://platon.c.u-tokyo.ac.jp/andrzej/ on 3/29/01 9:24 AM, Ralph Benzinger at mma-l at endlos.net wrote: > Hello: > > I've been trying to define a flat, orderless, one-identical function > `max', i.e. I want the following equivalences to hold: > > (1) max[a, max[b, c]] == max[a, b, c] > (2) max[a, b] == max[b, a] > (3) max[a] == a > > The built-in Plus[] function has exactly these properties. > > My original definition was > > In[1]:= > ClearAll[max] > SetAttributes[max, {Flat, OneIdentity, > Orderless, NumericFunction}] > max[a_?NumericQ, b_?NumericQ] := Max[a, b] > max[a_ b_, a_ c_] := a max[b, c] > > That works fine except for one-identity: > > In[5]:= > max[x] > Out[5]= > max[x] > > For some reason I cannot quite fathom, the developers of > Mathematica decided to heed the OneIdentity attribute only in > pattern matching but not during evaluation. Anyway, to fix this, > I naively added the missing rule > > In[7]:= > max[a_] := a > > This works for max[x], but suddenly we have other problems: > > In[12]:= > max[x, x] > $RecursionLimit::"reclim": "Recursion depth of 256 exceeded." > General::"stop": "Further output of $RecursionLimit::reclim will > be suppressed during this calculation." > Out[12]= > Hold[max[x, x]] > > Apparently, the OneIdentity pattern matching gets in the way. While > I'm not sure about the exact matching/evaluation sequence (Trace[] > won't tell you), I assume that max[x,x] matches max[max[x],max[x]] > which eventually reduces to back to max[x,x]. > > So let's try without OneIdentity: > > In[13]:= > ClearAll[max] > SetAttributes[max, {Flat, Orderless}] > max[a_?NumericQ, b_?NumericQ] := Max[a, b] > max[a_ b_, a_ c_] := a max[b, c] > max[a_] := a > > Alas, no use: > > In[18]:= > max[x] > $IterationLimit::"itlim": "Iteration limit of 4096 exceeded." > General::"stop": "Further output of $IterationLimit::itlim will > be suppressed during this calculation. > Out[18]= > Hold[max[x]] > > Note, however, that we now have a different kind of infinite loop. > > Does any of the Mathematica experts out there know how to define a > one-identical function properly? Plus[] can do it, so there must be a > way. I'm surprised that something so fundamental should be so hard to > define. > > Regards, > Ralph