fundamentally, is this a function to simplify symmetries that are obvious? such as derivative symmetries, i.e. a_,ji == a_,ij
or is this meant to dictate symmetries of non-derivative tensor values (but not derivatives)? i.e. g_ji,lk = g_ij,kl
or is this meant to dictate values anyhow anywhere? i.e. a_i,j == a_j,i
I'm leaning towards #1 and #2 but not #3
so use this for symmetries of derivatives and non-derivatives

SO THE TAKE-AWAY ...
1) swap variance with symbol.
2) assert the derivative type of the index match, error if they don't.
2.5) if all indexes have commas then error if any are upper (unless all are covariant derivatives)
3) allow an override for non-matching commas ... don't swap comma. still do swap variance.




simplifyAssertEq( a'_ji':symmetrizeIndexes(a,{1,2}), a'_ij')
${{{ a} _i} _j} = {{{ a} _i} _j}$
GOOD
time: 5.867000ms
stack: size: 7
  • Init
  • Prune
  • Expand
  • Prune
  • Factor
  • Prune
  • Tidy

TODO in the case of 3 this isn't used so often

simplifyAssertEq( a'_kji':symmetrizeIndexes(a,{1,2,3}), a'_ijk')
${{{{ a} _i} _j} _k} = {{{{ a} _i} _j} _k}$
GOOD
time: 3.107000ms
stack: size: 7
  • Init
  • Prune
  • Expand
  • Prune
  • Factor
  • Prune
  • Tidy

simplifyAssertEq( a'_jki':symmetrizeIndexes(a,{1,2,3}), a'_ijk')
${{{{ a} _i} _j} _k} = {{{{ a} _i} _j} _k}$
GOOD
time: 3.449000ms
stack: size: 7
  • Init
  • Prune
  • Expand
  • Prune
  • Factor
  • Prune
  • Tidy

simplifyAssertEq( a'_jik':symmetrizeIndexes(a,{1,2,3}), a'_ijk')
${{{{ a} _i} _j} _k} = {{{{ a} _i} _j} _k}$
GOOD
time: 2.294000ms
stack: size: 7
  • Init
  • Prune
  • Expand
  • Prune
  • Factor
  • Prune
  • Tidy

TODO make sure this works when?

maintain raise/lower

simplifyAssertEq( a'_j^i':symmetrizeIndexes(a,{1,2}), a'^i_j')
${{{ a} ^i} _j} = {{{ a} ^i} _j}$
GOOD
time: 2.915000ms
stack: size: 7
  • Init
  • Prune
  • Expand
  • Prune
  • Factor
  • Prune
  • Tidy

don't symmetrize a comma and a non-comma (should I restrict this?)

assertError(function() a'_j,i':symmetrizeIndexes(a,{1,2}) end)
nil
GOOD
time: 0.457000ms
stack: size: 0

    do allow with override

    simplifyAssertEq(a'_j,i':symmetrizeIndexes(a,{1,2},true), a'_i,j')
    ${{{ a} _i} _{,j}} = {{{ a} _i} _{,j}}$
    GOOD
    time: 2.496000ms
    stack: size: 7
    • Init
    • Prune
    • Expand
    • Prune
    • Factor
    • Prune
    • Tidy

    do symmetrize two commas

    simplifyAssertEq( a'_,ji':symmetrizeIndexes(a,{1,2}), a'_,ij')
    ${{{ a} _{,i}} _{,j}} = {{{ a} _{,i}} _{,j}}$
    GOOD
    time: 2.519000ms
    stack: size: 7
    • Init
    • Prune
    • Expand
    • Prune
    • Factor
    • Prune
    • Tidy

    simplifyAssertEq( a'_,kji':symmetrizeIndexes(a,{1,2,3}), a'_,ijk')
    ${{{{ a} _{,i}} _{,j}} _{,k}} = {{{{ a} _{,i}} _{,j}} _{,k}}$
    GOOD
    time: 1.782000ms
    stack: size: 7
    • Init
    • Prune
    • Expand
    • Prune
    • Factor
    • Prune
    • Tidy

    simplifyAssertEq( a'_,jki':symmetrizeIndexes(a,{1,2,3}), a'_,ijk')
    ${{{{ a} _{,i}} _{,j}} _{,k}} = {{{{ a} _{,i}} _{,j}} _{,k}}$
    GOOD
    time: 2.565000ms
    stack: size: 7
    • Init
    • Prune
    • Expand
    • Prune
    • Factor
    • Prune
    • Tidy

    simplifyAssertEq( a'_,jik':symmetrizeIndexes(a,{1,2,3}), a'_,ijk')
    ${{{{ a} _{,i}} _{,j}} _{,k}} = {{{{ a} _{,i}} _{,j}} _{,k}}$
    GOOD
    time: 2.320000ms
    stack: size: 7
    • Init
    • Prune
    • Expand
    • Prune
    • Factor
    • Prune
    • Tidy


    simplifyAssertEq( a'_ji,lk':symmetrizeIndexes(a,{1,2}):symmetrizeIndexes(a,{3,4}), a'_ij,kl')
    ${{{{{ a} _i} _j} _{,k}} _{,l}} = {{{{{ a} _i} _j} _{,k}} _{,l}}$
    GOOD
    time: 2.398000ms
    stack: size: 7
    • Init
    • Prune
    • Expand
    • Prune
    • Factor
    • Prune
    • Tidy

    assertError(function() a'_ji,lk':symmetrizeIndexes(a,{2,3}) end)
    nil
    GOOD
    time: 0.360000ms
    stack: size: 0

      simplifyAssertEq(a'_jl,ik':symmetrizeIndexes(a,{2,3},true), a'_ji,lk')
      ${{{{{ a} _j} _i} _{,l}} _{,k}} = {{{{{ a} _j} _i} _{,l}} _{,k}}$
      GOOD
      time: 2.435000ms
      stack: size: 7
      • Init
      • Prune
      • Expand
      • Prune
      • Factor
      • Prune
      • Tidy

      if a_ij = a_ji
      then a^i_j = g^ik a_kj = g^ik a_jk = a_j^i
      and a^i_j,k = (g^im a_mj)_,k = g^im_,k a_mj + g^im a_mj,k = g^im_,k a_jm + g^im a_jm,k = (g^im a_jm)_,k = a_j^i_,k
      so even symmetries with non-matching variance that are wrapped in derivatives can be symmetrized

      simplifyAssertEq( a'_j^i_,k':symmetrizeIndexes(a,{1,2}), a'^i_j,k')
      ${{{{ a} ^i} _j} _{,k}} = {{{{ a} ^i} _j} _{,k}}$
      GOOD
      time: 3.850000ms
      stack: size: 7
      • Init
      • Prune
      • Expand
      • Prune
      • Factor
      • Prune
      • Tidy

      simplifyAssertEq( a'_ji,k':symmetrizeIndexes(a,{1,2}), a'_ij,k')
      ${{{{ a} _i} _j} _{,k}} = {{{{ a} _i} _j} _{,k}}$
      GOOD
      time: 2.231000ms
      stack: size: 7
      • Init
      • Prune
      • Expand
      • Prune
      • Factor
      • Prune
      • Tidy

      simplifyAssertEq( a'^ji_,k':symmetrizeIndexes(a,{1,2}), a'^ij_,k')
      ${{{{ a} ^i} ^j} _{,k}} = {{{{ a} ^i} ^j} _{,k}}$
      GOOD
      time: 1.947000ms
      stack: size: 7
      • Init
      • Prune
      • Expand
      • Prune
      • Factor
      • Prune
      • Tidy

      same if the comma is raised? a_ij==a_ji <=> a_i^j,k==a^j_i^,k ?
      how about if multiple commas are upper? <=> a^i,jk == a^i,kj ?
      a^i,jk = (g^im a_m)^,jk = ((g^im a_m)_,n g^nj)_,p g^pk
      = ((g^im a_m)_,np g^nj + (g^im a_m)_,n g^nj_,p) g^pk
      = (g^im a_m)_,np g^pk g^nj + (g^im a_m)_,n g^nj_,p g^pk
      = (g^im_,n a_m + g^im a_m,n)_,p g^pk g^nj + (g^im_,n a_m + g^im a_m,n) g^nj_,p g^pk
      = g^im_,np g^pk g^nj a_m + g^im_,n a_m,p g^pk g^nj + g^im_,p a_m,n g^pk g^nj + g^im_,n a_m g^nj_,p g^pk + g^im a_m,n g^nj_,p g^pk + a_m,np g^im g^pk g^nj
      so it doesn't look like these match
      = g^im_,np g^pk g^nj a_m + g^im_,n a_m,p g^pk g^nj + g^im_,p a_m,n g^pk g^nj + g^im_,n a_m g^nk_,p g^pj + g^im a_m,n g^nk_,p g^pj + a_m,np g^im g^pk g^nj
      = a_m g^im_,np g^pj g^nk + g^im_,n a_m,p g^pj g^nk + g^im_,p a_m,n g^pj g^nk + g^im a_m,np g^pj g^nk + g^im_,n a_m g^nk_,p g^pj + g^im a_m,n g^nk_,p g^pj
      = a^i,kj
      this looks like a job for my CAS ... but it isn't looking like upper commas can be assumed to be symmetric
      so commas can only be symmetrized if they are all lowered

      simplifyAssertEq(a'_i,kj':symmetrizeIndexes(a,{2,3}), a'_i,jk')
      ${{{{ a} _i} _{,j}} _{,k}} = {{{{ a} _i} _{,j}} _{,k}}$
      GOOD
      time: 1.722000ms
      stack: size: 7
      • Init
      • Prune
      • Expand
      • Prune
      • Factor
      • Prune
      • Tidy
      but if they are upper then cause an error

      assertError(function() a'_i^,jk':symmetrizeIndexes(a,{2,3}) end)
      nil
      GOOD
      time: 0.576000ms
      stack: size: 0
        unless explicitly overridden

        simplifyAssertEq(a'_i^,kj':symmetrizeIndexes(a,{2,3},true), a'_i^,jk')
        ${{{{ a} _i} ^{,j}} ^{,k}} = {{{{ a} _i} ^{,j}} ^{,k}}$
        GOOD
        time: 2.449000ms
        stack: size: 7
        • Init
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • Tidy

        if you symmetrize non-lower-matching that are encased in deriv indexes ... still fine. (even if the derivs are upper?)

        simplifyAssertEq( a'^j_i,kl':symmetrizeIndexes(a,{1,2}), a'_i^j_,kl')
        ${{{{{ a} _i} ^j} _{,k}} _{,l}} = {{{{{ a} _i} ^j} _{,k}} _{,l}}$
        GOOD
        time: 2.192000ms
        stack: size: 7
        • Init
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • Tidy

        TODO test for also sort any multiplied tensors?
        another thing symmetrizing can do ...
        g^kl (d_klj + d_jlk - d_ljk) symmetrize g {1,2}
        ... not only sort g^kl
        but also sort all indexes in all multiplied expressions which use 'k' or 'l'
        so this would become
        g^kl (d_klj + d_jkl - d_kjl)
        then another symmetrize d {2,3} gives us
        g^kl (d_kjl + d_jkl - d_kjl)
        g^kl d_jkl

        simplifyAssertEq( (g'^kl' * (d'_klj' + d'_jlk' - d'_ljk')):symmetrizeIndexes(g, {1,2}), g'^kl' * (d'_klj' + d'_jkl' - d'_kjl') )
        ${{{{{ g} ^k} ^l}} {{\left({{{{{ d} _k} _l} _j} + {{{{ d} _j} _k} _l}{-{{{{ d} _k} _j} _l}}}\right)}}} = {{{{{ g} ^k} ^l}} {{\left({{{{{ d} _k} _l} _j} + {{{{ d} _j} _k} _l}{-{{{{ d} _k} _j} _l}}}\right)}}}$
        GOOD
        time: 28.582000ms
        stack: size: 21
        • Init
        • unm:Prune:doubleNegative
        • Prune
        • *:Expand:apply
        • Expand
        • *:Prune:flatten
        • Prune
        • unm:Prune:doubleNegative
        • +:Prune:combineConstants
        • unm:Prune:doubleNegative
        • +:Prune:combineConstants
        • unm:Prune:doubleNegative
        • +:Prune:combineConstants
        • +:Factor:apply
        • Factor
        • Prune
        • Constant:Tidy:apply
        • *:Tidy:apply
        • *:Tidy:apply
        • *:Tidy:apply
        • Tidy

        simplifyAssertEq( (g'^kl' * (d'_klj' + d'_jlk' - d'_ljk')):symmetrizeIndexes(g, {1,2}):symmetrizeIndexes(d, {2,3}), g'^kl' * (d'_kjl' + d'_jkl' - d'_kjl') )
        ${{{{{ g} ^k} ^l}} {{\left({{{{{ d} _k} _j} _l} + {{{{ d} _j} _k} _l}{-{{{{ d} _k} _j} _l}}}\right)}}} = {{{{{ g} ^k} ^l}} {{\left({{{{{ d} _k} _j} _l} + {{{{ d} _j} _k} _l}{-{{{{ d} _k} _j} _l}}}\right)}}}$
        GOOD
        time: 11.769000ms
        stack: size: 12
        • Init
        • unm:Prune:doubleNegative
        • *:Prune:apply
        • +:Prune:combineConstants
        • +:Prune:flattenAddMul
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • *:Tidy:apply
        • Tidy

        simplifyAssertEq( (g'^kl' * (d'_klj' + d'_jlk' - d'_ljk')):symmetrizeIndexes(g, {1,2}):symmetrizeIndexes(d, {2,3})(), g'^kl' * d'_jkl' )
        ${{{{{ g} ^k} ^l}} {{{{{ d} _j} _k} _l}}} = {{{{{ g} ^k} ^l}} {{{{{ d} _j} _k} _l}}}$
        GOOD
        time: 10.709000ms
        stack: size: 8
        • Init
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • *:Tidy:apply
        • Tidy

        same with all-lower

        simplifyAssertEq( (g'_kl' * (d'^kl_j' + d'_j^lk' - d'^l_j^k')):symmetrizeIndexes(g, {1,2}), g'_kl' * (d'^kl_j' + d'_j^kl' - d'^k_j^l') )
        ${{{{{ g} _k} _l}} {{\left({{{{{ d} ^k} ^l} _j} + {{{{ d} _j} ^k} ^l}{-{{{{ d} ^k} _j} ^l}}}\right)}}} = {{{{{ g} _k} _l}} {{\left({{{{{ d} ^k} ^l} _j} + {{{{ d} _j} ^k} ^l}{-{{{{ d} ^k} _j} ^l}}}\right)}}}$
        GOOD
        time: 20.058000ms
        stack: size: 21
        • Init
        • unm:Prune:doubleNegative
        • Prune
        • *:Expand:apply
        • Expand
        • *:Prune:flatten
        • Prune
        • unm:Prune:doubleNegative
        • +:Prune:combineConstants
        • unm:Prune:doubleNegative
        • +:Prune:combineConstants
        • unm:Prune:doubleNegative
        • +:Prune:combineConstants
        • +:Factor:apply
        • Factor
        • Prune
        • Constant:Tidy:apply
        • *:Tidy:apply
        • *:Tidy:apply
        • *:Tidy:apply
        • Tidy

        simplifyAssertEq( (g'_kl' * (d'^kl_j' + d'_j^lk' - d'^l_j^k')):symmetrizeIndexes(g, {1,2}):symmetrizeIndexes(d, {2,3}), g'_kl' * (d'^k_j^l' + d'_j^kl' - d'^k_j^l') )
        ${{{{{ g} _k} _l}} {{\left({{{{{ d} ^k} _j} ^l} + {{{{ d} _j} ^k} ^l}{-{{{{ d} ^k} _j} ^l}}}\right)}}} = {{{{{ g} _k} _l}} {{\left({{{{{ d} ^k} _j} ^l} + {{{{ d} _j} ^k} ^l}{-{{{{ d} ^k} _j} ^l}}}\right)}}}$
        GOOD
        time: 9.787000ms
        stack: size: 12
        • Init
        • unm:Prune:doubleNegative
        • *:Prune:apply
        • +:Prune:combineConstants
        • +:Prune:flattenAddMul
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • *:Tidy:apply
        • Tidy

        simplifyAssertEq( (g'_kl' * (d'^kl_j' + d'_j^lk' - d'^l_j^k')):symmetrizeIndexes(g, {1,2}):symmetrizeIndexes(d, {2,3})(), g'_kl' * d'_j^kl' )
        ${{{{{ g} _k} _l}} {{{{{ d} _j} ^k} ^l}}} = {{{{{ g} _k} _l}} {{{{{ d} _j} ^k} ^l}}}$
        GOOD
        time: 7.566000ms
        stack: size: 8
        • Init
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • *:Tidy:apply
        • Tidy

        same with mixed upper/lower

        simplifyAssertEq( (delta'_k^l' * (d'^k_lj' + d'_jl^k' - d'_lj^k')):symmetrizeIndexes(delta, {1,2}), delta'_k^l' * (d'^k_lj' + d'_j^k_l' - d'^k_jl') )
        ${{{{{ δ} _k} ^l}} {{\left({{{{{ d} ^k} _l} _j} + {{{{ d} _j} ^k} _l}{-{{{{ d} ^k} _j} _l}}}\right)}}} = {{{{{ δ} _k} ^l}} {{\left({{{{{ d} ^k} _l} _j} + {{{{ d} _j} ^k} _l}{-{{{{ d} ^k} _j} _l}}}\right)}}}$
        GOOD
        time: 20.038000ms
        stack: size: 21
        • Init
        • unm:Prune:doubleNegative
        • Prune
        • *:Expand:apply
        • Expand
        • *:Prune:flatten
        • Prune
        • unm:Prune:doubleNegative
        • +:Prune:combineConstants
        • unm:Prune:doubleNegative
        • +:Prune:combineConstants
        • unm:Prune:doubleNegative
        • +:Prune:combineConstants
        • +:Factor:apply
        • Factor
        • Prune
        • Constant:Tidy:apply
        • *:Tidy:apply
        • *:Tidy:apply
        • *:Tidy:apply
        • Tidy

        simplifyAssertEq( (delta'_k^l' * (d'^k_lj' + d'_jl^k' - d'_lj^k')):symmetrizeIndexes(delta, {1,2}):symmetrizeIndexes(d, {2,3}), delta'_k^l' * (d'^k_jl' + d'_j^k_l' - d'^k_jl') )
        ${{{{{ δ} _k} ^l}} {{\left({{{{{ d} ^k} _j} _l} + {{{{ d} _j} ^k} _l}{-{{{{ d} ^k} _j} _l}}}\right)}}} = {{{{{ δ} _k} ^l}} {{\left({{{{{ d} ^k} _j} _l} + {{{{ d} _j} ^k} _l}{-{{{{ d} ^k} _j} _l}}}\right)}}}$
        GOOD
        time: 6.605000ms
        stack: size: 12
        • Init
        • unm:Prune:doubleNegative
        • *:Prune:apply
        • +:Prune:combineConstants
        • +:Prune:flattenAddMul
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • *:Tidy:apply
        • Tidy

        simplifyAssertEq( (delta'_k^l' * (d'^k_lj' + d'_jl^k' - d'_lj^k')):symmetrizeIndexes(delta, {1,2}):symmetrizeIndexes(d, {2,3})(), delta'_k^l' * d'_j^k_l' )
        ${{{{{ δ} _k} ^l}} {{{{{ d} _j} ^k} _l}}} = {{{{{ δ} _k} ^l}} {{{{{ d} _j} ^k} _l}}}$
        GOOD
        time: 3.941000ms
        stack: size: 8
        • Init
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • *:Tidy:apply
        • Tidy

        how about with commas? don't forget, you can't exchange comma positions, even if you override errors, because commas cannot precede non-comma indexes.
        in fact, I vote yes, because of exchaning labels of indexes. g^ab t_a,b = g^ab t_b,a regardless of any symmetry between t_a,b and t_b,a.
        assertError(function() (g'^kl' * (d'_kl,j' + d'_jl,k' - d'_lj,k')):symmetrizeIndexes(g, {1,2}) end)
        assertError(function() (g'^kl' * (d'_kl,j' + d'_jl,k' - d'_lj,k')):symmetrizeIndexes(g, {1,2}):symmetrizeIndexes(d, {2,3}) end)
        assertError(function() (g'^kl' * (d'_kl,j' + d'_jl,k' - d'_lj,k')):symmetrizeIndexes(g, {1,2}):symmetrizeIndexes(d, {2,3})() end)


        simplifyAssertEq( (g'^kl' * (d'_kl,j' + d'_jl,k' - d'_lj,k')):symmetrizeIndexes(g, {1,2}), g'^kl' * (d'_kl,j' + d'_jk,l' - d'_kj,l') )
        ${{{{{ g} ^k} ^l}} {{\left({{{{{ d} _k} _l} _{,j}} + {{{{ d} _j} _k} _{,l}}{-{{{{ d} _k} _j} _{,l}}}}\right)}}} = {{{{{ g} ^k} ^l}} {{\left({{{{{ d} _k} _l} _{,j}} + {{{{ d} _j} _k} _{,l}}{-{{{{ d} _k} _j} _{,l}}}}\right)}}}$
        GOOD
        time: 17.799000ms
        stack: size: 21
        • Init
        • unm:Prune:doubleNegative
        • Prune
        • *:Expand:apply
        • Expand
        • *:Prune:flatten
        • Prune
        • unm:Prune:doubleNegative
        • +:Prune:combineConstants
        • unm:Prune:doubleNegative
        • +:Prune:combineConstants
        • unm:Prune:doubleNegative
        • +:Prune:combineConstants
        • +:Factor:apply
        • Factor
        • Prune
        • Constant:Tidy:apply
        • *:Tidy:apply
        • *:Tidy:apply
        • *:Tidy:apply
        • Tidy

        simplifyAssertEq( (g'^kl' * (d'_kl,j' + d'_jl,k' - d'_lj,k')):symmetrizeIndexes(g, {1,2}):symmetrizeIndexes(d, {2,3}, true), g'^kl' * (d'_kj,l' + d'_jk,l' - d'_kj,l') )
        ${{{{{ g} ^k} ^l}} {{\left({{{{{ d} _k} _j} _{,l}} + {{{{ d} _j} _k} _{,l}}{-{{{{ d} _k} _j} _{,l}}}}\right)}}} = {{{{{ g} ^k} ^l}} {{\left({{{{{ d} _k} _j} _{,l}} + {{{{ d} _j} _k} _{,l}}{-{{{{ d} _k} _j} _{,l}}}}\right)}}}$
        GOOD
        time: 6.925000ms
        stack: size: 12
        • Init
        • unm:Prune:doubleNegative
        • *:Prune:apply
        • +:Prune:combineConstants
        • +:Prune:flattenAddMul
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • *:Tidy:apply
        • Tidy

        simplifyAssertEq( (g'^kl' * (d'_kl,j' + d'_jl,k' - d'_lj,k')):symmetrizeIndexes(g, {1,2}):symmetrizeIndexes(d, {2,3}, true)(), g'^kl' * d'_jk,l' )
        ${{{{{ g} ^k} ^l}} {{{{{ d} _j} _k} _{,l}}}} = {{{{{ g} ^k} ^l}} {{{{{ d} _j} _k} _{,l}}}}$
        GOOD
        time: 5.763000ms
        stack: size: 8
        • Init
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • *:Tidy:apply
        • Tidy

        this is working
        simplifyAssertEq( (d'^d_dc'):symmetrizeIndexes(d, {2,3}), d'^d_cd')
        ${{{{ d} ^d} _c} _d} = {{{{ d} ^d} _c} _d}$
        GOOD
        time: 1.231000ms
        stack: size: 7
        • Init
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • Tidy
        this is failing
        simplifyAssertEq( (a'^c' * d'^d_dc'):symmetrizeIndexes(d, {2,3}), a'^c' * d'^d_cd')
        ${{{{ a} ^c}} {{{{{ d} ^d} _c} _d}}} = {{{{ a} ^c}} {{{{{ d} ^d} _c} _d}}}$
        GOOD
        time: 2.958000ms
        stack: size: 8
        • Init
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • *:Tidy:apply
        • Tidy


        simplifyAssertEq( (g'_ab' * a'^bac'):symmetrizeIndexes(g, {1,2}), g'_ab' * a'^abc')
        ${{{{{ g} _a} _b}} {{{{{ a} ^a} ^b} ^c}}} = {{{{{ g} _a} _b}} {{{{{ a} ^a} ^b} ^c}}}$
        GOOD
        time: 5.044000ms
        stack: size: 8
        • Init
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • *:Tidy:apply
        • Tidy

        simplifyAssertEq( (g'_ab' * a'^bac' * g'_ef' * b'^feg' ):symmetrizeIndexes(g, {1,2}), g'_ab' * a'^abc' * g'_ef' * b'^efg')
        ${{{{{ g} _a} _b}} {{{{{ a} ^a} ^b} ^c}} {{{{ g} _e} _f}} {{{{{ b} ^e} ^f} ^g}}} = {{{{{ g} _a} _b}} {{{{{ a} ^a} ^b} ^c}} {{{{ g} _e} _f}} {{{{{ b} ^e} ^f} ^g}}}$
        GOOD
        time: 11.691000ms
        stack: size: 8
        • Init
        • Prune
        • Expand
        • Prune
        • Factor
        • Prune
        • *:Tidy:apply
        • Tidy

        can't symmetrize b_a,b without override
        assertError(function() ( g'^ab' * b'_a,b' ):symmetrizeIndexes(b, {1,2}) end)
        nil
        GOOD
        time: 0.255000ms
        stack: size: 0
          can't symmetrize b^a_,b without override
          assertError(function() ( b'^a_,b' ):symmetrizeIndexes(b, {1,2}) end)
          nil
          GOOD
          time: 0.177000ms
          stack: size: 0
            you can indirectly symmetrize b_a,b without override
            simplifyAssertEq( ( g'^ba' * b'_a,b' ):symmetrizeIndexes(g, {1,2}), g'^ab' * b'_a,b' )
            ${{{{{ g} ^a} ^b}} {{{{ b} _a} _{,b}}}} = {{{{{ g} ^a} ^b}} {{{{ b} _a} _{,b}}}}$
            GOOD
            time: 2.372000ms
            stack: size: 8
            • Init
            • Prune
            • Expand
            • Prune
            • Factor
            • Prune
            • *:Tidy:apply
            • Tidy

            fine
            simplifyAssertEq(( d'^ab' * b'_b,a' ):symmetrizeIndexes(d, {1,2}), d'^ab' * b'_a,b')
            ${{{{{ d} ^a} ^b}} {{{{ b} _a} _{,b}}}} = {{{{{ d} ^a} ^b}} {{{{ b} _a} _{,b}}}}$
            GOOD
            time: 2.020000ms
            stack: size: 8
            • Init
            • Prune
            • Expand
            • Prune
            • Factor
            • Prune
            • *:Tidy:apply
            • Tidy
            fine
            simplifyAssertEq(( d'_ab' * b'^b,a' ):symmetrizeIndexes(d, {1,2}), d'_ab' * b'^a,b')
            ${{{{{ d} _a} _b}} {{{{ b} ^a} ^{,b}}}} = {{{{{ d} _a} _b}} {{{{ b} ^a} ^{,b}}}}$
            GOOD
            time: 3.660000ms
            stack: size: 8
            • Init
            • Prune
            • Expand
            • Prune
            • Factor
            • Prune
            • *:Tidy:apply
            • Tidy
            you can't indirectly symmetrize b^a_,b without override ... but because it's indirect, don't cause an error, just skip it.
            simplifyAssertEq(( d'^a_b' * b'^b_,a' ):symmetrizeIndexes(d, {1,2}), d'^a_b' * b'^b_,a')
            ${{{{{ d} ^a} _b}} {{{{ b} ^b} _{,a}}}} = {{{{{ d} ^a} _b}} {{{{ b} ^b} _{,a}}}}$
            GOOD
            time: 2.319000ms
            stack: size: 8
            • Init
            • Prune
            • Expand
            • Prune
            • Factor
            • Prune
            • *:Tidy:apply
            • Tidy
            if you override, then fine , but maybe care about the commas and upper/lower a bit more? maybe not, it's overridden anyways
            simplifyAssertEq(( d'^a_b' * b'^b_,a' ):symmetrizeIndexes(d, {1,2}, true), d'^a_b' * b'_a^,b')
            ${{{{{ d} ^a} _b}} {{{{ b} _a} ^{,b}}}} = {{{{{ d} ^a} _b}} {{{{ b} _a} ^{,b}}}}$
            GOOD
            time: 3.700000ms
            stack: size: 8
            • Init
            • Prune
            • Expand
            • Prune
            • Factor
            • Prune
            • *:Tidy:apply
            • Tidy