#############################################################################
##
#W  basismut.gd                 GAP library                     Thomas Breuer
##
#H  @(#)$Id: basismut.gd,v 4.16 2002/04/15 10:04:29 sal Exp $
##
#Y  Copyright (C)  1996,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
#Y  (C) 1998 School Math and Comp. Sci., University of St.  Andrews, Scotland
#Y  Copyright (C) 2002 The GAP Group
##
##  This file declares the categories and operations for mutable bases.
#1
##  It is useful to have a *mutable basis* of a free module when successively
##  closures with new vectors are formed, since one does not want to create
##  a new module and a corresponding basis for each step.
##  
##  Note that the situation here is different from the situation with
##  stabilizer chains, which are (mutable or immutable) records that do not
##  need to know about the groups they describe,
##  whereas each (immutable) basis stores the underlying left module
##  (see~"UnderlyingLeftModule").
## 
##  So immutable bases and mutable bases are different categories of objects.
##  The only thing they have in common is that one can ask both for
##  their basis vectors and for the coefficients of a given vector.
##  
##  Since `Immutable' produces an immutable copy of any {\GAP} object,
##  it would in principle be possible to construct a mutable basis that
##  is in fact immutable.
##  In the sequel, we will deal only with mutable bases that are in fact
##  *mutable* {\GAP} objects,
##  hence these objects are unable to store attribute values.
##
##  Basic operations for immutable bases are `NrBasisVectors'
##  (see~"NrBasisVectors"), `IsContainedInSpan' (see~"IsContainedInSpan"),
##  `CloseMutableBasis' (see~"CloseMutableBasis"),
##  `ImmutableBasis' (see~"ImmutableBasis"), `Coefficients'
##  (see~"Coefficients"), and `BasisVectors' (see~"BasisVectors").
##  `ShallowCopy' (see~"ShallowCopy") for a mutable basis returns a mutable
##  plain list containing the current basis vectors.
#T Also `LeftActingDomain' (or the analogy for it) should be a basic
#T operation; up to now, apparantly one can avoid it,
#T but conceptually it should be available!
##
##  Since mutable bases do not admit arbitrary changes of their lists of
##  basis vectors, a mutable basis is *not* a list.
##  It is, however, a collection, more precisely its family (see~"Families")
##  equals the family of its collection of basis vectors.
##
##  Mutable bases can be constructed with `MutableBasis'.
##
##  Similar to the situation with bases (cf.~"Bases of Vector Spaces"),
##  {\GAP} supports the following three kinds of mutable bases.
##
##  The *generic method* of `MutableBasis' returns a mutable basis that
##  simply stores an immutable basis;
##  clearly one wants to avoid this whenever possible with reasonable effort.
##
##  There are mutable bases that store a mutable basis for a nicer module.
#T  This works if we have access to the mechanism of computing nice vectors,
#T  and requires the construction with
#T  `MutableBasisViaNiceMutableBasisMethod2' or
#T  `MutableBasisViaNiceMutableBasisMethod3'!
##  Note that this is meaningful only if the mechanism of computing nice and
##  ugly vectors (see~"Vector Spaces Handled By Nice Bases") is invariant
##  under closures of the basis;
##  this is the case for example if the vectors are matrices, Lie objects,
##  or elements of structure constants algebras. 
##
##  There are mutable bases that use special information to perform their
##  tasks; examples are mutable bases of Gaussian row and matrix spaces.
##
Revision.basismut_gd :=
    "@(#)$Id: basismut.gd,v 4.16 2002/04/15 10:04:29 sal Exp $";


#############################################################################
##
#C  IsMutableBasis( <MB> )
##
##  Every mutable basis lies in the category `IsMutableBasis'.
##
DeclareCategory( "IsMutableBasis", IsObject );


#############################################################################
##
#O  MutableBasis( <R>, <vectors>[, <zero>] )
##
##  `MutableBasis' returns a mutable basis for the <R>-free module generated
##  by the vectors in the list <vectors>.
##  The optional argument <zero> is the zero vector of the module;
##  it must be given if <vectors> is empty.
##
##  *Note* that <vectors> will in general *not* be the basis vectors of the
##  mutable basis!
#T provide `AddBasisVector' to achieve this?
##
DeclareOperation( "MutableBasis", [ IsRing, IsCollection ] );


#############################################################################
##
#F  MutableBasisViaNiceMutableBasisMethod2( <R>, <vectors> )
#F  MutableBasisViaNiceMutableBasisMethod3( <R>, <vectors>, <zero> )
##
##  Let $M$ be the <R>-free left module generated by the vectors in the list
##  <vectors>, and assume that $M$ is handled via nice bases.
##  `MutableBasisViaNiceMutableBasisMethod?' returns a mutable basis for $M$.
##  The optional argument <zero> is the zero vector of the module.
##
##  *Note* that $M$ is stored, and that it is used in calls to `NiceVector'
##  and `UglyVector', and for accessing <R>.
##  (See the remark in the beginning of the file.)
##
DeclareGlobalFunction( "MutableBasisViaNiceMutableBasisMethod2" );

DeclareGlobalFunction( "MutableBasisViaNiceMutableBasisMethod3" );


#############################################################################
##
#O  NrBasisVectors( <MB> )
##
##  For a mutable basis <MB>, `NrBasisVectors' returns the current number of
##  basis vectors of <MB>.
##  Note that this operation is *not* an attribute, as it makes no sense to
##  store the value.
##  `NrBasisVectors' is used mainly as an equivalent of `Dimension' for the
##  underlying left module in the case of immutable bases.
##
DeclareOperation( "NrBasisVectors", [ IsMutableBasis ] );


#############################################################################
##
#O  ImmutableBasis( <MB>[, <V>] )
##
##  `ImmutableBasis' returns the immutable basis $B$, say,
##  with the same basis vectors as in the mutable basis <MB>.
##
##  If the second argument <V> is present then <V> is the value of
##  `UnderlyingLeftModule' (see~"UnderlyingLeftModule") for $B$.
##  The second variant is used mainly for the case that one knows the module
##  for the desired basis in advance, and if it has a nicer structure than
##  the module known to <MB>, for example if it is an algebra.
#T  This happens for example if one constructs a basis of an ideal using
#T  iterated closures of a mutable basis, and the final basis $B$ shall
#T  have the initial ideal as underlying module.
##
DeclareOperation( "ImmutableBasis", [ IsMutableBasis ] );

DeclareOperation( "ImmutableBasis", [ IsMutableBasis, IsFreeLeftModule ] );


#############################################################################
##
#O  CloseMutableBasis( <MB>, <v> )
##
##  For a mutable basis <MB> over the coefficient ring $R$, say,
##  and a vector <v>, `CloseMutableBasis' changes <MB> such that afterwards
##  it describes the $R$-span of the former basis vectors together with <v>.
##
##  *Note* that if <v> enlarges the dimension then this does in general *not*
##  mean that <v> is simply added to the basis vectors of <MB>.
##  Usually a linear combination of <v> and the other basis vectors is added,
##  and also the old basis vectors may be modified, for example in order to
##  keep the list of basis vectors echelonized (see~"IsSemiEchelonized").
##
DeclareOperation( "CloseMutableBasis",
    [ IsMutableBasis and IsMutable, IsVector ] );


#############################################################################
##
#O  IsContainedInSpan( <MB>, <v> )
##
##  For a mutable basis <MB> over the coefficient ring $R$, say,
##  and a vector <v>, `IsContainedInSpan' returns `true' is <v> lies in the
##  $R$-span of the current basis vectors of <MB>,
##  and `false' otherwise.
##
DeclareOperation( "IsContainedInSpan", [ IsMutableBasis, IsVector ] );


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

