# Select certain term containing some patterns and confusing pattern Alternatives in FreeQ

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

out[4]=0


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 }]
out[13]=0
in[14]:= termsContain[a + b + c + f[a x y + c] + b x y, { b y }]
out[14]=0


Edit:

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.