//
// The goal of this is to find all prime numbers p>3 such that there exists
// a 5x5 sub-matrix N < E (notation as in section 4 of the paper) such that
// rank_Q(N) = 5 and p divides one of the leading coefficients in the
// Hermite normal form of N
//

//
// First we store all possible equations (thought of as row vectors)
// in a big matrix
//
EQS := Matrix(IntegerRing(),45,5,[
2,1,1,0,0,
2,1,0,1,0,
2,1,0,0,1,
2,0,1,1,0,
2,0,1,0,1,
2,0,0,1,1,
1,2,1,0,0,
1,2,0,1,0,
1,2,0,0,1,
1,1,2,0,0,
1,1,0,2,0,
1,1,0,0,2,
1,0,2,1,0,
1,0,2,0,1,
1,0,1,2,0,
1,0,1,0,2,
1,0,0,2,1,
1,0,0,1,2,
0,2,1,1,0,
0,2,1,0,1,
0,2,0,1,1,
0,1,2,1,0,
0,1,2,0,1,
0,1,1,2,0,
0,1,1,0,2,
0,1,0,2,1,
0,1,0,1,2,
0,0,2,1,1,
0,0,1,2,1,
0,0,1,1,2,
1,1,0,0,0,
1,0,1,0,0,
1,0,0,1,0,
1,0,0,0,1,
0,1,1,0,0,
0,1,0,1,0,
0,1,0,0,1,
0,0,1,1,0,
0,0,1,0,1,
0,0,0,1,1,
1,1,1,1,0,
1,1,1,0,1,
1,1,0,1,1,
1,0,1,1,1,
0,1,1,1,1
]);



IND := {1..45};
WhichPrimes := {};

// Note: Magma makes a distinction between sets and sequences. Bbelow we will
// have 'Iset' - this is a subset of IND. We will also have 'Iseq' - this is
// the same collection of numbers, but then viewed as a sequence. We need this
// because 'Submatrix' requires a sequence of indices, not a set.

for Iset in Subsets(IND,5) do
  Iseq := [x: x in Iset];
  M := Submatrix(EQS,Iseq,[1..5]);
  d := AbsoluteValue(Determinant(M));
  if d gt 1 then
    Primes := {p : p in PrimeDivisors(d)};
    WhichPrimes := WhichPrimes join Primes;
  end if;
end for;

print WhichPrimes;
