# Groupings over non-atomic elements

I use groupings as below:

Join[
Groupings[IntegerPartitions, {A -> {2, Orderless}, B -> {2, Orderless}}],
{x}]


Which generates:

{A[2, 1], B[2, 1], A[A[1, 1], 1], A[B[1, 1], 1], B[A[1, 1], 1], B[B[1, 1], 1], 3}


How can A be restricted so A is not applied to arguments that are both atomic? That is. I want the output to be:

{B[2, 1], A[B[1, 1], 1], B[B[1, 1], 1], 3}


Of course, I can remove the results in which A is applied to two atoms (i.e. two positive integers) after generating the list:

{A[2, 1], B[2, 1], A[A[1, 1], 1], A[B[1, 1], 1], B[A[1, 1], 1], B[B[1, 1], 1], 3}


Is it possible to do prevent generating the cases where A applies to two atoms (integers in this case) by adapting the given code:

Join[
Groupings[IntegerPartitions, {A -> {2, Orderless}, B -> {2, Orderless}}],
{x}]


For example, by adding a condition

/, ! AtomQ[x] && !AtomQ[y]


for an application A[x,y]?

• What should happen to B[A[1,1],1]?
– chuy
Jun 19 '19 at 21:35
• It should not be added (it is not included in the intended result displayed). It contains A[1,1] which is not allowed since A is applied to two atoms.
– Mike
Jun 19 '19 at 21:37

Here's a variation of kglr's answer that doesn't modify A or B. First define a helper function h:

h[A[___?AtomQ] | A[_]] := Sequence[]
h[B[_] | B[]] := Sequence[]
h[a_] := a


Then use the helper function in your Groupings call:

Groupings[IntegerPartitions, {h @* A -> {2, Orderless}, h @* B -> {2, Orderless}}]


{B[2, 1], A[B[1, 1], 1], B[B[1, 1], 1]}

• Thanks Carl. This is what I got now and it seems to work fine: Block[{a, b}, a = A; b = B; h[a[_?AtomQ]] := Sequence[]; h[b[]] := Sequence[]; h[c_] := c; Groupings[ IntegerPartitions, {h@*A -> {2, Orderless}, h@*B -> {2, Orderless}}]] Result: {B[2, 1], A[B[1, 1], 1], B[B[1, 1], 1]}
– Mike
Jun 19 '19 at 22:36
• Unfortunately this still does not work on size 4: Groupings[IntegerPartitions, {h @* A -> {2, Orderless}, h @* B -> {2, Orderless}}] Produces: {B[3, 1], B[2, 2], A[B[2, 1], 1], B[B[2, 1], 1], A[], A[A[B[1, 1], 1], 1], A[B[1, 1]], A[B[1, 1]], B[], A[B[B[1, 1], 1], 1], A[B[1, 1], B[1, 1]], B[A[B[1, 1], 1], 1], B[B[B[1, 1], 1], 1], B[B[1, 1], B[1, 1]]} This contains A[] and also A[B[1, 1]], the latter of which should not be included as A is a binary operation
– Mike
Jun 19 '19 at 22:45
• @Mike See update Jun 19 '19 at 22:53
• Thanks Carl! Much appreciated. I need to read up on the operations you used...
– Mike
Jun 19 '19 at 23:12
ClearAll[a, b]
a = A;
b = B;
a[___?AtomQ] := Sequence[]
b[_] := Sequence[]

Groupings[IntegerPartitions, {a -> {2, Orderless}, b -> {2, Orderless}}]


{B[2, 1], A[B[1, 1], 1], B[B[1, 1], 1]}

• I can't use ClearAll, as A and B have other values attached. But removing ClearAll does not cause an issue. There is another problem though: Is it possible to protect (i.e. restrict use locally) the commands: A[?AtomQ,__?AtomQ]:=Sequence[] B[_]:=Sequence[] similar to local variables? I do not wish these commands to affect A and B outside the context I am using the above commands in.
– Mike
Jun 19 '19 at 22:02
• @Mike, does Block[{a,b}, a=A;b=B;a[_?AtomQ,__?AtomQ]:= ...] work?
– kglr
Jun 19 '19 at 22:09
• Almost, the code: Block[{a, b}, a = A; b = B; a[?AtomQ, __?AtomQ] := Sequence[]; B[] := Sequence[]; Groupings[ IntegerPartitions, {A -> {2, Orderless}, B -> {2, Orderless}}]] produces: {B[2, 1], A, A[B[1, 1], 1], B[B[1, 1], 1]} which includes A. It should not as A is an operation on two arguments.
– Mike
Jun 19 '19 at 22:24
• Thanks kgl, went with Carl's solution in the end, but this got it going
– Mike
Jun 19 '19 at 23:12