Unprotect[g,ϵ,tr,LinearFunction,γ,P,Commutator,Commute,CommuteQ,AntiCommutator,AntiCommute,AntiCommuteQ,RollLeft,ComputeTrace,SubstituteGamma5,VariableQ,RollTrace];
ClearAll["Global`*"];
Needs["Notation`"]

Not5Q[a_]:=(a≠5||!NumericQ[a]);

Unprotect[VariableQ];
SetAttributes[DeclareVariables,Listable];
Notation[(NotationTemplateTag[(Subscript[(NotationPatternTag[p_?VariableQ]), μ_])]) ⟺ (NotationTemplateTag[(NotationPatternTag[p_?VariableQ])[μ_]])];
Notation[(NotationTemplateTag[((NotationPatternTag[p_?VariableQ])∘(NotationPatternTag[k_?VariableQ]))]) ⟺ (NotationTemplateTag[p_∘k_])];
DeclareVariables[x_]:=(
Unprotect[VariableQ];
VariableQ[x]:=True;
VariableQ[x[μ_]]:=True;
x/:x[α_](k_?VariableQ)[α_]:=x∘k;
x/:((x[α_])^2):=(x^2);
x/:x[α_]∘x[α_]:=(x^2);
x/:x∘x:=(x^2);
x/:x[α_]x[β_]Unevaluated[ϵ[l___,α_,m___,β_,r___]]:=0;
x/:g[α_,β_]x[α_]:= x[β]/;!VariableQ[α];
x/:g[α_,β_]x[α_](y_?VariableQ)[β_]:=x∘y;
Protect[VariableQ];
Return[x];
);
DeclareVariables[x___]:=DeclareVariables[{x}];
Protect[VariableQ];

Unprotect[g];
Clear[g];
SetAttributes[g,{Orderless,NumericFunction}];
g[x_Integer,y_Integer]:=(({{1, 0, 0, 0}, {0, -1, 0, 0}, {0, 0, -1, 0}, {0, 0, 0, -1}}))[[x,y]];
g[α_,β_]g[β_,δ_]^:=g[α,δ];
g/:((g[α_,β_])^2):=4;
g/:g[α_,α_]:=4;

Notation[(NotationTemplateTag[(g^(μ_,ν_))]) ⟺ (NotationTemplateTag[g[μ_,ν_]])];
SetAttributes[SmallCircle,Orderless];
Protect[g];

Unprotect[ϵ];
Clear[ϵ];
SetAttributes[ϵ,{NumericFunction}];
ϵ/:g[α_,β_]ϵ[l___,α_,r___]:=ϵ[l,β,r];
ϵ[x__]:=Signature[{x}]/;AllTrue[{x},NumericQ];
ϵ[x__]:=Signature[{x}]Apply[ϵ,Sort[{x}]]/;!OrderedQ[{x}];
ϵ[l___,x_,m___,x_,r___]:=0;
ϵ[la___,m_,ra___]ϵ[lb___,m_,rb___]^:=Det[Outer[g[#1,#2]&,{la,m,ra},{lb,m,rb}]];
Notation[(NotationTemplateTag[(ϵ^(x___))]) ⟺ (NotationTemplateTag[ϵ[x___]])];
Protect[ϵ];

Unprotect[LinearFunction];
Clear[LinearFunction];
LinearFunction[func_,capture_:{}]:=(
func[l___,A_+B_,r___]:=func[l,A,r]+func[l,B,r];
func[l___,c_ A_,r___]:=c func[l,A,r]/;AllTrue[capture,FreeQ[c,#]&];
func[l___,c_· A_,r___]:=c func[l,A,r]/;NumericQ[c];
func[l___,-A_,r___]:=-func[l,A,r];
);
Protect[LinearFunction];

Unprotect[NonCommutativeMultiply];
LinearFunction[NonCommutativeMultiply,{γ}];
InfixNotation[(NotationTemplateTag[·]),NonCommutativeMultiply];
Protect[NonCommutativeMultiply];

Unprotect[γ,P];
Clear[γ];
γ/:((γ[α_])^2):=4;
γ/:NonCommutativeMultiply[l___,γ[α_],γ[α_],r___]:=NonCommutativeMultiply[l,r];
γ/:NonCommutativeMultiply[l___,γ[5],γ[α_],r___]:=-NonCommutativeMultiply[l,γ[α],γ[5],r];
γ[p_?VariableQ]:=(p[α]γ[α]/.α->Unique["α"]);
Notation[(NotationTemplateTag[(Subscript[γ, α_])]) ⟺ (NotationTemplateTag[γ[α_]])];
Notation[(NotationTemplateTag[(Subscript[P, L])]) ⟺ (NotationTemplateTag[((1-(Subscript[γ, 5]))/2)])];
Notation[(NotationTemplateTag[(Subscript[P, R])]) ⟺ (NotationTemplateTag[((1+(Subscript[γ, 5]))/2)])];
Protect[γ,P];

Unprotect[Commutator,Commute,CommuteQ,AntiCommuteQ];
SetAttributes[{CommuteQ,AntiCommuteQ},Orderless];
Commutator[a_,b_]:=0/;CommuteQ[a,b];
LinearFunction[Commutator,{γ}];
Notation[(NotationTemplateTag[(SubMinus[{a_,b_}])]) ⟺ (NotationTemplateTag[Commutator[a_,b_]])];

SetAttributes[AntiCommutator,Orderless];
AntiCommutator[a_,b_]:=0/;AntiCommuteQ[a,b];
LinearFunction[AntiCommutator,{γ}];
Notation[(NotationTemplateTag[(SubPlus[{a_,b_}])]) ⟺ (NotationTemplateTag[AntiCommutator[a_,b_]])];

Commute[expr_,a_]:=expr/.a·(Subscript[γ, β_]):>(Subscript[γ, β])·a+(SubMinus[{a,(Subscript[γ, β])}]);
Commute[a_·b_]:=Commute[a·b,a·b];
AntiCommute[expr_,a_]:=expr/.a·(Subscript[γ, β_]):>-(Subscript[γ, β])·a+(SubPlus[{a,(Subscript[γ, β])}]);
AntiCommute[a_·b_]:=AntiCommute[a·b,a·b];
Protect[Commutator,Commute,CommuteQ,AntiCommuteQ];

Unprotect[γ];
AntiCommuteQ[(Subscript[γ, 5]),(Subscript[γ, μ_])]^:=True/;Not5Q[μ];
AntiCommutator[(Subscript[γ, μ_]),(Subscript[γ, ν_])]^:=2 (g^(μ,ν))/;Not5Q[μ]&&Not5Q[ν];
Protect[γ];

Unprotect[tr,RollLeft];
Clear[tr];
tr[]:=4;
tr[n_?NumericQ]:=n;
LinearFunction[tr,{γ}];

tr[(Subscript[γ, μ_])]:=0;
tr[(Subscript[γ, μ_])·(Subscript[γ, 5])]:=0;
tr[(Subscript[γ, μ_])·(Subscript[γ, ν_])]:=4(g^(μ,ν));
tr[(Subscript[γ, μ_])·(Subscript[γ, ν_])·(Subscript[γ, 5])]:=0;
tr[NonCommutativeMultiply[γs__]]:=0/;OddQ[(Total[Cases[{γs},γ[α_]->1,Infinity]]-Total[Cases[{γs},(Subscript[γ, 5])->1,Infinity]])];

RollLeft[tr[a_·r___]]:=tr[r·a];
LinearFunction[RollLeft,{tr}]
RollLeft[n_]:=n/;FreeQ[n,tr];

tr/:Commute[tr[M_],(Subscript[γ, α_])]:=tr[Commute[M,(Subscript[γ, α])]];
tr/:AntiCommute[tr[M_],(Subscript[γ, α_])]:=tr[AntiCommute[M,(Subscript[γ, α])]];

tr[NonCommutativeMultiply[l___,c_?NumericQ,r___]]:=c  tr[NonCommutativeMultiply[l,r]];
Protect[tr,RollLeft];

Unprotect[SubstituteGamma5];
SubstituteGamma5[tr[A_]]:=(
If[FreeQ[tr[A],γ[5]],Return[tr[A]]];
params= {Unique[α],Unique[β],Unique[δ],Unique[ϵ]};
matrices5 = Length[Cases[A,γ[5]]];
Return[(I/24) Apply[ϵ,params]tr[A ]/. (γ[5]->Apply[NonCommutativeMultiply,γ[#]&/@params])];
);
LinearFunction[SubstituteGamma5,{tr}];
Protect[SubstituteGamma5];

Unprotect[RollTrace];
LinearFunction[RollTrace,{tr}];
RollTrace[tr[M_]]:=Module[{},(
matrices5=Length[Cases[M,(Subscript[γ, 5])->1,Infinity]];
matrices=Length[Cases[M,γ[α_]->1,Infinity]]-matrices5;
If[OddQ[matrices],Return[0]];

trace=tr[M];
(*trace=SubstituteGamma5[trace];*)
trace =Nest[RollLeft,trace,Count[trace,γ]];
If[FreeQ[trace,(Subscript[γ, α_])],Return[trace]];

firstγ = First[Cases[trace,(Subscript[γ, α_]),Infinity]];
res=Nest[AntiCommute[#,firstγ]&,trace,matrices];
trace=RollLeft[trace];
If[!SameQ[res,trace],
sol=Solve[trace==res,trace];
If[Length[sol]>0,
trace = trace/.First[sol];
If[FreeQ[trace,γ],Return[trace]];
Return[RollTrace[trace]];
];
];

Return[trace];
)];
RollTrace[n_]:=n/;FreeQ[n,tr];
Protect[RollTrace];

Unprotect[ComputeTrace];
ComputeTrace[tr[M_]]:=Expand[RollTrace[SubstituteGamma5[tr[M]]]]/.NonCommutativeMultiply[]->1;
LinearFunction[ComputeTrace,{tr}];
ComputeTrace[tr[A_]tr[B_]]:=ComputeTrace[tr[A]]ComputeTrace[tr[B]];
ComputeTrace[n_]:=n/;FreeQ[n,tr];
Protect[ComputeTrace];

tr[γ[α]·γ[β]·γ[σ]·γ[δ]]//ComputeTrace

tr[γ[α]·γ[β]·γ[σ]·γ[δ]·γ[β]·γ[ρ]]//ComputeTrace

tr[(Subscript[P, L])·γ[α]·γ[β]·γ[σ]·γ[δ]]//ComputeTrace

DeclareVariables[p1,p2,p3];
tr[(Subscript[P, L])·γ[p2]·γ[p1]·γ[p3]·γ[p1]]//ComputeTrace//Expand

DeclareVariables[p,q];
tr[γ[p]·γ[q]·γ[p]·γ[q]·(Subscript[P, R])]//ComputeTrace//Expand

DeclareVariables[{p1,p2,q1,q2}]; 
NumericQ[m]:=True
(tr[(γ[p1]+m)·(Subscript[γ, ν])·(γ[q1]+m)·(Subscript[γ, μ])]//ComputeTrace)(tr[(γ[q2]+m)·(Subscript[γ, μ])·(γ[p2]+m)·(Subscript[γ, ν])]//ComputeTrace)//Expand//Simplify

16 (4 ((m^2)-(q1∘p1)) ((m^2)-(q2∘p2))+2 ((q2∘p1) (q1∘p2)+(q1∘p1) ((m^2)-2 (q2∘p2))+(m^2) (q2∘p2)+(p2∘p1) (q2∘q1)))//FullSimplify

DeclareVariables[p,q];
tr[(γ[p]-γ[q])·γ[q]·(Subscript[P, R])·γ[p]·γ[q]]//ComputeTrace//Expand

DeclareVariables[n,l,u1,u2];
NumericQ[mN]=NumericQ[mL]=NumericQ[mU]=NumericQ[v]=NumericQ[a]=True;
(tr[γ[n]·(γ[n]+mN)·γ[n]·(Subscript[P, R])·(Subscript[γ, ν])·(γ[nu]-mL)·(Subscript[γ, μ])·(Subscript[P, L])]tr[(γ[u1]-mU)·(Subscript[γ, μ])·(v-a (Subscript[γ, 5]))·(γ[u2]+mU)·(v+a (Subscript[γ, 5]))·(Subscript[γ, ν])])/.{mL->0}//Expand//ComputeTrace//Expand//Simplify

-16 (n^2) ((mU^2) ((a^2)-(v^2)) (n∘nu)-(((a-v))^2) (n∘u2) (nu∘u1)-(((a+v))^2) (n∘u1) (nu∘u2))/.{v->(1/4),a->(1/4)-(2/3)Sin2W}//Simplify
-16 (n^2) ((mU^2) ((a^2)-(v^2)) (n∘nu)-(((a-v))^2) (n∘u2) (nu∘u1)-(((a+v))^2) (n∘u1) (nu∘u2))/.{v->-(1/4),a->-(1/4)+(1/3)Sin2W}//Simplify

DeclareVariables[n,l,u,d];
NumericQ[mL]=NumericQ[mN]=NumericQ[mU]=NumericQ[mD]=True;
tr[γ[n]·(γ[n]+mN)·γ[n]·(Subscript[P, R])·(Subscript[γ, ν])·(γ[l]+mL)·(Subscript[γ, μ])·(Subscript[P, L])]tr[(γ[u]-mU)·(Subscript[γ, μ])·(Subscript[P, L])·(γ[d]+mD)·(Subscript[P, R])·(Subscript[γ, ν])]//Expand//ComputeTrace//Expand//Simplify