SpaceSpinors

Handling of space spinor expressions

Thomas Bäckdahl     thomas.backdahl@chalmers.se
Mathematical Sciences
Chalmers University of Technology and University of Gothenburg 
Gothenburg, Sweden

(c) 2015-2025, under GPL

http://www.xAct.es/
http://groups.google.com/group/xAct

SpaceSpinors is a package for handling space spinor expressions.

SpaceSpinors is distributed under the GNU General Public License, and runs on top of xTensor, a free package for fast manipulation of abstract tensor expressions.

DateList[]

xAct`SpaceSpinors`$Version={"0.1.3",{2025,06,23}}

1. Initialization

1.0. TODO list

1.1. GPL

(* SpaceSpinors: Handling of space spinor expressions *)

(* Copyright (C) 2015-2025 Thomas Bäckdahl *)

(* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License,or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place-Suite 330, Boston, MA 02111-1307, USA. 
*)

1.2. Info package

(* :Title: SpaceSpinors *)

(* :Author: Thomas Bäckdahl *)

(* :Summary: Handling of space spinor expressions *)

(* :Brief Discussion:
   - Handles space spinor expressions. *)
  
(* :Context: xAct`SpaceSpinors` *)

(* :Package Version: 0.1.3 *)

(* :Copyright: Thomas Bäckdahl (2015-2025) *)

(* :History: See SpaceSpinors.History *)

(* :Keywords: *)

(* :Source: SpaceSpinors.nb *)

(* :Warning: *)

(* :Mathematica Version: 8.0 and later *)

(* :Limitations:
	- Only abstract indices can be used. *)
	
(* :Acknowledgements:
	The autor would like to thank A. García-Parrado
	and Steffen Aksteiner for helpful comments. *)

1.3. BeginPackage

If[Unevaluated[xAct`xCore`Private`$LastPackage]===xAct`xCore`Private`$LastPackage,xAct`xCore`Private`$LastPackage="xAct`SpaceSpinors`"];

Explicit (not hidden) import of TexAct, SymManipulator, Spinors, xTensor, xPerm and xCore:

BeginPackage["xAct`SpaceSpinors`",{"xAct`SymSpin`","xAct`TexAct`","xAct`SymManipulator`","xAct`Spinors`","xAct`xTensor`","xAct`xPerm`","xAct`xCore`"}]

Print[xAct`xCore`Private`bars]
Print["Package xAct`SpaceSpinors`  version ",$Version[[1]],", ",$Version[[2]]];
Print["CopyRight (C) 2013-2015, Thomas Bäckdahl, under the General Public License."];

We specify the context xAct`Spinors` to avoid overriding the Disclaimer of the other packages. However we need to turn off the message General:shdw temporarily:

Off[General::shdw]
xAct`SymManipulator`Disclaimer[]:=Print["These are points 11 and 12 of the General Public License:\n\nBECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM `AS IS´ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\nIN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES."]
On[General::shdw]

If SpaceSpinors is not being called from other package then write this GPL short disclaimer:

If[xAct`xCore`Private`$LastPackage==="xAct`SpaceSpinors`",
Unset[xAct`xCore`Private`$LastPackage];
Print[xAct`xCore`Private`bars];
Print["These packages come with ABSOLUTELY NO WARRANTY; for details type Disclaimer[]. This is free software, and you are welcome to redistribute it under certain conditions. See the General Public License for details."];
Print[xAct`xCore`Private`bars]]

Note that symbols in the Global` context cannot be accessed right now.

$ContextPath

$Context

Established connection to external executable?

$xpermQ

1.4. Non-standard setup

Screen all dollar indices:

$PrePrint = ScreenDollarIndices;

Timings will be shown if they are above 0.1 Second (Only for this notebook; this is not included in the package):

<<xAct/ShowTime1.m

$ShowTimeThreshold=0.1

We also read the package (this is not automatic in xCore anymore since its version 0.6.2):

<<xAct/ExpressionManipulation.m

1.5. Usage messages

DefSpaceSpinStructure::usage ="DefSpaceSpinStructure[Sigma, Metrich, Ns, SpatialSigma, Dd, Nb] defines a space spinor structure based on the spacetime spin soldering form Sigma and the intrinsic metric Metrich. The function defines the spinor version of the normal Ns, the spatial soldering form SpatialSigma, the Sen connection Dd, and the intrinsic connection Nb.";
SenToSpinCovDRules::usage="SenToSpinCovDRules is a collection of rules that transfoms indexed Sen derivatives to spacetime spinor derivatives.";
SpinCovDToSenRules::usage="SpinCovDToSenRules is a collection of rules that transfoms indexed spacetime spinor derivatives to Sen derivatives.";
DirToSpinCovDRules::usage="DirToSpinCovDRules is a collection of rules that transfoms indexed normal derivatives to indexed spacetime spinor derivatives.";
SpatialSFToSF::usage="SpatialSFToSF[Nn] is an equation expressing the spatial soldering form in terms of the spacetime soldering form. Nn is the normal tensor.";
SFToSpatialSF::usage="SpatialSFToSF[Nn] is an equation expressing the spatial soldering form in terms of the spacetime soldering form. Nn is the normal tensor.";
SlotsOfCovD::usage="Default index configuration in the derivative indices.";
DefSpatialBox::usage="DefSpatialBox[covd] defines a commutator box for the spatial derivative covd.";
SpatialBoxToCovD::usage="SpatialBoxToCovD[expr, boxcd] converts the spatial box boxcd in expr to the corresponding contracted and symmetrized derivative.";
DefFundSpatialSpinOperators::usage="DefFundSpatialSpinOperators[covd] defines fundamental spinor operators for the intrinsic or Sen differential operator covd.";
UndefFundSpatialSpinOperators::usage="UndefFundSpatialSpinOperators[covd]";
$ExtrinsicKScalingConv::usage="";
$AccelerationScalingConv::usage="";
NormalOfCovD::usage="";
SpinorOfNormal::usage="";
FundSpinOpNormalRules::usage="FundSpinOpNormalRules[Ns] converts the fundamental spinor operators acting on the normal spinor Ns to acceleration and irreducible components of the extrinsic curvature.";

1.6. Begin private

Begin["`Private`"]

"xAct`SpaceSpinors`Private`"

The reserved words in version 0.1.0 :

Names["xAct`SpaceSpinors`*"]

%//Length

$ContextPath

{"xAct`ExpressionManipulation`","Utilities`ShowTime`","xAct`SpaceSpinors`","xAct`TexAct`","xAct`SymManipulator`","xAct`Spinors`","xAct`xTensor`","xAct`xPerm`","xAct`xCore`","System`"}

$Context

"xAct`SpaceSpinors`Private`"

2. Development of some tools

2.1. Development of some tools

A simpler version of MakeRule

FormatDirRule[Dir[v_[index_]]]:=Dir[v[index]]-> Dir[v[xAct`xTensor`Private`pattern[index,_]]];

MakeSimpleRule[{LHS_,RHS_,conditions___},options___]:=With[{HeldLHS=Hold[LHS],HeldRHS=Hold[RHS]},
Module[{
(* Unblocked indices *)
indsLHS=List@@xAct`xTensor`Private`TakeEIndices[FindIndices[HeldLHS]],
freesLHS=List@@xAct`xTensor`Private`TakeEIndices[FindFreeIndices[HeldLHS]],
dirinds=List@@Select[FindIndices[HeldLHS],DIndexQ],
verb,
indsLHSinfo,
rulesLHS,
(*newHeldLHS=xAct`xTensor`Private`ReplaceIsolated[HeldLHS],
newHeldRHS=ReplaceDummies[HeldRHS],*)
rules,conds},

(* Options *)
{verb}={Verbose}/.CheckOptions[options]/.Options[MakeRule];

(**** B. Construct indsLHSinfo ****)
(* 0. Convert LHS inds to names *)
indsLHS=xAct`xTensor`Private`IndexName/@indsLHS;
freesLHS=xAct`xTensor`Private`IndexName/@freesLHS;

(* 1. Name of index in input rule *)
indsLHSinfo=Partition[indsLHS,1];

(* 2. Free character *)
indsLHSinfo=Append[#,MemberQ[freesLHS,First@#]]&/@indsLHSinfo;

(* 3. MetricOn. up/down character is corrected *)
indsLHSinfo=Append[#,MetricEndowedQ@VBundleOfIndex@First@#]&/@indsLHSinfo;

(* 4. TestIndices *)
indsLHSinfo=Append[#,True]&/@indsLHSinfo;

(* 5. Pattern character in final rule. up/down character in patindsLHS is corrected *)
indsLHSinfo=Append[#,True]&/@indsLHSinfo;

(* 6. Name in final rule. Currently we do not change names *)
indsLHSinfo=Append[#,First@#]&/@indsLHSinfo;
If[verb,Print["indsLHSinfo: ",indsLHSinfo]];
If[verb,Print["dirinds:", dirinds]];
(* 7. Final rules for LHS indices *)
rulesLHS=Join[(xAct`xTensor`Private`FormatIndexRule/@indsLHSinfo),FormatDirRule/@dirinds]/.{xAct`xTensor`Private`patternTest->PatternTest,xAct`xTensor`Private`pattern->Pattern};
If[verb,Print["rulesLHS: ",rulesLHS]];

(**** C. Construct rules ****)

(* 3. Construct rules *)
rules={Rule[HeldLHS,HeldRHS]};
If[verb,Print["rules: ",InputForm[rules]]];

(* 4. Replace indices *)
rules=rules/.Rule[lhs_Hold,rhs_Hold]:>Rule[ReplaceIndex[lhs,rulesLHS],rhs];
If[verb,Print["rules after pattern: ",rules]];

(* 5. Add Module on the RHS *)
rules=rules/.Rule->IndexRule;

(* 6. Add conditions *)
conds=Hold[conditions];
If[verb,Print["Conditions: ",conds]];
rules=(xAct`xTensor`Private`addconditions[#,conds]&/@rules)/.Hold[cond_]->cond;

(* 7. Return rules *)
ScreenDollarIndices@rules
]
]

3. Definition of space spinor structure

3.1. Definition

SenToSpinCovDRules={};
SpinCovDToSenRules={};
DirToSpinCovDRules={};
SpaceSpinors`Private`CommuteSpinCovD={};
$ExtrinsicKScalingConv=1;
$AccelerationScalingConv=1;

SenCovDQ[_]:=False;

SpaceSpinorsDefaultNames[Nn_]:={SymbolJoin["Acc",Nn],SymbolJoin["ExtrK",Nn],SymbolJoin["Ω4",Nn],SymbolJoin["Ω0",Nn],SymbolJoin["Dir",Nn,"Op"],SymbolJoin["Hat",Nn,"Op"],SymbolJoin["SpatialPhi4",Nn],SymbolJoin["SpatialPhi2",Nn],SymbolJoin["SpatialPhi0",Nn],SymbolJoin["R4",Nn],SymbolJoin["R0",Nn]}

SpaceSpinorsDefaultSymbols[Nn_]:={"A","K","Ω",RowBox[{OverlayBox[{"Ω","/"}]}],RowBox[{UnderscriptBox["R","_"]}],RowBox[{UnderscriptBox[OverlayBox[{"R","/"}],"_"]}]}

DefSpaceSpinStructure[sigma_,metrich_,t_,spatialsigma_, Dd_,nb_]:=
With[{tbundle=TangentBundleOfSolderingForm[sigma],
sbundle=VBundleOfSolderingForm[sigma],
metric=First@InducedFrom@metrich,
Nn=Last@InducedFrom@metrich,
eps=SpinMetricOfSolderingForm[sigma]},
With[{Mfd=ManifoldOfCovD@CovDOfMetric@metric,
Accname=SpaceSpinorsDefaultNames[Nn][[1]],
ExtrKname=SpaceSpinorsDefaultNames[Nn][[2]],
DirNnOpname=SpaceSpinorsDefaultNames[Nn][[5]],
HatNnOpname=SpaceSpinorsDefaultNames[Nn][[6]],
SpatialPhi4name=SpaceSpinorsDefaultNames[Nn][[7]],
SpatialPhi2name=SpaceSpinorsDefaultNames[Nn][[8]],
SpatialPhi0name=SpaceSpinorsDefaultNames[Nn][[9]],
hatboxname=SymbolJoin["HatBox",Evaluate@CovDOfMetric@eps,Nn],
a=First@First@IndicesOfVBundle@tbundle,b=First@Rest@First@IndicesOfVBundle@tbundle,
A=(First@IndicesOfVBundle@sbundle)[[1]],
B=(First@IndicesOfVBundle@sbundle)[[2]],
C=(First@IndicesOfVBundle@sbundle)[[3]],
D=(First@IndicesOfVBundle@sbundle)[[4]],
Adg=First@First@IndicesOfVBundle@Dagger@sbundle,
Bdg=First@Rest@First@IndicesOfVBundle@Dagger@sbundle,
CD=CovDOfMetric@eps},
With[{normsqr=Scalar[Nn[a]Nn[-a]]},
(* Defining the tensor version of the normal and it's contractions. *)
DefSpinorOfTensor[t[A,Adg],Nn[a],sigma,PrintAs->PrintAs[Nn]];
SpinorOfNormal[Nn]^=t;
AutomaticRules[t,MakeRule[{t[A,Adg]t[-A,-Adg],normsqr},MetricOn->All, ContractMetrics->True]];
AutomaticRules[t,MakeRule[{t[-A, Adg]*t[-B, -Adg], -(normsqr*eps[-A, -B])/2},MetricOn->All, ContractMetrics->True]];
AutomaticRules[t,MakeRule[{t[-A,-Bdg]*t[A,-Adg],-(normsqr*Dagger[eps][-Adg,-Bdg])/2},MetricOn->All, ContractMetrics->True]];
(* Definition of the index-free hat operator *)
xTensorQ[HatNnOpname[AA_?xTensorQ]]^=True;
SlotsOfTensor[HatNnOpname[AA_?xTensorQ]]^:=SlotsOfTensor[AA];
SymmetryGroupOfTensor[HatNnOpname[AA_?xTensorQ]]^:=SymmetryGroupOfTensor[AA];
PrintAs[HatNnOpname[AA_?xTensorQ]]^:=OverscriptBox[PrintAs[AA],"^"];
Tex[HatNnOpname[AA_?xTensorQ]]^:="\\widehat{"<>Tex[AA]<>"}";
PrintAs[HatNnOpname[AA_?xTensorQ]]^:=With[{s=First[Rasterize[AA,"RasterSize"]]/2,tt=0.6*First[Rasterize["^","RasterSize"]]},With[{sl=N[2 Log[2 s]]},OverscriptBox[PrintAs[AA],If[s<=tt,"^",TagBox[GraphicsBox[LineBox[{{-s,0},{0,sl},{s,0}}],ImageSize->{s,Automatic}],"LongOverHat",Selectable->False]]]]];
HatNnOpOfNormal[Nn]^=HatNnOpname;
HatNnOpname[expr_TensorPlus,z___]:=HatNnOpname[#,z]&/@expr;
HatNnOpname[ZeroTensor[vbs_],z___]:=ZeroTensorOfTensor@HatNnOpname[DummyTensor[vbs,CompatibleSymmetric[vbs]],z];
HatNnOpname[MultScal[c_,TT_?xTensorQ],z___]:=MultScal[Dagger[c],HatNnOpname[TT,z]];
Evaluate[SymbolJoin[HatNnOpname,"Rule"]]=HatNnOpname[ϕ_?(SymmetricSpinorOfArbitraryValenceQ[sbundle])]:>With[{k=NumOfUnprimedSlots[sbundle][ϕ]},MultScal[Power[2/normsqr ,k/2],Nest[SymMult[t,0,1,sbundle],Dagger[ϕ],k]]]/;(NumOfPrimedSlots[sbundle]@ϕ===0);
Evaluate[SymbolJoin[HatNnOpname,"Valence0Rule"]]=HatNnOpname[ϕ_?(SymmetricSpinorOfArbitraryValenceQ[sbundle])]:>Dagger[ϕ]/;And[NumOfUnprimedSlots[sbundle]@ϕ===0,NumOfPrimedSlots[sbundle]@ϕ===0];
Evaluate[SymbolJoin[HatNnOpname,HatNnOpname,"Rule"]]=HatNnOpname[HatNnOpname[ϕ_?(SymmetricSpinorOfArbitraryValenceQ[sbundle])]]:>With[{k=NumOfUnprimedSlots[sbundle][ϕ]},MultScal[(-1)^k,ϕ]]/;(NumOfPrimedSlots[sbundle]@ϕ===0);
HatNnOpname[SymMult[T1_,i_,0,sbundle][T2_]]^:=SymMult[HatNnOpname[T1],i,0,sbundle][HatNnOpname[T2]]/;And[(NumOfPrimedSlots[sbundle][T1]===0),(NumOfPrimedSlots[sbundle][T2]===0)];
(* Defining the spatial soldering form *)
DefSpinor[spatialsigma[-a,A,B],Mfd,Symmetric[{A,B}],OrthogonalTo-> {Nn[a]}, ProjectedWith->{metrich[a,-b]},PrintAs->PrintAs[sigma]];
SpatialSFToSF[Nn]^=spatialsigma[-a,A,B]==Symmetrize[sigma[-a,A,-Adg]t[B,Adg]/Sqrt[normsqr/2],{A,B}];
SFToSpatialSF[Nn]^=sigma[-a,A,Adg]==(Nn[-a]*t[A,Adg])/normsqr-spatialsigma[-a,A,-B]*t[B,Adg]*Sqrt[2]/Sqrt@normsqr;
(* HatBox *)
CovDQ[hatboxname]^=True;
xAct`xTensor`Private`MakeLinearDerivative[{hatboxname[A__],hatboxname[A]},True];
SymmetryGroupOfCovD[hatboxname]^=StrongGenSet[{1, 2},GenSet[Cycles@{1,2}]];
ManifoldOfCovD[hatboxname]^=ManifoldOfCovD[CD];
VBundlesOfCovD[hatboxname]^=VBundlesOfCovD[CD];
SymbolOfCovD[hatboxname]^={"?","(OverHat[□])"};
Evaluate[SymbolJoin[hatboxname,"ToBox",Evaluate@CovDOfMetric@eps]]=MakeSimpleRule[{hatboxname[A,B]@L_,2/Scalar[Nn[a]Nn[-a]]*t[A,Adg]t[B,Bdg]SymbolJoin["Box",Evaluate@CovDOfMetric@eps][-Adg,-Bdg]@L}];
(* Definition of Acceleration and Extrinsic curvature *)
DefSpinor[Accname[-A,-B],Mfd,Symmetric[{1,2}],PrintAs->SpaceSpinorsDefaultSymbols[Nn][[1]]];
AccNameOfNormal[Nn]^=Accname;
HatNnOpname[Accname]^=MultScal[-1,Accname];
Evaluate[SymbolJoin[Accname,"Def"]]=Accname[-A,-B]==Acceleration[Nn][a]*$AccelerationScalingConv*spatialsigma[-a,-A,-B];
Evaluate[SymbolJoin[Accname,"To", CD,t]]=Accname[-A,-B]==Sqrt[2]*$AccelerationScalingConv/(normsqr)^(3/2)*Symmetrize[t[-A,Adg]*CD[Dir[Nn[a]]][t[-B,-Adg]],IndexList[-A,-B]];
(* We assume that the normal is hypersurface orthogonal. *)
DefSpinor[ExtrKname[-A,-B,-C,-D],Mfd,StrongGenSet[{1,2,3,4},GenSet[Cycles[{1,2}],Cycles[{3,4}],Cycles[{1,3},{2,4}]]],PrintAs->SpaceSpinorsDefaultSymbols[Nn][[2]]];
ExtrKNameOfNormal[Nn]^=ExtrKname;
Evaluate[SymbolJoin[ExtrKname,"Def"]]=ExtrKname[-A,-B,-C,-D]==ExtrinsicK[metrich][-a,-b]spatialsigma[a,-A,-B]spatialsigma[b,-C,-D]*$ExtrinsicKScalingConv;
Evaluate[SymbolJoin[CD,t,"Eq"]]=CD[-A,-Adg][t[-B,-Bdg]]==-((Sqrt[2]*$AccelerationSign/$AccelerationScalingConv*Accname[-B,-C]*t[-A,-Adg]*t[C,-Bdg])/Sqrt[normsqr])+(2*$ExtrinsicKSign/$ExtrinsicKScalingConv*ExtrKname[-A,-C,-B,-D]*t[C,-Adg]*t[D,-Bdg])/(normsqr);
(* Defining the Sen connection *)
DefSenConnection[Dd,eps,CovDOfMetric@eps,t,Nn,sigma,{A,B,C,D,Adg,Bdg,a}];
(* Normal derivative in operator form *)
DirOpNameOfNormal[Nn]^=DirNnOpname;
xTensorQ[DirNnOpname[AA_?xTensorQ]]^=True;
SlotsOfTensor[DirNnOpname[AA_?xTensorQ]]^:=SlotsOfTensor[AA];
SymmetryGroupOfTensor[DirNnOpname[AA_?xTensorQ]]^:=SymmetryGroupOfTensor[AA];
PrintAs[DirNnOpname[AA_?xTensorQ]]^:=RowBox[{SubscriptBox[SymbolOfCovD[CD][[2]],PrintAs[Nn]],PrintAs[AA]}];
Tex[DirNnOpname[AA_?xTensorQ]]^:=xAct`TexAct`Private`TexCovD[CD][[2]]<>"_{"<>Tex[Nn]<>"}"<>Tex[AA];
Dagger[DirNnOpname[AA_?xTensorQ]]^:=DirNnOpname[Dagger@AA];
SetLinearOperatorRules[DirNnOpname];
(* Spatial parts of the tracefree Ricci *)
DefSymmetricSpinor[SpatialPhi4name,4,0,sbundle,"(Underscript[Φ, 4])"]; 
DefSymmetricSpinor[SpatialPhi2name,2,0,sbundle,"(Underscript[Φ, 2])"]; 
DefSymmetricSpinor[SpatialPhi0name,0,0,sbundle,"(Underscript[Φ, 0])"];
SpatialPhinamesOfNormal[Nn]^={SpatialPhi4name,SpatialPhi2name,SpatialPhi0name};
(* One commutator that does not need fundamental spinor operators. *)
CommuteOp[HatNnOpname,DirNnOpname]^={HatNnOpname[DirNnOpname[ϕ_]]:>With[{k=NumOfUnprimedSlots[sbundle]@ϕ},TensorPlus[DirNnOpname[HatNnOpname[ϕ]],MultScal[-Sqrt[2]*Sqrt[normsqr]*k,SymMult[Accname,1,0,sbundle][HatNnOpname[ϕ]]]]]/;(NumOfPrimedSlots[sbundle][ϕ]===0)};
SymMultLeibnizRules[DirNnOpname]^={DirNnOpname[SymMult[ϕ_,m_,0,sbundle][ψ_]]:>TensorPlus[MultScal[(-1)^m,SymMult[ψ,m,0,sbundle][DirNnOpname[ϕ]]],SymMult[ϕ,m,0,sbundle][DirNnOpname[ψ]]]};
(* Defining the Intrinsic connection *)
DefIntrinsicConnection[nb,eps,CovDOfMetric@eps,t,Nn,sigma,{A,B,Adg,Bdg,a}];
]]];

DefSenConnection[Dd_,eps_,CD_,t_,Nn_,sigma_,{A_,B_,C_,D_,Adg_,Bdg_,a_}]:=With[{normsqr=Scalar[Nn[a]Nn[-a]],epsdg=Dagger[eps],boxcd=SymbolJoin["Box",CD],tbundle=TangentBundleOfSolderingForm[sigma],
sbundle=VBundleOfSolderingForm[sigma],boxDd=SymbolJoin["Box",Dd],F=(First@IndicesOfVBundle@VBundleOfSolderingForm[sigma])[[5]],H=(First@IndicesOfVBundle@VBundleOfSolderingForm[sigma])[[6]],
Mfd=ManifoldOfCovD[CD],
Omega4name=SpaceSpinorsDefaultNames[Nn][[3]],
Omega0name=SpaceSpinorsDefaultNames[Nn][[4]],
DirOpname=Evaluate[DirOpNameOfNormal[Nn]],
ExtrKname=Evaluate[ExtrKNameOfNormal[Nn]],
HatNnOpname=SpaceSpinorsDefaultNames[Nn][[6]]},
CovDQ[Dd]^=True;
SpinCovDQ[Dd]^=True;
SenCovDQ[Dd]^=True;
NormalOfCovD[Dd]^=Nn;
SenCovDOfNormalSpinor[t]^=Dd;
ParentCovD[Dd]^=CD;
xAct`xTensor`Private`MakeLinearDerivative[Evaluate[{Dd[xAct`xTensor`Private`pattern[A,BlankSequence[]]],Dd[A]}/.xAct`xTensor`Private`pattern->Pattern],True];
TorsionQ[Dd]^=True;
SpatialSpinCovDQ[Dd]^=True;
SymmetryGroupOfCovD[Dd]^=StrongGenSet[{1,2},GenSet[Cycles@{1,2}]];
ManifoldOfCovD[Dd]^=ManifoldOfCovD[CD];
VBundlesOfCovD[Dd]^={tbundle,sbundle};
SymbolOfCovD[Dd]^={"?","▽"};
SlotsOfCovD[Dd]^={-sbundle,-sbundle};
eps/:Dd[__]@eps[__]:=0;
epsdg/:Dd[__]@epsdg[__]:=0;
DefSpinor[Evaluate[SymbolJoin["TorsionNormal",Dd]][-A,-B,-C,-D],ManifoldOfCovD[CD],GenSet[Cycles[{1,2}],Cycles[{3,4}],-Cycles[{1,3},{2,4}]],PrintAs->"(Subscript[ω, N])"];
DefSpinor[Evaluate[SymbolJoin["TorsionSpatial",Dd]][-A,-B,-C,-D,F,H],ManifoldOfCovD[CD],GenSet[Cycles[{1,2}],Cycles[{3,4}],Cycles[{5,6}],-Cycles[{1,3},{2,4}]],PrintAs->"(Subscript[ω, S])"];
DefSpatialBox[Dd];
(* Add the slashed package to Latex packages *)
If[FreeQ[$TexInitLatexPackages,"{slashed}"],AppendTo[$TexInitLatexPackages,"{slashed}"]];
(* Define irreducible parts of extrinsic curvature *)
DefSymmetricSpinor[Omega4name,4,0,sbundle,SpaceSpinorsDefaultSymbols[Nn][[3]]]; 
DefSymmetricSpinor[Omega0name,0,0,sbundle,SpaceSpinorsDefaultSymbols[Nn][[4]]]; 
Tex[Omega4name]^=Tex[Omega4name];
Tex[Omega0name]^=Tex[Omega0name];
Omega4NameOfCovD[Dd]^=Omega4name;
Omega0NameOfCovD[Dd]^=Omega0name;
HatNnOpname[Omega4name]^=Omega4name;
HatNnOpname[Omega0name]^=Omega0name;
Dagger[Omega0name]^=Omega0name;
Evaluate[SymbolJoin["IrrDec",ExtrKname,"Eq"]]=ExtrKname[-A,-B,-C,-D]==1/6 eps[-A,-D] eps[-B,-C] Omega0name[]+1/6 eps[-A,-C] eps[-B,-D] Omega0name[]+Omega4name[-A,-B,-C,-D];
(* Transforming between 4D and 3D derivatives *)
SenToSpinCovDRules=Join[SenToSpinCovDRules,MakeSimpleRule[{Dd[A,B]@expr_, 1/Sqrt[normsqr*2](t[B,Adg]CD[A,-Adg]@expr+t[A,Adg]CD[B,-Adg]@expr)}]];
SpinCovDToSenRules=Join[SpinCovDToSenRules,MakeSimpleRule[{CD[A,Adg]@expr_, (t[A,Adg]*CD[Dir@Nn[a]][expr])/normsqr-t[B,Adg]*Dd[-B,A][expr]*Sqrt[2]/Sqrt[normsqr]}]];
DirToSpinCovDRules=Join[DirToSpinCovDRules,MakeSimpleRule[{CD[Dir[Nn[a]]]@expr_,t[A,Adg]*CD[-A,-Adg][expr]}]];
(* Commutation rule for the Sen connection Dd *)
Evaluate[SymbolJoin["Commute",Dd,Dd,boxDd]]=MakeSimpleRule[{Dd[A, B][Dd[C, D][expr_]],  
 (eps[B, D]*boxDd[A, C][expr])/2 + 
  (eps[B, C]*boxDd[A, D][expr])/2 + 
  (eps[A, D]*boxDd[B, C][expr])/2 + 
  (eps[A, C]*boxDd[B, D][expr])/2 + 
  Dd[C, D][Dd[A, B][expr]]}];
Evaluate[SymbolJoin[boxDd,"ToHatBox"]]=
MakeSimpleRule[{boxDd[A,B][expr_],1/2 (boxcd[A,B][expr])-1/2Evaluate[SymbolJoin["TorsionNormal",Dd]][A,D,B,-D] (CD[Dir[Nn[a]]][expr])-1/2 Evaluate[SymbolJoin["TorsionSpatial",Dd]][A,C,B,-C,-D,-F] (Dd[D,F][expr])+1/2 (SymbolJoin["HatBox",CD,Nn][A,B][expr])}];
(* Commutation rule for the spacetime CovD *)
SpaceSpinors`Private`CommuteSpinCovD=MakeSimpleRule[{CD[A,Adg]@CD[B,Bdg]@expr_,epsdg[Adg,Bdg]*boxcd[A,B][expr]+eps[A,B]*boxcd[Adg,Bdg][expr]+CD[B,Bdg][CD[A,Adg][expr]]}];
];

DefIntrinsicConnection[nb_,eps_,CD_,t_,Nn_,sigma_,{A_,B_,Adg_,Bdg_,a_}]:=With[{normsqr=Scalar[Nn[a]Nn[-a]],epsdg=Dagger[eps],tbundle=TangentBundleOfSolderingForm[sigma],
sbundle=VBundleOfSolderingForm[sigma],R4name=SpaceSpinorsDefaultNames[Nn][[10]],R0name=SpaceSpinorsDefaultNames[Nn][[11]],Dd=SenCovDOfNormalSpinor[t]},
CovDQ[nb]^=True;
SpinCovDQ[nb]^=True;
SpatialSpinCovDQ[nb]^=True;
NormalOfCovD[nb]^=Nn;
ParentCovD[nb]^=CD;
IntrinsicCovDOfNormalSpinor[t]^=nb;
SlotsOfCovD[nb]^={-sbundle,-sbundle};
 xAct`xTensor`Private`MakeLinearDerivative[Evaluate[{nb[xAct`xTensor`Private`pattern[A,BlankSequence[]]],nb[A]}/.xAct`xTensor`Private`pattern->Pattern],True];
SymmetryGroupOfCovD[nb]^=StrongGenSet[{1,2},GenSet[Cycles@{1,2}]];
ManifoldOfCovD[nb]^=ManifoldOfCovD[CD];
VBundlesOfCovD[nb]^={tbundle,sbundle};
SymbolOfCovD[nb]^={"?","D"};
eps/:nb[__]@eps[__]:=0;
DefSpatialBox[nb];
Omega4NameOfCovD[nb]^=ZeroTensor[{-sbundle,-sbundle,-sbundle,-sbundle}];
Omega0NameOfCovD[nb]^=ZeroTensor[{}];
DefSymmetricSpinor[R4name,4,0,sbundle,SpaceSpinorsDefaultSymbols[Nn][[5]]]; 
DefSymmetricSpinor[R0name,0,0,sbundle,SpaceSpinorsDefaultSymbols[Nn][[6]]]; 
Tex[R4name]^=Tex[R4name];
Tex[R0name]^=Tex[R0name];
R4NameOfCovD[Dd]^=R4name;
R0NameOfCovD[Dd]^=R0name;
];

DefSpatialBox[covd_Symbol]:=With[{boxcd=SymbolJoin["Box",covd],A=(First@IndicesOfVBundle@VBundlesOfCovD[covd][[2]])[[1]],
B=(First@IndicesOfVBundle@VBundlesOfCovD[covd][[2]])[[2]]},
CovDQ[boxcd]^=True;
AppendTo[xAct`xTensor`Private`$MultiIndexCovDs,boxcd];
xAct`xTensor`Private`MakeLinearDerivative[{boxcd[A_,B_],boxcd[A,B]},True];
SymmetryGroupOfCovD[boxcd]^=Symmetric[{1,2}];
ManifoldOfCovD[boxcd]^=ManifoldOfCovD[covd];
VBundlesOfCovD[boxcd]^=VBundlesOfCovD[covd];
SlotsOfCovD[boxcd]^=SlotsOfCovD[covd];
xAct`Spinors`Private`CovDOfBox[boxcd]^=covd;
SymbolOfCovD[boxcd]^={First[SymbolOfCovD[covd]],StringJoin["(OverTilde[□])","[",Part[SymbolOfCovD@covd,2],"]"]};
xAct`xTensor`Private`SymbolRelations[boxcd,covd,{}];
Protect[boxcd];
];

SpatialBoxToCovD[expr_,boxcd_]:=With[{
cd=xAct`Spinors`Private`CovDOfBox@boxcd,
spin1=UpIndex@SlotsOfCovD[boxcd][[1]],spin2=UpIndex@SlotsOfCovD[boxcd][[2]]},
expr/.{boxcd[A_,B_]@L_:>With[{C=DummyIn[spin2]},Symmetrize[cd[A,-C]@cd[B,C]@L,{A,B}]]/;ABIndexQ[A,spin1]&&ABIndexQ[B,spin1],boxcd[A_,B_]@L_:>With[{C=DummyIn[spin1]},
Symmetrize[cd[-C,A]@cd[C,B]@L,{A,B}]]/;ABIndexQ[A,spin2]&&ABIndexQ[B,spin2]}
];

4. Decomposition into space spinors

4.1. Tensors

5. Fundamental space spinor operators

5.1. Common functions for the fundamental spinor operators

DivName[covd_?SpatialSpinCovDQ]:=Symbol[StringJoin["Div",SymbolName[covd]]]; CurlName[covd_?SpatialSpinCovDQ]:=Symbol[StringJoin["Curl",SymbolName[covd]]]; TwistName[covd_?SpatialSpinCovDQ]:=Symbol[StringJoin["Twist",SymbolName[covd]]];
BoxName[covd_?SpatialSpinCovDQ]:=Symbol[StringJoin["Box",SymbolName[covd]]];

ExtractUnprimedIndsGivenCovD[inds_List,covd_?xAct`Spinors`SpinCovDQ]:=With[{spin=VBundlesOfCovD[covd][[2]]},Select[inds,xAct`xTensor`Private`VBundleIndexPMQ@spin]];

5.2. Definition of fundamental spinor operators and tools

FundSpatialSpinOpQ[_]:=False;

$FundSpatialSpinOpCovDs={};

Options[DefFundSpatialSpinOperators]^={HideCovDSymbolReference->True};

SpatialOpValenceNumberPrintFunc[TT_,opsymbol_,opsymbsuper_, covdsymb_,spin_]:=Join[{If[OptionValue[DefFundSpinOperators,ShowValenceInfo],SubsuperscriptBox[opsymbol,ToString[DisplayForm[NumOfUnprimedSlots[spin][TT]],StandardForm],opsymbsuper],
If[StringLength[opsymbsuper]==0,opsymbol,SuperscriptBox[opsymbol,opsymbsuper]]]},If[OptionValue[DefFundSpatialSpinOperators,HideCovDSymbolReference],{},{"[",covdsymb,"]"}]]

SpatialTexValenceNumbers[TT_,spin_]:=If[OptionValue[DefFundSpinOperators,ShowValenceInfo],StringJoin["_{",xAct`TexAct`Tex[NumOfUnprimedSlots[spin][TT]/.xAct`TexAct`ToOrderedPlus],"} "]," "];

Definition of the spatial divergence, curl and twistor operators, and most tools that are needed to handle them.

DefFundSpatialSpinOperators[covd_?SpatialSpinCovDQ,options:OptionsPattern[]]:=
With[{
(* Names of the operators *)
divcd=DivName@covd, curlcd=CurlName@covd, twistcd=TwistName@covd,boxcd=BoxName@covd,
(* Names of lists *)
$irrdecrulescd=Symbol[StringJoin["$IrrDecRules",SymbolName[covd]]],
$expandfundspinoprulescd=Symbol[StringJoin["$ExpandFundSpinOpRules",SymbolName[covd]]],
(* Extract the spin bundles *)
spin=VBundlesOfCovD[covd][[2]],
Nn=NormalOfCovD[covd],
CD=ParentCovD[covd],
Omega4=Omega4NameOfCovD[covd],
Omega0=Omega0NameOfCovD[covd],
Accname=AccNameOfNormal[NormalOfCovD[covd]],
DirOp=DirOpNameOfNormal[NormalOfCovD[covd]],
Ns=SpinorOfNormal[NormalOfCovD[covd]],
aind=(First@IndicesOfVBundle@VBundlesOfCovD[covd][[1]])[[1]]},
With[{
normsqr=Scalar[Nn[aind]Nn[-aind]],
(* The spin metrics *)
eps=First@MetricsOfVBundle@spin,
divCD=xAct`SymManipulator`Private`DivName@CD,
curlCD=xAct`SymManipulator`Private`CurlName@CD,
curldgCD=xAct`SymManipulator`Private`CurlDgName@CD,
twistCD=xAct`SymManipulator`Private`TwistName@CD,
Aind=(First@IndicesOfVBundle@spin)[[1]],
Bind=(First@IndicesOfVBundle@spin)[[2]],
Cind=(First@IndicesOfVBundle@spin)[[3]],
Dind=(First@IndicesOfVBundle@spin)[[4]],
SpatialPhi4=SpatialPhinamesOfNormal[Nn][[1]],
SpatialPhi2=SpatialPhinamesOfNormal[Nn][[2]],
SpatialPhi0=SpatialPhinamesOfNormal[Nn][[3]],
HatNnOp=HatNnOpOfNormal[Nn],
R4Name=R4NameOfCovD[SenCovDOfNormalSpinor[Ns]],
R0Name=R0NameOfCovD[SenCovDOfNormalSpinor[Ns]],
(* Functions for extraction of unprimed indices and their numbers. *)
ExtractUnprimed=Select[#,xAct`xTensor`Private`VBundleIndexPMQ@spin]&},
Module[{expanddivcd,expandcurlcd,expandtwistcd},
(* Add to the lists $FundSpinOpCovDs and $FundSpatialSpinOpCovDs  *)
AppendTo[$FundSpatialSpinOpCovDs,covd];
AppendTo[xAct`SymManipulator`Private`$FundSpinOpCovDs,covd];

(* FundSpinOpQ *)
FundSpatialSpinOpQ[divcd]^=True;
FundSpatialSpinOpQ[curlcd]^=True;
FundSpatialSpinOpQ[twistcd]^=True;

(* Linking *)
CovDOfFundSpinOp[divcd]^=covd;
CovDOfFundSpinOp[curlcd]^=covd;
CovDOfFundSpinOp[twistcd]^=covd;

(* Tensor definitions. *)
xTensorQ[divcd[TT_?xTensorQ]]^= True;
xTensorQ[curlcd[TT_?xTensorQ]]^= True;
xTensorQ[twistcd[TT_?xTensorQ]]^= True;

(* Links to other symbols *)
VisitorsOf[covd]^=Union[VisitorsOf[covd],{divcd,curlcd,twistcd}];

(* How to undefine *)
Undef[divcd]^:=UndefFundSpatialSpinOperators@covd;
Undef[curlcd]^:=UndefFundSpatialSpinOperators@covd;
Undef[twistcd]^:=UndefFundSpatialSpinOperators@covd;

SetLinearOperatorRules[divcd];
SetLinearOperatorRules[curlcd];
SetLinearOperatorRules[twistcd];

(* Usage messages *)
$expandfundspinoprulescd::usage=StringJoin@@(ToString/@{$expandfundspinoprulescd,"contains rules for expansion of the fundamental operators ", divcd, ", ", curlcd," and ", twistcd," of expr in terms of symmetrized derivatives."});
$irrdecrulescd::usage=StringJoin@@(ToString/@{$irrdecrulescd," is a list of rules that are used by the function ", ToFundSpinOp," to convert derivatives to fundamental operators."});

(* Calculation of the slots of the tensors. *)
SlotsOfTensor[divcd[TT_?xTensorQ]]^:=Module[{k,l,ovb},
k=NumOfUnprimedSlots[spin]@TT;
l=NumOfPrimedSlots[spin]@TT;
ovb=xAct`SymManipulator`Private`ExtractOtherVBundles[spin]@SlotsOfTensor@TT;
If[And[xAct`SymManipulator`Private`$SlotsOfTensorWarning,Simplify[k<2]],Throw@Message[divcd::error,StringJoin["Wrong VBundles: ", ToString[SlotsOfTensor@TT]]],
SymmetricOfValence[k-2,l,spin,ovb]]];
SlotsOfTensor[curlcd[TT_?xTensorQ]]^:=Module[{k,l,ovb},
k=NumOfUnprimedSlots[spin]@TT;
l=NumOfPrimedSlots[spin]@TT;
ovb=xAct`SymManipulator`Private`ExtractOtherVBundles[spin]@SlotsOfTensor@TT;
If[And[xAct`SymManipulator`Private`$SlotsOfTensorWarning,Simplify[k<1]],Throw@Message[curlcd::error,StringJoin["Wrong VBundles: ", ToString[SlotsOfTensor@TT]]],
SymmetricOfValence[k,l,spin,ovb]]];
SlotsOfTensor[twistcd[TT_?xTensorQ]]^:=Module[{k,l,ovb},
k=NumOfUnprimedSlots[spin]@TT;
l=NumOfPrimedSlots[spin]@TT;
ovb=xAct`SymManipulator`Private`ExtractOtherVBundles[spin]@SlotsOfTensor@TT;
If[And[xAct`SymManipulator`Private`$SlotsOfTensorWarning,Simplify[k<0]],Throw@Message[twistcd::error,StringJoin["Wrong VBundles: ", ToString[SlotsOfTensor@TT]]],
SymmetricOfValence[k+2,l,spin,ovb]]];

TagSetDelayed[divcd,NumOfUnprimedSlots[spin][divcd[TT_?xTensorQ]],NumOfUnprimedSlots[spin][TT]-2];
TagSetDelayed[divcd,NumOfPrimedSlots[spin][divcd[TT_?xTensorQ]],NumOfPrimedSlots[spin][TT]];
TagSetDelayed[curlcd,NumOfUnprimedSlots[spin][curlcd[TT_?xTensorQ]],NumOfUnprimedSlots[spin][TT]];
TagSetDelayed[curlcd,NumOfPrimedSlots[spin][curlcd[TT_?xTensorQ]],NumOfPrimedSlots[spin][TT]];
TagSetDelayed[twistcd,NumOfUnprimedSlots[spin][twistcd[TT_?xTensorQ]],NumOfUnprimedSlots[spin][TT]+2];
TagSetDelayed[twistcd,NumOfPrimedSlots[spin][twistcd[TT_?xTensorQ]],NumOfPrimedSlots[spin][TT]];

(* Calculation of the symmetry groups of the tensors *)
SymmetryGroupOfTensor[divcd[TT_?xTensorQ]]^:=xAct`SymManipulator`Private`CompatibleSym@SlotsOfTensor[divcd[TT]];
SymmetryGroupOfTensor[curlcd[TT_?xTensorQ]]^:=xAct`SymManipulator`Private`CompatibleSym@SlotsOfTensor[curlcd[TT]];
SymmetryGroupOfTensor[twistcd[TT_?xTensorQ]]^:=xAct`SymManipulator`Private`CompatibleSym@SlotsOfTensor[twistcd[TT]];

SymmetricSpinorOfArbitraryValenceQ[spin][divcd[TT_?xTensorQ]] ^:= SymmetricSpinorOfArbitraryValenceQ[spin][TT];SymmetricSpinorOfArbitraryValenceQ[spin][curlcd[TT_?xTensorQ]] ^:= SymmetricSpinorOfArbitraryValenceQ[spin][TT];SymmetricSpinorOfArbitraryValenceQ[spin][twistcd[TT_?xTensorQ]] ^:= SymmetricSpinorOfArbitraryValenceQ[spin][TT];

(* Interaction with the ZeroTensor *)
divcd[ZeroTensor[vbundles_]]:=With[{k=NumOfUnprimedVBundles[spin]@vbundles,l=NumOfPrimedVBundles[spin]@vbundles,ovb=xAct`SymManipulator`Private`ExtractOtherVBundles[spin]@vbundles},
ZeroTensor[SymmetricOfValence[k-2,l,spin,ovb]]];
curlcd[ZeroTensor[vbundles_]]:=With[{k=NumOfUnprimedVBundles[spin]@vbundles,l=NumOfPrimedVBundles[spin]@vbundles,ovb=xAct`SymManipulator`Private`ExtractOtherVBundles[spin]@vbundles},
ZeroTensor[SymmetricOfValence[k,l,spin,ovb]]];
twistcd[ZeroTensor[vbundles_]]:=With[{k=NumOfUnprimedVBundles[spin]@vbundles,l=NumOfPrimedVBundles[spin]@vbundles,ovb=xAct`SymManipulator`Private`ExtractOtherVBundles[spin]@vbundles},
ZeroTensor[SymmetricOfValence[k+2,l,spin,ovb]]];

(* Printing *)
If[SenCovDQ[covd],
PrintAs[divcd[TT_?xTensorQ]]^:=RowBox@Join[SpatialOpValenceNumberPrintFunc[TT,"ɗ","",Last@SymbolOfCovD[covd],spin],{PrintAs[TT]}];
PrintAs[curlcd[TT_?xTensorQ]]^:=RowBox@Join[SpatialOpValenceNumberPrintFunc[TT,"ƈ","",Last@SymbolOfCovD[covd],spin],{PrintAs[TT]}];
PrintAs[twistcd[TT_?xTensorQ]]^:=RowBox@Join[SpatialOpValenceNumberPrintFunc[TT,"ƭ","",Last@SymbolOfCovD[covd],spin],{PrintAs[TT]}],
PrintAs[divcd[TT_?xTensorQ]]^:=RowBox@Join[SpatialOpValenceNumberPrintFunc[TT,StyleBox["ɗ",Underlined],"",Last@SymbolOfCovD[covd],spin],{PrintAs[TT]}];
PrintAs[curlcd[TT_?xTensorQ]]^:=RowBox@Join[SpatialOpValenceNumberPrintFunc[TT,StyleBox["ƈ",Underlined],"",Last@SymbolOfCovD[covd],spin],{PrintAs[TT]}];
PrintAs[twistcd[TT_?xTensorQ]]^:=RowBox@Join[SpatialOpValenceNumberPrintFunc[TT,StyleBox["ƭ",Underlined],"",Last@SymbolOfCovD[covd],spin],{PrintAs[TT]}];
];
(* Tex output. *)
xAct`TexAct`$TexInitLatexPackages=DeleteDuplicates@Join[xAct`TexAct`$TexInitLatexPackages,{"{tipa}"}];
xAct`TexAct`$TexInitLatexExtraCode=DeleteDuplicates@Join[xAct`TexAct`$TexInitLatexExtraCode,{"\\def\\sdiv{\\text{\\texthtd}}","\\def\\scurl{\\text{\\texthtc}}","\\def\\stwist{\\text{\\texthtt}}","\\def\\isdiv{\\underline{\\text{\\texthtd}}}","\\def\\iscurl{\\underline{\\text{\\texthtc}}}","\\def\\istwist{\\underline{\\text{\\texthtt}}}"}];

If[SenCovDQ[covd],xAct`SymManipulator`Private`TexFundOp[divcd[TT_?xTensorQ]]^:=StringJoin["\\sdiv",SpatialTexValenceNumbers[TT,spin],xAct`SymManipulator`Private`TexFundOp[TT]];
xAct`SymManipulator`Private`TexFundOp[curlcd[TT_?xTensorQ]]^:=StringJoin["\\scurl",SpatialTexValenceNumbers[TT,spin],xAct`SymManipulator`Private`TexFundOp[TT]];
xAct`SymManipulator`Private`TexFundOp[twistcd[TT_?xTensorQ]]^:=StringJoin["\\stwist",SpatialTexValenceNumbers[TT,spin],xAct`SymManipulator`Private`TexFundOp[TT]],
xAct`SymManipulator`Private`TexFundOp[divcd[TT_?xTensorQ]]^:=StringJoin["\\isdiv",SpatialTexValenceNumbers[TT,spin],xAct`SymManipulator`Private`TexFundOp[TT]];
xAct`SymManipulator`Private`TexFundOp[curlcd[TT_?xTensorQ]]^:=StringJoin["\\iscurl",SpatialTexValenceNumbers[TT,spin],xAct`SymManipulator`Private`TexFundOp[TT]];
xAct`SymManipulator`Private`TexFundOp[twistcd[TT_?xTensorQ]]^:=StringJoin["\\istwist",SpatialTexValenceNumbers[TT,spin],xAct`SymManipulator`Private`TexFundOp[TT]];
];
xAct`SymManipulator`Private`TexFundOp[expr_]:=xAct`TexAct`Tex@expr;
xAct`TexAct`Tex[x:((divcd|curlcd|twistcd)[_])]:=StringJoin["(",xAct`SymManipulator`Private`TexFundOp@x,")"];

(* Translating between 3D and 4D *)
If[SenCovDQ[covd],
Evaluate[SymbolJoin[DirOp,"ToFundSpinOpRule"]]=
{DirOp[ϕ_]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[MultScal[-k/(k+1),SymMult[Ns,0,1,spin][curldgCD[ϕ]]],SymMult[Ns,1,1,spin][twistCD[ϕ]]]]};
];
If[SenCovDQ[covd],
Evaluate[SymbolJoin["FundSpinOpToSenRules",covd]]={twistCD[ϕ_?xTensorQ]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[MultScal[1/normsqr,SymMult[Ns,0,0,spin][DirOp[ϕ]]],MultScal[-Sqrt[2]/Sqrt[normsqr],SymMult[Ns,1,0,spin][twistcd[ϕ]]],MultScal[Sqrt[2]/Sqrt[normsqr]*k/(k+2),SymMult[Ns,0,0,spin][curlcd[ϕ]]]]]/;(NumOfPrimedSlots[spin][ϕ]===0),
curldgCD[ϕ_?xTensorQ]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[MultScal[1/normsqr,SymMult[Ns,1,0,spin][DirOp[ϕ]]],MultScal[-Sqrt[2]/Sqrt[normsqr],SymMult[Ns,1,0,spin][curlcd[ϕ]]],MultScal[Sqrt[2]/Sqrt[normsqr]*(k-1)/k,SymMult[Ns,0,0,spin][divcd[ϕ]]]]]/;(NumOfPrimedSlots[spin][ϕ]===0)
};
Evaluate[SymbolJoin["SenToFundSpinOpRules",covd]]=
{twistcd[ϕ_?xTensorQ]:>MultScal[Sqrt[2]/Sqrt[normsqr],SymMult[Ns,0,1,spin][twistCD[ϕ]]]/;(NumOfPrimedSlots[spin][ϕ]===0),
curlcd[ϕ_?xTensorQ]:>Module[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[MultScal[Sqrt[2]/Sqrt[normsqr]/2,SymMult[Ns,1,1,spin][twistCD[ϕ]]],MultScal[Sqrt[2]/Sqrt[normsqr]*(k+2)/(2k+2),SymMult[Ns,0,1,spin][curldgCD[ϕ]]]]]/;(NumOfPrimedSlots[spin][ϕ]===0),divcd[ϕ_?xTensorQ]:>MultScal[Sqrt[2]/Sqrt[normsqr],SymMult[Ns,1,1,spin][curldgCD[ϕ]]]/;(NumOfPrimedSlots[spin][ϕ]===0)};
];
(* 4D derivatives of the normal *)
If[SenCovDQ[covd],
FundSpinOpNormalRules[Ns]^={divCD[Ns]->Omega0,
curlCD[Ns]->MultScal[Sqrt[normsqr]/Sqrt[2],Accname],
curldgCD[Ns]->MultScal[-(Sqrt[2]/Sqrt[normsqr]),SymMult[Ns,1,0,spin][SymMult[Ns,1,0,spin][Accname]]],
twistCD[Ns]->TensorPlus[MultScal[-1/3*1/normsqr,SymMult[Ns,0,0,spin][SymMult[Ns,0,0,spin][Omega0]]],MultScal[-(Sqrt[2]/Sqrt[normsqr]),SymMult[Ns,0,0,spin][SymMult[Ns,1,0,spin][Accname]]],MultScal[2/normsqr,SymMult[Ns,1,0,spin][SymMult[Ns,1,0,spin][Omega4]]]]};
];
(* Translation between intrinsic and Sen connection if both are defined. *)
If[SubsetQ[$FundSpatialSpinOpCovDs,{IntrinsicCovDOfNormalSpinor[Ns],SenCovDOfNormalSpinor[Ns]}],
With[{IntDiv=DivName@IntrinsicCovDOfNormalSpinor[Ns],IntCurl=CurlName@IntrinsicCovDOfNormalSpinor[Ns],IntTwist=TwistName@IntrinsicCovDOfNormalSpinor[Ns],SenDiv=DivName@SenCovDOfNormalSpinor[Ns],SenCurl=CurlName@SenCovDOfNormalSpinor[Ns],SenTwist=TwistName@SenCovDOfNormalSpinor[Ns],Omega4Sen=Omega4NameOfCovD@SenCovDOfNormalSpinor[Ns],Omega0Sen=Omega0NameOfCovD@SenCovDOfNormalSpinor[Ns]},
Evaluate[SymbolJoin["FundSpatial",IntrinsicCovDOfNormalSpinor[Ns],"To",SenCovDOfNormalSpinor[Ns],"Rule"]]={IntDiv[ϕ_]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[SenDiv[ϕ],MultScal[-(k-2)/Sqrt[2]/Sqrt[normsqr],SymMult[Omega4Sen,3,0,spin][ϕ]]]],IntCurl[ϕ_]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[SenCurl[ϕ],MultScal[(k+2)/6/Sqrt[2]/Sqrt[normsqr],SymMult[Omega0Sen,0,0,spin][ϕ]],MultScal[-(k-1)/Sqrt[2]/Sqrt[normsqr],SymMult[Omega4Sen,2,0,spin][ϕ]]]],IntTwist[ϕ_]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[SenTwist[ϕ],MultScal[-k/Sqrt[2]/Sqrt[normsqr],SymMult[Omega4Sen,1,0,spin][ϕ]]]]};
Evaluate[SymbolJoin["FundSpatial",SenCovDOfNormalSpinor[Ns],"To",IntrinsicCovDOfNormalSpinor[Ns],"Rule"]]={SenDiv[ϕ_]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[IntDiv[ϕ],MultScal[(k-2)/Sqrt[2]/Sqrt[normsqr],SymMult[Omega4Sen,3,0,spin][ϕ]]]],SenCurl[ϕ_]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[IntCurl[ϕ],MultScal[-(k+2)/6/Sqrt[2]/Sqrt[normsqr],SymMult[Omega0Sen,0,0,spin][ϕ]],MultScal[(k-1)/Sqrt[2]/Sqrt[normsqr],SymMult[Omega4Sen,2,0,spin][ϕ]]]],SenTwist[ϕ_]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[IntTwist[ϕ],MultScal[k/Sqrt[2]/Sqrt[normsqr],SymMult[Omega4Sen,1,0,spin][ϕ]]]]};
];
];
(* IntrinsicCurvatureRules *)
If[SenCovDQ[covd],Evaluate[SymbolJoin["IntrinsicCurvatureRules",covd]]={R0NameOfCovD[covd]->TensorPlus[MultScal[12,Lambda[CD]],MultScal[4/normsqr,SpatialPhi0],MultScal[-2/(3*normsqr),SymMult[Omega0,0,0,spin][Omega0]],MultScal[normsqr^(-1),SymMult[Omega4,4,0,spin][Omega4]]],R4NameOfCovD[covd]->TensorPlus[MultScal[-1,Psi[CD]],MultScal[-2/normsqr,SpatialPhi4],MultScal[Sqrt[2]/Sqrt[normsqr],curlcd[Omega4]],MultScal[2/(3*normsqr),SymMult[Omega0,0,0,spin][Omega4]],MultScal[-2/normsqr,SymMult[Omega4,2,0,spin][Omega4]]]};
];
(* Indexfree commutators *)
If[SenCovDQ[covd],
(* Sen derivative case *)
CommuteOp[divcd,curlcd]^=divcd[curlcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[MultScal[(k-2)/k,curlcd[divcd[ϕ]]],MultScal[1/Sqrt[2]/Sqrt[normsqr],SymMult[Omega4,4,0,spin][twistcd[ϕ]]],MultScal[(2-k)/(2+k)*Sqrt[2]/Sqrt[normsqr],SymMult[Omega4,3,0,spin][curlcd[ϕ]]],MultScal[(2+k)/2/normsqr,SymMult[ϕ,2,0,spin][SpatialPhi2]],MultScal[(2-k)/normsqr,SymMult[ϕ,3,0,spin][SpatialPhi4]],MultScal[((k-3) (k-2))/(2 k (1+k))*Sqrt[2]/Sqrt[normsqr],SymMult[Omega4,2,0,spin][divcd[ϕ]]],MultScal[-1/3*Sqrt[2]/Sqrt[normsqr],SymMult[Omega0,0,0,spin][divcd[ϕ]]],MultScal[ (k-2)/2,SymMult[Psi[CD],3,0,spin][ϕ]]]]/;And[EnoughIndsQSpin[ϕ,2,0,spin],NumOfPrimedSlots[spin][ϕ]===0];
CommuteOp[curlcd,divcd]^=curlcd[divcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[MultScal[k/(k-2),divcd[curlcd[ϕ]]],MultScal[(k/(4-2*k))*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,4,0,spin][twistcd[ϕ]]],MultScal[(k/(2+k))*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,3,0,spin][curlcd[ϕ]]],MultScal[(-2^(-1))*((k*(2+k))/(k-2)/normsqr),SymMult[ϕ,2,0,spin][SpatialPhi2]],MultScal[k/normsqr,SymMult[ϕ,3,0,spin][SpatialPhi4]],MultScal[((3-k)/(2+2*k))*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,2,0,spin][divcd[ϕ]]],MultScal[(k/(3*(-2+k)))*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega0,0,0,spin][divcd[ϕ]]],MultScal[(-2^(-1))*k,SymMult[Psi[CD],3,0,spin][ϕ]]]]/;And[EnoughIndsQSpin[ϕ,3,0,spin],NumOfPrimedSlots[spin][ϕ]===0];
CommuteOp[curlcd,twistcd]^=curlcd[twistcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[MultScal[k/(2+k),twistcd[curlcd[ϕ]]],MultScal[(1/2)*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,2,0,spin][twistcd[ϕ]]],MultScal[(-(k/(2+k)))*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,1,0,spin][curlcd[ϕ]]],MultScal[(-3^(-1))*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega0,0,0,spin][twistcd[ϕ]]],MultScal[k/2,SymMult[Psi[CD],1,0,spin][ϕ]],MultScal[(-4^(-1))*k*(2/normsqr),SymMult[ϕ,0,0,spin][SpatialPhi2]],MultScal[(-2^(-1))*k*(2/normsqr),SymMult[ϕ,1,0,spin][SpatialPhi4]],If[Simplify[k<=0],ZeroTensorOfTensor[curlcd[twistcd[ϕ]]],MultScal[((-1+k)/(2*(1+k)))*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,0,0,spin][divcd[ϕ]]]]]]/;NumOfPrimedSlots[spin][ϕ]===0;
CommuteOp[twistcd,curlcd]^=twistcd[curlcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[MultScal[(2+k)/k,curlcd[twistcd[ϕ]]],MultScal[(-2^(-1))*((2+k)/k)*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,2,0,spin][twistcd[ϕ]]],MultScal[(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,1,0,spin][curlcd[ϕ]]],MultScal[(2+k)/(3*k)*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega0,0,0,spin][twistcd[ϕ]]],MultScal[-1-k/2,SymMult[Psi[CD],1,0,spin][ϕ]],MultScal[(2+k)/2/normsqr,SymMult[ϕ,0,0,spin][SpatialPhi2]],MultScal[(2+k)/normsqr,SymMult[ϕ,1,0,spin][SpatialPhi4]],MultScal[(-2^(-1))*(((-1+k)*(2+k))/(k*(1+k)))*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,0,0,spin][divcd[ϕ]]]]]/;EnoughIndsQSpin[ϕ,1,0,spin]&&NumOfPrimedSlots[spin][ϕ]===0;
CommuteOp[divcd,twistcd]^=divcd[twistcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[MultScal[((-1+k)*(2+k))/(k*(1+k)),twistcd[divcd[ϕ]]],MultScal[-4/(2+k),curlcd[curlcd[ϕ]]],MultScal[(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,3,0,spin][twistcd[ϕ]]],MultScal[(2-2*k)/(2+k)*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,2,0,spin][curlcd[ϕ]]],MultScal[-2/3*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega0,0,0,spin][curlcd[ϕ]]],MultScal[(-2-k)/6*2/normsqr,SymMult[ϕ,0,0,spin][SpatialPhi0]],MultScal[-2/normsqr,SymMult[ϕ,1,0,spin][SpatialPhi2]],MultScal[(-1+k)*2/normsqr,SymMult[ϕ,2,0,spin][SpatialPhi4]],MultScal[-1+k,SymMult[Psi[CD],2,0,spin][ϕ]],MultScal[-2-k,SymMult[Lambda[CD],0,0,spin][ϕ]],MultScal[(2-3*k+k^2)/(k+k^2)*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,1,0,spin][divcd[ϕ]]]]]/;EnoughIndsQSpin[ϕ,1,0,spin]&&NumOfPrimedSlots[spin][ϕ]===0;
CommuteOp[twistcd,divcd]^=twistcd[divcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[MultScal[(k*(1+k))/(-2+k+k^2),divcd[twistcd[ϕ]]],MultScal[(4*k*(1+k))/((-1+k)*(2+k)^2),curlcd[curlcd[ϕ]]],MultScal[-((k*(1+k))/(-2+k+k^2))*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,3,0,spin][twistcd[ϕ]]],MultScal[(2*k*(1+k))/(2+k)^2*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,2,0,spin][curlcd[ϕ]]],MultScal[(2*k*(1+k))/(3*(-2+k+k^2))*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega0,0,0,spin][curlcd[ϕ]]],MultScal[(k*(1+k))/(6*(-1+k))*2/normsqr,SymMult[ϕ,0,0,spin][SpatialPhi0]],MultScal[(k*(1+k))/(-2+k+k^2)*2/normsqr,SymMult[ϕ,1,0,spin][SpatialPhi2]],MultScal[-((k*(1+k))/(2+k))*2/normsqr,SymMult[ϕ,2,0,spin][SpatialPhi4]],MultScal[-((k*(1+k))/(2+k)),SymMult[Psi[CD],2,0,spin][ϕ]],MultScal[(k*(1+k))/(-1+k),SymMult[Lambda[CD],0,0,spin][ϕ]],MultScal[(2-k)/(2+k)*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,1,0,spin][divcd[ϕ]]]]]/;EnoughIndsQSpin[ϕ,2,0,spin]&&NumOfPrimedSlots[spin][ϕ]===0;
CommuteOp[curlcd,curlcd]^=curlcd[curlcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[MultScal[(-2-k)/4,divcd[twistcd[ϕ]]],MultScal[((-1+k)*(2+k)^2)/(4*k*(1+k)),twistcd[divcd[ϕ]]],MultScal[(2+k)/4*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,3,0,spin][twistcd[ϕ]]],MultScal[(1/2-k/2)*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,2,0,spin][curlcd[ϕ]]],MultScal[(-2-k)/6*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega0,0,0,spin][curlcd[ϕ]]],MultScal[(-24^(-1))*(2+k)^2*2/normsqr,SymMult[ϕ,0,0,spin][SpatialPhi0]],MultScal[(-2-k)/4*2/normsqr,SymMult[ϕ,1,0,spin][SpatialPhi2]],MultScal[((-1+k)*(2+k))/4*2/normsqr,SymMult[ϕ,2,0,spin][SpatialPhi4]],MultScal[((-1+k)*(2+k))/4,SymMult[Psi[CD],2,0,spin][ϕ]],MultScal[(-4^(-1))*(2+k)^2,SymMult[Lambda[CD],0,0,spin][ϕ]],MultScal[((2+k)*(2-3*k+k^2))/(4*k*(1+k))*(Sqrt[2]/Sqrt[normsqr]),SymMult[Omega4,1,0,spin][divcd[ϕ]]]]]/;EnoughIndsQSpin[ϕ,1,0,spin]&&NumOfPrimedSlots[spin][ϕ]===0;
CommuteOp[DirOp,divcd]^=DirOp[divcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[divcd[DirOp[ϕ]],MultScal[(-3^(-1))*Omega0[],divcd[ϕ]],MultScal[-1,SymMult[Accname,2,0,spin][DirOp[ϕ]]],MultScal[Sqrt[normsqr]*Sqrt[2],SymMult[Accname,2,0,spin][curlcd[ϕ]]],MultScal[(-1+2/k)*Sqrt[normsqr]*Sqrt[2],SymMult[Accname,1,0,spin][divcd[ϕ]]],MultScal[(2*(-2+k))/(2+k),SymMult[Omega4,3,0,spin][curlcd[ϕ]]],MultScal[-((6-5*k+k^2)/(k+k^2)),SymMult[Omega4,2,0,spin][divcd[ϕ]]],MultScal[(-2+k)*(Sqrt[normsqr]/Sqrt[2]),SymMult[Psi[CD],3,0,spin][ϕ]],MultScal[-1,SymMult[Omega4,4,0,spin][twistcd[ϕ]]],MultScal[((-1-k/2)/Sqrt[normsqr])*Sqrt[2],SymMult[SpatialPhi2,2,0,spin][ϕ]],MultScal[((-2+k)/Sqrt[normsqr])*Sqrt[2],SymMult[ϕ,3,0,spin][SpatialPhi4]]]]/;EnoughIndsQSpin[ϕ,2,0,spin]&&NumOfPrimedSlots[spin][ϕ]===0;
CommuteOp[DirOp,curlcd]^=DirOp[curlcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[curlcd[DirOp[ϕ]],MultScal[(-3^(-1))*Omega0[],curlcd[ϕ]],MultScal[-1,SymMult[Accname,1,0,spin][DirOp[ϕ]]],MultScal[Sqrt[normsqr]/Sqrt[2],SymMult[Accname,2,0,spin][twistcd[ϕ]]],MultScal[(4/(2+k))*(Sqrt[normsqr]/Sqrt[2]),SymMult[Accname,1,0,spin][curlcd[ϕ]]],MultScal[-1,SymMult[Omega4,3,0,spin][twistcd[ϕ]]],MultScal[(2*(-1+k))/(2+k),SymMult[Omega4,2,0,spin][curlcd[ϕ]]],MultScal[(-6^(-1))*((2+k)*(Sqrt[normsqr]/Sqrt[2])*6*Lambda[CD][]),ϕ],MultScal[(1/6)*(((2+k)/Sqrt[normsqr])*Sqrt[2]*SpatialPhi0[]),ϕ],MultScal[(-Sqrt[normsqr]^(-1))*Sqrt[2],SymMult[SpatialPhi2,1,0,spin][ϕ]],MultScal[((1-k)/Sqrt[normsqr])*Sqrt[2],SymMult[SpatialPhi4,2,0,spin][ϕ]],MultScal[(-1+k)*(Sqrt[normsqr]/Sqrt[2]),SymMult[Psi[CD],2,0,spin][ϕ]],MultScal[(-(((-1+k)*(2+k))/(k*(1+k))))*(Sqrt[normsqr]/Sqrt[2]),SymMult[Accname,0,0,spin][divcd[ϕ]]],MultScal[-((2-3*k+k^2)/(k+k^2)),SymMult[Omega4,1,0,spin][divcd[ϕ]]]]]/;EnoughIndsQSpin[ϕ,1,0,spin]&&NumOfPrimedSlots[spin][ϕ]===0;
CommuteOp[DirOp,twistcd]^=DirOp[twistcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[twistcd[DirOp[ϕ]],MultScal[(-3^(-1))*Omega0[],twistcd[ϕ]],MultScal[-1,SymMult[Accname,0,0,spin][DirOp[ϕ]]],MultScal[2*(Sqrt[normsqr]/Sqrt[2]),SymMult[Accname,1,0,spin][twistcd[ϕ]]],MultScal[((-2*k)/(2+k))*(Sqrt[normsqr]/Sqrt[2]),SymMult[Accname,0,0,spin][curlcd[ϕ]]],MultScal[-1,SymMult[Omega4,2,0,spin][twistcd[ϕ]]],MultScal[(2*k)/(2+k),SymMult[Omega4,1,0,spin][curlcd[ϕ]]],MultScal[k*(Sqrt[normsqr]/Sqrt[2]),SymMult[Psi[CD],1,0,spin][ϕ]],MultScal[(k/2/Sqrt[normsqr])*Sqrt[2],SymMult[SpatialPhi2,0,0,spin][ϕ]],MultScal[(-k/Sqrt[normsqr])*Sqrt[2],SymMult[SpatialPhi4,1,0,spin][ϕ]],If[Simplify[k<=0],ZeroTensorOfTensor[twistcd[ϕ]],MultScal[(1-k)/(1+k),SymMult[Omega4,0,0,spin][divcd[ϕ]]]]]]/;NumOfPrimedSlots[spin][ϕ]===0,
(* Intrinsic derivative case *)
CommuteOp[divcd,curlcd]^=divcd[curlcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[MultScal[(k-2)/k,curlcd[divcd[ϕ]]],MultScal[ -(k-2)/2,SymMult[R4Name,3,0,spin][ϕ]]]]/;And[EnoughIndsQSpin[ϕ,2,0,spin],NumOfPrimedSlots[spin][ϕ]===0];
CommuteOp[curlcd,divcd]^=curlcd[divcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[MultScal[k/(k-2),divcd[curlcd[ϕ]]],MultScal[k/2,SymMult[R4Name,3,0,spin][ϕ]]]]/;And[EnoughIndsQSpin[ϕ,3,0,spin],NumOfPrimedSlots[spin][ϕ]===0];
CommuteOp[curlcd,twistcd]^=curlcd[twistcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[MultScal[k/(2+k),twistcd[curlcd[ϕ]]],MultScal[-1/2*k,SymMult[R4Name,1,0,spin][ϕ]]]]/;(NumOfPrimedSlots[spin][ϕ]===0);
CommuteOp[twistcd,curlcd]^=twistcd[curlcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[MultScal[(2+k)/k,curlcd[twistcd[ϕ]]],MultScal[(2+k)/2,SymMult[R4Name,1,0,spin][ϕ]]]]/;And[EnoughIndsQSpin[ϕ,1,0,spin],NumOfPrimedSlots[spin][ϕ]===0];
CommuteOp[divcd,twistcd]^=divcd[twistcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[MultScal[((-1+k)*(2+k))/(k*(1+k)),twistcd[divcd[ϕ]]],MultScal[-4/(2+k),curlcd[curlcd[ϕ]]],MultScal[1-k,SymMult[R4Name,2,0,spin][ϕ]],MultScal[(-2-k)/12,SymMult[R0Name,0,0,spin][ϕ]]]]/;And[EnoughIndsQSpin[ϕ,1,0,spin],NumOfPrimedSlots[spin][ϕ]===0];
CommuteOp[twistcd,divcd]^=twistcd[divcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[MultScal[(k*(k+1))/((k-1) (k+2)),divcd[twistcd[ϕ]]],MultScal[(4*k*(1+k))/((-1+k)*(2+k)^2),curlcd[curlcd[ϕ]]],MultScal[(k*(1+k))/(2+k),SymMult[R4Name,2,0,spin][ϕ]],MultScal[(k*(1+k))/(12*(-1+k)),SymMult[R0Name,0,0,spin][ϕ]]]]/;And[EnoughIndsQSpin[ϕ,2,0,spin],NumOfPrimedSlots[spin][ϕ]===0];
CommuteOp[curlcd,curlcd]^=curlcd[curlcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin]@ϕ},TensorPlus[MultScal[(-2-k)/4,divcd[twistcd[ϕ]]],MultScal[((-1+k)*(2+k)^2)/(4*k*(1+k)),twistcd[divcd[ϕ]]],MultScal[-1/4*((-1+k)*(2+k)),SymMult[R4Name,2,0,spin][ϕ]],MultScal[-1/48*(2+k)^2,SymMult[R0Name,0,0,spin][ϕ]]]]/;And[EnoughIndsQSpin[ϕ,1,0,spin],NumOfPrimedSlots[spin][ϕ]===0];
];

CommuteOp[HatNnOp,divcd]^={HatNnOp[divcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[MultScal[-1,divcd[HatNnOp[ϕ]]],MultScal[(Sqrt[2]/Sqrt[normsqr])*(k-2),SymMult[Omega4,3,0,spin][HatNnOp[ϕ]]]]]/;NumOfPrimedSlots[spin][ϕ]===0};
CommuteOp[HatNnOp,curlcd]^={HatNnOp[curlcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[MultScal[-1,curlcd[HatNnOp[ϕ]]],MultScal[(-Sqrt[2]/Sqrt[normsqr])*((2+k)/6),SymMult[Omega0,0,0,spin][HatNnOp[ϕ]]],MultScal[(Sqrt[2]/Sqrt[normsqr])*(k-1),SymMult[Omega4,2,0,spin][HatNnOp[ϕ]]]]]/;NumOfPrimedSlots[spin][ϕ]===0};
CommuteOp[HatNnOp,twistcd]^={HatNnOp[twistcd[ϕ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ]},TensorPlus[MultScal[-1,twistcd[HatNnOp[ϕ]]],MultScal[(Sqrt[2]/Sqrt[normsqr])*k,SymMult[Omega4,1,0,spin][HatNnOp[ϕ]]]]]/;NumOfPrimedSlots[spin][ϕ]===0};
(* Expansion of the operators. *)
expanddivcd[divcd[TT_?xTensorQ][inds___]]:=Module[{slotsTT=SlotsOfTensor@TT,unprimedinds,A=DummyIn@spin,B=DummyIn@spin,unprimedpos,TTinds},
unprimedinds=ExtractUnprimed[{inds}];
unprimedpos=Select[Range@Length@slotsTT,(UpIndex[slotsTT[[#]]]==spin)&];
TTinds=Range@Length@slotsTT/.Thread[unprimedpos->Join[unprimedinds,{-A,-B}]];
covd[A,B][TT@@TTinds]];
expandcurlcd[curlcd[TT_?xTensorQ][inds___]]:=Module[{slotsTT=SlotsOfTensor@TT,unprimedinds,A=DummyIn@spin,unprimedpos,TTinds},
unprimedinds=ExtractUnprimed[{inds}];
unprimedpos=Select[Range@Length@slotsTT,(UpIndex[slotsTT[[#]]]==spin)&];
TTinds=Range@Length@slotsTT/.Thread[unprimedpos->Append[Rest@unprimedinds,-A]];
ToCanonicalSym@ImposeSym[covd[First@unprimedinds,A][TT@@TTinds],IndexList@@unprimedinds]];
expandtwistcd[twistcd[TT_?xTensorQ][inds___]]:=Module[{slotsTT=SlotsOfTensor@TT,unprimedinds,unprimedpos,TTinds},
unprimedinds=ExtractUnprimed[{inds}];
unprimedpos=Select[Range@Length@slotsTT,(UpIndex[slotsTT[[#]]]==spin)&];
TTinds=Range@Length@slotsTT/.Thread[unprimedpos->Join[Rest@Rest@unprimedinds]];
ToCanonicalSym@ImposeSym[(covd@@Take[unprimedinds,2])[TT@@TTinds],IndexList[inds]]];
$expandfundspinoprulescd={x:(divcd[TT_?xTensorQ][inds___]):>expanddivcd[x],x:(curlcd[TT_?xTensorQ][inds___]):>expandcurlcd[x],x:(twistcd[TT_?xTensorQ][inds___]):>expandtwistcd[x]};

(* Imposing Twist *)
ImposeFundSpinOp[expr1_,twistcd, iinds_]:=
Module[{unprimedinds1,irrdecexpr, (* If the expression is an expanded symmetry, it is important that we do the contractions with the same index on all terms. Therefore, we sort the free indices so the contraction is done with the same index on all terms.*)
frees=Sort[List@@FindFreeIndices@Evaluate[expr1]], unprimedfrees,indexrules={}, intexpr},
unprimedinds1=ExtractUnprimed[iinds];
unprimedfrees=ExtractUnprimed[frees];
indexrules=Thread@Rule[unprimedfrees,Rest@Rest@unprimedinds1];
intexpr=(covd@@Take[unprimedinds1,2])[ReplaceIndex[expr1,indexrules]];
intexpr=ToFundSpinOp[intexpr,covd];
ImposeSym[intexpr,IndexList@@unprimedinds1]];

(* Imposing Curl *)
ImposeFundSpinOp[expr1_,curlcd, iinds_]:=
Module[{unprimedinds1,irrdecexpr, (* If the expression is an expanded symmetry, it is important that we do the contractions with the same index on all terms. Therefore, we sort the free indices so the contraction is done with the same index on all terms.*)
frees=Sort[List@@FindFreeIndices@Evaluate[expr1]], unprimedfrees,indexrules={}, intexpr,A=DummyIn@spin},
unprimedinds1=ExtractUnprimed[iinds];
unprimedfrees=ExtractUnprimed[frees];
indexrules=Thread@Rule[unprimedfrees,Append[Rest@unprimedinds1,-A]];
intexpr=covd[First@unprimedinds1,A][ReplaceIndex[expr1,indexrules]];
intexpr=ToFundSpinOp[intexpr,covd];
ImposeSym[intexpr,IndexList@@unprimedinds1]];

(* Imposing Div *)
ImposeFundSpinOp[expr1_,divcd, iinds_]:=
Module[{unprimedinds1,irrdecexpr, (* If the expression is an expanded symmetry, it is important that we do the contractions with the same index on all terms. Therefore, we sort the free indices so the contraction is done with the same index on all terms.*)
frees=Sort[List@@FindFreeIndices@Evaluate[expr1]], unprimedfrees,indexrules={}, intexpr,A=DummyIn@spin,B=DummyIn@spin},
unprimedinds1=ExtractUnprimed[iinds];
unprimedfrees=ExtractUnprimed[frees];
indexrules=Thread@Rule[unprimedfrees,Join[unprimedinds1,{-A,-B}]];
intexpr=covd[A,B][ReplaceIndex[expr1,indexrules]];
intexpr=ToFundSpinOp[intexpr,covd];
ImposeSym[intexpr,IndexList@@unprimedinds1]];

$irrdecrulescd={};

(* Commutators with indices and boxes *)

(* DivTwist *)
CommuteFundSpinOp[divcd,twistcd]^=divcd[twistcd[TT_?xTensorQ]][inds___]:>Module[{A=DummyIn[spin]},With[{k=NumOfUnprimedSlots[spin]@TT},If[k>1,(k-1)*(k+2)/k/(k+1)*twistcd[divcd[TT]][inds],0]-4/(k+2)curlcd[curlcd[TT]][inds]-2*ToCanonicalSym@ImposeSym[(boxcd[A,First@{inds}])[TT[Sequence@@Rest[{inds}],-A]],IndexList[inds]]]]/;NumOfUnprimedSlots[spin]@TT≥1;

(* TwistDiv *)
CommuteFundSpinOp[twistcd,divcd]^=twistcd[divcd[TT_?xTensorQ]][inds___]:>Module[{A=DummyIn[spin]},With[{k=NumOfUnprimedSlots[spin]@TT},k*(k+1)/(k-1)/(k+2)*divcd[twistcd[TT]][inds]+4*k*(k+1)/(k-1)/(k+2)^2*curlcd[curlcd[TT]][inds]+2*k*(k+1)/(k-1)/(k+2)*ToCanonicalSym@ImposeSym[(boxcd[A,First@{inds}])[TT[Sequence@@Rest[{inds}],-A]],IndexList[inds]]]];

(* CurlCurl *)
CommuteFundSpinOp[curlcd,curlcd]^=curlcd[curlcd[TT_?xTensorQ]][inds___]:>Module[{A=DummyIn[spin]},With[{k=NumOfUnprimedSlots[spin]@TT},If[k>1,(k-1)*(k+2)^2/4/k/(k+1)*twistcd[divcd[TT]][inds],0]-(k+2)/4*divcd[twistcd[TT]][inds]-(k+2)/2*ToCanonicalSym@ImposeSym[(boxcd[A,First@{inds}])[TT[Sequence@@Rest[{inds}],-A]],IndexList[inds]]]];

(* DivCurl *)
CommuteFundSpinOp[divcd,curlcd]^=divcd[curlcd[TT_?xTensorQ]][inds___]:>Module[{A=DummyIn[spin],B=DummyIn[spin]},With[{k=NumOfUnprimedSlots[spin]@TT},If[k>2,(k-2)/k*curlcd[divcd[TT]][inds],0]-boxcd[A,B][TT[inds,-A,-B]]]];

(* CurlDiv *)
CommuteFundSpinOp[curlcd,divcd]^=curlcd[divcd[TT_?xTensorQ]][inds___]:>Module[{A=DummyIn[spin],B=DummyIn[spin]},With[{k=NumOfUnprimedSlots[spin]@TT},k/(k-2)*divcd[curlcd[TT]][inds]+k/(k-2)*boxcd[A,B][TT[inds,-A,-B]]]];

(* CurlTwist *)
CommuteFundSpinOp[curlcd,twistcd]^=curlcd[twistcd[TT_?xTensorQ]][inds___]:>With[{k=NumOfUnprimedSlots[spin]@TT},k/(k+2)twistcd[curlcd[TT]][inds]-ToCanonicalSym@ImposeSym[(boxcd@@Take[{inds},2])[TT@@Drop[{inds},2]],IndexList[inds]]];
CommuteFundSpinOp[curlcd,twistcd,twistcd,curlcd]^=CommuteFundSpinOp[curlcd,twistcd];
(* TwistCurl *)
CommuteFundSpinOp[twistcd,curlcd]^=twistcd[curlcd[TT_?xTensorQ]][inds___]:>With[{k=NumOfUnprimedSlots[spin]@TT},(k+2)/k*curlcd[twistcd[TT]][inds]+(k+2)/k*ToCanonicalSym@ImposeSym[(boxcd@@Take[{inds},2])[TT@@Drop[{inds},2]],IndexList[inds]]]/;(NumOfUnprimedSlots[spin]@TT>0);
CommuteFundSpinOp[twistcd,curlcd,curlcd,twistcd]^=CommuteFundSpinOp[twistcd,curlcd];
]]];

UndefFundSpatialSpinOperators[covd_?SpatialSpinCovDQ]:=
With[{
(* Names of the operators *)
divcd=DivName@covd, curlcd=CurlName@covd, twistcd=TwistName@covd,
(* Names of lists *)
$irrdecrulescd=StringJoin["$IrrDecRules",SymbolName[covd]],
$expandfundspinoprulescd=StringJoin["$ExpandFundSpinOpRules",SymbolName[covd]]},

(* Removing special code *)
ImposeFundSpatialSpinOp[expr1_,twistcd, iinds_]=.;
ImposeFundSpatialSpinOp[expr1_,curlcd, iinds_]=.;
ImposeFundSpatialSpinOp[expr1_,divcd, iinds_]=.;

(* Unlinking *)
VisitorsOf[covd]^=DeleteCases[VisitorsOf[covd],Alternatives[divcd,curlcd,twistcd]];

(* Undefining objects *)
Remove@$irrdecrulescd;
Remove@$expandfundspinoprulescd;

Remove@divcd;
Remove@curlcd;
Remove@twistcd;

$FundSpatialSpinOpCovDs=DeleteCases[$FundSpatialSpinOpCovDs,covd];
];

5.3. Irreducible decompositions of covariant derivatives

Irreducible decompositions of covariant derivatives of symmetric spinors.

xAct`SymManipulator`IrrDecomposeCovD[covd_?SpatialSpinCovDQ[A_,B_]@TT_?xTensorQ[inds___],options:OptionsPattern[]]:=If[CompatibleSymQ[SlotsOfTensor@TT,SymmetryGroupOfTensor@TT]=!=True,Throw@Message[IrrDecomposeCovD::error,"Only decompositions of derivatives of symmetric tensors are implemented."],
With[{eps=First@MetricsOfVBundle@VBundlesOfCovD[covd][[2]]},
Module[{unprimedinds,irrdecexpr,k, resulttype,expandsym},
{resulttype,expandsym}=OptionValue[{ResultType,ExpandSym}];
unprimedinds=ExtractUnprimedIndsGivenCovD[{inds},covd];
k=Length@unprimedinds;
irrdecexpr=TwistName[covd][TT][A,B,Sequence@@unprimedinds];
If[k>0,irrdecexpr=irrdecexpr-k/(k+2)*ImposeSym[eps[A,First@unprimedinds]*CurlName[covd][TT][Sequence@@Rest@unprimedinds,B],IndexList@@unprimedinds]-k/(k+2)*ImposeSym[eps[B,First@unprimedinds]*CurlName[covd][TT][Sequence@@Rest@unprimedinds,A],IndexList@@unprimedinds]];
If[And[k>1],irrdecexpr=irrdecexpr+(1-k)/(1+k)*ImposeSym[eps[A,First@unprimedinds]*eps[Last@unprimedinds,B]*DivName[covd][TT][Sequence@@Most@Rest@unprimedinds],IndexList@@unprimedinds]];
If[expandsym,irrdecexpr=ToCanonical@ExpandSym[irrdecexpr,SmartExpand->True]];
Switch[resulttype,
"Expression",irrdecexpr,
"Equation",Equal[covd[A,B]@TT[inds],irrdecexpr],
"Rule",MakeRule[Evaluate[{covd[A,B]@TT[inds],irrdecexpr},MetricOn->All,ContractMetrics->True]],
"CompareRule",MakeCompareRule[Evaluate[{covd[A,B]@TT[inds],irrdecexpr}]],
_,Null]
]]];

We can also just give the name of the tensor and the covd.

xAct`SymManipulator`IrrDecomposeCovD[TT_?xTensorQ,covd_?SpatialSpinCovDQ,options:OptionsPattern[]]:=Module[{unprimedinds, cdeexpr},{unprimedinds}={DownIndex/@#1}&@@GetIndexRange@@@(Reverse/@Tally[UpIndex/@SlotsOfTensor@TwistName[covd][TT]]);
cdeexpr=covd[First@unprimedinds, First@Rest@unprimedinds]@TT[Sequence@@Rest@Rest@unprimedinds];
IrrDecomposeCovD[cdeexpr,options]];

Collecting rules for irreducible decompositions.

xAct`SymManipulator`ToFundSpinOp[expr_,covd_?SpatialSpinCovDQ,options:OptionsPattern[]]:=Module[{newtensors={},intermexpr},intermexpr=ToCanonical@ContractMetric[expr//.Symbol[StringJoin["$IrrDecRules",SymbolName[covd]]]]/.x:(covd[A_,B_][TTT_?xTensorQ[inds___]]):>Module[{},AppendTo[newtensors,TTT];x];
newtensors=DeleteDuplicates@newtensors;
newtensors=Select[newtensors,CompatibleSymQ[SlotsOfTensor@#,SymmetryGroupOfTensor@#]&];
If[Length@newtensors>0,Print["Adding rules for ", newtensors]];
xAct`SymManipulator`Private`AddToIrrDecRules[#,covd,ExpandSym->OptionValue[ExpandSym]]&/@newtensors;
ToCanonical@ContractMetric[expr//.Symbol[StringJoin["$IrrDecRules",SymbolName[covd]]]]
];

5.4. LeibnizRules

SpatialTwistMultScal[covd_,(T_?xTensorQ)[]]:=(xAct`SpaceSpinors`Private`TwistName@covd)[T]
SpatialTwistMultScal[covd_,Times[a_,rest__]]:=TensorPlus[MultScal[Times[rest],SpatialTwistMultScal[covd,a]],MultScal[a,SpatialTwistMultScal[covd,Times[rest]]]]
SpatialTwistMultScal[covd_,Power[a_,c_?ConstantQ]]:=MultScal[c*Power[a,c-1],SpatialTwistMultScal[covd,a]]
SpatialTwistMultScal[covd_,expr_Plus]:=SpatialTwistMultScal[covd,#]&/@TensorPlus@@expr
SpatialTwistMultScal[covd_,c_?ConstantQ]:=With[{spin=VBundlesOfCovD[covd][[2]]},ZeroTensor[{-spin,-spin}]]

MultScalLeibnizRules[covd_?SpatialSpinCovDQ]:=
With[{divcd=xAct`SpaceSpinors`Private`DivName@covd,
curlcd=xAct`SpaceSpinors`Private`CurlName@covd,
twistcd=xAct`SpaceSpinors`Private`TwistName@covd,
spin=VBundlesOfCovD[covd][[2]]},
{divcd[MultScal[expr_,T_]]:>TensorPlus[MultScal[expr,divcd[T]],SymMult[SpatialTwistMultScal[covd,expr],2,0,spin][T]],
curlcd[MultScal[expr_,T_]]:>TensorPlus[MultScal[expr,curlcd[T]],SymMult[SpatialTwistMultScal[covd,expr],1,0,spin][T]],
twistcd[MultScal[expr_,T_]]:>TensorPlus[MultScal[expr,twistcd[T]],SymMult[SpatialTwistMultScal[covd,expr],0,0,spin][T]]}];

SymMultLeibnizRules[covd_?SpatialSpinCovDQ]:=
With[{divcd=xAct`SpaceSpinors`Private`DivName@covd,
curlcd=xAct`SpaceSpinors`Private`CurlName@covd,
twistcd=xAct`SpaceSpinors`Private`TwistName@covd,
spin=VBundlesOfCovD[covd][[2]]},
{divcd[SymMult[ϕ_,m_,0,spin][ψ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ],l=NumOfUnprimedSlots[spin][ψ]},TensorPlus[MultScal[((-1)^m*(-1+l-m)*(l-m))/((-1+k+l-2*m)*(k+l-2*m)),SymMult[ψ,2+m,0,spin][twistcd[ϕ]]],MultScal[(2*(-1)^m*(k-m)*(1+k+l-m)*(-l+m))/((2+k)*(-1+k+l-2*m)*(k+l-2*m)),SymMult[ψ,1+m,0,spin][curlcd[ϕ]]],MultScal[If[k===0,0,((-1)^m*(-1+k-m)*(k-m)*(k+l-m)*(1+k+l-m))/(k*(1+k)*(-1+k+l-2*m)*(k+l-2*m))],SymMult[ψ,m,0,spin][divcd[ϕ]]],MultScal[((-1+k-m)*(k-m))/((-1+k+l-2*m)*(k+l-2*m)),SymMult[ϕ,2+m,0,spin][twistcd[ψ]]],MultScal[(2*(k-m)*(1+k+l-m)*(-l+m))/((2+l)*(-1+k+l-2*m)*(k+l-2*m)),SymMult[ϕ,1+m,0,spin][curlcd[ψ]]],MultScal[If[l===0,0,((-1+l-m)*(l-m)*(k+l-m)*(1+k+l-m))/(l*(1+l)*(-1+k+l-2*m)*(k+l-2*m))],SymMult[ϕ,m,0,spin][divcd[ψ]]]]]/;NumOfPrimedSlots[spin][ϕ]===0&&NumOfPrimedSlots[spin][ψ]===0,curlcd[SymMult[ϕ_,m_,0,spin][ψ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ],l=NumOfUnprimedSlots[spin][ψ]},TensorPlus[MultScal[((-1)^m*(-l+m))/(k+l-2*m),SymMult[ψ,1+m,0,spin][twistcd[ϕ]]],MultScal[((-1)^m*(k*(2+k+l)-2*(1+k+l)*m+2*m^2))/((2+k)*(k+l-2*m)),SymMult[ψ,m,0,spin][curlcd[ϕ]]],MultScal[If[k===0,0,((-1)^m*(k-m)*(1+k+l-m)*m)/(k*(1+k)*(k+l-2*m))],SymMult[ψ,-1+m,0,spin][divcd[ϕ]]],MultScal[(-k+m)/(k+l-2*m),SymMult[ϕ,1+m,0,spin][twistcd[ψ]]],MultScal[(l*(2+k+l)-2*(1+k+l)*m+2*m^2)/((2+l)*(k+l-2*m)),SymMult[ϕ,m,0,spin][curlcd[ψ]]],MultScal[If[l===0,0,((l-m)*(1+k+l-m)*m)/(l*(1+l)*(k+l-2*m))],SymMult[ϕ,-1+m,0,spin][divcd[ψ]]]]]/;NumOfPrimedSlots[spin][ϕ]===0&&NumOfPrimedSlots[spin][ψ]===0,twistcd[SymMult[ϕ_,m_,0,spin][ψ_]]:>With[{k=NumOfUnprimedSlots[spin][ϕ],l=NumOfUnprimedSlots[spin][ψ]},TensorPlus[MultScal[(-1)^m,SymMult[ψ,m,0,spin][twistcd[ϕ]]],MultScal[(2*(-1)^m*m)/(2+k),SymMult[ψ,-1+m,0,spin][curlcd[ϕ]]],MultScal[If[k===0,0,((-1)^m*(-1+m)*m)/(k*(1+k))],SymMult[ψ,-2+m,0,spin][divcd[ϕ]]],SymMult[ϕ,m,0,spin][twistcd[ψ]],MultScal[(2*m)/(2+l),SymMult[ϕ,-1+m,0,spin][curlcd[ψ]]],MultScal[If[l===0,0,((-1+m)*m)/(l*(1+l))],SymMult[ϕ,-2+m,0,spin][divcd[ψ]]]]]/;NumOfPrimedSlots[spin][ϕ]===0&&NumOfPrimedSlots[spin][ψ]===0
}]

5. End private and package

End[];
EndPackage[];

6. Examples

The user context is empty :

?Global`*

Define a manifold

$DefInfoQ=False;

SetOptions[AutomaticRules,Verbose->False];

DefManifold[M4,4,{a,b,c,d,f,h,l,m,p,q}]

DefMetric[{1,3,0},g[-a,-b],CD,{";","▽"}]

SetOptions[DefSpinor,PrintDaggerAs->AddBar];

Off[ValidateSymbol::"capital"]

SetOptions[DefAbstractIndex,PrintAs->PrimeDagger];

DefSpinStructure[g,Spin,{A,B,C,D,F,H,L,M,P,Q,R,S},ϵ,σ,CDe,{";","▽"},SpinorPrefix->SP,SpinorMark->"S"]

{$PsiSign=1,$PhiSign=1,$LambdaSign=1,$ChiSign=1,$RicciSign=1,$RiemannSign=-1};

DefTensor[Nn[a],M4,PrintAs->"τ"]

DefConstantSymbol[ccc,PrintAs->"c"]

AutomaticRules[Nn,MakeRule[{Nn[a]Nn[-a],ccc},MetricOn->All, ContractMetrics->True]]

Off[DefMetric::"old"]

DefMetric[-1,metrich[-a,-b],cd,{"|","D"},InducedFrom->{g,Nn},PrintAs->"h",DefInfo->False]

DefSpaceSpinStructure[σ,metrich,t,spatialσ,Dd,nb]

ExtrKNnDef

SpatialSFToSF[Nn]

%/.EqToRule[SFToSpatialSF[Nn]]

ToCanonical@ContractMetric@%

tSquareIrrDec=IrrDecompose[t[-A,-A†]t[-B,-B†],ResultType->"Equation"]

SFToSpatialSF[Nn]

%/.EqToRule@SpatialSFToSF[Nn]

%/.Nn[a_]:>SeparateSolderingForm[]@Nn[a]

ToCanonical@ContractMetric@%

%/.EqToRule@tSquareIrrDec

ToCanonical@ContractMetric@%

σ[-a,A,A†]σ[a,-A,-A†]

spatialσ[-a,A,B]spatialσ[a,-A,-B]

%/.EqToRule@SpatialSFToSF[Nn]

ToCanonical@ContractMetric@%

AccNnToCDet

SeparateDir@%

%/.t[A_,Adg_]:>SeparateSolderingForm[]@t[A,Adg]/.CDe->CD

GradNormalToExtrinsicK@%

ToCanonical@%

ToCanonical@ContractMetric[%/.EqToRule@SFToSpatialSF[Nn]]

%/.EqToRule@AccNnDef

metrich[-b,c]CD[-c]@Nn[-a]

Expand@GradNormalToExtrinsicK@%==%

ExtrKNnDef/.EqToRule@%/.CD->CDe

%/.EqToRule@SpatialSFToSF[Nn]

%/.CDe[a_][expr_]↦σ[a,A,A†]CDe[-A,-A†]@expr

%/.Nn[a_]:>SeparateSolderingForm[]@Nn[a]

ToCanonical@ContractMetric@%

ToCanonical@ContractMetric[%/.SpinCovDToSenRules]

(t[-B,A†] (Dd[-C,-D][t[-A,-A†]]))/ccc

ϵ[A,B]*%

ToCanonical@ContractMetric@%

Dd[-A,-B]@ϵ[-C,-D]

Dd[-A,-B]@t[-C,-A†]

%/.SenToSpinCovDRules

%/.SpinCovDToSenRules

ToCanonical@%

CDe[Dir[Nn[a]]][t[-C,-A†]]

%/.DirToSpinCovDRules

%/.SpinCovDToSenRules

ToCanonical@%