#############################################################################
##
##  forms.gd              'Forms' package
##                                                              John Bamberg
##                                                              Jan De Beule
##
##  Copyright 2007, Ghent University
##
##  Declaration matter for quadratic and sesquilinear forms
##
#############################################################################

#############################################################################
# Categories and representations:
#############################################################################

BindGlobal( "FormFamily", NewFamily( "FormFamily" ) );
DeclareCategory( "IsForm", IsAttributeStoringRep );
DeclareRepresentation( "IsFormRep", IsForm, [ "matrix", "basefield", "type" ] );

DeclareCategory( "IsQuadraticForm", IsForm );
DeclareCategoryCollections( "IsQuadraticForm" );

DeclareCategory( "IsSesquilinearForm", IsForm );
DeclareCategoryCollections( "IsSesquilinearForm" );

DeclareCategory( "IsBilinearForm", IsSesquilinearForm );
DeclareCategoryCollections( "IsBilinearForm" );

DeclareCategory( "IsHermitianForm", IsSesquilinearForm );
DeclareCategoryCollections( "IsHermitianForm" );

DeclareCategory( "IsTrivialForm", IsForm );
DeclareCategoryCollections( "IsTrivialForm" );

BindGlobal( "QuadraticFormFamily", 
            NewFamily( "QuadraticFormFamily", IsObject, IsQuadraticForm ) );  
BindGlobal( "QuadraticFormCollFamily", CollectionsFamily(QuadraticFormFamily) );
BindGlobal( "QuadraticFormType", 
            NewType( QuadraticFormFamily, IsQuadraticForm and IsFormRep) );

BindGlobal( "SesquilinearFormFamily", 
            NewFamily( "SesquilinearFormFamily", IsObject, IsSesquilinearForm ) );	
BindGlobal( "SesquilinearFormCollFamily", CollectionsFamily(SesquilinearFormFamily) );
BindGlobal( "SesquilinearFormType", 
            NewType( SesquilinearFormFamily, IsSesquilinearForm and IsFormRep) );

BindGlobal( "BilinearFormFamily", 
            NewFamily( "BilinearFormFamily", IsObject, IsBilinearForm ) );	    
BindGlobal( "BilinearFormCollFamily", CollectionsFamily(BilinearFormFamily) );
BindGlobal( "BilinearFormType", 
            NewType( BilinearFormFamily, IsBilinearForm and IsFormRep) );

BindGlobal( "HermitianFormFamily", 
            NewFamily( "HermitianFormFamily", IsObject, IsHermitianForm ) );	    
BindGlobal( "HermitianFormCollFamily", CollectionsFamily(HermitianFormFamily) );
BindGlobal( "HermitianFormType", 
            NewType( HermitianFormFamily, IsHermitianForm and IsFormRep) );

BindGlobal( "TrivialFormFamily", 
            NewFamily( "TrivialFormFamily", IsObject, IsTrivialForm ) );	    
BindGlobal( "TrivialFormCollFamily", CollectionsFamily(TrivialFormFamily) );
BindGlobal( "TrivialFormType", 
            NewType( TrivialFormFamily, IsTrivialForm and IsFormRep) );


#############################################################################
# Constructor operations:
#############################################################################
				    
DeclareOperation( "FormByMatrix", [IsMatrix and IsFFECollColl, IsField, IsString] );
DeclareOperation( "BilinearFormByMatrix", [IsMatrix and IsFFECollColl, IsField] );
DeclareOperation( "HermitianFormByMatrix", [IsMatrix and IsFFECollColl, IsField] );
DeclareOperation( "QuadraticFormByMatrix", [IsMatrix and IsFFECollColl, IsField] );

## the user probably won't use this one
DeclareOperation( "FormByPolynomial", 
                      [IsPolynomial, IsField, IsInt, IsList, IsString] );
## For the users...
DeclareOperation( "FormByPolynomial", 
                      [IsPolynomial, IsFiniteFieldPolynomialRing, IsInt, IsString] );
DeclareOperation( "BilinearFormByPolynomial", 
                      [ IsPolynomial, IsFiniteFieldPolynomialRing, IsInt ] );
DeclareOperation( "QuadraticFormByPolynomial", 
                      [ IsPolynomial, IsFiniteFieldPolynomialRing, IsInt ] );
DeclareOperation( "HermitianFormByPolynomial", 
                      [ IsPolynomial, IsFiniteFieldPolynomialRing, IsInt ] );	

## if no dimension is specified, then we use a natural default (i.e.,
## the dimension is just the number of indeterminates)

DeclareOperation( "BilinearFormByPolynomial", 
                      [ IsPolynomial, IsFiniteFieldPolynomialRing] );
DeclareOperation( "QuadraticFormByPolynomial", 
                      [ IsPolynomial, IsFiniteFieldPolynomialRing] );
DeclareOperation( "HermitianFormByPolynomial", 
                      [ IsPolynomial, IsFiniteFieldPolynomialRing] );		     
 
DeclareOperation( "BaseChangeToCanonical", [IsForm] );

## helper operations
DeclareOperation( "GramMatrixByPolynomialForQuadraticForm",                   
                      [IsPolynomial, IsField, IsInt, IsList] );
DeclareOperation( "GramMatrixByPolynomialForHermitianForm", 
                      [IsPolynomial, IsField, IsInt, IsList] );
DeclareOperation( "BaseChangeOrthogonalBilinear", 
                      [IsMatrix and IsFFECollColl, IsField and IsFinite] );
DeclareOperation( "BaseChangeOrthogonalQuadratic", 
                      [IsMatrix and IsFFECollColl, IsField and IsFinite] );
DeclareOperation( "BaseChangeSymplectic", 
                      [IsMatrix and IsFFECollColl, IsField and IsFinite] );
DeclareOperation( "BaseChangeHermitian",  
                      [IsMatrix and IsFFECollColl, IsField and IsFinite] );

#############################################################################
# Functions (not to be used by the user):
#############################################################################

DeclareGlobalFunction( "SWR" );
DeclareGlobalFunction( "SUM_OF_SQUARES" );
DeclareGlobalFunction( "REDUCE2" );
DeclareGlobalFunction( "REDUCE4" );
DeclareGlobalFunction( "DIFF_2_S" );
DeclareGlobalFunction( "RESET" );
DeclareGlobalFunction( "SQRT2" );
DeclareGlobalFunction( "PERM_VAR" );
DeclareGlobalFunction( "C1" );
DeclareGlobalFunction( "QUAD_EQ");
DeclareGlobalFunction( "HERM_CONJ" );

#############################################################################
# Functions (most likely not for the user):
#############################################################################

DeclareOperation( "IsSymplecticMatrix",[IsFFECollColl, IsField] );
DeclareOperation( "IsOrthogonalMatrix", [IsFFECollColl] );
DeclareOperation( "IsHermitianMatrix", [IsFFECollColl, IsField] );

#############################################################################
# Other operations:
#############################################################################

## Attributes
DeclareAttribute( "IsDegenerateForm", IsForm );
DeclareAttribute( "GramMatrix", IsForm );
DeclareAttribute( "RadicalOfForm", IsForm );
DeclareAttribute( "IsReflexiveForm", IsForm );
DeclareAttribute( "WittIndex", IsForm ); 
DeclareAttribute( "IsometricCanonicalForm", IsForm );
DeclareAttribute( "DiscriminantOfForm", IsForm );
DeclareAttribute( "PolynomialOfForm", IsForm );
DeclareAttribute( "IsAlternatingForm", IsBilinearForm );
DeclareAttribute( "IsSymmetricForm", IsBilinearForm );

## Properties
DeclareProperty( "IsEllipticForm", IsForm );
DeclareProperty( "IsParabolicForm", IsForm );
DeclareProperty( "IsHyperbolicForm", IsForm );
DeclareProperty( "IsSymplecticForm", IsForm );

## Operations
DeclareOperation( "BaseChangeHomomorphism", [ IsMatrix and IsFFECollColl, IsField ] );
DeclareOperation( "EvaluateForm", [ IsBilinearForm, 
       IsVector and IsFFECollection, IsVector and IsFFECollection]);
DeclareOperation( "EvaluateForm", [ IsHermitianForm, 
       IsVector and IsFFECollection, IsVector and IsFFECollection]);
DeclareOperation( "EvaluateForm", [ IsBilinearForm, IsFFECollColl, IsFFECollColl]);
DeclareOperation( "EvaluateForm", [ IsHermitianForm, IsFFECollColl, IsFFECollColl]);
DeclareOperation( "EvaluateForm", [ IsQuadraticForm, IsVector and IsFFECollection]);




