#!/bin/sh
#############################################################################
##
#W  mtog             GAP share package 'atlasrep'               Thomas Breuer
##
#H  @(#)$Id: mtog,v 1.2 2001/01/22 18:12:09 gap Exp $
##
#Y  Copyright (C)  2001,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
##
##  This script translates Magma format files with definitions of
##  matrix groups over the integers or over a ring of algebraic integers
##  (as contained in Rob Wilson's Atlas of Group Representations)
##  to {\GAP} readable format.
##
##  For producing <outfile> from <infile>,
##  just call 'mtog <infile> <outfile>'.
##
##  The output file can be read into {\GAP} with 'ReadAsFunction',
##  which yields a function whose return value is the list of generating
##  matrices.
##
awk -v "INFILE=$1" \
    'BEGIN {
         FS = ";";

         # Turn the comment into a GAP comment.
         while ( getline < INFILE && $0 !~ /^\*\// ) {
             printf( "# %s\n", $0 );
         }
         printf( "# %s\n", $0 );

         # Skip empty lines.
         while ( getline < INFILE && $0 ~ /^$/ ) {
         }

         reduce = "";

         if ( $0 ~ /RationalField/ || $0 ~ /Rationals\(/ ) {
             # No irrationalities occur.
             printf( "# %s\n", $0 );
             getline < INFILE
         }
         else {
             # Define quadratic irrationalities or roots of unity if present.
             # (Declare each irrationality as a local variable.)
             if ( $0 ~ /F<.*QuadraticField/ || $0 ~ /F<.*CyclotomicField/ ) {

                 printf( "# %s\n", $0 );
                 n = index( $0, "F<" ) + 2;
                 irrnam = substr( $0, n, index( $0, ">" ) - n );
                 locals = irrnam;
                 n = index( $0, "(" ) + 1;
                 n = substr( $0, n, index( $0, ")" )-n );
                 if ( $0 ~ /F<.*QuadraticField/ ) {
                   assign = irrnam ":= Sqrt(" n ")"
                 }
                 else {
                   assign = irrnam ":= E(" n ")"
                 }

                 for ( j = 2; j < NF; j++ ) {
                     k = index( $j, ":=" );
                     locals = locals ", " substr( $j, 1, k-1 );
                     assign = assign ";\n" $j;
                 }

                 printf( "local %s;\n", locals );
                 printf( "%s;\n", assign )

                 # Skip lines starting with '//' or involving 'PolynomialRing'.
                 while ( getline < INFILE && ( $0 ~ /^\/\// || $0 ~ /PolynomialRing/ ) ) {
                     printf( "# %s\n", $0 );
                 }
             }
             else {

                 # The representation may be written over a residue class ring.
                 if ( $0 ~ /:=Integers\(/ ) {
                     n = index( $0, "Integers(" ) + 9;
                     modulus = substr( $0, n, index( $0, ")" ) - n );
                     reduce = "*One(ZmodnZ(" modulus "))";
                     getline < INFILE
                 }
                 else {
                     printf( "# %s\n", $0 );
                     print( "not rational, quadratic, cycl. field in \"",
                            INFILE, "\"" ) > "/dev/stderr";
                     getline < INFILE
                 }
             }
         }

         # Skip empty lines.
         if ( $0 ~ /^$/ ) {
             while ( getline < INFILE && $0 ~ /^$/ ) {
             }
         }

         if ( $0 ~ /MatrixGroup/ ) {
             # Get the dimension.
             n = index( $0, "MatrixGroup<" ) + 12;
             nn = index( $0, ",F" );
             if ( nn == 0 ) {
                 nn = index( $0, ",Z" )
             }
             if ( nn == 0 ) {
                 print( "dimension not found in \"",
                        INFILE, "\"" ) > "/dev/stderr";
             }
             dim = substr( $0, n, nn - n );

             # Write the assignment.
             printf( "return List( [ [\n" );

         }
         else {
             printf( "# %s\n", $0 );
             print( "strange line in \"" INFILE "\":\n" $0 ) > "/dev/stderr"
         }

         # Copy the matrix entries.
         # (Replace '\[' by '[' where it occurs.)
         while ( getline < INFILE && $0 !~ /^>;/ ) {
             n = index( $0, "\[" );
             if ( n == 0 ) {
                 print( $0 );
             }
             else {
                 printf( "%s[", substr( $0, 1, n-1 ) );
                 line = substr( $0, n+2 );
                 n = index( line, "\[" );
                 while ( n != 0 ) {
                     printf( "%s[", substr( $0, 1, n-1 ) );
                     line = substr( $0, n+2 );
                     n = index( line, "\[" );
                 }
                 printf( "%s\n", line );
             }
         }
         printf( "], l -> List( [ 0 .. %s ], i -> l{ [ i*%s+1 .. (i+1)*%s ] } ) )%s;\n", dim-1, dim, dim, reduce );
     }' $1 > $2


#############################################################################
##
#E

