Re: Flat: Problems & Workarounds Sweden.

*To*: mathgroup at smc.vnet.net*Subject*: [mg8492] Re: Flat: Problems & Workarounds Sweden.*From*: Robert Villegas <villegas>*Date*: Tue, 2 Sep 1997 16:15:36 -0400*Organization*: Wolfram Research*Sender*: owner-wri-mathgroup at wolfram.com

> This is the result from my work trying to construct a associative function. > Assume I want a associative function h[] which treats numerical arguments > specially. Starting from the template in Roman Maeders "Programming in > Mathematica", 3rd ed. I define h[] as > > In[3]:= SetAttributes[h,{Flat,OneIdentity}] > h[x_,y_?NumericQ] := f[y,x] > h[x_?NumericQ,y_] := f[x,y] > h[x_] := x > h[] = 1 When I want an associative function h that acts as the identity on singletons, I ditch the use of attributes like Flat and OneIdentity and write a definition to make h self-flattening. If I want h to recognize certain argument arrangements and re-group them, I control this myself with additional definitions, since the pattern-matcher under the influence of Flat might try groupings and orderings of them different from what I want. Here is how I recommend formulating your h: ClearAll[h]; h[elems___] /; MemberQ[Unevaluated[{elems}], _h] := Flatten[Unevaluated @ h[elems], Infinity, h]; h[elems__, n_?NumberQ] := f[n, h[elems]]; h[n_?NumberQ, elems__] := f[n, h[elems]]; h[singleton_] := singleton; h[] = 1; This h does what you asked for the examples you cited, and its behavior seems reasonable in related cases: In[37]:= {h[], h[1], h[a], h[1, a], h[a, 1], h[a, b], h[2, a, 3], h[2, 3, a], h[a, 2, 3]} Out[37]= {1, 1, a, f[1, a], f[1, a], h[a, b], f[3, f[2, a]], f[2, f[3, a]], f[3, f[2, a]]} Your function isn't precisely specified, so this may not be exactly what you want, but it shouldn't be difficult to modify this to do something a bit different. The key definition in h was the following h[elems___] /; MemberQ[Unevaluated[{elems}], _h] := Flatten[Unevaluated @ h[elems], Infinity, h] which canonicalizes the arguments of h so that other definitions have the luxury of knowing that none of h's arguments have head h. From there, make a list of the precise arrangements you want to recognize and re-group, e.g. (1) A bunch of arguments followed by a final NumericQ argument (2) An initial NumericQ argument followed by a bunch of arguments then add the definitions for these. It is occasionally necessary to use HoldPattern on the left-hand sides of rules, or to notice the automatic ordering of rules, but not usually. Robby Villegas