# All examples from the hep-th paper, converted to version 2 format.
import timeit

def test01():
    __cdbkernel__=create_scope()
    { a, b, c, d }::Indices.
    obj:= A_{a b} B_{b c};
    substitute(_, $B_{a b} ->  C_{a b c} D_{c}$ )
    tst:= A_{a b}  C_{b c d} D_{d} - @(obj);
    assert(tst==0)
    print('Test 01 passed')

print(timeit.timeit(test01,number=1))

#-------

def test02():
    __cdbkernel__=create_scope()
    A_{\dot{a} \dot{b}}::AntiSymmetric.
    obj:= A_{\dot{b} \dot{a}}:
    canonicalise(_)
    tst:= A_{\dot{a} \dot{b}} + @(obj);
    assert(tst==0)
    print('Test 02 passed')

print(timeit.timeit(test02,number=1))

#-------

def test03():
    __cdbkernel__=create_scope()
    { a_{1}, a_{2}, a_{3}, a_{4} }::Indices(vector).
    obj:= V_{a_{1}} W_{a_{1}}:
    substitute(_, $V_{a_{2}} -> M_{a_{2} a_{1}} N_{a_{1}}$ )
    tst:= M_{a_{1} a_{2}}  N_{a_{2}}  W_{a_{1}} - @(obj);
    collect_terms(_)
    assert(tst==0)
    print('Test 03 passed')

print(timeit.timeit(test03,number=1))

#-------

def test04():
    __cdbkernel__=create_scope()
    R_{a b c d}::TableauSymmetry(shape={2,2}, indices={0,2,1,3}).
    obj:= R_{a b c d} R_{d c a b}:
    canonicalise(_)
    tst:= (-1) R_{a b c d} R_{a b c d} - @(obj);
    collect_terms(_)
    assert(tst==0)
    print('Test 04 passed')

print(timeit.timeit(test04,number=1))

#-------

def test05():
    __cdbkernel__=create_scope()
    {m,n,p,q}::Indices(position=free).
    \nabla{#}::Derivative.
    \partial{#}::PartialDerivative.
    A_{m n}::AntiSymmetric.
    V_{m}::Depends(\nabla{#}).
    obj:= \partial_{m p}( A_{q r} V_{n} ) A^{p m};
    canonicalise(_)
    assert(obj==0)
    print('Test 05a passed')
    obj:= \nabla_{m p}( A_{q r} V_{n} ) A^{p m};
    canonicalise(_)
    tst:= (-1) \nabla_{m p}( A_{q r} V_{n} ) A^{m p} - @(obj);
    canonicalise(_)
    assert(tst==0)
    print('Test 05b passed')
    unwrap(obj)
    tst:= (-1) A_{q r} \nabla_{m p}{ V_{n} } A^{m p} - @(obj);
    canonicalise(_)
    assert(tst==0)
    print('Test 05c passed')

print(timeit.timeit(test05,number=1))

#-------

def test06():
    __cdbkernel__=create_scope()
    {m,n,p,q,r,s,t#}::Indices(vector).
    \nabla{#}::Derivative.
    R_{m n p q}::RiemannTensor.
    \nabla_{m}{R_{p q r s}}::SatisfiesBianchi.
    obj:= \nabla_{m}{R_{p q r s}} + \nabla_{p}{R_{q m r s}} + \nabla_{q}{R_{m p r s}}:
    young_project_tensor(_, depth=1, modulo_monoterm=True);
    assert(obj==0)
    print('Test 06 passed')

print(timeit.timeit(test06,number=1))

#-------

def test07():
    __cdbkernel__=create_scope()
    { m, n, p, q }::Indices(vector).
    { A_{m n p}, B_{m n p} }::AntiSymmetric.
    { m, n, p, q }::Integer(1..4).
    obj:= A_{m n p} B_{m n q} - A_{m n q} B_{m n p};
    decompose_product(_)
    canonicalise(_)
    tst:= A_{m n p} B_{m n q} - A_{m n q} B_{m n p} - @(obj);
    canonicalise(_)
    assert(tst==0)
    print('Test 07 passed')

print(timeit.timeit(test07,number=1))

#-------

def test08():
    __cdbkernel__=create_scope()
    { m, n, p, q }::Indices(vector).
    { A_{m n p}, B_{m n p} }::AntiSymmetric.
    { m, n, p, q }::Integer(1..3).
    obj:= A_{m n p} B_{m n q} - A_{m n q} B_{m n p};
    decompose_product(_)
    canonicalise(_)
    assert(obj==0)
    print('Test 08 passed')

print(timeit.timeit(test08,number=1))

#-------

def test08b():
    __cdbkernel__=create_scope() 
    \ftableau{#}::FilledTableau(dimension=10);
    ex:=\ftableau{0,0}{1,1} \ftableau{a,a}{b,b};
    lr_tensor(_);    

print(timeit.timeit(test08b, number=1))
        
#-------

def test09():
    __cdbkernel__=create_scope()

    {i,j,m,n,k,p,q,l,r,r#}::Indices(vector).
    C_{m n p q}::WeylTensor.
    \nabla{#}::Derivative.
    \nabla_{r}{ C_{m n p q} }::SatisfiesBianchi.
    \delta_{i j}::KroneckerDelta.
    
    Eij:=- C_{i m k l} C_{j p k q} C_{l p m q} + 1/4 C_{i m k l} C_{j m p q} C_{k l p q}
         - 1/2 C_{i k j l} C_{k m p q} C_{l m p q};
    
    E:=  C_{j m n k} C_{m p q n} C_{p j k q} + 1/2 C_{j k m n} C_{p q m n} C_{j k p q};
    
    exp:= \nabla_{i}{\nabla_{j}{ @(Eij) }} - 1/6 \nabla_{i}{\nabla_{i}{ @(E) }};
    print('one')
    
    distribute(_)
    product_rule(_)
    distribute(_)
    product_rule(_)
    print('two')
    
    sort_product(_)
    canonicalise(_)
    rename_dummies(_)
    print('three')
        
    rl:={ \nabla_{i}{C_{k i l m}} -> 0, \nabla_{i}{C_{k m l i}} -> 0 };
    substitute(exp, rl)
    print('four')
    
    young_project_product(exp)
    assert(exp==0)
    print('Test 09 passed')

print(timeit.timeit(test09,number=1))

#-------

def test10():
    __cdbkernel__=create_scope()
    {M, N, P}::Indices(space).
    {m, n, p}::Indices(subspace1).
    {a, b, c}::Indices(subspace2).
    obj:= A_{M N} B_{N P};
    split_index(_, $M, m, a$)
    tst:= A_{M m}  B_{m P} + A_{M a} B_{a P} - @(obj);
    assert(tst==0)
    print('Test 10 passed')

print(timeit.timeit(test10,number=1))

#-------

def test11():
    __cdbkernel__=create_scope()
    {a,b,c,d#}::Indices(spinor).
    \Gamma_{#}::GammaMatrix(metric=\delta).
    obj:=(\Gamma_{m n})_{a b} (\Gamma_{n p})_{b c};
    combine(_);
    join_gamma(_);
    canonicalise(_);
    tst:= (\Gamma_{m p} \delta_{n n} - \Gamma_{m n} \delta_{n p} + \Gamma_{p n} \delta_{m n} + \delta_{n n} \delta_{m p} - \delta_{m n} \delta_{n p})_{a c} - @(obj);
    assert(tst==0)
    distribute(obj);
    expand(obj);
    tst:= (\Gamma_{m p})_{a c} \delta_{n n} - (\Gamma_{m n})_{a c} \delta_{n p} 
    + (\Gamma_{p n})_{a c} \delta_{m n} + (\delta_{n n} \delta_{m p} )_{a c} 
    - (\delta_{m n} \delta_{n p})_{a c} - @(obj);
    assert(tst==0)
    print('Test 11 passed')

print(timeit.timeit(test11,number=1))

#-------

def test12():
    __cdbkernel__=create_scope()
    {\mu,\nu,\rho}::Indices(curved, position=fixed).
    {m,n,p,q,r,s,t}::Indices(flat, position=free).
    {m,n,p,q,r,s,t}::Integer(0..10).
    T^{#{\mu}}::AntiSymmetric.
    \psi_{\mu}::SelfAntiCommuting.
    \psi_{\mu}::Spinor(dimension=11, type=Majorana).
    \theta::Spinor(dimension=11, type=Majorana).
    \epsilon::Spinor(dimension=11, type=Majorana).
    {\theta,\epsilon,\psi_{\mu}}::AntiCommuting.
    \bar{#}::DiracBar.
    \delta{#}::KroneckerDelta.
    \Gamma^{#{m}}::GammaMatrix(metric=\delta).

    obj:= T^{\mu\nu\rho} e_{\nu}^{s}
        \bar{\theta} \Gamma^{r s} \psi_{\rho}
        \bar{\psi_{\mu}} \Gamma^{r} \epsilon;

    fierz(_, $\theta, \epsilon, \psi_{\mu}, \psi_{\rho}$ );
    converge(obj):
        join_gamma(obj)
        distribute(obj)
        eliminate_kronecker(obj)
        eliminate_metric(obj)

    canonicalise(_)
    rename_dummies(_)
    tst:=1/4 T^{\mu \nu \rho} e_{\mu}^{m} \bar{\theta} \Gamma^{m n}
        \epsilon \bar{\psi_{\nu}} \Gamma^{n} \psi_{\rho} 
        + 5/16 T^{\mu \nu \rho} e_{\mu}^{m} \bar{\theta} \epsilon
        \bar{\psi_{\nu}} \Gamma^{m} \psi_{\rho} 
        + 3/32 T^{\mu \nu \rho} e_{\mu}^{m} \bar{\theta} \Gamma^{m n p} \epsilon
        \bar{\psi_{\nu}} \Gamma^{n p} \psi_{\rho} 
        + 1/4 T^{\mu \nu \rho} e_{\mu}^{m} \bar{\theta} \Gamma^{n}
        \epsilon \bar{\psi_{\nu}} \Gamma^{m n} \psi_{\rho} 
        + 1/384 T^{\mu \nu \rho} e_{\mu}^{m} \bar{\theta}
        \Gamma^{n p q r} \epsilon \bar{\psi_{\nu}} \Gamma^{m n p q r} \psi_{\rho}
        - @(obj);
    rename_dummies(tst);
    assert(tst==0)
    print("Test 12 passed")

print(timeit.timeit(test12,number=1))

#-------

def test13():
    __cdbkernel__=create_scope()
    \psi_{\mu}::SelfAntiCommuting.
    {\chi, \psi_{\mu} }::AntiCommuting.
    ex:= \chi A^{\mu\nu} \psi_{\mu} \chi \psi_{\nu};
    substitute(_, $\psi_{\mu} \psi_{nu} -> B_{\mu\nu}$ );
    tst:= - \chi A^{\mu\nu} B_{\mu\nu} \chi - @(ex);
    assert(tst==0)
    print("Test 13a passed")
    A^{\mu\nu}::Symmetric;
    ex:= \chi A^{\mu\nu} \psi_{\mu} \chi \psi_{\nu};
    canonicalise(_)
    assert(ex==0)
    print("Test 13b passed")

print(timeit.timeit(test13,number=1))

#-------

D{#}::Derivative.
\bar{#}::DiracBar.
\delta{A??}::Derivative.
{m,n,p,q,r,s,t,u,m#}::Indices(flat).
{m,n,p,q,r,s,t,u,m#}::Integer(0..3).
{\mu,\nu,\rho,\sigma,\kappa,\lambda,\alpha,\beta}::Indices(curved,position=fixed).
{\mu,\nu,\rho,\sigma,\kappa,\lambda,\alpha,\beta}::Integer(0..3).

e^{m \mu}::Vielbein.
e_{m \mu}::InverseVielbein.
g^{\mu\nu}::InverseMetric.
g_{\mu\nu}::Metric.

{ \epsilon,\psi_{\mu},\psi_{\mu\nu} }::Spinor(dimension=4, type=Majorana).
\Gamma_{#{m}}::GammaMatrix(metric=\delta).
{ \psi_{\mu\nu}, \psi_{\mu}, \epsilon }::AntiCommuting.
{ \psi_{\mu}, \psi_{\mu\nu} }::SelfAntiCommuting.
{ \epsilon, \psi_{\mu}, \psi_{\mu\nu} }::SortOrder.
\Gamma_{#}::Depends(\bar).
\psi_{\mu\nu}::AntiSymmetric.

L:= -1/2 e e^{n \nu} e^{m \mu} R_{\mu\nu n m}
- 1/2 e \bar{\psi_\mu} \Gamma^{\mu\nu\rho} D_{\nu}{\psi_{\rho}}:
rewrite_indices(_, $\Gamma^{m n p}$, $e^{n \mu}$ );

susy:= { e^{n \mu} -> -\bar{\epsilon} \Gamma^m \psi_\nu e^{m \mu} e^{n \nu},
         e         -> e \bar{\epsilon} \Gamma^n \psi_\mu e^{n\mu},
         \psi_\mu -> D_{\mu}{\epsilon} };

vary(L, susy);
