# Define replacement rules for totally antisymmetric objects

I want to define rules to simplify symbolic totally antisymmetric tensors. For example the rule (in the Minkowski signature) $$\varepsilon^{\mu\nu\rho\lambda} \varepsilon_{\kappa\nu\rho\lambda} = - 6\,\delta^\mu_\kappa\,,$$ and other similar things with 4, 2 or 1 contractions. I could simply define such a replacement rule but then there are a lot of cases involving all permutations of the contracted indices, which will differ only by signs. I would like to avoid having to type down all cases. Even if I define $\varepsilon$ as a totally antisymmetric tensor (such as g in this thread Totally Antisymmetric Function) I'd still have all possibilities involving the position of the uncontracted index among the contracted ones.

My set up is the following: I have a symbolic totally symmetric tensor ε4[m,n,r,l] and a symmetric tensor g[m,n] (the metric) which will appear with symbolic arguments (their indices do not need to assume specific numbers). Then whatever expression I have I want to simplify it by repeatedly expanding and applying rules.

You can use OrderlessPatternSequence to match a sequence of objects, no matter the order, but still retain the information about their order. A way to implement the rule in the post is

ε4[x:OrderlessPatternSequence[μ_,ν_,ρ_,λ_]]ε4[y:OrderlessPatternSequence[κ_,ν_,ρ_,λ_]] :> -6*g[μ,κ]*Signature[PermutationList[FindPermutation[{x},{μ,ν,ρ,λ}]]]*Signature[PermutationList[FindPermutation[{y},{κ,ν,ρ,λ}]]]


In this rule x and y contain the Sequence of indices as they appear, while OrderlessPatternSequence tells Mathematica to match that rule no matter the ordering. Then Signature[PermutationList[FindPermutation[{x},{μ,ν,ρ,λ}]]] is $-1$ or $1$ according to whether the permutation taking me from x to μ,ν,ρ,λ is even or odd. Other rules can be defined similarly, e.g.

ε4[x:OrderlessPatternSequence[μ_,ν_,ρ_,λ_]]ε4[μ_,ν_,ρ_,λ_] :> -24*Signature[PermutationList[FindPermutation[{x},{μ,ν,ρ,λ}]]]


When less indices are contracted the identities might be trickier to write just because the expressions are more invovlved, but the overall principle is the same.

Then what I would do is to define a List r with all these rules and apply them to any expression expr with

ReplaceExpand[expr_,rule_]:=FixedPoint[Expand[#]/.rule&,expr];
ReplaceExpand[rule_]:=ReplaceExpand[#,rule]&;

expr//ReplaceExpand[r]


Here's how I did it in earlier versions of Package-X, if I translate it to your notation:

rules =
{ε4[idx1:PatternSequence[_, _, _, _]]* ε4[idx2:PatternSequence[_, _, _, _]]:>
Det[Outer[g, {idx1}, {idx2}, 1, 1]],
ε4[idx1:PatternSequence[_, _, _, _]]^2 :> Det[Outer[g, {idx1}, {idx1}, 1, 1]],
g[a_, a_] :> 4,
g[a_, b_] g[b_, c_] :> g[a, c],
g[a_, b_]^2 :> 4
};


And then, so that the metric tensors sort their arguments, I also do:

SetAttributes[g, Orderless];


Now you can try something like

ε4[a, b, c, d] ε4[a, x, c, e] //. rules

(* 2 g[b, x] g[d, e] - 2 g[b, e] g[d, x] *)