[Date Index]
[Thread Index]
[Author Index]
Re: Flat, OneIdentity attributes
*To*: mathgroup at smc.vnet.net
*Subject*: [mg21641] Re: [mg21600] Flat, OneIdentity attributes
*From*: Hartmut Wolf <hwolf at debis.com>
*Date*: Tue, 18 Jan 2000 02:35:24 -0500 (EST)
*Organization*: debis Systemhaus
*References*: <200001170343.WAA13401@smc.vnet.net>
*Sender*: owner-wri-mathgroup at wolfram.com
Ersek, Ted R schrieb:
>
> For the most part I understand how Flat and OneIdentity are related and I
> demonstrate this using Version 4 in the examples below.
>
> In the first example (f) has the attributes Flat and OneIdentity.
> The pattern matcher treats f[a,2,3] as f[a,f[2,3]] then uses the
> replacement rule and {1,{2,3}} is returned.
>
> In[1]:=
> ClearAll[f];
> Attributes[f]={Flat,OneIdentity};
> f[1,2,3]//.f[a_,b_]:>{a,b}
>
> Out[3]=
> {1,{2,3}}
>
> ---------------------------------------------------
> In the next example the only attribute (f) has is Flat.
> In this case the pattern matcher treats f[1,2,3] as
> f[f[1],f[f[2],f[3]]] then uses the replacement rule and
> {f[1],{f[2],f[3]}} is returned.
>
> In[4]:=
> ClearAll[f];
> Attributes[f]={Flat};
> f[1,2,3]//.f[a_,b_]:>{a,b}
>
> Out[6]=
> {f[1],{f[2],f[3]}}
>
> OneIdentity the pattern matcher doesn't wrap (f) around a single argument
> when it tries different ways of nesting (f).
>
> --------------------------------
> In the next example (f) has the attributes Flat, OneIdentity and the rule is
> used.
>
> In[7]:=
> ClearAll[f]
> Attributes[f]={Flat,OneIdentity};
> f[2]/.f[n_Integer]:>n+10
>
> Out[9]=
> 12
>
> --------------------------------
> For reasons I can't understand the rule isn't used in the next example. Can
> anyone explain why?
>
> In[10]:=
> ClearAll[f]
> Attributes[f]={Flat};
> f[2]/.f[n_Integer]:>n+10
>
> Out[12]=
> f[2]
>
> ---------------------------------------------
> Regards,
> Ted Ersek
>
> For Mathematica tips, tricks see
> http://www.dot.net.au/~elisha/ersek/Tricks.html
Hello Ted,
the answer to your question is given in The Book, Section 2.3.7 p.274
(4th ed.), where it says:
In an ordinary function that is not flat, a pattern such as x_ matches
an individual argument of the function. But in a function f[a, b, c, ... ]
that is flat, x_ can match objects such as f[b, c] which effectively
correspond to a sequence of arguments. However, in the case where x_
matches a single argument in a flat function, the question comes up as
to whether the object it matches is really just the argument a itself,
or f[a]. Mathematica chooses the first of these cases if the function
carries the attribute OneIdentity, and chooses the second case
otherwise.
You can observe that behaviour, if you take a simple test:
In[1]:= ClearAll[f];
In[2]:= f[a] /. f[x_] :> h[x]
Out[2]= h[a]
-- normal case: f[_] matches f with one argument, x_ matches a
In[3]:= ClearAll[f];
Attributes[f] = {Flat};
In[5]:= f[a] /. f[x_] :> h[x]
Out[5]= h[f[a]]
-- now again f[_] matches f with one argument, but x_ matches f[a]
because of Attribute Flat (f[a] is converted to f[f[a]] for pattern
matching)
In[6]:= ClearAll[f];
Attributes[f] = {Flat, OneIdentity};
In[8]:= f[a] /. f[x_] :> h[x]
Out[8]= h[a]
-- here f[_] matches f with one argument, and x_ matches a_ because of
OneIdentity
For your example, Ted, you had Plus[x,10] instead of h[x], which doesn't
change anything, but you had n_Integer instead of x_ here, so n_Integer
could not match f[2] in case of Flat only. The other cases did match
obviously.
For fun let's look at some other cases:
In[9]:= ClearAll[f];
In[10]:= f[f[a]] /. f[x_] :> h[x]
Out[10]= h[f[a]]
-- ok, clear
In[11]:= ClearAll[f];
Attributes[f] = {Flat};
In[13]:= f[f[a]] /. f[x_] :> h[x]
Out[13]= h[f[a]]
-- because of flatness there can be no difference between this lhs. and
simple f[a] as above in Out[5], so again x_ matches f[a]
In[14]:=
ClearAll[f];
Attributes[f] = {Flat, OneIdentity};
In[16]:= f[f[a]] /. f[x_] :> h[x]
Out[16]= h[a]
-- again as above, for the same reason
What happens with two arguments?
In[17]:= ClearAll[f];
In[18]:= f[a, b] /. f[x_] :> h[x]
Out[18]= f[a, b]
-- no match, obviously
In[19]:= ClearAll[f];
Attributes[f] = {Flat};
In[21]:= f[a, b] /. f[x_] :> h[x]
Out[21]= h[f[a, b]]
-- a match: f[_] to f again with *one* argument. but we have two? No,
the lhs. is equivalent to f[f[a,b]] because of flatness and x_ matches
f[a,b]
In[22]:= ClearAll[f];
Attributes[f] = {Flat, OneIdentity};
In[24]:= f[a, b] /. f[x_] :> h[x]
Out[24]= h[f[a, b]]
-- OneIdentity is not involved here
A variant
In[57]:= ClearAll[f];
In[58]:= f[a, f[b]] /. f[x_] :> h[x]
Out[58]= f[a, h[b]]
-- f[x_] matches f[b]
In[59]:= ClearAll[f];
Attributes[f] = {Flat};
In[61]:= f[a, f[b]] /. f[x_] :> h[x]
Out[61]= h[f[a, b]]
-- f[a,f[b]] is equivalent to f[f[a,b]]
In[62]:= ClearAll[f];
Attributes[f] = {Flat, OneIdentity};
In[64]:= f[a, f[b]] /. f[x_] :> h[x]
Out[64]= h[f[a, b]]
-- same here
Interestingly things are somewhat different with BlankSequence[]
In[27]:= ClearAll[f];
Attributes[f] = {Flat};
In[29]:= f[a] /. f[x__] :> h[x]
Out[29]= h[a]
-- f[f[a]] is not tried here, x__ matches directly to a. ReplaceList
shows this is the only match.
In[35]:= ClearAll[f];
Attributes[f] = {Flat};
In[37]:= f[f[a]] /. f[x__] :> h[x]
Out[37]= h[a]
-- this match is consistent with Out[29], as it should
In[43]:= ClearAll[f];
Attributes[f] = {Flat};
In[45]:= f[a, b] /. f[x__] :> h[x]
Out[45]= h[a, b]
-- now x__ matches the Sequence[a, b], again consistent with Out[29]
In[51]:= ClearAll[f];
Attributes[f] = {Flat};
In[53]:= f[a, f[b]] /. f[x__] :> h[x]
Out[53]= h[a, b]
-- no surprise
In all these test cases here with Pattern[x, BlankSequence[]] there is
no difference between Attributes[f] = {Flat} and Attributes[f] = {Flat,
OneIdentity}
Kind regards, yours
Hartmut
Prev by Date:
**Re: Flat, OneIdentity attributes**
Next by Date:
**Cell Group**
Previous by thread:
**Flat, OneIdentity attributes**
Next by thread:
**Re: Flat, OneIdentity attributes**
| |