       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:=
> ClearAll[f];
> Attributes[f]={Flat,OneIdentity};
> f[1,2,3]//.f[a_,b_]:>{a,b}
>
> Out=
> {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,f[f,f]] then uses the replacement rule and
> {f,{f,f}} is returned.
>
> In:=
> ClearAll[f];
> Attributes[f]={Flat};
> f[1,2,3]//.f[a_,b_]:>{a,b}
>
> Out=
> {f,{f,f}}
>
> 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:=
> ClearAll[f]
> Attributes[f]={Flat,OneIdentity};
> f/.f[n_Integer]:>n+10
>
> Out=
> 12
>
> --------------------------------
> For reasons I can't understand the rule isn't used in the next example. Can
> anyone explain why?
>
> In:=
> ClearAll[f]
> Attributes[f]={Flat};
> f/.f[n_Integer]:>n+10
>
> Out=
> f
>
> ---------------------------------------------
> 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:= ClearAll[f];
In:= f[a] /. f[x_] :> h[x]
Out= h[a]
-- normal case: f[_] matches f with one argument, x_ matches a

In:= ClearAll[f];
Attributes[f] = {Flat};
In:= f[a] /. f[x_] :> h[x]
Out= 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:= ClearAll[f];
Attributes[f] = {Flat, OneIdentity};
In:= f[a] /. f[x_] :> h[x]
Out= h[a]
-- here f[_] matches f with one argument, and x_ matches a_ because of
OneIdentity

change anything, but you had n_Integer instead of x_ here, so n_Integer
could not match f in case of Flat only. The other cases did match
obviously.

For fun let's look at some other cases:

In:= ClearAll[f];
In:= f[f[a]] /. f[x_] :> h[x]
Out= h[f[a]]
-- ok, clear

In:= ClearAll[f];
Attributes[f] = {Flat};
In:= f[f[a]] /. f[x_] :> h[x]
Out= h[f[a]]
--  because of flatness there can be no difference between this lhs. and
simple f[a] as above in Out, so again x_ matches f[a]

In:=
ClearAll[f];
Attributes[f] = {Flat, OneIdentity};
In:= f[f[a]] /. f[x_] :> h[x]
Out= h[a]
-- again as above, for the same reason

What happens with two arguments?

In:= ClearAll[f];
In:= f[a, b] /. f[x_] :> h[x]
Out= f[a, b]
-- no match, obviously

In:= ClearAll[f];
Attributes[f] = {Flat};
In:= f[a, b] /. f[x_] :> h[x]
Out= 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:= ClearAll[f];
Attributes[f] = {Flat, OneIdentity};
In:= f[a, b] /. f[x_] :> h[x]
Out= h[f[a, b]]
-- OneIdentity is not involved here

A variant

In:= ClearAll[f];
In:= f[a, f[b]] /. f[x_] :> h[x]
Out= f[a, h[b]]
-- f[x_] matches f[b]

In:= ClearAll[f];
Attributes[f] = {Flat};
In:= f[a, f[b]] /. f[x_] :> h[x]
Out= h[f[a, b]]
-- f[a,f[b]] is equivalent to f[f[a,b]]

In:= ClearAll[f];
Attributes[f] = {Flat, OneIdentity};
In:= f[a, f[b]] /. f[x_] :> h[x]
Out= h[f[a, b]]
-- same here

Interestingly things are somewhat different with BlankSequence[]

In:= ClearAll[f];
Attributes[f] = {Flat};
In:= f[a] /. f[x__] :> h[x]
Out= h[a]
-- f[f[a]] is not tried here, x__ matches directly to a. ReplaceList
shows this is the only match.

In:= ClearAll[f];
Attributes[f] = {Flat};
In:= f[f[a]] /. f[x__] :> h[x]
Out= h[a]
-- this match is consistent with Out, as it should

In:= ClearAll[f];
Attributes[f] = {Flat};
In:= f[a, b] /. f[x__] :> h[x]
Out= h[a, b]
-- now x__ matches the Sequence[a, b], again consistent with Out

In:= ClearAll[f];
Attributes[f] = {Flat};
In:= f[a, f[b]] /. f[x__] :> h[x]
Out= 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