For developers
Idenso FORM color and Dirac source map
FORM sources, Symbolica and Spenso target patterns, implementation mappings, historical validation commands, and unresolved provenance retained behind the concise public convention contract.
FORM color and Dirac rules
This specification records source-backed replacement rules for FORM gamma-algebra simplification and the FORM color.h color-algebra package. The mathematical notation is independent of FORM token names except where a source symbol is documented literally. Open gamma strings always carry explicit bispinor indices; closed gamma traces are written as explicit bispinor contractions, not as a separate trace-index placeholder.
The Symbolica + spenso section uses the approved chain and trace tensor-pattern notation:
chain(bis(4,a),bis(4,c),
gamma(in,out,p(2,mink(4))),
gamma(in,out,mink(4,mu)))and
chain(cof(Nc,i),dind(cof(Nc,j)),
t(coad(Nc^2-1,a),in,out),
t(coad(Nc^2-1,b),in,out))This is a specification-level pattern notation. GammaLoop currently has internal helpers named spenso::gamma_chain and spenso::gamma_trace; those names are mentioned only when documenting the implementation source.
Source Inventory
- FORM manual gamma-algebra section: https://www.nikhef.nl/~form/maindir/documentation/reference/html/manual.html#dx1-85012.
- FORM current source repository, gamma trace implementation: https://github.com/form-dev/form/blob/master/sources/opera.c.
- FORM package page for
color.h: https://www.nikhef.nl/~form/maindir/packages/color/color.html. - FORM package source
color.h: https://www.nikhef.nl/~form/maindir/packages/color/color.h. This source is not currently present in theform-dev/formGitHub tree; line references tocolor.htherefore use package-source line numbers recorded in this document and not GitHub anchors. - FORM color example programs: https://www.nikhef.nl/~form/maindir/packages/color/color.tar.gz. The package page describes these as simple FORM programs that use
color.h. - GammaLoop/idenso current tensor simplifiers: https://github.com/alphal00p/gammaloop/blob/e51747446aa724c3ffac5c42c4103d090c09c6b0/crates/idenso/src/dirac/mod.rs, https://github.com/alphal00p/gammaloop/blob/e51747446aa724c3ffac5c42c4103d090c09c6b0/crates/idenso/src/color/mod.rs.
- Symbolica pattern matching documentation: https://symbolica.io/docs/pattern_matching.html.
- Symbolica Rust
idAPI documentation: https://docs.rs/symbolica/latest/symbolica/id/index.html, https://docs.rs/symbolica/latest/symbolica/id/struct.ReplaceBuilder.html. - spenso Rust crate documentation: https://docs.rs/spenso/latest/spenso/, symbolic tensor-library source: https://docs.rs/spenso/latest/src/spenso/network/library/symbolic.rs.html.
- Typst syntax and math documentation: https://typst.app/docs/reference/syntax/, https://typst.app/docs/reference/math/.
Notational Conventions
Lorentz indices are written as and are raised and lowered with and . The dimension is denoted by in dimension-generic identities and fixed to in the four-dimensional FORM trace4 rules. Repeated Lorentz labels are contracted.
Bispinor indices are . An open gamma chain is written as . A closed trace is an explicit contraction .
Fundamental color indices are . Adjoint color indices are . Fundamental generators are . The package constants are mapped as cA, cR, I2R, and NR; NA is the adjoint dimension. For ordinary , , , and , but color.h is written in terms of invariants.
The word product denotes an ordered noncommutative string inside a chain. It is not used as FORM syntax.
Gamma-algebra replacement rules
Overview
| Rule | Dimension | Purpose |
|---|---|---|
| Gamma collection | all | Collect adjacent bispinor-contracted gamma factors into an ordered chain. |
| Chain joining | all | Join two open chains when the outgoing bispinor index of one equals the incoming index of the next. |
| Metric contraction | all or | Replace and related repeated Lorentz slots by the active dimension. |
| Trace closure | all | Turn an open chain with equal endpoints into an explicit bispinor contraction. |
| Trace recursion | or | Evaluate even traces recursively and annihilate odd traces without gamma-five insertions. |
| Chisholm reduction | only | Reduce using four-dimensional identities. |
| Gamma-five and epsilon | only | Use Levi-Civita and gamma-five branch logic in FORM trace4. |
G1. Gamma-chain product and joining
Mathematical identity:
For longer strings, the same rule constructs an ordered product inside the chain:
FORM source context:
/* Trace4 receives a string of gamma matrices in 'instring'. */
number = *params - 6;
...
for ( i = 0; i < number; i++ ) *p++ = *m++;Source: https://github.com/form-dev/form/blob/master/sources/opera.c#L670-L686, https://github.com/form-dev/form/blob/master/sources/opera.c#L715-L745. Manual: https://www.nikhef.nl/~form/maindir/documentation/reference/html/manual.html#dx1-85012.
GammaLoop/idenso implementation currently collects adjacent gamma matrices by replacing two contracted spenso::gamma calls with an internal chain:
AGS.gamma_pattern(RS.a__, RS.b__, RS.c__) * AGS.gamma_pattern(RS.d__, RS.c__, RS.e__),
GS.chain_pattern(RS.b__, RS.e__, [RS.a__, RS.c__, RS.d__]),Symbolica + spenso pattern:
gamma(bis(4,a),bis(4,b),p(2,mink(4)))
* gamma(bis(4,b),bis(4,c),mink(4,mu))
-> chain(bis(4,a),bis(4,c),
gamma(in,out,p(2,mink(4))),
gamma(in,out,mink(4,mu)))Assumptions: in and out are local slots of each factor in the chain. Dummy bispinor labels consumed during collection are not retained as free indices.
G2. Chain orientation and reversal
Mathematical identity:
Here rev means that the implementation may represent the same contracted tensor network with opposite local slot orientation. This is not a gamma-algebra identity by itself; it is a tensor-pattern canonicalization convention.
Pattern examples:
A(1,j,la,i,mu) * B(j,k) * C(k,l)
-> chain(rep,i,l,A(1,out,la,in,mu),B(in,out),C(in,out))
B(j,k) * C(l,k)
-> chain(rep,j,l,B(in,out),C(out,in))Source context: Symbolica matches syntactically with wildcard variables and respects function-argument ordering for non-symmetric functions; see https://symbolica.io/docs/pattern_matching.html. spenso provides symbolic tensor structures and contraction support; see https://docs.rs/spenso/latest/spenso/.
G3. Metric contraction in gamma chains
Dimension-generic terminal identity:
In the approved chain notation:
chain(bis(D,a),bis(D,c),
gamma(in,out,mink(D,mu)),
gamma(in,out,mink(D,mu)))
-> D * g(bis(D,a),bis(D,c))FORM source context: Trace4Gen tests repeated adjacent objects and puts the repeated pair into the accumulated delta list before recursing.
if ( *p == p[1] ) {
*(t->accup)++ = *p;
*(t->accup)++ = *p;
...
Trace4Gen(..., number-2)
}Source: https://github.com/form-dev/form/blob/master/sources/opera.c#L958-L972. Manual: https://www.nikhef.nl/~form/maindir/documentation/reference/html/manual.html#dx1-85012.
GammaLoop/idenso records the dimension contraction in its repeated-Lorentz chain patterns:
function!(GS.gamma_chain, ..., mink(d_,a_), ..., mink(d_,a_), ...)
-> function!(GS.gamma_chain, ...) * d_Assumptions: is the dimension attached to the Lorentz representation. Four-dimensional Chisholm rules below require .
G4. Trace closure with explicit bispinor contraction
Mathematical identity:
Pattern:
chain(bis(4,a),bis(4,a),
gamma(in,out,p(2,mink(4))),
gamma(in,out,mink(4,mu)),
gamma(in,out,p(3,mink(4))))
-> trace(bis(4),
gamma(in,out,p(2,mink(4))),
gamma(in,out,mink(4,mu)),
gamma(in,out,p(3,mink(4))))FORM source context: FORM trace4 and tracen operate on a spin line, represented internally as a string of gamma matrices. Trace4 copies that string into t->inlist and then dispatches to Trace4Gen.
t->inlist = AT.WorkPointer;
...
for ( i = 0; i < number; i++ ) *p++ = *m++;
...
ret = Trace4Gen(...);Source: https://github.com/form-dev/form/blob/master/sources/opera.c#L730-L745, https://github.com/form-dev/form/blob/master/sources/opera.c#L820-L823. Manual: https://www.nikhef.nl/~form/maindir/documentation/reference/html/manual.html#dx1-85012.
GammaLoop/idenso closes chains when the endpoints agree:
replace(function!(GS.gamma_chain, RS.a__, RS.x_, RS.x_).to_pattern())
.repeat()
.with(function!(GS.gamma_trace, RS.a__).to_pattern())G5. Odd and even trace recursion
Odd trace without gamma-five:
Two-gamma trace:
Recursive even trace:
FORM source context:
if ( ( number < 0 ) || ( number & 1 ) ) return(0);
...
if ( number == 2 ) { *kron++ = *t->inlist; *kron++ = t->inlist[1]; }Source: https://github.com/form-dev/form/blob/master/sources/opera.c#L424-L432. The recursive trace generator comments describe zero- and two-gamma terminal cases before general recursion: https://github.com/form-dev/form/blob/master/sources/opera.c#L830-L856. Manual: https://www.nikhef.nl/~form/maindir/documentation/reference/html/manual.html#dx1-85012.
Symbolica + spenso pattern:
trace(bis(4),
gamma(in,out,mink(4,mu)),
gamma(in,out,mink(4,nu)))
-> 4 * g(mink(4,mu),mink(4,nu))Dummy-index freshness: recursive trace replacement removes the paired Lorentz argument and must not reuse bound labels introduced by metric contractions.
G6. Four-dimensional Chisholm reductions
Odd interior:
Even interior:
Special two-interior case:
FORM source comment:
g(mu)*g(a1)*...*g(an)*g(mu)=
n=odd: -2*g(an)*...*g(a1)
n=even: 2*g(an)*g(a1)*...*g(a(n-1))
+2*g(a(n-1))*...*g(a1)*g(an)
There is a special case for n=2 : 4*d(a1,a2)*giSource: https://github.com/form-dev/form/blob/master/sources/opera.c#L670-L680. Implementation odd contraction: https://github.com/form-dev/form/blob/master/sources/opera.c#L978-L1012. Implementation even contraction: https://github.com/form-dev/form/blob/master/sources/opera.c#L1021-L1096, https://github.com/form-dev/form/blob/master/sources/opera.c#L1118-L1157. Manual: https://www.nikhef.nl/~form/maindir/documentation/reference/html/manual.html#dx1-85012.
Pattern:
chain(bis(4,a),bis(4,d),
gamma(in,out,mink(4,mu)),
gamma(in,out,mink(4,nu1)),
gamma(in,out,mink(4,nu2)),
gamma(in,out,mink(4,nu3)),
gamma(in,out,mink(4,mu)))
-> -2 * chain(bis(4,a),bis(4,d),
gamma(in,out,mink(4,nu3)),
gamma(in,out,mink(4,nu2)),
gamma(in,out,mink(4,nu1)))Assumptions: The contracted Lorentz label must belong to a four-dimensional Lorentz representation. The source code checks dimension equality with 4 before applying the Chisholm branches.
G7. Gamma-five and epsilon rules
FORM trace4 uses the four-dimensional identity:
Source comment:
g_(j,mu)*g_(j,nu)*g_(j,ro)=e_(mu,nu,ro,si)*g5_(j)*g_(j,si)
+d_(mu,nu)*g_(j,ro)-d_(mu,ro)*g_(j,nu)+d_(nu,ro)*g_(j,mu)
which is for 4 dimensions only!Source: https://github.com/form-dev/form/blob/master/sources/opera.c#L320-L329. The gamma-five branch logic in trace generation is at https://github.com/form-dev/form/blob/master/sources/opera.c#L480-L489 and https://github.com/form-dev/form/blob/master/sources/opera.c#L808-L813. Manual: https://www.nikhef.nl/~form/maindir/documentation/reference/html/manual.html#dx1-85012.
Pattern:
chain(bis(4,a),bis(4,b),
gamma(in,out,mink(4,mu)),
gamma(in,out,mink(4,nu)),
gamma(in,out,mink(4,rho)))
-> epsilon(mink(4,mu),mink(4,nu),mink(4,rho),mink(4,sigma))
* chain(bis(4,a),bis(4,b),
gamma5(in,out),
gamma(in,out,mink(4,sigma)))
+ g(mink(4,mu),mink(4,nu)) * chain(... gamma(rho) ...)
- g(mink(4,mu),mink(4,rho)) * chain(... gamma(nu) ...)
+ g(mink(4,nu),mink(4,rho)) * chain(... gamma(mu) ...)This is explicitly four-dimensional and requires a fresh dummy Lorentz label sigma.
Color-algebra replacement rules from color.h
Overview
| Rule | Convention | Purpose |
|---|---|---|
| Line joining | T(i,j,?a) | Join open noncommutative color lines. |
| Trace closure | cOlTr, cOlTt | Convert closed lines to trace blocks and choose trace blocks to simplify. |
| Casimir reduction | cR, cA | Remove repeated adjacent or separated generators in traces. |
| Trace normalization | I2R | Evaluate two-generator trace. |
| Structure constants | f antisymmetric | Contract small f loops and rewrite larger loops through invariants. |
| Symmetric invariants | cOldR, cOldA | Represent and contract generalized d tensors. |
simpli strategy | procedure | Eliminate f tensors in environments of invariants using generalized Jacobi moves. |
C1. Open color-line joining
Mathematical identity:
FORM source:
repeat id T(cOli1?,cOli2?,?a)*T(cOli2?,cOli3?,?b) = T(cOli1,cOli3,?a,?b);
id T(cOli1?,cOli1?,?a) = cOlTr(?a);Source package lines: color.h lines 91–93 at https://www.nikhef.nl/~form/maindir/packages/color/color.h. Package documentation: https://www.nikhef.nl/~form/maindir/packages/color/color.html. No official GitHub line anchor was found for color.h; see the validation appendix.
Pattern:
chain(cof(Nc,i),dind(cof(Nc,j)),
t(coad(Nc^2-1,a1),in,out),
t(coad(Nc^2-1,a2),in,out))
*
chain(cof(Nc,j),dind(cof(Nc,k)),
t(coad(Nc^2-1,b1),in,out))
-> chain(cof(Nc,i),dind(cof(Nc,k)),
t(coad(Nc^2-1,a1),in,out),
t(coad(Nc^2-1,a2),in,out),
t(coad(Nc^2-1,b1),in,out))C2. Trace closure and trace normalization
Closed line:
One generator:
Two generators:
FORM source:
id cOlTt(cOli1?) = 0;
id cOlTt(cOli1?,cOli2?) = I2R*d_(cOli1,cOli2);
id cOlTt(cOli1?,cOli2?,cOli3?) = cOldR(...) + i_/2*f(...)*I2R;Source package lines: color.h lines 459–461 at https://www.nikhef.nl/~form/maindir/packages/color/color.h. Package documentation: https://www.nikhef.nl/~form/maindir/packages/color/color.html.
Pattern:
chain(cof(Nc,i),dind(cof(Nc,i)),
t(coad(Nc^2-1,a),in,out),
t(coad(Nc^2-1,b),in,out))
-> trace(cof(Nc),
t(coad(Nc^2-1,a),in,out),
t(coad(Nc^2-1,b),in,out))
-> TR * g(coad(Nc^2-1,a),coad(Nc^2-1,b))C3. Fundamental Casimir and adjacent contractions
Mathematical identities:
FORM source:
id cOlTr(cOli1?,cOli1?,?a) = cR*cOlTr(?a);
id cOlTr(cOli1?,cOli2?,cOli1?,?a) = [cR-cA/2]*cOlTr(cOli2,?a);Source package lines: color.h lines 108–111 at https://www.nikhef.nl/~form/maindir/packages/color/color.h, repeated for cOlTt at lines 173–175. Package documentation: https://www.nikhef.nl/~form/maindir/packages/color/color.html.
Pattern:
chain(cof(Nc,i),dind(cof(Nc,k)),
t(coad(Nc^2-1,a),in,out),
t(coad(Nc^2-1,a),in,out))
-> C_F * g(cof(Nc,i),dind(cof(Nc,k)))Assumptions: color.h keeps C_F as cR, not automatically as .
C4. Fundamental Fierz generator contraction
Mathematical identity:
This identity is not written in this explicit form in color.h, whose main algorithm uses trace joining and invariant reductions. It is implemented directly in GammaLoop/idenso:
t(e,a,b) * t(e,c,d)
-> TR * (id(a,d) * id(c,b) - id(a,b) * id(c,d) / Nc)Source: https://github.com/alphal00p/gammaloop/blob/e51747446aa724c3ffac5c42c4103d090c09c6b0/crates/idenso/src/color/mod.rs#L407-L414. Symbolica documentation for replacement mechanics: https://symbolica.io/docs/pattern_matching.html.
Pattern:
t(coad(Nc^2-1,a),cof(Nc,i),dind(cof(Nc,j)))
* t(coad(Nc^2-1,a),cof(Nc,k),dind(cof(Nc,l)))
-> TR * (
g(cof(Nc,i),dind(cof(Nc,l)))
* g(cof(Nc,k),dind(cof(Nc,j)))
- g(cof(Nc,i),dind(cof(Nc,j)))
* g(cof(Nc,k),dind(cof(Nc,l))) / Nc)C5. Structure-constant loop contractions
Mathematical identities:
FORM source:
ReplaceLoop,f,a=3,l<4,outfun=cOlff;
id cOlff(cOli1?,cOli2?) = -cA*d_(cOli1,cOli2);
id cOlff(cOli1?,cOli2?,cOli3?) = cA/2*f(cOli1,cOli2,cOli3);Source package lines: color.h lines 148–150, 208–210, 505–507, and 538–541 at https://www.nikhef.nl/~form/maindir/packages/color/color.h. Package documentation: https://www.nikhef.nl/~form/maindir/packages/color/color.html.
Pattern:
f(coad(Nc^2-1,a),coad(Nc^2-1,c),coad(Nc^2-1,d))
* f(coad(Nc^2-1,b),coad(Nc^2-1,c),coad(Nc^2-1,d))
-> ca * g(coad(Nc^2-1,a),coad(Nc^2-1,b))Sign note: FORM’s ReplaceLoop loop orientation produces -cA*d_(...) for the two-argument cyclic helper. The standard identity above assumes the displayed orientation .
C6. Mixed trace–structure contraction
Mathematical identity:
FORM source:
id cOlTr(cOli1?,cOli2?,?a)*f(cOli1?,cOli2?,cOli3?) =
i_*cA/2*cOlTr(cOli3,?a);Source package lines: color.h lines 108–111 and 173–175 at https://www.nikhef.nl/~form/maindir/packages/color/color.h. Package documentation: https://www.nikhef.nl/~form/maindir/packages/color/color.html.
Pattern:
trace(cof(Nc),
t(coad(Nc^2-1,a),in,out),
t(coad(Nc^2-1,b),in,out),
rest__)
* f(coad(Nc^2-1,a),coad(Nc^2-1,b),coad(Nc^2-1,c))
-> i_ * ca / 2 * trace(cof(Nc),
t(coad(Nc^2-1,c),in,out),
rest__)C7. Symmetric invariant contractions
color.h uses cOldR and cOldA for symmetric invariant tensors and reduces contractions to named invariants such as d33, d44, and d55.
Representative identities:
FORM source:
id cOldr1?cOldar[cOlx3](cOli1?,cOli2?,cOli3?)
*cOldr2?cOldar[cOlx4](cOli1?,cOli2?,cOli4?)
= d33(...)*cOlx1*d_(cOli3,cOli4)/NA;
...
id cOldr1?cOldar[cOlx3](cOli1?,...,cOli3?)
*cOldr2?cOldar[cOlx4](cOli1?,...,cOli3?) = d33(...);Source package lines: color.h lines 1287–1294 and 1316–1335 at https://www.nikhef.nl/~form/maindir/packages/color/color.h. Package documentation: https://www.nikhef.nl/~form/maindir/packages/color/color.html.
Pattern:
d(sym_rep_x,coad(Nc^2-1,a),coad(Nc^2-1,b),coad(Nc^2-1,c))
* d(sym_rep_y,coad(Nc^2-1,a),coad(Nc^2-1,b),coad(Nc^2-1,d))
-> d33(sym_rep_x,sym_rep_y)
* g(coad(Nc^2-1,c),coad(Nc^2-1,d)) / (Nc^2 - 1)Assumptions: The package treats these as group-invariant placeholders rather than expanding them into polynomials.
C8. simpli and generalized Jacobi strategy
simpli is an implementation strategy, not one scalar identity. It eliminates pairs of structure constants in environments of symmetric invariants and applies generalized Jacobi transformations.
FORM source:
* Procedure tries to eliminate f tensors in an environment of invariants.
* Apply the generalized Jacobi identity ...
if ( count(f,1) != multipleof(2) ) discard;
#call contract
...
id f(cOlpR`isimpli',cOli1?,cOli3?)*f(cOlpR`isimpli',cOli2?,cOli3?) =
cOlpR`isimpli'(cOli1)*cOlpR`isimpli'(cOli2)*cA/2;Source package lines: color.h lines 688–713 at https://www.nikhef.nl/~form/maindir/packages/color/color.h. Package documentation: https://www.nikhef.nl/~form/maindir/packages/color/color.html.
Pattern family:
f(coad(Nc^2-1,x),coad(Nc^2-1,a),coad(Nc^2-1,c))
* f(coad(Nc^2-1,x),coad(Nc^2-1,b),coad(Nc^2-1,c))
* invariant_environment__
-> ca / 2 * projected_invariant(a,b,invariant_environment__)This rule class requires canonicalization of symmetric invariants and freshness of all auxiliary adjoint labels introduced during generalized Jacobi expansion.
Symbolica and Spenso rewrite patterns
This section is written for a Rust implementation with Symbolica as a dependency. Symbolica’s Rust id module exposes pattern matching through AtomCore::replace, AtomCore::pattern_match, Replacement, MatchSettings, and ReplaceBuilder; complex right-hand sides can be built with ReplaceBuilder::with_map or with replace_map callbacks. See https://docs.rs/symbolica/latest/symbolica/id/index.html and https://docs.rs/symbolica/latest/symbolica/id/struct.ReplaceBuilder.html. spenso represents tensor slots through symbolic structures and representation slots; the crate documents tensor structures, symbolic tensors, and contraction support at https://docs.rs/spenso/latest/spenso/, with symbolic tensor-library keys in https://docs.rs/spenso/latest/src/spenso/network/library/symbolic.rs.html.
Symbolica wildcard convention: x_ is one atom, x__ is one-or-more atoms, and x___ is zero-or-more atoms. Function argument order is preserved for non-symmetric functions. Repeated wildcard names require exact structural equality; this is the right mechanism for repeated dummy labels such as mu_ or a_.
The public target syntax for this specification is chain(...) and trace(...). If implemented inside GammaLoop/idenso, the current internal Rust symbols are spenso::gamma_chain and spenso::gamma_trace; those should be adapter names only, not the public pattern vocabulary. The approved surface form remains:
chain(bis(4,a),bis(4,c),
gamma(in,out,p(2,mink(4))),
gamma(in,out,mink(4,mu)))Rust pattern construction guidelines
Use concrete spenso builders for tensor slots where available and Symbolica wildcards only for the abstract labels. This keeps representation constraints attached to the pattern.
use symbolica::{
atom::{Atom, AtomCore, AtomView, FunctionBuilder, Symbol},
function, symbol,
id::{Match, MatchSettings, Pattern, Replacement},
utils::Settable,
};Implementation rules:
- Use
Replacement::new(lhs.to_pattern(), rhs.to_pattern())for local structural rules whose right side is another static pattern. - Use
replace_multiple_intoin a loop for FORM-style short-circuit passes where rule order matters and each pass should be followed by expansion and metric simplification. - Use
replace_maporReplaceBuilder::with_mapfor Chisholm parity, sequence reversal, trace recursion,ReplaceLoop-style loop detection, cyclic color traces, and fresh dummy allocation. - Add
MatchSettings { rhs_cache_size: 0, ..Default::default() }for replacement maps whose right side depends on match-local fresh symbols. - Keep
chainandtracenon-symmetric. Their argument order is algebraically meaningful.
Gamma collection patterns
Mathematical identity: Equation 2. Source: https://github.com/alphal00p/gammaloop/blob/e51747446aa724c3ffac5c42c4103d090c09c6b0/crates/idenso/src/dirac/mod.rs#L604-L613.
Raw gamma pair:
gamma(bis(d_,a_),bis(d_,b_),x_)
* gamma(bis(d_,b_),bis(d_,c_),y_)
-> chain(bis(d_,a_),bis(d_,c_),
gamma(in,out,x_),
gamma(in,out,y_))Append and prepend raw gamma factors:
chain(bis(d_,a_),bis(d_,b_),xs___)
* gamma(bis(d_,b_),bis(d_,c_),y_)
-> chain(bis(d_,a_),bis(d_,c_),xs___,gamma(in,out,y_))
gamma(bis(d_,a_),bis(d_,b_),x_)
* chain(bis(d_,b_),bis(d_,c_),ys___)
-> chain(bis(d_,a_),bis(d_,c_),gamma(in,out,x_),ys___)Join two chains:
chain(bis(d_,a_),bis(d_,b_),xs___)
* chain(bis(d_,b_),bis(d_,c_),ys___)
-> chain(bis(d_,a_),bis(d_,c_),xs___,ys___)Orientation case:
chain(bis(d_,a_),bis(d_,b_),xs___)
* chain(bis(d_,c_),bis(d_,b_),ys___)
-> chain(bis(d_,a_),bis(d_,c_),xs___,reverse_flip(ys___))reverse_flip is not a plain Symbolica replacement. Build it in Rust by reading the matched ys___ argument list, reversing the entries, and swapping in and out in each tensor factor.
Gamma terminal and trace patterns
Mathematical identity: Equation 5.
chain(bis(d_,a_),bis(d_,a_),xs___)
-> trace(bis(d_),xs___)
trace(bis(d_),gamma(in,out,x_))
-> 0
trace(bis(4),
gamma(in,out,mink(4,mu_)),
gamma(in,out,mink(4,nu_)))
-> 4 * g(mink(4,mu_),mink(4,nu_))Adjacent repeated Lorentz object:
chain(bis(d_,a_),bis(d_,b_),
xs___,
gamma(in,out,mink(d_,mu_)),
gamma(in,out,mink(d_,mu_)),
ys___)
-> d_ * chain(bis(d_,a_),bis(d_,b_),xs___,ys___)GammaLoop/idenso currently has the equivalent repeated-object contraction in Rust at https://github.com/alphal00p/gammaloop/blob/e51747446aa724c3ffac5c42c4103d090c09c6b0/crates/idenso/src/dirac/mod.rs#L784-L829 and trace closure at https://github.com/alphal00p/gammaloop/blob/e51747446aa724c3ffac5c42c4103d090c09c6b0/crates/idenso/src/dirac/mod.rs#L877-L879. FORM’s corresponding short-circuit in Trace4Gen removes adjacent equal objects before deeper recursion; source https://github.com/form-dev/form/blob/master/sources/opera.c#L958-L972.
Gamma Chisholm and trace recursion builders
Mathematical identities: Equation 9, Equation 10, and Equation 8. Source: https://github.com/form-dev/form/blob/master/sources/opera.c#L670-L680, https://github.com/form-dev/form/blob/master/sources/opera.c#L978-L1012, https://github.com/form-dev/form/blob/master/sources/opera.c#L1021-L1096, https://github.com/form-dev/form/blob/master/sources/opera.c#L1118-L1157.
Match contracted endpoints in four dimensions:
chain(bis(4,a_),bis(4,b_),
gamma(in,out,mink(4,mu_)),
middle___,
gamma(in,out,mink(4,mu_)))Rust-side builder:
fn build_chisholm(middle: &[Atom], a: Atom, b: Atom) -> Option<Atom> {
if !all_gamma_factors(middle) {
return None;
}
match middle.len() {
n if n % 2 == 1 => {
Some(-Atom::num(2) * chain(a, b, reverse(middle)))
}
2 => {
let (x, y) = lorentz_pair(&middle[0], &middle[1])?;
Some(Atom::num(4) * g(x, y) * bis_id(a, b))
}
n if n % 2 == 0 => {
Some(Atom::num(2) * chain(a.clone(), b.clone(), move_last_to_front(middle))
+ Atom::num(2) * chain(a, b, reverse_except_last_then_last(middle)))
}
_ => None,
}
}Trace recursion should also be a Rust-side builder, not a static RHS:
trace(bis(4),first_,rest___)Builder rule: if the trace length is odd, return zero. If the length is two, return 4 * g(first, second). Otherwise sum over all pairings of first_ with one later gamma, alternating signs and recursively rebuilding trace(bis(4), ...). This mirrors the source branch that uses zero/two-gamma terminals and then recursive generation; see https://github.com/form-dev/form/blob/master/sources/opera.c#L424-L432 and https://github.com/form-dev/form/blob/master/sources/opera.c#L830-L856.
Color collection patterns
Mathematical identity: Equation 13.
Raw generator pair:
t(coad(na_,a_),cof(nc_,i_),dind(cof(nc_,j_)))
* t(coad(na_,b_),cof(nc_,j_),dind(cof(nc_,k_)))
-> chain(cof(nc_,i_),dind(cof(nc_,k_)),
t(coad(na_,a_),in,out),
t(coad(na_,b_),in,out))Join chains:
chain(cof(nc_,i_),dind(cof(nc_,j_)),xs___)
* chain(cof(nc_,j_),dind(cof(nc_,k_)),ys___)
-> chain(cof(nc_,i_),dind(cof(nc_,k_)),xs___,ys___)Opposite endpoint orientation:
chain(cof(nc_,i_),dind(cof(nc_,j_)),xs___)
* chain(cof(nc_,k_),dind(cof(nc_,j_)),ys___)
-> chain(cof(nc_,i_),dind(cof(nc_,k_)),xs___,reverse_flip(ys___))The first two rules correspond to color.h line joining and trace closure at package lines 91–93. GammaLoop/idenso’s current direct color simplifier starts from raw spenso::t and spenso::f patterns; source https://github.com/alphal00p/gammaloop/blob/e51747446aa724c3ffac5c42c4103d090c09c6b0/crates/idenso/src/color/mod.rs#L360-L414.
Color trace and Casimir patterns
Mathematical identity: Equation 14 and Equation 16.
chain(cof(nc_,i_),dind(cof(nc_,i_)),xs___)
-> trace(cof(nc_),xs___)
trace(cof(nc_),t(coad(na_,a_),in,out))
-> 0
trace(cof(nc_),
t(coad(na_,a_),in,out),
t(coad(na_,b_),in,out))
-> TR * g(coad(na_,a_),coad(na_,b_))
trace(cof(nc_),
t(coad(na_,a_),in,out),
t(coad(na_,b_),in,out),
t(coad(na_,c_),in,out))
-> dR(coad(na_,a_),coad(na_,b_),coad(na_,c_))
+ i_ / 2 * TR * f(coad(na_,a_),coad(na_,b_),coad(na_,c_))Casimir and separated-generator shortcuts:
chain(cof(nc_,i_),dind(cof(nc_,k_)),
xs___,
t(coad(na_,a_),in,out),
t(coad(na_,a_),in,out),
ys___)
-> CF * chain(cof(nc_,i_),dind(cof(nc_,k_)),xs___,ys___)
trace(cof(nc_),
t(coad(na_,a_),in,out),
t(coad(na_,b_),in,out),
t(coad(na_,a_),in,out),
xs___)
-> (CF - CA / 2) * trace(cof(nc_),t(coad(na_,b_),in,out),xs___)Source: color.h selected-trace terminal rules at lines 459–464 and easy contraction rules at lines 108–111 and 173–175.
Color structure-constant and invariant patterns
Structure-constant contractions:
f(coad(na_,a_),coad(na_,c_),coad(na_,d_))
* f(coad(na_,b_),coad(na_,c_),coad(na_,d_))
-> CA * g(coad(na_,a_),coad(na_,b_))
f(coad(na_,a_),coad(na_,b_),coad(na_,e_))
* f(coad(na_,b_),coad(na_,c_),coad(na_,f_))
* f(coad(na_,c_),coad(na_,a_),coad(na_,g_))
-> CA / 2 * f(coad(na_,e_),coad(na_,f_),coad(na_,g_))Trace–structure shortcut:
trace(cof(nc_),
t(coad(na_,a_),in,out),
t(coad(na_,b_),in,out),
xs___)
* f(coad(na_,a_),coad(na_,b_),coad(na_,c_))
-> i_ * CA / 2 * trace(cof(nc_),t(coad(na_,c_),in,out),xs___)Symmetric-invariant contraction:
d(sym_x_,coad(na_,a_),coad(na_,b_),coad(na_,c_))
* d(sym_y_,coad(na_,a_),coad(na_,b_),coad(na_,d_))
-> d33(sym_x_,sym_y_) * g(coad(na_,c_),coad(na_,d_)) / na_f must be registered or canonicalized as antisymmetric. Symbolica’s documentation warns that antisymmetric functions canonicalize written patterns; implementers should either use canonical argument order in the pattern or absorb the sign in a pre-canonicalization pass. Source for small f loop reductions: color.h lines 148–150, 208–210, 505–507, and 537–541. Source for d33 and higher invariant contractions: color.h lines 1287–1348.
FORM short-circuit rewrite order
These are the high-priority short-circuit patterns FORM uses before falling back to expensive generic recursion.
Gamma trace4 short-circuit order:
- Reject impossible input: negative number, odd number, or missing spin-line parameter returns zero. Source https://github.com/form-dev/form/blob/master/sources/opera.c#L715-L717.
- Resolve zero- and two-gamma traces before recursion; gamma-five can force zero. Source https://github.com/form-dev/form/blob/master/sources/opera.c#L424-L432 and https://github.com/form-dev/form/blob/master/sources/opera.c#L867-L875.
- Remove adjacent equal objects before Chisholm scans. Source https://github.com/form-dev/form/blob/master/sources/opera.c#L958-L972.
- Try four-dimensional odd Chisholm contraction first. Source https://github.com/form-dev/form/blob/master/sources/opera.c#L978-L1012.
- Try four-dimensional even Chisholm contraction, with a special two-interior case before the longer case. Source https://github.com/form-dev/form/blob/master/sources/opera.c#L1021-L1096 and https://github.com/form-dev/form/blob/master/sources/opera.c#L1118-L1157.
- Search same objects by shortest cyclic distance and emit alternating recursive terms. Source https://github.com/form-dev/form/blob/master/sources/opera.c#L1168-L1232.
- If all objects are different, fall back to
Trace4no; the three-gamma epsilon trick is part of the four-dimensional branch. Source https://github.com/form-dev/form/blob/master/sources/opera.c#L320-L329 and https://github.com/form-dev/form/blob/master/sources/opera.c#L1240-L1244.
Color color.h short-circuit order:
- Join open color lines and close equal endpoints before any trace selection. Source
color.hlines 91–93. - Skip the main trace route unless at least one closed trace exists. Source
color.hlines 95–103. - Apply easy trace contractions first: adjacent equal generator, separated
a b a, and trace timesf(a,b,c). Sourcecolor.hlines 108–111 and 173–175. - Rewrite duplicated trace blocks of lengths four, three, and two before general expansion. Source
color.hlines 112–147 and 178–207. - Collapse small
floops viaReplaceLoop: two-leg and three-leg loops are terminal. Sourcecolor.hlines 148–150, 208–210, 505–507, 537–541, and 672–676. - Select the trace with the fewest different indices by wrapping traces in
cOlTT. Sourcecolor.hlines 156–163. - Use terminal selected-trace rules for one, two, three, and four generators before converting longer traces back to
T. Sourcecolor.hlines 459–466. - In
simpli, discard oddfcounts, contract matching invariant-vectorf fpairs, then run generalized Jacobi/invariant passes. Sourcecolor.hlines 688–724. - Convert completed invariant-vector products into
d33,d44,d55, and higher invariants, and discard impossible overlap topologies. Sourcecolor.hlines 1258–1294 and 1316–1348.
Rust implementation note: implement the short-circuit order as ordered passes, not as one unordered replace_multiple containing every rule. FORM’s performance relies on reducing the expression before the broader searches are attempted.
FORM-side test cases in Symbolica/Spenso syntax
This section translates the compact FORM-side rule tests and the package example cases into the chain/trace notation used above. Expected values are written in the same symbolic convention: TR for I2R, CA for cA, CF for cR, and NA for adjoint dimension. The local validation used FORM 4.3.1 for the explicitly listed compact values.
Gamma trace tests
Source basis: FORM manual gamma algebra and trace4 implementation; see https://www.nikhef.nl/~form/maindir/documentation/reference/html/manual.html#dx1-85012, https://github.com/form-dev/form/blob/master/sources/opera.c#L424-L432, and https://github.com/form-dev/form/blob/master/sources/opera.c#L867-L875.
// FORM: g_(1,mu,nu); trace4,1;
trace(bis(4),
gamma(in,out,mink(4,mu)),
gamma(in,out,mink(4,nu)))
-> 4 * g(mink(4,mu),mink(4,nu))
// FORM: g_(1,mu,nu,rho); trace4,1;
trace(bis(4),
gamma(in,out,mink(4,mu)),
gamma(in,out,mink(4,nu)),
gamma(in,out,mink(4,rho)))
-> 0
// FORM: g_(1,mu,nu,rho,sigma); trace4,1;
trace(bis(4),
gamma(in,out,mink(4,mu)),
gamma(in,out,mink(4,nu)),
gamma(in,out,mink(4,rho)),
gamma(in,out,mink(4,sigma)))
-> 4 * g(mink(4,mu),mink(4,nu)) * g(mink(4,rho),mink(4,sigma))
- 4 * g(mink(4,mu),mink(4,rho)) * g(mink(4,nu),mink(4,sigma))
+ 4 * g(mink(4,mu),mink(4,sigma)) * g(mink(4,nu),mink(4,rho))Chisholm and adjacent-contraction chain tests:
// FORM manual: g_(1,mu,mu) = gi_(1)*d_(mu,mu).
chain(bis(d,a),bis(d,b),
gamma(in,out,mink(d,mu)),
gamma(in,out,mink(d,mu)))
-> d * g(bis(d,a),bis(d,b))
// FORM manual, four-dimensional odd interior.
chain(bis(4,a),bis(4,b),
gamma(in,out,mink(4,mu)),
gamma(in,out,mink(4,nu1)),
gamma(in,out,mink(4,nu2)),
gamma(in,out,mink(4,nu3)),
gamma(in,out,mink(4,mu)))
-> -2 * chain(bis(4,a),bis(4,b),
gamma(in,out,mink(4,nu3)),
gamma(in,out,mink(4,nu2)),
gamma(in,out,mink(4,nu1)))
// FORM manual, four-dimensional two-interior special case.
chain(bis(4,a),bis(4,b),
gamma(in,out,mink(4,mu)),
gamma(in,out,mink(4,nu)),
gamma(in,out,mink(4,rho)),
gamma(in,out,mink(4,mu)))
-> 4 * g(mink(4,nu),mink(4,rho)) * g(bis(4,a),bis(4,b))Gamma-five epsilon test:
// FORM Trick identity in opera.c.
chain(bis(4,a),bis(4,b),
gamma(in,out,mink(4,mu)),
gamma(in,out,mink(4,nu)),
gamma(in,out,mink(4,rho)))
-> epsilon(mink(4,mu),mink(4,nu),mink(4,rho),mink(4,sigma))
* chain(bis(4,a),bis(4,b),
gamma5(in,out),
gamma(in,out,mink(4,sigma)))
+ g(mink(4,mu),mink(4,nu))
* chain(bis(4,a),bis(4,b),gamma(in,out,mink(4,rho)))
- g(mink(4,mu),mink(4,rho))
* chain(bis(4,a),bis(4,b),gamma(in,out,mink(4,nu)))
+ g(mink(4,nu),mink(4,rho))
* chain(bis(4,a),bis(4,b),gamma(in,out,mink(4,mu)))FORM manual gamma-five stress examples:
// FORM: symmetric trace of gamma5 and 12 regular matrices via distrib_ and tracen.
g5_trace_symmetric_12(m1,...,m12)
-> 51975 terms
// FORM: regular trace g_(1,5_,m1,...,m12); trace4,1.
trace(bis(4),gamma5(in,out),gamma(in,out,mink(4,m1)),...,gamma(in,out,mink(4,m12)))
-> 1029 output terms after FORM trace4These are term-count regression tests from the manual, not compact algebraic values.
Compact color-rule tests
Source basis: color.h line joining, selected trace terminals, and small f loops; see https://www.nikhef.nl/~form/maindir/packages/color/color.h, especially lines 91–93, 459–464, and 505–507.
// FORM: T(i1,i1,a)
chain(cof(Nc,i),dind(cof(Nc,i)),
t(coad(NA,a),in,out))
-> 0
// FORM: T(i1,i1,a,b)
chain(cof(Nc,i),dind(cof(Nc,i)),
t(coad(NA,a),in,out),
t(coad(NA,b),in,out))
-> TR * g(coad(NA,a),coad(NA,b))
// FORM: T(i1,i1,a,b,c)
chain(cof(Nc,i),dind(cof(Nc,i)),
t(coad(NA,a),in,out),
t(coad(NA,b),in,out),
t(coad(NA,c),in,out))
-> dR(coad(NA,a),coad(NA,b),coad(NA,c))
+ i_ / 2 * TR * f(coad(NA,a),coad(NA,b),coad(NA,c))// FORM: f(a,c,d)*f(b,c,d)
f(coad(NA,a),coad(NA,c),coad(NA,d))
* f(coad(NA,b),coad(NA,c),coad(NA,d))
-> CA * g(coad(NA,a),coad(NA,b))
// FORM: f(a,b,e)*f(b,c,f)*f(c,a,g)
f(coad(NA,a),coad(NA,b),coad(NA,e))
* f(coad(NA,b),coad(NA,c),coad(NA,f))
* f(coad(NA,c),coad(NA,a),coad(NA,g))
-> CA / 2 * f(coad(NA,e),coad(NA,f),coad(NA,g))Four-generator trace terminal:
trace(cof(Nc),
t(coad(NA,a),in,out),
t(coad(NA,b),in,out),
t(coad(NA,c),in,out),
t(coad(NA,d),in,out))
-> dR(coad(NA,a),coad(NA,b),coad(NA,c),coad(NA,d))
+ i_ / 2 * (
dR(coad(NA,a),coad(NA,b),coad(NA,x))
* f(coad(NA,c),coad(NA,d),coad(NA,x))
+ dR(coad(NA,c),coad(NA,d),coad(NA,x))
* f(coad(NA,a),coad(NA,b),coad(NA,x)))
- TR / 6 * f(coad(NA,a),coad(NA,c),coad(NA,x))
* f(coad(NA,b),coad(NA,d),coad(NA,x))
+ TR / 3 * f(coad(NA,a),coad(NA,d),coad(NA,x))
* f(coad(NA,b),coad(NA,c),coad(NA,x))FORM color.tar.gz example families
The color package page links color.tar.gz as “some FORM programs that use color.h”; see https://www.nikhef.nl/~form/maindir/packages/color/color.html and https://www.nikhef.nl/~form/maindir/packages/color/color.tar.gz. The example programs define source-side graph families. The following schematics preserve their topology in Symbolica/spenso notation.
tloop.frm cases:
// TYPE = qloop, SIZE = n.
chain(cof(Nc,i1),dind(cof(Nc,i1)),
t(coad(NA,j1),in,out),...,t(coad(NA,jn),in,out),
t(coad(NA,j1),in,out),...,t(coad(NA,jn),in,out))
// For SIZE = 3, FORM color+simpli expected:
Q6 -> NA * TR * CF^2 - 3/2 * NA * TR * CA * CF + 1/2 * NA * TR * CA^2
// TYPE = gloop, SIZE = n.
f(coad(NA,k1),coad(NA,k2),coad(NA,j1)) * ...
* f(coad(NA,k(2 n)),coad(NA,k1),coad(NA,jn))
// For SIZE = 3:
G6 -> 0
// TYPE = qqloop, SIZE = n: two fundamental loops linked by adjoint labels.
trace(cof(Nc),t(j1),...,t(jn)) * trace(cof(Nc),t(j1),...,t(jn))
// For SIZE = 3:
QQ3 -> -1/4 * NA * TR^2 * CA + d33(R1,R2)
// TYPE = qgloop, SIZE = n: one fundamental loop and one adjoint loop.
trace(cof(Nc),t(j1),...,t(jn)) * adjoint_loop(j1,...,jn)
// For SIZE = 3:
QG3 -> i_ / 4 * NA * TR * CA^2
// TYPE = ggloop, SIZE = n: two linked adjoint loops.
adjoint_loop(j1,...,jn) * adjoint_loop(j1,...,jn)
// For SIZE = 3:
GG3 -> 1/4 * NA * CA^3Fixed graph examples:
// TYPE = g14: Coxeter graph with 14 trivalent adjoint vertices.
g14 -> 1/648 * NA * CA^7
- 8/15 * d444(A1,A2,A3) * CA
+ 16/9 * d644(A1,A2,A3)
// TYPE = fiveq: five linked quark loops.
fiveq -> 1/192 * NA * TR^5 * CA^3
+ 1/4 * d33(R1,R2) * TR^3 * CA^2
+ 5/48 * d33(R1,R2) * d33(R3,R4) * NA^-1 * TR * CA
+ 5/48 * d33(R1,R3) * d33(R2,R4) * NA^-1 * TR * CA
+ 1/8 * d33(R1,R4) * d33(R2,R3) * NA^-1 * TR * CA
+ 1/16 * d44(R1,A1) * TR^4
+ 3/8 * d433(R3,R1,R2) * TR^2 * CA
+ 1/2 * d3333(R1,R2,R3,R4) * TR * CA
+ d43333a(R5,R2,R1,R4,R3)
// TYPE = g24 is a high-cost stress example in tloop.frm.
// No compact expected value is included in the package source; it is not a short unit test.su.frm examples using #call SUn:
// CASE = F3F3.
F3F3 -> 2*a^3*NF^-1 - 5/2*a^3*NF + 1/2*a^3*NF^3
// CASE = F4F4.
F4F4 -> -3*a^4*nf^2*NF^-2 + 4*a^4*nf^2
- 7/6*a^4*nf^2*NF^2 + 1/6*a^4*nf^2*NF^4
// CASE = F4A4.
F4A4 -> -2*a^4*nf*NF + 5/3*a^4*nf*NF^3 + 1/3*a^4*nf*NF^5
// CASE = A4A4.
A4A4 -> -24*a^4*NF^2 + 70/3*a^4*NF^4 + 2/3*a^4*NF^6
// CASE = FnFn with n = 3.
F3F3 -> 2*a^3*nf^2*NF^-1 - 2*a^3*nf^2*NF
// CASE = FnAn with n = 3.
F3A3 -> -i_*a^3*nf*NF^2 + i_*a^3*nf*NF^4
// CASE = AnAn with n = 3.
A3A3 -> -2*a^3*NF^3 + 2*a^3*NF^5
// CASE = qloop with n = 3.
Q6 -> -a^3*nf*NF^-2 + a^3*nf*NF^2
// CASE = gloop with n = 3.
G6 -> 0The SU checker procedure uses , , , and ; source SUn.prc lines 26–58.
Implementation caveats
- FORM’s four-dimensional gamma simplifications depend on index dimension checks in
Trace4Gen; applying them in dimension-generic algebra is wrong. trace4accepts gamma-five branches with special sign changes and gamma-six/gamma-seven toggles;tracenis dimension-generic and does not tolerate gamma-five variants.color.his group- and representation-invariant. It intentionally keeps symbols such ascR,cA,I2R,NA, and higherdinvariants rather than reducing all cases to .- The
simpliprocedure is a rewrite strategy over invariant environments. Its output depends on canonicalization choices and on theRANKbound. - Symbolica matching is syntactic. Sequence reversal, parity tests, fresh dummy generation, and antisymmetric signs require Rust-side construction or explicit pattern restrictions.
- The approved
chainandtracesyntax in this document is a target specification for tensor-pattern rules, not a claim that Symbolica ships built-in functions with those names.
Appendix: source map
Source snippets appear next to each detailed rule above. Symbolica/spenso pattern references are the code blocks in the corresponding detailed rule and in the Symbolica + spenso rewrite-pattern section.
Appendix: validation
Typst compile result
The pre-migration standalone source recorded this successful environment:
typst 0.14.2 (b33de9de)Its captured compilation command was:
typst compile form_gamma_color_rules_from_scratch.typ form_gamma_color_rules_from_scratch.pdfThat historical command succeeded and produced form_gamma_color_rules_from_scratch.pdf; the old filename is evidence, not the current source path. The maintained specification now builds through the Idenso product route and complete PDF with:
cargo run --locked -p alphal00p-docs-builder -- build --product idenso --channel latest --output /tmp/idenso-docs --skip-rustdocStatic checks
Checks captured against the pre-migration Typst filename:
rg -n '\b\x70rod\b' form_gamma_color_rules_from_scratch.typ
rg -n 'tr_[A-Za-z]+\(|Tr_[A-Za-z]+\(|op\("tr"\)_[A-Za-z]+\(' form_gamma_color_rules_from_scratch.typ
rg -n '#L[0-9]+' form_gamma_color_rules_from_scratch.typ
rg -n 'gamma_chain|gamma_trace' form_gamma_color_rules_from_scratch.typ
rg -n 'with_map|replace_map|FORM Short-Circuit' form_gamma_color_rules_from_scratch.typ
rg -n 'FORM-Side Test Cases|Q6 ->|F3F3 ->|g14 ->|fiveq ->' form_gamma_color_rules_from_scratch.typResults:
- No word token
\x70rodwas found; intended occurrences useproduct. - No subscripted trace operator was immediately attached to a parenthesized argument; trace calls use explicit spacing.
- GitHub line-anchor fragments were found for the FORM
opera.c, GammaLoop Dirac, and GammaLoop color source links.color.hrules cite exact package-source line numbers because no official GitHub-hostedcolor.hwas found inform-dev/form. - The internal names
spenso::gamma_chainandspenso::gamma_traceoccur only in source-code snippets or explanatory text documenting GammaLoop internals; target patterns usechainandtrace. - Rust-only operations that cannot be static Symbolica RHS patterns, including sequence reversal, parity checks, cyclic loop detection, and fresh-index creation, are assigned to
with_map,replace_map, or explicit Rust builders. - The FORM-side test-case section is present and contains expected values for compact gamma tests, compact color tests, and short
color.tar.gzexample instantiations.
Additional FORM checks used to populate the test-case section:
form -q /tmp/gamma-test.frm
form -q /tmp/color-trace.frm
form -q /tmp/color-short.frm
cd /tmp/form-color && form -q tloop-qloop.frm
cd /tmp/form-color && form -q tloop-gloop.frm
cd /tmp/form-color && form -q tloop-qqloop.frm
cd /tmp/form-color && form -q tloop-qgloop.frm
cd /tmp/form-color && form -q tloop-ggloop.frm
cd /tmp/form-color && form -q tloop-g14.frm
cd /tmp/form-color && form -q tloop-fiveq.frm
cd /tmp/form-color && form -q su-F3F3.frm
cd /tmp/form-color && form -q su-F4F4.frm
cd /tmp/form-color && form -q su-F4A4.frm
cd /tmp/form-color && form -q su-A4A4.frm
cd /tmp/form-color && form -q su-FnFn.frm
cd /tmp/form-color && form -q su-FnAn.frm
cd /tmp/form-color && form -q su-AnAn.frm
cd /tmp/form-color && form -q su-qloop.frm
cd /tmp/form-color && form -q su-gloop.frmUnresolved uncertainties
- The current official FORM GitHub repository contains
sources/opera.cbut not the legacycolor.hpackage file. The package page links the actual source. Therefore color rules cite exact package-source line numbers and the package source URL, but they do not have official GitHub line anchors. - The approved
chainandtracenotation is a specification-level Symbolica/spenso tensor-pattern notation. Exact Rust constructors for sequence reversal and parity-filtered Chisholm replacement must be implemented with Rust-side match processing.
References
- FORM manual gamma algebra: https://www.nikhef.nl/~form/maindir/documentation/reference/html/manual.html#dx1-85012.
- FORM
opera.c: https://github.com/form-dev/form/blob/master/sources/opera.c. - FORM
color.hpackage page: https://www.nikhef.nl/~form/maindir/packages/color/color.html. - FORM
color.hsource: https://www.nikhef.nl/~form/maindir/packages/color/color.h. - FORM
color.hexample programs: https://www.nikhef.nl/~form/maindir/packages/color/color.tar.gz. - GammaLoop/idenso Dirac implementation: https://github.com/alphal00p/gammaloop/blob/e51747446aa724c3ffac5c42c4103d090c09c6b0/crates/idenso/src/dirac/mod.rs.
- GammaLoop/idenso color implementation: https://github.com/alphal00p/gammaloop/blob/e51747446aa724c3ffac5c42c4103d090c09c6b0/crates/idenso/src/color/mod.rs.
- Symbolica pattern matching: https://symbolica.io/docs/pattern_matching.html.
- Symbolica Rust
idAPI: https://docs.rs/symbolica/latest/symbolica/id/index.html. - Symbolica Rust
ReplaceBuilder: https://docs.rs/symbolica/latest/symbolica/id/struct.ReplaceBuilder.html. - spenso crate documentation: https://docs.rs/spenso/latest/spenso/.
- spenso symbolic tensor-library source: https://docs.rs/spenso/latest/src/spenso/network/library/symbolic.rs.html.
- Typst syntax: https://typst.app/docs/reference/syntax/.
- Typst math: https://typst.app/docs/reference/math/.