// Magma scripts for the paper:
//
// Henri Johnston, Tommy Hofmann: Computing Isomorphisms Between Lattices
//
// Please cite the paper if you used these Magma scripts.
//
// Copyright (c) 2019: Tommy Hofmann
//
// Here is how to use the functions:

AttachSpec("Iso.spec");

// Test if a ring of integers is locally free (same as being tamely ramified)

K1 := QuadraticField(15);
G, _, mK1 := AutomorphismGroup(K1);
QG := GroupAlgebra(Rationals(), G);
IsLocallyFree(QG, IntegersToIdeal(QG, K1, mK1));
IsTamelyRamified(K1);

// Test if two rings of integers a locally isomorphic (continued)

K2 := QuadraticField(17);
G2, _, mK2 := AutomorphismGroup(K2);
b, f := IsIsomorphic(G, G2);
IsLocallyIsomorphic(QG, IntegersToIdeal(QG, K1, mK1), IntegersToIdeal(QG, K2, f * mK2));

// Note that the local isomorphism testing does not require the "WedderburnInit".

// Test if two rings of integers are ZG-isomorphic

K1 := Cougnard_Nd_adjoin(1, 5 : opt);
K2 := Cougnard_Nd_adjoin(1, 221);
G1, _, mK1 := AutomorphismGroup(K1);
G2, _, mK2 := AutomorphismGroup(K2);
QG := GroupAlgebra(Rationals(), G1);
_, f := IsIsomorphic(G1, G2);
WedderburnInit(QG);
I1 := IntegersToIdeal(QG, K1, mK1);
I2 := IntegersToIdeal(QG, K2, f * mK2);
b := IsIsomorphic(QG, I1, I2);

// Now test if O_K1 is free ZG-module

isfree := IsIsomorphic(QG, I1, IdentityMatrix(Rationals(), 16));

// Now test if O_K1 is locally free ZG-module

IsLocallyFree(QG, I1);

// Now test if two things are locally isomorphic (at 2)

IsLocallyIsomorphic(QG, I1, I2);

IsLocallyIsomorphic(QG, I1, I2, 2);

// Now test if an ideal is free ZG-module

A := &*[ P[1] : P in Decomposition(MaximalOrder(K1), 17)];
I3 := IdealToIdeal(QG, K1, A, mK1);
isfree := IsIsomorphic(QG, I3, IdentityMatrix(Rationals(), 16));

// Now compute the generator of a normal integral basis

b, alpha := HasNormalIntegralBasis(K1);

// It also works with C2 and Q8 extensions.
