# Applying functions repeatedly on parts of complicated expressions

I am dealing with expressions like

$$\textrm{expr}=5D_{4,1}\langle12\rangle\langle23\rangle\big(-\langle15\rangle^2\langle24\rangle\langle34\rangle + \langle14\rangle\langle15\rangle\langle24\rangle\langle35\rangle - \langle14\rangle\langle15\rangle\langle23\rangle\langle45\rangle - \langle12\rangle\langle15\rangle\langle34\rangle\langle45\rangle \big) + \\ 5D_{4,2}\langle12\rangle\langle23\rangle\big(-\langle15\rangle\langle24\rangle\langle25\rangle\langle34\rangle + \langle14\rangle\langle25\rangle\langle24\rangle\langle35\rangle - \langle12\rangle\langle24\rangle\langle35\rangle\langle45\rangle - \langle12\rangle\langle23\rangle\langle45\rangle^2 \big) + 5\langle12\rangle\langle23\rangle\big[D_{4,3} \big(\textrm{similar stuff}\big)+D_{4,4} \big(\textrm{similar stuff}\big)+D_{4,5} \big(\textrm{similar stuff}\big)\big]$$

Here, $D_{ij}$ are simply matrix elements, whereas the brackets $\langle ab\rangle$ are special objects that basically obey antisymmetry and a special identity, which I implemented, calling it schId (it boils down to a substitution rule for expressions of the form $\langle ij \rangle\langle kl \rangle - \langle ik \rangle\langle jl \rangle$ or obvious variations).

Now, if I try something like expr//Simplify//schId, nothing happens. Basically, Simplify tends to destroy the nice "factorization" of the matrix elements $D_{ij}$, which I had obtained with Collect[#,D[i_,j_]]& and then schId doesn't see any of the combinations of brackets that it knows how to replace.
Nevertheless, I can obtain the desired simplifications if I copy-paste each of the parentheses multiplied by $D_{4,k}\langle12\rangle\langle23\rangle$ and act on them with //Simplify//schId (two or three (potentially even more) consecutive times). I've seen that those parenthesis can be obtained as parts of expr, namely expr[[i,5]] for $i=1,\dots,5$.

• How can I ask Mathematica to try to apply a sequence of functions on all the subparts of a complicated expression?
• Moreover, how can I ask it to do it as many times as it is necessary, in order for the result not to change anymore?

I hope the question is not very trivial: I have searched on the forum as well as on the Help (for functions like Map or Apply), but I couldn't find any working strategy for my problem.

Code update:
I am working with a package which defines my brackets.
A reasonable definition for them can be given as follows:

 sb[h__] := Signature[{h}] 〈Sort[{h}] /. List -> Sequence〉


In the package, arguments of the brackets are automatically sorted at each step in the computation. I don't know how to do that, so I just wrote a sorting function:

sortarg = # //. {〈l__〉 :> Signature[{l}] 〈Sort[{l}] /. List -> Sequence〉} &;


Here's the function that implements the identity among the brackets:

schId = # //. {〈a_,b_〉 〈c_,d_〉 - 〈a_,c_〉 〈b_,d_〉 :> 〈a,d〉 〈c,b〉, 〈a_,b_〉 〈c_,d_〉 + 〈a_,c_〉 〈d_,b_〉 :> 〈a,d〉 〈c,b〉, -〈a_,b_〉 〈c_,d_〉 - 〈a_,c_〉 〈d_,b_〉 :> -〈a,d〉 〈c,b〉, 〈a_,b_〉 〈c_,d_〉 - 〈a_,d_〉 〈c_,b_〉 :> 〈a,c〉 〈b,d〉, 〈a_,b_〉 〈c_,d_〉 + 〈a_,d_〉 〈b_,c_〉 :> 〈a,c〉 〈b,d〉, -〈a_,b_〉 〈c_,d_〉 - 〈a_,d_〉 〈b_,c_〉 :> -〈a,c〉 〈b,d〉} &;


(there must be a more elegant way to list all those substitution rules, but I cannot get even PlusMinus to work)

Easy example: sb[2, 1] sb[3, 4] - sb[1, 4] sb[2, 3] // schId
Real example (first summand of expr):

expr1 = 5 matD[4, 1] 〈1,2〉 〈2,3〉 (-〈1,5〉^2 〈2,4〉 〈3,4〉 + 〈1,4〉 〈1,5〉 〈2,4〉 〈3,5〉 - 〈1,4〉 〈1,5〉 〈2,3〉 〈4,5〉 - 〈1,2〉 〈1,5〉 〈3,4〉 〈4,5〉)


This gives zero when writing
expr1 // Simplify // schId // sortarg // Simplify // schId // sortarg

So my questions would be:

• How to ask Mathematica to act repeatedly on an expr1 with Simplify, schId, sortarg?
• How to make it possible to use those functions directly on expr and not on its subparts?
• Please provide your code, or a simplified version of it, including the definitions of your brackets. Otherwise, it is very difficult for the reader to provide useful advice. Mar 24, 2015 at 18:13

As a place to start I suggest TransformationFunctions:

FullSimplify[expr1, TransformationFunctions -> {Automatic, schId, sortarg}]


0

This works even if both sortarg and schId are defined with /. rather than //..

For more manual application consider MapAt. Also familiarize yourself with levelspec.

• Thank you, Mr.Wizard, this is very helpful! I'll wait just a bit more to accept the answer, in case somebody wants to share some further ideas. Mar 26, 2015 at 15:06
• @AndreaOrta I am glad it is helpful. Please do not feel pressure to Accept this. It is far from a complete and orderly answer. I found the question a bit confusing in a quick read and I didn't want to take time to re-read it carefully. Therefore I recommended one fairly general solution rather than providing a detailed answer. I hope to return to this though honestly I'll probably find some other problem to distract me. (continued) Mar 26, 2015 at 20:34
• @AndreaOrta One thing for now: understand the evaluation order difference between Replace or MapAll and ReplaceAll/ReplaceRepeated. Some references: (9233), (20181), (56062). Mar 26, 2015 at 20:37