Re: Defining a flat, orderless, one-identical function?
- To: mathgroup at smc.vnet.net
- Subject: [mg28083] Re: Defining a flat, orderless, one-identical function?
- From: Jens-Peer Kuska <kuska at informatik.uni-leipzig.de>
- Date: Fri, 30 Mar 2001 04:12:32 -0500 (EST)
- Organization: Universitaet Leipzig
- References: <99us0v$601@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
Hi, a) what is so complicated on the definion Remove[mymax] SetAttributes[mymax, {Orderless}] mymax[a__, mymax[b__], c___] := mymax[a, b, c] mymax[a_] := a mymax[a_ + c_, b_ + c_] /; NumericQ[c] := mymax[a, b] mymax[a_?NumericQ, b__?NumericQ] := Max[a, b] b) or Remove[max] max[a_] := a max[a_?NumericQ, b_?NumericQ] := Max[a, b] max[a_ b_, a_ c_] := a max[b, c] SetAttributes[max, {Flat, Orderless}] both definitions are working. The first definition is a better explanation of the problem and create the same set of rules for mymax[]/max[] If you define mymax[a_]:=a before you define mymax[a__, mymax[b__], c___] := mymax[a, b, c] the second rule is simplifyed to mymax[a__, b__, c___] := mymax[a, b, c] and this cause the recursion. So you have the case here, opposite to *all* documentation, where you have to define the attribute *after* the definition of the rules, because the attributes seems to operate on the left hand side of the delayed rules for speed reasons and to optimize the usage of the replacement rules. Regards Jens BTW: Plus[] and Times[] ar not defined in Mathermatica's language. This definitions are deep in the C-Source of the kernel... Ralph Benzinger 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 > > -- > Ralph Benzinger "This is my theory, it is mine, I own it, > Cornell University and what it is, too." -- Ann Elk (Mrs.)