Re: pattern bugs and comment on intuitive syntax for the New Year
- To: mathgroup at smc.vnet.net
- Subject: [mg115187] Re: pattern bugs and comment on intuitive syntax for the New Year
- From: Andrzej Kozlowski <akoz at mimuw.edu.pl>
- Date: Tue, 4 Jan 2011 04:22:23 -0500 (EST)
- References: <ifs30a$oor$1@smc.vnet.net> <4D21F917.2020209@cs.berkeley.edu>
I have skipped most of the tired and empty rhetorics. On 3 Jan 2011, at 17:28, Richard Fateman wrote: > > So to call Lisp compiled and Mathematica not compiled is either > over-simplified or ignorant. Please check: http://en.wikipedia.org/wiki/Compiled_language I quote: "A compiled language is a programming language whose implementations are typically compilers..." Among the list of "compiled languages" you will find Lisp. My point was obvious: since Lisp is a compiled language it is not surprising that programs written in Lips can be compiled. Is it? Neither I not anyone else ever asserted that it would not be possible to write a CAS like Mathematica in which purely symbolic code could be compiled. But that it is not the way Mathematica works and that is all that this list is concerned with. All your comments on this matter are irrelevant and are simply displays of certain aspects of your personality. They provide no other information and the one that they do is already very well known. > > > > $ but then > $ nobody wanting to make sense would use a BlankNullSequence in > $ this situation: it is an artificial examples made up purely > $ to cause puzzlement and an appearance of something like a > $ "bug". In the case > > $ x /. x + c___ :> aha[c] > > $ x > > $ one gets a different outcome because no match is found, but > $ there is nothing at all surprising here since the function > $ Plus with its attributes is not explicitly involved and one > $ would not expect Mathematica to replace all instances of > $ single symbols by Plus[x] in order to make a match. > > Of course Mathematica would not have to use your proposed mechanism > to make this match. Indeed, I doubt that it uses your proposed > mechanism of rewriting as Plus[x,y,Plus[]], either. But one does > not have to replace "all instances of single symbols by Plus[x]. > Only when trying to match against a pattern that looks like Plus[...]. In fact I was wrong on some points of detail concerning the role of the Flat and OneIdenitity attributes although it was you who quite spuriously introduced them into this issue. Observe: ClearAll[f] f[a] /. f[a_, c___] :> aha[c] aha() This is without any f having any attributes. In[3]:= Attributes[f] Out[3]= {} The point is that the very presence of BlankNullSequence in the pattern makes Mathematica re-write f[a] as f[a, ]. If f has the Flat attribute (like Plus) then f[a, ] is equivalent (as a pattern) to f[a,f[]], which is why I wrote Plus[x,y,Plus[]] (as I thought writing Plus[x,y, ] would like like some sort of error). But the Flat attribute plays no role here. In any case, the point is that the basic principle of Mathematica pattern matching is that if you use a certain pattern Mathematica assumes that you wish to find a match. So when you use ___ instead of _ you are inviting matches involving no arguments i.e. f[a, ]. This is true in general and so it is also true for Plus, even though Plus[a,b, ] does not make mathematical sense (a blank space is not 0). This is exactly why I think using this pattern in this context shows lack of understanding of Mathematica. > > Ok, here's why I tried c___, seeing the construction c_. (or > in this example, b_., fail. Desperation? Flailing?) > > Construct a test to see if an expression is a quadratic in a > given variable. > > quadp[a_. x_^2+ b_. x_+c_., x_]:= qq[c,b,a] /; FreeQ[{a,b,c},x] > > for example, > quadp[5+4*x +3*x^2,x] produces qq[5,4,3]. > quadp[ 4*x +3*x^2,x] produces qq[0,4,3]. > quadp[ x + x^2,x] produces qq[0,1,1]. > > quadp[5 +3*x^2,x] no match oops. But the problem is obvious. The default for multiplication is 1 not 0. So, as you noted yourself, you need more patterns. > Now, using 2 rules seems to help: > quadp[a_. x_^2+ b_. x_+c_., x_]:= qq[c,b,a] /; FreeQ[{a,b,c},x] > quadp[a_. x_^2 +c_., x_]:= qq[c,0,a] /; FreeQ[{a,c},x] but this clearly shows a (shocking!) lack of understanding of what is going on! Try quadp[x + 1, x] quadp(x+1,x) You need to account for all coefficients being either 0 or 1. That means 8 rules. E.g.: quadp[a_. x_^2 + b_. x_ + c_., x_] /; FreeQ[{a, b, c}, x] := qq[c, b, a] quadp[a_:0 x_^2 + b_. x_ + c_., x_] /; FreeQ[{a, b, c}, x] := qq[c, b, a] quadp[a_. x_^2 + b_:0 x_ + c_., x_] /; FreeQ[{a, b, c}, x] := qq[c, b, a] .... and so on. quadp[1 + x^2, x] qq(1,0,1) It would certainly be nice if one one could do it all using Alternatives but I don't think it can be done. > > Now this pattern collection also fails, e.g. for r*x^2+s*x^2+1 which most people would think is a quadratic. (I tried various other > tricks like Alternatives, to get everything into one neat rule, > but decided the 2 rules were probably better. I'm open to suggestions > of neater patterns. Well, it fails on the simpler case above. As for this case, if will work if you first use Collect[r*x^2+s*x^2+1,x]. Actually you can incorporate doing Collect automatically into your function. But obviously the right way is to do it without pattern matching which seem to have realised after wasting a lot of time (perhaps yours but certainly mine). Andrzej > > Here is a better program. Something like > > quadp=Function[{ex,var}, Module[{ans=CoefficientList[ex,var]}, > If [Length[ans]==3 && FreeQ[ans,var], Apply[qq,ans], notqq[ex]]]] > > It also works for r*x^2+s*x^2. > RJF > > > > > > $ Andrzej Kozlowski > >