Re: Flat, OneIdentity Again

• To: mathgroup at smc.vnet.net
• Subject: [mg21679] Re: [mg21637] Flat, OneIdentity Again
• From: Andrzej Kozlowski <andrzej at tuins.ac.jp>
• Date: Fri, 21 Jan 2000 04:00:39 -0500 (EST)
• Sender: owner-wri-mathgroup at wolfram.com

```I was left still somewhat puzzled after sending my previous reply to this
message, so I investigeted the question a little more and would like to add
a few addtional comments. basically i am still of the opinion which I
expressed at the end of the last message: which is that when a function f
has the Attribute Flat (or Flat and OneIdentity) it gets invloved in pattern
matching in various ways which are not clealry documented and are not based
on a single clear principle. This means it is difficult to work out what is
going on by logic alone and one has to experiment. We know that if f has the
attribute Flat it will sometimes use f[f[a]] in place　of f[a] in pattern
matching and sometimes not, and the rules which it uses to decide when to do
so are not documented. Here is an example which partly at least explains the
problem discussed at the end of my last reply.

In[1]:=
SetAttributes[f, {Flat}]

Now observe the following:

In[2]:=
MatchQ[f[3], f[x_Integer]]
Out[2]=
False

In[3]:=
MatchQ[f[3], f[x_]]
Out[3]=
True

We already know the reason for this. The pattern matcher replaced f[3] by
f[f[3]]so the first match did not work but the second did.

But now :

In[4]:=
MatchQ[f[g[3]], f[g[x_Integer]]]
Out[4]=
True

The pattern matcher did not replace f[g[3]] by f[f[g[3]] so the direct match
worked.

In other words the pattern matcher takes the form of the argument into
account when deciding when if to use the "equivalence" of f[a] and f[f[a]]
in pattern matching. Exactly what rules it uses is not, as far as I can
tell, documented.

This seems to explain why we have:

In[5]:=
MatchQ[f[a], f[f[x_]]]
Out[5]=
True
In[6]:=
MatchQ[f[a], HoldPattern[f[f[x_]]]]
Out[6]=
False
--

In the first case f[f[x__]] was first replaced by f[x_], then f[a] by
f[f[a]] and a match was found. In the second case f[a] was not replaced by
f[f[a]] at all, so no match was found.

As I wrote in my earlier message, on the whole the behaviour of Flat
illustrated here seems to be based on ad hoc rules rather than a universal
logical principle and gives the distinct impression of being based on an
unfinished idea. This is even more true about the OneIdentity attribute. By
the way, this attribute has one other aspect, which has nothing to do with
Flat, and which, as far as I can tell, is quite independent of what we have
been discussing. It manifests itself only in connection with the use of
Optional in patterns (or Defaults) and can me summed up by the following
example:

In[7]:=
ClearAll[f]
In[8]:=
SetAttributes[f, OneIdentity]
In[9]:=
MatchQ[a, f[x_:b]]
Out[9]=
True

In[10]:=
MatchQ[a, f[x_]]

Out[10]=
False

This is a very useful property of OneIdentity, but it does not seem to be
logically connected with the other one (which applies in the presence of
Flat), and is also not clearly documented.

I suggest that both attributes should either be re-structured based on some
coherent and intuitive rules or failing that precise documentation should be

--
Andrzej Kozlowski
Toyama International University
JAPAN
http://sigma.tuins.ac.jp

> From: Andrzej Kozlowski <andrzej at tuins.ac.jp>
To: mathgroup at smc.vnet.net
> Date: Tue, 18 Jan 2000 22:20:30 +0900
> To: "Ersek, Ted R" <ErsekTR at navair.navy.mil>, <mathgroup at smc.vnet.net>
> Subject: [mg21679] Re: [mg21637] Flat, OneIdentity Again
>
>
> Below are a few somewhat speculative comments on some points you have raised.
>
>> At http://support.wolfram.com/Kernel/Symbols/System/Flat.html
>> it says in so many words ....
>> If (f) has the Flat attribute you better not have a definition like
>> f[p_]:=p
>> because if you do, then an attempt to evaluate f[1,2] will not work and the
>> kernel will have to quit when the infinite iteration limit is exceeded.
>>
>> In addition I found that you can't even evaluate f[2] in the above case, and
>> it doesn't help if (f) also has the OneIdentity attribute!
>
> What happens is that you if you evaluate f[1,2] you get into an infinite loop
> since Mathematica trying to match the pattenrn re-writes this as f[f[1,2]]
> then re-writes the inner f[1,2] as f[f[1,2]] and so on. However, you can avoid
> this problem by using the (non-standard) approach of giving f the Flat
> attribute only after the definition of f. You get most of the properties of a
> flat function without the infinite loop:
>
> In[1]:=
> ClearAll[f]
> In[2]:=
> f[p_] := p
> In[3]:=
> SetAttributes[f, Flat];
> In[4]:=
> f[a]
> Out[4]=
> a
> In[5]:=
> f[f[a, b], f[c]]
> Out[5]=
> f[a, b, c]
> In[6]:=
> f[1, 2]
> Out[6]=
> f[1, 2]
>
>>
>> But if the pattern matcher treats f[1,2] as f[f[1,2]]
>> why doesn't MatchQ return True in Out[4] below ?
>>
>> In[5]:=
>> MatchQ[f[1,2],HoldPattern[f[f[_Integer,_Integer]]]]
>> Out[5]=
>> False
>
> In this case there is no match whether you use HoldPattern or not.
> In[7]:=
> ClearAll[f]
> In[8]:=
> SetAttributes[f, Flat];
> In[9]:=
> MatchQ[f[1, 2], f[f[_Integer, _Integer]]]
> Out[9]=
> False
>
> I think this is basically the same problem as in your first message on this
> topic. Mathemtica converts f[1,2] to f[f[1,2]]. Now it tries to make the match
> f[f[1,2]] and HoldPattern[f[f[_Integer,_Integer]]. For the match to hold
> however, f[1,2] would have to match f[_Integer,_Integer]. However, if f has
> the attribute Flat this is not so:
>
> In[10]:=
> MatchQ[f[1, 2], f[_Integer, _Integer]]
> Out[10]=
> False
>
>>
>> Even stranger is the next line where the pattern is much more general!
>> Notice that is a triple blank inside (f).
>>
>> In[6]:=
>> MatchQ[f[1,2],HoldPattern[f[f[___]]]]
>> Out[6]=
>> False
>
> It seems to me that this is a quite differerent problem from the above one.
> This time without HoldPattern we do have a match:
>
> In[11]:=
> MatchQ[f[1, 2], f[f[___]]]
> Out[11]=
> True
>
> so this seems to contradtict your theory that holdPattern is being ignored.
> It seems to me that the reason can be seen when we compare these two results:
>
> In[13]:=
> MatchQ[f[a], f[f[x_]]]
> Out[13]=
> True
> In[14]:=
> MatchQ[f[a], f[x_]]
> Out[14]=
> True
>
> Both of these work because f[something] is matched with f[f[something]], but
> in a different way. In the first case f[f[x_]] is replaced by f[x_] so
> inserting HoldPattern prevents matching:
>
> In[15]:=
> MatchQ[f[a], HoldPattern[f[f[x_]]]]
> Out[15]=
> False
>
> In the other case the f[a] on the left is replaced by f[f[a]] so HoldPattern
> has no effect:
>
> In[16]:=
> MatchQ[f[a], HoldPattern[f[x_]]]
> Out[16]=
> True
>
> Of course this is esentially speculation because there is no reliable
> documentation. While we know that  expressions like x and f[x]  are matched in
> the presence of the Flat or  Flat and OneIdentity attributes exactly how it is
> done is not really clearly documented. I believe this is due to the fact that
> both of these attributes, particulalry OneIdentity are not in their final
> version, and this behaviour will probably change in the future.
>
>
> --
> Andrzej Kozlowski
> Toyama International University
> JAPAN
> http://sigma.tuins.ac.jp

```

• Prev by Date: Re: Flat, OneIdentity Again
• Next by Date: Re: Flat, OneIdentity Again
• Previous by thread: Re: Flat, OneIdentity Again
• Next by thread: Re: Flat, OneIdentity Again