Regina 7.0 Calculation Engine
Classes | Macros | Typedefs | Enumerations | Functions | Variables
Normal Surfaces

Normal surfaces in 3-manifold triangulations. More...

Classes

struct  regina::DiscSpec
 Specifies a single normal disc in a normal surface. More...
 
class  regina::DiscSetTet
 Represents a set of normal discs inside a single tetrahedron. More...
 
class  regina::DiscSetTetData< T >
 Stores data of type T for every normal disc inside a single tetrahedron. More...
 
class  regina::DiscSetSurfaceDataImpl< TetData >
 Stores a piece of data alongside every normal disc within a particular normal surface. More...
 
class  regina::DiscSpecIterator< TetData >
 A forward iterator used for running through all normal discs in a normal surface. More...
 
struct  regina::DiscType
 Identifies a single normal or almost normal disc type within a triangulation. More...
 
class  regina::NormalEncoding
 Indicates precisely how a normal surface is encoded by an integer vector. More...
 
class  regina::NormalInfo
 A class used to query general information about different normal coordinate systems. More...
 
class  regina::NormalSurface
 Represents a single normal surface in a 3-manifold triangulation. More...
 
class  regina::NormalSurfaces
 A collection of normal surfaces in a 3-manifold triangulation. More...
 
struct  regina::PrismSpec
 Specifies a single triangular prism in a tetrahedron. More...
 
class  regina::SurfaceFilter
 A packet that accepts or rejects normal surfaces. More...
 
class  regina::SurfaceFilterCombination
 A normal surface filter that simply combines other filters. More...
 
class  regina::SurfaceFilterProperties
 A normal surface filter that filters by basic properties of the normal surface. More...
 

Macros

#define REGINA_SURFACE_FILTER(id, name)
 Defines various constants, types and virtual functions for a descendant class of SurfaceFilter. More...
 

Typedefs

template<typename T >
using regina::DiscSetSurfaceData = DiscSetSurfaceDataImpl< DiscSetTetData< T > >
 A structure that stores data of type T alongside every normal disc within a particular normal surface. More...
 
using regina::DiscSetSurface = DiscSetSurfaceDataImpl< DiscSetTet >
 A structure that builds all of the normal discs within a particular normal surface, but does not store any additional data alongside them. More...
 
using regina::NormalList = regina::Flags< NormalListFlags >
 A combination of flags for types of normal surface lists. More...
 
using regina::NormalAlg = regina::Flags< NormalAlgFlags >
 A combination of flags for normal surface enumeration algorithms. More...
 
using regina::SurfaceExport = regina::Flags< SurfaceExportFields >
 A set of fields to export alongside a normal surface list. More...
 

Enumerations

enum  regina::NormalCoords {
  regina::NS_STANDARD = 0 , regina::NS_QUAD = 1 , regina::NS_QUAD_CLOSED = 10 , regina::NS_AN_LEGACY = 100 ,
  regina::NS_AN_QUAD_OCT = 101 , regina::NS_AN_STANDARD = 102 , regina::NS_AN_QUAD_OCT_CLOSED = 110 , regina::NS_EDGE_WEIGHT = 200 ,
  regina::NS_TRIANGLE_ARCS = 201 , regina::NS_ANGLE = 400
}
 Represents different coordinate systems that can be used for enumerating and/or displaying normal surfaces. More...
 
enum  regina::NormalListFlags {
  regina::NS_LIST_DEFAULT = 0x0000 , regina::NS_EMBEDDED_ONLY = 0x0001 , regina::NS_IMMERSED_SINGULAR = 0x0002 , regina::NS_VERTEX = 0x0004 ,
  regina::NS_FUNDAMENTAL = 0x0008 , regina::NS_LEGACY = 0x4000 , regina::NS_CUSTOM = 0x8000
}
 Represents different lists of normal surfaces that might be constructed for a given 3-manifold triangulation. More...
 
enum  regina::NormalAlgFlags {
  regina::NS_ALG_DEFAULT = 0x0000 , regina::NS_VERTEX_VIA_REDUCED = 0x0001 , regina::NS_VERTEX_STD_DIRECT = 0x0002 , regina::NS_VERTEX_TREE = 0x0010 ,
  regina::NS_VERTEX_DD = 0x0020 , regina::NS_HILBERT_PRIMAL = 0x0100 , regina::NS_HILBERT_DUAL = 0x0200 , regina::NS_HILBERT_CD = 0x0400 ,
  regina::NS_HILBERT_FULLCONE = 0x0800 , regina::NS_ALG_LEGACY = 0x4000 , regina::NS_ALG_CUSTOM = 0x8000
}
 Represents options and variants of algorithms for enumerating various types of normal surfaces in 3-manifold triangulations. More...
 
enum  regina::NormalTransform {
  regina::NS_CONV_REDUCED_TO_STD = 0x01 , regina::NS_CONV_STD_TO_REDUCED = 0x02 , regina::NS_FILTER_COMPATIBLE = 0x10 , regina::NS_FILTER_DISJOINT = 0x20 ,
  regina::NS_FILTER_INCOMPRESSIBLE = 0x30
}
 Represents different ways in which Regina can transform one normal surface list into another. More...
 
enum  regina::SurfaceExportFields {
  regina::surfaceExportName = 0x0001 , regina::surfaceExportEuler = 0x0002 , regina::surfaceExportOrient = 0x0004 , regina::surfaceExportSides = 0x0008 ,
  regina::surfaceExportBdry = 0x0010 , regina::surfaceExportLink = 0x0020 , regina::surfaceExportType = 0x0040 , regina::surfaceExportNone = 0 ,
  regina::surfaceExportAllButName = 0x007e , regina::surfaceExportAll = 0x007f
}
 Used to describe a field, or a set of fields, that can be exported alongside a normal surface list. More...
 
enum  regina::SurfaceFilterType { regina::NS_FILTER_LEGACY_DEFAULT = 0 , regina::NS_FILTER_PROPERTIES = 1 , regina::NS_FILTER_COMBINATION = 2 }
 Represents different types of filter classes that can be used to filter lists of normal surfaces in 3-manifold triangulations. More...
 

Functions

std::ostream & regina::operator<< (std::ostream &out, const DiscSpec &spec)
 Writes the given disc specifier to the given output stream. More...
 
bool regina::numberDiscsAwayFromVertex (int discType, int vertex)
 Determines whether or not normal discs of the given type are numbered away from the given vertex. More...
 
bool regina::discOrientationFollowsEdge (int discType, int vertex, int edgeStart, int edgeEnd)
 Determines whether or not the natural boundary orientation of a normal disc of the given type follows the given directed normal arc. More...
 
template<class T >
void regina::swap (DiscSetTetData< T > &a, DiscSetTetData< T > &b) noexcept
 Swaps the contents of the two given disc sets. More...
 
template<class T >
void regina::swap (DiscSetSurfaceDataImpl< T > &a, DiscSetSurfaceDataImpl< T > &b) noexcept
 Swaps the contents of the two given disc sets. More...
 
std::ostream & regina::operator<< (std::ostream &out, const DiscType &type)
 Writes the given disc type to the given output stream. More...
 
NormalList regina::operator| (NormalListFlags lhs, NormalListFlags rhs)
 Returns the bitwise OR of the two given flags. More...
 
NormalAlg regina::operator| (NormalAlgFlags lhs, NormalAlgFlags rhs)
 Returns the bitwise OR of the two given flags. More...
 
void regina::swap (NormalSurface &a, NormalSurface &b) noexcept
 Swaps the contents of the given normal surfaces. More...
 
SurfaceExport regina::operator| (SurfaceExportFields lhs, SurfaceExportFields rhs)
 Returns the bitwise OR of the two given flags. More...
 
void regina::swap (NormalSurfaces &lhs, NormalSurfaces &rhs)
 Swaps the contents of the two given lists. More...
 
MatrixInt regina::makeMatchingEquations (const Triangulation< 3 > &triangulation, NormalCoords coords)
 Generates the set of normal surface matching equations for the given triangulation using the given coordinate system. More...
 
ValidityConstraints regina::makeEmbeddedConstraints (const Triangulation< 3 > &triangulation, NormalCoords coords)
 Generates the validity constraints representing the condition that normal surfaces be embedded. More...
 
std::ostream & regina::operator<< (std::ostream &out, const PrismSpec &spec)
 Writes the given prism specifier to the given output stream. More...
 
void regina::swap (SurfaceFilterCombination &a, SurfaceFilterCombination &b)
 Swaps the contents of the given combination filters. More...
 
void regina::swap (SurfaceFilterProperties &a, SurfaceFilterProperties &b)
 Swaps the contents of the given property-based filters. More...
 

Variables

constexpr int regina::quadSeparating [4][4]
 Lists which quadrilateral types separate which pairs of vertices in a tetrahedron. More...
 
constexpr int regina::quadMeeting [4][4][2]
 Lists which quadrilateral types meet which edges in a tetrahedron. More...
 
constexpr int regina::quadDefn [3][4]
 Lists which vertices each quadrilateral type separates in a tetrahedron. More...
 
constexpr int regina::quadPartner [3][4]
 Lists the second vertex with which each vertex is paired under each quadrilateral type in a tetrahedron. More...
 
constexpr char regina::quadString [3][6] = { "01/23", "02/13", "03/12" }
 Contains strings that can be used to represent each quadrilateral type in a tetrahedron. More...
 
constexpr Perm< 4 > regina::triDiscArcs [4][3]
 Lists in consecutive order the directed normal arcs that form the boundary of each type of triangular normal disc. More...
 
constexpr Perm< 4 > regina::quadDiscArcs [3][4]
 Lists in consecutive order the directed normal arcs that form the boundary of each type of quadrilateral normal disc. More...
 
constexpr Perm< 4 > regina::octDiscArcs [3][8]
 Lists in consecutive order the directed normal arcs that form the boundary of each type of octagonal normal disc. More...
 

Detailed Description

Normal surfaces in 3-manifold triangulations.

Macro Definition Documentation

◆ REGINA_SURFACE_FILTER

#define REGINA_SURFACE_FILTER (   id,
  name 
)
Value:
public: \
static constexpr const SurfaceFilterType filterTypeID = id; \
inline SurfaceFilterType filterType() const override { \
return id; \
} \
inline std::string filterTypeName() const override { \
return name; \
}
SurfaceFilterType
Represents different types of filter classes that can be used to filter lists of normal surfaces in 3...
Definition: surfacefiltertype.h:55

Defines various constants, types and virtual functions for a descendant class of SurfaceFilter.

Every descendant class of SurfaceFilter must include REGINA_SURFACE_FILTER at the beginning of the class definition.

This macro provides the class with:

  • a compile-time constant filterTypeID, which is equal to the corresponding SurfaceFilterType constant;
  • declarations and implementations of the virtual functions SurfaceFilter::filterType() and SurfaceFilter::filterTypeName();
Parameters
idthe corresponding SurfaceFilterType constant.
namea human-readable name for this filter type.

Typedef Documentation

◆ DiscSetSurface

A structure that builds all of the normal discs within a particular normal surface, but does not store any additional data alongside them.

This structure can be used for iterating through disc types, and for moving between adjacent disc types within a surface.

◆ DiscSetSurfaceData

template<typename T >
using regina::DiscSetSurfaceData = typedef DiscSetSurfaceDataImpl<DiscSetTetData<T> >

A structure that stores data of type T alongside every normal disc within a particular normal surface.

Python
Not present.

◆ NormalAlg

A combination of flags for normal surface enumeration algorithms.

If a function requires a NormalAlg object as an argument, you can pass a single NormalAlgFlags constant, or a combination of such constants using the bitwise OR operator, or empty braces {} to indicate no flags at all.

◆ NormalList

A combination of flags for types of normal surface lists.

If a function requires a NormalList object as an argument, you can pass a single NormalListFlags constant, or a combination of such constants using the bitwise OR operator, or empty braces {} to indicate no flags at all.

◆ SurfaceExport

A set of fields to export alongside a normal surface list.

If a function requires a SurfaceExport object as an argument, you can pass a single SurfaceExportFields constant, or a combination of such constants using the bitwise OR operator, or empty braces {} to indicate no fields at all.

Enumeration Type Documentation

◆ NormalAlgFlags

Represents options and variants of algorithms for enumerating various types of normal surfaces in 3-manifold triangulations.

These options can be combined using the bitwise OR operator, and then passed to enumeration routines such as the NormalSurfaces class constructor.

Enumerator
NS_ALG_DEFAULT 

An empty flag, indicating to an enumeration routine that it should use its default behaviour.

The numeric value of this flag is zero (i.e., it has no effect when combined with other flags using bitwise OR).

NS_VERTEX_VIA_REDUCED 

When enumerating in standard normal or almost normal coordinates, this flag indicates that the algorithm should first enumerate in quadrilateral or quadrilateral-octagon coordinates, and then expand this "reduced" solution set to the (typically larger) "standard" solution set.

This is typically much faster than a direct enumeration in standard normal or almost normal coordinates, and enumeration routines will use this option where possible unless explicitly requested not to (via the flag NS_VERTEX_STD_DIRECT).

For an explanation of this procedure, see B. A. Burton, "Converting between quadrilateral and standard solution sets in normal surface theory", Algebr. Geom. Topol. 9 (2009), 2121-2174.

This flag is incompatible with NS_VERTEX_STD_DIRECT.

NS_VERTEX_STD_DIRECT 

When enumerating in standard normal or almost normal coordinates, this flag indicates that the algorithm should work directly in that coordinate system, and should not go via the "reduced" (quadrilateral or quadrilateral-octagon) coordinate system.

This is typically much slower than going via the reduced system, and users should only request this if they have a specialised need. See NS_VERTEX_VIA_REDUCED for further information.

This flag is incompatible with NS_VERTEX_VIA_REDUCED.

NS_VERTEX_TREE 

When enumerating vertex normal surfaces, this flag indicates that the tree traversal algorithm should be used.

This algorithm is based on linear and integer programming techniques, and has many desirable properties including a relatively low overhead. Enumeration algorithms will use it if possible unless a different method is explicitly requested.

For details on the tree traversal algorithm, see B. A. Burton and M. Ozlen, "A tree traversal algorithm for decision problems in knot theory and 3-manifold topology", Algorithmica 65 (2013), pp. 772-801.

This flag is incompatible with NS_VERTEX_DD.

NS_VERTEX_DD 

When enumerating vertex normal surfaces, this flag indicates that a modified double description method should be used.

This algorithm can suffer from a combinatorial explosion with larger problems, leading to extremely large time and memory footprints. Users should only request this if they have some specialised need.

For details on the modified double description method, see B. A. Burton, "Optimizing the double description method for normal surface enumeration", Mathematics of Computation 79 (2010), pp. 453-484.

This flag is incompatible with NS_VERTEX_TREE.

NS_HILBERT_PRIMAL 

When enumerating fundamental normal surfaces, this flag indicates that the primal method should be used for enumerating a Hilbert basis.

The primal method is recommended, and enumeration algorithms will use it if possible unless a different method is explicitly requested. This method uses code from Normaliz for parts of its processing.

For details and comparisons of the various options for enumerating fundamental normal surfaces, see B. A. Burton, "Enumerating fundamental normal surfaces: Algorithms, experiments and invariants", ALENEX 2014: Proceedings of the Meeting on Algorithm Engineering & Experiments, SIAM, 2014, pp. 112-124.

This flag is incompatible with NS_HILBERT_DUAL, NS_HILBERT_CD and NS_HILBERT_FULLCONE.

NS_HILBERT_DUAL 

When enumerating fundamental normal surfaces, this flag indicates that the dual method should be used for enumerating a Hilbert basis.

The dual method is fast (like the primal method), but its performance is highly variable; for this reason the primal method is recommended instead. This method does not make use of Normaliz, and is the recommended method for situations in which Normaliz is not available for some reason.

For details and comparisons of the various options for enumerating fundamental normal surfaces, see B. A. Burton, "Enumerating fundamental normal surfaces: Algorithms, experiments and invariants", ALENEX 2014: Proceedings of the Meeting on Algorithm Engineering & Experiments, SIAM, 2014, pp. 112-124.

This flag is incompatible with NS_HILBERT_PRIMAL, NS_HILBERT_CD and NS_HILBERT_FULLCONE.

NS_HILBERT_CD 

When enumerating fundamental normal surfaces, this flag indicates that a modified Contejean-Devie procedure should be used for enumerating a Hilbert basis.

The Contejean-Devie procedure is typically much slower than either the primal or dual method, and users should only request it if they have some specialised need.

For details and comparisons of the various options for enumerating fundamental normal surfaces, see B. A. Burton, "Enumerating fundamental normal surfaces: Algorithms, experiments and invariants", ALENEX 2014: Proceedings of the Meeting on Algorithm Engineering & Experiments, SIAM, 2014, pp. 112-124.

This flag is incompatible with NS_HILBERT_PRIMAL, NS_HILBERT_DUAL and NS_HILBERT_FULLCONE.

NS_HILBERT_FULLCONE 

When enumerating fundamental normal surfaces, this flag indicates that a Hilbert basis for the full solution cone should be constructed, and additional combinatorial constraints (such as the quadrilateral constraints) should only be enforced as the final step.

If you are only enumerating properly embedded surfaces then this procedure extremely slow, and users should only request it if they have some specialised need.

For details and comparisons of the various options for enumerating fundamental normal surfaces, see B. A. Burton, "Enumerating fundamental normal surfaces: Algorithms, experiments and invariants", ALENEX 2014: Proceedings of the Meeting on Algorithm Engineering & Experiments, SIAM, 2014, pp. 112-124.

This flag is incompatible with NS_HILBERT_PRIMAL, NS_HILBERT_DUAL and NS_HILBERT_CD.

NS_ALG_LEGACY 

Indicates that a normal surface list was enumerated using an older version of Regina (4.93 or earlier).

These older versions did not retain details of the algorithm used to build each list, and so in such cases no further algorithmic information is available.

If this flag is passed to an enumeration algorithm, it will be ignored.

NS_ALG_CUSTOM 

Indicates that a normal surface list was built using a customised algorithm.

In such cases, no further details on the algorithm are available.

If this flag is passed to an enumeration algorithm, it will be ignored.

◆ NormalCoords

Represents different coordinate systems that can be used for enumerating and/or displaying normal surfaces.

IDs 0-9999 are reserved for future use by Regina. If you are extending Regina to include your own coordinate system, you should choose an ID >= 10000.

Enumerator
NS_STANDARD 

Represents standard triangle-quadrilateral coordinates for normal surfaces.

Regina can both enumerate and view surfaces in this coordinate system.

NS_QUAD 

Represents quadrilateral coordinates for normal surfaces.

For details, see "Normal surface Q-theory", Jeffrey L. Tollefson, Pacific J. Math. 183 (1998), no. 2, 359–374.

Regina can both enumerate and view surfaces in this coordinate system.

NS_QUAD_CLOSED 

Represents quadrilateral coordinates in ideal triangulations for enumerating closed surfaces only (thus excluding spun-normal surfaces).

The coordinates themselves are identical to quadrilateral coordinates, as described by NS_QUAD; however, the enumeration procedure introduces additional constraints. The resulting solution space is the space Q_0 as described in "Computing closed essential surfaces in knot complements", by Burton, Coward and Tillmann, in SCG ’13: Proceedings of the 29th Annual Symposium on Computational Geometry, ACM, 2013, pp. 405–414.

Note that, if a vertex surface in quad coordinates is closed, it will always be a vertex surface in this system of "closed quad coordinates". However, the converse is not true: a vertex surface in closed quad coordinates need not be a vertex in "plain" quad coordinates.

Regina can enumerate surfaces in this coordinate system, but it is not for viewing. You can just view the surfaces in quad coordinates (NS_QUAD) instead.

Precondition
Regina can only create matching equations in this coordinate system for a limited class of triangulations. Currently, such triangulations must be oriented and ideal, with precisely one torus cusp and no other boundary components or internal vertices. These conditions will be checked when building the matching equations, and Regina will throw an InvalidArgument exception if they are not met.
SnapPea must be able to work with the underlying triangulation, without retriangulating. This should follow from the previous constraints; however, it will also be checked when building the matching equations, and Regina will throw an UnsolvedCase exception if this requirement is not met.
NS_AN_LEGACY 

Indicates that a list of almost normal surfaces was created using Regina 4.5.1 or earlier, where surfaces with more than one octagon of the same type were stripped out of the final solution set.

As of Regina 4.6 such surfaces are now included in the solution set, since we need them if we wish to enumerate all almost normal surfaces (not just the vertex almost normal surfaces).

Regina cannot enumerate or view surfaces in this coordinate system. It is only used for reading legacy data files. If you have a list that uses this system, you can just view the surfaces in standard almost normal coordinates (NS_AN_STANDARD).

NS_AN_QUAD_OCT 

Represents quadrilateral-octagon coordinates for octagonal almost normal surfaces.

For details, see "Quadrilateral-octagon coordinates for almost normal surfaces", Benjamin A. Burton, Experiment. Math. 19 (2010), 285-315.

Regina can both enumerate and view surfaces in this coordinate system.

NS_AN_STANDARD 

Represents standard triangle-quadrilateral-octagon coordinates for octagonal almost normal surfaces.

Regina can both enumerate and view surfaces in this coordinate system.

NS_AN_QUAD_OCT_CLOSED 

Represents quadrilateral-octagon coordinates in ideal triangulations for enumerating closed surfaces only (thus excluding spun-almost normal surfaces).

The coordinates themselves are identical to quadrilateral-octagon coordinates, as described by NS_AN_QUAD_OCT; however, the enumeration procedure introduces additional constraints.

Note that, if a vertex surface in quad-oct coordinates is closed, it will always be a vertex surface in this system of "closed quad-oct coordinates". However, the converse is not true: a vertex surface in closed quad-oct coordinates need not be a vertex in "plain" quad-oct coordinates.

Regina can enumerate surfaces in this coordinate system, but it is not for viewing. You can just view the surfaces in quad-oct coordinates (NS_AN_QUAD_OCT) instead.

Precondition
Regina can only create matching equations in this coordinate system for a limited class of triangulations. Currently, such triangulations must be oriented and ideal, with precisely one torus cusp and no other boundary components or internal vertices. These conditions will be checked when building the matching equations, and Regina will throw an InvalidArgument exception if they are not met.
SnapPea must be able to work with the underlying triangulation, without retriangulating. This should follow from the previous constraints; however, it will also be checked when building the matching equations, and Regina will throw an UnsolvedCase exception if this requirement is not met.
NS_EDGE_WEIGHT 

Represents edge weight coordinates for normal surfaces.

This coordinate system is for display only: Regina can view surfaces in this coordinate system, but it cannot use it to enumerate or create surfaces.

NS_TRIANGLE_ARCS 

Represents triangle arc coordinates for normal surfaces.

This coordinate system is for display only: Regina can view surfaces in this coordinate system, but it cannot use it to enumerate or create surfaces.

NS_ANGLE 

Represents angle structure coordinates.

This coordinate system is not for use with normal surfaces: it cannot be used either to display them or enumerate them. Instead it is for use with angle structures on triangulations. Because the combinatorics and linear algebra of angle strutures are tightly related to those of normal surfaces, we include NS_ANGLE here so that angle structure routines can make use of some of Regina's existing normal surface machinery.

For a triangulation with n tetrahedra, this system has 3n+1 coordinates. The first 3n are analogous to quadrilateral coordinates (specifically, for each quadrilateral type Q, the corresponding angle structure coordinate represents the pair of angles in the same tetrahedron that Q does not meet). The final coordinate is a scaling coordinate, used to projectivise the angle structure polytope so that it becomes a polyhedral cone that is invariant under (positive) scaling. If the final scaling coordinate is s, then a rational value of x in any other coordinate position should be interpreted as the angle x.π/s.

Precondition
This coordinate system must not be used with any of Regina's routines unless they explicitly declare that NS_ANGLE is allowed.

◆ NormalListFlags

Represents different lists of normal surfaces that might be constructed for a given 3-manifold triangulation.

The NormalList enumeration refers to the contents of the list, whereas the NormalAlgFlags enumeration refers to the algorithm used to build it.

These flags can be combined using the bitwise OR operator, and then passed to enumeration routines such as the NormalSurfaces class constructor.

Enumerator
NS_LIST_DEFAULT 

An empty flag, indicating to an enumeration routine that it should use its default behaviour.

The numeric value of this flag is zero (i.e., it has no effect when combined with other flags using bitwise OR).

NS_EMBEDDED_ONLY 

Indicates that this list is restricted to properly embedded surfaces only.

This flag is incompatible with NS_IMMERSED_SINGULAR.

NS_IMMERSED_SINGULAR 

Indicates that the scope of this list includes not just properly embedded surfaces, but also immersed and/or branched surfaces.

This is no guarantee that the list contains immersed and/or branched surfaces; it merely states that such surfaces have not been explicitly excluded (in particular, the quadrilateral constraints have not been enforced).

This flag is incompatible with NS_EMBEDDED_ONLY.

NS_VERTEX 

Indicates a list of all vertex normal surfaces, with respect to the particular normal coordinate system used by the list.

This flag is incompatible with NS_FUNDAMENTAL.

NS_FUNDAMENTAL 

Indicates a list of all fundamental normal surfaces, with respect to the particular normal coordinate system used by the list.

This flag is incompatible with NS_VERTEX.

NS_LEGACY 

Indicates a list that was constructed using an old version of Regina (4.93 or earlier).

These older versions did not retain details of how each list was constructed, beyond whether immersed and/or singular surfaces were included. Therefore no information is available for such lists, other than the presence or absence of the NS_EMBEDDED_ONLY and/or NS_IMMERSED_SINGULAR flags.

If this flag is passed to an enumeration routine, it will be ignored.

NS_CUSTOM 

Indicates some other type of list, typically hand-crafted by the user or built by some customised algorithm.

If this flag is passed to an enumeration routine, it will be ignored.

◆ NormalTransform

Represents different ways in which Regina can transform one normal surface list into another.

Each type of transformation comes with its own preconditions on the original normal surface list and/or its underlying triangulation; these preconditions are documented alongside the individual enumeration values.

Enumerator
NS_CONV_REDUCED_TO_STD 

Converts the set of all embedded vertex normal surfaces in quadrilateral or quadrilateral-octagon coordinates to the set of all embedded vertex normal surfaces in standard normal or standard almost normal coordinates respectively.

It should be emphasised that this routine does not simply convert vectors from one coordinate system to another; instead it converts a full set of vertex surfaces in quad or quad-oct coordinates into a full set of vertex surfaces in standard normal or almost normal coordinates. Typically there are many more vertex surfaces in standard coordinates (all of which this routine will find).

This conversion process is typically much faster than enumerating surfaces directly in standard coordinates. However, normally you would not need to invoke this transformation yourself, since the standard enumeration process will use it automatically when possible. That is, when asked to build a list of standard vertex surfaces, the NormalSurfaces constructor will (if possible) first find all quad or quad-oct vertex surfaces and then use this procedure to convert the solution set.

Nevertheless, this standalone transformation is provided as a convenience for users who already have a set of quad or quad-oct vertex surfaces, and who simply wish to convert them to a set of standard vertex surfaces without the implicit cost of enumerating the quad or quad-oct vertex surfaces again.

The conversion algorithm is described in detail in "Converting between quadrilateral and standard solution sets in normal surface theory", Benjamin A. Burton, Algebr. Geom. Topol. 9 (2009), 2121-2174.

The preconditions for using this transformation:

  • The underlying triangulation is valid, and has no ideal vertices.
  • The input to this transformation is exactly the set of all embedded vertex surfaces in quadrilateral or quadrilateral-octagon coordinates. This will be checked by examining NormalSurface::coords() and NormalSurface::which().
NS_CONV_STD_TO_REDUCED 

Converts the set of all embedded vertex normal surfaces in standard normal or standard almost normal coordinates to the set of all embedded vertex normal surfaces in quadrilateral or quadrilateral-octagon coordinates respectively.

It should be emphasised that this routine does not simply convert vectors from one coordinate system to another; instead it converts a full set of vertex surfaces in standard normal or almost normal coordinates into a full set of vertex surfaces in quad or quad-oct coordinates. Typically there are far fewer vertex surfaces in quad or quad-oct coordinates (all of which this routine will find).

The conversion algorithm is described in detail in "Converting between quadrilateral and standard solution sets in normal surface theory", Benjamin A. Burton, Algebr. Geom. Topol. 9 (2009), 2121-2174.

The preconditions for using this transformation:

  • The underlying triangulation is valid, and has no ideal vertices.
  • The input to this transformation is exactly the set of all embedded vertex surfaces in standard normal or almost normal coordinates. This will be checked by examining NormalSurface::coords() and NormalSurface::which().
NS_FILTER_COMPATIBLE 

Selects only the surfaces in the input list that have at least one locally compatible partner.

That is, a surface S from the input list will be included in the output list if and only if there is some other surface T in the input list for which S and T are locally compatible. See NormalSurface::locallyCompatible() for further details on compatibility testing.

Be aware that, since vertex links are compatible with everything, if the input list contains a vertex link plus at least one other surface, then the output list will be identical to the input.

For the output list, which() will include the NS_CUSTOM flag, and algorithm() will be precisely NS_ALG_CUSTOM.

The preconditions for using this transformation:

  • The input list contains only embedded normal or almost normal surfaces. This will be checked by examining NormalSurface::which().
NS_FILTER_DISJOINT 

Selects only the surfaces in the input list that have at least one disjoint partner.

That is, a surface S from the input list will be included in the output list if and only if there is some other surface T in the input list for which S and T can be made to intersect nowhere at all, without changing either normal isotopy class. See NormalSurface::disjoint() for further details on disjointness testing.

This transformation comes with some caveats:

  • It cannot deal with empty, disconnected or non-compact surfaces. Such surfaces will be silently ignored, and will not be used in any disjointness tests (in particular, they will never be considered as a "disjoint partner" for any other surface).
  • Since vertex links can always be made disjoint from other surfaces, if the input list contains a vertex link plus at least one other surface, then the output list will be identical to the input.

For the output list, which() will include the NS_CUSTOM flag, and algorithm() will be precisely NS_ALG_CUSTOM.

The preconditions for using this transformation:

  • The input list contains only embedded normal or almost normal surfaces. This will be checked by examining NormalSurface::which().
NS_FILTER_INCOMPRESSIBLE 

Selects only the surfaces in the input list that "might" represent two-sided incompressible surfaces.

More precisely, this transformation considers all two-sided surfaces in the input list, as well as the two-sided double covers of all one-sided surfaces in the input list (see below for details on how one-sided surfaces are handled). Each of these surfaces is examined using relatively fast heuristic tests for incompressibility. Any surface that is definitely not incompressible is ignored, and all other surfaces are placed in the output list.

Therefore, it is guaranteed that every incompressible surface from the input list will be included in the output list. However, each individual output surface might or might not be incompressible.

See NormalSurface::isIncompressible() for the definition of incompressibility that is used here. Note in particular that spheres are never considered incompressible.

As indicated above, this filter works exclusively with two-sided surfaces. If a surface in the input list is one-sided, the heuristic incompressibility tests will be run on its two-sided double cover. Nevertheless, if the tests pass, the original one-sided surface (not the double cover) will be added to the output list.

Currently the heuristic tests include (i) throwing away all vertex links and thin edge links, and then (ii) cutting along the remaining surfaces and running Triangulation<3>::hasSimpleCompressingDisc() on the resulting bounded triangulations. For more details on these tests see "The Weber-Seifert dodecahedral space is non-Haken", Benjamin A. Burton, J. Hyam Rubinstein and Stephan Tillmann, Trans. Amer. Math. Soc. 364:2 (2012), pp. 911-932.

For the output list, which() will include the NS_CUSTOM flag, and algorithm() will be precisely NS_ALG_CUSTOM.

The preconditions for using this transformation:

  • The underlying 3-manifold triangulation is valid and closed.
  • The input list contains only compact, connected, embedded normal surfaces. In particular, almost normal surfaces are not supported.
Warning
The behaviour of this transformation is subject to change in future versions of Regina, since additional tests may be added to improve the power of this filtering.

◆ SurfaceExportFields

Used to describe a field, or a set of fields, that can be exported alongside a normal surface list.

This enumeration type, and the corresponding flags class SurfaceExport, is used with export routines such as NormalSurfaces::saveCSVStandard() or NormalSurfaces::saveCSVEdgeWeight().

This type describes fields in addition to normal coordinates, not the normal coordinates themselves (which are always exported). Each field describes some property of a single normal surface, and corresponds to a single column in a table of normal surfaces.

You can describe a set of fields by combining the values for individual fields using the bitwise OR operator.

The list of available fields may grow with future releases of Regina.

Enumerator
surfaceExportName 

Represents the user-assigned surface name.

surfaceExportEuler 

Represents the calculated Euler characteristic of a surface.

This will be an integer, and will be left empty if the Euler characteristic cannot be computed.

surfaceExportOrient 

Represents the calculated property of whether a surface is orientable.

This will be the string TRUE or FALSE, or will be left empty if the orientability cannot be computed.

surfaceExportSides 

Represents the calculated property of whether a surface is one-sided or two-sided.

This will be the integer 1 or 2, or will be left empty if the "sidedness" cannot be computed.

surfaceExportBdry 

Represents the calculated property of whether a surface is bounded.

In most cases, this will be one of the strings "closed", "real bdry" or "infinite" (where "infinite" indicates a surface with infinitely many discs). For spun-normal surfaces in certain ideal triangulations, this string will be followed by the boundary slopes of the surface at the cusps: these written as a list of pairs (p, q), one for each cusp, indicating that the boundary curves of the surface run p times around the meridian and q times around the longitude. See NormalSurface::boundaryIntersections() for further information on interpreting these values.

surfaceExportLink 

Represents whether a surface is a single vertex link or a thin edge link.

See NormalSurface::isVertexLink() and NormalSurface::isThinEdgeLink() for details. This will be written as a human-readable string.

surfaceExportType 

Represents any additional high-level properties of a surface, such as whether it is a splitting surface or a central surface.

This will be written as a human-readable string. This field is somewhat arbitrary, and the precise properties it describes are subject to change in future releases of Regina.

surfaceExportNone 

Indicates that no additional fields should be exported.

surfaceExportAllButName 

Indicates that all available fields should be exported, except for the user-assigned surface name.

Since the list of available fields may grow with future releases, the numerical value of this constant may change as a result.

surfaceExportAll 

Indicates that all available fields should be exported, including the user-assigned surface name.

Since the list of available fields may grow with future releases, the numerical value of this constant may change as a result.

◆ SurfaceFilterType

Represents different types of filter classes that can be used to filter lists of normal surfaces in 3-manifold triangulations.

IDs 0-9999 are reserved for future use by Regina. If you are extending Regina to include your own filter class, you should choose an ID >= 10000.

Enumerator
NS_FILTER_LEGACY_DEFAULT 

A legacy constant representing a do-nothing filter that accepts any normal surface.

This type of filter could technically appear in a second-generation Regina data file, though it is unlikely that this feature was ever used in practice (in particular, filters of this type could not be created through the GUI).

NS_FILTER_PROPERTIES 

Represents the SurfaceFilterProperties subclass: a filter that examines simple properties of a normal surface.

NS_FILTER_COMBINATION 

Represents the SurfaceFilterCombination subclass: a filter that combines other filters using boolean AND or OR.

Function Documentation

◆ discOrientationFollowsEdge()

bool regina::discOrientationFollowsEdge ( int  discType,
int  vertex,
int  edgeStart,
int  edgeEnd 
)

Determines whether or not the natural boundary orientation of a normal disc of the given type follows the given directed normal arc.

Natural boundary orientation is defined by arrays regina::triDiscArcs, regina::quadDiscArcs and regina::octDiscArcs.

Precondition
The given normal arc lies on a normal disc of the given type.
Parameters
discTypethe normal disc type under consideration; this should be between 0 and 9 inclusive, as described by the DiscSpec class notes.
vertexthe vertex about which the normal arc runs.
edgeStartthe start vertex of the edge to which the normal arc is parallel.
edgeEndthe end vertex of the edge to which the normal arc is parallel.

◆ makeEmbeddedConstraints()

ValidityConstraints regina::makeEmbeddedConstraints ( const Triangulation< 3 > &  triangulation,
NormalCoords  coords 
)

Generates the validity constraints representing the condition that normal surfaces be embedded.

The validity constraints will be expressed relative to the given coordinate system.

For some coordinate systems, these will include additional constraints of a similar nature (i.e., restricting which combinations of coordinates may be non-zero). For instance, in almost normal coordinates, there will typically be an extra constraint insisting that at most one octagon type is non-zero across the entire triangulation.

These are the constraints that will be used when enumerating embedded surfaces in the given coordinate system (i.e., when the default NS_EMBEDDED_ONLY flag is used). They will not be used when the enumeration allows for immersed and/or singular surfaces.

Parameters
triangulationthe triangulation upon which these validity constraints will be based.
coordsthe coordinate system to be used.
Returns
the set of validity constraints.

◆ makeMatchingEquations()

MatrixInt regina::makeMatchingEquations ( const Triangulation< 3 > &  triangulation,
NormalCoords  coords 
)

Generates the set of normal surface matching equations for the given triangulation using the given coordinate system.

These are the matching equations that will be used when enumerating normal surfaces in the coordinate system coords.

Each equation will be represented as a row of the resulting matrix. Each column of the matrix represents a coordinate in the given coordinate system.

Exceptions
InvalidArgumentthe matching equations could not be created for the given triangulation in the given coordinate system, due to an error that should have been preventable with the right checks in advance. This can only happen in certain coordinate systems, and for all such coordinate systems this is explicitly described in the NormalCoords enum documentation.
UnsolvedCasethe matching equations could not be created for the given triangulation in the given coordinate system, due to an error that was "genuinely" unforseeable. Again this can only happen in certain coordinate systems, where this is explicitly described in the NormalCoords enum documentation.
Parameters
triangulationthe triangulation upon which these matching equations will be based.
coordsthe coordinate system to be used.
Returns
the resulting set of matching equations.

◆ numberDiscsAwayFromVertex()

bool regina::numberDiscsAwayFromVertex ( int  discType,
int  vertex 
)

Determines whether or not normal discs of the given type are numbered away from the given vertex.

Parameters
discTypethe normal disc type under consideration; this should be between 0 and 9 inclusive, as described by the DiscSpec class notes.
vertexthe vertex under consideration; this should be between 0 and 3 inclusive.
Returns
true if normal discs of the given type are numbered away from the given vertex, or false if they are numbered towards the given vertex.

◆ operator<<() [1/3]

std::ostream & regina::operator<< ( std::ostream &  out,
const DiscSpec spec 
)
inline

Writes the given disc specifier to the given output stream.

The disc specifier will be written as a triple (tetIndex, type, number).

Parameters
outthe output stream to which to write.
specthe disc specifier to write.
Returns
a reference to out.

◆ operator<<() [2/3]

std::ostream & regina::operator<< ( std::ostream &  out,
const DiscType type 
)
inline

Writes the given disc type to the given output stream.

The disc type will be written as a pair (tetIndex, type).

Parameters
outthe output stream to which to write.
typethe disc type to write.
Returns
a reference to the given output stream.

◆ operator<<() [3/3]

std::ostream & regina::operator<< ( std::ostream &  out,
const PrismSpec spec 
)
inline

Writes the given prism specifier to the given output stream.

The prism specifier will be written as a pair (tetIndex, edge).

Parameters
outthe output stream to which to write.
specthe prism specifier to write.
Returns
a reference to out.

◆ operator|() [1/3]

NormalAlg regina::operator| ( NormalAlgFlags  lhs,
NormalAlgFlags  rhs 
)
inline

Returns the bitwise OR of the two given flags.

Parameters
lhsthe first flag to combine.
rhsthe second flag to combine.
Returns
the combination of both flags.

◆ operator|() [2/3]

NormalList regina::operator| ( NormalListFlags  lhs,
NormalListFlags  rhs 
)
inline

Returns the bitwise OR of the two given flags.

Parameters
lhsthe first flag to combine.
rhsthe second flag to combine.
Returns
the combination of both flags.

◆ operator|() [3/3]

SurfaceExport regina::operator| ( SurfaceExportFields  lhs,
SurfaceExportFields  rhs 
)
inline

Returns the bitwise OR of the two given flags.

Parameters
lhsthe first flag to combine.
rhsthe second flag to combine.
Returns
the combination of both flags.

◆ swap() [1/6]

template<class T >
void regina::swap ( DiscSetSurfaceDataImpl< T > &  a,
DiscSetSurfaceDataImpl< T > &  b 
)
noexcept

Swaps the contents of the two given disc sets.

This global routine simply calls DiscSetSurfaceDataImpl::swap(); it is provided so that DiscSetSurfaceDataImpl meets the C++ Swappable requirements.

Parameters
athe first disc set whose contents should be swapped.
bthe second disc set whose contents should be swapped.

◆ swap() [2/6]

template<class T >
void regina::swap ( DiscSetTetData< T > &  a,
DiscSetTetData< T > &  b 
)
noexcept

Swaps the contents of the two given disc sets.

This global routine simply calls DiscSetTetData::swap(); it is provided so that DiscSetTetData meets the C++ Swappable requirements.

Parameters
athe first disc set whose contents should be swapped.
bthe second disc set whose contents should be swapped.

◆ swap() [3/6]

void regina::swap ( NormalSurface a,
NormalSurface b 
)
inlinenoexcept

Swaps the contents of the given normal surfaces.

This is a fast (constant time) operation.

This global routine simply calls NormalSurface::swap(); it is provided so that NormalSurface meets the C++ Swappable requirements.

Parameters
athe first normal surface whose contents should be swapped.
bthe second normal surface whose contents should be swapped.

◆ swap() [4/6]

void regina::swap ( NormalSurfaces lhs,
NormalSurfaces rhs 
)
inline

Swaps the contents of the two given lists.

This global routine simply calls NormalSurfaces::swap(); it is provided so that NormalSurfaces meets the C++ Swappable requirements.

See NormalSurfaces::swap() for more details.

Note
This swap function is not marked noexcept, since it fires change events on both lists which may in turn call arbitrary code via any registered packet listeners.
Parameters
lhsthe list whose contents should be swapped with rhs.
rhsthe list whose contents should be swapped with lhs.

◆ swap() [5/6]

void regina::swap ( SurfaceFilterCombination a,
SurfaceFilterCombination b 
)
inline

Swaps the contents of the given combination filters.

This global routine simply calls SurfaceFilterCombination::swap(); it is provided so that SurfaceFilterCombination meets the C++ Swappable requirements.

Parameters
athe first filter whose contents should be swapped.
bthe second filter whose contents should be swapped.

◆ swap() [6/6]

void regina::swap ( SurfaceFilterProperties a,
SurfaceFilterProperties b 
)
inline

Swaps the contents of the given property-based filters.

This global routine simply calls SurfaceFilterProperties::swap(); it is provided so that SurfaceFilterProperties meets the C++ Swappable requirements.

Parameters
athe first filter whose contents should be swapped.
bthe second filter whose contents should be swapped.

Variable Documentation

◆ octDiscArcs

constexpr Perm<4> regina::octDiscArcs[3][8]
inlineconstexpr
Initial value:
= {
Perm<4>(0,3,1,2), Perm<4>(0,1,2,3), Perm<4>(2,0,3,1), Perm<4>(2,3,1,0),
Perm<4>(1,2,0,3), Perm<4>(1,0,3,2), Perm<4>(3,1,2,0), Perm<4>(3,2,0,1),
Perm<4>(0,1,2,3), Perm<4>(0,2,3,1), Perm<4>(3,0,1,2), Perm<4>(3,1,2,0),
Perm<4>(2,3,0,1), Perm<4>(2,0,1,3), Perm<4>(1,2,3,0), Perm<4>(1,3,0,2),
Perm<4>(0,2,3,1), Perm<4>(0,3,1,2), Perm<4>(1,0,2,3), Perm<4>(1,2,3,0),
Perm<4>(3,1,0,2), Perm<4>(3,0,2,1), Perm<4>(2,3,1,0), Perm<4>(2,1,0,3)
}
Represents a permutation of {0,1,2,3}.
Definition: perm4.h:103

Lists in consecutive order the directed normal arcs that form the boundary of each type of octagonal normal disc.

Each permutation p represents an arc about vertex p[0] parallel to the directed edge from p[1] to p[2].

Array octDiscArcs[i] lists the boundary arcs of the octagonal disc of type i. See NormalSurface::octs() for further details.

Note that permutation octDiscArcs[i][j] will be even precisely when j is 0, 1, 4 or 5.

◆ quadDefn

constexpr int regina::quadDefn[3][4]
inlineconstexpr
Initial value:
= {
{ 0, 1, 2, 3 }, { 0, 2, 1, 3 }, { 0, 3, 1, 2 }
}

Lists which vertices each quadrilateral type separates in a tetrahedron.

See regina::quadSeparating and NormalSurface::quads() for more information on quadrilateral types.

Quadrilateral type i splits the vertex pairs quadDefn[i][0,1] and quadDefn[i][2,3].

It is guaranteed that:

  • quadDefn[i][0] < quadDefn[i][1];
  • quadDefn[i][2] < quadDefn[i][3];
  • quadDefn[i][0] < quadDefn[i][2].

This array contains similar information to the function Edge<3>::ordering(). Instead of quadDefn[i][j], you can call Edge<3>::ordering(i)[j]; this will give the same results for j = 0 and 1, but it might switch the results for j = 2 and 3.

◆ quadDiscArcs

constexpr Perm<4> regina::quadDiscArcs[3][4]
inlineconstexpr
Initial value:
= {
Perm<4>(0,2,3,1), Perm<4>(3,0,1,2), Perm<4>(1,3,2,0), Perm<4>(2,1,0,3),
Perm<4>(0,3,1,2), Perm<4>(1,0,2,3), Perm<4>(2,1,3,0), Perm<4>(3,2,0,1),
Perm<4>(0,1,2,3), Perm<4>(2,0,3,1), Perm<4>(3,2,1,0), Perm<4>(1,3,0,2)
}

Lists in consecutive order the directed normal arcs that form the boundary of each type of quadrilateral normal disc.

Each permutation p represents an arc about vertex p[0] parallel to the directed edge from p[1] to p[2].

Array quadDiscArcs[i] lists the boundary arcs of the quadrilateral disc of type i. See NormalSurface::quads() for further details.

Note that permutation quadDiscArcs[i][j] will be even precisely when j is even.

◆ quadMeeting

constexpr int regina::quadMeeting[4][4][2]
inlineconstexpr
Initial value:
= {
{ {-1,-1}, { 1, 2}, { 0, 2}, { 0, 1} },
{ { 1, 2}, {-1,-1}, { 0, 1}, { 0, 2} },
{ { 0, 2}, { 0, 1}, {-1,-1}, { 1, 2} },
{ { 0, 1}, { 0, 2}, { 1, 2}, {-1,-1} }
}

Lists which quadrilateral types meet which edges in a tetrahedron.

See regina::quadSeparating and NormalSurface::quads() for more information on quadrilateral types.

quadMeeting[i][j][0,1] are the numbers of the two quadrilateral types that meet the edge joining tetrahedron vertices i and j.

◆ quadPartner

constexpr int regina::quadPartner[3][4]
inlineconstexpr
Initial value:
= {
{ 1, 0, 3, 2}, { 2, 3, 0, 1}, { 3, 2, 1, 0}
}

Lists the second vertex with which each vertex is paired under each quadrilateral type in a tetrahedron.

See regina::quadSeparating and NormalSurface::quads() for more information on quadrilateral types.

Quadrilateral type i pairs vertex v with vertex quadPartner[i][v].

◆ quadSeparating

constexpr int regina::quadSeparating[4][4]
inlineconstexpr
Initial value:
= {
{ -1, 0, 1, 2 }, { 0,-1, 2, 1 }, { 1, 2,-1, 0 }, { 2, 1, 0,-1 }
}

Lists which quadrilateral types separate which pairs of vertices in a tetrahedron.

As outlined in NormalSurface::quads(), there are three quadrilateral types in a tetrahedron, numbered 0, 1 and 2. Each quadrilateral type separates the four tetrahedron vertices 0,1,2,3 into two pairs. quadSeparating[i][j] is the number of the quadrilateral type that keeps vertices i and j together.

It is guaranteed that quadrilateral type i will keep the vertices of edge i together (and will therefore also keep the vertices of edge 5-i together).

◆ quadString

constexpr char regina::quadString[3][6] = { "01/23", "02/13", "03/12" }
inlineconstexpr

Contains strings that can be used to represent each quadrilateral type in a tetrahedron.

See regina::quadSeparating and NormalSurface::quads() for more information on quadrilateral types.

The string describing quadrilateral type i is quadString[i] and is of the form 02/13, which in this case is the quadrilateral type that splits vertices 0,2 from vertices 1,3.

◆ triDiscArcs

constexpr Perm<4> regina::triDiscArcs[4][3]
inlineconstexpr
Initial value:
= {
Perm<4>(0,1,2,3), Perm<4>(0,2,3,1), Perm<4>(0,3,1,2),
Perm<4>(1,0,3,2), Perm<4>(1,3,2,0), Perm<4>(1,2,0,3),
Perm<4>(2,3,0,1), Perm<4>(2,0,1,3), Perm<4>(2,1,3,0),
Perm<4>(3,2,1,0), Perm<4>(3,1,0,2), Perm<4>(3,0,2,1)
}

Lists in consecutive order the directed normal arcs that form the boundary of each type of triangular normal disc.

Each permutation p represents an arc about vertex p[0] parallel to the directed edge from p[1] to p[2].

Array triDiscArcs[i] lists the boundary arcs of the triangular disc of type i. See NormalSurface::triangles() for further details.

Note that every permutation in this array is even.


Copyright © 1999-2021, The Regina development team
This software is released under the GNU General Public License, with some additional permissions; see the source code for details.
For further information, or to submit a bug or other problem, please contact Ben Burton (bab@maths.uq.edu.au).