MathGroup Archive 1998

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Flat riddle




Continuing with the detailed reply from Robby Villegas:

I said:  *******************
|> At http://www.wolfram.com/support/Kernel/Symbols/findsymbol.cgi |>
Wolfram Research Technical Support points out that you will run into |>
trouble  if you have a function (f) with the Flat attribute, and the |>
rule ( f[p_]:=p  ).
|> If (f) has these properties then ( f[1,2] ) will result in infinite
|> iteration.
|
|
Robby said:  *******************
|If you want f to ungroup its arguments that have head f, and also to
|act as the identity on a single argument, I recommend that you avoid
|attributes and use definitions instead.  Here is a foundation that |I
think will establish the basic properties you want for f: |
|  ClearAll[f]
|
|  f[elems___] /; MemberQ[Unevaluated[{elems}], _f] := |   
Flatten[Unevaluated @ f[elems], Infinity, f] |
|  f[singleton_] := singleton
|
|  f[] = 0  (* Degenerate case:  replace 0 with whatever you like *) |
|From here, you can add definitions for several arguments that have the
|luxury of assuming a canonical form where arguments don't have head f.
|For instance, I think this one will implement the formula you wanted:
|
|  f[p1_, p2_, q_] := {f[p1, p2], q} |
|As a rule of thumb, if I want f to group its arguments, I prefer to do
this |myself with definitions that make the intention explicit, rather
than |leaving it up to the Flat attribute, which has a pre-set order
for trying |groupings.
|
|

Now I reply with: *****************
   I used that example to demonstrate that the Flat attribute I gave (f)
did  affect pattern matching for expressions with the head (f).   If
(f) is Flat  the pattern matcher will try to find a way to "unflatten" 
(f) to make it  fit a pattern.  I wanted to give my function (f) this
capability.

Maybe it is impossible to make a user defined function that can do the 
things Plus and Times can do.  Specifically, I would want the
following: (1)  Layers of (f) are flattened during evaluation. (2)  The
pattern matcher "unflattens" (f) to make a pattern match. (3)  (
ClearAll[p]; f[p]  ) evaluates to (p). (4)  ( ClearAll[a,b]; f[a,b] )
does not lead to infinite iteration.

I don't have a need for this capability.  I just find it disconcerting
that  a user can't create a function that has the same nuances as Plus
and Times.

Robby also wrote:  ***************
|
|There is an undocumented hack that I want to warn you against because I
|have seen it proposed from time to time.  Relying on it in your code
is |risky, since its behavior may change some day.  The hack is to set
the |attributes after the making the function definitions. |
|(* risky *)   h[] = 0;
|
|(* risky *)   h[x_] := x
|
|(* risky *)   h[p1_, p2_, q_] := {h[p1, p2], q} |
|(* risky *)   Attributes[h] = Flat; |
|
|In[14]:= ClearAll[h]
|
|In[15]:= h[] = 0;
|
|In[16]:= h[x_] := x;
|
|In[17]:= h[p1_, p2_, q_] := {h[p1, p2], q} |
|In[18]:= Attributes[h] = Flat;
|
|In[19]:= {h[], h[1], h[1, 2], h[1, 2, 3], h[h[1], h[2, 3]]} |
|Out[19]= {0, 1, h[1, 2], {h[1, 2], 3}, {h[1, 2], 3}} |
|
   I found that when I do this (h) is Flat for evaluation purposes, but
the  pattern matcher doesn't "unflatten" (h) to make an expression
match a  pattern.

|
|> One Mathematica expert has told me it's impossible.  I couldn't
believe |> it,  so I continued searching for a solution.  I think I
found one. |>
|> In[1]:=
|> $Post=ReplaceAll[#,f[a_]->a]&;
|> Attributes[f]={Flat,OneIdentity}; |
|
|One problem I have with this, and I gather it makes you uncomfortable,
too, |is that it clobbers $Post to implement simplification of a
specific |function.  What if you have fifteen functions where you're
having |difficulty getting simplifications to work?  Do you keep adding
rules |to $Post?
|

********************************

  Yes.  That is way I asked the group to suggest a better approach.

|
|A deeper problem with it is the ReplaceAll, which replaces all f[a_]
|everywhere in the expression, even if you purposely wrapped them in
|Hold, or used them in something like the body of Function where they
|are supposed to remain unevaluated: |
|In[1]:= $Post = ReplaceAll[#, HoldPattern[f[a_]] :> a]&; |
|In[2]:= Attributes[f] = {Flat, OneIdentity}; |
|In[3]:= f[p_, q_] := {p, q} /; Length[p] == 2 |
|In[4]:= Hold[ f[1], f[2, 3, 4] ]
|
|Out[4]= Hold[1, f[2, 3, 4]]
|
|It's even difficult to see what rule is attached to $Post now: |
|In[5]:= $Post
|
|Out[5]= #1 /. HoldPattern[a_] :> a & |
***********************************

  I hadn't thought of all this.  It's pretty scary!

|
|It's better to set things up so the rewrites occur within the normal
|evaluation procedure.
|
************************************

  I agree.
Ted Ersek




  • Prev by Date: Re: Flat riddle
  • Next by Date: Re: ImplicitPlot Problem
  • Prev by thread: Re: Flat riddle
  • Next by thread: Re: Flat riddle