I need to match a products with exactly one factor F, an arbitrary number of factors of head A, and possibly additional inert factors. I'm having trouble writing one pattern that can capture all the following cases.
I tried the following rule (the c term is there for show)
rule1 = Times[ayes___A, F] :> func[Times[ayes], F]; c + F /. rule1 c + A[x] F /. rule1 c + A[x] A[y] F /. rule1 c + d A[x] A[y] F /. rule1 c + F (*desired: c + func[1,F] *) c + func[A[x], F] (*correct*) c + func[A[x] A[y], F] (*correct*) c + d func[A[x] A[y], F] (*correct*)
The first expression failed to properly match, because it doesn't have head Times. Then I tried a second rule with Optional:
rule2 = rule2 = Times[Optional[ayes__A], F] :> func[Times[ayes], F]; (*Input same as above but with /. rule2*) c + func[1,F] (*correct*) c + func[A[x], F] (*correct*) c + func[A[x] A[y], F] (*correct*) c + d A[x] A[y] func[1, F] (*desired: c + d func[A[x] A[y], F] *)
This time the fourth expression failed to match because of the extra factor. So now I try a third rule to accommodate that extra factor:
rule3 = Times[extra_. Optional[ayes__A], F] :> extra*func[Times[ayes], F] (*Input same as above but with /. rule3*) c + func[1,F] (*correct*) c + func[A[x], F] (*correct*) c + A[y] func[A[x], F] (*desired: c + func[A[x] A[y], F]*) c + d A[y] func[A[x], F] (*desired: c + d func[A[x] A[y], F] *)
Now the pattern matcher got confused probably because of all the optional arguments.
Is there a single pattern that can match all these cases? Since I'm working with potentially large expressions, I would also prefer to avoid using pattern tests (Conditional) for performance reasons.
Times[a_. ayes__A, F] | a_. F :> a func[Times[ayes], F]? $\endgroup$c + A[y] func[A[x], F]$\endgroup$Alternativesis the way to go, although I'm not sure if it has the same performance hit as using pattern tests. For instance,rule1 = Times[ayes__A, F] | Times[a_ ayes__A, F] | a_. F :> a func[Times[ayes], F];. $\endgroup$