I am considering a function termsContain[func_,list_] which select in an expression func the terms containing the ones in the list. The func in general is a sum of some terms and could also be only one term, for example,

in[1]:= termsContain[a + b + c + a x +b y, {x,y}]
out[1]= a x+b y

in[2]:= termsContain[a + b + c + f[a x +c]+b y, {a x}]
out[2]=f[c + a x]

in[3]:= termsContain[a x , {a x}]
out[3]= a x

in[4]:=  termsContain[a + b + c + a x[i] y[j] +b x[l] y[m] , {x[_]y[_]}]
out[4]= a x[i] y[j]+b x[l] y[m]

I came up with this :

termsContain[func_, list_] :=  func /. (Longest[u___?(Not[FreeQ[#, Alternatives @@ list]] &)] + v___) :> (Plus[u]);

This works fine for the first three examples, but not for the last one. For the last one, this gives only zero


Try another example which is also not as expected:

in[5]:=termsContain[a + b + c + a x[i] y[j] +b x[l] y[m] +c f[x[l] y[m]], {x[_]y[_]}]
out[5]= c f[x[l] y[m]]

I thought it should give a x[i] y[j] +b x[l] y[m] +c f[x[l] y[m]]. How to understand these results? I did some experiments, the problem seems to be the FreeQ combined with Alternatives. The Alternatives seems not to take one argument, that is, Alternatives[x[_] y[_]] does not match x[_] y[_] as I thought. See these examples,

in[6]:=FreeQ[a x[i] y[j] +b x[l] y[m], x[_] y[_]]
out[6]= False
in[7]:=FreeQ[a x[i] y[j] +b x[l] y[m], Alternatives[x[_] y[_]]]
out[7]= True

But the out[2] and the out[3] seem to give the correct answer. Why? I am really confused. And how to modify the code to give the expected answer? Thanks!

Appendix: We can test this, for a special case without using Alternatives

   in[8]:= c a[i] x[j] + d f[a[l] x[m]] + f + l +   d a[l] x[n] /. (Longest[u___?(Not[FreeQ[#, a[i_] x[j_]]] &)] + v___) :> (Plus[u])
   out[8]= d f[a[l] x[m]] + c a[i] x[j] + d a[l] x[n]

It works here. So the problem really is in Alternatives. FreeQ combined with Alternatives is really confusing, look at these

in[9]:= FreeQ[a x y, a x ]
out[9]= False
in[10]:= FreeQ[a x y, a x | y ]
out[10]= False
in[11]:= FreeQ[a x y, a x | a y ]
out[11]= True

Modify the in[2] a little

in[12]:= termsContain[a + b + c + f[a x y + c] + b x y, { x }]
out[12]= b x y + f[c + a x y]
in[13]:= termsContain[a + b + c + f[a x y + c] + b x y, { a x }]
in[14]:= termsContain[a + b + c + f[a x y + c] + b x y, { b y }]


At last, I come to this realization,

termsContain[func_, list_] := func /. (Longest[
   u___?(Not[And @@ (Through[(FreeQ[#] & /@ list)[#]])] &)] + 
  v___) :> (Plus[u]);

which is what I want. But I still would like to know how to understand the Alternatives in FreeQ.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.