1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
# Testing the DefaultRules system.
# Test 1: Basics
#
::PostDefaultRules(@@distribute!(%), @@collect_terms!(%)).
obj1:= (a+b)(c+d);
tst1:= a c + a d + b c + b d - @(obj1);
@assert(tst1);
# Test 2: More complicated
#
@reset;
\commutator{#}::IndexInherit.
::PreDefaultRules( @@substitute!(%)( [a?_{d?},b?_{e?}] -> \commutator{a?_{d?}}{b?_{e?}} ) ).
::PostDefaultRules(@@distribute!(%),
@@substitute!(%)( \commutator{x_i}{p_j} -> I*\delta_{i j} )).
obj2:= 3 [x_a, p_b] - 6 [x_a, x_b];
tst2:= 3 I \delta_{a b} - 6 [ x_{a}, x_{b} ] - @(obj2);
@collect_terms!(%);
@assert(tst2);
# Test 3: The example from gamma.cdb, from section 4.7 of Abra, now with default rules.
#
@reset;
::PostDefaultRules( @@eliminate_kr!(%), @@prodsort!(%), @@canonicalise!(%), @@collect_terms!(%) ).
\delta_{m n}::SelfCommuting.
\delta_{m n}::KroneckerDelta.
\delta^{m n}::SelfCommuting.
\delta^{m n}::KroneckerDelta.
{m, n, p, q, r, a, b}::Integer(1..10).
\GAMMA^{#}::GammaMatrix(metric=\delta).
obj3:= \GAMMA^{m n p q r}\GAMMA^{a}\GAMMA^{b}\GAMMA^{m n p}\GAMMA^{c}\GAMMA^{q r};
@join!(%){expand}:
@distribute!(%):
@join!(%){expand}:
@distribute!(%):
@join!(%){expand}:
@distribute!(%):
@join!(%){expand}:
@distribute!(%):
@join!(%){expand}:
@distribute!(%):
tst3:= \GAMMA^{a}*@(obj3);
@distribute!(%):
@join!(%){expand}:
@distribute!(%):
@assert(tst3);
# Test 4: Default rules with indirect reference to other expressions.
#
@reset.
{\mu,\nu,\rho,\sigma}::Indices.
\delta{#}::KroneckerDelta.
\eta_{\mu\nu}::Metric.
ElimOffDiagMetric := { \eta_{0 i} -> 0, \eta_{i 0} -> 0, \eta_{0 0} -> 1 };
::PostDefaultRules( @@substitute!(%)( @(ElimOffDiagMetric) ), @@eliminate_metric!(%), @@eliminate_kr!(%), @@rename_dummies!(%), @@collect_terms!(%) ).
obj4 := \eta_{\mu \nu} X^\nu + \delta_{\mu \lambda} Y_\lambda;
tst4 := X_{\mu} + Y_{\mu} - @(obj4);
@collect_terms!(%);
@assert(tst4);
# Test 5: Default rule applied to an expression which is not the
# last one in the tree.
@reset.
::PostDefaultRules( @@substitute!(%)( A A -> Q ) ).
one:= A B C;
two:= A D E;
@substitute!(one)( B -> A );
tst:= Q C - @(one);
@collect_terms!(%);
@assert(tst);
# Test 6: Default rules with generated zeroes.
#
@reset.
::PostDefaultRules( @@substitute!(%)( \eta_{a? b?} -> a? v_{b?} ) ).
obj6:= J_{1 0} P_{2};
@substitute!(%)( J_{a? b?} P_{c?} -> \eta_{a? c?} w_{b?} - \eta_{b? c?} w_{a?} );
tst6:= v_{2} w_{0} - @(obj6);
@collect_terms!(%);
@assert(tst6);
# This always works, but the key is whether the 0 has been simplified automatically
# immediately after the substitute step. If you put the command in the normal flow,
# instead of in the default rules, then the zeroes are always cleaned up properly:
# (again, this has to be run by hand to see it).
@reset.
obj6:= J_{1 0} P_{2};
@substitute!(%)( J_{a? b?} P_{c?} -> \eta_{a? c?} w_{b?} - \eta_{b? c?} w_{a?} );
@substitute!(%)( \eta_{a? b?} -> a? v_{b?} ) );
tst6:= v_{2} w_{0} - @(obj6);
@collect_terms!(%);
@assert(tst6);
# Test 7: Default rule which leads to a nested \prod{\sum{\prod{..}{..}}}{..} expression
# which should be flattened.
@reset.
{i,j,k}::Indices.
::PostDefaultRules( @@substitute!(%)( \eta_{0 j} -> 0, \eta_{i j} -> \delta_{i j} ) ).
obj7:= I * \hbar**(-1) * P_{0} * \commutator{J_{0 i}}{Q_{j}};
@substitute!(%)( \commutator{J_{a? b?}}{Q_{c?}} -> \eta_{a? c?} Q_{b?} - \eta_{b? c?} Q_{a?} );
tst7:= I * \hbar**(-1) * P_{0} * \delta_{i j} * Q_{0} + @(obj7);
@collect_terms!(%);
@assert(tst7);
|