Handbook Volume 01
Handbook Volume 01
Volume 1
Language, Aggregates and Semigroups
John Cannon Wieb Bosma
Editors
Version 2.13
Sydney
September 22, 2006
ii
MAGMA
C O M P U T E R A L G E B R A
HANDBOOK OF MAGMA FUNCTIONS
Editors:
John Cannon Wieb Bosma
Handbook Contributors:
Geo Bailey, Wieb Bosma, Gavin Brown, Herbert Br uck-
ner, Nils Bruin, John Cannon, Jon Carlson, Scott Contini,
Bruce Cox, Steve Donnelly, Willem de Graaf, Claus Fieker,
Volker Gebhardt, Sergei Haller, Michael Harrison, Florian
He, David Kohel, Axel Kohnert, Dimitri Leemans, Paulette
Lieby, Graham Matthews, Scott Murray, Eamonn OBrien,
Ben Smith, Bernd Souvignier, William Stein, Allan Steel,
Nicole Sutherland, Don Taylor, Bill Unger, Alexa van der
Waall, Paul van Wamelen, Helena Verrill, John Voight, Mark
Watkins, Greg White
Production Editors:
Wieb Bosma Claus Fieker Allan Steel Nicole Sutherland
HTML Production:
Claus Fieker Allan Steel
PREFACE
The computer algebra system Magma is designed to provide a software environment for
computing with the structures which arise in areas such as algebra, number theory, al-
gebraic geometry and (algebraic) combinatorics. Magma enables users to dene and to
compute with structures such as groups, rings, elds, modules, algebras, schemes, curves,
graphs, designs, codes and many others. The main features of Magma include:
Algebraic Design Philosophy: The design principles underpinning both the user lan-
guage and system architecture are based on ideas from universal algebra and category
theory. The language attempts to approximate as closely as possible the usual mathe-
matical modes of thought and notation. In particular, the principal constructs in the
user language are set, (algebraic) structure and morphism.
Explicit Typing: The user is required to explicitly dene most of the algebraic structures
in which calculations are to take place. Each object arising in the computation is then
dened in terms of these structures.
Integration: The facilities for each area are designed in a similar manner using generic
constructors wherever possible. The uniform design makes it a simple matter to pro-
gram calculations that span dierent classes of mathematical structures or which involve
the interaction of structures.
Relationships: Magma provides a mechanism that manages relationships between
complex bodies of information. For example, when substructures and quotient struc-
tures are created by the system, the natural homomorphisms that arise are always
stored. These are then used to support automatic coercion between parent and child
structures.
Mathematical Databases: Magma has access to a large number of databases containing
information that may be used in searches for interesting examples or which form an
integral part of certain algorithms. Examples of current databases include factorizations
of integers of the form p
n
1, p a prime; modular equations; strongly regular graphs;
maximal subgroups of simple groups; integral lattices; K3 surfaces; best known linear
codes and many others.
Performance: The intention is that Magma provide the best possible performance
both in terms of the algorithms used and their implementation. The design philosophy
permits the kernel implementor to choose optimal data structures at the machine level.
Most of the major algorithms currently installed in the Magma kernel are state-of-the-
art and give performance similar to, or better than, specialized programs.
The theoretical basis for the design of Magma is founded on the concepts and methodology
of modern algebra. The central notion is that of an algebraic structure. Every object
created during the course of a computation is associated with a unique parent algebraic
structure. The type of an object is then simply its parent structure.
vi PREFACE
Algebraic structures are rst classied by variety: a variety being a class of structures
having the same set of dening operators and satisfying a common set of axioms. Thus,
the collection of all rings forms a variety. Within a variety, structures are partitioned into
categories. Informally, a family of algebraic structures forms a category if its members all
share a common representation. All varieties possess an abstract category of structures
(the nitely presented structures). However, categories based on a concrete representation
are as least as important as the abstract category in most varieties. For example, within
the variety of algebras, the family of nitely presented algebras constitutes an abstract
category, while the family of matrix algebras constitutes a concrete category.
Magma comprises a novel user programming language based on the principles outlined
above together with program code and databases designed to support computational re-
search in those areas of mathematics which are algebraic in nature. The major areas
represented in Magma V2.13 include group theory, ring theory, commutative algebra,
arithmetic elds and their completions, module theory and lattice theory, nite dimen-
sional algebras, Lie theory, representation theory, the elements of homological algebra,
general schemes and curve schemes, modular forms and modular curves, nite incidence
structures, linear codes and much else.
This set of volumes (known as the Handbook) constitutes the main reference work on
Magma. It aims to provide a comprehensive description of the Magma language and the
mathematical facilities of the system, In particular, it documents every function and oper-
ator available to the user. Our aim (not yet achieved) is to list not only the functionality
of the Magma system but also to show how the tools may be used to solve problems in
the various areas that fall within the scope of the system. This is attempted through the
inclusion of tutorials and sophisticated examples. Finally, starting with the edition corre-
sponding to release V2.8, this work aims to provide some information about the algorithms
and techniques employed in performing sophisticated or time-consuming operations. It will
take some time before this goal is fully realised.
We give a brief overview of the organization of the Handbook.
Volume 1 contains a terse summary of the language together with a description of the
central datatypes: sets, sequences, tuples, mappings, etc. It also describes the facilities
for semigroups and monoids. An index of all intrinsics appears at the end of the volume.
Volume 2 describes the facilities for nite groups and, in particular, discusses permu-
tation groups, matrix groups and nite soluble groups dened by a power-conjugate
presentation. A chapter is devoted to databases of groups.
Volume 3 describes the machinery provided for innite groups. In Magma these cor-
respond mainly to various kinds of nitely presented groups. Included are abelian
groups, general nitely presented groups, polycyclic groups, braid groups, automatic
groups and subgroups of PSL
2
(R).
Volume 4 deals with basic rings and linear algebra. The rings include the integers, the
rationals, nite elds, univariate and multivariate polynomial rings and the real and
complex elds. The linear algebra section covers matrices and vector spaces.
PREFACE vii
Volume 5 covers ring extensions. The major topics are number elds and their orders,
function elds, local rings and elds, power series rings including Laurent and Puiseux
series rings, and algebraically closed elds.
Volume 6 is devoted to module theory and (linear) algebras. The module theory in-
cludes R-modules, basic homological algebra and lattices. Most of the material relating
to algebras is concerned with nite dimensional associate algebras including matrix
algebras, group algebras, basic algebras and quaternion algebras.
Volume 7 is concerned with representation theory and Lie theory. The representa-
tion theory includes K[G]-modules, character theory and invariant theory. Lie theory
includes root systems, root data, Lie algebras, Coxeter groups, reection groups, Lie
groups and quantum groups.
Volume 8 covers commutative algebra and algebraic geometry. The commutative alge-
bra material includes constructive ideal theory, ane algebras and modules over ane
algebras. In algebraic geometry, the main topics are schemes, curves and surfaces.
Volume 9 describes the machinery pertaining to arithmetic geometry. The main topics
include the arithmetic properties of low genus curves such as elliptic and hyperelliptic
curves, modular curves and modular forms and L-series.
In general terms, Volume 10 is concerned with combinatorial theory and (nite) inci-
dence structures. The topics include graphs, designs, nite planes, incidence geometry,
linear codes, pseudo-random sequences and a small chapter on optimization (linear
programming).
Although the Handbook has been compiled with care, it is possible that the semantics of
some facilities have not been described adequately. We regret any inconvenience that this
may cause, and we would be most grateful for any comments and suggestions for improve-
ment. We would like to thank users for numerous helpful suggestions for improvement and
for pointing out misprints in previous versions.
The development of Magma has only been possible through the dedication and enthu-
siasm of a group of very talented mathematicians and computer scientists. Since 1990,
the principal members of the Magma group have included: Geo Bailey, Mark Bonger,
Wieb Bosma, Gavin Brown, John Brownie, Herbert Br uckner, Nils Bruin, Steve Collins,
Scott Contini, Bruce Cox, Steve Donnelly, Willem de Graaf, Claus Fieker, Damien Fisher,
Alexandra Flynn, Volker Gebhardt, Katharina Geiler, Sergei Haller, Michael Harrison,
Emanuel Herrmann, Florian He, David Kohel, Paulette Lieby, Graham Matthews, Scott
Murray, Anne OKane, Catherine Playoust, Richard Rannard, Colva Roney-Dougal, An-
drew Solomon, Bernd Souvignier, Ben Smith, Allan Steel, Damien Stehle, Nicole Suther-
land, Bill Unger, John Voight, Alexa van der Waall, Mark Watkins and Greg White.
John Cannon
Sydney, June 2006
ACKNOWLEDGEMENTS
The Magma Development Team
Current Members
Geo Bailey, BSc (Hons) (Sydney), [1995-]: Main interests include elliptic curves (espe-
cially those dened over the rationals), virtual machines and computer language design.
Has implemented part of the elliptic curve facilities especially the calculation of Mordell-
Weil groups. Other main areas of contribution include combinatorics, local elds and the
Magma system internals.
John Cannon Ph.D. (Sydney), [1971-]: Research interests include computational meth-
ods in algebra, geometry, number theory and combinatorics; the design of mathematical
programming languages and the integration of databases with Computer Algebra systems.
Contributions include overall concept and planning, language design, specic design for
many categories, numerous algorithms (especially in group theory) and general manage-
ment.
Steve Donnelly, Ph.D. (Georgia) [2005-]: Research interests are in arithmetic geometry.
Major contributions have been to the elliptic curve machinery with particular emphasis on
descent methods.
Claus Fieker, Ph.D. (TU Berlin), [2000-]: Formerly a member of the KANT project.
Research interests are in constructive algebraic number theory and, especially, relative
extensions and computational class eld theory. Main contributions are the development
of explicit algorithmic class eld theory in the case of both number and function elds.
Contributed to the module theory over Dedekind domains and is currently developing
generic constructive techniques for Drinfeld modules.
Damien Fisher, BSc (Advanced) (Sydney), BSc (Hons) (UNSW), [2002-]: Implemented
a new package for p-adic rings and their extensions that places a strong emphasis on fast
arithmetic. Played a major role in the installation (in 2004-2005) of the MPFR package
in place of the previous MP and Pari real packages. Current projects focus on extensions
to the Magma language, and include a Magma proler.
Sergei Haller, Ph.D. (Eindhoven) [2004, 2006-]: Works in the area of linear algebraic
groups. Implemented new algorithms for element operations in (split and twisted) groups
of Lie type, non-reduced and extended root data, Cartan type Lie algebras, Galois coho-
mology, and cohomology of nite non-abelian groups.
Michael Harrison, Ph.D. (Cambridge,UK 1992), [2003-]: Research interests are in num-
ber theory, arithmetic and algebraic geometry. Implemented the p-adic methods for count-
ing points on hyperelliptic curves and their Jacobians over nite elds: Kedlayas method
x ACKNOWLEDGEMENTS
and the modular parameter method of Mestre. Currently working on machinery for general
surfaces and cohomology for projective varieties.
Allan Steel, BA (Hons, University Medal) (Sydney), [1989-]: Has developed many of
the fundamental data structures and algorithms in Magma for multiprecision integers,
nite elds, matrices and modules, polynomials and Grobner bases, aggregates, memory
management, environmental features, and the package system, and has also worked on the
Magma language interpreter. In collaboration, he has developed the code for lattice theory
(with Bernd Souvignier), invariant theory (with Gregor Kemper) and module theory (with
Jon Carlson and Derek Holt).
Damien Stehle, Ph.D. (Nancy) [2006]: Works in the areas of algorithmic number theory
(in particular, the geometry of numbers) and computer arithmetic. Implemented the
proveably correct oating-point LLL algorithm together with a number of fast non-rigorous
variants.
Nicole Sutherland, BSc (Hons) (Macquarie), [1999-]: Works in the areas of number
theory and algebraic geometry. Developed the machinery for Newton polygons and lazy
power series and contributed to the code for local elds, number elds, modules over
Dedekind domains, function elds, schemes and has done some work with Algebras.
Bill Unger, Ph.D. (Sydney), [1998-]: Works in computational group theory, with par-
ticular emphasis on algorithms for permutation and matrix groups. Implemented many
of the current permutation and matrix group algorithms for Magma, in particular BSGS
verication, solvable radical and chief series algorithms. Recently developed a new method
for computing character tables of nite groups.
John Voight, Ph.D. (Berkeley) [2005-]: Works in the area of algebraic number theory and
arithmetic geometry. Implemented algorithms for quaternion algebras (including recogni-
tion functions, and computation of maximal orders and ideal classes over number elds),
associative orders (with Nicole Sutherland), and Shimura curves.
Greg White, BSc (Hons) (Sydney), [2000-]: Research interests include cryptography and
coding theory. Contributions include a database of best known linear codes database for
binary and quaternary codes, machinery for codes over nite rings, and a package for
Young Tableaux. Current projects include discrete logarithms in nite elds and quantum
error correcting codes.
ACKNOWLEDGEMENTS xi
Former Members
Wieb Bosma, [1989-1996]: Responsible for the initial development of number theory
in Magma and the coordination of work on commutative rings. Also has continuing
involvement with the design of Magma.
Gavin Brown,[1998-2001]: Developed code in basic algebraic geometry, applications of
Grobner bases, number eld and function eld kernel operations; applications of Hilbert
series to lists of varieties.
Herbert Br uckner, [19981999]: Developed code for constructing the ordinary irre-
ducible representations of a nite soluble group and the maximal nite soluble quotient of
a nitely presented group.
Nils Bruin, [20022003]: Contributions include Selmer groups of elliptic curves and hy-
perelliptic Jacobians over arbitrary number elds, local solubility testing for arbitrary pro-
jective varieties and curves, Chabauty-type computations on Weil-restrictions of elliptic
curves and some algorithms for, and partial design of, the dierential rings module.
Bruce Cox, [19901998]: A member of the team that worked on the design of the Magma
language. Responsible for implementing much of the rst generation Magma machinery
for permutation and matrix groups.
Alexandra Flynn, [19951998]: Incorporated various Pari modules into Magma, and
developed much of the machinery for designs and nite planes.
Volker Gebhardt, [19992003]: Author of the Magma categories for innite polycyclic
groups and for braid groups. Other contributions include machinery for general nitely
presented groups.
Katharina Geiler, [19992001]: Developed the code for computing Galois groups of
number elds and function elds.
Willem de Graaf, [2004-2005]: Contributed functions for computing with nite-
dimensional Lie algebras, nitely-presented Lie algebras, universal enveloping algebras
and quantum groups.
Emanuel Herrmann, [1999]: Developed code for computing integral points and S-
integral points on elliptic curves.
Florian He, [19992001]: Developed a substantial part of the algebraic function eld
module in Magma including algorithms for the computation of Riemann-Roch spaces
and class groups. His most recent contribution (2005) is a package for computing all
isomorphisms between a pair of function elds.
David Kohel, [19992002]: Contributions include a model for schemes (with G Brown);
algorithms for curves of low genus; implementation of elliptic curves, binary quadratic
forms, quaternion algebras, Brandt modules, spinor genera and genera of lattices, modular
curves, conics (with P Lieby), modules of supersingular points (with W Stein), Witt rings.
xii ACKNOWLEDGEMENTS
Paulette Lieby, [19992003]: Contributed to the development of algorithms for alge-
braic geometry, abelian groups and incidence structures. Developed datastructures for
multigraphs and implemented algorithms for planarity, triconnectivity and network ows.
Graham Matthews, [19891993]: Involved in the design of the Magma semantics, user
interface, and internal organisation.
Richard Rannard, [19971998]: Contributed to the code for elliptic curves over nite
elds including a rst version of the SEA algorithm.
Colva M. Roney-Dougal, [20012003]: Completed the classication of primitive per-
mutation groups up to degree 999 (with Bill Unger). Also undertook a constructive clas-
sication of the maximal subgroups of the classical simple groups.
Michael Slattery, [19872006]: Contributed a large part of the machinery for nite
soluble groups including subgroup lattice and automorphism group.
Ben Smith, [20002003]: Contributed to an implementation of the Number Field Sieve
and a package for integer linear programming.
Bernd Souvignier, [19961997]: Contributed to the development of algorithms and code
for lattices, local elds, nite dimensional algebras and permutation groups.
Alexa van der Waall, [2003]: Implemented the module for dierential Galois theory.
Paul B. van Wamelen, [20022003]: Implemented analytic Jacobians of hyperelliptic
curves in Magma.
Mark Watkins, [2003, 2004-2005]: Implemented a range of analytic tools for the study
of elliptic curves including analytic rank, modular degree, set of curves Q-isogenous to a
given curve, 4-descent, Heegner points and other point searching methods.
ACKNOWLEDGEMENTS xiii
External Contributors
The Magma system has beneted enormously from contributions made by many members
of the mathematical community. We list below those persons and research groups who have
given the project substantial assistance either by allowing us to adapt their software for
inclusion within Magma or through general advice and criticism. We wish to express our
gratitude both to the people listed here and to all those others who participated in some
aspect of the Magma development.
Group Theory
Constructive recognition of quasi-simple groups belonging to the Suzuki and Ree families
has been implemented by Hendrik Baarnhielm (QMUL). The package includes code for
constructing the Sylow p-subgroups of Suzuki and Ree groups.
A database of all groups having order at most 2000, excluding order 1024 has been made
available by Hans Ulrich Besche (Aachen), Bettina Eick (Braunschweig), and Ea-
monn OBrien (Auckland). This library incorporates directly the libraries of 2-groups
of order dividing 256 and the 3-groups of order dividing 729, which were prepared and
distributed at various intervals by Mike Newman (ANU) and Eamonn OBrien and
various assistants, the rst release dating from 1987.
Peter Brooksbank (Ohio) gave the Magma group permission to base its implementation
of the Kantor-Seress algorithm for black-box recognition of linear, symplectic and unitary
groups on his GAP implementations.
The soluble quotient algorithm in Magma was designed and implemented by Herbert
Br uckner (Aachen).
Michael Downward and Eamonn OBrien (Auckland) provided functions to access
much of the data in the on-line Atlas of Finite Simple Groups for the sporadic groups. A
function to select good base points for sporadic groups was provided by Eamonn and
Robert Wilson (London).
A new algorithm for computing all normal subgroups of a nitely presented group up to a
specied index has been designed and implemented by David Firth and Derek Holt.
Derek Holt (Warwick) has implemented his algorithm for testing whether two nitely
presented groups are isomorphic in Magma.
Procedures to list irreducible (soluble) subgroups of GL(2, q) and GL(3, q) for arbitrary q
are provided by Dane Flannery (Galway) and Eamonn OBrien (Auckland).
Greg Gamble (UWA) helped rene the concept of a G-set for a permutation group and
drafted several sections of the chapter on permutation groups.
The descriptions of the groups of order p
4
, p
5
, p
6
, p
7
for p > 3 were contributed by
Boris Girnat, Robert McKibbin, Mike Newman, Eamonn OBrien, and Mike
Vaughan-Lee.
xiv ACKNOWLEDGEMENTS
Versions of Magma from V2.8 onwards employ the Advanced Coset Enumerator designed
by George Havas (Queensland) and implemented by Colin Ramsay (also of Queens-
land). George has also contributed to the design of the machinery for nitely presented
groups.
Machinery for computing group cohomology and for producing group extensions has been
provided by Derek Holt (Warwick). There are two parts to this machinery. The rst
part comprises Dereks older C-language package for permutation groups while the second
part comprises a recent Magma language package for group cohomology.
Calculation of automorphism groups (for permutation and matrix groups) and determin-
ing group isomorphism (for nite groups) is performed by code written by Derek Holt
(Warwick).
Derek Holt (Warwick) developed a modied version of his program, kbmag, for inclusion
within Magma. The Magma facilities for groups and monoids dened by conuent rewrite
systems, as well as automatic groups, are supported by this code.
Derek Holt (Warwick) has implemented the Magma version of the Bratus/Pak algorithm
for black-box recognition of the symmetric and alternating groups.
The function for determining whether a given nite permutation group is a homomor-
phic image of a nitely presented group has been implemented in C by Volker Gebhardt
(Magma) from a Magma language prototype developed by Derek Holt (Warwick).
Alexander Hulpke (Colorado State) has made available his database of all transitive
permutation groups of degree up to 30. This incorporates the earlier database of Greg
Butler (Concordia) and John McKay (Concordia) containing all transitive groups of
degree up to 15.
Most of the algorithms for p-groups and many of the algorithms implemented in Magma
for nite soluble groups are largely due to Charles LeedhamGreen (QMW, London).
The PERM package developed by Je Leon (UIC) for ecient backtrack searching in
permutation groups is used for most of the permutation group constructions that employ
backtrack search.
A Monte-Carlo algorithm to determine the dening characteristic of a quasisimple group
of Lie type has been contributed by Martin Liebeck (Imperial) and Eamonn OBrien
(Auckland).
A Monte-Carlo algorithm for non-constructive recognition of simple groups has been con-
tributed by Gunter Malle (Kaiserslautern) and Eamonn OBrien (Auckland). This
procedure includes the algorithm of Babai et al. to name a quasisimple group of Lie type.
Magma incorporates a database of the maximal nite rational subgroups of GL(n, Q) up
to dimension 31. This database is due to Gabriele Nebe (Ulm) and Wilhelm Plesken
(Aachen). A database of quaternionic matrix groups constructed by Gabriele is also in-
cluded.
ACKNOWLEDGEMENTS xv
A function that determines whether a matrix group G (dened over a nite eld) is the
normaliser of an extraspecial group in the case where the degree of G is an odd prime uses
the new Monte-Carlo algorithm of Alice Niemeyer (Perth) and has been implemented
in Magma by Eamonn OBrien (Auckland).
The NQ program of Werner Nickel (Darmstadt) is used to compute nilpotent quotients
of nitely presented groups.
The package for recognizing large degree classical groups over nite elds was designed
and implemented by Alice Niemeyer (Perth) and Cheryl Praeger (Perth). It has been
extended to include 2-dimensional linear groups by Eamonn OBrien (Auckland).
The p-quotient program, developed by Eamonn OBrien (Auckland) based on earlier
work by George Havas and Mike Newman (ANU), provides a key facility for studying
p-groups in Magma. Eamonns extensions in Magma of this package for generating p-
groups, computing automorphism groups of p-groups, and deciding isomorphism of p-
groups are also included. He has contributed software to count certain classes of p-groups
and to construct central extensions of soluble groups.
Eamonn OBrien (Auckland) has contributed a Magma implementation of algorithms
for determining the Aschbacher category of a subgroup of GL(n, q). The corresponding
sections of the Handbook were written by Eamonn.
Eamonn OBrien (Auckland) has provided implementations of constructive recognition
algorithms for matrix groups as either (P)SL(2, q) or (P)SL(3, q).
The package for classifying metacyclic p-groups has been developed by Eamonn OBrien
(Auckland) and Mike Vaughan-Lee (Oxford).
A fast algorithm for determining subgroup conjugacy based on Aschbachers theorem clas-
sifying the maximal subgroups of a linear group has been designed and implemented by
Colva Roney-Dougal (Sydney).
Colva Roney-Dougal (Sydney) has implemented the Beals et al algorithm for black-box
recognition of the symmetric and alternating groups.
A package for constructing the Sylow p-subgroups of the classical groups has been imple-
mented by Mark Stather (Warwick).
Generators for matrix representations for groups of Lie type were constructed and imple-
mented by Don Taylor (Sydney) with some assistance from Leanne Rylands (Western
Sydney).
The low index subgroup function is implemented by code that is based on a Pascal program
written by Charlie Sims (Rutgers).
A package for computing with subgroups of nite index in the group PSL(2, R) has been
developed by Helena Verrill (Hannover).
A Magma database has been constructed from the permutation and matrix representations
contained in the on-line Atlas of Finite Simple Groups with the assistance of its author
Robert Wilson (Birmingham).
xvi ACKNOWLEDGEMENTS
Basic Rings
A facility for computing with arbitrary but xed precision reals was based on Richard
Brents (ANU) FORTRAN package MP. Richard has also made available his database of
237, 578 factorizations of integers of the form p
n
1, together with his intelligent factor-
ization code FACTOR.
Ste Cavallar (CWI, Amsterdam) has adapted her code for ltering relations in the CWI
Number Field Sieve so as to run as part of the Magma Number Field Sieve.
The group headed by Henri Cohen (Bordeaux) made available parts of their Pari system
for computational number theory for inclusion in Magma. Pascal Letard of the Pari
group visited Sydney for two months in 1994 and recoded large sections of Pari for Magma.
The Pari facilities installed in Magma include arithmetic for real and complex elds (the
free model), approximately 100 special functions for real and complex numbers, quadratic
elds and other features.
Xavier Gourdon (INRIA, Paris) made available his C implementation of A. Schonhages
splitting-circle algorithm for the fast computation of the roots of a polynomial to a specied
precision. Xavier also assisted with the adaptation of his code for the Magma kernel.
One of the main integer factorization tools available in Magma is due to Arjen
K. Lenstra (EPFL) and his collaborators: a multiple polynomial quadratic sieve de-
veloped by Arjen from his factoring by email MPQS during visits to Sydney in 1995 and
1998.
The primality of integers is proven using the ECPP (Elliptic Curves and Primality Prov-
ing) package written by Fran cois Morain (Ecole Polytechnique and INRIA). The ECPP
program in turn uses the BigNum package developed jointly by INRIA and Digital PRL.
The code for Coppersmiths index-calculus algorithm (used to compute logarithms in nite
elds of characteristic 2) was developed by Emmanuel Thome (Ecole Polytechnique).
Magma uses the GMP-ECM implementation of the Elliptic Curve Method (ECM) for
integer factorisation. This was developed by Paul Zimmermann (Nancy).
Some portions of the GNU GMP multiprecision integer library (http://swox.com/gmp)
are used for integer multiplication.
Most real and complex arithmetic in Magma is based on the MPFR package which is
being developed by Paul Zimmermann (Nancy) and associates. (See www.mpfr.org).
Extensions of Rings
The algebraic function eld module in Magma is based on machinery developed in KANT.
It was further developed by Florian He (TU Berlin) while at the University of Sydney
over the period September, 1999 - January, 2001. In 2005 Florian contributed a major
package for determining all isomorphisms between a pair of algebraic function elds.
David Kohel (Singapore, Sydney) has contributed to the machinery for binary quadratic
forms and has implemented rings of Witt vectors.
ACKNOWLEDGEMENTS xvii
J urgen Kl uners (Kassel) has made major contributions to the Galois theory machinery
for function elds and number elds. In particular, he implemented the subeld and
automorphism group functions as well as the computation of the subeld lattice of the
normal closure of a eld.
J urgen Kl uners (Kassel) and Gunter Malle (Kassel) made available their extensive
tables of polynomials realising all Galois groups over Q up to degree 15.
Sebastian Pauli (TU Berlin) has implemented his algorithm for factoring polynomials
over local elds within Magma. This algorithm may also be used for the factorization of
ideals, the computation of completions of global elds, and for splitting extensions of local
elds into towers of unramied and totally ramied extensions.
Class elds over local elds are computed using a new algorithm and implementation due
to Sebastian Pauli (TU Berlin).
The facilities for general number elds in Magma are provided by the KANT V4 package
developed by Michael Pohst and collaborators, originally at D usseldorf and now at TU,
Berlin. This package provides extensive machinery for computing with maximal orders of
number elds and their ideals, Galois groups and function elds. Particularly noteworthy
are functions for computing the class group, the unit group, systems of fundamental units,
and subelds of a number eld.
Linear Algebra and Module Theory
The functions for computing automorphism groups and isometries of lattices are based on
the AUTO and ISOM programs of Bernd Souvignier (Nijmegen).
The packages for chain complexes and basic algebras have been developed by Jon F.
Carlson (Athens, GA).
Derek Holt (Warwick) has made a number of important contributions to the design of
the module theory algorithms employed in Magma.
Charles Leedham-Green (QMW, London) was responsible for the original versions of
the submodule lattice and endomorphism ring algorithms.
A collection of lattices from the on-line tables of lattices prepared by Neil Sloane (AT&T
Research) and Gabriele Nebe (Ulm) is included in Magma.
Parts of the ATLAS (Automatically Tuned Linear Algebra Software) of R. Clint Whaley
et al. are used for some fundamental matrix algorithms over machine-int-sized prime nite
elds.
Algebras and Representation Theory
Gregor Kemper (Heidelberg) has contributed most of the major algorithms of the In-
variant Theory module of Magma, together with many other helpful suggestions in the
area of Commutative Algebra.
xviii ACKNOWLEDGEMENTS
Quaternion algebras over the rational eld Q have been implemented by David Kohel
(Singapore, Sydney).
The vector enumeration program of Steve Linton (St. Andrews) provides Magma with
the capability of constructing matrix representations for nitely presented associative al-
gebras.
The Magma implementation of the DixonSchneider algorithm for computing the table
of ordinary characters of a nite group is based on an earlier version written for Cayley by
Gerhard Schneider (Karlsruhe).
John Voight generalised the machinery for quaternion algebras to apply to algebras over
number elds.
Lie Theory
The major structural machinery for Lie algebras has been implemented for Magma by
Willem de Graaf (Utrecht) and is based on his ELIAS package written in GAP.
A fast algorithm for multiplying Coxeter group elements has been designed and imple-
mented by Bob Howlett (Sydney).
The original version of the code for root systems and permutation Coxeter groups was
modelled, in part, on the Chevie package of GAP and implemented by Don Taylor
(Sydney) with the assistance of Frank L ubeck (Aachen).
The current version of Lie theory in Magma has been implemented by Scott H. Mur-
ray (Sydney) with some assistance from Don Taylor (Sydney). It includes the three
contributions listed immediately above.
Functions that construct any nite irreducible unitary reection group in C
n
have been
implemented by Don Taylor (Sydney). Extension to the innite case was implemented
by Scott H. Murray (Sydney).
Algebraic Geometry
The machinery for working with Hilbert series of polarised varieties and the associated
databases of K3 surfaces and Fano 3-folds has been constructed by Gavin Brown (War-
wick).
The Magma facility for determining the Mordell-Weil group of an elliptic curve over the
rational eld is based on the mwrank programs of John Cremona (Nottingham).
John Cremona (Nottingham) has contributed his code implementing Tates algorithm
for computing local minimal models for elliptic curves dened over number elds.
The widely-used database of all elliptic curves over Q having conductor up to 130,000
constructed by John Cremona (Nottingham) is also included.
The implementation of 3-descent on elliptic curves that is available in Magma is mainly
due to John Cremona (Nottingham) and Michael Stoll (Bremen).
ACKNOWLEDGEMENTS xix
Tim Dokchitser (Edinburgh) has implemented his techniques for computing special val-
ues of motivic L-functions in Magma.
A package contributed by Tom Fisher (Cambridge) deals with curves of genus 1 given
by models of a special kind (genus one normal curves) having degree 2, 3, 4 and 5.
Various point-counting algorithms for hyperelliptic curves have been implemented by Pier-
rick Gaudry (Ecole Polytechnique, Paris). These include an implementation of the Schoof
algorithm for genus 2 curves.
Martine Girard (Sydney) has contributed her fast code for determining the heights of a
point on an elliptic curve dened over a number eld or a function eld.
A Magma package for calculating Igusa and other invariants for genus 2 hyperelliptic
curves functions was written by Everett Howe (CCR, San Diego) and is based on gp
routines developed by Fernando RodriguezVillegas (Texas) as part of the Computa-
tional Number Theory project funded by a TARP grant.
Hendrik Hubrechts (Leuven) has made available his package for point-counting and
computing zeta-functions using deformation methods for parametrized families of hyper-
elliptic curves and their Jacobians in small, odd characteristic.
David Kohel (Singapore, Sydney) has provided implementations of division polynomials
and isogeny structures for elliptic curves, Brandt modules and modular curves. He devel-
oped the machinery for conics with Paulette Lieby (Magma), and, jointly with William
Stein (Harvard), he implemented the module of supersingular points.
Reynard Lercier (Rennes) provided much advice and assistance to the Magma group
concerning the implementation of the SEA point counting algorithm for elliptic curves.
Miles Reid (Warwick) has been heavily involved in the design and development of a
database of K3 surfaces within Magma.
Jasper Scholten (Leuven) has developed much of the code for computing with elliptic
curves over function elds.
A package for computing with modular symbols (known as HECKE) has been developed
by William Stein (Harvard). William has also provided a package for modular forms.
In 20032004, William Stein (Harvard) developed extensive machinery for computing
with modular abelian varieties within Magma.
A database of 136, 924, 520 elliptic curves with conductors up to 10
8
has been provided by
William Stein (Harvard) and Mark Watkins (Penn State).
Much of the initial development of the package for computing with hyperelliptic curves is
due to Michael Stoll (D usseldorf).
Tom Womack (Nottingham) contributed code for performing four-descent and for locat-
ing Heegner points on an elliptic curve.
xx ACKNOWLEDGEMENTS
Incidence Structures, Codes and Optimization
Michel Berkelaar (Eindhoven) gave us permission to incorporate his lp solve package
for linear programming.
The rst stage of the Magma database of Hadamard and skew-Hadamard matrices was
prepared with the assistance of Stelios Georgiou (Athens), Ilias Kotsireas (Wilfrid
Laurier) and Christos Koukouvinos (Athens). In particular, they made available their
tables of Hadamard matrices of orders 32, 36, 44, 48 and 52.
The construction of a database of Best Known Linear Codes over GF(2) was a joint project
with Markus Grassl (IAKS, Karlsruhe). Other contributors to this project include:
Andries Brouwer, Zhi Chen, Stephan Grosse, Aaron Gulliver, Ray Hill, David
Jae, Simon Litsyn, James B. Shearer and Henk van Tilborg. Markus Grassl has
also made many other contributions to the Magma coding theory machinery.
The databases of Best Known Linear Codes over GF(3) and GF(4) were constructed by
Markus Grassl (IAKS, Karlsruhe).
The Magma machinery for symmetric functions is based on the Symmetrica package
developed by Abalbert Kerber (Bayreuth) and colleagues. The Magma version was
implemented by Axel Kohnert of the Bayreuth group.
The Magma kernel code for computing with incidence geometries has been developed by
Dimitri Leemans (Brussels).
The PERM package developed by Je Leon (UIC) is used to determine automorphism
groups of codes, designs and matrices.
The calculation of the automorphism groups of graphs and the determination of graph
isomorphism is performed using Brendan McKays (ANU) program nauty (version 2.2).
Databases of graphs and machinery for generating such databases have also been made
available by Brendan. He has also collaborated in the design of the sparse graph machinery.
Graham Norton (Queensland) has provided substantial advice and help in the develop-
ment of Z
4
-codes in Magma.
The code to perform the regular expression matching in the regexp intrinsic function
comes from the V8 regexp package by Henry Spencer (Toronto).
ACKNOWLEDGEMENTS xxi
Handbook Contributors
Introduction
The Handbook of Magma Functions is the work of many individuals. It was based on a
similar Handbook written for Cayley in 1990. Up until 1997 the Handbook was mainly
written by Wieb Bosma, John Cannon and Allan Steel but in more recent times, as Magma
expanded into new areas of mathematics, additional people became involved. It is not
uncommon for some chapters to comprise contributions from 8 to 10 people. Because of
the complexity and dynamic nature of chapter authorship, rather than ascribe chapter
authors, in the table below we attempt to list those people who have made signicant
contributions to chapters.
We distinguish between:
Principal Author, i.e. one who primarily conceived the core element(s) of a chapter
and who was also responsible for the writing of a large part of its current content, and
Contributing Author, i.e. one who has written a signicant amount of content but
who has not had primary responsibility for chapter design and overall content.
It should be noted that attribution of a person as an author of a chapter carries no im-
plications about the authorship of the associated computer code: for some chapters it will
be true that the author(s) listed for a chapter are also the authors of the corresponding
code, but in many chapters this is either not the case or only partly true. Some informa-
tion about code authorship may be found in the sections Magma Development Team and
External Contributors.
The attributions given below reect the authorship of the material comprising the V2.13
edition. Since many of the authors have since moved on to other careers, we have not
been able to check that all of the attributions below are completely correct. We would
appreciate hearing of any omissions.
In the chapter listing that follows, for each chapter the start of the list of principal authors
(if any) is denoted by while the start of the list of contributing authors is denoted by .
People who have made minor contributions to one or more chapters are listed in a general
acknowledgement following the chapter listing.
xxii ACKNOWLEDGEMENTS
The Chapters
1 Statements and Expressions W. Bosma, A. Steel
2 Functions, Procedures and Packages W. Bosma, A. Steel
3 Input and Output W. Bosma, A. Steel
4 Environment and Options A. Steel W. Bosma
5 Magma Semantics G. Matthews
6 The Magma Proler D. Fisher
7 Debugging Magma Code D. Fisher
8 Introduction to Aggregates W. Bosma
9 Sets W. Bosma, J. Cannon A. Steel
10 Sequences W. Bosma, J. Cannon
11 Tuples and Cartesian Products W. Bosma
12 Lists W. Bosma
13 Coproducts A. Steel
14 Records W. Bosma
15 Mappings W. Bosma
16 Finitely Presented Semigroups J. Cannon
17 Monoids Given by Rewrite Systems D. Holt G. Matthews
18 Groups J. Cannon W. Unger
19 Permutation Groups J. Cannon B. Cox, W. Unger
20 Matrix Groups over General Rings J. Cannon B. Cox, E.A. OBrien, A. Steel
21 Matrix Groups over Finite Fields E.A. OBrien H. Baarnhielm, D. Holt,
M. Stather
22 Finite Soluble Groups J. Cannon, M. Slattery
23 Finite p-Groups E.A. OBrien
24 Generic Abelian Groups P. Lieby
25 Black-box Groups W. Unger
26 Automorphism Groups D. Holt W. Unger
27 Cohomology and Extensions D. Holt S. Haller
28 Databases of Groups W. Unger V. Gebhardt
29 Finitely Presented Abelian Groups J. Cannon
30 Finitely Presented Groups J. Cannon V. Gebhardt
31 Finitely Presented Groups: Advanced H. Br uckner, V. Gebhardt E.A. OBrien
32 Polycyclic Groups V. Gebhardt
33 Braid Groups V. Gebhardt
34 Groups Dened by Rewrite Systems D. Holt G. Matthews
35 Automatic Groups D. Holt G. Matthews
36 Groups of Straight-line Programs J. Cannon
37 Subgroups of PSL
2
(R) H. Verrill
ACKNOWLEDGEMENTS xxiii
38 Introduction to Rings W. Bosma
39 Ring of Integers W. Bosma, A. Steel S. Contini, B. Smith
40 Rational Field W. Bosma
41 Finite Fields W. Bosma, A. Steel
42 Univariate Polynomial Rings A. Steel
43 Multivariate Polynomial Rings A. Steel
44 Real and Complex Fields W. Bosma
45 Matrices A. Steel
46 Sparse Matrices A. Steel
47 Vector Spaces J. Cannon, A. Steel
48 Orders and Algebraic Fields W. Bosma, C. Fieker J. Cannon, N. Sutherland
49 Binary Quadratic Forms D. Kohel
50 Quadratic Fields W. Bosma
51 Cyclotomic Fields W. Bosma, C. Fieker
52 Class Field Theory C. Fieker
53 Algebraically Closed Fields A. Steel
54 Rational Function Fields A. Steel
55 Algebraic Function Fields F. Hess C. Fieker, N. Sutherland
56 Modules over Dedekind Domains C. Fieker, N. Sutherland
57 Valuation Rings W. Bosma
58 Newton Polygons G. Brown, N. Sutherland
59 p-adic Rings and their Extensions D. Fisher, B. Souvignier N. Sutherland
60 Galois Rings A. Steel
61 Power, Laurent and Puiseux Series A. Steel
62 Lazy Power Series Rings N. Sutherland
63 Introduction to Modules J. Cannon
64 Free Modules J. Cannon, A. Steel
65 Chain Complexes J. Carlson
66 Lattices B. Souvignier, A. Steel D. Stehle
67 Algebras J. Cannon, B. Souvignier
68 Structure Constant Algebras J. Cannon, B. Souvignier
69 Associative Algebras J. Cannon, B. Souvignier
70 Matrix Algebras J. Cannon, A. Steel J. Carlson
71 Basic Algebras J. Carlson
72 Quaternion Algebras D. Kohel, J. Voight
73 Orders of Associative Algebras J. Voight N. Sutherland
74 Finitely Presented Algebras A. Steel, S. Linton
75 Dierential Rings, Fields and Operators A. vander Waall
76 Modules over An Algebra J. Cannon, A. Steel
xxiv ACKNOWLEDGEMENTS
77 Group Algebras J. Cannon, B. Souvignier
78 K[G]-Modules and Group Representations J. Cannon, A. Steel
79 Characters of Finite Groups W. Bosma, J. Cannon
80 Representation Theory of Symmetric Groups A. Kohnert
81 Invariant Rings of Finite Groups A. Steel
82 Introduction to Lie Theory S. Murray D. Taylor
83 Coxeter Systems S. Murray D. Taylor
84 Root Systems S. Murray S. Haller, D. Taylor
85 Root Data S. Haller, S. Murray D. Taylor
86 Coxeter Groups S. Murray D. Taylor
87 Coxeter Groups as Permutation Groups S. Murray, D. Taylor
88 Reection Groups S. Murray D. Taylor
89 Groups of Lie Type S. Haller, S. Murray D. Taylor
90 Lie Algebras W. de Graaf S. Haller, S. Murray
91 Finitely Presented Lie Algebras W. de Graaf
92 Quantum Groups W. de Graaf
93 Universal Enveloping Algebras W. de Graaf
94 Ideal Theory and Grobner Bases A. Steel M. Harrison
95 Ane Algebras A. Steel
96 Modules over Ane Algebras A. Steel
97 Schemes G. Brown J. Cannon, M. Harrison, N. Sutherland
98 Algebraic Curves G. Brown N. Bruin, J. Cannon, M. Harrison
99 Resolution Graphs and Splice Diagrams G. Brown
100 Hilbert Series of Polarised Varieties G. Brown
101 Rational Curves and Conics D. Kohel, P. Lieby M. Watkins
102 Elliptic Curves G. Bailey, W. Bosma, N. Bruin, , D. Kohel, M. Watkins
103 Elliptic Curves over Finite Fields M. Harrison P. Lieby
104 Elliptic Curves over Function Fields J. Scholten
105 Models of Genus One Curves T. Fisher
106 Hyperelliptic Curves N. Bruin, , M. Harrison, D. Kohel, P. vanWamelen
107 Modular Curves D. Kohel
108 Modular Symbols W. Stein K. Buzzard
109 Brandt Modules D. Kohel
110 Supersingular Divisors on Modular Curves D. Kohel, W. Stein
111 Modular Forms W. Stein K. Buzzard
112 Modular Abelian Varieties W. Stein
113 L-functions T. Dokchitser
114 Enumerative Combinatorics G. Bailey G. White
115 Partitions, Words and Young Tableaux G. White
ACKNOWLEDGEMENTS xxv
116 Symmetric Functions A. Kohnert
117 Graphs J. Cannon, P. Lieby G. Bailey
118 Multigraphs J. Cannon, P. Lieby
119 Networks P. Lieby
120 Incidence Structures and Designs J. Cannon
121 Hadamard Matrices G. Bailey
122 Finite Planes J. Cannon
123 Incidence Geometry D. Leemans
124 Linear Codes over Finite Fields J. Cannon, A. Steel G. White
125 Algebraic-geometric Codes J. Cannon, G. White
126 Low Density Party Check Codes G. White
127 Linear Codes over Finite Rings A. Steel G. White
128 Additive Codes G. White
129 Quantum Codes G. White
130 Pseudo-random Bit Sequences S. Contini
131 Linear Programming B. Smith
General Acknowledgements
In addition to the contributors listed above, we gratefully acknowledge the contributions
to the Handbook made by the following people:
J. Brownie (group theory)
K. Geiler (Galois groups)
A. Flynn (algebras and designs)
E. Herrmann (elliptic curves)
E. Howe (Igusa invariants)
B. McKay (graph theory)
S. Pauli (local elds)
C. Playoust (data structures, rings)
C. Roney-Dougal (groups)
P. Walford (elliptic and modular functions)
T. Womack (elliptic curves)
USING THE HANDBOOK
Most sections within a chapter of this Handbook consist of a brief introduction and expla-
nation of the notation, followed by a list of Magma functions, procedures and operators.
Each entry in this list consists of an expression in a box, and an indented explanation of
use and eects. The typewriter typefont is used for commands that can be used literally;
however, one should be aware that most functions operate on variables that must have
values assigned to them beforehand, and return values that should be assigned to variables
(or the rst value should be used in an expression). Thus the entry:
Xgcd(a, b)
The extended gcd; returns integers d, l and m such that d is the greatest common divisor
of the integers a and b, and d = l a +m b.
indicates that this function could be called in Magma as follows:
g, a, b := Xgcd(23, 28);
If the function has optional named parameters, a line like the following will be found in
the description:
Proof BoolElt Default : true
The rst word will be the name of the parameter, the second word will be the type
which its value should have, and the rest of the line will indicate the default for the
parameter, if there is one. Parameters for a function call are specied by appending a
colon to the last argument, followed by a comma-separated list of assignments (using :=)
for each parameter. For example, the function call IsPrime(n: Proof := false) calls
the function IsPrime with argument n but also with the value for the parameter Proof
set to false.
Whenever the symbol # precedes a function name in a box, it indicates that the par-
ticular function is not yet available but should be in the future.
An index is provided at the end of each volume which contains all the intrinsics in the
Handbook.
Running the Examples
All examples presented in this Handbook are available to Magma users. If your Magma
environment has been set up correctly, you can load the source for an example by using
the name of the example as printed in boldface at the top (the name has the form HmEn,
where m is the Chapter number and n is the Example number). So, to run the rst
example in the Chapter 28, type:
load "H28E1";
xxviii USING THE HANDBOOK
VOLUME 1: OVERVIEW
I THE MAGMA LANGUAGE . . . . . . . . . . . . 1
1 STATEMENTS AND EXPRESSIONS 3
2 FUNCTIONS, PROCEDURES AND PACKAGES 33
3 INPUT AND OUTPUT 57
4 ENVIRONMENT AND OPTIONS 85
5 MAGMA SEMANTICS 107
6 THE MAGMA PROFILER 127
7 DEBUGGING MAGMA CODE 137
II SETS, SEQUENCES, AND MAPPINGS . . . . . . 143
8 INTRODUCTION TO AGGREGATES 145
9 SETS 155
10 SEQUENCES 183
11 TUPLES AND CARTESIAN PRODUCTS 205
12 LISTS 211
13 COPRODUCTS 217
14 RECORDS 223
15 MAPPINGS 229
III SEMIGROUPS AND MONOIDS . . . . . . . . . 239
16 FINITELY PRESENTED SEMIGROUPS 241
17 MONOIDS GIVEN BY REWRITE SYSTEMS 253
VOLUME 2: OVERVIEW
IV FINITE GROUPS . . . . . . . . . . . . . . . 271
18 GROUPS 273
19 PERMUTATION GROUPS 327
20 MATRIX GROUPS OVER GENERAL RINGS 439
21 MATRIX GROUPS OVER FINITE FIELDS 509
22 FINITE SOLUBLE GROUPS 567
23 FINITE p-GROUPS 635
24 GENERIC ABELIAN GROUPS 653
25 BLACK-BOX GROUPS 675
26 AUTOMORPHISM GROUPS 681
27 COHOMOLOGY AND EXTENSIONS 699
28 DATABASES OF GROUPS 723
VOLUME 3: OVERVIEW
V INFINITE GROUPS . . . . . . . . . . . . . . 773
29 FINITELY PRESENTED ABELIAN GROUPS 775
30 FINITELY PRESENTED GROUPS 797
31 FINITELY PRESENTED GROUPS: ADVANCED 907
32 POLYCYCLIC GROUPS 983
33 BRAID GROUPS 1023
34 GROUPS DEFINED BY REWRITE SYSTEMS 1075
35 AUTOMATIC GROUPS 1093
36 GROUPS OF STRAIGHT-LINE PROGRAMS 1113
37 SUBGROUPS OF PSL
2
(R) 1123
VOLUME 4: OVERVIEW
VI BASIC RINGS AND LINEAR ALGEBRA . . . . 1147
38 INTRODUCTION TO RINGS 1149
39 RING OF INTEGERS 1169
40 RATIONAL FIELD 1229
41 FINITE FIELDS 1241
42 UNIVARIATE POLYNOMIAL RINGS 1269
43 MULTIVARIATE POLYNOMIAL RINGS 1301
44 REAL AND COMPLEX FIELDS 1329
45 MATRICES 1373
46 SPARSE MATRICES 1409
47 VECTOR SPACES 1429
VOLUME 5: OVERVIEW
VII EXTENSIONS OF RINGS . . . . . . . . . . . 1453
48 ORDERS AND ALGEBRAIC FIELDS 1455
49 BINARY QUADRATIC FORMS 1569
50 QUADRATIC FIELDS 1583
51 CYCLOTOMIC FIELDS 1595
52 CLASS FIELD THEORY 1603
53 ALGEBRAICALLY CLOSED FIELDS 1639
54 RATIONAL FUNCTION FIELDS 1661
55 ALGEBRAIC FUNCTION FIELDS 1673
56 MODULES OVER DEDEKIND DOMAINS 1787
57 VALUATION RINGS 1809
58 NEWTON POLYGONS 1815
59 p-ADIC RINGS AND THEIR EXTENSIONS 1843
60 GALOIS RINGS 1891
61 POWER, LAURENT AND PUISEUX SERIES 1899
62 LAZY POWER SERIES RINGS 1921
VOLUME 6: OVERVIEW
VIII MODULES AND ALGEBRAS . . . . . . . . . 1937
63 INTRODUCTION TO MODULES 1939
64 FREE MODULES 1943
65 CHAIN COMPLEXES 1967
66 LATTICES 1983
67 ALGEBRAS 2065
68 STRUCTURE CONSTANT ALGEBRAS 2077
69 ASSOCIATIVE ALGEBRAS 2087
70 MATRIX ALGEBRAS 2097
71 BASIC ALGEBRAS 2137
72 QUATERNION ALGEBRAS 2173
73 ORDERS OF ASSOCIATIVE ALGEBRAS 2209
74 FINITELY PRESENTED ALGEBRAS 2227
IX DIFFERENTIAL RINGS . . . . . . . . . . . 2263
75 DIFFERENTIAL RINGS, FIELDS AND OPERATORS 2265
VOLUME 7: OVERVIEW
X REPRESENTATION THEORY . . . . . . . . . 2313
76 MODULES OVER AN ALGEBRA 2315
77 GROUP ALGEBRAS 2351
78 K[G]-MODULES AND GROUP REPRESENTATIONS 2365
79 CHARACTERS OF FINITE GROUPS 2389
80 REPRESENTATION THEORY OF SYMMETRIC GROUPS 2403
81 INVARIANT RINGS OF FINITE GROUPS 2411
XI LIE THEORY . . . . . . . . . . . . . . . . 2441
82 INTRODUCTION TO LIE THEORY 2443
83 COXETER SYSTEMS 2449
84 ROOT SYSTEMS 2473
85 ROOT DATA 2495
86 COXETER GROUPS 2541
87 COXETER GROUPS AS PERMUTATION GROUPS 2555
88 REFLECTION GROUPS 2579
89 GROUPS OF LIE TYPE 2605
90 LIE ALGEBRAS 2641
91 FINITELY PRESENTED LIE ALGEBRAS 2683
92 QUANTUM GROUPS 2691
93 UNIVERSAL ENVELOPING ALGEBRAS 2717
VOLUME 8: OVERVIEW
XII COMMUTATIVE ALGEBRA . . . . . . . . . 2725
94 IDEAL THEORY AND GR
= v
1
, . . . , v
r
) exists such that t
i
is a v
i
and v
i
is a u
i
. Once the
sets S
i
are computed, Magma nds their intersection. If this intersection is empty, then
there is no match. If this intersection has cardinality greater than one, then the match is
ambiguous. Otherwise, Magma calls the overload thus obtained.
An example at this point will make the above process clearer:
Example H2E8
We demonstrate Magmas lookup mechanism with the following example. Suppose we have the
following overloaded intrinsics:
intrinsic overloaded(x::RngUPolElt, y::RngUPolElt) -> RngIntElt
{ Overload 1 }
return 1;
end intrinsic;
intrinsic overloaded(x::RngUPolElt[RngInt], y::RngUPolElt) -> RngIntElt
{ Overload 2 }
return 2;
end intrinsic;
intrinsic overloaded(x::RngUPolElt, y::RngUPolElt[RngInt]) -> RngIntElt
46 THE MAGMA LANGUAGE Part I
{ Overload 3 }
return 3;
end intrinsic;
intrinsic overloaded(x::RngUPolElt[RngInt], y::RngUPolElt[RngInt]) -> RngIntElt
{ Overload 4 }
return 4;
end intrinsic;
The following Magma session illustrates how the lookup mechanism operates for the intrinsic
overloaded:
> R1<x> := PolynomialRing(Integers());
> R2<y> := PolynomialRing(Rationals());
> f1 := x + 1;
> f2 := y + 1;
> overloaded(f2, f2);
1
> overloaded(f1, f2);
2
> overloaded(f2, f1);
3
> overloaded(f1, f1);
4
2.3.4 Attaching and Detaching Package Files
The procedures Attach and Detach are provided to attach or detach package les. Once a
le is attached, all intrinsics within it are included in Magma. If the le is modied, it is
automatically recompiled just after the user hits return and just before the next statement
is executed. So there is no need to re-attach the le (or re-load it). If the recompilation of
a package le fails (syntax errors, etc.), all of the intrinsics of the package le are removed
from the Magma session and none of the intrinsics of the package le are included again
until the package le is successfully recompiled. When errors occur during compilation of
a package, the appropriate messages are printed with the string [PC] at the beginning of
the line, indicating that the errors are detected by the Magma package compiler.
If a package le contains the single directive freeze; at the top then the package le
becomes frozen it will not be automatically recompiled after each statement is entered
into Magma. A frozen package is recompiled if need be, however, when it is attached (thus
allowing xes to be updated) the main point of freezing a package which is stable is
to stop Magma looking at it between every statement entered into Magma interactively.
When a package le is complete and tested, it is usually installed in a spec le so it
is automatically attached when the spec le is attached. Thus Attach and Detach are
generally only used when one is developing a single package le containing new intrinsics.
Ch. 2 FUNCTIONS, PROCEDURES AND PACKAGES 47
Attach(F)
Procedure to attach the package le F.
Detach(F)
Procedure to detach the package le F.
freeze;
Freeze the package le in which this appears at the top.
2.3.5 Related Files
There are two les related to any package source le file.m:
file.sig sig le containing signature information;
file.lck lock le.
The lock le exists while a package le is being compiled. If someone else tries to
compile the le, it will just sit there till the lock le disappears. In various circumstances
(system down, Magma crash) .lck les may be left around; this will mean that the next
time Magma attempts to compile the associated source le it will just sit there indenitely
waiting for the .lck le to disappear. In this case the user should search for .lck les
that should be removed.
2.3.6 Importing Constants
import "lename": ident list;
This is the general form of the import statement, where "lename" is a string and
ident list is a list of identiers.
The import statement is a normal statement and can in fact be used anywhere in
Magma, but it is recommended that it only be used to import common constants
and functions/procedures shared between a collection of package les. It has the fol-
lowing semantics: for each identier I in the list ident list, that identier is declared
just like a normal identier within Magma. Within the package le referenced by
lename, there should be an assignment of the same identier I to some object O.
When the identier I is then used as an expression after the import statement, the
value yielded is the object O.
The le that is named in the import statement must already have been attached
by the time the identiers are needed. The best way to achieve this in practice is to
place this le in the spec le, along with the package les, so that all the les can
be attached together.
Thus the only way objects (whether they be normal objects, procedures or func-
tions) assigned within packages can be referenced from outside the package is by an
explicit import with the import statement.
48 THE MAGMA LANGUAGE Part I
Example H2E9
Suppose we have a spec le that lists several package les. Included in the spec le is the le
defs.m containing:
MY LIMIT := 10000;
function fred(x)
return 1/x;
end function;
Then other package les (in the same directory) listed in the spec le which wish to use these
denitions would have the line
import "defs.m": MY LIMIT, fred;
at the top. These could then be used inside any intrinsics of such package les. (If the package
les are not in the same directory, the pathname of defs.m will have to be given appropriately in
the import statement.)
2.3.7 Argument Checking
Using require etc. one can do argument checking easily within intrinsics. If a necessary
condition on the argument fails to hold, then the relevant error message is printed and the
error pointer refers to the caller of the intrinsic. This feature allows user-dened intrinsics
to treat errors in actual arguments in exactly the same way as they are treated by the
Magma standard functions.
require condition: print args;
The expression condition may be any yielding a Boolean value. If the value is false,
then print args is printed and execution aborts with the error pointer pointing to
the caller. The print arguments print args can consist of any expressions (depending
on arguments or variables already dened in the intrinsic).
requirerange v, L, U;
The argument variable v must be the name of one of the argument variables (includ-
ing parameters) and must be of integer type. L and U may be any expressions each
yielding an integer value. If v is not in the range [L, . . . , U], then an appropriate
error message is printed and execution aborts with the error pointer pointing to the
caller.
requirege v, L;
The argument variable v must be the name of one of the argument variables (in-
cluding parameters) and must be of integer type. L must yield an integer value. If
v is not greater than or equal to L, then an appropriate error message is printed
and execution aborts with the error pointer pointing to the caller.
Ch. 2 FUNCTIONS, PROCEDURES AND PACKAGES 49
Example H2E10
A trivial version of Binomial(n, k) which checks that n 0 and 0 k n.
intrinsic Binomial(n::RngIntElt, k::RngIntElt) -> RngIntElt
{ Return n choose k }
requirege n, 0;
requirerange k, 0, n;
return Factorial(n) div Factorial(n - k) div Factorial(k);
end intrinsic;
A simple function to nd a random p-element of a group G.
intrinsic pElement(G::Grp, p::RngIntElt) -> GrpElt
{ Return p-element of group G }
require IsPrime(p): "Argument 2 is not prime";
x := random{x: x in G | Order(x) mod p eq 0};
return x^(Order(x) div p);
end intrinsic;
2.3.8 Package Specication les
A spec le (short for specication le) lists a complete tree of Magma package les.
This makes it easy to collect many package les together and attach them simultaneously.
The specication le consists of a list of tokens which are just space-separated words.
The tokens describe a list of package les and directories containing other packages. The
list is described as follows. The les that are to be attached in the directory indicated by
S are listed enclosed in and characters. A directory may be listed there as well, if it is
followed by a list of les from that directory (enclosed in braces again); arbitrary nesting
is allowed this way. A lename of the form +spec is interpreted as another specication le
whose contents will be recursively attached when AttachSpec (below) is called. The les
are taken relative to the directory that contains the specication le. See also the example
below.
AttachSpec(S)
If S is a string indicating the name of a spec le, this command attaches all the les
listed in S. The format of the spec le is given above.
DetachSpec(S)
If S is a string indicating the name of a spec le, this command detaches all the les
listed in S. The format of the spec le is given above.
50 THE MAGMA LANGUAGE Part I
Example H2E11
Suppose we have a spec le /home/user/spec consisting of the following lines:
{
Group
{
chiefseries.m
socle.m
}
Ring
{
funcs.m
Field
{
galois.m
}
}
}
Then there should be the les
/home/user/spec/Group/chiefseries.m
/home/user/spec/Group/socle.m
/home/user/spec/Ring/funcs.m
/home/user/spec/Ring/Field/galois.m
and if one typed within Magma
AttachSpec("/home/user/spec");
then each of the above les would be attached. If instead of the lename galois.m we have
+galspec, then the le /home/user/spec/Ring/Field/galspec would be a specication le itself
whose contents would be recursively attached.
2.3.9 User Startup Specication Files
The user may specify a list of spec les to be attached automatically when Magma starts
up. This is done by setting the environment variable MAGMA USER SPEC to a colon separated
list of spec les.
Example H2E12
One could have
setenv MAGMA USER SPEC "$HOME/Magma/spec:/home/friend/Magma/spec"
in ones .cshrc . Then when Magma starts up, it will attach all packages listed in the spec les
$HOME/Magma/spec and /home/friend/Magma/spec.
Ch. 2 FUNCTIONS, PROCEDURES AND PACKAGES 51
2.4 Attributes
This section is placed beside the section on packages because the use of attributes is most
common within packages.
For any structure within Magma, it is possible to have attributes associated with it. These
are simply values stored within the structure and are referred to by named elds in exactly
the same manner as Magma records.
There are two kinds of structure attributes: predened system attributes and user-
dened attributes. Both kinds are discussed in the following subsections. A description of
how attributes are accessed and assigned then follows.
2.4.1 Predened System Attributes
The valid elds of predened system attributes are automatically dened at the startup of
Magma. These elds now replace the old method of using the procedure AssertAttribute
and the function HasAttribute (which will still work for some time to preserve backwards
compatibility). For each name which is a valid rst argument for AssertAttribute and
HasAttribute, that name is a valid attribute eld for structures of the appropriate cate-
gory. Thus the backquote method for accessing attributes described in detail below should
now be used instead of the old method. For such attributes, the code:
> SName := x;
is completely equivalent to the code:
> AssertAttribute(S, "Name", x);
(note that the function AssertAttribute takes a string for its second argument so the
name must be enclosed in double quotes). Similarly, the code:
> if assigned SName then
> x := SName;
> // do something with x...
> end if;
is completely equivalent to the code:
> l, x := HasAttribute(S, "Name");
> if l then
> // do something with x...
> end if;
(note again that the function HasAttribute takes a string for its second argument so the
name must be enclosed in double quotes).
Note also that if a system attribute is not set, referring to it in an expression (using the
backquote operator) will not trigger the calculation of it (while the corresponding intrinsic
function will if it exists); rather an error will ensue. Use the assigned operator to test
whether an attribute is actually set.
52 THE MAGMA LANGUAGE Part I
2.4.2 User-dened Attributes
For any category C, the user can stipulate valid attribute elds for structures of C. After
this is done, any structure of category C may have attributes assigned to it and accessed
from it.
There are two ways of adding new valid attributes to a category C: by the procedure
AddAttribute or by the declare attributes package declaration. The former should be
used outside of packages (e.g. in interactive usage), while the latter must be used within
packages to declare attribute elds used by the package and related packages.
AddAttribute(C, F)
(Procedure.) Given a category C, and a string F, append the eld name F to
the list of valid attribute eld names for structures belonging to category C. This
procedure should not be used within packages but during interactive use. Previous
elds for C are still valid this just adds another valid one.
declare attributes C: F
1
, . . . , F
n
;
Given a category C, and a comma-separated list of identiers F
1
, . . . , F
n
append
the eld names specied by the identiers to the list of valid attribute eld names
for structures belonging to category C. This declaration directive must be used
within (and only within) packages to declare attribute elds used by the package
and packages related to it which use the same elds. It is not a statement but
a directive which is stored with the other information of the package when it is
compiled and subsequently attached not when any code is actually executed.
2.4.3 Accessing Attributes
Attributes of structures are accessed in the same way that records are: using the backquote
() operator.
Seldname
Given a structure S and a eld name, return the current value for the given eld in
S. If the value is not assigned, an error results. The eld name must be valid for
the category of S.
assigned Seldname
Given a structure S and a eld name, return whether the given eld in S currently
has a value. The eld name must be valid for the category of S.
Seldname := expression;
Given a structure S and a eld name, assign the given eld of S to be the value of
the expression (any old value is rst discarded). The eld name must be valid for
the category of S.
Ch. 2 FUNCTIONS, PROCEDURES AND PACKAGES 53
delete Seldname;
Given a structure S and a eld name, delete the given eld of S. The eld then
becomes unassigned in S. The eld name must be valid for the category of S and the
eld must be currently assigned in S. This statement is not allowed for predened
system attributes.
GetAttributes(C)
Given a category C, return the valid attribute eld names for structures belonging
to category C as a sorted sequence of strings.
ListAttributes(C)
(Procedure.) Given a category C, list the valid attribute eld names for structures
belonging to category C.
2.4.4 User-dened Verbose Flags
Since version V2.7, verbose ags may be dened by users within packages.
declare verbose F, m;
Given a verbose ag name F (without quotes), and a literal integer m, create the
verbose ag F, with the maximal allowable level for the ag set to m. This directive
may only be used within package les.
2.4.5 Examples
In this subsection we give examples which illustrate all of the above features.
Example H2E13
We illustrate how the predened system attributes may be used. Note that the valid arguments for
AssertAttribute and HasAttribute documented elsewhere now also work as system attributes so
see the documentation for these functions for details as to the valid system attribute eld names.
> // Create group G.
> G := PSL(3, 2);
> // Check whether order known.
> assigned GOrder;
false
> // Attempt to access order -- error since not assigned.
> GOrder;
>> GOrder;
^
Runtime error in : Attribute Order for this structure
is valid but not assigned
> // Force computation of order by intrinsic Order.
> Order(G);
168
> // Check Order field again.
54 THE MAGMA LANGUAGE Part I
> assigned GOrder;
true
> GOrder;
168
> // Create code C and set its minimum weight.
> C := QRCode(GF(2), 31);
> CMinimumWeight := 7;
> C;
[31, 16, 7] Quadratic Residue code over GF(2)
...
Example H2E14
We illustrate how user attributes may be dened and used in an interactive session. This situation
would arise rarely more commonly, attributes would be used within packages.
> // Add attribute field MyStuff for matrix groups.
> AddAttribute(GrpMat, "MyStuff");
> // Create group G.
> G := GL(2, 3);
> // Try illegal field.
> Gsilly;
>> Gsilly;
^
Runtime error in : Invalid attribute silly for this structure
> // Try legal but unassigned field.
> GMyStuff;
>> GMyStuff;
^
Runtime error in : Attribute MyStuff for this structure is valid but not
assigned
> // Assign field and notice value.
> GMyStuff := [1, 2];
> GMyStuff;
[ 1, 2 ]
Example H2E15
We illustrate how user attributes may be used in packages. This is the most common usage of such
attributes. We rst give some (rather naive) Magma code to compute and store a permutation
representation of a matrix group. Suppose the following code is stored in the le permrep.m.
declare attributes GrpMat: PermRep, PermRepMap;
intrinsic PermutationRepresentation(G::GrpMat) -> GrpPerm
{A permutation group representation P of G, with homomorphism f: G -> P};
// Only compute rep if not already stored.
if not assigned GPermRep then
GPermRepMap, GPermRep := CosetAction(G, sub<G|>);
Ch. 2 FUNCTIONS, PROCEDURES AND PACKAGES 55
end if;
return GPermRep, GPermRepMap;
end intrinsic;
Note that the information stored will be reused in subsequent calls of the intrinsic. Then the
package can be attached within a Magma session and the intrinsic PermutationRepresentation
called like in the following code (assumed to be run in the same directory).
> Attach("permrep.m");
> G := GL(2, 2);
> P, f := PermutationRepresentation(G);
> P;
Permutation group P acting on a set of cardinality 6
(1, 2)(3, 5)(4, 6)
(1, 3)(2, 4)(5, 6)
> f;
Mapping from: GrpMat: G to GrpPerm: P
Suppose the following line were also in the package le:
declare verbose MyAlgorithm, 3;
Then there would be a new verbose ag MyAlgorithm for use anywhere within Magma, with the
maximum 3 for the level.
3 INPUT AND OUTPUT
3.1 Introduction . . . . . . . . . 59
3.2 Character Strings . . . . . . . 59
3.2.1 Representation of Strings . . . . . . 59
3.2.2 Creation of Strings . . . . . . . . 60
"abc" 60
BinaryString(s) 60
BString(s) 60
cat 60
* 60
cat:= 60
*:= 60
&cat s 60
&* s 60
^ 60
s[i] 60
s[i] 61
ElementToSequence(s) 61
Eltseq(s) 61
ElementToSequence(s) 61
Eltseq(s) 61
Substring(s, n, k) 61
3.2.3 Integer-Valued Functions . . . . . . 61
# 61
Index(s, t) 61
Position(s, t) 61
3.2.4 Character Conversion . . . . . . . 61
StringToCode(s) 61
CodeToString(n) 61
StringToInteger(s) 62
StringToInteger(s, b) 62
StringToIntegerSequence(s) 62
IntegerToString(n) 62
IntegerToString(n, b) 62
3.2.5 Boolean Functions . . . . . . . . . 62
eq 62
ne 62
in 62
notin 63
lt 63
le 63
gt 63
ge 63
3.2.6 Parsing Strings . . . . . . . . . . 65
Split(S, D) 65
Split(S) 65
Regexp(R, S) 65
3.3 Printing . . . . . . . . . . . 66
3.3.1 The print-Statement . . . . . . . 66
print e; 66
print e, ..., e; 66
print e: -; 66
3.3.2 The printf and fprintf Statements 67
printf format, e, ..., e; 67
fprintf le, format, e, ..., e; 68
3.3.3 Verbose Printing (vprint, vprintf)69
vprint ag: e, ..., e; 69
vprint ag, n: e, ..., e; 69
vprintf ag: format, e, ..., e; 69
vprintf ag, n: format, e, ..., e; 69
3.3.4 Automatic Printing . . . . . . . . 69
ShowPrevious() 70
ShowPrevious(i) 70
ClearPrevious() 70
SetPreviousSize(n) 70
GetPreviousSize() 70
3.3.5 Indentation . . . . . . . . . . . . 72
IndentPush() 72
IndentPop() 72
3.3.6 Printing to a File . . . . . . . . . 72
PrintFile(F, x) 72
Write(F, x) 72
WriteBinary(F, s) 72
PrintFile(F, x, L) 72
Write(F, x, L) 72
PrintFileMagma(F, x) 73
3.3.7 Printing to a String . . . . . . . . 73
Sprint(x) 73
Sprint(x, L) 73
Sprintf(F, ...) 73
3.3.8 Redirecting Output . . . . . . . . 73
SetOutputFile(F) 73
UnsetOutputFile() 74
HasOutputFile() 74
3.4 External Files . . . . . . . . . 74
3.4.1 Opening Files . . . . . . . . . . . 74
Open(S, T) 74
3.4.2 Operations on File Objects . . . . . 74
Flush(F) 74
Tell(F) 74
Seek(F, o, p) 74
Rewind(F) 75
Put(F, S) 75
Puts(F, S) 75
Getc(F) 75
Gets(F) 75
IsEof(S) 75
Ungetc(F, c) 75
58 THE MAGMA LANGUAGE Part I
3.4.3 Reading a Complete File . . . . . . 76
Read(F) 76
ReadBinary(F) 76
3.5 Pipes . . . . . . . . . . . . 77
3.5.1 Pipe Creation . . . . . . . . . . . 77
POpen(C, T) 77
Pipe(C, S) 77
3.5.2 Operations on Pipes . . . . . . . . 78
Read(P : -) 78
ReadBytes(P : -) 78
Write(P, s) 78
WriteBytes(P, Q) 78
3.6 Sockets . . . . . . . . . . . 78
3.6.1 Socket Creation . . . . . . . . . . 79
Socket(H, P : -) 79
Socket( : -) 79
WaitForConnection(S) 80
3.6.2 Socket Properties . . . . . . . . . 80
SocketInformation(S) 80
3.6.3 Socket Predicates . . . . . . . . . 80
IsServerSocket(S) 80
3.6.4 Socket I/O . . . . . . . . . . . . 80
Read(S : -) 80
ReadBytes(S : -) 81
Write(S, s) 81
WriteBytes(S, Q) 81
3.7 Interactive Input . . . . . . . 82
read id; 82
read id, prompt; 82
readi id; 82
readi id, prompt; 82
3.8 Loading a Program File . . . . 82
load "lename"; 82
iload "lename"; 82
3.9 Saving and Restoring Workspaces 82
save "lename"; 82
restore "lename"; 82
3.10 Logging a Session . . . . . . . 83
SetLogFile(F) 83
UnsetLogFile() 83
SetEchoInput(b) 83
3.11 Memory Usage . . . . . . . . 83
GetMemoryUsage() 83
GetMaximumMemoryUsage() 83
ResetMaximumMemoryUsage() 83
3.12 System Calls . . . . . . . . . 83
Alarm(s) 83
ChangeDirectory(s) 83
GetCurrentDirectory() 83
Getpid() 84
Getuid() 84
System(C) 84
%! shell-command 84
3.13 Creating Names . . . . . . . . 84
Tempname(P) 84
Chapter 3
INPUT AND OUTPUT
3.1 Introduction
This chapter is concerned with the various facilities provided for communication between
Magma and its environment. The rst section describes character strings and their op-
erations. Following this, the various forms of the print-statement are presented. Next
the le type is introduced and its operations summarized. The chapter concludes with
a section listing system calls. These include facilities that allow the user to execute an
operating system command from within Magma or to run an external process.
3.2 Character Strings
Strings of characters play a central role in input/output so that the operations provided for
strings to some extent reect this. However, if one wishes, a more general set of operations
are available if the string is rst converted into a sequence. We will give some examples of
this below.
Magma provides two kinds of strings: normal character strings, and binary strings.
Character strings are an inappropriate choice for manipulating data that includes non-
printable characters. If this is required, a better choice is the binary string type. This type
is similar semantically to a sequence of integers, in which each character is represented by
its ASCII value between 0 and 255. The dierence between a binary string and a sequence
of integers is that a binary string is stored internally as an array of bytes, which is a more
space-ecient representation.
3.2.1 Representation of Strings
Character strings may consist of all ordinary characters appearing on your keyboard, in-
cluding the blank (space). Two symbols have a special meaning: the double-quote " and
the backslash \. The double-quote is used to delimit a character string, and hence cannot
be used inside a string; to be able to use a double-quote in strings the backslash is designed
to be an escape character and is used to indicate that the next symbol has to be taken
literally; thus, by using \" inside a string one indicates that the symbol " has to be taken
literally and is not to be interpreted as the end-of-string delimiter. Thus:
> "\"Print this line in quotes\"";
"Print this line in quotes"
To obtain a literal backslash, one simply types two backslashes; for characters other than
double-quotes and backslash it does not make a dierence when a backslash precedes them
60 THE MAGMA LANGUAGE Part I
inside a string, with the exception of n, r and t. Any occurrence of \n or \r inside a string
is converted into a <new-line> while \t is converted into a <tab>. For example:
> "The first line,\nthe second line, and then\ran\tindented line";
The first line,
the second line, and then
an indented line
Note that a backslash followed by a return allows one to conveniently continue the current
construction on the next line; so \<return> inside a string will be ignored, except that
input will continue on a new line on your screen.
Binary strings, on the hand, can consist of any character, whether printable or non-
printable. Binary strings cannot be constructed using literals, but must be constructed
either from a character string, or during a read operation from a le.
3.2.2 Creation of Strings
"abc"
Create a string from a succession of keyboard characters (a, b, c) enclosed in double
quotes " ".
BinaryString(s)
BString(s)
Create a binary string from the character string s.
s cat t
s * t
Concatenate the strings s and t.
s cat:= t
s *:= t
Modication-concatenation of the string s with t: concatenate s and t and put the
result in s.
&cat s
&* s
Given an enumerated sequence s of strings, return the concatenation of these strings.
s ^ n
Form the n-fold concatenation of the string s, for n 0. If n = 0 this is the empty
string, if n = 1 it equals s, etc.
s[i]
Returns the substring of s consisting of the i-th character.
Ch. 3 INPUT AND OUTPUT 61
s[i]
Returnsthe numeric value representing the i-th character of s.
ElementToSequence(s)
Eltseq(s)
Returns the sequence of characters of s (as length 1 strings).
ElementToSequence(s)
Eltseq(s)
Returns the sequence of numeric values representing the characters of s.
Substring(s, n, k)
Return the substring of s of length k starting at position n.
3.2.3 Integer-Valued Functions
#s
The length of the string s.
Index(s, t)
Position(s, t)
This function returns the position (an integer p with 0 < p #s) in the string s
where the beginning of a contiguous substring t occurs. It returns 0 if t is not a
substring of s. (If t is the empty string, position 1 will always be returned, even if
s is empty as well.)
3.2.4 Character Conversion
To perform more sophisticated operations, one may convert the string into a sequence
and use the extensive facilities for sequences described in the next part of this manual; see
the examples at the end of this chapter for details.
StringToCode(s)
Returns the code number of the rst character of string s. This code depends on
the computer system that is used; it is ASCII on most UNIX machines.
CodeToString(n)
Returns a character (string of length 1) corresponding to the code number n, where
the code is system dependent (see previous entry).
62 THE MAGMA LANGUAGE Part I
StringToInteger(s)
Returns the integer corresponding to the string of decimal digits s. All non-space
characters in the string s must be digits (0, 1, . . . , 9), except the rst character,
which is also allowed to be + or . An error results if any other combination of
characters occurs. Leading zeros are omitted.
StringToInteger(s, b)
Returns the integer corresponding to the string of digits s, all assumed to be written
in base b. All non-space characters in the string s must be digits less than b (if b is
greater than 10, A is used for 10, B for 11, etc.), except the rst character, which
is also allowed to be + or . An error results if any other combination of characters
occurs.
StringToIntegerSequence(s)
Returns the sequence of integers corresponding to the string s of space-separated
decimal numbers. All non-space characters in the string s must be digits (0, 1, . . . , 9),
except the rst character after each space, which is also allowed to be + or .
An error results if any other combination of characters occurs. Leading zeros are
omitted. Each number can begin with a sign (+ or ) without a space.
IntegerToString(n)
Convert the integer n into a string of decimal digits; if n is negative the rst character
of the string will be . (Note that leading zeros and a + sign are ignored when
Magma builds an integer, so the resulting string will never begin with + or 0
characters.)
IntegerToString(n, b)
Convert the integer n into a string of digits with the given base (which must be in
the range [2 . . . 36]); if n is negative the rst character of the string will be .
3.2.5 Boolean Functions
s eq t
Returns true if and only if the strings s and t are identical. Note that blanks are
signicant.
s ne t
Returns true if and only if the strings s and t are distinct. Note that blanks are
signicant.
s in t
Returns true if and only if s appears as a contiguous substring of t. Note that the
empty string is contained in every string.
Ch. 3 INPUT AND OUTPUT 63
s notin t
Returns true if and only if s does not appear as a contiguous substring of t. Note
that the empty string is contained in every string.
s lt t
Returns true if s is lexicographically less than t, false otherwise. Here the ordering
on characters imposed by their ASCII code number is used.
s le t
Returns true if s is lexicographically less than or equal to t, false otherwise. Here
the ordering on characters imposed by their ASCII code number is used.
s gt t
Returns true if s is lexicographically greater than t, false otherwise. Here the
ordering on characters imposed by their ASCII code number is used.
s ge t
Returns true if s is lexicographically greater than or equal to t, false otherwise.
Here the ordering on characters imposed by their ASCII code number is used.
Example H3E1
> "Mag" cat "ma";
Magma
Omitting double-quotes usually has undesired eects:
> "Mag cat ma";
Mag cat ma
And note that there are two dierent equalities involved in the following!
> "73" * "9" * "42" eq "7" * "3942";
true
> 73 * 9 * 42 eq 7 * 3942;
true
The next line shows how strings can be concatenated quickly, and also that strings of blanks can
be used for formatting:
> s := ("Mag" cat "ma? ")^2;
> s, " "^30, s[4]^12, "!";
Magma? Magma? mmmmmmmmmmmm !
Here is a way to list (in a sequence) the rst occurrence of each of the ten digits in the decimal
expansion of , using IntegerToString and Position.
> pi := Pi(RealField(1001));
> dec1000 := Round(10^1000*(pi-3));
> I := IntegerToString(dec1000);
> [ Position(I, IntegerToString(i)) : i in [0..9] ];
64 THE MAGMA LANGUAGE Part I
[ 32, 1, 6, 9, 2, 4, 7, 13, 11, 5 ]
Using the length # and string indexing [ ] it is also easy to count the number of occurrences of
each digit in the string containing the rst 1000 digits.
> [ #[i : i in [1..#I] | I[i] eq IntegerToString(j)] : j in [0..9] ];
[ 93, 116, 103, 102, 93, 97, 94, 95, 101, 106 ]
We would like to test if the ASCII-encoding of the string Magma appears. This could be done
as follows, using StringToCode and in, or alternatively, Position. To reduce the typing, we rst
abbreviate IntegerToString to is and StringToCode to sc.
> sc := StringToCode;
> its := IntegerToString;
> M := its(sc("M")) * its(sc("a")) * its(sc("g")) * its(sc("m")) * its(sc("a"));
> M;
779710310997
> M in I;
false
> Position(I, M);
0
So Magma does not appear this way. However, we could be satised if the letters appear
somewhere in the right order. To do more sophisticated operations (like this) on strings, it is
necessary to convert the string into a sequence, because sequences constitute a more versatile
data type, allowing many more advanced operations than strings.
> Iseq := [ I[i] : i in [1..#I] ];
> Mseq := [ M[i] : i in [1..#M] ];
> IsSubsequence(Mseq, Iseq);
false
> IsSubsequence(Mseq, Iseq: Kind := "Sequential");
true
Finally, we nd that the string magma lies in between Pi and pi:
> "Pi" le "magma";
true
> "magma" lt "pi";
true
Ch. 3 INPUT AND OUTPUT 65
3.2.6 Parsing Strings
Split(S, D)
Split(S)
Given a string S, together with a string D describing a list of separator characters,
return the sequence of strings obtained by splitting S at any of the characters
contained in D. That is, S is considered as a sequence of elds, with any character
in D taken to be a delimiter separating the elds. If D is omitted, it is taken to be
the string consisting of the newline character alone (so S is split into the lines found
in it). If S is desired to be split into space-separated words, the argument " \t\n"
should be given for D.
Example H3E2
We demonstrate elementary uses of Split.
> Split("a b c d", " ");
[ a, b, c, d ]
> // Note that an empty field is included if the
> // string starts with the separator:
> Split(" a b c d", " ");
[ , a, b, c, d ]
> Split("abxcdyefzab", "xyz");
[ ab, cd, ef, ab ]
> // Note that no splitting happens if the delimiter
> // is empty:
> Split("abcd", "");
[ abcd ]
Regexp(R, S)
Given a string R specifying a regular expression, together with a string S, return
whether S matches R. If so, return also the matched substring of S, together
with the sequence of matched substrings of S corresponding to the parenthesized
expressions of R. This function is based on the freely distributable reimplementation
of the V8 regexp package by Henry Spencer. The syntax and interpretation of the
characters |, *, +, ?, ^, $, [], \ is the same as in the UNIX command egrep.
The parenthesized expressions are numbered in left-to-right order of their opening
parentheses (note that they should not have an initial \ before them as the UNIX
commands grep and ed require so).
66 THE MAGMA LANGUAGE Part I
Example H3E3
We demonstrate some elementary uses of Regexp.
> Regexp("b.*d", "abcde");
true bcd []
> Regexp("b(.*)d", "abcde");
true bcd [ c ]
> Regexp("b.*d", "xyz");
false
> date := "Mon Jun 17 10:27:27 EST 1996";
> _, _, f := Regexp("([0-9][0-9]):([0-9][0-9]):([0-9][0-9])", date);
> f;
[ 10, 27, 27 ]
> h, m, s := Explode(f);
> h, m, s;
10 27 27
3.3 Printing
3.3.1 The print-Statement
print expression;
print expression, ..., expression;
print expression: parameters;
Print the value of the expression. Some limited ways of formatting output are
described in the section on strings. Four levels of printing (that may in specic
cases coincide) exist, and may be indicated after the colon: Default (which is the
same as the level obtained if no level is indicated), Minimal, Maximal, and Magma.
The last of these produces output representing the value of the identier as valid
Magma-input (when possible).
Ch. 3 INPUT AND OUTPUT 67
3.3.2 The printf and fprintf Statements
printf format, expression, ..., expression;
Print values of the expressions under control of format. The rst argument, the
format string, must be a string which contains two types of objects: plain char-
acters, which are simply printed, and conversion specications (indicated by the
% character), each of which causes conversion and printing of zero or more of the
expressions. (Use %% to get a literal percent character.) Currently, the only conver-
sion specications allowed are %o, which stands for object, %m, which stands for
magma, and %h, which stands for hexadecimal. The hexadecimal conversion
specication will print its argument in hexadecimal; currently, it only supports inte-
ger arguments. For object, the corresponding object of the expression arguments
is printed in a default printing mode, while for magma the corresponding object
of the expression arguments is printed in Magma printing mode. For each of these
conversion specications, the object can be printed in a eld of a particular width
by placing extra characters immediately after the % character: digits describing a
positive integer, specifying a eld with width equal to that number and with right-
justication; digits describing a negative integer, specifying a eld with width equal
to the absolute value of the number and with left-justication; or the character *
specifying a eld width given by the next appropriate expression argument (with
justication determined by the sign of the number). This statement is thus like the
C language function printf(), except that %o (and %m) covers all kinds of objects
it is not necessary to have dierent conversion specications for the dierent
types of Magma objects. Note also that this statement does not print a newline
character after its arguments while the print statement does (a \n character should
be placed in the format string if this is desired). A newline character will be printed
just before the next prompt, though, if there is an incomplete line at that point.
Example H3E4
The following statements demonstrate simple uses of printf.
> for i := 1 to 150 by 33 do printf "[%3o]\n", i; end for;
[ 1]
[ 34]
[ 67]
[100]
[133]
> for i := 1 to 150 by 33 do printf "[%-3o]\n", i; end for;
[1 ]
[34 ]
[67 ]
[100]
[133]
> for w := 1 to 5 do printf "[%*o]", w, 1; end for;
68 THE MAGMA LANGUAGE Part I
[1][ 1][ 1][ 1][ 1]
Example H3E5
Some further uses of the printf statement are illustrated below.
> x := 3;
> y := 4;
> printf "x = %o, y = %o\n", x, y;
x = 3, y = 4
> printf "G"; printf "day";
Gday
> AssertAttribute(FldPr, "OutputPrecision", 5);
> p := 53.211;
> x := 123.2;
> printf "%o%% of %o is %o\n", p, x, p/100.0 * x;
53.211% of 123.20 is 65.556
fprintf le, format, expression, ..., expression;
Print values of the expressions under control of format into the le given by le.
The rst argument le must be either a string specifying a le which can be opened
for appending (tilde expansion is performed on the lename), or an le object (see
the section below on external les) opened for writing. The rest of the arguments
are exactly as in the printf statement. In the string (lename) case, the le is
opened for appending, the string obtained from the formatted printing of the other
arguments is appended to the le, and the le is closed. In the le object case,
the string obtained from the formatted printing of the other arguments is simply
appended to the le. Note that this statement, like printf, does not print a newline
character after its arguments (a \n character should be placed in the format string
if this is desired).
Example H3E6
The following statements demonstrate a (rather contrived) use of fprintf with a le pipe.
> p := 1000000000000000000000000000057;
> F := POpen("sort -n", "w");
> for i := 100 to 110 do
> fprintf F, "%30o (2^%o mod p)\n", 2^i mod p, i;
> end for;
> // Close F and then see output on standard output:
> delete F;
37107316853453566312041115519 (2^109 mod p)
70602400912917605986812821219 (2^102 mod p)
74214633706907132624082231038 (2^110 mod p)
129638414606681695789005139447 (2^106 mod p)
Ch. 3 INPUT AND OUTPUT 69
141204801825835211973625642438 (2^103 mod p)
259276829213363391578010278894 (2^107 mod p)
267650600228229401496703205319 (2^100 mod p)
282409603651670423947251284876 (2^104 mod p)
518553658426726783156020557788 (2^108 mod p)
535301200456458802993406410638 (2^101 mod p)
564819207303340847894502569752 (2^105 mod p)
3.3.3 Verbose Printing (vprint, vprintf)
The following statements allow convenient printing of information conditioned by whether
an appropriate verbose ag is turned on.
vprint ag: expression, ..., expression;
vprint ag, n: expression, ..., expression;
If the verbose ag ag (see the function SetVerbose) has a level greater than or
equal to n, print the expressions to the right of the colon exactly as in the print
statement. If the ag has level 0 (i.e. is not turned on), do nothing. In the rst
form of this statement, where a specic level is not given, n is taken to be 1. This
statement is useful in Magma code found in packages where one wants to print
verbose information if an appropriate verbose ag is turned on.
vprintf ag: format, expression, ..., expression;
vprintf ag, n: format, expression, ..., expression;
If the verbose ag ag (see the function SetVerbose) has a level greater than or
equal to n, print using the format and the expressions to the right of the colon
exactly as in the printf statement. If the ag has level 0 (i.e. is not turned on),
do nothing. In the rst form of this statement, where a specic level is not given, n
is taken to be 1. This statement is useful in Magma code found in packages where
one wants to print verbose information if an appropriate verbose ag is turned on.
3.3.4 Automatic Printing
Magma allows automatic printing of expressions: basically, a statement consisting of an
expression (or list of expressions) alone is taken as a shorthand for the print-statement.
Some subtleties are involved in understanding the precise behaviour of Magma in
interpreting lone expressions as statements. The rules Magma follows are outlined here.
In the following, a call-form means any expression of the form f(arguments); that is,
anything which could be a procedure call or a function call.
(a) Any single expression followed by a semicolon which is not a call-form is printed, just
as if you had print in front of it.
(b)For a single call-form followed by a semicolon (which could be a function call or proce-
dure call), the rst signature which matches the input arguments is taken and if that is
70 THE MAGMA LANGUAGE Part I
procedural, the whole call is taken as a procedure call, otherwise it is taken as function
call and the results are printed.
(c) A comma-separated list of any expressions is printed, just as if you had print in front of
it. Here any call-form is taken as a function call only so procedure calls are impossible.
(d)A print level modier is allowed after an expression list (whether the list has length 1
or more). Again any call-form is taken as a function call only so procedure calls are
impossible.
(e) Any list of objects printed, whether by any of the above rules or by the print statement,
is placed in the previous value buer. $1 gives the last printed list, $2 the one before,
etc. Note that multi-return values stay as a list of values in the previous value buer.
The only way to get at the individual values of such a list is by assignment to a list
of identiers, or by where (this is of course the only way to get the second result out
of Quotrem, etc.). In other places, a $1 expression is evaluated with principal value
semantics.
Magma also provides procedures to manipulate the previous value buer in which $1, etc.
are stored.
ShowPrevious()
Show all the previous values stored. This does not change the contents of the
previous value buer.
ShowPrevious(i)
Show the i-th previous value stored. This does not change the contents of the
previous value buer.
ClearPrevious()
Clear all the previous values stored. This is useful for ensuring that no more memory
is used than that referred to by the current identiers.
SetPreviousSize(n)
Set the size of the previous value buer (this is not how many values are dened in
it at the moment, but the maximum number that will be stored). The default size
is 3.
GetPreviousSize()
Return the size of the previous value buer.
Example H3E7
Examples which illustrate point (a):
> 1;
1
> x := 3;
> x;
Ch. 3 INPUT AND OUTPUT 71
3
Examples which illustrate point (b):
> 1 + 1; // really function call +(1, 1)
2
> Q := [ 0 ];
> Append(~Q, 1); // first (in fact only) match is procedure call
> Append(Q, 1); // first (in fact only) match is function call
[ 0, 1, 1 ]
> // Assuming fp is assigned to a procedure or function:
> fp(x); // whichever fp is at runtime
> SetVerbose("Meataxe", true); // simple procedure call
Examples which illustrate point (c):
> 1, 2;
1 2
> // Assuming f assigned:
> f(x), 1; // f only can be a function
> SetVerbose("Meataxe", true), 1; // type error in SetVerbose
> // (since no function form)
Examples which illustrate point (d):
> 1: Magma;
1
> Sym(3), []: Maximal;
Symmetric group acting on a set of cardinality 3
Order = 6 = 2 * 3
[]
> SetVerbose("Meataxe", true): Magma; // type error as above
Examples which illustrate point (e):
> 1;
1
> $1;
1
> 2, 3;
2 3
> $1;
2 3
> Quotrem(124124, 123);
1009 17
> $1;
1009 17
> a, b := $1;
> a;
1009
72 THE MAGMA LANGUAGE Part I
3.3.5 Indentation
Magma has an indentation level which determines how many initial spaces should be
printed before each line. The level can be increased or decreased. Each time the top
level of Magma is reached (i.e. a prompt is printed), the level is reset to 0. The level is
usually changed in verbose output of recursive functions and procedures. The functions
SetIndent and GetIndent are used to control and examine the number of spaces used for
each indentation level (default 4).
IndentPush()
Increase (push) the indentation level by 1. Thus the beginning of a line will have s
more spaces than before, where s is the current number of indentation spaces.
IndentPop()
Decrease (pop) the indentation level by 1. Thus the beginning of a line will have s
less spaces than before, where s is the current number of indentation spaces. If the
current level is already 0, an error occurs.
3.3.6 Printing to a File
PrintFile(F, x)
Write(F, x)
Overwrite BoolElt Default : false
Print x to the le specied by the string F. If this le already exists, the output
will be appended, unless the optional parameter Overwrite is set to true, in which
case the le is overwritten.
WriteBinary(F, s)
Overwrite BoolElt Default : false
Write the binary string s to the le specied by the string F. If this le already
exists, the output will be appended, unless the optional parameter Overwrite is set
to true, in which case the le is overwritten.
PrintFile(F, x, L)
Write(F, x, L)
Overwrite BoolElt Default : false
Print x in format dened by the string L to the le specied by the string F. If
this le already exists, the output will be appended unless the optional parameter
Overwrite is set to true, in which case the le is overwritten. The level L can be
any of the print levels on the print command above (i.e., it must be one of the
strings "Default", "Minimal", "Maximal", or "Magma").
Ch. 3 INPUT AND OUTPUT 73
PrintFileMagma(F, x)
Overwrite BoolElt Default : false
Print x in Magma format to the le specied by the string F. If this le already
exists, the output will be appended, unless the optional parameter Overwrite is set
to true, in which case the le is overwritten.
3.3.7 Printing to a String
Magma allows the user to obtain the string corresponding to the output obtained when
printing an object by means of the Sprint function. The Sprintf function allows format-
ted printing like the printf statement.
Sprint(x)
Sprint(x, L)
Given any Magma object x, this function returns a string containing the output
obtained when x is printed. If a print level L is given also (a string), the printing
is done according to that level (see the print statement for the possible printing
levels).
Sprintf(F, ...)
Given a format string F, together with appropriate extra arguments corresponding
to F, return the string resulting from the formatted printing of F and the arguments.
The format string F and arguments should be exactly as for the printf statement
see that statement for details.
Example H3E8
We demonstrate elementary uses of Sprintf.
> Q := [Sprintf("{%4o<->%-4o}", x, x): x in [1,10,100,1000]];
> Q;
[ { 1<->1 }, { 10<->10 }, { 100<->100 }, {1000<->1000} ]
3.3.8 Redirecting Output
SetOutputFile(F)
Overwrite BoolElt Default : false
Redirect all Magma output to the le specied by the string F. By using
SetOutputFile(F: Overwrite := true) the le F is emptied before output is
written onto it.
74 THE MAGMA LANGUAGE Part I
UnsetOutputFile()
Close the output le, so that output will be directed to standard output again.
HasOutputFile()
If Magma currently has an output or log le F, return true and F; otherwise return
false.
3.4 External Files
Magma provides a special le type for the reading and writing of external les. Most of
the standard C library functions can be applied to such les to manipulate them.
3.4.1 Opening Files
Open(S, T)
Given a lename (string) S, together with a type indicator T, open the le named by
S and return a Magma le object associated with it. Tilde expansion is performed
on S. The standard C library function fopen() is used, so the possible characters
allowed in T are the same as those allowed for that function in the current operating
system, and have the same interpretation. Thus one should give the value "r" for
T to open the le for reading, and give the value "w" for T to open the le for
writing, etc. (Note that in the PC version of Magma, the character "b" should
also be included in T if the le is desired to be opened in binary mode.) Once a le
object is created, various I/O operations can be performed on it see below. A
le is closed by deleting it (i.e. by use of the delete statement or by reassigning the
variable associated with the le); there is no Fclose function. This ensures that the
le is not closed while there are still multiple references to it. (The function is called
Open instead of Fopen to follow Perl-style conventions. The following functions also
follow such conventions where possible.)
3.4.2 Operations on File Objects
Flush(F)
Given a le F, ush the buer of F.
Tell(F)
Given a le F, return the oset in bytes of the le pointer within F.
Seek(F, o, p)
Perform fseek(F, o, p); i.e. move the le pointer of F to oset o (relative to p: 0
means beginning, 1 means current, 2 means end).
Ch. 3 INPUT AND OUTPUT 75
Rewind(F)
Perform rewind(F); i.e. move the le pointer of F to the beginning.
Put(F, S)
Put (write) the characters of the string S to the le F.
Puts(F, S)
Put (write) the characters of the string S, followed by a newline character, to the
le F.
Getc(F)
Given a le F, get and return one more character from le F as a string. If F is at
end of le, a special EOF marker string is returned; the function IsEof should be
applied to the character to test for end of le. (Thus the only way to loop over a
le character by character is to get each character and test whether it is the EOF
marker before processing it.)
Gets(F)
Given a le F, get and return one more line from le F as a string. The newline
character is removed before the string is returned. If F is at end of le, a special
EOF marker string is returned; the function IsEof should be applied to the string
to test for end of le.
IsEof(S)
Given a string S, return whether S is the special EOF marker.
Ungetc(F, c)
Given a character (length one string) C, together with a le F, perform ungetc(C,
F); i.e. push the character C back into the input buer of F.
Example H3E9
We write a function to count the number of lines in a le. Note the method of looping over the
characters of the le: we must get the line and then test whether it is the special EOF marker.
> function LineCount(F)
> FP := Open(F, "r");
> c := 0;
> while true do
> s := Gets(FP);
> if IsEof(s) then
> break;
> end if;
> c +:= 1;
> end while;
> return c;
> end function;
76 THE MAGMA LANGUAGE Part I
> LineCount("/etc/passwd");
59
3.4.3 Reading a Complete File
Read(F)
Function that returns the contents of the text-le with name indicated by the string
F. Here F may be an expression returning a string.
ReadBinary(F)
Function that returns the contents of the text-le with name indicated by the string
F as a binary string.
Example H3E10
In this example we show how Read can be used to import the complete output from a separate C
program into a Magma session. We assume that a le mystery.c (of which the contents are shown
below) is present in the current directory. We rst compile it, from within Magma, and then use
it to produce output for the Magma version of our mystery function.
> Read("mystery.c");
#include <stdio.h>
main(argc, argv)
int argc;
char **argv;
{
int n, i;
n = atoi(argv[1]);
for (i = 1; i <= n; i++)
printf("%d\n", i * i);
return 0;
}
> System("cc mystery.c -o mystery");
> mysteryMagma := function(n)
> System("./mystery " cat IntegerToString(n) cat " >outfile");
> output := Read("outfile");
> return StringToIntegerSequence(output);
> end function;
> mysteryMagma(5);
[ 1, 4, 9, 16, 25 ]
Ch. 3 INPUT AND OUTPUT 77
3.5 Pipes
Pipes are used to communicate with newly-created processes. Currently pipes are only
available on UNIX systems.
The Magma I/O module is currently undergoing revision, and the current pipe facilities
are a mix of the old and new methods. A more uniform model will be available in future
releases.
3.5.1 Pipe Creation
POpen(C, T)
Given a shell command line C, together with a type indicator T, open a pipe between
the Magma process and the command to be executed. The standard C library
function popen() is used, so the possible characters allowed in T are the same as
those allowed for that function in the current operating system, and have the same
interpretation. Thus one should give the value "r" for T so that Magma can read
the output from the command, and give the value "w" for T so that Magma can
write into the input of the command. See the Pipe intrinsic for a method for sending
input to, and receiving output from, a single command.
Important: this function returns a File object, and the I/O functions for les
described previously must be used rather then those described in the following.
Pipe(C, S)
Given a shell command C and an input string S, create a pipe to the command C,
send S into the standard input of C, and return the output of C as a string. Note
that for many commands, S should nish with a new line character if it consists of
only one line.
Example H3E11
We write a function which returns the current time as 3 values: hour, minutes, seconds. The
function opens a pipe to the UNIX command date and applies regular expression matching to
the output to extract the relevant elds.
> function GetTime()
> D := POpen("date", "r");
> date := Gets(D);
> _, _, f := Regexp("([0-9][0-9]):([0-9][0-9]):([0-9][0-9])", date);
> h, m, s := Explode(f);
> return h, m, s;
> end function;
> h, m, s := GetTime();
> h, m, s;
14 30 01
> h, m, s := GetTime();
> h, m, s;
14 30 04
78 THE MAGMA LANGUAGE Part I
3.5.2 Operations on Pipes
When a read request is made on a pipe, the available data is returned. If no data is
currently available, then the process waits until some does becomes available, and returns
that. (It will also return if the pipe has been closed and hence no more data can be
transmitted.) It does not continue trying to read more data, as it cannot tell whether or
not there is some on the way.
The upshot of all this is that care must be exercised as reads may return less data than
is expected.
Read(P : parameters)
Max RngIntElt Default : 0
Waits for data to become available for reading from P and then returns it as a string.
If the parameter Max is set to a positive value then at most that many characters
will be read. Note that less than Max characters may be returned, depending on the
amount of currently available data.
If the pipe has been closed then the special EOF marker string is returned.
ReadBytes(P : parameters)
Max RngIntElt Default : 0
Waits for data to become available for reading from P and then returns it as a
sequence of bytes (integers in the range 0..255). If the parameter Max is set to a
positive value then at most that many bytes will be read. Note that less than Max
bytes may be returned, depending on the amount of currently available data.
If the pipe has been closed then the empty sequence is returned.
Write(P, s)
Writes the characters of the string s to the pipe P.
WriteBytes(P, Q)
Writes the bytes in the byte sequence Q to the pipe P. Each byte must be an integer
in the range 0..255.
3.6 Sockets
Sockets may be used to establish communication channels between machines on the same
network. Once established, they can be read from or written to in much the same ways
as more familiar I/O constructs like les. One major dierence is that the data is not
instantly available, so the I/O operations take much longer than with les. Currently
sockets are only available on UNIX systems.
Strictly speaking, a socket is a communication endpoint whose dening information
consists of a network address and a port number. (Even more strictly speaking, the
communication protocol is also part of the socket. Magma only uses TCP sockets, however,
so we ignore this point from now on.)
Ch. 3 INPUT AND OUTPUT 79
The network address selects on which of the available network interfaces communication
will take place; it is a string identifying the machine on that network, in either domain name
or dotted-decimal format. For example, both "localhost" and "127.0.0.1" identify
the machine on the loopback interface (which is only accessible from the machine itself),
whereas "foo.bar.com" or "10.0.0.3" might identify the machine in a local network,
accessible from other machines on that network.
The port number is just an integer that identies the socket on a particular network
interface. It must be less than 65 536. A value of 0 will indicate that the port number
should be chosen by the operating system.
There are two types of sockets, which we will call client sockets and server sockets. The
purpose of a client socket is to initiate a connection to a server socket, and the purpose of a
server socket is to wait for clients to initiate connections to it. (Thus the server socket needs
to be created before the client can connect to it.) Once a server socket accepts a connection
from a client socket, a communication channel is established and the distinction between
the two becomes irrelevant, as they are merely each side of a communication channel.
In the following descriptions, the network address will often be referred to as the host.
So a socket is identied by a (host, port) pair, and an established communication channel
consists of two of these pairs: (local-host, local-port), (remote-host, remote-port).
3.6.1 Socket Creation
Socket(H, P : parameters)
LocalHost MonStgElt Default : none
LocalPort RngIntElt Default : 0
Attempts to create a (client) socket connected to port P of host H. Note: these are
the remote values; usually it does not matter which local values are used for client
sockets, but for those rare occasions where it does they may be specied using the
parameters LocalHost and LocalPort. If these parameters are not set then suitable
values will be chosen by the operating system. Also note that port numbers below
1 024 are usually reserved for system use, and may require special privileges to be
used as the local port number.
Socket( : parameters)
LocalHost MonStgElt Default : none
LocalPort RngIntElt Default : 0
Attempts to create a server socket on the current machine, that can be used to
accept connections. The parameters LocalHost and LocalPort may be used to
specify which network interface and port the socket will accept connections on; if
either of these are not set then their values will be determined by the operating
system. Note that port numbers below 1 024 are usually reserved for system use,
and may require special privileges to be used as the local port number.
80 THE MAGMA LANGUAGE Part I
WaitForConnection(S)
This may only be used on server sockets. It waits for a connection attempt to
be made, and then creates a new socket to handle the resulting communication
channel. Thus S may continue to be used to accept connection attempts, while the
new socket is used for communication with whatever entity just connected. Note:
this new socket is not a server socket.
3.6.2 Socket Properties
SocketInformation(S)
This routine returns the identifying information for the socket as a pair of tuples.
Each tuple is a <host, port> pair the rst tuple gives the local information and the
second gives the remote information. Note that this second tuple will be undened
for server sockets.
3.6.3 Socket Predicates
IsServerSocket(S)
Returns whether S is a server socket or not.
3.6.4 Socket I/O
Due to the nature of the network, it takes signicant time to transmit data from one
machine to another. Thus when a read request is begun it may take some time to complete,
usually because the data to be read has not yet arrived. Also, data written to a socket
may be broken up into smaller pieces for transmission, each of which may take dierent
amounts of time to arrive. Thus, unlike les, there is no easy way to tell if there is still
more data to be read; the current lack of data is no indicator as to whether more might
arrive.
When a read request is made on a socket, the available data is returned. If no data is
currently available, then the process waits until some does becomes available, and returns
that. (It will also return if the socket has been closed and hence no more data can be
transmitted.) It does not continue trying to read more data, as it cannot tell whether or
not there is some on the way.
The upshot of all this is that care must be exercised as reads may return less data than
is expected.
Read(S : parameters)
Max RngIntElt Default : 0
Waits for data to become available for reading from S and then returns it as a string.
If the parameter Max is set to a positive value then at most that many characters
will be read. Note that less than Max characters may be returned, depending on the
amount of currently available data.
If the socket has been closed then the special EOF marker string is returned.
Ch. 3 INPUT AND OUTPUT 81
ReadBytes(S : parameters)
Max RngIntElt Default : 0
Waits for data to become available for reading from S and then returns it as a
sequence of bytes (integers in the range 0..255). If the parameter Max is set to a
positive value then at most that many bytes will be read. Note that less than Max
bytes may be returned, depending on the amount of currently available data.
If the socket has been closed then the empty sequence is returned.
Write(S, s)
Writes the characters of the string s to the socket S.
WriteBytes(S, Q)
Writes the bytes in the byte sequence Q to the socket S. Each byte must be an
integer in the range 0..255.
Example H3E12
Here is a trivial use of sockets to send a message from one Magma process to another running on
the same machine. The rst Magma process sets up a server socket and waits for another Magma
to contact it.
> // First Magma process
> server := Socket(: LocalHost := "localhost");
> SocketInformation(server);
<localhost, 32794>
> S1 := WaitForConnection(server);
The second Magma process establishes a client socket connection to the rst, writes a greeting
message to it, and closes the socket.
> // Second Magma process
> S2 := Socket("localhost", 32794);
> SocketInformation(S2);
<localhost, 32795> <localhost, 32794>
> Write(S2, "Hello, other world!");
> delete S2;
The rst Magma process is now able to continue; it reads and displays all data sent to it until the
socket is closed.
> // First Magma process
> SocketInformation(S1);
<localhost, 32794> <localhost, 32795>
> repeat
> msg := Read(S1);
> msg;
> until IsEof(msg);
Hello, other world!
EOF
82 THE MAGMA LANGUAGE Part I
3.7 Interactive Input
read identier;
read identier, prompt;
This statement will cause Magma to assign to the given identier the string of
characters appearing (at run-time) on the following line. This allows the user to
provide an input string at run-time. If the optional prompt is given (a string), that
is printed rst.
readi identier;
readi identier, prompt;
This statement will cause Magma to assign to the given identier the literal integer
appearing (at run-time) on the following line. This allows the user to specify integer
input at run-time. If the optional prompt is given (a string), that is printed rst.
3.8 Loading a Program File
load "lename";
Input the le with the name specied by the string. The le will be read in, and
the text will be treated as Magma input. Tilde expansion of le names is allowed.
iload "lename";
(Interactive load.) Input the le with the name specied by the string. The le will
be read in, and the text will be treated as Magma input. Tilde expansion of le
names is allowed. In contrast to load, the user has the chance to interact as each
line is read in:
As the line is read in, it is displayed and the system waits for user response. At
this point, the user can skip the line (by moving down), edit the line (using the
normal editing keys) or execute it (by pressing enter). If the line is edited, the
new line is executed and the original line is presented again.
3.9 Saving and Restoring Workspaces
save "lename";
Copy all information present in the current Magma workspace onto a le specied
by the string "lename". The workspace is left intact, so executing this command
does not interfere with the current computation.
restore "lename";
Copy a previously stored Magma workspace from the le specied by the string
"lename" into central memory. Information present in the current workspace prior
to the execution of this command will be lost. The computation can now proceed
from the point it was at when the corresponding save-command was executed.
Ch. 3 INPUT AND OUTPUT 83
3.10 Logging a Session
SetLogFile(F)
Overwrite BoolElt Default : false
Set the log le to be the le specied by the string F: all input and output will be
sent to this log le as well as to the terminal. If a log le is already in use, it is closed
and F is used instead. By using SetLogFile(F: Overwrite := true) the le F is
emptied before input and output are written onto it. See also HasOutputFile.
UnsetLogFile()
Stop logging Magmas output.
SetEchoInput(b)
Set to true or false according to whether or not input from external les should also
be sent to standard output.
3.11 Memory Usage
GetMemoryUsage()
Return the current memory usage of Magma (in bytes as an integer). This is the
process data size, which does not include the executable code.
GetMaximumMemoryUsage()
Return the maximum memory usage of Magma (in bytes as an integer) which has
been attained since last reset (see ResetMaximumMemoryUsage). This is the maxi-
mum process data size, which does not include the executable code.
ResetMaximumMemoryUsage()
Reset the value of the maximum memory usage of Magma to be the current memory
usage of Magma (see GetMaximumMemoryUsage).
3.12 System Calls
Alarm(s)
A procedure which when used on UNIX systems, sends the signal SIGALRM to the
Magma process after s seconds. This allows the user to specify that a Magma-
process should self-destruct after a certain period.
ChangeDirectory(s)
Change to the directory specied by the string s. Tilde expansion is allowed.
GetCurrentDirectory()
Returns the current directory as a string.
84 THE MAGMA LANGUAGE Part I
Getpid()
Returns Magmas process ID (value of the Unix C system call getpid()).
Getuid()
Returns the user ID (value of the Unix C system call getuid()).
System(C)
Execute the system command specied by the string C. This is done by calling the
C function system().
This also returns the system commands return value as an integer. On most
Unix systems, the lower 8 bits of this value give the process status while the next 8
bits give the value given by the command to the C function exit() (see the Unix
manual entries for system(3) or wait(2), for example). Thus one should normally
divide the result by 256 to get the exit value of the program on success.
See also the Pipe intrinsic function.
%! shell-command
Execute the given command in the Unix shell then return to Magma. Note that this
type of shell escape (contrary to the one using a System call) takes place entirely
outside Magma and does not show up in Magmas history.
3.13 Creating Names
Sometimes it is necessary to create names for les from within Magma that will not clash
with the names of existing les.
Tempname(P)
Given a prex string P, return a unique temporary name derived from P (by use of
the C library function mktemp()).
4 ENVIRONMENT AND OPTIONS
4.1 Introduction . . . . . . . . . 87
4.2 Command Line Options . . . . 87
magma -b 87
magma -c lename 87
magma -d 88
magma -n 88
magma -r workspace 88
magma -s lename 88
magma -S integer 88
4.3 Environment Variables . . . . . 89
MAGMA STARTUP FILE 89
MAGMA PATH 89
MAGMA MEMORY LIMIT 89
MAGMA LIBRARY ROOT 89
MAGMA LIBRARIES 89
MAGMA SYSTEM SPEC 89
MAGMA USER SPEC 89
MAGMA HELP DIR 89
4.4 Set and Get . . . . . . . . . 90
SetAssertions(b) 90
GetAssertions() 90
SetAutoColumns(b) 90
GetAutoColumns() 90
SetAutoCompact(b) 90
GetAutoCompact() 90
SetBeep(b) 90
GetBeep() 90
SetColumns(n) 90
GetColumns() 90
GetCurrentDirectory() 90
SetEchoInput(b) 91
GetEchoInput() 91
SetHistorySize(n) 91
GetHistorySize() 91
SetIgnorePrompt(b) 91
GetIgnorePrompt() 91
SetIgnoreSpaces(b) 91
GetIgnoreSpaces() 91
SetIndent(n) 91
GetIndent() 91
SetLibraries(s) 91
GetLibraries() 91
SetLibraryRoot(s) 92
GetLibraryRoot() 92
SetLineEditor(b) 92
GetLineEditor() 92
SetLogFile(F) 92
UnsetLogFile() 92
SetMemoryLimit(n) 92
GetMemoryLimit() 92
SetOutputFile(F) 92
UnsetOutputFile() 92
SetPath(s) 92
GetPath() 92
SetPrintLevel(l) 93
GetPrintLevel() 93
SetPrompt(s) 93
GetPrompt() 93
SetQuitOnError(b) 93
SetRows(n) 93
GetRows() 93
SetTraceback(n) 93
GetTraceback() 93
SetSeed(s, c) 93
GetSeed() 93
GetVersion() 94
SetViMode(b) 94
GetViMode() 94
4.5 Verbose Levels . . . . . . . . 94
SetVerbose(s, i) 94
SetVerbose(s, b) 94
GetVerbose(s) 94
IsVerbose(s) 94
IsVerbose(s, l) 94
ListVerbose() 94
ClearVerbose() 94
4.6 Other Information Procedures . 95
ShowMemoryUsage() 95
ShowIdentifiers() 95
ShowValues() 95
Traceback() 95
ListSignatures(C) 95
ListCategories() 95
ListTypes() 95
4.7 History . . . . . . . . . . . 96
%p 96
%pn 96
%pn
1
n
2
96
%P 96
%Pn 96
%Pn
1
n
2
96
%s 96
%sn 96
%sn
1
n
2
96
%S 96
%Sn 96
%Sn
1
n
2
97
% 97
%n 97
%n
1
n
2
97
%e 97
%en 97
%en
1
n
2
97
%! shell-command 97
86 THE MAGMA LANGUAGE Part I
4.8 The Magma Line Editor . . . . 97
SetViMode 97
SetViMode 97
4.8.1 Key Bindings (Emacs and VI mode) . 98
<Return> 98
<Backspace> 98
<Delete> 98
<Tab> 98
<Ctrl>-A 98
<Ctrl>-B 98
<Ctrl>-C 98
<Ctrl>-D 98
<Ctrl>-E 98
<Ctrl>-F 98
<Ctrl>-H 98
<Ctrl>-I 98
<Ctrl>-J 98
<Ctrl>-K 98
<Ctrl>-L 99
<Ctrl>-M 99
<Ctrl>-N 99
<Ctrl>-P 99
<Ctrl>-U 99
<Ctrl>-Vchar 99
<Ctrl>-W 99
<Ctrl>-X 99
<Ctrl>-Y 99
<Ctrl>-Z 99
<Ctrl>- 100
<Ctrl>-\ 100
4.8.2 Key Bindings in Emacs mode only . 100
Mb 100
MB 100
Mf 100
MF 100
4.8.3 Key Bindings in VI mode only . . 100
0 100
$ 100
<Ctrl>-space 100
% 100
; 100
, 100
B 101
b 101
E 101
e 101
Fchar 101
fchar 101
h 101
H 101
l 101
L 101
Tchar 101
tchar 101
w 101
W 101
A 102
a 102
C 102
crange 102
D 102
drange 102
I 102
i 102
j 102
k 102
P 102
p 102
R 102
rchar 102
S 102
s 103
U 103
u 103
X 103
x 103
Y 103
yrange 103
4.9 The Magma Help System. . . 103
SetHelpExternalBrowser(S, T) 104
SetHelpExternalBrowser(S) 104
SetHelpUseExternalBrowser(b) 104
SetHelpExternalSystem(s) 104
SetHelpUseExternalSystem(b) 105
GetHelpExternalBrowser() 105
GetHelpExternalSystem() 105
GetHelpUseExternal() 105
4.9.1 Internal Help Browser . . . . . . 105
Chapter 4
ENVIRONMENT AND OPTIONS
4.1 Introduction
This chapter describes the environmental features of Magma, together with options which
can be specied at start-up on the command line, or within Magma by the Set- proce-
dures. The history and line-editor features of Magma are also described.
4.2 Command Line Options
When starting up Magma, various command-line options can be supplied, and a list of
les to be automatically loaded can also be specied. These les may be specied by simply
listing their names as normal arguments (i.e., without a - option) following the Magma
command. For each such le name, a search for the specied le is conducted, starting in
the current directory, and in directories specied by the environment variable MAGMA PATH
after that if necessary. It is also possible to have a startup le, in which one would usually
store personal settings of parameters and variables. The startup le is specied by the
MAGMA STARTUP FILE environment variable which should be set in the users .cshrc le or
similar. This environment variable can be overridden by the -s option, or cancelled by the
-n option. The les specied by the arguments to Magma are loaded after the startup
le. Thus the startup le is not cancelled by giving extra le arguments, which is what is
usually desired.
Magma also allows one to set variables from the command line if one of the argu-
ments is of the form var:=val, where var is a valid identier (consisting of letters, under-
scores, or non-initial digits) and there is no space between var and the :=, then the variable
var is assigned within Magma to the string value val at the point where that argument
is processed. (Functions like StringToInteger should be used to convert the value to an
object of another type once inside Magma.)
magma -b
If the -b argument is given to Magma, the opening banner and all other introduc-
tory messages are suppressed. The nal total time message is also suppressed.
This is useful when sending the whole output of a Magma process to a le so that
extra removing of unwanted output is not needed.
magma -c lename
If the -c argument is given to Magma, followed by a lename, the lename is as-
sumed to refer to a package source le and the package is compiled and Magma then
exits straight away. This option is rarely needed since packages are automatically
compiled when attached.
88 THE MAGMA LANGUAGE Part I
magma -d
If the -d option is supplied to Magma, the licence for the current magmapassfile
is dumped. That is, the expiry date and the valid hostids are displayed. Magma
then exits.
magma -n
If the -n option is supplied to Magma, any startup le specied by the environment
variable MAGMA STARTUP FILE or by the -s option is cancelled.
magma -r workspace
If the -r option is supplied to Magma, together with a workspace le, that
workspace is automatically restored by Magma when it starts up.
magma -s lename
If the -s option is supplied to Magma, the given lename is used for the
startup le for Magma. This overrides the variable of the environment variable
MAGMA STARTUP FILE if it has been set. This option should not be used (as it was
before), for automatically loading les since that can be done by just listing them
as arguments to the Magma process.
magma -S integer
When starting up Magma, it is possible to specify a seed for the generation of
pseudo-random numbers. (Pseudo-random quantities are used in several Magma
algorithms, and may also be generated explicitly by some intrinsics.) The seed
should be in the range 0 to (2
32
1) inclusive. If -S is not followed by any number,
or if the -S option is not used, Magma selects the seed itself.
Example H4E1
By typing the command
magma file1 x:=abc file2
Magma would start up, read the users startup le specied by MAGMA STARTUP FILE if existent,
then read the le file1, then assign the variable x to the string value "abc", then read the le
file2, then give the prompt.
Ch. 4 ENVIRONMENT AND OPTIONS 89
4.3 Environment Variables
This section lists some environment variables used by Magma. These variables are set
by an appropriate operating system command and are used to dene various search paths
and other run-time options.
MAGMA STARTUP FILE
The name of the default start-up le. It can be overridden by the magma -s com-
mand.
MAGMA PATH
Search path for les that are loaded (a colon separated list of directories). It need not
include directories for the libraries, just personal directories. This path is searched
before the library directories.
MAGMA MEMORY LIMIT
Limit on the size of the memory that may be used by a Magma-session (in bytes).
MAGMA LIBRARY ROOT
The root directory for the Magma libraries (by supplying an absolute path name).
From within Magma SetLibraryRoot and GetLibraryRoot can be used to change
and view the value.
MAGMA LIBRARIES
Give a list of Magma libraries (as a colon separated list of sub-directories of the
library root directory). From within Magma SetLibraries and GetLibraries can
be used to change and view the value.
MAGMA SYSTEM SPEC
The Magma system spec le containing the system packages automatically attached
at start-up.
MAGMA USER SPEC
The personal user spec le containing the user packages automatically attached at
start-up.
MAGMA HELP DIR
The root directory for the Magma help les.
90 THE MAGMA LANGUAGE Part I
4.4 Set and Get
The Set- procedures allow the user to attach values to certain environment variables. The
Get- functions enable one to obtain the current values of these variables.
SetAssertions(b)
GetAssertions()
Controls the checking of assertions (see the assert statement in the chapter on the
language). Default is SetAssertions(true).
SetAutoColumns(b)
GetAutoColumns()
If enabled, the IO system will try to determine the number of columns in the win-
dow by using ioctl(); when a window change or a stop/cont occurs, the Columns
variable (below) will be automatically updated. If disabled, the Columns vari-
able will only be changed when explicitly done so by SetColumns. Default is
SetAutoColumns(true).
SetAutoCompact(b)
GetAutoCompact()
Control whether automatic compaction is performed. Normally the memory man-
ager of Magma will compact all of its memory between each statement at the top
level. This removes fragmentation and reduces excessive memory usage. In some
very rare situations, the compactions may become very slow (one symptom is that
an inordinate pause occurs between prompts when only a trivial operation or noth-
ing is done). In such cases, turning the automatic compaction o may help (at the
cost of possibly more use of memory). Default is SetAutoCompact(true).
SetBeep(b)
GetBeep()
Controls beeps. Default is SetBeep(true).
SetColumns(n)
GetColumns()
Controls the number of columns used by the IO system. This aects the line editor
and the output system. (As explained above, if AutoColumns is on, this variable
will be automatically determined.) The number of columns will determine how
words are wrapped. If set to 0, word wrap is not performed. The default value is
SetColumns(80) (unless SetAutoColumns(true)).
GetCurrentDirectory()
Returns the current directory as a string. (Use ChangeDirectory(s) to change the
working directory.)
Ch. 4 ENVIRONMENT AND OPTIONS 91
SetEchoInput(b)
GetEchoInput()
Set to true or false according to whether or not input from external les should
also be sent to standard output.
SetHistorySize(n)
GetHistorySize()
Controls the number of lines saved in the history. If the number is set to 0, no
history is preserved.
SetIgnorePrompt(b)
GetIgnorePrompt()
Controls the option to ignore the prompt to allow the pasting of input lines back
in. If enabled, any leading > characters (possibly separated by white space) are
ignored by the history system when the input le is a terminal, unless the line
consists of the > character alone (without a following space), which could not
come from a prompt since in a prompt a space or another character follows a >.
Default is SetIgnorePrompt(false).
SetIgnoreSpaces(b)
GetIgnoreSpaces()
Controls the option to ignore spaces when searching in the line editor. If the user
moves up or down in the line editor using <Ctrl>-P or <Ctrl>-N (see the line editor
key descriptions) and if the cursor is not at the beginning of the line, a search is
made forwards or backwards, respectively, to the rst line which starts with the
same string as the string consisting of all the characters before the cursor. While
doing the search, spaces are ignored if and only if this option is on (value true).
Default is SetIgnoreSpaces(true).
SetIndent(n)
GetIndent()
Controls the indentation level for formatting output. The default is SetIndent(4).
SetLibraries(s)
GetLibraries()
Controls the Magma library directories via environment variable MAGMA LIBRARIES.
The procedure SetLibraries takes a string, which will be taken as the (colon-
separated) list of sub-directories in the library root directory for the libraries; the
function GetLibraryRoot returns the current value as a string. These directories
will be searched when you try to load a le; note however that rst the directories
indicated by the current value of your path environment variable MAGMA PATH will
be searched. See SetLibraryRoot for the root directory.
92 THE MAGMA LANGUAGE Part I
SetLibraryRoot(s)
GetLibraryRoot()
Controls the root directory for the Magma libraries, via the environment variable
MAGMA LIBRARY ROOT. The procedure SetLibraryRoot takes a string, which will be
the absolute pathname for the root of the libraries; the function GetLibraryRoot
returns the current value as a string. See also SetLibraries
SetLineEditor(b)
GetLineEditor()
Controls the line editor. Default is SetLineEditor(true).
SetLogFile(F)
Overwrite BoolElt Default : false
UnsetLogFile()
Procedure. Set the log le to be the le specied by the string F: all input and
output will be sent to this log le as well as to the terminal. If a log le is already
in use, it is closed and F is used instead. The parameter Overwrite can be used to
indicate that the le should be truncated before writing input and output on it; by
default the le is appended.
SetMemoryLimit(n)
GetMemoryLimit()
Set the limit (in bytes) of the memory which the memory manager will allocate (no
limit if 0). Default is SetMemoryLimit(0).
SetOutputFile(F)
Overwrite BoolElt Default : false
UnsetOutputFile()
Start/stop redirecting all Magma output to a le (specied by the string F). The
parameter Overwrite can be used to indicate that the le should be truncated
before writing output on it.
SetPath(s)
GetPath()
Controls the path by which the searching of les is done. The path consists of a colon
separated list of directories which are searched in order (. implicitly assumed at
the front). Tilde expansion is done on each directory. (May be overridden by the
environment variable MAGMA PATH.)
Ch. 4 ENVIRONMENT AND OPTIONS 93
SetPrintLevel(l)
GetPrintLevel()
Controls the global printing level, which is one of "Minimal", "Magma", "Maximal",
"Default". Default is SetPrintLevel("Default").
SetPrompt(s)
GetPrompt()
Controls the terminal prompt (a string). Expansion of the following % escapes
occurs:
%% The character %
%h The current history line number.
%S The parser state: when a new line is about to be read while the parser
has only seen incomplete statements, the state consists of a stack of words
like if, while, indicating the incomplete statements.
%s Like %S except that only the topmost word is displayed.
Default is SetPrompt("%S> ").
SetQuitOnError(b)
Set whether Magma should quit on any error to b. If b is true, Magma
will completely quit when any error (syntax, runtime, etc.) occurs. Default is
SetQuitOnError(false).
SetRows(n)
GetRows()
Controls the number of rows in a page used by the IO system. This aects the
output system. If set to 0, paging is not performed. Otherwise a prompt is given
after the given number of rows for a new page. The default value is SetRows(0).
SetTraceback(n)
GetTraceback()
Controls whether Magma should produce a traceback of user function calls before
each error message. The default value is SetTraceback(true).
SetSeed(s, c)
GetSeed()
Controls the initialization seed and step number for pseudo-random number gener-
ation. For details, see the section on random object generation in the chapter on
statements and expressions.
94 THE MAGMA LANGUAGE Part I
GetVersion()
Return integers x, y and z such the current version of Magma is Vx.yz.
SetViMode(b)
GetViMode()
Controls the type of line editor used: Emacs (false) or VI style. Default is
SetViMode(false).
4.5 Verbose Levels
By turning verbose printing on for certain modules within Magma, some information on
computations that are performed can be obtained. For each option, the verbosity may
have dierent levels. The default is level 0 for each option.
There are also 5 slots available for user-dened verbose ags. The ags can be set in
user programs by SetVerbose("Usern", true) where n should be one of 1, 2, 3, 4, 5, and
the current setting is returned by GetVerbose("Usern").
SetVerbose(s, i)
SetVerbose(s, b)
Set verbose level for s to be level i or b. Here the argument s must be a string. The
verbosity may have dierent levels. An integer i for the second argument selects the
appropriate level. A second argument i of 0 or b of false means no verbosity. A
boolean value for b of true for the second argument selects level 1. (See above for
the valid values for the string s).
GetVerbose(s)
Return the value of verbose ag s as an integer. (See above for the valid values for
the string s).
IsVerbose(s)
Return the whether the value of verbose ag s is non-zero. (See above for the valid
values for the string s).
IsVerbose(s, l)
Return the whether the value of verbose ag s is greater than or equal to l. (See
above for the valid values for the string s).
ListVerbose()
List all verbose ags. That is, print each verbose ag and its maximal level.
ClearVerbose()
Clear all verbose ags. That is, set the level for all verbose ags to 0.
Ch. 4 ENVIRONMENT AND OPTIONS 95
4.6 Other Information Procedures
The following procedures print information about the current state of Magma.
ShowMemoryUsage()
(Procedure.) Show Magmas current memory usage.
ShowIdentifiers()
(Procedure.) List all identiers that have been assigned to.
ShowValues()
(Procedure.) List all identiers that have been assigned to with their values.
Traceback()
(Procedure.) Display a traceback of the current Magma function invocations.
ListSignatures(C)
Isa BoolElt Default : true
Search MonStgElt Default : Both
ShowSrc BoolElt Default : false
List all intrinsic functions, procedures and operators having objects from category
C among their arguments or return values. The parameter Isa may be set to false
so that any categories which C inherit from are not considered. The parameter
Search, with valid string values Both, Arguments, ReturnValues, may be used
to specify whether the arguments, the return values, or both, are considered (de-
fault both). ShowSrc can be used to see where package intrinsics are dened. Use
ListCategories for the names of the categories.
ListCategories()
ListTypes()
Procedure to list the (abbreviated) names for all available categories in Magma.
96 THE MAGMA LANGUAGE Part I
4.7 History
Magma provides a history system which allows the recall and editing of previous lines.
The history system is invoked by typing commands which begin with the history character
%. Currently, the following commands are available.
%p
List the contents of the history buer. Each line is preceded by its history line
number.
%pn
List the history line n in %p format.
%pn
1
n
2
List the history lines in the range n
1
to n
2
in %p format.
%P
List the contents of the history buer. The initial numbers are not printed.
%Pn
List the history line n in %P format.
%Pn
1
n
2
List the history lines in the range n
1
to n
2
in %P format.
%s
List the contents of the history buer with an initial statement for each line to reset
the random number seed to the value it was just before the line was executed. This
is useful when one wishes to redo a computation using exactly the same seed as
before but does not know what the seed was at the time.
%sn
Print the history line n in %s format.
%sn
1
n
2
Print the history lines in the range n
1
to n
2
in %s format.
%S
As for %s except that the statement to set the seed is only printed if the seed has
changed since the previous time it was printed. Also, it is not printed if it would
appear in the middle of a statement (i.e., the last line did not end in a semicolon).
%Sn
Print the history line n in %S format.
Ch. 4 ENVIRONMENT AND OPTIONS 97
%Sn
1
n
2
Print the history lines in the range n
1
to n
2
in %S format.
%
Reenter the last line into the input stream.
%n
Reenter the line specied by line number n into the input stream.
%n
1
n
2
Reenter the history lines in the range n
1
to n
2
into the input stream.
%e
Edit the last line. The editor is taken to be the value of the EDITOR environment
variable if is set, otherwise /bin/ed is used. If after the editor has exited the le
has not been changed then nothing is done. Otherwise the contents of the new le
are reentered into the input stream.
%en
Edit the line specied by line number n.
%en
1
n
2
Edit the history lines in the range n
1
to n
2
.
%! shell-command
Execute the given command in the Unix shell then return to Magma.
4.8 The Magma Line Editor
Magma provides a line editor with both Emacs and VI style key bindings. To enable the
VI style of key bindings, type
SetViMode(true)
and type
SetViMode(false)
to revert to the Emacs style of key bindings. By default ViMode is false; that is, the
Emacs style is in eect.
Many key bindings are the same in both Emacs and VI style. This is because some VI
users like to be able to use some Emacs keys (like <Ctrl>-P) as well as the VI command
keys. Thus key bindings in Emacs which are not used in VI insert mode can be made
common to both.
98 THE MAGMA LANGUAGE Part I
4.8.1 Key Bindings (Emacs and VI mode)
<Ctrl>-key means hold down the Control key and press key.
<Return>
Accept the line and print a new line. This works in any mode.
<Backspace>
<Delete>
Delete the previous character.
<Tab>
Complete the word which the cursor is on or just after. If the word doesnt have a
unique completion, it is rst expanded up to the common prex of all the possible
completions. An immediately following Tab key will list all of the possible comple-
tions. Currently completion occurs for system functions and procedures, parameters,
reserved words, and user identiers.
<Ctrl>-A
Move to the beginning of the line (alpha = beginning).
<Ctrl>-B
Move back a character (back).
<Ctrl>-C
Abort the current line and start a new line.
<Ctrl>-D
On an empty line, send a EOF character (i.e., exit at the top level of the command
interpreter). If at end of line, list the completions. Otherwise, delete the character
under the cursor (delete).
<Ctrl>-E
Move to the end of the line (end).
<Ctrl>-F
Move forward a character (forward).
<Ctrl>-H
Same as Backspace.
<Ctrl>-I
Same as Tab.
<Ctrl>-J
Same as Return.
Ch. 4 ENVIRONMENT AND OPTIONS 99
<Ctrl>-K
Delete all characters from the cursor to the end of the line (kill).
<Ctrl>-L
Redraw the line on a new line (helpful if the screen gets wrecked by programs like
write, etc.).
<Ctrl>-M
Same as <Return>.
<Ctrl>-N
Go forward a line in the history buer (next). If the cursor is not at the begin-
ning of the line, go forward to the rst following line which starts with the same
string (ignoring spaces i the ignore spaces option is on see SetIgnoreSpaces)
as the string consisting of all the characters before the cursor. Also, if <Ctrl>-N
is typed initially at a new line and the last line entered was actually a recall of a
preceding line, then the next line after that is entered into the current buer. Thus
to repeat a sequence of lines (with minor modications perhaps to each), then one
only needs to go back to the rst line with <Ctrl>-P (see below), press <Return>,
then successively press <Ctrl>-N followed by <Return> for each line.
<Ctrl>-P
Go back a line in the history buer (previous). If the cursor is not at the beginning
of the line, go back to the rst preceding line which starts with the same string
(ignoring spaces i the ignore spaces option is on see SetIgnoreSpaces) as the
string consisting of all the characters before the cursor. For example, typing at a
new line x:= and then <Ctrl>-P will go back to the last line which assigned x (if a
line begins with, say, x :=, it will also be taken).
<Ctrl>-U
Clear the whole of the current line.
<Ctrl>-Vchar
Insert the following character literally.
<Ctrl>-W
Delete the previous word.
<Ctrl>-X
Same as <Ctrl>-U.
<Ctrl>-Y
Insert the contents of the yank-buer before the character under the cursor.
<Ctrl>-Z
Stop Magma.
100 THE MAGMA LANGUAGE Part I
<Ctrl>-
Undo the last change.
<Ctrl>-
Immediately quit Magma.
On most systems the arrow keys also have the obvious meaning.
4.8.2 Key Bindings in Emacs mode only
Mkey means press the Meta key and then key. (At the moment, the Meta key is only the
Esc key.)
Mb
MB
Move back a word (Back).
Mf
MF
Move forward a word (Forward).
4.8.3 Key Bindings in VI mode only
In the VI mode, the line editor can also be in two modes: the insert mode and the command
mode. When in the insert mode, any non-control character is inserted at the current cursor
position. The command mode is then entered by typing the Esc key. In the command
mode, various commands are given a range giving the extent to which they are performed.
The following ranges are available:
0
Move to the beginning of the line.
$
Move to the end of the line.
<Ctrl>-space
Move to the rst non-space character of the line.
%
Move to the matching bracket. (Bracket characters are (, ), [, ], , , <, and >.)
;
Move to the next character. (See F, f, T, and t.)
,
Move to the previous character. (See F, f, T, and t.)
Ch. 4 ENVIRONMENT AND OPTIONS 101
B
Move back a space-separated word (Back).
b
Move back a word (back).
E
Move forward to the end of the space-separated word (End).
e
Move forward to the end of the word (end).
Fchar
Move back to the rst occurrence of char.
fchar
Move forward to the rst occurrence of char.
h
H
Move back a character (<Ctrl>-H = Backspace).
l
L
Move back a character (<Ctrl>-L = forward on some keyboards).
Tchar
Move back to just after the rst occurrence of char.
tchar
Move forward to just before the rst occurrence of char.
w
Move forward a space-separated word (Word).
W
Move forward a word (word).
Any range may be preceded by a number to multiply to indicate how many times the
operation is done. The VI-mode also provides the yank-buer, which contains characters
which are deleted or yanked see below.
The following keys are also available in command mode:
102 THE MAGMA LANGUAGE Part I
A
Move to the end of the line and change to insert mode (Append).
a
Move forward a character (if not already at the end of the line) and change to insert
mode (append).
C
Delete all the characters to the end of line and change to insert mode (Change).
crange
Delete all the characters to the specied range and change to insert mode (change).
D
Delete all the characters to the end of line (Delete).
drange
Delete all the characters to the specied range (delete).
I
Move to the rst non-space character in the line and change to insert mode (In-
sert).
i
Change to insert mode (insert).
j
Go forward a line in the history buer (same as <Ctrl>-N).
k
Go back a line in the history buer (same as <Ctrl>-P).
P
Insert the contents of the yank-buer before the character under the cursor.
p
Insert the contents of the yank-buer before the character after the cursor.
R
Enter over-type mode: typed characters replace the old characters under the cursor
without insertion. Pressing Esc returns to the command mode.
rchar
Replace the character the cursor is over with char.
S
Ch. 4 ENVIRONMENT AND OPTIONS 103
Delete the whole line and change to insert mode (Substitute).
s
Delete the current character and change to insert mode (substitute).
U
u
Undo the last change.
X
Delete the character to the left of the cursor.
x
Delete the character under the cursor.
Y
Yank the whole line - i.e., copy the whole line into the yank-buer (Yank).
yrange
Copy all characters from the cursor to the specied range into the yank-buer
(yank).
4.9 The Magma Help System
Magma provides extensive online help facilities that can be accessed in dierent ways. The
easiest way to access the documentation is by typing:
magmahelp
Which should start some browser (usually netscape) on the main page of the Magma
documentation.
The easiest way to get some information about any Magma intrinsic is by typing:
(Here we assume you to be interested in FundamentalUnit)
> FundamentalUnit;
Which now will list all signatures for this intrinsic (i.e. all known ways to use this function):
> FundamentalUnit;
Intrinsic FundamentalUnit
Signatures:
(<FldQuad> K) -> FldQuadElt
(<RngQuad> O) -> RngQuadElt
The fundamental unit of K or O
(<RngQuad> R) -> RngQuadElt
104 THE MAGMA LANGUAGE Part I
Fundamental unit of the real quadratic order.
Next, to get more detailed information, try
> ?FundamentalUnit
But now several things could happen depending on the installation. Using the default,
you get
===========================================================
PATH: /magma/ring-field-algebra/quadratic/operation/\
class-group/FundamentalUnit
KIND: Intrinsic
===========================================================
FundamentalUnit(K) : FldQuad -> FldQuadElt
FundamentalUnit(O) : RngQuad -> RngQuadElt
A generator for the unit group of the order O or the
maximal order
of the quadratic field K.
===========================================================
Second, a WWW-browser could start on the part of the online help describing your
function (or at least the index of the rst character). Third, some arbitrary program could
be called to provide you with the information.
If SetVerbose("Help", true); is set, Magma will show the exact command used and
the return value obtained.
SetHelpExternalBrowser(S, T)
SetHelpExternalBrowser(S)
Denes the external browser to be used if SetHelpUseExternalBrowser(true) is
in eect. The string has to be a valid command taking exactly one argument (%s)
which will we replaced by a URL. In case two strings are provided, the second
denes a fall-back system. Typical use for this is to rst try to use an already
running browser and if this fails, start a new one.
SetHelpUseExternalBrowser(b)
Tells Magma to actually use (or stop to use) the external browser. If both
SetHelpUseExternalSystem and SetHelpUseExternalBrowser are set to true, the
assignment made last will be eective.
SetHelpExternalSystem(s)
This will tell Magma to use a user dened external program to access the help.
The string has to contain exactly one %s which will be replaced by the argument to
?. The resulting string must be a valid command.
Ch. 4 ENVIRONMENT AND OPTIONS 105
SetHelpUseExternalSystem(b)
Tells Magma to actually use (or stop to use) the external help system. If both
SetHelpUseExternalSystem and SetHelpUseExternalBrowser are set to true, the
assignment made last will be eective.
GetHelpExternalBrowser()
Returns the currently used command strings.
GetHelpExternalSystem()
Returns the currently used command string.
GetHelpUseExternal()
The rst value is the currently used value from SetHelpUseExternalBrowser, the
second reects SetHelpUseExternalSystem.
4.9.1 Internal Help Browser
Magma has a very powerful internal help-browser that can be entered with
> ??
5 MAGMA SEMANTICS
5.1 Introduction . . . . . . . . 109
5.2 Terminology . . . . . . . . 109
5.3 Assignment . . . . . . . . . 110
5.4 Uninitialized Identiers . . . 110
5.5 Evaluation in Magma . . . . 111
5.5.1 Call by Value Evaluation . . . . . 111
5.5.2 Magmas Evaluation Process . . . 112
5.5.3 Function Expressions . . . . . . 113
5.5.4 Function Values Assigned to Identiers114
5.5.5 Recursion and Mutual Recursion . 114
5.5.6 Function Application . . . . . . 115
5.5.7 The Initial Context . . . . . . . 116
5.6 Scope . . . . . . . . . . . 116
5.6.1 Local Declarations . . . . . . . . 117
5.6.2 The rst use Rule . . . . . . . 117
5.6.3 Identier Classes . . . . . . . . 118
5.6.4 The Evaluation Process Revisited . 119
5.6.5 The single use Rule . . . . . . . 119
5.7 Procedure Expressions . . . . 119
5.8 Reference Arguments . . . . 121
5.9 Dynamic Typing . . . . . . 122
5.10 Traps for Young Players . . . 123
5.10.1 Trap 1 . . . . . . . . . . . . . 123
5.10.2 Trap 2 . . . . . . . . . . . . . 123
5.11 Appendix A: Precedence . . . 125
5.12 Appendix B: Reserved Words . 126
Chapter 5
MAGMA SEMANTICS
5.1 Introduction
This chapter describes the semantics of Magma (how expressions are evaluated, how
identiers are treated, etc.) in a fairly informal way. Although some technical language
is used (particularly in the opening few sections) the chapter should be easy and essential
reading for the non-specialist. The chapter is descriptive in nature, describing how Magma
works, with little attempt to justify why it works the way it does. As the chapter proceeds,
it becomes more and more precise, so while early sections may gloss over or omit things
for the sake of simplicity and learnability, full explanations are provided later.
It is assumed that the reader is familiar with basic notions like a function, an operator,
an identier, a type ...
And now for some buzzwords: Magma is an imperative, call by value, statically scoped,
dynamically typed programming language, with an essentially functional subset. The
remainder of the chapter explains what these terms mean, and why a user might want to
know about such things.
5.2 Terminology
Some terminology will be useful. It is perhaps best to read this section only briey, and
to refer back to it when necessary.
The term expression will be used to refer to a textual entity. The term value will be
used to refer to a run-time value denoted by an expression. To understand the dierence
between an expression and a value consider the expressions 1+2 and 3. The expressions
are textually dierent but they denote the same value, namely the integer 3.
A function expression is any expression of the form function ... end function or of
the form func< ... | ... >. The former type of function expression will be said to be
in the statement form, the latter in the expression form. A function value is the run-time
value denoted by a function expression. As with integers, two function expressions can be
textually dierent while denoting the same (i.e., extensionally equal) function value. To
clearly distinguish function values from function expressions, the notation FUNC( ... : ...
) will be used to describe function values.
The formal arguments of a function in the statement form are the identiers that
appear between the brackets just after the function keyword, while for a function in the
expression form they are the identiers that appear before the |. The arguments to a
function are the expressions between the brackets when a function is applied.
The body of a function in the statement form is the statements after the formal ar-
guments. The body of a function in the expression form is the expression after the |
symbol.
110 THE MAGMA LANGUAGE Part I
An identier is said to occur inside a function expression when it is occurs textually
anywhere in the body of a function.
5.3 Assignment
An assignment is an association of an identier to a value. The statement,
> a := 6;
establishes an association between the identier a and the value 6 (6 is said to be the value
of a, or to be assigned to a). A collection of such assignments is called a context.
When a value V is assigned to an identier I one of two things happens:
(1) if I has not been previously assigned to, it is added to the current context and associated
with V . I is said to be declared when it is assigned to for the rst time.
(2) if I has been previously assigned to, the value associated with I is changed to V . I is
said to be re-assigned.
The ability to assign and re-assign to identiers is why Magma is called an imperative
language.
One very important point about assignment is illustrated by the following example.
Say we type,
> a := 6;
> b := a+7;
After executing these two lines the context is [ (a,6), (b,13) ]. Now say we type,
> a := 0;
The context is now [ (a,0), (b,13) ]. Note that changing the value of a does not
change the value of b because bs value is statically determined at the point where it is
assigned. Changing a does not produce the context [ (a,0), (b,7) ].
5.4 Uninitialized Identiers
Before executing a piece of code Magma attempts to check that it is semantically well
formed (i.e., that it will execute without crashing). One of the checks Magma makes is to
check that an identier is declared (and thus initialized) before it is used in an expression.
So, for example assuming a had not been previously declared, then before executing either
of the following lines Magma will raise an error:
> a;
> b := a;
Magma can determine that execution of either line will cause an error since a has no as-
signed value. The user should be aware that the checks made for semantic well-formedness
are necessarily not exhaustive!
Ch. 5 MAGMA SEMANTICS 111
There is one important rule concerning uninitialized identiers and assignment. Con-
sider the line,
> a := a;
Now if a had been previously declared then this is re-assignment of a. If not then it is
an error since a on the right hand side of the := has no value. To catch this kind of
error Magma checks the expression on the right hand side of the := for semantic well
formedness before it declares the identiers on the left hand side of the :=. Put another
way the identiers on the left hand side are not considered to be declared in the right hand
side, unless they were declared previously.
5.5 Evaluation in Magma
Evaluation is the process of computing (or constructing) a value from an expression. For
example the value 3 can be computed from the expression 1+2. Computing a value from
an expression is also known as evaluating an expression.
There are two aspects to evaluation, namely when and how it is performed. This section
discusses these two aspects.
5.5.1 Call by Value Evaluation
Magma employs call by value evaluation. This means that the arguments to a function
are evaluated before the function is applied to those arguments. Assume f is a function
value. Say we type,
> r := f( 6+7, true or false );
Magma evaluates the two arguments to 13 and true respectively, before applying f.
While knowing the exact point at which arguments are evaluated is not usually very
important, there are cases where such knowledge is crucial. Say we type,
> f := function( n, b )
> if b then return n else return 1;
> end function;
and we apply f as follows
> r := f( 4/0, false );
Magma treats this as an error since the 4/0 is evaluated, and an error produced, before
the function f is applied.
By contrast some languages evaluate the arguments to a function only if those argu-
ments are encountered when executing the function. This evaluation process is known as
call by name evaluation. In the above example r would be set to the value 1 and the ex-
pression 4/0 would never be evaluated because b is false and hence the argument n would
never be encountered.
112 THE MAGMA LANGUAGE Part I
Operators like + and are treated as inx functions. So
> r := 6+7;
is treated as the function application,
> r := +(6,7);
Accordingly all arguments to an operator are evaluated before the operator is applied.
There are three operators, select, and and or that are exceptions to this rule and
are thus not treated as inx functions. These operators use call by name evaluation and
only evaluate arguments as need be. For example if we type,
> false and (4/0 eq 6);
Magma will reply with the answer false since Magma knows that false and X for all X
is false.
5.5.2 Magmas Evaluation Process
Let us examine more closely how Magma evaluates an expression as it will help later in
understanding more complex examples, specically those using functions and maps. To
evaluate an expression Magma proceeds by a process of identier substitution, followed by
simplication to a canonical form. Specically expression evaluation proceeds as follows,
(1) replace each identier in the expression by its value in the current context.
(2) simplify the resultant value to its canonical form.
The key point here is that the replacement step takes an expression and yields an unsim-
plied value! A small technical note: to avoid the problem of having objects that are part
expressions, part values, all substitutions in step 1 are assumed to be done simultaneously
for all identiers in the expression. The examples in this chapter will however show the
substitutions being done in sequence and will therefore be somewhat vague about what
exactly these hybrid objects are!
To clarify this process assume that we type,
> a := 6;
> b := 7;
producing the context [ (a,6), (b,7) ]. Now say we type,
> c := a+b;
This produces the context [ (a,6), (b,7), (c,13) ]. By following the process outlined
above we can see how this context is calculated. The steps are,
(1) replace a in the expression a+b by its value in the current context giving 6+b.
(2) replace b in 6+b by its value in the current context giving 6+7.
(3) simplify 6+7 to 13
The result value of 13 is then assigned to c giving the previously stated context.
Ch. 5 MAGMA SEMANTICS 113
5.5.3 Function Expressions
Magmas evaluation process might appear to be an overly formal way of stating the obvious
about calculating expression values. This formality is useful, however when it comes to
function (and map) expressions.
Functions in Magma are rst class values, meaning that Magma treats function values
just like it treats any other type of value (e.g., integer values). A function value may be
passed as an argument to another function, may be returned as the result of a function,
and may be assigned to an identier in the same way that any other type of value is. Most
importantly however function expressions are evaluated exactly as are all other expressions.
The fact that Magma treats functions as rst class values is why Magma is said to have
an essentially functional subset.
Take the preceding example. It was,
> a := 6;
> b := 7;
> c := a+b;
giving the context [ (a,6),(b,7),(c,13) ]. Now say I type,
> d := func< n | a+b+c+n >;
Magma uses the same process to evaluate the function expression func< n | a+b+c+n >
on the right hand side of the assignment d := ... as it does to evaluate expression a+b on
the right hand side of the assignment c := .... So evaluation of this function expression
proceeds as follows,
(1) replace a in the expression func< n | a+b+c+n > by its value in the current context
giving func< n | 6+b+c+n >.
(2) replace b in func< n | 6+b+c+n > by its value in the current context giving func< n
| 6+7+c+n >.
(3) replace c in func< n | 6+7+c+n > by its value in the current context giving FUNC(n :
6+7+13+n)
(4) simplify the resultant value FUNC(n : 6+7+13+n) to the value FUNC(n : 26+n).
Note again that the process starts with an expression and ends with a value, and that
throughout the function expression is evaluated just like any other expression. A small
technical point: function simplication may not in fact occur but the user is guaranteed
that the simplication process will at least produce a function extensionally equal to the
function in its canonical form.
The resultant function value is now assigned to d just like any other type of value would
be assigned to an identier yielding the context [ (a,6),(b,7), (c,8), (d,FUNC(n :
26+n)) ].
As a nal point note that changing the value of any of a, b, and c, does not change the
value of d!
114 THE MAGMA LANGUAGE Part I
5.5.4 Function Values Assigned to Identiers
Say we type the following,
> a := 1;
> b := func< n | a >;
> c := func< n | b(6) >;
The rst line leaves a context of the form [ (a,1) ]. The second line leaves a context of
the form [ (a,1), (b,FUNC(n : 1)) ].
The third line is evaluated as follows,
(1) replace the value of b in the expression func< n | b(6) > by its value in the current
context giving FUNC(n : (FUNC(n : 1))(6)).
(2) simplify this value to FUNC(n : 1) since applying the function value FUNC(n : 1)
to the argument 6 always yields 1.
The key point here is that identiers whose assigned value is a function value (in this case
b), are treated exactly like identiers whose assigned value is any other type of value.
Now look back at the example at the end of the previous section. One step in the series
of replacements was not mentioned. Remember that + is treated as a shorthand for an
inx function. So a+b is equivalent to +(a,b). + is an identier (assigned a function
value), and so in the replacement part of the evaluation process there should have been an
extra step, namely,
(4) replace + in func< n : 6+7+13+n > by its value in the current context giving FUNC(n
: A( A( A(6,7), 13 ), n )).
(5) simplify the resultant value to FUNC(n : A( 26, n )). where A is the (function)
value that is the addition function.
5.5.5 Recursion and Mutual Recursion
How do we write recursive functions? Function expressions have no names so how can a
function expression apply itself to do recursion?
It is tempting to say that the function expression could recurse by using the identier
that the corresponding function value is to be assigned to. But the function value may
not be being assigned at all: it may simply be being passed as an actual argument to
some other function value. Moreover even if the function value were being assigned to an
identier the function expression cannot use that identier because the assignment rules
say that the identiers on the left hand side of the := in an assignment statement are not
considered declared on the right hand side, unless they were previously declared.
The solution to the problem is to use the $$ pseudo-identier. $$ is a placeholder for
the function value denoted by the function expression inside which the $$ occurs. An
example serves to illustrate the use of $$. A recursive factorial function can be dened as
follows,
> factorial := function(n)
> if n eq 1 then
> return 1;
Ch. 5 MAGMA SEMANTICS 115
> else
> return n * $$(n-1);
> end if;
> end function;
Here $$ is a placeholder for the function value that the function expression function(n)
if n eq ... end function denotes (those worried that the denoted function value ap-
pears to be dened in terms of itself are referred to the xed point semantics of recursive
functions in any standard text on denotational semantics).
A similar problem arises with mutual recursion where a function value f applies another
function value g, and g likewise applies f. For example,
> f := function(...) ... a := g(...); ... end function;
> g := function(...) ... b := f(...); ... end function;
Again Magmas evaluation process appears to make this impossible, since to construct f
Magma requires a value for g, but to construct g Magma requires a value for f. Again
there is a solution. An identier can be declared forward to inform Magma that a
function expression for the forward identier will be supplied later. The functions f and
g above can therefore be declared as follows,
> forward f, g;
> f := function(...) ... a := g(...); ... end function;
> g := function(...) ... b := f(...); ... end function;
(strictly speaking it is only necessary to declare g forward as the value of f will be known by
the time the function expression function(...) ... b := f(...); ... end function
is evaluated).
5.5.6 Function Application
It was previously stated that Magma employs call by value evaluation, meaning that the
arguments to a function are evaluated before the function is applied. This subsection
discusses how functions are applied once their arguments have been evaluated.
Say we type,
> f := func< a, b | a+b >;
producing the context [ (f,FUNC(a,b : a+b)) ].
Now say we apply f by typing,
> r := f( 1+2, 6+7 ).
How is the value to be assigned to r calculated? If we follow the evaluation process we will
reach the nal step which will say something like,
simplify (FUNC(a, b : A(a,b)))(3,13) to its canonical form
where as before A is the value that is the addition function. How is this simplication
performed? How are function values applied to actual function arguments to yield result
116 THE MAGMA LANGUAGE Part I
values? Not unsurprisingly the answer is via a process of substitution. The evaluation of
a function application proceeds as follows,
(1) replace each formal argument in the function body by the corresponding actual argu-
ment.
(2) simplify the function body to its canonical form.
Exactly what it means to simplify the function body ... is intentionally left vague as the
key point here is the process of replacing formal arguments by values in the body of the
function.
5.5.7 The Initial Context
The only thing that remains to consider with the evaluation semantics, is how to get the
ball rolling. Where do the initial values for things like the addition function come from?
The answer is that when Magma starts up it does so with an initial context dened. This
initial context has assignments of all the built-in Magma function values to the appropriate
identiers. The initial context contains for example the assignment of the addition function
to the identier +, the multiplication function to the identier *, etc.
If, for example, we start Magma and immediately type,
> 1+2;
then in evaluating the expression 1+2 Magma will replace + by its value in the initial
context.
Users interact with this initial context by typing statements at the top level (i.e.,
statements not inside any function or procedure). A user can change the initial context
through re-assignment or expand it through new assignments.
5.6 Scope
Say we type the following,
> temp := 7;
> f := function(a,b)
> temp := a * b;
> return temp^2;
> end function;
If the evaluation process is now followed verbatim, the resultant context will look like
[ (temp,7), (f,FUNC(a,b : 7 := a*b; return 7^2;)) ], which is quite clearly not
what was intended!
Ch. 5 MAGMA SEMANTICS 117
5.6.1 Local Declarations
What is needed in the previous example is some way of declaring that an identier, in this
case temp, is a new identier (i.e., distinct from other identiers with the same name)
whose use is conned to the enclosing function. Magma provides such a mechanism, called
a local declaration. The previous example could be written,
> temp := 7;
> f := function(a,b)
> local temp;
> temp := a * b;
> return temp^2;
> end function;
The identier temp inside the body of f is said to be (declared) local to the enclosing
function. Evaluation of these two assignments would result in the context being [ (temp,
7), (f, FUNC(a,b : local temp := a*b; return local temp^2;)) ] as intended.
It is very important to remember that temp and local temp are distinct! Hence if we
now type,
> r := f(3,4);
the resultant context would be [ (temp,7), (f,FUNC(a,b : local temp := a*b;
return local temp^2;)), (r,144) ]. The assignment to local temp inside the body
of f does not change the value of temp outside the function. The eect of an assignment
to a local identier is thus localized to the enclosing function.
5.6.2 The rst use Rule
It can become tedious to have to declare all the local variables used in a function body.
Hence Magma adopts a convention whereby an identier can be implicitly declared ac-
cording to how it is rst used in a function body. The convention is that if the rst use
of an identier inside a function body is on the left hand side of a :=, then the identier
is considered to be local, and the function body is considered to have an implicit local
declaration for this identier at its beginning. There is in fact no need therefore to declare
temp as local in the previous example as the rst use of temp is on the left hand side of a
:= and hence temp is implicitly declared local.
It is very important to note that the term rst use refers to the rst textual use of an
identier. Consider the following example,
> temp := 7;
> f := function(a,b)
> if false then
> temp := a * b;
> return temp;
> else
> temp;
> return 1;
118 THE MAGMA LANGUAGE Part I
> end if;
> end function;
The rst textual use of temp in this function body is in the line
> temp := a * b;
Hence temp is considered as a local inside the function body. It is not relevant that the
if false ... condition will never be true and so the rst time temp will be encountered
when f is applied to some arguments is in the line
> temp;
First use means rst textual use, modulo the rule about examining the right hand side
of a := before the left!
5.6.3 Identier Classes
It is now necessary to be more precise about the treatment of identiers in Magma. Every
identier in a Magma program is considered to belong to one of three possible classes,
these being:
(a) the class of value identiers
(b)the class of variable identiers
(c) the class of reference identiers
The class an identier belongs to indicates how the identier is used in a program.
The class of value identiers includes all identiers that stand as placeholders for values,
namely:
(a) the formal arguments to a function expression.
(b)all loop identiers.
(c) the $$ pseudo-identier.
(d)all identiers whose rst use in a function expression is as a value (i.e., not on the left
hand side of an :=, nor as an actual reference argument to a procedure).
Because value identiers stand as placeholders for values to be substituted during the
evaluation process, they are eectively constants, and hence they cannot be assigned to.
Assigning to a value identier would be akin to writing something like 7 := 8;!
The class of variable identiers includes all those identiers which are declared as local,
either implicitly by the rst use rule, or explicitly through a local declaration. Identiers
in this class may be assigned to.
The class of reference identiers will be discussed later.
Ch. 5 MAGMA SEMANTICS 119
5.6.4 The Evaluation Process Revisited
The reason it is important to know the class of an identier is that the class of an identier
eects how it is treated during the evaluation process. Previously it was stated that the
evaluation process was,
(1) replace each identier in the expression by its value in the current context.
(2) simplify the resultant value to its canonical form.
Strictly speaking the rst step of this process should read,
(1
) replace each free identier in the expression by its value in the current context, where
an identier is said to be free if it is a value identier which is not a formal argument,
a loop identier, or the $$ identier.
This denition of the replacement step ensures for example that while computing the value
of a function expression F, Magma does not attempt to replace Fs formal arguments with
values from the current context!
5.6.5 The single use Rule
As a nal point on identier classes it should be noted that an identier may belong to
only one class within an expression. Specically therefore an identier can only be used
in one way inside a function body. Consider the following function,
> a := 7;
> f := function(n) a := a; return a; end function;
It is not the case that a is considered as a variable identier on the left hand side of the
:=, and as a value identier on the right hand side of the :=. Rather a is considered to be
a value identier as its rst use is as a value on the right hand side of the := (remember
that Magma inspects the right hand side of an assignment, and hence sees a rst as a
value identier, before it inspects the left hand side where it sees a being used as a variable
identier).
5.7 Procedure Expressions
To date we have only discussed function expressions, these being a mechanism for com-
puting new values from the values of identiers in the current context. Together with
assignment this provides us with a means of changing the current context to compute a
new value for an identier in the current context, we call a function and then re-assign the
identier with the result of this function. That is we do
> X := f(Y);
where Y is a list of arguments possibly including the current value of X.
At times however using re-assignment to change the value associated with an identier
can be both un-natural and inecient. Take the problem of computing some reduced form
of a matrix. We could write a function that looked something like this,
120 THE MAGMA LANGUAGE Part I
reduce :=
function( m )
local lm;
...
lm := m;
while not reduced do
...
lm := some_reduction(m);
...
end while;
...
end function;
Note that the local lm is necessary since we cannot assign to the functions formal argument
m since it stands for a value (and values cannot be assigned to). Note also that the function
is inecient in its space usage since at any given point in the program there are at least
two dierent copies of the matrix (if the function was recursive then there would be more
than two copies!).
Finally the function is also un-natural. It is perhaps more natural to think of writing a
program that takes a given matrix and changes that matrix into its reduced form (i.e., the
original matrix is lost). To accommodate for this style of programming, Magma includes
a mechanism, the procedure expression with its reference arguments, for changing an
association of an identier and a value in place.
Before examining procedure expressions further, it is useful to look at a simple example
of a procedure expression. Say we type,
> a := 5; b := 6;
giving the context [ (a,5), (b,6) ]. Now saw we type the following,
> p := procedure( x, ~y ) y := x; end procedure;
This gives us a context that looks like [ (a,5), (b,6), (p, PROC(x,y : y := x;))
], using a notation analogous to the FUNC notation.
Say we now type the following statement,
> p(a, ~b);
This is known as a call of the procedure p (strictly it should be known as a call to the
procedure value associated with the identier p, since like functions, procedures in Magma
are rst class values!). Its eect is to change the current context to [ (a,5), (b,5),
(p, PROC(a,b : b := a;)) ]. a and x are called actual and formal value arguments
respectively since they are not prexed by a , while b and y are called actual and formal
reference arguments respectively because they are prexed by a .
This example illustrates the dening attribute of procedures, namely that rather than
returning a value, a procedure changes the context in which it is called. In this case the
value of b was changed by the call to p. Observe however that only b was changed by the
Ch. 5 MAGMA SEMANTICS 121
call to p as only b in the call, and its corresponding formal argument y in the denition,
are reference arguments (i.e., prexed with a ). A procedure may therefore only change
that part of the context associated with its reference arguments! All other parts of the
context are left unchanged. In this case a and p were left unchanged!
Note that apart from reference arguments (and the corresponding fact that that pro-
cedures do not return values), procedures are exactly like functions. In particular:
a) procedures are rst class values that can be assigned to identiers, passed as arguments,
returned from functions, etc.
b) procedure expressions are evaluated in the same way that function expressions are.
c) procedure value arguments (both formal and actual) behave exactly like function argu-
ments (both formal and actual). Thus procedure value arguments obey the standard
substitution semantics.
d) procedures employ the same notion of scope as functions.
e) procedure calling behaves like function application.
f) procedures may be declared forward to allow for (mutual) recursion.
g) a procedure may be assigned to an identier in the initial context.
The remainder of this section will thus restrict itself to looking at reference arguments, the
point of dierence between procedures and functions.
5.8 Reference Arguments
If we look at a context it consists of a set of pairs, each pair being a name (an identier)
and a value (that is said to be assigned to that identier).
When a function is applied actual arguments are substituted for formal arguments,
and the body of the function is evaluated. The process of evaluating an actual argument
yields a value and any associated names are ignored. Magmas evaluation semantics treats
identiers as indexes into the context when Magma wants the value of say x it searches
through the context looking for a pair whose name component is x. The corresponding
value component is then used as the value of x and the name part is simply ignored
thereafter.
When we call a procedure with a reference argument, however, the name components
of the context become important. When, for example we pass x as an actual reference
argument to a formal reference argument y in some procedure, Magma remembers the
name x. Then if y is changed (e.g., by assignment) in the called procedure, Magma,
knowing the name x, nds the appropriate pair in the calling context and updates it by
changing its corresponding value component. To see how this works take the example in
the previous section. It was,
> a := 5; b := 6;
> p := procedure( x, ~y ) y := x; end procedure;
122 THE MAGMA LANGUAGE Part I
> p(a, ~b);
In the call Magma remembers the name b. Then when y is assigned to in the body of p,
Magma knows that y is really b in the calling context, and hence changes b in the calling
context appropriately. This example shows that an alternate way of thinking of reference
arguments is as synonyms for the same part of (or pair in) the calling context.
5.9 Dynamic Typing
Magma is a dynamically typed language. In practice this means that:
(a) there is no need to declare the type of identiers (this is especially important for iden-
tiers assigned function values!).
(b)type violations are only checked for when the code containing the type violation is
actually executed.
To make these ideas clearer consider the following two functions,
> f := func< a, b | a+b >;
> g := func< a, b | a+true >;
First note that there are no declarations of the types of any of the identiers.
Second consider the use of + in the denition of function f. Which addition function
is meant by the + in a+b? Integer addition? Matrix addition? Group addition? ... Or
in other words what is the type of the identier + in function f? Is it integer addition,
matrix addition, etc.? The answer to this question is that + here denotes all possible
addition function values (+ is said to denote a family of function values), and Magma will
automatically chose the appropriate function value to apply when it knows the type of a
and b.
Say we now type,
> f(1,2);
Magma now knows that a and b in f are both integers and thus + in f should be taken
to mean the integer addition function. Hence it will produce the desired answer of 3.
Finally consider the denition of the function g. It is clear X+true for all X is a type
error, so it might be expected that Magma would raise an error as soon as the denition of
g is typed in. Magma does not however raise an error at this point. Rather it is only when
g is applied and the line return a + true is actually executed that an error is raised.
In general the exact point at which type checking is done is not important. Sometimes
however it is. Say we had typed the following denition for g,
> g := function(a,b)
> if false then
> return a+true;
> else
> return a+b;
> end if;
Ch. 5 MAGMA SEMANTICS 123
> end function;
Now because the if false condition will never be true, the line return a+true will never
be executed, and hence the type violation of adding a to true will never be raised!
One closing point: it should be clear now that where it was previously stated that
the initial context contains assignments of all the built-in Magma function values to the
appropriate identiers, in fact the initial context contains assignments of all the built-in
Magma function families to the appropriate identiers.
5.10 Traps for Young Players
This section describes the two most common sources of confusion encountered when using
Magmas evaluation strategy.
5.10.1 Trap 1
We boot Magma. It begins with an initial context something like [ ..., (+,A),
(-,S), ... ] where A is the (function) value that is the addition function, and S is
the (function) value that is the subtraction function.
Now say we type,
> + := -;
> 1 + 2;
Magma will respond with the answer -1.
To see why this is so consider the eect of each line on the current context. After the
rst line the current context will be [ ..., (+,S), (-,S), ... ], where S is as
before. The identier + has been re-assigned. Its new value is the value of the identier -
in the current context, and the value of - is the (function) value that is the subtraction
function. Hence in the second line when Magma replaces the identier + with its value in
the current context, the value that is substituted is therefore S, the subtraction function!
5.10.2 Trap 2
Say we type,
> f := func< n | n + 1 >;
> g := func< m | m + f(m) >;
After the rst line the current context is [ (f,FUNC( n : n+1)) ]. After the sec-
ond line the current context is [ (f,FUNC( n : n+1)), (g,FUNC(m : m + FUNC(n :
n+1)(m))) ].
If we now type,
> g(6);
Magma will respond with the answer 13.
124 THE MAGMA LANGUAGE Part I
Now say we decide that our denition of f is wrong. So we now type in a new denition
for f as follows,
> f := func< n | n + 2 >;
If we again type,
> g(6);
Magma will again reply with the answer 13!
To see why this is so consider how the current context changes. After typing in the
initial denitions of f and g the current context is [ (f, FUNC(n : n+1)), (g, FUNC(m
: m + FUNC(n : n+1)(m))) ]. After typing in the second denition of f the current
context is [ (f, FUNC(n : n+2)), (g, FUNC(m : m + FUNC(n : n+1)(m)))]. Re-
member that changing the value of one identier, in this case f, does not change the value
of any other identiers, in this case g! In order to change the value of g to reect the new
value of f, g would have to be re-assigned.
Ch. 5 MAGMA SEMANTICS 125
5.11 Appendix A: Precedence
The table below denes the relative precedence of operators in Magma. The second
column indicates whether the operator is left-, right-, or non-associative.
left
( left
[ left
assigned right
~ non
# non
&* &+ &and &cat &join &meet &or non-associative
$ $$ non
. left
@ @@ left
! !! right
^ right
unary- right
cat left
* / div mod left
+ - left
meet left
sdiff left
diff left
join left
adj in notadj notin notsubset subset non
cmpeq cmpne eq ge gt le lt ne left
not right
and left
or xor left
^^ non
? else select right
-> left
= left
:= is where left
126 THE MAGMA LANGUAGE Part I
5.12 Appendix B: Reserved Words
The list below contains all reserved words in the Magma language; these cannot be used
as identier names.
end le requirerange
adj eq load restore
and error local return
assert eval lt save
assigned exists meet sdi
break exit mod select
by false ne subset
case for not then
cat forall notadj time
catch forward notin to
clear fprintf notsubset true
cmpeq freeze or try
cmpne function print until
continue ge printf vprint
declare gt procedure vprintf
default if quit vtime
delete iload random when
di import read where
div in readi while
do intrinsic repeat xor
elif is require
else join requirege
6 THE MAGMA PROFILER
6.1 Introduction . . . . . . . . 129
6.2 Proler Basics . . . . . . . 129
SetProfile(b) 129
ProfileReset() 129
ProfileGraph() 130
6.3 Exploring the Call Graph . . 131
6.3.1 Internal Reports . . . . . . . . 131
ProfilePrintByTotalCount(G) 132
ProfilePrintByTotalTime(G) 132
ProfilePrintChildrenByCount(G, n) 132
ProfilePrintChildrenByTime(G, n) 132
6.3.2 HTML Reports . . . . . . . . . 133
ProfileHTMLOutput(G, prefix) 133
6.4 Recursion and the Proler . . 133
Chapter 6
THE MAGMA PROFILER
6.1 Introduction
One of the most important aspects of the development cycle is optimization. It is often the
case that during the implementation of an algorithm, a programmer makes erroneous as-
sumptions about its run-time behavior. These errors can lead to performance which diers
in surprising ways from the expected output. The unfortunate tendency of programmers
to optimize code before establishing run-time bottlenecks tends to exacerbate the problem.
Experienced programmers will thus often be heard repeating the famous mantra Pre-
mature optimization is the root of all evil, coined by Sir Charles A. R. Hoare, the inventor
of the Quick sort algorithm. Instead of optimizing during the initial implementation, it is
generally better to perform an analysis of the run-time behaviour of the complete program,
to determine what are the actual bottlenecks. In order to assist in this task, Magma pro-
vides a proler, which gives the programmer a detailed breakdown of the time spent in a
program. In this chapter, we provide an overview of how to use the proler.
6.2 Proler Basics
The Magma proler records timing information for each function, procedure, map, and
intrinsic call made by your program. When the proler is switched on, upon the entry and
exit to each such call the current system clock time is recorded. This information is then
stored in a call graph, which can be viewed in various ways.
SetProfile(b)
Turns proling on (if b is true) or o (if b is false). Proling information is stored
cumulatively, which means that in the middle of a proling run, the proler can
be switched o during sections for which proling information is not wanted. At
startup, the proler is o. Turning the proler on will slow down the execution of
your program slightly.
ProfileReset()
Clear out all information currently recorded by the proler. It is generally a good
idea to do this after the call graph has been obtained, so that future proling runs
in the same Magma session begin with a clean slate.
130 THE MAGMA LANGUAGE Part I
ProfileGraph()
Get the call graph based upon the information recorded up to this point by the
proler. This function will return an error if the proler has not yet been turned
on.
The call graph is a directed graph, with the nodes representing the functions
that were called during the programs execution. There is an edge in the call graph
from a function x to a function y if y was called during the execution of x. Thus,
recursive calls will result in cycles in the call graph.
Each node in the graph has an associated label, which is a record with the
following elds:
(i) Name: the name of the function
(ii) Time: the total time spent in the function
(iii) Count: the number of times the function was called
Each edge x, y) in the graph also has an associated label, which is a record with
the following elds:
(i) Time: the total time spent in function y when it was called from function
x
(ii) Count: the total number of times function y was called by function x
Example H6E1
We illustrate the basic use of the proler in the following example. The code we test is a simple
implementation of the Fibonacci sequence; this can be replaced by any Magma code that needs
to be proled.
> function fibonacci(n)
> if n eq 1 or n eq 2 then
> return 1;
> else
> return fibonacci(n - 1) + fibonacci(n - 2);
> end if;
> end function;
>
> SetProfile(true);
> time assert fibonacci(27) eq Fibonacci(27);
Time: 10.940
> SetProfile(false);
> G := ProfileGraph();
> G;
Digraph
Vertex Neighbours
1 2 3 6 7 ;
2 2 3 4 5 ;
3 ;
4 ;
Ch. 6 THE MAGMA PROFILER 131
5 ;
6 ;
7 ;
> V := Vertices(G);
> Label(V!1);
rec<recformat<Name: Strings(), Time: RealField(), Count: IntegerRing()> |
Name := <main>,
Time := 10.93999999999999950262,
Count := 1
>
> Label(V!2);
rec<recformat<Name: Strings(), Time: RealField(), Count: IntegerRing()> |
Name := fibonacci,
Time := 10.93999999999999950262,
Count := 392835
>
> E := Edges(G);
> Label(E![1,2]);
rec<recformat<Time: RealField(), Count: IntegerRing()> |
Time := 10.93999999999999950262,
Count := 1
>
6.3 Exploring the Call Graph
6.3.1 Internal Reports
The above example demonstrates that while the call graph contains some useful informa-
tion, it does not aord a particularly usable interface. The Magma proler contains some
prole report generators which can be used to study the call graph in a more intuitive way.
The reports are all tabular, and have a similar set of columns:
(i) Index: The numeric identier for the function in the vertex list of the call graph.
(ii) Name: The name of the function. The function name will be followed by an
asterisk if a recursive call was made through it.
(iii) Time: The time spent in the function; depending on the report, the meaning
might vary slightly.
(iv) Count: The number of times the function was called; depending on the report,
the meaning might vary slightly.
132 THE MAGMA LANGUAGE Part I
ProfilePrintByTotalCount(G)
Percentage BoolElt Default : false
Max RngIntElt Default : 1
Print the list of functions in the call graph, sorted in descending order by the total
number of times they were called. The Time and Count elds of the report give the
total time and total number of times the function was called. If Percentage is true,
then the Time and Count elds represent their values as percentages of the total
value. If Max is non-negative, then the report only displays the rst Max entries.
ProfilePrintByTotalTime(G)
Percentage BoolElt Default : false
Max RngIntElt Default : 1
Print the list of functions in the call graph, sorted in descending order by the total
time spent in them. Apart from the sort order, this functions behaviour is identical
to that of ProfilePrintByTotalCount.
ProfilePrintChildrenByCount(G, n)
Percentage BoolElt Default : false
Max RngIntElt Default : 1
Given a vertex n in the call graph G, print the list of functions called by the function
n, sorted in descending order by the number of times they were called by n. The
Time and Count elds of the report give the time spent during calls by the function
n and the number of times the function was called by the function n. If Percentage
is true, then the Time and Count elds represent their values as percentages of the
total value. If Max is non-negative, then the report only displays the rst Max entries.
ProfilePrintChildrenByTime(G, n)
Percentage BoolElt Default : false
Max RngIntElt Default : 1
Given a vertex n in the call graph G, print the list of functions in the called by
the function n, sorted in descending order by the time spent during calls by the
function n. Apart from the sort order, this functions behaviour is identical to that
of ProfilePrintChildrenByCount.
Example H6E2
Continuing with the previous example, we examine the call graph using prole reports.
> ProfilePrintByTotalTime(G);
Index Name Time Count
1 <main> 10.940 1
2 fibonacci 10.940 392835
3 eq(<RngIntElt> x, <RngIntElt> y) -> BoolElt 1.210 710646
Ch. 6 THE MAGMA PROFILER 133
4 -(<RngIntElt> x, <RngIntElt> y) -> RngIntElt 0.630 392834
5 +(<RngIntElt> x, <RngIntElt> y) -> RngIntElt 0.250 196417
6 Fibonacci(<RngIntElt> n) -> RngIntElt 0.000 1
7 SetProfile(<BoolElt> v) 0.000 1
> ProfilePrintChildrenByTime(G, 2);
Function: fibonacci
Function Time: 10.940
Function Count: 392835
Index Name Time Count
2 fibonacci (*) 182.430 392834
3 eq(<RngIntElt> x, <RngIntElt> y) -> BoolElt 1.210 710645
4 -(<RngIntElt> x, <RngIntElt> y) -> RngIntElt 0.630 392834
5 +(<RngIntElt> x, <RngIntElt> y) -> RngIntElt 0.250 196417
* A recursive call is made through this child
6.3.2 HTML Reports
While the internal reports are useful for casual inspection of a prole run, for detailed
examination a text-based interface has serious limitations. Magmas proler also supports
the generation of HTML reports of the prole run. The HTML report can be loaded
up in any web browser. If Javascript is enabled, then the tables in the report can be
dynamically sorted by any eld, by clicking on the column heading you wish to perform
a sort with. Clicking the column heading multiple times will alternate between ascending
and descending sorts.
ProfileHTMLOutput(G, prefix)
Given a call graph G, an HTML report is generated using the le prex prefix.
The index le of the report will be prefix.html, and exactly n additional les will
be generated with the given lename prefix, where n is the number of functions in
the call graph.
6.4 Recursion and the Proler
Recursive calls can cause some diculty with proler results. The proler takes care to
ensure that double-counting does not occur, but this can lead to unintuitive results, as the
following example shows.
134 THE MAGMA LANGUAGE Part I
Example H6E3
In the following example, recursive is a recursive function which simply stays in a loop for half
a second, and then recurses if not in the base case. Thus, the total running time should be
approximately (n + 1)/2 seconds, where n is the parameter to the function.
> procedure delay(s)
> t := Cputime();
> repeat
> _ := 1+1;
> until Cputime(t) gt s;
> end procedure;
>
> procedure recursive(n)
> if n ne 0 then
> recursive(n - 1);
> end if;
>
> delay(0.5);
> end procedure;
>
> SetProfile(true);
> recursive(1);
> SetProfile(false);
> G := ProfileGraph();
Printing the prole results by total time yield no surprises:
> ProfilePrintByTotalTime(G);
Index Name Time Count
1 <main> 1.020 1
2 recursive 1.020 2
5 delay 1.020 2
8 Cputime(<FldReElt> T) -> FldReElt 0.130 14880
7 +(<RngIntElt> x, <RngIntElt> y) -> RngIntElt 0.020 14880
9 gt(<FldReElt> x, <FldReElt> y) -> BoolElt 0.020 14880
3 ne(<RngIntElt> x, <RngIntElt> y) -> BoolElt 0.000 2
4 -(<RngIntElt> x, <RngIntElt> y) -> RngIntElt 0.000 1
6 Cputime() -> FldReElt 0.000 2
10 SetProfile(<BoolElt> v) 0.000 1
However, printing the children of recursive, and displaying the results in percentages, does yield
a surprise:
> ProfilePrintChildrenByTime(G, 2 : Percentage);
Function: recursive
Function Time: 1.020
Function Count: 2
Index Name Time Count
5 delay 100.00 33.33
2 recursive (*) 50.00 16.67
Ch. 6 THE MAGMA PROFILER 135
3 ne(<RngIntElt> x, <RngIntElt> y) -> BoolElt 0.00 33.33
4 -(<RngIntElt> x, <RngIntElt> y) -> RngIntElt 0.00 16.67
* A recursive call is made through this child
At rst glance, this doesnt appear to make sense, as the sum of the time column is 150%! The
reason for this behavior is because some time is double counted: the total time for the rst call
to recursive includes the time for the recursive call, which is also counted separately. In more
detail:
> V := Vertices(G);
> E := Edges(G);
> Label(V!1)Name;
<main>
> Label(V!2)Name;
recursive
> Label(E![1,2])Time;
1.019999999999999795718
> Label(E![2,2])Time;
0.51000000000000000888
> Label(V!2)Time;
1.019999999999999795718
As can seen in the above, the total time for recursive is approximately one second, as expected.
The double-counting of the recursive call can be seen in the values of Time for the edges [1,2]
and [2,2].
7 DEBUGGING MAGMA CODE
7.1 Introduction . . . . . . . . 139
SetDebugOnError(f) 139
7.2 Using the Debugger . . . . . 139
Chapter 7
DEBUGGING MAGMA CODE
7.1 Introduction
In ordered to facilitate the debugging of complex pieces of Magma code, Magma includes
a debugger. This debugger is very much a prototype, and can cause Magma to crash.
SetDebugOnError(f)
If f is true, then upon an error Magma will break into the debugger. The usage of
the debugger is described in the next section.
7.2 Using the Debugger
When use of the debugger is enabled and an error occurs, Magma will break into the
command-line debugger. The syntax of the debugger is modelled on the GNU GDB de-
bugger for C programs, and supports the following commands (acceptable abbreviations
for the commands are given in parentheses):
backtrace (bt) Print out the stack of function and procedure calls, from
the top level to the point at which the error occurred. Each line i this trace gives a
single frame, which consists of the function/procedure that was called, as well as all
local variable denitions for that function. Each frame is numbered so that it can be
referenced in other debugger commands.
frame (f) n Change the current frame to the frame numbered n (the
list of frames can be obtained using the backtrace command). The current frame is
used by other debugger commands, such as print, to determine the context within
which expressions should be evaluated. The default current frame is the top-most
frame.
list (l) [n] Print a source code listing for the current context (the
context is set by the frame command). If n is specied, then the list command will
print n lines of source code; the default value is 10.
print (p) expr Evaluate the expression expr in the current context (the
context is set by the frame command). The print command has semantics identical
to evaluating the expression eval "expr" at the current point in the program.
help (h) Print brief help on usage.
quit (q) Quit the debugger and return to the Magma session.
140 THE MAGMA LANGUAGE Part I
Example H7E1
We now give a sample session in the debugger. In the following, we have written a function
to evaluate f(n) =
n
i=1
1/n, but have in our implementation we have accidentally included the
evaluation of the term at n = 0.
> function f(n)
> if n ge 0 then
> return 1.0 / n + f(n - 1);
> else
> return 1.0 / n;
> end if;
> end function;
>
> SetDebugOnError(true);
> f(3);
f(
n: 3
)
f(
n: 2
)
f(
n: 1
)
f(
n: 0
)
>> return 1.0 / n + f(n - 1);
^
Runtime error in /: Division by zero
debug> p n
0
debug> p 1.0 / (n + 1)
1.00000000000000000000000000000
debug> bt
#0 *f(
n: 0
) at <main>:1
#1 f(
n: 1
) at <main>:1
#2 f(
n: 2
) at <main>:1
#3 f(
n: 3
) at <main>:1
debug> f 1
Ch. 7 DEBUGGING MAGMA CODE 141
debug> p n
1
debug> p 1.0 / n
1.00000000000000000000000000000
PART II
SETS, SEQUENCES, AND MAPPINGS
8 INTRODUCTION TO AGGREGATES 145
9 SETS 155
10 SEQUENCES 183
11 TUPLES AND CARTESIAN PRODUCTS 205
12 LISTS 211
13 COPRODUCTS 217
14 RECORDS 223
15 MAPPINGS 229
8 INTRODUCTION TO AGGREGATES
8.1 Introduction . . . . . . . . 147
8.2 Restrictions on Sets and
Sequences . . . . . . . . . 147
8.2.1 Universe of a Set or Sequence . . . 148
8.2.2 Modifying the Universe of a Set or Se-
quence . . . . . . . . . . . . . 149
8.2.3 Parents of Sets and Sequences . . . 151
8.3 Nested Aggregates . . . . . 152
8.3.1 Multi-indexing . . . . . . . . . 152
Chapter 8
INTRODUCTION TO AGGREGATES
8.1 Introduction
This part of the Handbook comprises four chapters on aggregate objects in Magma as
well as a chapter on maps.
Sets, sequences, tuples and lists are the four main types of aggregates, and each has its
own specic purpose. Sets are used to collect objects that are elements of some common
structure, and the most important operation is to test element membership. Sequences
also contain objects of a common structure, but here the emphasis is on the ordering of
the objects, and the most important operation is that of accessing (or modifying) elements
at given positions. Sets will contain at most one copy of any element, whereas sequences
may contain arbitrarily many copies of the same object. Enumerated sets and sequences
are of arbitrary but nite length and will store all elements explicitly (with the exception
of arithmetic progressions), while formal sets and sequences may be innite, and use a
Boolean function to test element membership. Indexed sets are a hybrid form of sets al-
lowing indexing like sequences. Elements of Cartesian products of structures in Magma
will be called tuples; they are of xed length, and each coecient must be in the corre-
sponding structure of the dening Cartesian product. Lists are arbitrary nite ordered
collections of objects of any type, and are mainly provided to the user to store assorted
data to which access is not critical.
8.2 Restrictions on Sets and Sequences
Here we will explain the subtleties behind the mechanism dealing with sets and sequences
and their universes and parents. Although the same principles apply to their formal
counterparts, we will only talk about enumerated sets and sequences here, for two reasons:
the enumerated versions are much more useful and common, and the very restricted number
of operations on formal sets/sequences make issues of universe and overstructure of less
importance for them.
In principle, every object e in Magma has some parent structure S such that e S;
this structure can be used for type checking (are we allowed to apply function f to e?),
algorithm look-up etc. To avoid storing the structure with every element of a set or
sequence and having to look up the structure of every element separately, only elements
of a common structure are allowed in sets or sequences, and that common parent will only
be stored once.
148 SETS, SEQUENCES, AND MAPPINGS Part II
8.2.1 Universe of a Set or Sequence
This common structure is called the universe of the set or sequence. In the general con-
structors it may be specied up front to make clear what the universe for the set or sequence
will be; the dierence between the sets i and s in
> i := IntegerRing() | 1, 2, 3 ;
> s := RationalField() | 1, 2, 3 ;
lies entirely in their universes. The specication of the universe may be omitted if there is
an obvious common overstructure for the elements. Thus the following provides a shorter
way to create the set containing 1, 2, 3 and having the ring of integers as universe:
> i := 1, 2, 3 ;
Only empty sets and sequences that have been obtained directly from the constructions
> S := ;
> T := [ ];
do not have their universe dened we will call them the null set or sequence. (There
are two other ways in which empty sets and sequences arise: it is possible to create empty
sequences with a prescribed universe, using
> S := U | ;
> T := [ U | ];
and it may happen that a non-empty set/sequence becomes empty in the course of a
computation. In both cases these empty objects have their universe dened and will not
be null).
Usually (but not always: the exception will be explained below) the universe of a set
or sequence is the parent for all its elements; thus the ring of integers is the parent of 2
in the set i = 1, 2, 3, rather than that set itself. The universe is not static, and it is not
necessarily the same structure as the parent of the elements before they were put in the
set or sequence. To illustrate this point, suppose that we try to create a set containing
integers and rational numbers, say T = 1, 2, 1/3; then we run into trouble with the rule
that the universe must be common for all elements in T; the way this problem is solved
in Magma is by automatic coercion: the obvious universe for T is the eld of rational
numbers of which 1/3 is already an element and into which any integer can be coerced in
an obvious way. Hence the assignment
> T := 1, 2, 1/3
will result in a set with universe the eld of rationals (which is also present when Magma
is started up). Consequently, when we take the element 1 of the set T, it will have the
rational eld as its parent rather than the integer ring! It will now be clear that
> s := 1/1, 2, 3 ;
is a shorter way to specify the set of rational numbers 1,2, 3 than the way we saw before, but
in general it is preferable to declare the universe beforehand using the U | notation.
Ch. 8 INTRODUCTION TO AGGREGATES 149
Of course
> T := Integers() | 1, 2, 1/3
would result in an error because 1/3 cannot be coerced into the ring of integers.
So, usually not every element of a given structure can be coerced into another structure,
and even if it can, it will not always be done automatically. The possible (automatic)
coercions are listed in the descriptions of the various Magma modules. For instance, the
table in the introductory chapter on rings shows that integers can be coerced automatically
into the rational eld.
In general, every Magma structure is valid as a universe. This includes enumerated
sets and sequences themselves, that is, it is possible to dene a set or sequence whose
elements are conned to be elements of a given set or sequence. So, for example,
> S := [ [ 1..10 ] | x^2+x+1 : x in -3 .. 2 by 1 ];
produces the sequence [7, 3, 1, 1, 3, 7] of values of the polynomial x
2
+x +1 for x Z with
3 x 2. However, an entry of S will in fact have the ring of integers as its parent
(and not the sequence [1..10]), because the eect of the above assignment is that the values
after the [ are calculated and coerced into the universe, which is [1..10]; but coercing an
element into a sequence or set means that it will in fact be coerced into the universe of
that sequence/set, in this case the integers. So the main dierence between the above
assignment and
> T := [ Integers() | x^2+x+1 : x in { -3 .. 2 by 1} ];
is that in the rst case it is checked that the resulting values y satisfy 1 y 10, and an
error would occur if this is violated:
> S := [ [ 1..10 ] | x^2+x+1 : x in { -3 .. 3 by 1} ];
leads to a run-time error.
In general then, the parent of an element of a set or sequence will be the universe of the
set or sequence, unless that universe is itself a set or sequence, in which case the parent
will be the universe of this universe, and so on, until a non-set or sequence is encountered.
8.2.2 Modifying the Universe of a Set or Sequence
Once a (non-null) set or sequence S has been created, the universe has been dened. If one
attempts to modify S (that is, to add elements, change entries etc. using a procedure that
will not reassign the result to a new set or sequence), the universe will not be changed,
and the modication will only be successful if the new element can be coerced into the
current universe. Thus,
> Z := Integers();
> T := [ Z | 1, 2, 3/3 ];
> T[2] := 3/4;
will result in an error, because 3/4 cannot be coerced into Z.
150 SETS, SEQUENCES, AND MAPPINGS Part II
The universe of a set or sequence S can be explicitly modied by creating a parent for
S with the desired universe and using the ! operator for the coercion; as we will see in
the next subsection, such a parent can be created using the PowerSet and PowerSequence
commands. Thus, for example, the set 1, 2 can be made into a sequence of rationals as
follows:
> I := 1, 2 ;
> P := PowerSet( RationalField() );
> J := P ! I;
The coercion will be successful if every element of the sequence can be coerced into the
new universe, and it is not necessary that the old universe could be coerced completely
into the new one: the set 3/3 of rationals can be coerced into PowerSet(Integers()).
As a consequence, the empty set (or sequence) with any universe can be coerced into the
power set (power sequence) of any other universe.
Binary functions on sets or sequences (like join or cat) can only applied to sets and
sequences that are compatible: the operation on S with universe A and T with universe B
can only be performed if a common universe C can be found such that the elements of S
and T are all elements of C. The compatibility conditions are dependent on the particular
Magma module to which A and B belong (we refer to the corresponding chapters of this
manual for further information) and do also apply to elements of a A and b B
that is, the compatibility conditions for S and T are the same as the ones that determine
whether binary operations on a A and b B are allowed. For example, we are able to
join a set of integers and a set of rationals:
> T := 1, 2 join 1/3 ;
for the same reason that we can do
> c := 1 + 1/3;
(automatic coercion for rings). The resulting set T will have the rationals as universe.
The basic rules for compatibility of two sets or sequences are then:
(1) every set/sequence is compatible with the null set/sequence (which has no universe
dened (see above));
(2) two sets/sequences with the same universe are compatible;
(3) a set/sequence S with universe A is compatible with set/sequence T with universe B
if the elements of A can be automatically coerced into B, or vice versa;
(4) more generally, a set/sequence S with universe A is also compatible with set/sequence
T with universe B if Magma can automatically nd an over-structure for the parents
A and B (see below);
(5) nested sets and sequences are compatible only when they are of the same depth and
type (that is, sets and sequences appear in exactly the same recursive order in both)
and the universes are compatible.
The possibility of nding an overstructure C for the universe A and B of sets or sequences
S and T (such that A C B), is again module dependent. We refer the reader for
Ch. 8 INTRODUCTION TO AGGREGATES 151
details to the Introductions of Parts IIIVI, and we give some examples here; the next
subsection contains the rules for parents of sets and sequences.
8.2.3 Parents of Sets and Sequences
The universe of a set or sequence S is the common parent for all its elements; but S itself
is a Magma object as well, so it should have a parent too.
The parent of a set is a power set: the set of all subsets of the universe of S. It
can be created using the PowerSet function. Similarly, PowerSequence(A) creates the
parent structure for a sequence of elements from the structure A that is, the elements of
PowerSequence(A) are all sequences of elements of A.
The rules for nding a common overstructure for structures A and B, where either A or
B is a set/sequence or the parent of a set/sequence, are as follows. (If neither A nor B is
a set, sequence, or its parent we refer to the Part of this manual describing the operations
on A and B.)
(1) The overstructure of A and B is the same as that of B and A.
(2) If A is the null set or sequence (empty, and no universe specied) the overstructure of
A and B is B.
(3) If A is a set or sequence with universe U, the overstructure of A and B is the over-
structure of U and B; in particular, the overstructure of A and A will be the universe
U of A.
(4) If A is the parent of a set (a power set), then A and B can only have a common
overstructure if B is also the parent of a set, in which case the overstructure is the
power set of the overstructure of the universes U and V of A and B respectively.
Likewise for sequences instead of sets.
We give two examples to illustrate rules (3) and (4). It is possible to create a set with a
set as its universe:
> S := 1..100 | x^3 : x in [ 0..3 ] ;
If we wish to intersect this set with some set of integers, say the formal set of odd integers
> T := ! x : x in Integers() | IsOdd(x) !;
> W := S meet T;
then we can only do that if we can nd a universe for W, which must be the common
overstructure of the universe U = 1, 2, . . . , 100 of S and the universe ring of integers of
T. By rule (3) above, this overstructure of U = 1, 2, . . . , 100 will be the overstructure
of the universe of U and the ring of integers; but the universe of U is the ring of integers
(because it is the default for the set 1, 2, . . . , 100), and hence the overstructure we are
looking for (and the universe for W) will be the ring of integers.
For the second example we look at sequences of sequences:
> a := [ [ 1 ], [ 1, 2, 3 ] ];
152 SETS, SEQUENCES, AND MAPPINGS Part II
> b := [ [ 2/3 ] ];
so a is a sequence of sequences of integers, and b is a sequence of sequences of rationals. If
we wish to concatenate a and b,
> c := a cat b;
we will only succeed if we nd a universe for c. This universe must be the common
overstructure of the universes of a and b, which are the power sequence of the integers
and the power sequence of the rationals respectively. By rule (4), the overstructure of
these two power sequences is the power sequence of the common overstructure of the
rationals and the integers, which is the rationals themselves. Hence c will be a sequence
of sequences of rationals, and the elements of a will have to be coerced.
8.3 Nested Aggregates
Enumerated sets and sequences can be arbitrarily nested (that is, one may create sets of
sets, as well as sequences of sets etc.); tuples can also be nested and may be freely mixed
with sets and sequences (as long as the proper Cartesian product parent can be created).
Lists can be nested, and one may create lists of sets or sequences or tuples.
8.3.1 Multi-indexing
Since sequences (and lists) can be nested, assignment functions and mutation operators
allow you to use multi-indexing, that is, one can use a multi-index i
1
, i
2
, . . . , i
r
rather than
a single i to reach r levels deep. Thus, for example, if S = [ [1, 2], [2, 3] ], instead of
> S[2][2] := 4;
one may use the multi-index 2, 2 to obtain the same eect of changing the 3 into a 4:
> S[2,2] := 4;
All i
j
in the multi-index i
1
, i
2
, . . . , i
r
have to be greater than 0, and an error will also be
agged if any i
j
indexes beyond the length at level j, that is, if i
j
> #S[i
1
, . . . , i
j1
],
(which means i
1
> #S for j = 1). There is one exception: the last index i
r
is allowed to
index beyond the current length of the sequence at level r if the multi-index is used on the
left-hand side of an assignment, in which case any intermediate terms will be undened.
This generalizes the possibility to assign beyond the length of a at sequence. In the
above example the following assignments are allowed:
> S[2,5] := 7;
(and the result will be S = [ [1, 2], [2, 3, undef, undef, 7] ])
> S[4] := [7];
(and the result will be S = [ [1, 2], [2, 3], undef, [7] ]). But the following results in an
error:
> S[4,1] := 7;
Finally we point out that multi-indexing should not be confused with the use of sequences as
Ch. 8 INTRODUCTION TO AGGREGATES 153
indexes to create subsequences. For example, to create a subsequence of S = [5, 13, 17, 29]
consisting of the second and third terms, one may use
> S := [ 5, 13, 17, 29 ];
> T := S[ [2, 3] ];
To obtain the second term of this subsequence one could have done:
> x := S[ [2, 3] ][2];
(so x now has the value S[3] = 17), but it would have been more ecient to index the
indexing sequence, since it is rather expensive to build the subsequence [ S[2], S[3] ] rst,
so:
> x := S[ [2, 3][2] ];
has the same eect but is better (of course x := S[3] would be even better in this simple
example.) To add to the confusion, it is possible to mix the above constructions for
indexing, since one can use lists of sequences and indices for indexing; continuing our
example, there is now a third way to do the same as above, using an indexing list that
rst takes out the subsequence consisting of the second and third terms and then extracts
the second term of that:
> x := S[ [2, 3], 2 ];
Similarly, the construction
> X := S[ [2, 3], [2] ];
pulls out the subsequence consisting of the second term of the subsequence of terms two
and three of S, in other words, this assigns the sequence consisting of the element 17, not
just the element itself!
9 SETS
9.1 Introduction . . . . . . . . 157
9.1.1 Enumerated Sets . . . . . . . . 157
9.1.2 Formal Sets . . . . . . . . . . . 157
9.1.3 Indexed Sets . . . . . . . . . . 157
9.1.4 Multisets . . . . . . . . . . . . 157
9.1.5 Compatibility . . . . . . . . . . 158
9.1.6 Notation . . . . . . . . . . . . 158
9.2 Creating Sets . . . . . . . . 158
9.2.1 The Formal Set Constructor . . . 158
{! x in F | P(x) !} 158
9.2.2 The Enumerated Set Constructor . 159
{ } 159
{ U | } 159
{ e
1
, e
2
, ..., e
n
} 159
{ U | e
1
, e
2
, ..., e
n
} 159
{ e(x) : x in E | P(x) } 160
{ U | e(x) : x in E | P(x) } 160
{ e(x
1
,...,x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
) } 160
{ U | e(x
1
,...,x
k
) : x
1
in E
1
, ...,
x
k
in E
k
| P(x
1
, ..., x
k
) } 160
9.2.3 The Indexed Set Constructor . . . 161
{@ @} 161
{@ U | @} 161
{@ e
1
, e
2
, ..., e
n
@} 161
{@ U | e
1
, e
2
, ..., e
m
@} 161
{@ e(x) : x in E | P(x) @} 161
{@ U | e(x) : x in E | P(x) @} 161
{@ e(x
1
,...,x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
) @} 162
{@ U | e(x
1
,...,x
k
) : x
1
in E
1
, ...,
x
k
in E
k
| P(x
1
, ..., x
k
)@} 162
9.2.4 The Multiset Constructor . . . . 162
{* *} 162
{* U | *} 162
{* e
1
, e
2
, ..., e
n
*} 163
{* U | e
1
, e
2
, ..., e
m
*} 163
{* e(x) : x in E | P(x) *} 163
{* U | e(x) : x in E | P(x) *} 163
{* e(x
1
,...,x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
) *} 163
{* U | e(x
1
,...,x
k
) : x
1
in E
1
, ...,
x
k
in E
k
| P(x
1
, ..., x
k
)*} 163
9.2.5 The Arithmetic Progression Construc-
tors . . . . . . . . . . . . . . 164
{ i..j } 164
{ U | i..j } 164
{ i .. j by k } 165
{ U | i .. j by k } 165
9.3 Power Sets . . . . . . . . . 165
PowerSet(R) 165
PowerIndexedSet(R) 165
PowerMultiset(R) 166
in 166
PowerFormalSet(R) 166
in 166
in 166
! 166
! 166
! 166
9.3.1 The Cartesian Product Constructors 167
9.4 Sets from Structures . . . . . 167
Set(M) 167
FormalSet(M) 167
9.5 Accessing and Modifying Sets . 168
9.5.1 Accessing Sets and their Associated
Structures . . . . . . . . . . . 168
# 168
Category(S) 168
Type(S) 168
Parent(R) 168
Universe(R) 168
Index(S, x) 168
Position(S, x) 168
S[i] 168
S[I] 168
9.5.2 Selecting Elements of Sets . . . . 169
Random(R) 170
random{ e(x) : x in E | P(x) } 170
random{e(x
1
, ..., x
k
) : x
1
in E
1
,
..., x
k
in E
k
| P(x
1
, ..., x
k
)} 170
Representative(R) 170
Rep(R) 170
ExtractRep(R, r) 171
rep{ e(x) : x in E | P(x) } 171
rep{ e(x
1
, ..., x
k
) : x
1
in E
1
, ...,
x
k
in E
k
| P(x
1
, ..., x
k
) } 171
Minimum(S) 172
Min(S) 172
Maximum(S) 172
Max(S) 172
Hash(x) 172
9.5.3 Modifying Sets . . . . . . . . . 172
Include(S, x) 172
Include(S, x) 172
Exclude(S, x) 172
Exclude(S, x) 172
ChangeUniverse(S, V) 173
156 SETS, SEQUENCES, AND MAPPINGS Part II
ChangeUniverse(S, V) 173
CanChangeUniverse(S, V) 173
SetToIndexedSet(E) 174
IndexedSetToSet(S) 174
Isetset(S) 174
IndexedSetToSequence(S) 174
Isetseq(S) 174
MultisetToSet(S) 174
SetToMultiset(E) 174
SequenceToMultiset(Q) 174
9.6 Operations on Sets . . . . . 175
9.6.1 Boolean Functions and Operators . 175
IsNull(R) 175
IsEmpty(R) 175
eq 175
ne 175
in 175
notin 175
subset 176
notsubset 176
eq 176
ne 176
IsDisjoint(R, S) 176
9.6.2 Binary Set Operators . . . . . . 176
join 176
meet 177
diff 177
sdiff 177
9.6.3 Other Set Operations . . . . . . 177
Multiplicity(S, x) 177
Multiplicities(S) 177
Subsets(S) 177
Subsets(S, k) 177
Multisets(S, k) 178
Subsequences(S, k) 178
Permutations(S) 178
Permutations(S, k) 178
9.7 Quantiers . . . . . . . . . 178
exists(t){ e(x): x in E | P(x) } 178
exists(t
1
, ..., t
r
){ e(x) :
x in E | P(x) } 178
exists(t){e(x
1
, ..., x
k
): x
1
in E
1
,
..., x
k
in E
k
| P(x
1
, ..., x
k
)} 179
exists(t
1
, ..., t
r
){ e(x
1
, ..., x
k
) :
x
1
in E
1
, ..., x
k
in E
k
| P } 179
forall(t){ e(x) : x in E | P(x) } 179
forall(t
1
, ..., t
r
){ e(x) :
x in E | P(x) } 179
forall(t){e(x
1
, ..., x
k
): x
1
in E
1
,
..., x
k
in E
k
| P(x
1
, ..., x
k
)} 180
forall(t
1
, ..., t
r
){ e(x
1
, ..., x
k
) :
x
1
in E
1
, ..., x
k
in E
k
| P } 180
9.8 Reduction and Iteration over Sets181
x in S 181
& 181
Chapter 9
SETS
9.1 Introduction
A set in Magma is a (usually unordered) collection of objects belonging to some common
structure (called the universe of the set). There are four basic types of sets: enumer-
ated sets, whose elements are all stored explicitly (with one exception, see below); formal
sets, whose elements are stored implicitly by means of a predicate that allows for testing
membership; indexed sets, which are restricted enumerated sets having a numbering on
elements; and multisets, which are enumerated sets with possible repetition of elements.
In particular, enumerated and indexed sets and multisets are always nite, and formal sets
are allowed to be innite.
9.1.1 Enumerated Sets
Enumerated sets are nite, and can be specied in three basic ways (see also section 2
below): by listing all elements; by an expression involving elements of some nite structure;
and by an arithmetic progression. If an arithmetic progression is specied, the elements
are not calculated explicitly until a modication of the set necessitates it; in all other cases
all elements of the enumerated set are stored explicitly.
9.1.2 Formal Sets
A formal set consists of the subset of elements of some carrier set (structure) on which a
certain predicate assumes the value true.
The only set-theoretic operations that can be performed on formal sets are union,
intersection, dierence and symmetric dierence, and element membership testing.
9.1.3 Indexed Sets
For some purposes it is useful to be able to access elements of a set through an index map,
which numbers the elements of the set. For that purpose Magma has indexed sets, on
which a very few basic set operations are allowed (element membership testing) as well
as some sequence-like operations (such as accessing the i-th term, getting the index of an
element, appending and pruning).
9.1.4 Multisets
For some purposes it is useful to construct a set with some of its members repeated. For
that purpose Magma has multisets, which take into account the repetition of members.
The number of times an object x occurs in a multiset S is called the multiplicity of x
in S. Magma has the operator to specify a multiplicity: the expression x^^n means
the object x with multiplicity n. In the following, whenever any multiset constructor or
function expects an element y, the expression xn may usually be used.
158 SETS, SEQUENCES, AND MAPPINGS Part II
9.1.5 Compatibility
The binary operators for sets do not allow mixing of the four types of sets (so one cannot
take the intersection of an enumerated set and a formal set, for example), but it is easy to
convert an enumerated set into a formal set see the section on binary operators below
and there are functions provided for making an enumerated set out of an indexed set or a
multiset (and vice versa).
By the limitation on their construction formal sets can only contain elements from one
structure in Magma. The elements of enumerated sets are also restricted, in the sense
that either some universe must be specied upon creation, or Magma must be able to nd
such universe automatically. The rules for compatibility of elements and the way Magma
deals with these universes are the same for sequences and sets, and are described in the
previous chapter. The restrictions on indexed sets are the same as those for enumerated
sets.
9.1.6 Notation
Certain expressions appearing in the sections below (possibly with subscripts) have a
standard interpretation:
U the universe: any Magma structure;
E the carrier set for enumerated sets: any enumerated structure (it must be possible to
loop over its elements see the Introduction to this Part (Chapter 8));
F the carrier set for formal sets: any structure for which membership testing using in is
dened see the Introduction to this Part (Chapter 8));
x a free variable which successively takes the elements of E (or F in the formal case) as
its values;
P a Boolean expression that usually involves the variable(s) x, x
1
, . . . , x
k
;
e an expression that also usually involves the variable(s) x, x
1
, . . . , x
k
.
9.2 Creating Sets
The customary braces and are used to dene enumerated sets. Formal sets are delimited
by the composite braces ! and !. For indexed sets @ and @ are used. For multisets *
and * are used.
9.2.1 The Formal Set Constructor
The formal set constructor has the following xed format (the expressions appearing in
the construct are dened above):
! x in F | P(x) !
Form the formal set consisting of the subset of elements x of F for which P(x) is
true. If P(x) is true for every element of F, the set constructor may be abbreviated
to ! x in F !. Note that the universe of a formal set will always be equal to
the carrier set F.
Ch. 9 SETS 159
9.2.2 The Enumerated Set Constructor
Enumerated sets can be constructed by expressions enclosed in braces, provided that the
values of all expressions can be automatically coerced into some common structure, as out-
lined in the Introduction, (Chapter 8). All general constructors have an optional universe
(U in the list below) up front, that allows the user to specify into which structure all terms
of the sets should be coerced.
The null set: an empty set that does not have its universe dened.
U |
The empty set with universe U.
e
1
, e
2
, ..., e
n
Given a list of expressions e
1
, . . . , e
n
, dening elements a
1
, a
2
, . . . , a
n
all belonging
to (or automatically coercible into) a single algebraic structure U, create the set
a
1
, a
2
, ..., a
n
of elements of U.
Example H9E1
We create a set by listing its elements explicitly.
> S := { (7^2+1)/5, (8^2+1)/5, (9^2-1)/5 };
> S;
{ 10, 13, 16 }
> Parent(S);
Set of subsets of Rational Field
Thus S was created as a set of rationals, because / on integers has a rational result. If one wishes
to obtain a set of integers, one could specify the universe (or one could use div, or one could use
! on every element to coerce it into the ring of integers):
> T := { Integers() | (7^2+1)/5, (8^2+1)/5, (9^2-1)/5 };
> T;
{ 10, 13, 16 }
> Parent(T);
Set of subsets of Integer Ring
U | e
1
, e
2
, ..., e
n
Given a list of expressions e
1
, . . . , e
n
, which dene elements a
1
, a
2
, . . . , a
n
that are
all coercible into U, create the set a
1
, a
2
, ..., a
n
of elements of U.
160 SETS, SEQUENCES, AND MAPPINGS Part II
e(x) : x in E | P(x)
Form the set of elements e(x), all belonging to some common structure, for those
x E with the property that the predicate P(x) is true. The expressions appearing
in this construct have the interpretation given in the Introduction (Chapter 8) (in
particular, E must be a nite structure that can be enumerated).
If P(x) is true for every value of x in E, then the set constructor may be abbre-
viated to e(x) : x in E .
U | e(x) : x in E | P(x)
Form the set of elements of U consisting of the values e(x) for those x E for which
the predicate P(x) is true (an error results if not all e(x) are coercible into U). The
expressions appearing in this construct have the same interpretation as before.
If P is always true, it may be omitted (including the [).
e(x
1
,...,x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
)
The set consisting of those elements e(x
1
, . . . , x
k
), in some common structure, for
which x
1
, . . . , x
k
in E
1
, . . . , E
k
have the property that P(x
1
, . . . , x
k
) is true. The
expressions appearing in this construct have the interpretation given in the Intro-
duction (Chapter 8).
Note that if two successive allowable structures E
i
and E
i+1
are identical, then
the specication of the carrier sets for x
i
and x
i+1
may be abbreviated to x
i
, x
i+1
in E
i
.
Also, if P(x
1
, ..., x
k
) is always true, it may be omitted (including the [).
U | e(x
1
,...,x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
)
As in the previous entry, the set consisting of those elements e(x
1
, . . . , x
k
) for which
P(x
1
, . . . , x
k
) is true, is formed, as a set of elements of U (an error occurs if not all
e(x
1
, . . . , x
k
) are elements of or coercible into U).
Again, identical successive structures may be abbreviated, and a predicate that
is always true may be omitted.
Example H9E2
Now that Fermats last theorem may have been proven, it may be of interest to nd integers
that almost satisfy x
n
+ y
n
= z
n
. In this example we nd all 2 < x, y, z < 1000 such that
x
3
+y
3
= z
3
+ 1. First we build a set of cubes, then two sets of pairs for which the sum of cubes
diers from a cube by 1. Note that we build a set rather than a sequence of cubes because we
only need fast membership testing. Also note that the resulting sets of pairs do not have their
elements in the order in which they were found.
> cubes := { Integers() | x^3 : x in [1..1000] };
> plus := { <a, b> : a in [2..1000], b in [2..1000] | \
> b ge a and (a^3+b^3-1) in cubes };
> plus;
{
Ch. 9 SETS 161
< 9, 10 >,
< 135, 235 >
< 334, 438 >,
< 73, 144 >,
< 64, 94 >,
< 244, 729 >
}
Note that we spend a lot of time cubing integers this way. For a more ecient approach, see a
subsequent example.
9.2.3 The Indexed Set Constructor
The creation of indexed sets is similar to that of enumerated sets.
@ @
The null set: an empty indexed set that does not have its universe dened.
@ U | @
The empty indexed set with universe U.
@ e
1
, e
2
, ..., e
n
@
Given a list of expressions e
1
, . . . , e
n
, dening elements a
1
, a
2
, . . . , a
n
all belonging
to (or automatically coercible into) a single algebraic structure U, create the indexed
set Q = a
1
, a
2
, ..., a
n
of elements of U.
@ U | e
1
, e
2
, ..., e
m
@
Given a list of expressions e
1
, . . . , e
m
, which dene elements a
1
, a
2
, . . . , a
n
that are
all coercible into U, create the indexed set Q = a
1
, a
2
, ..., a
n
of elements of U.
@ e(x) : x in E | P(x) @
Form the indexed set of elements e(x), all belonging to some common structure,
for those x E with the property that the predicate P(x) is true. The expres-
sions appearing in this construct have the interpretation given in the Introduction
(Chapter 8) (in particular, E must be a nite structure that can be enumerated).
If P is always true, it may be omitted (including the [).
@ U | e(x) : x in E | P(x) @
Form the indexed set of elements of U consisting of the values e(x) for those x E
for which the predicate P(x) is true (an error results if not all e(x) are coercible
into U). The expressions appearing in this construct have the same interpretation
as before.
If P is always true, it may be omitted (including the [).
162 SETS, SEQUENCES, AND MAPPINGS Part II
@ e(x
1
,...,x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
) @
The indexed set consisting of those elements e(x
1
, . . . , x
k
) (in some common struc-
ture), for which x
1
, . . . , x
k
in E
1
. . . E
k
have the property that P(x
1
, . . . , x
k
) is
true. The expressions appearing in this construct have the interpretation given in
the Introduction (Chapter 8).
Note that if two successive allowable structures E
i
and E
i+1
are identical, then
the specication of the carrier sets for x
i
and x
i+1
may be abbreviated to x
i
, x
i+1
in E
i
.
Also, if P(x
1
, ..., x
k
) is always true, it may be omitted.
@ U | e(x
1
,...,x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
)@
As in the previous entry, the indexed set consisting of those elements e(x
1
, . . . , x
k
)
for which P(x
1
, . . . , x
k
) is true is formed, as an indexed set of elements of U (an
error occurs if not all e(x
1
, . . . , x
k
) are elements of or coercible into U).
Again, identical successive structures may be abbreviated, and a predicate that
is always true may be omitted.
Example H9E3
In the previous example we found pairs x, y such that x
3
+ y
3
diers by one from some cube z
3
.
Using indexed sets it is somewhat easier to retrieve the integer z as well. We give a small example.
Note also that it is benecial to know here that evaluation of expressions proceeds left to right.
> cubes := { @ Integers() | z^3 : z in [1..25] @};
> plus := { <x, y, z> : x in [-10..10], y in [-10..10], z in [1..25] |
> y ge x and Abs(x) gt 1 and Abs(y) gt 1 and (x^3+y^3-1) in cubes
> and (x^3+y^3-1) eq cubes[z] };
> plus;
{ <-6, 9, 8>, <9, 10, 12>, <-8, 9, 6> }
9.2.4 The Multiset Constructor
The creation of multisets is similar to that of enumerated sets. An important dierence
is that repetitions are signicant and the operator (mentioned above) may be used to
specify the multiplicity of an element.
* *
The null set: an empty multiset that does not have its universe dened.
* U | *
The empty multiset with universe U.
Ch. 9 SETS 163
* e
1
, e
2
, ..., e
n
*
Given a list of expressions e
1
, . . . , e
n
, dening elements a
1
, a
2
, . . . , a
n
all belonging to
(or automatically coercible into) a single algebraic structure U, create the multiset
Q = a
1
, a
2
, ..., a
n
of elements of U.
* U | e
1
, e
2
, ..., e
m
*
Given a list of expressions e
1
, . . . , e
m
, which dene elements a
1
, a
2
, . . . , a
n
that are
all coercible into U, create the multiset Q = a
1
, a
2
, ..., a
n
of elements of U.
* e(x) : x in E | P(x) *
Form the multiset of elements e(x), all belonging to some common structure, for
those x E with the property that the predicate P(x) is true. The expressions
appearing in this construct have the interpretation given in the Introduction (Chap-
ter 8) (in particular, E must be a nite structure that can be enumerated).
If P is always true, it may be omitted (including the [).
* U | e(x) : x in E | P(x) *
Form the multiset of elements of U consisting of the values e(x) for those x E
for which the predicate P(x) is true (an error results if not all e(x) are coercible
into U). The expressions appearing in this construct have the same interpretation
as before.
If P is always true, it may be omitted (including the [).
* e(x
1
,...,x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
) *
The multiset consisting of those elements e(x
1
, . . . , x
k
) (in some common structure),
for which x
1
, . . . , x
k
in E
1
. . . E
k
have the property that P(x
1
, . . . , x
k
) is true.
The expressions appearing in this construct have the interpretation given in the
Introduction (Chapter 8).
Note that if two successive allowable structures E
i
and E
i+1
are identical, then
the specication of the carrier sets for x
i
and x
i+1
may be abbreviated to x
i
, x
i+1
in E
i
.
Also, if P(x
1
, ..., x
k
) is always true, it may be omitted.
* U | e(x
1
,...,x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
)*
As in the previous entry, the multiset consisting of those elements e(x
1
, . . . , x
k
) for
which P(x
1
, . . . , x
k
) is true is formed, as an multiset of elements of U (an error
occurs if not all e(x
1
, . . . , x
k
) are elements of or coercible into U).
Again, identical successive structures may be abbreviated, and a predicate that
is always true may be omitted.
164 SETS, SEQUENCES, AND MAPPINGS Part II
Example H9E4
Here we demonstrate the use of the multiset constructors.
> M := {* 1, 1, 1, 3, 5 *};
> M;
{* 1^^3, 3, 5 *}
> M := {* 1^^4, 2^^5, 1/2^^3 *};
> M;
> // Count frequency of digits in first 1000 digits of pi:
> pi := Pi(RealField(1001));
> dec1000 := Round(10^1000*(pi-3));
> I := IntegerToString(dec1000);
> F := {* I[i]: i in [1 .. #I] *};
> F;
{* 7^^95, 3^^102, 6^^94, 2^^103, 9^^106, 5^^97,
1^^116, 8^^101, 4^^93, 0^^93 *}
> for i := 0 to 9 do i, Multiplicity(F, IntegerToString(i)); end for;
0 93
1 116
2 103
3 102
4 93
5 97
6 94
7 95
8 101
9 106
9.2.5 The Arithmetic Progression Constructors
Some special constructors exist to create and store enumerated sets of integers in arithmetic
progression eciently. This only works for arithmetic progressions of elements of the ring
of integers.
i..j
U | i..j
The enumerated set whose elements form the arithmetic progression i, i + 1, i +
2, . . . , j, where i and j are (expressions dening) integers. If j is less than i then
the empty set will be created.
The only universe U that is legal here is the ring of integers.
Ch. 9 SETS 165
i .. j by k
U | i .. j by k
The enumerated set consisting of the integers forming the arithmetic progression
i, i + k, i + 2 k, . . . , j, where i, j and k are (expressions dening) integers (but
k ,= 0).
If k is positive then the last element in the progression will be the greatest integer
of the form i +n k that is less than or equal to j. If j is less than i, the empty set
will be constructed.
If k is negative then the last element in the progression will be the least integer
of the form i + n k that is greater than or equal to j. If j is greater than i, the
empty set will be constructed.
As for the previous constructor, only the ring of integers is allowed as a legal
universe U.
Example H9E5
It is possible to use the arithmetic progression constructors to save typing in the creation of
arithmetic progressions of elements of other structures than the ring of integers, but it should
be kept in mind that the result will not be treated especially eciently like the integer case. Here
is the wrong way, as well as two correct ways to create a set of 10 nite eld elements.
> S := { FiniteField(13) | 1..10 };
Runtime error in { .. }: Invalid set universe
> S := { FiniteField(13) | x : x in { 1..10 } };
> S;
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
> G := PowerSet(FiniteField(13));
> S := G ! { 1..10 };
> S;
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
9.3 Power Sets
The PowerSet constructor returns a structure comprising the subsets of a given structure
R; it is mainly useful as a parent for other set and sequence constructors. The only
operations that are allowed on power sets are printing, testing element membership, and
coercion into the power set (see the examples below).
PowerSet(R)
The structure comprising all enumerated subsets of structure R.
PowerIndexedSet(R)
The structure comprising all indexed subsets of structure R.
166 SETS, SEQUENCES, AND MAPPINGS Part II
PowerMultiset(R)
The structure consisting of all submultisets of the structure R.
S in P
Returns true if enumerated set S is in the power set P, that is, if all elements of
the set S are contained in or coercible into R, where P is the power set of R; false
otherwise.
PowerFormalSet(R)
The structure comprising all formal subsets of structure R.
S in P
Returns true if indexed set S is in the power set P, that is, if all elements of the
set S are contained in or coercible into R, where P is the power set of R; false
otherwise.
S in P
Returns true if multiset S is in the power set P, that is, if all elements of the set S
are contained in or coercible into R, where P is the power set of R; false otherwise.
P ! S
Return a set with universe R consisting of the elements of the set S, where P is the
power set of R. An error results if not all elements of S can be coerced into R.
P ! S
Return an indexed set with universe R consisting of the elements of the set S, where
P is the power set of R. An error results if not all elements of S can be coerced into
R.
P ! S
Return an multiset with universe R consisting of the elements of the set S, where P
is the power set of R. An error results if not all elements of S can be coerced into
R.
Ch. 9 SETS 167
Example H9E6
> S := { 1 .. 10 };
> P := PowerSet(S);
> P;
Set of subsets of { 1 .. 10 }
> F := { 6/3, 12/4 };
> F in P;
true
> G := P ! F;
> Parent(F);
Set of subsets of Rational Field
> Parent(G);
Set of subsets of { 1 .. 10 }
9.3.1 The Cartesian Product Constructors
Using car< > and CartesianProduct( ), it is possible to create the Cartesian product of
sets (or, in fact, of any combination of structures), but the result will be of type Cartesian
product rather than set, and the elements are tuples we refer the reader to Chapter 11
for details.
9.4 Sets from Structures
Set(M)
Given a nite structure that allows explicit enumeration of its elements, return the
set containing its elements (having M as its universe).
FormalSet(M)
Given a structure M, return the formal set consisting of its elements.
168 SETS, SEQUENCES, AND MAPPINGS Part II
9.5 Accessing and Modifying Sets
Enumerated sets can be modied by inserting or removing elements. Indexed sets allow
some sequence-like operators for modication and access.
9.5.1 Accessing Sets and their Associated Structures
#R
Cardinality of the enumerated, indexed, or multi- set R. Note that for a multiset,
repetitions are signicant, so the result may be greater than the underlying set.
Category(S)
Type(S)
The category of the object S. For a set this will be one of SetEnum, SetIndx,
SetMulti, or SetForm. For a power set the type is one of PowSetEnum, PowSetIndx,
PowSetMulti.
Parent(R)
Returns the parent structure of R, that is, the structure consisting of all (enumer-
ated) sequences over the universe of R.
Universe(R)
Returns the universe of the (enumerated or indexed or multi- or formal) set R,
that is, the common structure to which all elements of the set belong. An error is
signalled when R is the null set.
Index(S, x)
Position(S, x)
Given an indexed set S, and an element x, returns the index i such that S[i] = x if
such index exists, or return 0 if x is not in S. If x is not in the universe of S, an
attempt will be made to coerce it; an error occurs if this fails.
S[i]
Return the i-th entry of indexed set S. If i < 1 or i > #S an error occurs. Note
that indexing is not allowed on the left hand side.
S[I]
The indexed set S[i
1
], . . . , S[i
r
] consisting of terms selected from the indexed set
S, according to the terms of the integer sequence I. If any term of I lies outside the
range 1 to #S, then an error results. If I is the empty sequence, then the empty
set with universe the same as that of S is returned.
Ch. 9 SETS 169
Example H9E7
We build an indexed set of sets to illustrate the use of the above functions.
> B := { @ { i : i in [1..k] } : k in [1..5] @};
> B;
{ @
{ 1 },
{ 1, 2 },
{ 1, 2, 3 },
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4, 5 },
@}
> #B;
5
> Universe(B);
Set of subsets of Integer Ring
> Parent(B);
Set of indexed subsets of Set of subsets of Integer Ring
> Category(B);
SetIndx
> Index(B, { 2, 1});
2
> #B[2];
2
> Universe(B[2]);
Integer Ring
9.5.2 Selecting Elements of Sets
Most nite structures in Magma, including enumerated sets, allow one to obtain a random
element using Random. There is an alternative (and often preferable) option for enumerated
sets in the random constructor. This makes it possible to choose a random element of
the set without generating the whole set rst.
Likewise, rep is an alternative to the general Rep function returning a representative
element of a structure, having the advantage of aborting the construction of the set as soon
as one element has been found.
Here, E will again be an enumerable structure, that is, a structure that allows enumer-
ation of its elements (see the Appendix for an exhaustive list).
Note that random e(x) : x in E | P(x) does not return a random element of
the set of values e(x), but rather a value of e(x) for a random x in E which satises P
(and mutatis mutandis for rep).
See the subsection on Notation in the Introduction (Chapter 8) for conventions regard-
ing e, x, E, P.
170 SETS, SEQUENCES, AND MAPPINGS Part II
Random(R)
A random element chosen from the enumerated, indexed or multi- set R. Every
element has an equal probability of being chosen for enumerated or indexed sets,
and a weighted probability in proportion to its multiplicity for multisets. Succes-
sive invocations of the function will result in independently chosen elements being
returned as the value of the function. If R is empty an error occurs.
random e(x) : x in E | P(x)
Given an enumerated structure E and a Boolean expression P, return the value of
the expression e(y) for a randomly chosen element y of E for which P(y) is true.
P may be omitted if it is always true.
randome(x
1
, ..., x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
)
Given enumerated structures E
1
, . . . , E
k
, and a Boolean expression P(x
1
, . . ., x
k
),
return the value of the expression e(y
1
, , y
k
) for a randomly chosen element <
y
1
, . . . , y
k
> of E
1
E
k
, for which P(y
1
, . . . , y
k
) is true.
P may be omitted if it is always true.
If successive structures E
i
and E
i+1
are identical, then the abbreviation x
i
, x
i+1
in E
i
may be used.
Example H9E8
Here are two ways to nd a random primitive element for a nite eld.
> p := 10007;
> F := FiniteField(p);
> proots := { z : z in F | IsPrimitive(z) };
> #proots;
5002
> Random(proots);
5279
This way, a set of 5002 elements is built (and primitivity is checked for all elements of F), and a
random choice is made. Alternatively, we use random.
> random{ x : x in F | IsPrimitive(x) };
4263
In this case random elements in F are chosen until one is found that is primitive. Since almost half
of Fs elements are primitive, only very few primitivity tests will be done before success occurs.
Representative(R)
Rep(R)
An arbitrary element chosen from the enumerated, indexed, or multi- set R.
Ch. 9 SETS 171
ExtractRep(R, r)
Assigns an arbitrary element chosen from the enumerated set R to r, and removes
it from R. Thus the set R is modied, as well as the element r. An error occurs if
R is empty.
rep e(x) : x in E | P(x)
Given an enumerated structure E and a Boolean expression P, return the value of
the expression e(y) for the rst element y of E for which P(y) is true. If P(x) is
false for every element of E, an error will occur.
rep e(x
1
, ..., x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
)
Given enumerated structures E
1
, . . . , E
k
, and a Boolean expression P(x
1
, . . ., x
k
),
return the value of the expression e(y
1
, , y
k
) for the rst element < y
1
, . . . , y
k
>
of E
1
E
k
, for which P(y
1
, . . . , y
k
) is true. An error occurs if no element of
E
1
E
k
satises P.
P may be omitted if it is always true.
If successive structures E
i
and E
i+1
are identical, then the abbreviation x
i
, x
i+1
in E
i
may be used.
Example H9E9
As an illustration of the use of ExtractRep, we modify an earlier example, and nd cubes satisfying
x
3
+ y
3
= z
3
1 (with x, y, z 1000).
> cubes := { Integers() | x^3 : x in [1..1000] };
> cc := cubes;
> min := { };
> while not IsEmpty(cc) do
> ExtractRep(~cc, ~a);
> for b in cc do
> if a+b+1 in cubes then
> min join:= { <a, b> };
> end if;
> end for;
> end while;
> { < Iroot(x[1], 3), Iroot(x[2], 3) > : x in min };
{ <138, 135>, <823, 566>, <426, 372>, <242, 720>,
<138, 71>, <426, 486>, <6, 8> }
Note that instead of taking cubes over again, we only have to take cube roots in the last line (on
the small resulting set) once.
172 SETS, SEQUENCES, AND MAPPINGS Part II
Minimum(S)
Min(S)
Given a non-empty enumerated, indexed, or multi- set S, such that lt and eq are
dened on the universe of S, this function returns the minimum of the elements of
S. If S is an indexed set, the position of the minimum is also returned.
Maximum(S)
Max(S)
Given a non-empty enumerated, indexed, or multi- set S, such that lt and eq are
dened on the universe of S, this function returns the maximum of the elements of
S. If S is an indexed set, the position of the maximum is also returned.
Hash(x)
Given a Magma object x which can be placed in a set, return the hash value of
x used by the set machinery. This is a xed but arbitrary non-negative integer
(whose maximum value is the maximum value of a C unsigned long on the particular
machine). The crucial property is that if x and y are objects and x equals y then the
hash values of x and y are equal (even if x and y have dierent internal structures).
Thus one could implement sets manually if desired by the use of this function.
9.5.3 Modifying Sets
Include(S, x)
Include(S, x)
Create the enumerated, indexed, or multi- set obtained by putting the element x in
S (S is unchanged if S is not a multiset and x is already in S). If S is an indexed
set, the element will be appended at the end. If S is a multiset, the multiplicity of
x will be increased accordingly. If x is not in the universe of S, an attempt will be
made to coerce it; an error occurs if this fails.
There are two versions of this: a procedure, where S is replaced by the new set,
and a function, which returns the new set. The procedural version takes a reference
S to S as an argument.
Note that the procedural version is much more ecient since the set S will not
be copied.
Exclude(S, x)
Exclude(S, x)
Create a new set by removing the element x from S. If S is an enumerated set,
nothing happens if x is not in S. If S is a multiset, the multiplicity of x will be
decreased accordingly. If x is not in the universe of S, an attempt will be made to
coerce it; an error occurs if this fails.
Ch. 9 SETS 173
There are two versions of this: a procedure, where S is replaced by the new set,
and a function, which returns the new set. The procedural version takes a reference
S to S as an argument.
Note that the procedural version is much more ecient since the set S will not
be copied.
ChangeUniverse(S, V)
ChangeUniverse(S, V)
Given an enumerated, indexed, or multi- set S with universe U and a structure
V which contains U, construct a new set of the same type which consists of the
elements of S coerced into V .
There are two versions of this: a procedure, where S is replaced by the new set,
and a function, which returns the new set. The procedural version takes a reference
S to S as an argument.
Note that the procedural version is much more ecient since the set S will not
be copied.
CanChangeUniverse(S, V)
Given an enumerated, indexed, or multi- set S with universe U and a structure V
which contains U, attempt to construct a new set T of the same type which consists
of the elements of S coerced into V ; if successful, return true and T, otherwise
return false.
Example H9E10
This example uses Include and Exclude to nd a set (if it exists) of cubes of integers such that
the elements of a given set R can be expressed as the sum of two of those.
> R := { 218, 271, 511 };
> x := 0;
> cubes := { 0 };
> while not IsEmpty(R) do
> x +:= 1;
> c := x^3;
> Include(~cubes, c);
> Include(~cubes, -c);
> for z in cubes do
> Exclude(~R, z+c);
> Exclude(~R, z-c);
> end for;
> end while;
We did not record how the elements of R were obtained as sums of a pair of cubes. For that, the
following suces.
> R := { 218, 271, 511 }; // it has been emptied !
> { { x, y } : x, y in cubes | x+y in R };
174 SETS, SEQUENCES, AND MAPPINGS Part II
{
{ -729, 1000 },
{ -125, 343 },
{ -1, 512 },
}
SetToIndexedSet(E)
Given an enumerated set E, this function returns an indexed set with the same
elements (and universe) as E.
IndexedSetToSet(S)
Isetset(S)
Given an indexed set S, this function returns an enumerated set with the same
elements (and universe) as E.
IndexedSetToSequence(S)
Isetseq(S)
Given an indexed set S, this function returns a sequence with the same elements
(and universe) as E.
MultisetToSet(S)
Given a multiset S, this function returns an enumerated set with the same elements
(and universe) as S.
SetToMultiset(E)
Given an enumerated set E, this function returns a multiset with the same elements
(and universe) as E.
SequenceToMultiset(Q)
Given an enumerated sequence E, this function returns a multiset with the same
elements (and universe) as E.
Ch. 9 SETS 175
9.6 Operations on Sets
9.6.1 Boolean Functions and Operators
As explained in the Introduction (Chapter 8), when elements are taken out of a set their
parent will be the universe of the set (or, if the universe is itself a set, the universe of the
universe, etc.); in particular, the set itself is not the parent. Hence equality testing on set
elements is in fact equality testing between two elements of certain algebraic structures,
and the sets are irrelevant. We only list the (in)equality operator for convenience here.
Element membership testing is of critical importance for all types of sets.
Testing whether or not R is a subset of S can be done if R is an enumerated or indexed
set and S is any set; hence (in)equality testing is only possible between sets that are not
formal sets.
IsNull(R)
Returns true if and only if the enumerated, indexed, or multi- set R is empty and
does not have its universe dened.
IsEmpty(R)
Returns true if and only if the enumerated, indexed or multi- set R is empty.
x eq y
Given an element x of a set R with universe U and an element y of a set S with
universe V , where a common overstructure W can be found with U W V (see
the Introduction (Chapter 8) for details on overstructures), return true if and only
if x and y are equal as elements of W.
x ne y
Given an element x of a set R with universe U and an element y of a set S with
universe V , where a common overstructure W can be found with U W V (see
the Introduction (Chapter 8) for details on overstructures), return true if and only
if x and y are distinct as elements of W.
x in R
Returns true if and only if the element x is a member of the set R. If x is not an
element of the universe U of R, it is attempted to coerce x into U; if this fails, an
error occurs.
x notin R
Returns true if and only if the element x is not a member of the set R. If x is not
an element of the parent structure U of R, it is attempted to coerce x into U; if this
fails, an error occurs.
176 SETS, SEQUENCES, AND MAPPINGS Part II
R subset S
Returns true if the enumerated, indexed or multi- set R is a subset of the set S,
false otherwise. For multisets, if an element x of R has multiplicity n in R, the
multiplicity of x in S must be at least n. Coercion of the elements of R into S is
attempted if necessary, and an error occurs if this fails.
R notsubset S
Returns true if the enumerated, indexed, or multi- set R is a not a subset of the set
S, false otherwise. Coercion of the elements of R into S is attempted if necessary,
and an error occurs if this fails.
R eq S
Returns true if and only if R and S are identical sets, where R and S are enumerated,
indexed or multi- sets For indexed sets, the index function is irrelevant for deciding
equality. For multisets, matching multiplicities must also be equal. Coercion of the
elements of R into S is attempted if necessary, and an error occurs if this fails.
R ne S
Returns true if and only if R and S are distinct sets, where R and S are enumerated
indexed, or multi- sets. For indexed sets, the index function is irrelevant for deciding
equality. For multisets, matching multiplicities must also be equal. Coercion of the
elements of R into S is attempted if necessary, and an error occurs if this fails.
IsDisjoint(R, S)
Returns true i the enumerated, indexed or multi- sets R and S are disjoint. Co-
ercion of the elements of R into S is attempted if necessary, and an error occurs if
this fails.
9.6.2 Binary Set Operators
For each of the following operators, R and S are sets of the same type. If R and S are
both formal sets, then an error will occur unless both have been constructed with the same
carrier structure F in the denition. If R and S are both enumerated, indexed, or multi-
sets, then an error occurs unless the universes of R and S are compatible, as dened in
the Introduction to this Part (Chapter 8).
Note that
Q := ! x in R !
converts an enumerated set R into a formal set Q.
R join S
Union of the sets R and S (see above for the restrictions on R and S). For multisets,
matching multiplicities are added in the union.
Ch. 9 SETS 177
R meet S
Intersection of the sets R and S (see above for the restrictions on R and S). For
multisets, the minimum of matching multiplicities is stored in the intersection.
R diff S
Dierence of the sets R and S, i.e., the set consisting of those elements of R which
are not members of S (see above for the restrictions on R and S).
R sdiff S
Symmetric dierence of the sets R and S, i.e., the set consisting of those elements
which are members of either R or S but not both (see above for the restrictions on
R and S).
Example H9E11
> R := { 1, 2, 3 };
> S := { 1, 1/2, 1/3 };
> R join S;
{ 1/3, 1/2, 1, 2, 3 }
> R meet S;
{ 1 }
> R diff S;
{ 2, 3 }
> S diff R;
{ 1/3, 1/2 }
> R sdiff S;
{ 1/3, 1/2, 2, 3 }
9.6.3 Other Set Operations
Multiplicity(S, x)
Return the multiplicity in multiset S of element x. If x is not in S, zero is returned.
Multiplicities(S)
Returns the sequence of multiplicities of distinct elements in the multiset S. The
order is the same as the internal enumeration order of the elements.
Subsets(S)
The set of all subsets of S.
Subsets(S, k)
The set of subsets of S of size k. If k is larger than the cardinality of S then the
result will be empty.
178 SETS, SEQUENCES, AND MAPPINGS Part II
Multisets(S, k)
The set of multisets consisting of k not necessarily distinct elements of S.
Subsequences(S, k)
The set of sequences of length k with elements from S.
Permutations(S)
The set of permutations (stored as sequences) of the elements of S.
Permutations(S, k)
The set of permutations (stored as sequences) of each of the subsets of S of cardi-
nality k.
9.7 Quantiers
To test whether some enumerated set is empty or not, one may use the IsEmpty function.
However, to use IsEmpty, the set has to be created in full rst. The existential quantier
exists enables one to do the test and abort the construction of the set as soon as an
element is found; moreover, the element found will be assigned to a variable.
Likewise, forall enables one to abort the construction of the set as soon as an element
not satisfying a certain property is encountered.
Note that exists(t) e(x) : x in E | P(x) is not designed to return true if an
element of the set of values e(x) satises P, but rather if there is an x E satisfying P(x)
(in which case e(x) is assigned to t).
For the notation used here, see the beginning of this chapter.
exists(t) e(x): x in E | P(x)
exists(t
1
, ..., t
r
) e(x) : x in E | P(x)
Given an enumerated structure E and a Boolean expression P(x), the Boolean value
true is returned if E contains at least one element x for which P(x) is true. If P(x)
is not true for any element x of E, then the Boolean value false is returned.
Moreover, if P(x) is found to be true for the element y, say, of E, then in the rst
form of the exists expression, variable t will be assigned the value of the expression
e(y). If P(x) is never true for an element of E, t will be left unassigned. In the
second form, where r variables t
1
, . . . , t
r
are given, the result e(y) should be a tuple
of length r; each variable will then be assigned to the corresponding component of
the tuple. Similarly, all the variables will be left unassigned if P(x) is never true.
The clause (t) may be omitted entirely.
P may be omitted if it is always true.
Ch. 9 SETS 179
exists(t)e(x
1
, ..., x
k
): x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
)
exists(t
1
, ..., t
r
) e(x
1
, ..., x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P
Given enumerated structures E
1
, . . . , E
k
, and a Boolean expression P(x
1
, . . ., x
k
),
the Boolean value true is returned if there is an element < y
1
, . . ., y
k
> in the
Cartesian product E
1
E
k
, such that P(y
1
, . . . , y
k
) is true. If P(x
1
, . . . , x
k
) is
not true for any element (y
1
, . . ., y
k
) of E
1
E
k
, then the Boolean value false
is returned.
Moreover, if P(x
1
, . . ., x
k
) is found to be true for the element < y
1
, . . . , y
k
> of
E
1
E
k
, then in the rst form of the exists expression, the variable t will be
assigned the value of the expression e(y
1
, , y
k
). If P(x
1
, . . ., x
k
) is never true for
an element of E
1
E
k
, then the variable t will be left unassigned. In the second
form, where r variables t
1
, . . . , t
r
are given, the result e(y
1
, , y
k
) should be a tuple
of length r; each variable will then be assigned to the corresponding component of
the tuple. Similarly, all the variables will be left unassigned if P(x
1
, . . ., x
k
) is never
true. The clause (t) may be omitted entirely.
P may be omitted if it is always true.
If successive structures E
i
and E
i+1
are identical, then the abbreviation x
i
, x
i+1
in E
i
may be used.
Example H9E12
As a variation on an earlier example, we check whether or not some integers can be written as
sums of cubes (less than 10
3
in absolute value):
> exists(t){ <x, y> : x, y in [ t^3 : t in [-10..10] ] | x + y eq 218 };
true
> t;
<-125, 343>
> exists(t){ <x, y> : x, y in [ t^3 : t in [1..10] ] | x + y eq 218 };
false
> t;
>> t;
^
User error: Identifier t has not been declared
forall(t) e(x) : x in E | P(x)
forall(t
1
, ..., t
r
) e(x) : x in E | P(x)
Given an enumerated structure E and a Boolean expression P(x), the Boolean value
true is returned if P(x) is true for every element x of E.
If P(x) is not true for at least one element x of E, then the Boolean value false
is returned.
Moreover, if P(x) is found to be false for the element y, say, of E, then in the rst
form of the exists expression, variable t will be assigned the value of the expression
180 SETS, SEQUENCES, AND MAPPINGS Part II
e(y). If P(x) is true for every element of E, t will be left unassigned. In the second
form, where r variables t
1
, . . . , t
r
are given, the result e(y) should be a tuple of
length r; each variable will then be assigned to the corresponding component of the
tuple. Similarly, all the variables will be left unassigned if P(x) is always true. The
clause (t) may be omitted entirely.
P may be omitted if it is always true.
forall(t)e(x
1
, ..., x
k
): x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
)
forall(t
1
, ..., t
r
) e(x
1
, ..., x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P
Given sets E
1
, . . . , E
k
, and a Boolean expression P(x
1
, . . ., x
k
), the Boolean value
true is returned if P(x
1
, . . . , x
k
) is true for every element (x
1
, . . ., x
k
) in the Carte-
sian product E
1
E
k
.
If P(x
1
, . . . , x
k
) fails to be true for some element (y
1
, . . ., y
k
) of E
1
E
k
,
then the Boolean value false is returned.
Moreover, if P(x
1
, . . ., x
k
) is false for the element < y
1
, . . . , y
k
> of E
1
E
k
,
then in the rst form of the exists expression, the variable t will be assigned the
value of the expression e(y
1
, , y
k
). If P(x
1
, . . ., x
k
) is true for every element of
E
1
E
k
, then the variable t will be left unassigned. In the second form, where
r variables t
1
, . . . , t
r
are given, the result e(y
1
, , y
k
) should be a tuple of length
r; each variable will then be assigned to the corresponding component of the tuple.
Similarly, all the variables will be left unassigned if P(x
1
, . . ., x
k
) is never true. The
clause (t) may be omitted entirely.
P may be omitted if it is always true.
If successive structures E
i
and E
i+1
are identical, then the abbreviation x
i
, x
i+1
in E
i
may be used.
Example H9E13
This example shows that forall and exists may be nested.
It is well known that every prime that is 1 modulo 4 can be written as the sum of two squares,
but not every integer m congruent to 1 modulo 4 can. In this example we explore for small m
whether perhaps m (with || 1) is always a sum of squares.
> forall(u){ m : m in [5..1000 by 4] |
> exists{ <x, y, z> : x, y in [0..30], z in [-1, 0, 1] |
> x^2+y^2+z eq m } };
false
> u;
77
Ch. 9 SETS 181
9.8 Reduction and Iteration over Sets
Both enumerated and indexed sets allow enumeration of their elements; formal sets do not.
For indexed sets the enumeration will occur according to the order given by the indexing.
Instead of using a loop to apply the same binary associative operator to all elements of
an enumerated or indexed set, it is in certain cases possible to use the reduction operator
&.
x in S
Enumerate the elements of an enumerated or indexed set S. This can be used in
loops, as well as in the set and sequence constructors.
&o S
Given an enumerated or indexed set S = a
1
, a
2
, . . . , a
n
of elements belonging to
an algebraic structure U, and an (associative) operator : U U U, form the
element a
i
1
a
i
2
a
i
3
. . . a
i
n
, for some permutation i
1
, . . . , i
n
of 1, . . . , n.
Currently, the following operators may be used to reduce enumerated sets: +,
*, and, or, join, meet and +, *, and, or to reduce indexed sets. An error
will occur if the operator is not dened on U.
If S contains a single element a, then the value returned is a. If S is the null set
(empty and no universe specied) or S is empty with universe U (and the operation
is dened in U), then the result (or error) depends on the operation and upon U.
The following table denes the return value:
empty null
&+ U ! 0 error
& U ! 1 error
&and true true
&or false false
&join empty null
&meet error error
Warning: since the reduction may take place in an arbitrary order on the argu-
ments a
1
, . . . , a
n
, the result is not unambiguously dened if the operation is not
commutative on the arguments!
Example H9E14
The function choose dened below takes a set S and an integer k as input, and produces a set of
all subsets of S with cardinality k.
> function choose(S, k)
> if k eq 0 then
> return { { } };
> else
> return &join{{ s join { x} : s in choose(S diff { x}, k-1) } : x in S};
182 SETS, SEQUENCES, AND MAPPINGS Part II
> end if;
> end function;
So, for example:
> S := { 1, 2, 3, 4 };
> choose(S, 2);
{
{ 1, 3 },
{ 1, 4 },
{ 2, 4 },
{ 2, 3 },
{ 1, 2 },
{ 3, 4 }
}
Try to guess what happens if k < 0.
10 SEQUENCES
10.1 Introduction . . . . . . . . 185
10.1.1 Enumerated Sequences . . . . . . 185
10.1.2 Formal Sequences . . . . . . . . 185
10.1.3 Compatibility . . . . . . . . . . 186
10.2 Creating Sequences . . . . . 186
10.2.1 The Formal Sequence Constructor . 186
[! x in F | P(x) !] 186
10.2.2 The Enumerated Sequence Construc-
tor . . . . . . . . . . . . . . 187
[ ] 187
[ U | ] 187
[ e
1
, e
2
, ..., e
n
] 187
[ U | e
1
, e
2
, ..., e
m
] 187
[ e(x) : x in E | P(x) ] 187
[ U | e(x) : x in E | P(x) ] 187
[ e(x
1
,...,x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
) ] 187
[ U | e(x
1
,...,x
k
) : x
1
in E
1
, ...,
x
k
in E
k
| P(x
1
, ..., x
k
) ] 188
10.2.3 The Arithmetic Progression Construc-
tors . . . . . . . . . . . . . . 188
[ i..j ] 188
[ U | i..j ] 188
[ i .. j by k ] 188
[ U | i .. j by k ] 188
10.2.4 Literal Sequences . . . . . . . . 189
\[ m
1
, ..., m
n
] 189
10.3 Power Sequences . . . . . . 189
PowerSequence(R) 189
in 189
! 189
10.4 Operators on Sequences . . . 190
10.4.1 Access Functions . . . . . . . . 190
# 190
Parent(S) 190
Universe(S) 190
S[i] 190
10.4.2 Selection Operators on Enumerated
Sequences . . . . . . . . . . . 191
S[I] 191
Minimum(S) 191
Min(S) 191
Maximum(S) 191
Max(S) 191
Index(S, x) 191
Index(S, x, f) 191
Position(S, x) 191
Position(S, x, f) 191
Representative(R) 191
Rep(R) 191
Random(R) 192
Explode(R) 192
Eltseq(R) 192
10.4.3 Modifying Enumerated Sequences . 192
Append(S, x) 192
Append(S, x) 192
Exclude(S, x) 192
Exclude(S, x) 192
Include(S, x) 193
Include(S, x) 193
Insert(S, i, x) 193
Insert(S, i, x) 193
Insert(S, k, m, T) 193
Insert(S, k, m, T) 193
Prune(S) 194
Prune(S) 194
Remove(S, i) 194
Remove(S, i) 194
Reverse(S) 194
Reverse(S) 194
Rotate(S, p) 194
Rotate(S, p) 194
Sort(S) 195
Sort(S) 195
Sort(S, C) 195
Sort(S, C, p) 195
Sort(S, C) 195
Undefine(S, i) 195
Undefine(S, i) 195
ChangeUniverse(S, V) 195
ChangeUniverse(S, V) 195
CanChangeUniverse(S, V) 196
10.4.4 Creating New Enumerated Sequences
from Existing Ones . . . . . . . 197
cat 197
Partition(S, p) 197
Partition(S, P) 197
Setseq(S) 197
SetToSequence(S) 197
Seqset(S) 198
SequenceToSet(S) 198
And(S, T) 199
And(S, T) 199
Or(S, T) 199
Or(S, T) 199
Xor(S, T) 199
Xor(S, T) 199
Not(S) 199
Not(S) 199
10.5 Predicates on Sequences . . . 199
184 SETS, SEQUENCES, AND MAPPINGS Part II
IsComplete(S) 199
IsDefined(S, i) 199
IsEmpty(S) 200
IsNull(S) 200
10.5.1 Membership Testing . . . . . . . 200
in 200
notin 200
IsSubsequence(S, T) 200
IsSubsequence(S, T: Kind := o) 200
eq 200
ne 200
10.5.2 Testing Order Relations . . . . . 201
lt 201
le 201
ge 201
gt 201
10.6 Recursion, Reduction, and Itera-
tion . . . . . . . . . . . . 202
10.6.1 Recursion . . . . . . . . . . . 202
Self(n) 202
Self() 202
10.6.2 Reduction . . . . . . . . . . . 202
& 202
10.7 Iteration . . . . . . . . . . 203
for x in S do st; end for; 203
10.8 Bibliography . . . . . . . . 204
Chapter 10
SEQUENCES
10.1 Introduction
A sequence in Magma is a linearly ordered collection of objects belonging to some common
structure (called the universe of the sequence).
There are two types of sequence: enumerated sequences, of which the elements are all
stored explicitly (with one exception, see below); and formal sequences, of which elements
are stored implicitly by means of a predicate that allows for testing membership. In
particular, enumerated sequences are always nite, and formal sequences are allowed to be
innite. In this chapter a sequence will be either a formal or an enumerated sequence.
10.1.1 Enumerated Sequences
An enumerated sequence of length l is an array of indenite length of which only nitely
many terms including the l-th term, but no term of bigger index have been dened
to be elements of some common structure. Such sequence is called complete if all of the
terms (from index 1 up to the length l) are dened.
In practice the length of any sequence is bounded by the constant integer beta (usually
2
29
).
Incomplete enumerated sequences are allowed as a convenience for the programmer in
building complete enumerated sequences. Some sequence functions require their arguments
to be complete; if that is the case, it is mentioned explicitly in the description below.
However, all functions using sequences in other Magma modules always assume that
a sequence that is passed in as an argument is complete. Note that the following line
converts a possibly incomplete sequence S into a complete sequence T:
T := [ s : s in S ];
because the enumeration using the in operator simply ignores undened terms.
Enumerated sequences of Booleans are highly optimized (stored as bit-vectors).
10.1.2 Formal Sequences
A formal sequence consists of elements of some range set on which a certain predicate
assumes the value true.
There is only a very limited number of operations that can be performed on them.
186 SETS, SEQUENCES, AND MAPPINGS Part II
10.1.3 Compatibility
The binary operators for sequences do not allow mixing of the formal and enumerated
sequence types (so one cannot take the concatenation of an enumerated sequence and a
formal sequence, for example); but it is easy to convert an enumerated sequence into a
formal sequence see the section on binary operators below.
By the limitation on their construction formal sequences can only contain elements from
one structure in Magma. The elements of enumerated sequences are also restricted, in
the sense that either some common structure must be specied upon creation, or Magma
must be able to nd such universe automatically. The rules for compatibility of elements
and the way Magma deals with these parents is the same for sequences and sets, and is
outlined in the Introduction to this Part of the Handbook.
10.2 Creating Sequences
Square brackets are used for the denition of enumerated sequences; formal sequences are
delimited by the composite brackets [! and !].
Certain expressions appearing below (possibly with subscripts) have the standard in-
terpretation:
U the universe: any Magma structure;
E the range set for enumerated sequences: any enumerated structure (it must be possible
to loop over its elements see the Introduction to this Part);
F the range set for formal sequences: any structure for which membership testing using
in is dened see the Introduction to this Part);
x a free variable which successively takes the elements of E (or F in the formal case) as
its values;
P a Boolean expression that usually involves the variable(s) x, x
1
, . . . , x
k
;
e an expression that also usually involves the variable(s) x, x
1
, . . . , x
k
.
10.2.1 The Formal Sequence Constructor
The formal sequence constructor has the following xed format (the expressions appearing
in the construct are dened above):
[! x in F | P(x) !]
Create the formal sequence consisting of the subsequence of elements x of F for
which P(x) is true. If P(x) is true for every element of F, the sequence constructor
may be abbreviated to [! x in F !]
Ch. 10 SEQUENCES 187
10.2.2 The Enumerated Sequence Constructor
Sequences can be constructed by expressions enclosed in square brackets, provided that
the values of all expressions can be automatically coerced into some common structure,
as outlined in the Introduction. All general constructors have the universe U optionally
up front, which allows the user to specify into which structure all terms of the sequences
should be coerced.
[ ]
The null sequence (empty, and no universe specied).
[ U | ]
The empty sequence with universe U.
[ e
1
, e
2
, ..., e
n
]
Given a list of expressions e
1
, . . . , e
n
, dening elements a
1
, a
2
, . . . , a
n
all belonging to
(or automatically coercible into) a single algebraic structure U, create the sequence
Q = [a
1
, a
2
, ..., a
n
] of elements of U.
[ U | e
1
, e
2
, ..., e
m
]
Given a list of expressions e
1
, . . . , e
m
, which dene elements a
1
, a
2
, . . . , a
n
that are
all coercible into U, create the sequence Q = [a
1
, a
2
, ..., a
n
] of elements of U.
[ e(x) : x in E | P(x) ]
Form the sequence of elements e(x), all belonging to some common structure, for
those x E with the property that the predicate P(x) is true. The expressions
appearing in this construct have the interpretation given at the beginning of this
section.
If P(x) is true for every element of E, the sequence constructor may be abbre-
viated to [ e(x) : x in E ] .
[ U | e(x) : x in E | P(x) ]
Form the sequence of elements of U consisting of the values e(x) for those x E
for which the predicate P(x) is true (an error results if not all e(x) are coercible
into U). The expressions appearing in this construct have the same interpretation
as above.
[ e(x
1
,...,x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
) ]
The sequence consisting of those elements e(x
1
, . . . , x
k
), in some common structure,
for which x
1
, . . . , x
k
in E
1
, . . . , E
k
have the property that P(x
1
, . . . , x
k
) is true.
The expressions appearing in this construct have the interpretation given at the
beginning of this section.
Note that if two successive ranges E
i
and E
i+1
are identical, then the specication
of the ranges for x
i
and x
i+1
may be abbreviated to x
i
, x
i+1
in E
i
.
Also, if P(x
1
, ..., x
k
) is always true, it may be omitted.
188 SETS, SEQUENCES, AND MAPPINGS Part II
[ U | e(x
1
,...,x
k
) : x
1
in E
1
, ..., x
k
in E
k
| P(x
1
, ..., x
k
) ]
As in the previous entry, the sequence consisting of those elements e(x
1
, . . . , x
k
)
for which P(x
1
, . . . , x
k
) is true is formed, as a sequence of elements of U (an error
occurs if not all e(x
1
, . . . , x
k
) are coercible into U).
10.2.3 The Arithmetic Progression Constructors
Since enumerated sequences of integers arise so often, there are a few special constructors
to create and handle them eciently in case the entries are in arithmetic progression. The
universe must be the ring of integers. Some eort is made to preserve the special way of
storing arithmetic progressions under sequence operations.
[ i..j ]
[ U | i..j ]
The enumerated sequence of integers whose elements form the arithmetic progression
i, i + 1, i + 2, . . . , j, where i and j are (expressions dening) arbitrary integers. If j
is less than i then the empty sequence of integers will be created.
The universe U, if it is specied, has to be the ring of integers; any other universe
will lead to an error.
[ i .. j by k ]
[ U | i .. j by k ]
The enumerated sequence consisting of the integers forming the arithmetic progres-
sion i, i + k, i + 2 k, . . . , j, where i, j and k are (expressions dening) arbitrary
integers (but k ,= 0).
If k is positive then the last element in the progression will be the greatest integer
of the form i + n k that is less than or equal to j; if j is less than i, the empty
sequence of integers will be constructed.
If k is negative then the last element in the progression will be the least integer
of the form i + n k that is greater than or equal to j; if j is greater than i, the
empty sequence of integers will be constructed.
The universe U, if it is specied, has to be the ring of integers; any other universe
will lead to an error.
Example H10E1
As in the case of sets, it is possible to use the arithmetic progression constructors to save some
typing in the creation of sequences of elements of rings other than the ring of integers, but the
result will not be treated especially eciently.
> s := [ IntegerRing(200) | x : x in [ 25..125 ] ];
Ch. 10 SEQUENCES 189
10.2.4 Literal Sequences
A literal sequence is an enumerated sequence all of whose terms are from the same structure
and all of these are typed in literally. The sole purpose of literal sequences is to load
certain enumerated sequences very fast and very space-eciently; this is only useful when
reading in very large sequences (all of whose elements must have been specied literally,
that is, not as some expression other than a literal), but then it may save a lot of time.
The result will be an enumerated sequence, that is, not distinguished in any way from
other such sequences.
At present, only literal sequences of integers are supported.
\[ m
1
, ..., m
n
]
Given a succession of literal integers m
1
, . . . , m
n
, build the enumerated sequence
[m
1
, . . . , m
n
], in a time and space ecient way.
10.3 Power Sequences
The PowerSequence constructor returns a structure comprising the enumerated sequences
of a given structure R; it is mainly useful as a parent for other set and sequence con-
structors. The only operations that are allowed on power sequences are printing, testing
element membership, and coercion into the power sequence (see the examples below).
PowerSequence(R)
The structure comprising all enumerated sequences of elements of structure R. If R
itself is a sequence (or set) then the power structure of its universe is returned.
S in P
Returns true if enumerated sequence S is in the power sequence P, that is, if all
elements of the sequence S are contained in or coercible into R, where P is the
power sequence of R; false otherwise.
P ! S
Return a sequence with universe R consisting of the entries of the enumerated se-
quence S, where P is the power sequence of R. An error results if not all elements
of S can be coerced into R.
Example H10E2
> S := [ 1 .. 10 ];
> P := PowerSequence(S);
> P;
Set of sequences over [ 1 .. 10 ]
> F := [ 6/3, 12/4 ];
> F in P;
true
> G := P ! F;
190 SETS, SEQUENCES, AND MAPPINGS Part II
> Parent(F);
Set of sequences over Rational Field
> Parent(G);
Set of sequences over [ 1 .. 10 ]
10.4 Operators on Sequences
This section lists functions for obtaining information about existing sequences, for modify-
ing sequences and for creating sequences from others. Most of these operators only apply
to enumerated sequences.
10.4.1 Access Functions
#S
Returns the length of the enumerated sequence S, which is the index of the last
term of S whose value is dened. The length of the empty sequence is zero.
Parent(S)
Returns the parent structure for a sequence S, that is, the structure consisting of
all (enumerated) sequences over the universe of S.
Universe(S)
Returns the universe of the sequence S, that is, the common structure to which all
elements of the sequence belong. This universe may itself be a set or sequence. An
error is signalled when S is the null sequence.
S[i]
The i-th term s
i
of the sequence S. If i 0, or i > #S + 1, or S[i] is not dened,
then an error results. Here i is allowed to be a multi-index (see Introduction for
the interpretation). This can be used as the left hand side of an assignment: S[i]
:= x redenes the i-th term of the sequence S to be x. If i 0, then an error
results. If i > n, then the sequence [s
1
, . . . , s
n
, s
n+1
, . . . , s
i1
, x] replaces S, where
s
n+1
, . . . , s
i1
are all undened. Here i is allowed to be a multi-index.
An error occurs if x cannot be coerced into the universe of S.
Ch. 10 SEQUENCES 191
10.4.2 Selection Operators on Enumerated Sequences
Here, S denotes an enumerated sequence [s
1
, . . . , s
n
]. Further, i and j are integers or
multi-indices (see Introduction).
S[I]
The sequence [s
i
1
, . . . , s
i
r
] consisting of terms selected from the sequence S, accord-
ing to the terms of the integer sequence I. If any term of I lies outside the range 1
to #S, then an error results. If I is the empty sequence, then the empty set with
universe the same as that of S is returned.
The eect of T := S[I] diers from that of T := [ S[i] : i in I ]: if in
the rst case an undened entry occurs for i I between 1 and #S it will be copied
over; in the second such undened entries will lead to an error.
Minimum(S)
Min(S)
Given a non-empty, complete enumerated sequence S such that lt and eq are dened
on the universe of S, this function returns two values: a minimal element s in S, as
well as the rst position i such that s = S[i].
Maximum(S)
Max(S)
Given a non-empty, complete enumerated sequence S such that gt and eq are dened
on the universe of S, this function returns two values: a maximal element s in S, as
well as the rst position i such that s = S[i].
Index(S, x)
Index(S, x, f)
Position(S, x)
Position(S, x, f)
Returns either the position of the rst occurrence of x in the sequence S, or zero
if S does not contain x. The second variants of each function starts the search at
position f. This can save time in second (and subsequent) searches for the same
entry further on. If no occurrence of x in S from position f onwards is found, then
zero is returned.
Representative(R)
Rep(R)
An (arbitrary) element chosen from the enumerated sequence R
192 SETS, SEQUENCES, AND MAPPINGS Part II
Random(R)
A random element chosen from the enumerated sequence R. Every element has an
equal probability of being chosen. Successive invocations of the function will result
in independently chosen elements being returned as the value of the function. If R
is empty an error occurs.
Explode(R)
Given an enumerated sequence R of length r this function returns the r entries of
the sequence (in order).
Eltseq(R)
The enumerated sequence R itself. This function is just included for completeness.
10.4.3 Modifying Enumerated Sequences
The operations given here are available as both procedures and functions. In the procedure
version, the given sequence is destructively modied in place. This is very ecient, since
it is not necessary to make a copy of the sequence. In the function version, the given
sequence is not changed, but a modied version of it is returned. This is more suitable if
the old sequence is still required. Some of the functions also return useful but non-obvious
values.
Here, S denotes an enumerated sequence, and x an element of some structure V . The
modications involving S and x will only be successful if x can be coerced into the universe
of S; an error occurs if this fails. (See the Introduction to this Part).
Append(S, x)
Append(S, x)
Create an enumerated sequence by adding the object x to the end of S, i.e., the
enumerated sequence [s
1
, . . . s
n
, x].
There are two versions of this: a procedure, where S is replaced by the appended
sequence, and a function, which returns the new sequence. The procedural version
takes a reference S to S as an argument.
Note that the procedural version is much more ecient since the sequence S will
not be copied.
Exclude(S, x)
Exclude(S, x)
Create an enumerated sequence obtained by removing the rst occurrence of the
object x from S, i.e., the sequence [s
1
,. . . s
i1
, s
i+1
, . . ., s
n
], where s
i
is the rst
term of S that is equal to x. If x is not in S then this is just S.
There are two versions of this: a procedure, where S is replaced by the new
sequence, and a function, which returns the new sequence. The procedural version
takes a reference S to S as an argument.
Ch. 10 SEQUENCES 193
Note that the procedural version is much more ecient since the sequence S will
not be copied.
Include(S, x)
Include(S, x)
Create a sequence by adding the object x to the end of S, provided that no term of S
is equal to x. Thus, if x does not occur in S, the enumerated sequence [s
1
, . . . , s
n
, x]
is created.
There are two versions of this: a procedure, where S is replaced by the new
sequence, and a function, which returns the new sequence. The procedural version
takes a reference S to S as an argument.
Note that the procedural version is much more ecient since the sequence S will
not be copied.
Insert(S, i, x)
Insert(S, i, x)
Create the sequence formed by inserting the object x at position i in S and moving
the terms S[i], . . . , S[n] down one place, i.e., the enumerated sequence [s
1
,. . . s
i1
,
x, s
i
, . . ., s
n
]. Note that i may be bigger than the length n of S, in which case the
new length of S will be i, and the entries S[n + 1], . . . , S[i 1] will be undened.
There are two versions of this: a procedure, where S is replaced by the new
sequence, and a function, which returns the new sequence. The procedural version
takes a reference S to S as an argument.
Note that the procedural version is much more ecient since the sequence S will
not be copied.
Insert(S, k, m, T)
Insert(S, k, m, T)
Create the sequence [s
1
, . . ., s
k1
, t
1
, . . ., t
l
, s
m+1
, . . ., s
n
]. If k 0 or
k > m + 1, then an error results. If k = m + 1 then the terms of T will be
inserted into S immediately before the term s
k
. If k > n, then the sequence
[s
1
, . . . , s
n
, s
n+1
, . . . , s
k1
, t
1
, . . . , t
l
] is created, where s
n+1
, . . . , s
k1
are all unde-
ned. In the case where T is the empty sequence, terms s
k
, . . . , s
m
are deleted from
S.
There are two versions of this: a procedure, where S is replaced by the new
sequence, and a function, which returns the new sequence. The procedural version
takes a reference S to S as an argument.
Note that the procedural version is much more ecient since the sequence S will
not be copied.
194 SETS, SEQUENCES, AND MAPPINGS Part II
Prune(S)
Prune(S)
Create the enumerated sequence formed by removing the last term of the sequence
S, i.e., the sequence [s
1
, . . ., s
n1
]. An error occurs if S is empty.
There are two versions of this: a procedure, where S is replaced by the new
sequence, and a function, which returns the new sequence. The procedural version
takes a reference S to S as an argument.
Note that the procedural version is much more ecient since the sequence S will
not be copied.
Remove(S, i)
Remove(S, i)
Create the enumerated sequence formed by removing the i-th term from S, i.e., the
sequence [s
1
,. . . s
i1
, s
i+1
, . . ., s
n
]. An error occurs if i < 1 or i > n.
There are two versions of this: a procedure, where S is replaced by the new
sequence, and a function, which returns the new sequence. The procedural version
takes a reference S to S as an argument.
Note that the procedural version is much more ecient since the sequence S will
not be copied.
Reverse(S)
Reverse(S)
Create the enumerated sequence formed by reversing the order of the terms in the
complete enumerated sequence S, i.e., the sequence [s
n
, . . . , s
1
].
There are two versions of this: a procedure, where S is replaced by the new
sequence, and a function, which returns the new sequence. The procedural version
takes a reference S to S as an argument.
Note that the procedural version is much more ecient since the sequence S will
not be copied.
Rotate(S, p)
Rotate(S, p)
Given a complete sequence S and an integer p, create the enumerated sequence
formed by cyclically rotating the terms of the sequence p terms: if p is positive,
rotation will be to the right; if p is negative, S is cyclically rotated p terms to the
left; if p is zero nothing happens.
There are two versions of this: a procedure, where S is replaced by the new
sequence, and a function, which returns the new sequence. The procedural version
takes a reference S to S as an argument.
Note that the procedural version is much more ecient since the sequence S will
not be copied.
Ch. 10 SEQUENCES 195
Sort(S)
Sort(S)
Given a complete enumerated sequence S whose terms belong to a structure on which
lt and eq are dened, create the enumerated sequence formed by (quick-)sorting
the terms of S into increasing order.
There are two versions of this: a procedure, where S is replaced by the new
sequence, and a function, which returns the new sequence. The procedural version
takes a reference S to S as an argument.
Note that the procedural version is much more ecient since the sequence S will
not be copied.
Sort(S, C)
Sort(S, C, p)
Sort(S, C)
Given a complete enumerated sequence S and a comparison function C which com-
pares elements of S, create the enumerated sequence formed by sorting the terms
of S into increasing order with respect to C. The comparison function C must take
two arguments and return an integer less than, equal to, or greater than 0 accord-
ing to whether the rst argument is less than, equal to, or greater than the second
argument (e.g.: func<x, y | x - y>).
There are three versions of this: a procedure, where S is replaced by the new
sequence, a procedure, where S is replaced by the new sequence and the correspond-
ing permutation p is set, and a function, which returns the new sequence and the
corresponding permutation. The procedural version takes a reference S to S as
an argument. Note that the procedural version is much more ecient since the
sequence S will not be copied.
Undefine(S, i)
Undefine(S, i)
Create the sequence which is the same as the enumerated sequence S but with the
i-th term of S undened; i may be bigger than #S, but i 0 produces an error.
There are two versions of this: a procedure, where S is replaced by the new
sequence, and a function, which returns the new sequence. The procedural version
takes a reference S to S as an argument.
Note that the procedural version is much more ecient since the sequence S will
not be copied.
ChangeUniverse(S, V)
ChangeUniverse(S, V)
Given a sequence S with universe U and a structure V which contains U, construct
a sequence which consists of the elements of S coerced into V .
196 SETS, SEQUENCES, AND MAPPINGS Part II
There are two versions of this: a procedure, where S is replaced by the new
sequence, and a function, which returns the new sequence. The procedural version
takes a reference S to S as an argument.
Note that the procedural version is much more ecient since the sequence S will
not be copied.
CanChangeUniverse(S, V)
Given a sequence S with universe U and a structure V which contains U, attempt
to construct a sequence T which consists of the elements of S coerced into V ; if
successful, return true and T, otherwise return false.
Example H10E3
We present three ways to obtain the Farey series F
n
of degree n.
The Farey series F
n
of degree n consists of all rational numbers with denominator less than or
equal to n, in order of magnitude. Since we will need numerator and denominator often, we rst
abbreviate those functions.
> D := Denominator;
> N := Numerator;
The rst method calculates the entries in order. It uses the fact that for any three consecutive
Farey fractions
p
q
,
p
,
p
of degree n:
p
=
q + n
q
p, q
=
q + n
q
q.
> farey := function(n)
> f := [ RationalField() | 0, 1/n ];
> p := 0;
> q := 1;
> while p/q lt 1 do
> p := ( D(f[#f-1]) + n) div D(f[#f]) * N(f[#f]) - N(f[#f-1]);
> q := ( D(f[#f-1]) + n) div D(f[#f]) * D(f[#f]) - D(f[#f-1]);
> Append(~f, p/q);
> end while;
> return f;
> end function;
The second method calculates the Farey series recursively. It uses the property that F
n
may
be obtained from F
n1
by inserting a new fraction (namely
p+p
q+q
in F
n1
for which q + q
equals n.
> function farey(n)
> if n eq 1 then
> return [RationalField() | 0, 1 ];
> else
> f := farey(n-1);
Ch. 10 SEQUENCES 197
> i := 0;
> while i lt #f-1 do
> i +:= 1;
> if D(f[i]) + D(f[i+1]) eq n then
> Insert( ~f, i+1, (N(f[i]) + N(f[i+1]))/(D(f[i]) + D(f[i+1])));
> end if;
> end while;
> return f;
> end if;
> end function;
The third method is very straightforward, and uses Sort and Setseq (dened above).
> farey := func< n |
> Sort(Setseq({ a/b : a in { 0..n}, b in { 1..n} | a le b }))>;
> farey(6);
[ 0, 1/6, 1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5, 5/6, 1 ]
10.4.4 Creating New Enumerated Sequences from Existing Ones
S cat T
The enumerated sequence formed by concatenating the terms of S with the terms
of T, i.e. the sequence [s
1
, . . . , s
n
, t
1
, . . . , t
m
].
If the universes of S and T are dierent, an attempt to nd a common overstruc-
ture is made; if this fails an error results (see the Introduction).
Partition(S, p)
Given a complete non-empty sequence S as well as an integer p that divides the
length n of S, construct the sequence whose terms are the sequences formed by
taking p terms of S at a time.
Partition(S, P)
Given a complete non-empty sequence S as well as a complete sequence of positive
integers P, such that the sum of the entries of P equals the length of S, construct
the sequence whose terms are the sequences formed by taking P[i] terms of S, for
i = 1, . . . , #P.
Setseq(S)
SetToSequence(S)
Given a set S, construct a sequence whose terms are the elements of S taken in
some arbitrary order.
198 SETS, SEQUENCES, AND MAPPINGS Part II
Seqset(S)
SequenceToSet(S)
Given a sequence S, create a set whose elements are the distinct terms of S.
Example H10E4
The following example illustrates several of the access, creation and modication operations on
sequences.
Given a rational number r, this function returns a sequence of dierent integers d
i
such that
r =
1/d
i
[Bee93].
> egyptian := function(r)
> n := Numerator(r);
> d := Denominator(r);
> s := [d : i in [1..n]];
> t := { d};
> i := 2;
> while i le #s do
> c := s[i];
> if c in t then
> Remove(~s, i);
> s cat:= [c+1, c*(c+1)];
> else
> t join:= { c};
> i := i+1;
> end if;
> end while;
> return s;
> end function;
Note that the result may be rather larger than necessary:
> e := egyptian(11/13);
> // Check the result!
> &+[1/d : d in e];
11/13
> #e;
2047
> #IntegerToString(Maximum(e));
1158
while instead of this sequence of 2047 integers, the biggest of the entries having 1158 decimal
digits, the following equation also holds:
1
3
+
1
4
+
1
6
+
1
12
+
1
78
=
11
13
.
Ch. 10 SEQUENCES 199
10.4.4.1 Operations on Sequences of Booleans
The following operation work pointwise on sequences of booleans of equal length.
And(S, T)
And(S, T)
The sequence whose ith entry is the logical and of the ith entries of S and T. The
result is placed in S if it is given by reference ().
Or(S, T)
Or(S, T)
The sequence whose ith entry is the logical or of the ith entries of S and T. The
result is placed in S if it is given by reference.
Xor(S, T)
Xor(S, T)
The sequence whose ith entry is the logical xor of the ith entries of S and T. The
result is placed in S if it is given by reference.
Not(S)
Not(S)
The sequence whose ith entry is the logical not of the ith entry of S. The result is
placed in S if it is given by reference.
10.5 Predicates on Sequences
Boolean valued operators and functions on enumerated sequences exist to test whether
entries are dened (see previous section), to test for membership and containment, and to
compare sequences with respect to an ordering on its entries. On formal sequences, only
element membership can be tested.
IsComplete(S)
Boolean valued function, returning true if and only if each of the terms S[i] for
1 i #S is dened, for an enumerated sequence S.
IsDefined(S, i)
Given an enumerated sequence S and an index i, this returns true if and only if S[i]
is dened. (Hence the result is false if i > #S, but an error results if i < 1.) Note
that the index i is allowed to be a multi-index; if i = [i
1
, . . . , i
r
] is a multi-index and
i
j
> #S[i
1
, . . . , i
j1
] the function returns false, but if S is s levels deep and r > s
while i
j
#S[i
1
, . . . , i
j1
] for 1 j s, then an error occurs.
200 SETS, SEQUENCES, AND MAPPINGS Part II
IsEmpty(S)
Boolean valued function, returning true if and only if the enumerated sequence S
is empty.
IsNull(S)
Boolean valued function, returning true if and only if the enumerated sequence S
is empty and its universe is undened, false otherwise.
10.5.1 Membership Testing
Here, S and T denote sequences. The element x is always assumed to be compatible with
S.
x in S
Returns true if the object x occurs as a term of the enumerated or formal sequence
S, false otherwise. If x is not in the universe of S, coercion is attempted. If that
fails, an error results.
x notin S
Returns true if the object x does not occur as a term of the enumerated or formal
sequence S, false otherwise. If x is not in the universe of S, coercion is attempted.
If that fails, an error results.
IsSubsequence(S, T)
IsSubsequence(S, T: Kind := option)
Kind MonStgElt Default : Consecutive
Returns true if the enumerated sequence S appears as a subsequence of consecutive
elements of the enumerated sequence T, false otherwise.
By changing the default value "Consecutive" of the parameter Kind to
"Sequential" or to "Setwise", this returns true if and only if the elements of
S appear in order (but not necessarily consecutively) in T, or if and only if all ele-
ments of S appear as elements of T; so in the latter case the test is merely whether
the set of elements of S is contained in the set of elements of T.
If the universes of S and T are not the same, coercion is attempted.
S eq T
Returns true if the enumerated sequences S and T are equal, false otherwise. If
the universes of S and T are not the same, coercion is attempted.
S ne T
Returns true if the enumerated sequences S and T are not equal, false otherwise.
If the universes of S and T are not the same, coercion is attempted.
Ch. 10 SEQUENCES 201
10.5.2 Testing Order Relations
Here, S and T denote complete enumerated sequences with universe U and V respectively,
such that a common overstructure W for U and V can be found (as outlined in the
Introduction), and such that on W an ordering on the elements is dened allowing the
Magma operators eq (=), le (), lt (<), gt (>), and ge () to be invoked on its
elements.
With these comparison operators the lexicographical ordering is used to order complete
enumerated sequences. Sequences S and T are equal (S eq T) if and only if they have the
same length and all terms are the same. A sequence S precedes T (S lt T) in the ordering
imposed by that of the terms if at the rst index i where S and T dier then S[i] < T[i].
If the length of T exceeds that of S and S and T agree in all places where S until after
the length of S, then S lt T is true also. In all other cases where S ,= T one has S gt T.
S lt T
Returns true if the sequence S precedes the sequence T under the ordering induced
from S, false otherwise. Thus, true is returned if and only if either S[k] < T[k]
and S[i] = T[i] (for 1 i < k) for some k, or S[i] = T[i] for 1 i #S and
#S < #T.
S le T
Returns true if the sequence S either precedes the sequence T, under the ordering
induced from S, or is equal to T, false otherwise. Thus, true is returned if and
only if either S[k] < T[k] and S[i] = T[i] (for 1 i < k) for some k, or S[i] = T[i]
for 1 i #S and #S #T.
S ge T
Returns true if the sequence S either comes after the sequence T, under the ordering
induced from S, or is equal to T, false otherwise. Thus, true is returned if and
only if either S[k] > T[k] and S[i] = T[i] (for 1 i < k) for some k, or S[i] = T[i]
for 1 i #T and #S #T.
S gt T
Returns true if the sequence S comes after the sequence T under the ordering
induced from S, false otherwise. Thus, true is returned if and only if either
S[k] > T[k] and S[i] = T[i] (for 1 i < k) for some k, or S[i] = T[i] for 1 i #T
and #S > #T.
202 SETS, SEQUENCES, AND MAPPINGS Part II
10.6 Recursion, Reduction, and Iteration
10.6.1 Recursion
It is often very useful to be able to refer to a sequence currently under construction, for
example to dene the sequence recursively. For this purpose the Self operator is available.
Self(n)
Self()
This operator enables the user to refer to an already dened previous entry s[n] of
the enumerated sequence s inside the sequence constructor, or the sequence s itself.
Example H10E5
The example below shows how the sequence of the rst 100 Fibonacci numbers can be created
recursively, using Self. Next it is shown how to use reduction on these 100 integers.
> s := [ i gt 2 select Self(i-2)+Self(i-1) else 1 : i in [1..100] ];
> &+s;
927372692193078999175
10.6.2 Reduction
Instead of using a loop to apply the same binary associative operator to all elements of a
complete enumerated sequence, it is possible to use the reduction operator &.
& S
Given a complete enumerated sequence S = [a
1
, a
2
, . . . , a
n
] of elements belonging
to an algebraic structure U, and an (associative) operator : U U U, form the
element a
1
a
2
a
3
. . . a
n
.
Currently, the following operators may be used to reduce sequences: +, *, and,
or, join, meet, cat. An error will occur if the operator is not dened on U.
If S contains a single element a, then the value returned is a. If S is the null
sequence (empty and no universe specied), then reduction over S leads to an error;
if S is empty with universe U in which the operation is dened, then the result (or
error) depends on the operation and upon U. The following table denes the return
value:
Ch. 10 SEQUENCES 203
empty null
&+ U ! 0 error
& U ! 1 error
&and true true
&or false false
&join empty null
&meet error error
&cat empty null
10.7 Iteration
Enumerated sequences allow iteration over their elements. In particular, they can be used
as the range set in the sequence and set constructors, and as domains in for loops.
When multiple range sequences are used, it is important to know in which order the
range are iterated over; the rule is that the repeated iteration takes place as nested loops
where the rst range forms the innermost loop, etc. See the examples below.
for x in S do statements; end for;
An enumerated sequence S may be the range for the for-statement. The iteration
only enumerates the dened terms of the sequence.
Example H10E6
The rst example shows how repeated iteration inside a sequence constructor corresponds to
nesting of loops.
> [<number, letter> : number in [1..5], letter in ["a", "b", "c"]];
[ <1, a>, <2, a>, <3, a>, <4, a>, <5, a>, <1, b>, <2, b>, <3, b>, <4, b>, <5,
b>, <1, c>, <2, c>, <3, c>, <4, c>, <5, c> ]
> r := [];
> for letter in ["a", "b", "c"] do
> for number in [1..5] do
> Append(~r, <number, letter>);
> end for;
> end for;
> r;
[ <1, a>, <2, a>, <3, a>, <4, a>, <5, a>, <1, b>, <2, b>, <3, b>, <4, b>, <5,
b>, <1, c>, <2, c>, <3, c>, <4, c>, <5, c> ]
This explains why the rst construction below leads to an error, whereas the second leads to the
desired sequence.
> // The following produces an error:
> [ <x, y> : x in [0..5], y in [0..x] | x^2+y^2 lt 16 ];
^
204 SETS, SEQUENCES, AND MAPPINGS Part II
User error: Identifier x has not been declared
> [ <x, y> : x in [0..y], y in [0..5] | x^2+y^2 lt 16 ];
[ <0, 0>, <0, 1>, <1, 1>, <0, 2>, <1, 2>, <2, 2>, <0, 3>, <1, 3>, <2, 3> ]
Note the following! In the last line below there are two dierent things with the name x. One is
the (inner) loop variable, the other just an identier with value 1000 that is used in the bound for
the other (outer) loop variable y: the limited scope of the inner loop variable x makes it invisible
to y, whence the error in the rst case.
> // The following produces an error:
> #[ <x, y> : x in [0..5], y in [0..x] | x^2+y^2 lt 100 ];
^
User error: Identifier x has not been declared
> x := 1000;
> #[ <x, y> : x in [0..5], y in [0..x] | x^2+y^2 lt 100 ];
59
10.8 Bibliography
[Bee93] L. Beeckmans. The splitting algorithm for Egyptian fractions. J. Number Th.,
43:173185, 1993.
11 TUPLES AND CARTESIAN PRODUCTS
11.1 Introduction . . . . . . . . 207
11.2 Cartesian Product Constructor
and Functions . . . . . . . . 207
car< > 207
CartesianProduct(R, S) 207
CartesianProduct(L) 207
CartesianPower(R, k) 207
Flat(C) 207
NumberOfComponents(C) 208
Component(C, i) 208
C[i] 208
# 208
Rep(C) 208
Random(C) 208
11.3 Creating and Modifying Tuples 208
elt< > 208
! 208
< a
1
, a
2
, ..., a
k
> 208
Append(T, x) 208
Append(T, x) 209
Prune(T) 209
Prune(T) 209
Flat(T) 209
11.4 Tuple Access Functions . . . 210
Parent(T) 210
# 210
T[i] 210
Explode(T) 210
TupleToList(T) 210
Tuplist(T) 210
11.5 Equality . . . . . . . . . . 210
eq 210
ne 210
Chapter 11
TUPLES AND CARTESIAN PRODUCTS
11.1 Introduction
A cartesian product may be constructed from a nite number of factors, each of which
may be a set or algebraic structure. The term tuple will refer to an element of a cartesian
product.
Note that the rules for tuples are quite dierent to those for sequences. Sequences are
elements of a cartesian product of n copies of a xed set (or algebraic structure) while tuples
are elements of cartesian products where the factors may be dierent sets (structures). The
semantics for tuples are quite dierent to those for sequences. In particular, the parent
cartesian product of a tuple is xed once and for all. This is in contrast to a sequence, which
may grow and shrink during its life (thus implying a varying parent cartesian product).
11.2 Cartesian Product Constructor and Functions
The special constructor car< ... > is used for the creation of cartesian products of
structures.
car< R
1
, ..., R
k
>
Given a list of sets or algebraic structures R
1
, . . . , R
k
, construct the cartesian prod-
uct set R
1
R
k
.
CartesianProduct(R, S)
Given structures R and S, construct the cartesian product set R S. This is the
same as calling the car constructor with the two arguments R and S.
CartesianProduct(L)
Given a sequence or tuple L of structures, construct the cartesian product of the
elements of L.
CartesianPower(R, k)
Given a structure R and an integer k, construct the cartesian power set R
k
Flat(C)
Given a cartesian product C of structures which may themselves be cartesian prod-
ucts, return the cartesian product of the base structures, considered in depth-rst
order (see Flat for the element version).
208 SETS, SEQUENCES, AND MAPPINGS Part II
NumberOfComponents(C)
Given a cartesian product C, return the number of components of C.
Component(C, i)
C[i]
The i-th component of C.
#C
Given a cartesian product C, return the cardinality of C.
Rep(C)
Given a cartesian product C, return a representative of C.
Random(C)
Given a cartesian product C, return a random element of C.
Example H11E1
We create the product of Q and Z.
> C := car< RationalField(), Integers() >;
> C;
Cartesian Product<Rational Field, Ring of Integers>
11.3 Creating and Modifying Tuples
elt< C | a
1
, a
2
, ..., a
k
>
C ! < a
1
, a
2
, ..., a
k
>
Given a cartesian product C = R
1
R
k
and a sequence of elements
a
1
, a
2
, . . . , a
k
, such that a
i
belongs to the set R
i
(i = 1, . . . , k), create the tuple
T =< a
1
, a
2
, ..., a
k
> of C.
< a
1
, a
2
, ..., a
k
>
Given a cartesian product C = R
1
R
k
and a list of elements a
1
, a
2
, . . . , a
k
, such
that a
i
belongs to the set R
i
, (i = 1, . . . , k), create the tuple T =< a
1
, a
2
, ..., a
k
>
of C. Note that if C does not already exist, it will be created at the time this
expression is evaluated.
Append(T, x)
Return the tuple formed by adding the object x to the end of the tuple T. Note
that the result lies in a new cartesian product of course.
Ch. 11 TUPLES AND CARTESIAN PRODUCTS 209
Append(T, x)
(Procedure.) Destructively add the object x to the end of the tuple T. Note that
the new T lies in a new cartesian product of course.
Prune(T)
Return the tuple formed by removing the last term of the tuple T. The length of
T must be greater than 1. Note that the result lies in a new cartesian product of
course.
Prune(T)
(Procedure.) Destructively remove the last term of the tuple T. The length of T
must be greater than 1. Note that the new T lies in a new cartesian product of
course.
Flat(T)
Construct the attened version of the tuple T. The attening is done in the same
way as Flat, namely depth-rst.
Example H11E2
We build a set of pairs consisting of primes and their reciprocals.
> C := car< Integers(), RationalField() >;
> C ! < 26/13, 13/26 >;
<2, 1/2>
> S := { C | <p, 1/p> : p in [1..25] | IsPrime(p) };
> S;
{ <5, 1/5>, <7, 1/7>, <2, 1/2>, <19, 1/19>, <17, 1/17>, <23, 1/23>, <11, 1/11>,
<13, 1/13>, <3, 1/3> }
210 SETS, SEQUENCES, AND MAPPINGS Part II
11.4 Tuple Access Functions
Parent(T)
The cartesian product to which the tuple T belongs.
#T
Number of components of the tuple T.
T[i]
Return the i-th component of tuple T. Note that this indexing can also be used on
the left hand side for modication of T.
Explode(T)
Given a tuple T of length n, this function returns the n entries of T (in order).
TupleToList(T)
Tuplist(T)
Given a tuple T return a list containing the entries of T.
Example H11E3
> f := < 11/2, 13/3, RootOfUnity(3, CyclotomicField(3)) >;
> f;
<11/2, 13/3, (zeta_3)>
> #f;
3
> Parent(f);
Cartesian Product<Rational Field, Rational Field, Cyclotomic field Q(zeta_3)>
> f[1]+f[2]+f[3];
(1/6) * (59 + 6*zeta_3)
> f[3] := 7;
> f;
<11/2, 13/3, 7>
11.5 Equality
T eq U
Return true if and only if the tuples T and U are equal.
T ne U
Return true if and only if the tuples T and U are distinct.
12 LISTS
12.1 Introduction . . . . . . . . 213
12.2 Construction of Lists . . . . 213
[* *] 213
[* e
1
, e
2
, ..., e
n
*] 213
12.3 Creation of New Lists . . . . 213
cat 213
cat:= 213
Append(S, x) 213
Append(S, x) 213
Insert(S, i, x) 214
Insert(S, i, x) 214
Prune(S) 214
Prune(S) 214
SequenceToList(Q) 214
Seqlist(Q) 214
TupleToList(T) 214
Tuplist(T) 214
Reverse(L) 214
12.4 Access Functions . . . . . . 214
# 214
IsEmpty(S) 214
S[i] 214
IsDefined(L, i) 215
12.5 Assignment Operator . . . . 215
S[i] := x 215
Chapter 12
LISTS
12.1 Introduction
A list in Magma is an ordered nite collection of objects. Unlike sequences, lists are
not required to consist of objects that have some common parent. Lists are not stored
compactly and the operations provided for them are not extensive. They are mainly
provided to enable the user to gather assorted objects temporarily together.
12.2 Construction of Lists
Lists can be constructed by expressions enclosed in special brackets [* and *].
[* *]
The empty list.
[* e
1
, e
2
, ..., e
n
*]
Given a list of expressions e
1
, . . . , e
n
, dening elements a
1
, a
2
, . . . , a
n
, create the list
containing a
1
, a
2
, . . . , a
n
.
12.3 Creation of New Lists
Here, S denotes the list [ s
1
, . . . , s
n
], while T denotes the list [ t
1
, . . . , t
m
].
S cat T
The list formed by concatenating the terms of the list S with the terms of the list
T, i.e. the list [ s
1
, . . . , s
n
, t
1
, . . . , t
m
].
S cat:= T
(Procedure.) Destructively concatenate the terms of the list T to S; i.e. so S becomes
the list [ s
1
, . . . , s
n
, t
1
, . . . , t
m
].
Append(S, x)
The list formed by adding the object x to the end of the list S, i.e. the list
[ s
1
, . . . s
n
, x ].
Append(S, x)
(Procedure.) Destructively add the object x to the end of the list S; i.e. so S
becomes the list [ s
1
, . . . s
n
, x ].
214 SETS, SEQUENCES, AND MAPPINGS Part II
Insert(S, i, x)
Insert(S, i, x)
Create the list formed by inserting the object x at position i in S and moving the
terms S[i], . . . , S[n] down one place, i.e., the list [ s
1
, . . . , s
i1
, x, s
i
, . . . , s
n
]. Note
that i must not be bigger than n + 1 where n is the length of S.
There are two versions of this: a procedure, where S is replaced by the new list,
and a function, which returns the new list. The procedural version takes a reference
S to S as an argument.
Note that the procedural version is much more ecient since the list S will not
be copied.
Prune(S)
The list formed by removing the last term of the list S, i.e. the list [ s
1
, . . ., s
n1
].
Prune(S)
(Procedure.) Destructively remove the last term of the list S; i.e. so S becomes the
list [ s
1
, . . ., s
n1
].
SequenceToList(Q)
Seqlist(Q)
Given a sequence Q, construct a list whose terms are the elements of Q taken in the
same order.
TupleToList(T)
Tuplist(T)
Given a tuple T, construct a list whose terms are the elements of T taken in the
same order.
Reverse(L)
Given a list L return the same list, but in reverse order.
12.4 Access Functions
#S
The length of the list S.
IsEmpty(S)
Return whether S is empty (has zero length).
S[i]
The i-th term of the list S. If either i 0 or i > #S + 1, then an error results.
Here i is allowed to be a multi-index (see Introduction for the interpretation).
Ch. 12 LISTS 215
IsDefined(L, i)
Checks weather the ith item in L is dened or not, that is it returns true if i is at
most the length of L and false otherwise.
12.5 Assignment Operator
S[i] := x
Redene the i-th term of the list S to be x. If i 0, then an error results. If
i = #S + 1, then x is appended to S. Otherwise, if i > #S + 1, an error results.
Here i is allowed to be a multi-index.
13 COPRODUCTS
13.1 Introduction . . . . . . . . 219
13.2 Creation Functions . . . . . 219
13.2.1 Creation of Coproducts . . . . . 219
cop< > 219
cop< > 219
13.2.2 Creation of Coproduct Elements . 219
m(e) 219
! 219
13.3 Accessing Functions . . . . . 220
Injections(C) 220
# 220
Constituent(C, i) 220
Index(x) 220
13.4 Retrieve . . . . . . . . . . 220
Retrieve(x) 220
13.5 Flattening . . . . . . . . . 221
Flat(C) 221
13.6 Universal Map . . . . . . . 221
UniversalMap(C, S, [ n
1
, ..., n
m
]) 221
Chapter 13
COPRODUCTS
13.1 Introduction
Coproducts can be useful in various situations, as they may contain objects of entirely
dierent types. Although the coproduct structure will serve as a single parent for such
diverse objects, the proper parents of the elements are recorded internally and restored
whenever the element is retrieved from the coproduct.
13.2 Creation Functions
There are two versions of the coproduct constructor. Ordinarily, coproducts will be con-
structed from a list of structures. These structures are called the constituents of the
coproduct. A single sequence argument is allowed as well to be able to create coproducts
of parameterized families of structures conveniently.
13.2.1 Creation of Coproducts
cop< S
1
, S
2
, ..., S
k
>
cop< [ S
1
, S
2
, ..., S
k
] >
Given a list or a sequence of two or more structures S
1
, S
2
, . . ., S
k
, this function
creates and returns their coproduct C as well as a sequence of maps [m
1
, m
2
, . . .,
m
k
] that provide the injections m
i
: S
i
C.
13.2.2 Creation of Coproduct Elements
Coproduct elements are usually created by the injections returned as the second return
value from the cop<> constructor. The bang (!) operator may also be used but only if the
type of the relevant constituent is unique for the particular coproduct.
m(e)
Given a coproduct injection map m and an element of one of the constituents of the
coproduct C, create the coproduct element version of e.
C ! e
Given a coproduct C and an element e of one of the constituents of C such that
the type of that constituent is unique within that coproduct, create the coproduct
element version of e.
220 SETS, SEQUENCES, AND MAPPINGS Part II
13.3 Accessing Functions
Injections(C)
Given a coproduct C, return the sequence of injection maps returned as the second
argument from the cop<> constructor.
#C
Given a coproduct C, return the length (number of constituents) of C.
Constituent(C, i)
Given a coproduct C and an integer i between 1 and the length of C, return the
i-th constituent of C.
Index(x)
Given an element x from a coproduct C, return the constituent number of C to
which x belongs.
13.4 Retrieve
The function described here restores an element of a coproduct to its original state.
Retrieve(x)
Given an element x of some coproduct C, return the element as an element of the
structure that formed its parent before it was mapped into C.
Example H13E1
We illustrate basic uses of the coproduct constructors and functions.
> C := cop<IntegerRing(), Strings()>;
> x := C ! 5;
> y := C ! "abc";
> x;
5
> y;
abc
> Parent(x);
Coproduct<Integer Ring, String structure>
> x eq 5;
true
> x eq y;
false
> Retrieve(x);
5
> Parent(Retrieve(x));
Integer Ring
Ch. 13 COPRODUCTS 221
13.5 Flattening
The function described here enables the concatenation of coproducts into a single one.
Flat(C)
Given a coproduct C of structures which may themselves be coproducts, return the
coproduct of the base structures, considered in depth-rst order.
13.6 Universal Map
UniversalMap(C, S, [ n
1
, ..., n
m
])
Given maps n
1
, . . ., n
m
from structures S
1
, . . ., S
m
that compose the coproduct C,
to some structure S, this function returns the universal map C S.
14 RECORDS
14.1 Introduction . . . . . . . . 225
14.2 The Record Format Constructor 225
recformat< > 225
14.3 Creating a Record . . . . . . 226
rec< > 226
14.4 Access and Modication
Functions . . . . . . . . . 227
Format(r) 227
Names(F) 227
Names(r) 227
reldname 227
reldname:= e; 227
delete 227
assigned 227
rs 227
Chapter 14
RECORDS
14.1 Introduction
In a record several objects can be collected. The objects in a record are stored in record
elds, and are accessed by using eldnames. Records are like tuples (and unlike sets or
sequences) in that the objects need not all be of the same kind. Though records and
tuples are somewhat similar, there are several dierences too. The components of tuples
are indexed by integers, and every component must be dened. The elds of records are
indexed by eldnames, and it is possible for some (or all) of the elds of a record not to
be assigned; in fact, a eld of a record may be assigned or deleted at any time. A record
must be constructed according to a pre-dened record format, whereas a tuple may be
constructed without rst giving the Cartesian product that is its parent, since Magma
can deduce the parent from the tuple.
In the denition of a record format, each eld is given a eldname. If the eld is also
given a parent magma or a category, then in any record created according to this format,
that eld must conform to this requirement. However, if the eld is not given a parent
magma or category, there is no restriction on the kinds of values stored in that eld;
dierent records in the format may contain disparate values in that eld. By contrast,
every component of a Cartesian product is a magma, and the components of all tuples in
this product must be elements of the corresponding magma.
Because of the exibility of records, with respect to whether a eld is assigned and what
kind of value is stored in it, Boolean operators are not available for comparing records.
14.2 The Record Format Constructor
The special constructor recformat< ... > is used for the creation of record formats. A
record format must be created before records in that format are created.
recformat< L >
(and optional parents or categories) in L
Construct the record format corresponding to the non-empty eldname list L. Each
term of L must be one of the following:
(a) eldname in which case there is no restriction on values that may be stored in
this eld of records having this format;
(b)eldname:expression where the expression evaluates to a magma which will be
the parent of values stored in this eld of records having this format; or
(c) eldname:expression where the expression evaluates to a category which will
be the category of values stored in this eld of records having this format;
where eldname consists of characters that would form a valid identier name. Note
that it is not a string.
226 SETS, SEQUENCES, AND MAPPINGS Part II
Example H14E1
We create a record format with these elds: n, an integer; misc, which has no restrictions; and
seq, a sequence (with any universe possible).
> RF := recformat< n : Integers(), misc, seq : SeqEnum >;
> RF;
recformat<n: IntegerRing(), misc, seq: SeqEnum>
> Names(RF);
[ n, misc, seq ]
14.3 Creating a Record
Before a record is created, its record format must be dened. A record may be created by
assigning as few or as many of the record elds as desired.
rec< F | L >
Given a record format F, construct the record format corresponding to the eld
assignment list L. Each term of L must be of the form eldname : = expression
where eldname is in F and the value of the expression conforms (directly or by
coercion) to any restriction on it. The list L may be empty, and there is no xed
order for the eldnames.
Example H14E2
We build some records having the record format RF.
> RF := recformat< n : Integers(), misc, seq : SeqEnum >;
> r := rec< RF | >;
> r;
rec<RF | >
> s := rec< RF | misc := "adsifaj", n := 42, seq := [ GF(13) | 4, 8, 1 ]>;
> s;
rec<RF | n := 42, misc := adsifaj, seq := [ 4, 8, 1 ]>
> t := rec< RF | seq := [ 4.7, 1.9 ], n := 51/3 >;
> t;
rec<RF | n := 17, seq := [ 4.7, 1.9 ]>
> u := rec< RF | misc := RModule(PolynomialRing(Integers(7)), 4) >;
> u;
rec<RF | misc := RModule of dimension 4 with base ring Univariate Polynomial
Algebra over Integers(7)>
Ch. 14 RECORDS 227
14.4 Access and Modication Functions
Fields of records may be inspected, assigned and deleted at any time.
Format(r)
The format of record r.
Names(F)
The eldnames of the record format F returned as a sequence of strings.
Names(r)
The eldnames of record r returned as a sequence of strings.
reldname
Return the eld of record r with this eldname. The format of r must include this
eldname, and the eld must be assigned in r.
reldname:= expression;
Reassign the given eld of r to be the value of the expression. The format of r
must include this eldname, and the expressions value must satisfy (directly or by
coercion) any restriction on the eld.
delete reldname
(Statement.) Delete the current value of the given eld of record r.
assigned reldname
Returns true if and only if the given eld of record r currently contains a value.
rs
Given an expression s that evaluates to a string, return the eld of record r with the
eldname corresponding to this string. The format of r must include this eldname,
and the eld must be assigned in r.
This syntax may be used anywhere that reldname may be used, including in
left hand side assignment, assigned and delete.
228 SETS, SEQUENCES, AND MAPPINGS Part II
Example H14E3
> RF := recformat< n : Integers(), misc, seq : SeqEnum >;
> r := rec< RF | >;
> s := rec< RF | misc := "adsifaj", n := 42, seq := [ GF(13) | 4, 8, 1 ]>;
> t := rec< RF | seq := [ 4.7, 1.9 ], n := 51/3 >;
> u := rec< RF | misc := RModule(PolynomialRing(Integers(7)), 4) >;
> V4 := umisc;
> assigned rseq;
false
> rseq := Append(tseq, tn); assigned rseq;
true
> r;
rec<RF | seq := [ 4.7, 1.9, 17 ]>
> // The following produces an error:
> t(smisc);
>> t(smisc);
^
Runtime error in : Field adsifaj does not exist in this record
> delete u("m" cat "isc"); u;
rec<RF | >
15 MAPPINGS
15.1 Introduction . . . . . . . . 231
15.1.1 The Map Constructors . . . . . . 231
15.1.2 The Graph of a Map . . . . . . . 232
15.1.3 Rules for Maps . . . . . . . . . 232
15.1.4 Homomorphisms . . . . . . . . 232
15.1.5 Checking of Maps . . . . . . . . 232
15.2 Creation Functions . . . . . 233
15.2.1 Creation of Maps . . . . . . . . 233
map< > 233
map< > 233
map< > 233
15.2.2 Creation of Partial Maps . . . . . 234
pmap< > 234
pmap< > 234
pmap< > 234
15.2.3 Creation of Homomorphisms . . . 234
hom< > 234
hom< > 234
hom< > 234
hom< > 235
pmap< > 235
15.2.4 Coercion Maps . . . . . . . . . 235
Coercion(D, C) 235
Bang(D, C) 235
15.3 Operations on Mappings . . . 235
15.3.1 Composition . . . . . . . . . . 235
* 235
Components(f) 235
15.3.2 (Co)Domain and (Co)Kernel . . . 236
Domain(f) 236
Codomain(f) 236
Image(f) 236
Kernel(f) 236
15.3.3 Inverse . . . . . . . . . . . . . 236
Inverse(m) 236
15.3.4 Function . . . . . . . . . . . . 236
Function(f) 236
15.4 Images and Preimages . . . . 237
@ 237
f(a) 237
@ 237
f(S) 237
@ 237
f(C) 237
@@ 237
@@ 237
@@ 237
HasPreimage(x, f) 237
15.5 Parents of Maps . . . . . . . 238
Parent(m) 238
Domain(P) 238
Codomain(P) 238
Maps(D, C) 238
Iso(D, C) 238
Aut(S) 238
Chapter 15
MAPPINGS
15.1 Introduction
Mappings play a fundamental role in algebra and, indeed, throughout mathematics. Re-
ecting this importance, mappings are one of the fundamental datatypes in our language.
The most general way to dene a mapping f : A B in a programming language is
to write a function which, given any element of A, will return its image under f in B.
While this approach to the denition of mappings is completely general, it is desirable to
have mappings as an independent datatype. It is then possible to provide a very compact
notation for specifying important classes of mappings such as homomorphisms. Further, a
range of operations peculiar to the mapping type can be provided.
Mappings are created either through use of mapping constructors as described in this
Chapter, or through use of certain standard functions that return mappings as either
primary or secondary values.
All mappings are objects in the Magma category Map.
15.1.1 The Map Constructors
There are three main mapping constructors: the general map constructor map< >, the ho-
momorphism constructor hom< >, and the partial map constructor pmap< >. The general
form of all constructors is the same: inside the angle brackets there are two components
separated by a pipe |. To the left the user species a domain A and a codomain B, sepa-
rated by ->; to the right of the pipe the user species how images are obtained for elements
of the domain. The latter can be done in one of several ways: one species either the graph
of the map, or a rule describing how images are to be formed, or for homomorphisms, one
species generator images. We will describe each in the next subsections. The result is
something like map< A -> B | expression>.
The domain and codomain of the map can be arbitrary magmas. When a full map
(as opposed to a partial map) is constructed by use of a graph, the domain is necessarily
nite.
The main dierence between maps and partial maps is that a partial map need not be
dened for every element of the domain. The main dierence between these two types of
map and homomorphisms is that the latter are supposed to provide structure-preserving
maps between algebraic structures. On the one hand this makes it possible to allow the
specication of images for homomorphisms in a dierent fashion: homomorphism can be
given via images for generators of the domain. On the other hand homomorphisms are
restricted to cases where domain and (image in the) codomain have a similar structure.
The generator image form only makes sense for domains that are nitely presented. Ho-
momorphisms are described in more detail below.
232 SETS, SEQUENCES, AND MAPPINGS Part II
15.1.2 The Graph of a Map
Let A and B be structures. A subgraph of the cartesian product C = AB is a subset G
of C such that each element of A appears at most once among the rst components of the
pairs < a, b > of G. A subgraph having the additional property that every element of A
appears as the rst component of some pair < a, b > of G is called a graph of AB.
A mapping between A and B can be identied with a graph G of AB, a partial map
can be identied with a subgraph. We now describe how a graph may be represented in
the context of the map constructor. An element of the graph of AB can be given either
as a tuple <a, b>, or as an arrow pair a -> b. The specication of a (sub)graph in a map
constructor should then consist of either a (comma separated) list, a sequence, or a set of
such tuples or arrow pairs (a mixture is permitted).
15.1.3 Rules for Maps
The specication of a rule in the map constructor involves a free variable and an expression,
usually involving the free variable, separated by :->, for example x :-> 3*x - 1. The
scope of the free variable is restricted to the map constructor (so the use of x does not
interfere with values of x outside the constructor). A general expression is allowed in the
rule, which may involve intrinsic or user functions, and even in-line denitions of such
functions.
15.1.4 Homomorphisms
Probably the most useful form of the map-constructor is the version for homomorphisms.
Most interesting mappings in algebra are homomorphisms, and if an algebraic structure
A belongs to a family of algebraic structures which form a variety we have the fundamen-
tal result that a homomorphism is uniquely determined by the images of any generating
set. This provides us with a particularly compact way of dening and representing homo-
morphisms. While the syntax of the homomorphism constructor is similar to that of the
general mapping constructor, the semantics are sometimes dierent.
The kind of homomorphism built by the hom-constructor is determined entirely by the
domain: thus, a group homomorphism results from applying hom to a domain A that is
one of the types of group in Magma, a ring homomorphism results when A is a ring, etc.
As a consequence, the requirements on the specication of homomorphisms are dependent
on the category to which A belongs. Often, the codomain of a homomorphism is required
to belong to the same variety. But even within a category the specication may depend
on the type of structure; for details we refer the reader to the specic chapters.
A homomorphism can be specied using either a rule map or by generator images. In
the latter case the processor will seek to express an element as a word in the generators of
A when asked to compute its image. Thus A needs to be nitely presented.
15.1.5 Checking of Maps
It should be pointed out that checking the correctness of mappings can be done to a
limited extent only. If the mapping is given by means of a graph, Magma will check
that no multiple images are specied, and that an image is given for every element of the
Ch. 15 MAPPINGS 233
domain (unless a partial map is dened). If a rule is given, it cannot be checked that it is
dened on all of the domain. Also, it is in general the responsibility of the user to ensure
that the images provided for a hom constructor do indeed dene a homomorphism.
15.2 Creation Functions
In this section we describe the creation of maps, partial maps, and homomorphisms via the
various forms of the constructors, as well as maps that dene coercions between algebraic
structures.
15.2.1 Creation of Maps
Maps between structures A and B may be specied either by providing the full graph (as
dened in the previous section) or by supplying an expression rule for nding images.
map< A -> B | G >
Given a nite structure A, a structure B and a graph G of A B, construct the
mapping f : A B, as dened by G. The graph G may be given by either a set,
sequence, or list of tuples or arrow-pairs as described in the Introduction to this
Chapter. Note that G must be a full graph, i.e., every element of A must occur
exactly once as a rst component.
map< A -> B | x :-> e(x) >
Given a set or structure A, a set or structure B, a variable x and an expression e(x),
usually involving x, construct the mapping f : A B, as dened by e(x). It is the
users responsibility to ensure that a value is dened for every x A. The scope of
the variable x is restricted to the map-constructor.
map< A -> B | x :-> e(x), y :-> i(y) >
Given a set or structure A, a set or structure B, a variable x, an expression e(x),
usually involving x, a variable y, and an expression i(y), usually involving y, con-
struct the mapping f : A B, as dened by x e(x), with corresponding inverse
f
1
: B A, as dened by y i(y). It is the users responsibility to ensure that
a value e(x) is dened for every x A, a value i(y) is dened for every y B, and
that i(y) is the true inverse of e(x). The scope of the variables x and y is restricted
to the map-constructor.
234 SETS, SEQUENCES, AND MAPPINGS Part II
15.2.2 Creation of Partial Maps
Partial mappings are quite dierent to both general mappings and homomorphisms, in
that images need not be dened for every element of the domain.
pmap< A -> B | G >
Given a nite structure A of cardinality n, a structure B and a subgraph G of AB,
construct the partial map f : A B, as dened by G. The subgraph G may be
given by either a set, sequence, or list of tuples or arrow-pairs as described in the
Introduction to this Chapter.
pmap< A -> B | x :-> e(x) >
Given a set A, a set B, a variable x and an expression e(x), construct the partial map
f : A B, as dened by e(x). This form of the map constructor is a special case of
the previous one whereby the image of x can be dened using a single expression.
Again the scope of x is restricted to the map-constructor.
pmap< A -> B | x :-> e(x), y :-> i(y) >
This constructor is the same as the map constructor above which allows the inverse
map i(y) to be specied, except that the result is marked to be a partial map.
15.2.3 Creation of Homomorphisms
The principal construction for homomorphisms consists of the generator image form, where
the images of the generators of the domain are listed. Note that the kind of homomorphism
and the kind and number of generators for which images are expected, depend entirely on
the type of the domain. Moreover, some features of the created homomorphism, e.g.
whether checking of the homomorphism is done during creation or whether computing
preimages is possible, depend on the types of the domain and the codomain. We refer to
the appropriate handbook chapters for further information.
hom< A -> B | G >
Given a nitely generated algebraic structure A and a structure B, as well as a
graph G of A B, construct the homomorphism f : A B dened by extending
the map of the generators of A to all of A. The graph G may be given by either
a set, sequence, or list of tuples or arrow-pairs as described in the Introduction to
this Chapter.
The detailed requirements on the specication are module dependent, and can
be found in the chapter describing the domain A.
hom< A -> B | y
1
, ..., y
n
>
hom< A -> B | x
1
-> y
1
, ..., x
n
-> y
n
>
This is a module dependent constructor for homomorphisms between structures A
and B; see the chapter describing the functions for A. In general after the bar the
images for all generators of the structure A must be specied.
Ch. 15 MAPPINGS 235
hom< A -> B | x :-> e(x) >
Given a structure A, a structure B, a variable x and an expression e(x), construct
the homomorphism f : A B, as dened by e(x). This form of the map constructor
is a special case of the previous one whereby the image of x can be dened using a
single expression. Again the scope of x is restricted to the map-constructor.
pmap< A -> B | x :-> e(x), y :-> i(y) >
This constructor is the same as the map constructor above which allows the inverse
map i(y) to be specied, except that the result is marked to be a homomorphism.
15.2.4 Coercion Maps
Magma has a sophisticated machinery for coercion of elements into structures other than
the parent. Non-automatic coercion is usually performed via the ! operator. To obtain
the coercion map corresponding to ! in a particular instance the Coercion function can
be used.
Coercion(D, C)
Bang(D, C)
Given structures D and C such that elements from D can be coerced into C, return
the map m that performs this coercion. Thus the domain of m will be D and the
codomain will be C.
15.3 Operations on Mappings
15.3.1 Composition
Although compatible maps can be composed by repeated application, say g(f(x)), it is
also possible to create a composite map.
f * g
Given a mapping f : A B, and a mapping g : B C, construct the composition
h of the mappings f and g as the mapping h = g f : A C.
Components(f)
Returns the maps which were composed to form f.
236 SETS, SEQUENCES, AND MAPPINGS Part II
15.3.2 (Co)Domain and (Co)Kernel
The domain and codomain of any map can simply be accessed. Only for some intrinsic
maps and for maps with certain domains and codomains, also the formation of image,
kernel and cokernel is available.
Domain(f)
The domain of the mapping f.
Codomain(f)
The codomain of the mapping f.
Image(f)
Given a mapping f with domain A and codomain B, return the image of A in B
as a substructure of B. This function is currently supported only for some intrinsic
maps and for maps with certain domains and codomains.
Kernel(f)
Given the homomorphism f with domain A and codomain B, return the kernel of f
as a substructure of A. This function is currently supported only for some intrinsic
maps and for maps with certain domains and codomains.
15.3.3 Inverse
Inverse(m)
The inverse map of the map m.
15.3.4 Function
For a map given by a rule, it is possible to get access to the rule as a user dened function.
Function(f)
The function underlying the mapping f. Only available if f has been dened by
the user by means of a rule map (i. e., an expression for the image under f of an
arbitrary element of the domain).
Ch. 15 MAPPINGS 237
15.4 Images and Preimages
The standard mathematical notation is used to denote the calculation of a map image.
Some mappings dened by certain system intrinsics and constructors permit the taking of
preimages. However, preimages are not available for any mapping dened by means of the
mapping constructor.
a @ f
f(a)
Given a mapping f with domain A and codomain B, and an element a belonging
to A, return the image of a under f as an element of B.
S @ f
f(S)
Given a mapping f with domain A and codomain B, and a nite enumerated set,
indexed set, or sequence S of elements belonging to A, return the image of S under
f as an enumerated set, indexed set, or sequence of elements of B.
C @ f
f(C)
Given a homomorphism f with domain A and codomain B, and a substructure C
of A, return the image of C under f as a substructure of B.
y @@ f
Given a mapping f with domain A and codomain B, where f supports preimages,
and an element y belonging to B, return the preimage of y under f as an element
of A.
If the mapping f is a homomorphism, then a single element is returned as the
preimage of y. In order to obtain the full preimage of y, it is necessary to form the
coset K y@@f, where K is the kernel of f.
R @@ f
Given a mapping f with domain A and codomain B, where f supports preimages,
and a nite enumerated set, indexed set, or sequence of elements R belonging to B,
return the preimage of R under f as an enumerated set, indexed set, or sequence of
elements of A.
D @@ f
Given a mapping f with domain A and codomain B, where f supports preimages
and the kernel of f is known or can be computed, and a substructure D of B, return
the preimage of D under f as a substructure of A.
HasPreimage(x, f)
Return whether the preimage of x under f can be taken and the preimage as a
second argument if it can.
238 SETS, SEQUENCES, AND MAPPINGS Part II
15.5 Parents of Maps
Parents of maps are structures knowing a domain and a codomain. They are often used in
automorphism group calculations where a map is returned from an automorphism group
into the set of all automorphisms of some structure. Parents of maps all inherit from the
type PowMap. The type PowMapAut which inherits from PowMap is type which the parents
of automorphisms inherit from.
There is also a power structure of maps (of type PowStr, similar to that of other
structures) which is used as a common overstructure of the dierent parents.
Parent(m)
The parent of m.
Domain(P)
Codomain(P)
The domain and codomain of the maps for which P is the parent.
Maps(D, C)
Iso(D, C)
The parent of maps (or isomorphisms) from D to C. Iso will only return a dierent
structure to Maps if it has been specically implemented for such maps.
Aut(S)
The parent of automorphisms of S.
PART III
SEMIGROUPS AND MONOIDS
16 FINITELY PRESENTED SEMIGROUPS 241
17 MONOIDS GIVEN BY REWRITE SYSTEMS 253
16 FINITELY PRESENTED SEMIGROUPS
16.1 Introduction . . . . . . . . 243
16.2 The Construction of Free Semi-
groups and their Elements . . 243
16.2.1 Structure Constructors . . . . . . 243
FreeSemigroup(n) 243
FreeMonoid(n) 243
16.2.2 Element Constructors . . . . . . 244
! 244
Id(M) 244
! 244
16.3 Elementary Operators for Words 244
16.3.1 Multiplication and Exponentiation . 244
* 244
^ 244
! 244
16.3.2 The Length of a Word . . . . . . 244
# 244
16.3.3 Equality and Comparison . . . . 245
eq 245
ne 245
lt 245
le 245
ge 245
gt 245
IsOne(u) 245
16.4 Specication of a Presentation 246
16.4.1 Relations . . . . . . . . . . . . 246
= 246
LHS(r) 246
RHS(r) 246
16.4.2 Presentations . . . . . . . . . . 246
Semigroup< > 246
Monoid< > 247
16.4.3 Accessing the Dening Generators and
Relations . . . . . . . . . . . . 247
. 247
Generators(S) 247
NumberOfGenerators(S) 247
Ngens(S) 247
Parent(u) 247
Relations(S) 248
16.5 Subsemigroups, Ideals and Quo-
tients . . . . . . . . . . . 248
16.5.1 Subsemigroups and Ideals . . . . 248
sub< > 248
ideal< > 248
lideal< > 248
rideal< > 248
16.5.2 Quotients . . . . . . . . . . . 249
quo< > 249
/ 249
16.6 Extensions . . . . . . . . . 249
DirectProduct(R, S) 249
FreeProduct(R, S) 249
16.7 Elementary Tietze
Transformations . . . . . . . 250
AddRelation(S, r) 250
AddRelation(S, r, i) 250
DeleteRelation(S, r) 250
DeleteRelation(S, i) 250
ReplaceRelation(S, r
1
, r
2
) 250
ReplaceRelation(S, i, r) 250
AddGenerator(S) 250
AddGenerator(S, w) 250
DeleteGenerator(S, y) 250
16.8 String Operations on Words . 251
Eliminate(u, x, v) 251
Match(u, v, f) 251
Random(S, m, n) 251
RotateWord(u, n) 251
Substitute(u, f, n, v) 251
Subword(u, f, n) 251
ElementToSequence(u) 251
Eltseq(u) 251
Chapter 16
FINITELY PRESENTED SEMIGROUPS
16.1 Introduction
This Chapter presents the functions designed for computing with nitely-presented semi-
groups (fp-semigroups for short).
16.2 The Construction of Free Semigroups and their Elements
16.2.1 Structure Constructors
FreeSemigroup(n)
Construct the free semigroup F on n generators, where n is a positive integer. The
i-th generator may be referenced by the expression F.i, i = 1, . . . , n. Note that
a special form of the assignment statement is provided which enables the user to
assign names to the generators of F. In this form of assignment, the list of generator
names is enclosed within angle brackets and appended to the variable name on the
left hand side of the assignment statement.
FreeMonoid(n)
Construct the free monoid F on n generators, where n is a positive integer. The
i-th generator may be referenced by the expression F.i, i = 1, . . . , n. Note that
a special form of the assignment statement is provided which enables the user to
assign names to the generators of F. In this form of assignment, the list of generator
names is enclosed within angle brackets and appended to the variable name on the
left hand side of the assignment statement.
Example H16E1
The statement
> F := FreeSemigroup(2);
creates the free semigroup on two generators. Here the generators may be referenced using the
standard names, F.1 and F.2.
The statement
> F<x, y> := FreeSemigroup(2);
denes F to be the free semigroup on two generators and assigns the names x and y to the
generators.
244 SEMIGROUPS AND MONOIDS Part III
16.2.2 Element Constructors
Suppose S is an fp-semigroup, not necessarily free, for which generators have already been
dened. A word is dened inductively as follows:
(i) A generator is a word;
(ii)The product uv of the words u and v is a word;
(iii) The power of a word, u
n
, where u is a word and n is an integer, is a word.
An element (word) of S may be constructed as an expression in the generators as outlined
below.
S ! [i
1
, ... i
s
]
Given a semigroup S dened on r generators and a sequence Q = [i
1
, , i
s
] of
integers lying in the range [1, r], construct the word G.i
1
G.i
2
G.i
s
.
Id(M)
M ! 1
Construct the identity element (empty word) for the fp-monoid M.
16.3 Elementary Operators for Words
16.3.1 Multiplication and Exponentiation
The word operations dened here may be applied either to the words of a free semigroup
or the words of a semigroup with non-trivial relations.
u * v
Given words u and v belonging to the same fp-semigroup S, return the product of
u and v.
u ^ n
The n-th power of the word u, where n is a positive integer.
G ! Q
Given a sequence Q of words belonging to the fp-semigroup G, return the product
Q[1]Q[2] Q[n] of the terms of Q as a word in G.
16.3.2 The Length of a Word
#u
The length of the word u.
Ch. 16 FINITELY PRESENTED SEMIGROUPS 245
16.3.3 Equality and Comparison
The words of an fp-semigroup S are ordered rst by length and then lexicographically.
The lexicographic ordering is determined by the following ordering on the generators:
S.1 < S.2 < S.3 < S.4 <
Here, u and v are words belonging to some common fp-semigroup.
u eq v
Returns true if the words u and v are identical (as elements of the appropriate free
semigroup), false otherwise.
u ne v
Returns true if the words u and v are not identical (as elements of the appropriate
free semigroup), false otherwise.
u lt v
Returns true if the word u precedes the word v, with respect to the ordering dened
above for elements of an fp-semigroup, false otherwise.
u le v
Returns true if the word u either precedes, or is equal to, the word v, with respect
to the ordering dened above for elements of an fp-semigroup, false otherwise.
u ge v
Returns true if the word u either follows, or is equal to, the word v, with respect
to the ordering dened above for elements of an fp-semigroup, false otherwise.
u gt v
Returns true if the word u follows the word v, with respect to the ordering dened
above for elements of an fp-semigroup.
IsOne(u)
Returns true if the word u, belonging to the monoid M, is the identity word, false
otherwise.
246 SEMIGROUPS AND MONOIDS Part III
16.4 Specication of a Presentation
16.4.1 Relations
w
1
= w
2
Given words w
1
and w
2
over the generators of an fp-semigroup S, create the relation
w
1
= w
2
. Note that this relation is not automatically added to the existing set of
dening relations R for S. It may be added to R, for example, through use of the
quo-constructor (see below).
LHS(r)
Given a relation r over the generators of S, return the left hand side of the relation
r. The object returned is a word over the generators of S.
RHS(r)
Given a relation r over the generators of S, return the right hand side of the relation
r. The object returned is a word over the generators of S.
16.4.2 Presentations
A semigroup with non-trivial relations is constructed as a quotient of an existing semigroup,
possibly a free semigroup.
Semigroup< generators | relations >
Given a generators clause consisting of a list of variables x
1
, , x
r
, and a set of
relations relations over these generators, rst construct the free semigroup F on
the generators x
1
, , x
r
and then construct the quotient of F corresponding to the
ideal of F dened by relations.
The syntax for the relations clause is the same as for the quo-constructor. The
function returns:
(a) The quotient semigroup S;
(b)The natural homomorphism : F S.
Thus, the statement
S< y
1
, ..., y
r
> := Semigroup< x
1
, ..., x
r
| w
1
, ..., w
s
>;
is an abbreviation for
F< x
1
, ..., x
r
> := FreeSemigroup(r);
S< y
1
, ..., y
r
> := quo< F | w
1
, ..., w
s
>;
Ch. 16 FINITELY PRESENTED SEMIGROUPS 247
Monoid< generators | relations >
Given a generators clause consisting of a list of variables x
1
, , x
r
, and a set of
relations relations over these generators, rst construct the free monoid F on the
generators x
1
, , x
r
and then construct the quotient of F corresponding to the
ideal of F dened by relations.
The syntax for the relations clause is the same as for the quo-constructor. The
function returns:
(a) The quotient monoid M;
(b)The natural homomorphism : F M.
Thus, the statement
M< y1, ..., yr > := Monoid< x1, ..., xr | w1, ..., ws >;
is an abbreviation for
F< x
1
, ..., x
r
> := FreeMonoid(r);
M< y
1
, ..., y
r
> := quo< F | w
1
, ..., w
s
>;
Example H16E2
We create the monoid dened by the presentation < x, y | x
2
, y
2
, (xy)
2
>.
> M<x,y> := Monoid< x, y | x^2, y^2, (x*y)^2 >;
> M;
Finitely presented monoid
Relations:
x^2 = Id(M)
y^2 = Id(M)
(x * y)^2 = Id(M)
16.4.3 Accessing the Dening Generators and Relations
The functions in this group provide access to basic information stored for a nitely-
presented semigroup G.
S . i
The i-th dening generator for S.
Generators(S)
A set containing the generators for S.
NumberOfGenerators(S)
Ngens(S)
The number of generators for S.
Parent(u)
The parent semigroup S of the word u.
248 SEMIGROUPS AND MONOIDS Part III
Relations(S)
A sequence containing the dening relations for S.
16.5 Subsemigroups, Ideals and Quotients
16.5.1 Subsemigroups and Ideals
sub< S | L
1
, ..., L
r
>
Construct the subsemigroup R of the fp-semigroup S generated by the words spec-
ied by the terms of the generator list L
1
,. . ., L
r
.
A term L
i
of the generator list may consist of any of the following objects:
(a) A word;
(b)A set or sequence of words;
(c) A sequence of integers representing a word;
(d)A set or sequence of sequences of integers representing words;
(e) A subsemigroup of an fp-semigroup;
(f) A set or sequence of subsemigroups.
The collection of words and semigroups specied by the list must all belong to
the semigroup S, and R will be constructed as a subgroup of S.
The generators of R consist of the words specied directly by terms L
i
together
with the stored generating words for any semigroups specied by terms of L
i
. Rep-
etitions of an element and occurrences of the identity element are removed (unless
R is trivial).
ideal< S | L
1
, ..., L
r
>
Construct the two-sided ideal I of the fp-semigroup S generated by the words spec-
ied by the terms of the generator list L
1
,. . ., L
r
.
The possible forms of a term L
i
of the generator list are the same as for the
sub-constructor.
lideal< G | L
1
, ..., L
r
>
Construct the left ideal I of the fp-semigroup S generated by the words specied by
the terms of the generator list L
1
,. . ., L
r
.
The possible forms of a term L
i
of the generator list are the same as for the
sub-constructor.
rideal< G | L
1
, ..., L
r
>
Construct the right ideal I of the fp-semigroup S generated by the words specied
by the terms of the generator list L
1
,. . ., L
r
.
The possible forms of a term L
i
of the generator list are the same as for the
sub-constructor.
Ch. 16 FINITELY PRESENTED SEMIGROUPS 249
16.5.2 Quotients
quo< F | relations >
Given an fp-semigroup F, and a list of relations relations over the generators of F,
construct the quotient of F by the ideal of F dened by relations.
The expression dening F may be either simply the name of a previously con-
structed semigroup, or an expression dening an fp-semigroup.
Each term of the list relations must be a relation, a relation list or, if S is a
monoid, a word.
A word is interpreted as a relator if S is a monoid.
A relation consists of a pair of words, separated by =. (See above).
A relation list consists of a list of words, where each pair of adjacent words
is separated by =: w
1
= w
2
= = w
r
. This is interpreted as the relations
w
1
= w
r
, . . . , w
r1
= w
r
.
Note that the relation list construct is only meaningful in the context of the fp
semigroup-constructor.
In the context of the quo-constructor, the identity element (empty word) of a
monoid may be represented by the digit 1.
Note that this function returns:
(a) The quotient semigroup S;
(b)The natural homomorphism : F S.
S / I
Given an ideal I of the semigroup S, construct the quotient of S by the ideal I. The
quotient is formed by taking the presentation for S and including the generating
words of I as additional relations.
16.6 Extensions
DirectProduct(R, S)
Given two fp-semigroups R and S, construct the direct product of R and S.
FreeProduct(R, S)
Given two fp-semigroups R and S, construct the free product of R and S.
250 SEMIGROUPS AND MONOIDS Part III
16.7 Elementary Tietze Transformations
AddRelation(S, r)
AddRelation(S, r, i)
Given an fp-semigroup S and a relation r in the generators of S, create the quotient
semigroup obtained by adding the relation r to the dening relations of S. If an
integer i is specied as third argument, insert the new relation after the i-th relation
of S. If the third argument is omitted, r is added to the end of the relations that
are carried across from S.
DeleteRelation(S, r)
Given an fp-semigroup S and a relation r that occurs among the given dening
relations for S, create the semigroup T, having the same generating set as S but
with the relation r removed.
DeleteRelation(S, i)
Given an fp-semigroup S and an integer i, 1 i m, where m is the number of
dening relations for S, create the semigroup T having the same generating set as
S but with the i-th relation omitted.
ReplaceRelation(S, r
1
, r
2
)
Given an fp-semigroup S and relations r
1
and r
2
in the generators of S, where r
1
is one of the given dening relations for S, create the semigroup T having the same
generating set as S but with the relation r
1
replaced by the relation r
2
.
ReplaceRelation(S, i, r)
Given an fp-semigroup S, an integer i, 1 i m, where m is the number of dening
relations for S, and a relation r in the generators of S, create the semigroup T having
the same generating set as S but with the i-th relation of S replaced by the relation
r.
AddGenerator(S)
Given an fp-semigroup S with presentation < X [ R >, create the semigroup T with
presentation < X y [ R >, where y denotes a new generator.
AddGenerator(S, w)
Given an fp-semigroup S with presentation < X [ R > and a word w in the gener-
ators of S, create the semigroup T with presentation < X y [ R y = w >,
where y denotes a new generator.
DeleteGenerator(S, y)
Given an fp-semigroup S with presentation < X [ R > and a generator y of S such
that either S has no relations involving y, or a single relation r containing a single
occurrence of y, create the semigroup T with presentation < X y [ R r >.
Ch. 16 FINITELY PRESENTED SEMIGROUPS 251
16.8 String Operations on Words
Eliminate(u, x, v)
Given words u and v, and a generator x, belonging to a semigroup S, return the
word obtained from u by replacing each occurrence of x by v.
Match(u, v, f)
Suppose u and v are words belonging to the same semigroup S, and that f is an
integer such that 1 f #u. If v is a subword of u, the function returns true, as
well as the least integer l such that:
(a) l f; and,
(b)v appears as a subword of u, starting at the l-th letter of u.
If no such l is found, Match returns only false.
Random(S, m, n)
A random word of length l in the generators of the semigroup S, where m l n.
RotateWord(u, n)
The word obtained by cyclically permuting the word u by n places. If n is positive,
the rotation is from left to right, while if n is negative the rotation is from right to
left. In the case where n is zero, the function returns u.
Substitute(u, f, n, v)
Given words u and v belonging to a semigroup S, and non-negative integers f and
n, this function replaces the substring of u of length n, starting at position f, by the
word v. Thus, if u = x
i
1
x
i
f
x
i
f+n1
x
i
m
then the substring x
i
f
x
i
f+n1
is replaced by v. If u and v belong to a monoid M and the function is invoked with
v =Id(M), then the substring x
i
f
x
i
f+n1
of u is deleted.
Subword(u, f, n)
The subword of the word u comprising the n consecutive letters commencing at the
f-th letter of u.
ElementToSequence(u)
Eltseq(u)
The sequence obtained by decomposing u into the indices of its constituent genera-
tors. Thus, if u = x
i
1
. . . x
i
m
, then the sequence constructed by ElementToSequence
is [i
1
, i
2
, . . . , i
m
].
17 MONOIDS GIVEN BY
REWRITE SYSTEMS
17.1 Introduction . . . . . . . . 255
17.1.1 Terminology . . . . . . . . . . 255
17.1.2 The Category of Rewrite Monoids . 255
17.1.3 The Construction of a Rewrite Monoid255
17.2 Construction of a Rewrite Monoid256
RWSMonoid(Q: -) 256
SetVerbose("KBMAG", v) 258
17.3 Basic Operations . . . . . . 261
17.3.1 Accessing Monoid Information . . 261
. 261
Generators(M) 261
NumberOfGenerators(M) 261
Ngens(M) 261
Relations(M) 261
NumberOfRelations(M) 261
Nrels(M) 261
Ordering(M) 261
Parent(w) 261
17.3.2 Properties of a Rewrite Monoid . . 262
IsConfluent(M) 262
IsFinite(M) 262
Order(M) 263
# 263
17.3.3 Construction of a Word . . . . . 264
Identity(M) 264
Id(M) 264
! 264
! 264
17.3.4 Arithmetic with Words . . . . . . 264
* 265
^ 265
eq 265
ne 265
IsId(w) 265
IsIdentity(w) 265
# 265
ElementToSequence(u) 265
Eltseq(u) 265
17.4 Homomorphisms . . . . . . 266
17.4.1 General remarks . . . . . . . . 266
17.4.2 Construction of Homomorphisms . 266
hom< > 266
17.5 Set Operations . . . . . . . 266
Random(M, n) 266
Random(M) 266
Representative(M) 266
Rep(M) 266
Set(M, a, b) 267
Set(M) 267
Seq(M, a, b) 267
Seq(M) 267
17.6 Conversion to a Finitely Presented
Monoid . . . . . . . . . . 268
17.7 Bibliography . . . . . . . . 269
Chapter 17
MONOIDS GIVEN BY
REWRITE SYSTEMS
17.1 Introduction
The category of monoids dened by nite sets of rewrite rules provide a Magma level in-
terface to Derek Holts KBMAG programs, and specically to KBMAGs KnuthBendix
completion procedure on monoids dened by a nite presentation. As such much of the
documentation in this chapter is taken from the KBMAG documentation [Hol97]. Famil-
iarity with the KnuthBendix completion procedure is assumed. Some familiarity with
KBMAG would be benecial.
17.1.1 Terminology
A rewrite monoid M is a nitely presented monoid in which equality between elements
of M, called words or strings, is decidable via a sequence of rewriting equations, called
reduction relations, rules, or equations. In the interests of eciency the reduction rules are
codied into a nite state automaton called a reduction machine. The words in a rewrite
monoid M are ordered, as are the reduction relations of M. Several possible orderings of
words are supported, namely short-lex, recursive, weighted short-lex and wreath-product
orderings. A rewrite monoid can be conuent or non-conuent. If a rewrite monoid M is
conuent its reduction relations, or more specically its reduction machine, can be used
to reduce words in M to their irreducible normal forms under the given ordering, and so
the word problem for M can be eciently solved.
17.1.2 The Category of Rewrite Monoids
The family of all rewrite monoids forms a category. The objects are the rewrite monoids
and the morphisms are monoid homomorphisms. The Magma designation for this category
of monoids is MonRWS. Elements of a rewrite monoid are designated as MonRWSElt.
17.1.3 The Construction of a Rewrite Monoid
A rewrite monoid M is constructed in a three-step process:
(i) A free monoid F of the appropriate rank is dened.
(ii)A quotient Q of F is created.
(iii) The KnuthBendix completion procedure is applied to the monoid Q to produce a
monoid M dened by a rewrite system.
The KnuthBendix procedure may or may not succeed. If it fails the user may need
to perform the above steps several times, manually adjusting parameters that control
the execution of the KnuthBendix procedure. If it succeeds then the rewrite systems
constructed will be conuent.
256 SEMIGROUPS AND MONOIDS Part III
17.2 Construction of a Rewrite Monoid
RWSMonoid(Q: parameters)
The KnuthBendix completion procedure for monoids is run, with the relations of
Q taken as the initial reduction rules for the procedure. Regardless of whether
or not the completion procedure succeeds, the result will be a rewrite monoid,
M, containing a reduction machine and a sequence of reduction relations. If the
procedure succeeds M will be marked as conuent, and the word problem for M is
therefore decidable. If, as is very likely, the procedure fails then M will be marked
as non-conuent. In this case M will contain both the reduction relations and the
reduction machine computed up to the point of failure.
As the KnuthBendix procedure will more often than not run forever, some
conditions must be specied under which it will stop. These take the form of limits
that are placed on certain variables, such as the number of reduction relations. If
any of these limits are exceeded during a run of the completion procedure it will
fail, returning a non-conuent rewrite monoid. The optimal values for these limits
varies from example to example.
MaxRelations RngIntElt Default : 32767
Limit the maximum number of reduction equations to MaxRelations.
GeneratorOrder SeqEnum Default :
Give an ordering for the generators. This ordering aects the ordering of words
in the alphabet. If not specied the ordering defaults to the order induced by Qs
generators, that is [g
1
, . . . , g
n
] where g
1
, . . . , g
n
are the generators of Q.
Ordering MonStgElt Default : ShortLex
Levels SeqEnum Default :
Weights SeqEnum Default :
Ordering := "ShortLex": Use the short-lex ordering on strings. Shorter words
come before longer, and for words of equal length lexicographical ordering is used,
using the given ordering of the generators.
Ordering := "Recursive" | "RTRecursive": Use a recursive ordering on strings.
There are various ways to dene this. Perhaps the quickest is as follows. Let u and
v be strings in the generators. If one of u and v, say v, is empty, then u v.
Otherwise, let u = u
a and v = v
> v
;
(ii)a > b and u > v
;
(iii) b > a and u
> v.
The RTRecursive ordering is similar to the Recursive ordering, but with u = au
and v = bv