/**********************************************************
 * 
 * This is a test file for local_square_classes.m
 * 
 * It performs a cross-check of LocalGroupOfSquaresClasses 
 * against the built-in method LocalMultiplicativeGroupModSquares
 * for fields selected in such a way that all the execution
 * path should be traversed. 
 * 
 *********************************************************/

// set the path to the package
import "path.m" : PATH_TO_LSC;
Attach(PATH_TO_LSC);

SetDebugOnError(true);

R<x> := PolynomialRing(Rationals());

procedure run_tests( K )
    printf ".";
    p :=  PrimeFactorization(K, 2)[1][1];

    // compute the local square-class groups in three ways
    G, mG := LocalMultiplicativeGroupModSquares(p);
    H, mH := LocalGroupOfSquaresClasses(p);

    // construct the change-of-basis matrices
    M := Matrix([ h @ mH @@ mG : h in Basis(H) ]);
    N := Matrix([ g @ mG @@ mH : g in Basis(G) ]);

    // the matrices must be mutually inverse
    assert IsOne(M*N);
end procedure;

// The following list of fields should exhaust all the
// branches of the code

// LMFDB 2.5.0.1: e = 1, f = 5
K<t> := NumberField( R![1, 0, 1, 0, 0, 1] );
run_tests(K);

// LMRDB 2.5.4.1: e = 5, f = 1
K<t> := NumberField( R![2, 0, 0, 0, 0, 1] );
run_tests(K);

// LMFDB 2.4.6.3: e = 2, f = 2
K<t> := NumberField( R![84, 48, 28, 8, 1] );
run_tests(K);

// LMFDB 2.4.6.7: e = 4, f = 1
K<t> := NumberField( R![2, 0, 2, 2, 1] );
run_tests(K);

// LMFDB 2.4.0.1: e = 1, f = 4
K<t> := NumberField( R![1, 1, 0, 0, 1] );
run_tests(K);

// LMFDB 2.6.4.1: e = 3, f = 2
K<t> := NumberField( R![7, 11, 22, 19, 10, 3, 1] );
run_tests(K);

// LMFDB 2.6.6.2: e = 2, f = 3
K<t> := NumberField( R![72, 8, 44, 24, 14, 6, 1] );
run_tests(K);

// LMFDB 2.9.6.1: e = 3, f = 3
K<t> := NumberField( R![29, -27, 9, -26, 0, 3, 9, 3, 0, 1] );
run_tests(K);

// a few more hand-picked fields with degree > 30
// (hence, no pre-compution used)

// e = 31, f = 1, degree > 30 (so no precomputation used)
K<t> := NumberField(x^31 + 128);
run_tests(K);

// e = 1, f = 31, degree > 30 (so no precomputation used)
K<t> := NumberField(x^31 + x^3 + 1);
run_tests(K);

// e = 2, f = 17, degree > 30 (so no precomputation used)
K<t> := NumberField(x^34 + 2*x^20 + 2*x^17 + x^6 + 2*x^3 + 16*x + 1);
run_tests(K);

// example from a review
K<t> := NumberField(x^18 + 9*x^17 + 45*x^16 + 156*x^15 + 414*x^14 + 882*x^13 + 1554*x^12 + 2304*x^11 + 2907*x^10 + 3139*x^9 + 2907*x^8 + 2304*x^7 + 1554*x^6 + 882*x^5 + 414*x^4 + 156*x^3 + 45*x^2 + 9*x + 3);
run_tests(K);

print "\nAll test passed!";
quit;
