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 made available. -- 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