diff --git a/doc/SimplicialSurfaces.xml b/doc/SimplicialSurfaces.xml
index 2a878d54..8356b151 100644
--- a/doc/SimplicialSurfaces.xml
+++ b/doc/SimplicialSurfaces.xml
@@ -38,7 +38,6 @@
<#Include SYSTEM "_Chapter_Generating.xml">
<#Include SYSTEM "_Chapter_Library.xml">
<#Include SYSTEM "_Chapter_Graphs.xml">
- <#Include SYSTEM "_Chapter_ConstructingFamilies.xml">
<#Include SYSTEM "_Chapter_Embeddings.xml">
<#Include SYSTEM "_Chapter_AnimationJavaScript.xml">
<#Include SYSTEM "_Chapter_EdgeColouring.xml">
diff --git a/gap/Library/library.gd b/gap/Library/library.gd
index 9e7a7bd0..ed3b7cc6 100644
--- a/gap/Library/library.gd
+++ b/gap/Library/library.gd
@@ -402,282 +402,4 @@ DeclareOperation( "Dodecahedron", [] );
#! @InsertChunk Example_Icosahedron
#!
#! @Returns a simplicial surface
-DeclareOperation( "Icosahedron", [] );
-
-
-
-#! @Section Other pre-defined surfaces
-#! @SectionLabel Library_Uncategorised
-#!
-#! This section contains all other pre-defined surfaces that are not
-#! covered in one of the other sections.
-
-#! @Description
-#! Return a one-face as a simplicial surface. A one-face consists
-#! of one triangular face.
-#!
-#! @Returns a simplicial surface
-DeclareOperation( "OneFace", [] );
-
-#! @Description
-#! Return a butterfly as a simplicial surface. A butterfly consists
-#! of two triangular faces that share an edge.
-#!
-#!
-#! <img src="./images/_Wrapper_Image_Butterfly-1.svg"> </img>
-#!
-#!
-#! \begin{center}
-#! \includegraphics{images/_Wrapper_Image_Butterfly.pdf}
-#! \end{center}
-#!
-#!
-#! Image omitted in terminal text
-#!
-#!
-#! @Returns a simplicial surface
-DeclareOperation( "Butterfly", [] );
-
-
-#! @Description
-#! Return a Janus-Head as a simplicial surface. A Janus-Head consists
-#! of two triangular faces that share three edges.
-#!
-#! @InsertChunk Example_JanusHead
-#!
-#! @Returns a simplicial surface
-DeclareOperation( "JanusHead", [] );
-
-
-#!
-#!
-#!
-#! a simplicial surface
-#!
-#! Return a simplicial surface consisting of one closed umbrella-path
-#! with nrFaces triangles. The labels are assigned according
-#! to the following illustration, in which n is nrFaces:
-#!
-#! <br><img src='./images/_Wrapper_library-1-1.svg'> </img> <br>
-#!
-#!
-#! \begin{center}
-#! \includegraphics{images/_Wrapper_library-1.pdf}
-#! \end{center}
-#!
-#!
-#! Image omitted in terminal text
-#!
-#!
-#! @ExampleSession
-#! gap> umb4 := SimplicialUmbrella(4);
-#! simplicial surface (5 vertices, 8 edges, and 4 faces)
-#! gap> VerticesOfEdges(umb4);
-#! [ [ 1, 5 ], [ 2, 5 ], [ 3, 5 ], [ 4, 5 ], [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 1, 4 ] ]
-#! gap> EdgesOfFaces(umb4);
-#! [ [ 1, 2, 5 ], [ 2, 3, 6 ], [ 3, 4, 7 ], [ 1, 4, 8 ] ]
-#! gap> VerticesOfFaces(umb4);
-#! [ [ 1, 2, 5 ], [ 2, 3, 5 ], [ 3, 4, 5 ], [ 1, 4, 5 ] ]
-#! gap> umb2 := SimplicialUmbrella(2);
-#! simplicial surface (3 vertices, 4 edges, and 2 faces)
-#! gap> VerticesOfEdges(umb2);
-#! [ [ 1, 3 ], [ 2, 3 ], [ 1, 2 ], [ 1, 2 ] ]
-#! gap> EdgesOfFaces(umb2);
-#! [ [ 1, 2, 3 ], [ 1, 2, 4 ] ]
-#! @EndExampleSession
-#!
-#!
-# here no AutoDoc documentation since synonyms can't be handled automatically
-DeclareOperation("SimplicialUmbrella", [ IsPosInt ] );
-DeclareSynonym("SimplicialGon", SimplicialUmbrella);
-
-#!
-#!
-#!
-#! a simplicial surface
-#!
-#! Return a simplicial surface consisting of two closed umbrella-paths
-#! with nrFaces triangles which are joined at their boundary.
-#! The labels of one umbrella are assigned according to the illustration for SimplicialUmbrella,
-#! the additional vertex is labelled with nrFaces+2, the incident edges to this vertex
-#! are labelled from 2*nrFaces+1 to 4*nrFaces and the incident faces are labelled from
-#! nrFaces+1 to 2*nrFaces.
-#! @ExampleSession
-#! gap> doubleumb2:=SimplicialDoubleUmbrella(2);
-#! simplicial surface (4 vertices, 6 edges, and 4 faces)
-#! gap> VerticesOfEdges(doubleumb2);
-#! [ [ 1, 3 ], [ 2, 3 ], [ 1, 2 ], [ 1, 2 ], [ 1, 4 ], [ 2, 4 ] ]
-#! gap> EdgesOfFaces(doubleumb2);
-#! [ [ 1, 2, 3 ], [ 1, 2, 4 ], [ 3, 5, 6 ], [ 4, 5, 6 ] ]
-#! gap> doubleumb4:=SimplicialDoubleUmbrella(4);
-#! simplicial surface (6 vertices, 12 edges, and 8 faces)
-#! gap> IsIsomorphic(doubleumb4,Octahedron());
-#! true
-#! @EndExampleSession
-#!
-#!
-# here no AutoDoc documentation since synonyms can't be handled automatically
-DeclareOperation("SimplicialDoubleUmbrella", [ IsPosInt ] );
-DeclareSynonym("SimplicialDoubleGon", SimplicialDoubleUmbrella);
-
-#! @BeginGroup SimplicialOpenGeodesic
-#! @Description
-#! Return a simplicial surface consisting of one non-closed geodesic-path
-#! with nrFaces triangles. The labels are assigned according
-#! to the following illustration (for n odd),
-#! in which n is nrFaces.
-#!
-#! <br><img src="./images/_Wrapper_Image_SimplicialOpenGeodesic-1.svg"> </img> <br>
-#!
-#!
-#! \begin{center}
-#! \includegraphics{images/_Wrapper_Image_SimplicialOpenGeodesic.pdf}
-#! \end{center}
-#!
-#!
-#! Image omitted in terminal text
-#!
-#!
-#! @ExampleSession
-#! gap> geo4 := SimplicialOpenGeodesic(4);
-#! simplicial surface (6 vertices, 9 edges, and 4 faces)
-#! gap> VerticesOfEdges(geo4);
-#! [ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 2, 4 ], [ 3, 4 ], [ 3, 5 ], [ 4, 5 ],
-#! [ 4, 6 ], [ 5, 6 ] ]
-#! gap> EdgesOfFaces(geo4);
-#! [ [ 1, 2, 3 ], [ 3, 4, 5 ], [ 5, 6, 7 ], [ 7, 8, 9 ] ]
-#! gap> VerticesOfFaces(geo4);
-#! [ [ 1, 2, 3 ], [ 2, 3, 4 ], [ 3, 4, 5 ], [ 4, 5, 6 ] ]
-#! gap>
-#! gap> geo5 := SimplicialStrip(5);
-#! simplicial surface (7 vertices, 11 edges, and 5 faces)
-#! gap> VerticesOfEdges(geo5);
-#! [ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 2, 4 ], [ 3, 4 ], [ 3, 5 ], [ 4, 5 ],
-#! [ 4, 6 ], [ 5, 6 ], [ 5, 7 ], [ 6, 7 ] ]
-#! gap> EdgesOfFaces(geo5);
-#! [ [ 1, 2, 3 ], [ 3, 4, 5 ], [ 5, 6, 7 ], [ 7, 8, 9 ], [ 9, 10, 11 ] ]
-#! @EndExampleSession
-#!
-#!
-#! @Returns a simplicial surface
-#! @Arguments nrFaces
-DeclareOperation( "SimplicialOpenGeodesic", [ IsPosInt ] );
-#! @Arguments nrFaces
-DeclareOperation( "SimplicialStrip", [ IsPosInt ] );
-#! @EndGroup
-
-#! @BeginGroup SimplicialClosedGeodesic
-#! @Description
-#! Return a simplicial surface consisting of one closed geodesic-path
-#! with nrFaces triangles (at least 3 faces are needed).
-#! The labels are assigned according
-#! to the following illustration (for n odd),
-#! in which n is nrFaces.
-#!
-#! <br><img src="./images/_Wrapper_Image_SimplicialClosedGeodesic-1.svg"> </img> <br>
-#!
-#!
-#! \begin{center}
-#! \includegraphics{images/_Wrapper_Image_SimplicialClosedGeodesic.pdf}
-#! \end{center}
-#!
-#!
-#! Image omitted in terminal text
-#!
-#!
-#! @ExampleSession
-#! gap> geo3 := SimplicialClosedGeodesic(3);
-#! simplicial surface (3 vertices, 6 edges, and 3 faces)
-#! gap> VerticesOfEdges(geo3);
-#! [ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 1, 2 ], [ 1, 3 ], [ 2, 3 ] ]
-#! gap> EdgesOfFaces(geo3);
-#! [ [ 1, 2, 3 ], [ 3, 4, 5 ], [ 1, 5, 6 ] ]
-#! gap> VerticesOfFaces(geo3);
-#! [ [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ] ]
-#! gap>
-#! gap> geo6 := SimplicialGeodesic(6);
-#! simplicial surface (6 vertices, 12 edges, and 6 faces)
-#! gap> VerticesOfEdges(geo6);
-#! [ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 2, 4 ], [ 3, 4 ], [ 3, 5 ], [ 4, 5 ],
-#! [ 4, 6 ], [ 5, 6 ], [ 1, 5 ], [ 1, 6 ], [ 2, 6 ] ]
-#! gap> EdgesOfFaces(geo6);
-#! [ [ 1, 2, 3 ], [ 3, 4, 5 ], [ 5, 6, 7 ], [ 7, 8, 9 ], [ 9, 10, 11 ], [ 1, 11, 12 ] ]
-#! @EndExampleSession
-#!
-#!
-#! @Returns a simplicial surface
-#! @Arguments nrFaces
-DeclareOperation( "SimplicialClosedGeodesic", [ IsPosInt ] );
-#! @Arguments nrFaces
-DeclareOperation( "SimplicialGeodesic", [ IsPosInt ] );
-#! @EndGroup
-
-#! @BeginGroup SimplexRingByIsomorphismType
-#! @Description
-#! This method constructs a simplex ring given its isomorphism type.
-#! A simplicial surface is a simplex ring if it is connected and each face
-#! has exactly one inner and two outer edges.
-#! They can be described uniquely by their isomorphism type which is a list
-#! [n_1,...,n_k].
-#! The simplex ring with isomorphism type [n_1,...,n_k] has n_1+...+n_k faces
-#! and is constructed based on a closed geodesic with k faces where the i-th faces is subdivided in n_i
-#! faces. How the subdivision is defined can be seen in the picture below.
-#! The incidences between vertices and faces can also be observed there.
-#!
-#! As an example consider the simplex ring with isomorphism type [1,2,3], where the left and right edge have to be identified:
-#!
-#! <br><img src="./images/_Wrapper_Image_SimplexString-1.svg"> </img> <br>
-#!
-#!
-#! \begin{center}
-#! \includegraphics{images/_Wrapper_Image_SimplexString.pdf}
-#! \end{center}
-#!
-#!
-#! Image omitted in terminal text
-#!
-#! @BeginExampleSession
-#! gap> ring:=SimplexRingByIsomorphismType([1,2,3]);
-#! simplicial surface (6 vertices, 12 edges, and 6 faces)
-#! gap> UmbrellaDescriptorOfSurface(ring);
-#! [ [ 2, 1, 6 ], [ 1, 2, 3, 4 ], [ 2, 3 ], [ 1, 6, 5, 4, 3 ], [ 4, 5 ], [ 5, 6 ] ]
-#! gap> IsClosedSurface(ring);
-#! false
-#! gap> IsOrientableSurface(ring);
-#! false
-#! gap> IsSimplexRing(ring);
-#! true
-#! @EndExampleSession
-#!
-#! @Returns a simplicial surface
-#! @Arguments isomorphismType
-DeclareOperation( "SimplexRingByIsomorphismType", [IsList] );
-#! @EndGroup
-
-#! @BeginGroup SimplexStringByIsomorphismType
-#! @Description
-#! This method constructs a simplex string given its isomorphism type.
-#! A simplicial surface is a simplex string if it is connected and it is a face or
-#! exactly two of its faces (end faces) have two boundary edges and all other
-#! faces have exactly one inner and two outer edges.
-#! They can be described uniquely by their isomorphism type which is a list
-#! [n_1,...,n_k].
-#! The simplex string with isomorphism type [n_1,...,n_k] has n_1+...+n_k faces
-#! and is constructed based on a strip with k faces where the i-th faces is subdivided in n_i
-#! faces, as shown in .
-#!
-#! As an example consider the simplex string with isomorphism type [1,2,3]:
-#! @BeginExampleSession
-#! gap> string:=SimplexStringByIsomorphismType([1,2,3]);
-#! simplicial surface (8 vertices, 13 edges, and 6 faces)
-#! gap> UmbrellaDescriptorOfSurface(string);
-#! [ [ 1 ], [ 1, 2 ], [ 4, 3, 2, 1 ], [ 2, 3 ], [ 3, 4, 5, 6 ], [ 4, 5 ], [ 5, 6 ],
-#! [ 6 ] ]
-#! gap> IsSimplexString(string);
-#! true
-#! @EndExampleSession
-#!
-#! @Returns a simplicial surface
-#! @Arguments isomorphismType
-DeclareOperation( "SimplexStringByIsomorphismType", [IsList] );
-#! @EndGroup
\ No newline at end of file
+DeclareOperation( "Icosahedron", [] );
\ No newline at end of file
diff --git a/gap/Library/library.gi b/gap/Library/library.gi
index 7cc84073..ddead4d0 100644
--- a/gap/Library/library.gi
+++ b/gap/Library/library.gi
@@ -777,215 +777,4 @@ InstallMethod( Icosahedron, "", [], function()
##
## End platonic surfaces
##
-#######################################
-
-
-#######################################
-##
-## Other examples
-##
-InstallMethod( OneFace, "", [], function()
- return SimplicialSurfaceByVerticesInFaces( [[1,2,3]] );
- end
-);
-
-InstallMethod( Butterfly, "", [], function()
- return SimplicialSurfaceByVerticesInFaces( [[1,2,3],[1,3,4]] );
- end
-);
-
-InstallMethod( JanusHead, "", [], function()
- return SimplicialSurfaceByVerticesInFaces( 3, 2,
- [ [1,2,3], [1,2,3] ] );
- end
-);
-
-InstallMethod( SimplicialUmbrella, "for an integer at least 2", [IsPosInt],
- function(nrFaces)
- local verticesOfEdges, edgesOfFaces, i;
-
- if nrFaces = 1 then
- Error("SimplicialUmbrella: Argument has to be greater than 1.");
- fi;
-
- verticesOfEdges := [];
- edgesOfFaces := [];
- for i in [1..nrFaces-1] do
- verticesOfEdges[i] := [i, nrFaces+1];
- verticesOfEdges[nrFaces+i] := [i,i+1];
-
- edgesOfFaces[i] := [i,i+1,nrFaces+i];
- od;
- verticesOfEdges[nrFaces] := [nrFaces, nrFaces+1];
- verticesOfEdges[2*nrFaces] := [1, nrFaces];
-
- edgesOfFaces[nrFaces] := [1,nrFaces, 2*nrFaces];
-
- return SimplicialSurfaceByDownwardIncidenceNC([1..nrFaces+1],
- [1..2*nrFaces], [1..nrFaces], verticesOfEdges, edgesOfFaces);
- end
-);
-
-InstallMethod(SimplicialDoubleUmbrella, "for an integer at least 2", [IsPosInt],
- function(nrFaces)
- local umbr, verticesOfEdges, edgesOfFaces, i;
-
- if nrFaces = 1 then
- Error("SimplicialUmbrella: Argument has to be greater than 1.");
- fi;
-
- umbr:=SimplicialUmbrella(nrFaces);
- verticesOfEdges:=ShallowCopy(VerticesOfEdges(umbr));
- edgesOfFaces:=ShallowCopy(EdgesOfFaces(umbr));
-
- for i in [1..nrFaces-1] do
- edgesOfFaces[i+nrFaces] := [i+nrFaces,2*nrFaces+i,2*nrFaces+i+1];
-
- verticesOfEdges[2*nrFaces+i] := [i,nrFaces+2];
- od;
- edgesOfFaces[2*nrFaces] := [2*nrFaces,2*nrFaces+nrFaces, 2*nrFaces+1];
- verticesOfEdges[2*nrFaces+nrFaces]:=[nrFaces, nrFaces+2];
-
- return SimplicialSurfaceByDownwardIncidenceNC(verticesOfEdges, edgesOfFaces);
-end);
-
-
-InstallMethod( SimplicialOpenGeodesic, "for an integer at least 1", [IsPosInt],
- function(nrFaces)
- local verticesOfFaces;
-
- verticesOfFaces := List([1..nrFaces], i -> [i,i+1,i+2]);
-
- return SimplicialSurfaceByVerticesInFacesNC([1..nrFaces+2], [1..nrFaces], verticesOfFaces);
- end
-);
-InstallMethod( SimplicialStrip, "for an integer at least 1", [IsPosInt],
- function(nrFaces)
- return SimplicialOpenGeodesic(nrFaces);
- end
-);
-
-InstallMethod( SimplicialClosedGeodesic, "for an integer at least 3", [IsPosInt],
- function(nrFaces)
- local verticesOfEdges, edgesOfFaces, i;
-
- if nrFaces < 3 then
- Error("SimplicialClosedGeodesic: Argument has to be greater than 2.");
- fi;
-
- verticesOfEdges := [];
- for i in [1..nrFaces-1] do
- verticesOfEdges[2*i-1] := [i, i+1];
- verticesOfEdges[2*i] := [i, i+2];
- od;
- verticesOfEdges[2*nrFaces-2] := [1,nrFaces-1];
- verticesOfEdges[2*nrFaces-1] := [1,nrFaces];
- verticesOfEdges[2*nrFaces] := [2,nrFaces];
-
- edgesOfFaces := List([1..nrFaces-1], i -> [2*i-1,2*i,2*i+1]);
- edgesOfFaces[nrFaces] := [1,2*nrFaces-1,2*nrFaces];
-
- return SimplicialSurfaceByDownwardIncidenceNC([1..nrFaces],
- [1..2*nrFaces], [1..nrFaces], verticesOfEdges, edgesOfFaces);
- end
-);
-InstallMethod( SimplicialGeodesic, "for an integer at least 3", [IsPosInt],
- function(nrFaces)
- return SimplicialClosedGeodesic(nrFaces);
- end
-);
-
-# The length of the given list defines the number of faces in the geodesic which is subdivided
-# The i-th entry defines in how many faces the i-th face of the geodesic subdivided
-InstallMethod( SimplexRingByIsomorphismType, "for a list",[IsList],
- function(list)
- local k, sum, m, umbr, i, u, j;
- if 0 in list then
- Error("This is not a valid isomorphism type for a simplex ring.");
- fi;
- k:=Length(list);
- sum:= Sum(list); # number of the faces n=n_1+...+n_k
- m:=0; # number of faces that are used so far
- umbr:=[];
- # constructing the umbrella descriptor
- if k > 2 then
- # go through all n_i
- for i in [1..k] do
- # constructing the umbrella of the essential vertex
- u:=[(m-1) mod sum +1]; # adding the predecessor face
- for j in [1..list[i]+1] do # adding the faces made by subdivision and the last face to the umbrella
- Add(u, (m+j-1)mod sum +1);
- od;
- Add(umbr,u);
- # constructing the umbrella of the inessential vertices
- if list[i]>1 then
- for j in [1..list[i]-1] do
- m:=m+1;
- u:=[m,m+1];
- #u:=[(m-1) mod sum+1,m mod sum+1]; # each umbrella has only those two faces
- Add(umbr,u);
- od;
- m:=m+1;
- else
- m:=m+list[i];
- fi;
- od;
- return SimplicialSurfaceByUmbrellaDescriptor(umbr);
- elif k=1 then
- return SimplicialUmbrella(list[1]);
- else
- Error("This is not a valid isomorphism type for a simplex ring.");
- fi;
-end);
-
-
-# The length of the given list defines the number of faces in the strip which is subdivided
-# The i-th entry defines in how many faces the i-th face of the strip subdivided
-InstallMethod( SimplexStringByIsomorphismType, "for a list",[IsList],
- function(list)
- local k, sum, m, umbr, i, u, j;
- if 0 in list then
- Error("This is not a valid isomorphism type for a simplex string.");
- fi;
- k:=Length(list);
- sum:= Sum(list); # number of the faces n=n_1+...+n_k
- m:=0; # number of faces that are used so far
- umbr:=[[1]];
- # constructing the umbrella descriptor
- if k > 2 then
- # go through all n_i
- for i in [1..k] do
- # constructing the umbrella of the essential vertex
- if i>1 then
- u:=[(m-1) mod sum +1];
- else
- u:=[];
- fi;
- for j in [1..list[i]] do # adding the faces made by subdivision and the last face to the umbrella
- Add(u, (m+j-1)mod sum +1);
- od;
- if i<>k then
- Add(u, m+list[i]+1);
- fi;
- Add(umbr,u);
- # constructing the umbrella of the inessential vertices
- if list[i]>1 then
- for j in [1..list[i]-1] do
- m:=m+1;
- u:=[m,m+1]; # each umbrella has only those two faces
- Add(umbr,u);
- od;
- m:=m+1;
- else
- m:=m+list[i];
- fi;
- od;
- Add(umbr,[m]);
- #Error();
- return SimplicialSurfaceByUmbrellaDescriptor(umbr);
- elif k=1 then
- #return SimplicialOneFace();
- else
- Error("This is not a valid isomorphism type for a simplex ring.");
- fi;
-end);
\ No newline at end of file
+#######################################
\ No newline at end of file
diff --git a/gap/PolygonalComplexes/constructing_families.gd b/gap/PolygonalComplexes/constructing_families.gd
index 28c57569..f225f0ea 100644
--- a/gap/PolygonalComplexes/constructing_families.gd
+++ b/gap/PolygonalComplexes/constructing_families.gd
@@ -1,8 +1,340 @@
-#! @Chapter Constructing Families of Simplicial Surfaces
-#! @ChapterLabel ConstructingFamilies
-#! @Section CombinatorialEmbeddings
-#! @SectionLabel LabelEmbeddings
-#! @BeginGroup Reembeddings
+#! @Chapter Generating certain simplicial surfaces
+#! @ChapterLabel Generating
+
+#! This chapter introduces methods to find all simplicial surfaces with certain
+#! restrictions.
+#! Section includes several constuction
+#! methods for simplex rings and strings.
+#! In Section
+#! all simplicial surfaces for a given vertex-faithful simplicial surface
+#! are constructed which can be generated by using essential butterfly insertion.
+#! Simplicial surfaces which have isomorphic face graphs are computed in
+#! Section by using different approaches.
+
+#! @Section Simplex String and Rings
+#! @SectionLabel Strings_Rings
+
+#! This section includes different possibilities to construct simplex string and rings.
+#! A simplex string is a simplicial surface that it is connected and it is a single triangle or
+#! exactly two of its faces (end faces) have two boundary edges and all other
+#! faces have exactly one inner and two outer edges.
+#! If all vertices of a simplex string have degree at least three, it is called a
+#!simplicial strip or open geodesic.
+#! A simplicial surface is a simplex ring if it is connected and each face
+#! has exactly one inner and two outer edges. If all vertices of a simplex ring have
+#! degree 3, it is called a (closed) geodesic.
+#! Note that a simplicial umbrella is a simplex ring with exactly one inner vertex.
+
+#! @BeginGroup SimplexStringByIsomorphismType
+#! @Description
+#! This method constructs a simplex string given its isomorphism type.
+#! Simplex strings can be described uniquely by their isomorphism type which is a list
+#! [n_1,...,n_k].
+#! The simplex string with isomorphism type [n_1,...,n_k] has n_1+...+n_k faces
+#! and is constructed based on a strip with k faces where the i-th faces is subdivided in n_i
+#! faces, as shown in .
+#!
+#! As an example consider the simplex string with isomorphism type [1,2,3]:
+#! @BeginExampleSession
+#! gap> string:=SimplexStringByIsomorphismType([1,2,3]);
+#! simplicial surface (8 vertices, 13 edges, and 6 faces)
+#! gap> UmbrellaDescriptorOfSurface(string);
+#! [ [ 1 ], [ 1, 2 ], [ 4, 3, 2, 1 ], [ 2, 3 ], [ 3, 4, 5, 6 ], [ 4, 5 ], [ 5, 6 ],
+#! [ 6 ] ]
+#! gap> IsSimplexString(string);
+#! true
+#! @EndExampleSession
+#!
+#! @Returns a simplicial surface
+#! @Arguments isomorphismType
+DeclareOperation( "SimplexStringByIsomorphismType", [IsList] );
+#! @EndGroup
+
+#! @BeginGroup SimplicialOpenGeodesic
+#! @Description
+#! Return a simplicial surface consisting of one non-closed geodesic-path
+#! with nrFaces triangles. The labels are assigned according
+#! to the following illustration (for n odd),
+#! in which n is nrFaces.
+#!
+#! <br><img src="./images/_Wrapper_Image_SimplicialOpenGeodesic-1.svg"> </img> <br>
+#!
+#!
+#! \begin{center}
+#! \includegraphics{images/_Wrapper_Image_SimplicialOpenGeodesic.pdf}
+#! \end{center}
+#!
+#!
+#! Image omitted in terminal text
+#!
+#!
+#! @ExampleSession
+#! gap> geo4 := SimplicialOpenGeodesic(4);
+#! simplicial surface (6 vertices, 9 edges, and 4 faces)
+#! gap> VerticesOfEdges(geo4);
+#! [ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 2, 4 ], [ 3, 4 ], [ 3, 5 ], [ 4, 5 ],
+#! [ 4, 6 ], [ 5, 6 ] ]
+#! gap> EdgesOfFaces(geo4);
+#! [ [ 1, 2, 3 ], [ 3, 4, 5 ], [ 5, 6, 7 ], [ 7, 8, 9 ] ]
+#! gap> VerticesOfFaces(geo4);
+#! [ [ 1, 2, 3 ], [ 2, 3, 4 ], [ 3, 4, 5 ], [ 4, 5, 6 ] ]
+#! gap>
+#! gap> geo5 := SimplicialStrip(5);
+#! simplicial surface (7 vertices, 11 edges, and 5 faces)
+#! gap> VerticesOfEdges(geo5);
+#! [ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 2, 4 ], [ 3, 4 ], [ 3, 5 ], [ 4, 5 ],
+#! [ 4, 6 ], [ 5, 6 ], [ 5, 7 ], [ 6, 7 ] ]
+#! gap> EdgesOfFaces(geo5);
+#! [ [ 1, 2, 3 ], [ 3, 4, 5 ], [ 5, 6, 7 ], [ 7, 8, 9 ], [ 9, 10, 11 ] ]
+#! @EndExampleSession
+#!
+#!
+#! @Returns a simplicial surface
+#! @Arguments nrFaces
+DeclareOperation( "SimplicialOpenGeodesic", [ IsPosInt ] );
+#! @Arguments nrFaces
+DeclareOperation( "SimplicialStrip", [ IsPosInt ] );
+#! @EndGroup
+
+#! @BeginGroup SimplexRingByIsomorphismType
+#! @Description
+#! This method constructs a simplex ring given its isomorphism type.
+#! They can be described uniquely by their isomorphism type which is a list
+#! [n_1,...,n_k].
+#! The simplex ring with isomorphism type [n_1,...,n_k] has n_1+...+n_k faces
+#! and is constructed based on a closed geodesic with k faces where the i-th faces is subdivided in n_i
+#! faces. How the subdivision is defined can be seen in the picture below.
+#! The incidences between vertices and faces can also be observed there.
+#!
+#! As an example consider the simplex ring with isomorphism type [1,2,3], where the left and right edge have to be identified:
+#!
+#! <br><img src="./images/_Wrapper_Image_SimplexString-1.svg"> </img> <br>
+#!
+#!
+#! \begin{center}
+#! \includegraphics{images/_Wrapper_Image_SimplexString.pdf}
+#! \end{center}
+#!
+#!
+#! Image omitted in terminal text
+#!
+#! @BeginExampleSession
+#! gap> ring:=SimplexRingByIsomorphismType([1,2,3]);
+#! simplicial surface (6 vertices, 12 edges, and 6 faces)
+#! gap> UmbrellaDescriptorOfSurface(ring);
+#! [ [ 2, 1, 6 ], [ 1, 2, 3, 4 ], [ 2, 3 ], [ 1, 6, 5, 4, 3 ], [ 4, 5 ], [ 5, 6 ] ]
+#! gap> IsClosedSurface(ring);
+#! false
+#! gap> IsOrientableSurface(ring);
+#! false
+#! gap> IsSimplexRing(ring);
+#! true
+#! @EndExampleSession
+#!
+#! @Returns a simplicial surface
+#! @Arguments isomorphismType
+DeclareOperation( "SimplexRingByIsomorphismType", [IsList] );
+#! @EndGroup
+
+#! @BeginGroup SimplicialClosedGeodesic
+#! @Description
+#! Return a simplicial surface consisting of one closed geodesic-path
+#! with nrFaces triangles (at least 3 faces are needed).
+#! The labels are assigned according
+#! to the following illustration (for n odd),
+#! in which n is nrFaces.
+#!
+#! <br><img src="./images/_Wrapper_Image_SimplicialClosedGeodesic-1.svg"> </img> <br>
+#!
+#!
+#! \begin{center}
+#! \includegraphics{images/_Wrapper_Image_SimplicialClosedGeodesic.pdf}
+#! \end{center}
+#!
+#!
+#! Image omitted in terminal text
+#!
+#!
+#! @ExampleSession
+#! gap> geo3 := SimplicialClosedGeodesic(3);
+#! simplicial surface (3 vertices, 6 edges, and 3 faces)
+#! gap> VerticesOfEdges(geo3);
+#! [ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 1, 2 ], [ 1, 3 ], [ 2, 3 ] ]
+#! gap> EdgesOfFaces(geo3);
+#! [ [ 1, 2, 3 ], [ 3, 4, 5 ], [ 1, 5, 6 ] ]
+#! gap> VerticesOfFaces(geo3);
+#! [ [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ] ]
+#! gap>
+#! gap> geo6 := SimplicialGeodesic(6);
+#! simplicial surface (6 vertices, 12 edges, and 6 faces)
+#! gap> VerticesOfEdges(geo6);
+#! [ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 2, 4 ], [ 3, 4 ], [ 3, 5 ], [ 4, 5 ],
+#! [ 4, 6 ], [ 5, 6 ], [ 1, 5 ], [ 1, 6 ], [ 2, 6 ] ]
+#! gap> EdgesOfFaces(geo6);
+#! [ [ 1, 2, 3 ], [ 3, 4, 5 ], [ 5, 6, 7 ], [ 7, 8, 9 ], [ 9, 10, 11 ], [ 1, 11, 12 ] ]
+#! @EndExampleSession
+#!
+#!
+#! @Returns a simplicial surface
+#! @Arguments nrFaces
+DeclareOperation( "SimplicialClosedGeodesic", [ IsPosInt ] );
+#! @Arguments nrFaces
+DeclareOperation( "SimplicialGeodesic", [ IsPosInt ] );
+#! @EndGroup
+
+#!
+#!
+#!
+#! a simplicial surface
+#!
+#! Returns a simplex ring with nrFaces and exactly one inner vertex.
+#! The labels are assigned according to the following illustration, in which
+#! n is nrFaces:
+#!
+#! <br><img src='./images/_Wrapper_library-1-1.svg'> </img> <br>
+#!
+#!
+#! \begin{center}
+#! \includegraphics{images/_Wrapper_library-1.pdf}
+#! \end{center}
+#!
+#!
+#! Image omitted in terminal text
+#!
+#!
+#! @ExampleSession
+#! gap> umb4 := SimplicialUmbrella(4);
+#! simplicial surface (5 vertices, 8 edges, and 4 faces)
+#! gap> VerticesOfEdges(umb4);
+#! [ [ 1, 5 ], [ 2, 5 ], [ 3, 5 ], [ 4, 5 ], [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 1, 4 ] ]
+#! gap> EdgesOfFaces(umb4);
+#! [ [ 1, 2, 5 ], [ 2, 3, 6 ], [ 3, 4, 7 ], [ 1, 4, 8 ] ]
+#! gap> VerticesOfFaces(umb4);
+#! [ [ 1, 2, 5 ], [ 2, 3, 5 ], [ 3, 4, 5 ], [ 1, 4, 5 ] ]
+#! gap> umb2 := SimplicialUmbrella(2);
+#! simplicial surface (3 vertices, 4 edges, and 2 faces)
+#! gap> VerticesOfEdges(umb2);
+#! [ [ 1, 3 ], [ 2, 3 ], [ 1, 2 ], [ 1, 2 ] ]
+#! gap> EdgesOfFaces(umb2);
+#! [ [ 1, 2, 3 ], [ 1, 2, 4 ] ]
+#! @EndExampleSession
+#!
+#!
+# here no AutoDoc documentation since synonyms can't be handled automatically
+DeclareOperation("SimplicialUmbrella", [ IsPosInt ] );
+DeclareSynonym("SimplicialGon", SimplicialUmbrella);
+
+
+#! @Section Generation by butterfly insertion
+#! @SectionLabel Generating_Butterfly_Insertion
+
+#! This section contains a method to compute for a given vertex-faithful
+#! simplicial surface all simplicial surfaces that can be constructed by
+#! essential butterfly insertions.
+
+#! @BeginGroup AllSimplicialSurfacesByEssentialButterflyInsertion
+#! @Description
+#! This function computes representatives of the isomorphism classes of
+#! all simplicial surfaces that can be obtained from
+#! the input surface surf by an essential butterfly insertion.
+#! Note that the input surface surf has to be vertex-faithful.
+#! An essential butterfly insertion is a butterfly insertion that does not
+#! create a 3-waist.
+#!
+#! @BeginLogSession
+#! gap> surface := SimplicialSurfaceByDownwardIncidence(
+#! > [ [ 1, 3 ], [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ],
+#! > [ 2, 6 ], [ 2, 7 ], [ 3, 7 ], [ 3, 8 ], [ 4, 8 ], [ 4, 5 ], [ 5, 6 ],
+#! > [ 6, 7 ], [ 7, 8 ], [ 5, 8 ] ],
+#! > [ [1, 2, 3], [1, 4, 5], [6, 7, 14], [2, 7, 8], [8, 9, 15],
+#! > [3, 9, 10], [10, 11, 16], [4, 11, 12], [12, 13, 17], [5, 6, 13] ]);
+#! simplicial surface (8 vertices, 17 edges, and 10 faces)
+#! gap> IsConnectedSurface(surface);
+#! true
+#! gap> EulerCharacteristic(surface);
+#! 1
+#! gap> AllSimplicialSurfacesByEssentialButterflyInsertion(surface);
+#! [ simplicial surface (9 vertices, 20 edges, and 12 faces),
+#! simplicial surface (9 vertices, 20 edges, and 12 faces)
+#! , simplicial surface (9 vertices, 20 edges, and 12 faces),
+#! simplicial surface (9 vertices, 20 edges, and 12 faces) ]
+#! @EndLogSession
+#! @Arguments surface
+#! @Returns a list of simplicial surfaces
+DeclareOperation( "AllSimplicialSurfacesByEssentialButterflyInsertion", [IsSimplicialSurface] );
+#! @EndGroup
+
+
+
+#! @Section Edge-Face equivalent simplicial surfaces
+#! @SectionLabel Edge_Face_Equivalent
+
+#! This section contains method to compute edge-face equivalent simplicial surfaces.
+#! Two simplicial surfaces are called edge-face equivalent if their face-graphs are isomorphic.
+
+#! @BeginGroup AllSimplicialSurfacesOfDigraph
+#! @Description
+#! Return all (vertex-faithful) simplicial surfaces, that have digraph as face graph or are edge-face
+#! equivalent to surface.
+#! Note that digraph has to be cubic, connected, symmetric and simple and surface has to
+#! be a closed surface.
+#! The parameter vertexfaithful indicates whether only vertex-faithful simplicial surfaces are searched,
+#! where the default value is false.
+#! The vertices of a simplicial surface can be identified with certain cycles in the face graph.
+#! This method searches possible combinations of cycles, with the cycles corresponding to the vertices
+#! of a simplicial surface.
+#!
+#!
+#! For example, consider the complete graph on four nodes:
+#!
+#! <br><img src="./images/_Wrapper_Image_FaceGraphTetra-1.svg"> </img> <br>
+#!
+#!
+#! \begin{center}
+#! \includegraphics{images/_Wrapper_Image_FaceGraphTetra.pdf}
+#! \end{center}
+#!
+#!
+#! Image omitted in terminal text
+#!
+#!
+#! @BeginLogSession
+#! gap> digraph:=CompleteDigraph(4);;
+#! gap> tet1 := AllSimplicialSurfacesOfDigraph(digraph,true);
+#! [ simplicial surface (4 vertices, 6 edges, and 4 faces) ]
+#! gap> IsIsomorphic(tet1[1],Tetrahedron());
+#! true
+#! @EndLogSession
+#! So the only vertex-faithful simplicial surface of the digraph is the tetrahedron.
+#! But there is another simplicial surface, which is not vertex-faithful:
+#! @BeginLogSession
+#! gap> list := AllSimplicialSurfacesOfDigraph(digraph,false);
+#! [ simplicial surface (4 vertices, 6 edges, and 4 faces),
+#! simplicial surface (3 vertices, 6 edges, and 4 faces)]
+#! gap> tet2 := Filtered(list,IsVertexFaithful);
+#! [ simplicial surface (4 vertices, 6 edges, and 4 faces) ]
+#! gap> IsIsomorphic(tet2[1],Tetrahedron());
+#! true
+#! gap> AllSimplicialSurfacesByFacesOfEdges (Tetrahedron());
+#! [ simplicial surface (4 vertices, 6 edges, and 4 faces),
+#! simplicial surface (3 vertices, 6 edges, and 4 faces) ]
+#! @EndLogSession
+#!
+#! Since it takes a long time to compute all cycles, you should only call the method for
+#! digraphs with twelve or less nodes for vertexfaithful equal to false.
+#! For vertexfaithful equal to true, the method needs to consider
+#! only chordless and non-separating cycles. This makes the method fast for digraphs up to 28 nodes.
+#! In general, it is much faster to only compute the vertex-faithful simplicial surfaces.
+#!
+#! @Arguments digraph[, vertexfaithful]
+#! @Returns a list
+DeclareOperation( "AllSimplicialSurfacesOfDigraph", [IsDigraph, IsBool]);
+#! @Arguments surface[, vertexfaithful]
+#! @Returns a list
+DeclareOperation( "AllSimplicialSurfacesByFacesOfEdges", [IsSimplicialSurface, IsBool]);
+#! @EndGroup
+
+#! @BeginGroup Reembedding
#! @Description
#! The method ReembeddingsOfSimplicialSphere computes all edge-face equivalent simplicial surfaces
#! of the given vertex-faithful simplicial sphere surf with the given genus g if these
@@ -51,4 +383,76 @@ DeclareOperation( "ReembeddingsOfDigraph", [IsDigraph, IsInt, IsBool]);
#! @Arguments surf, g, oriented
#! @Returns a list
DeclareOperation( "ReembeddingsOfSimplicialSphere", [IsSimplicialSurface, IsInt, IsBool]);
-#! @EndGroup
\ No newline at end of file
+#! @EndGroup
+
+#! @Section Other pre-defined surfaces
+#! @SectionLabel Library_Uncategorised
+#!
+#! This section contains all other pre-defined surfaces that are not
+#! covered in one of the other sections.
+
+#! @Description
+#! Return a one-face as a simplicial surface. A one-face consists
+#! of one triangular face.
+#!
+#! @Returns a simplicial surface
+DeclareOperation( "OneFace", [] );
+
+#! @Description
+#! Return a butterfly as a simplicial surface. A butterfly consists
+#! of two triangular faces that share an edge.
+#!
+#!
+#! <img src="./images/_Wrapper_Image_Butterfly-1.svg"> </img>
+#!
+#!
+#! \begin{center}
+#! \includegraphics{images/_Wrapper_Image_Butterfly.pdf}
+#! \end{center}
+#!
+#!
+#! Image omitted in terminal text
+#!
+#!
+#! @Returns a simplicial surface
+DeclareOperation( "Butterfly", [] );
+
+
+#! @Description
+#! Return a Janus-Head as a simplicial surface. A Janus-Head consists
+#! of two triangular faces that share three edges.
+#!
+#! @InsertChunk Example_JanusHead
+#!
+#! @Returns a simplicial surface
+DeclareOperation( "JanusHead", [] );
+
+
+#!
+#!
+#!
+#! a simplicial surface
+#!
+#! Return a simplicial surface consisting of two closed umbrella-paths
+#! with nrFaces triangles which are joined at their boundary.
+#! The labels of one umbrella are assigned according to the illustration for SimplicialUmbrella,
+#! the additional vertex is labelled with nrFaces+2, the incident edges to this vertex
+#! are labelled from 2*nrFaces+1 to 4*nrFaces and the incident faces are labelled from
+#! nrFaces+1 to 2*nrFaces.
+#! @ExampleSession
+#! gap> doubleumb2:=SimplicialDoubleUmbrella(2);
+#! simplicial surface (4 vertices, 6 edges, and 4 faces)
+#! gap> VerticesOfEdges(doubleumb2);
+#! [ [ 1, 3 ], [ 2, 3 ], [ 1, 2 ], [ 1, 2 ], [ 1, 4 ], [ 2, 4 ] ]
+#! gap> EdgesOfFaces(doubleumb2);
+#! [ [ 1, 2, 3 ], [ 1, 2, 4 ], [ 3, 5, 6 ], [ 4, 5, 6 ] ]
+#! gap> doubleumb4:=SimplicialDoubleUmbrella(4);
+#! simplicial surface (6 vertices, 12 edges, and 8 faces)
+#! gap> IsIsomorphic(doubleumb4,Octahedron());
+#! true
+#! @EndExampleSession
+#!
+#!
+# here no AutoDoc documentation since synonyms can't be handled automatically
+DeclareOperation("SimplicialDoubleUmbrella", [ IsPosInt ] );
+DeclareSynonym("SimplicialDoubleGon", SimplicialDoubleUmbrella);
\ No newline at end of file
diff --git a/gap/PolygonalComplexes/constructing_families.gi b/gap/PolygonalComplexes/constructing_families.gi
index 1193f7e0..505213a9 100644
--- a/gap/PolygonalComplexes/constructing_families.gi
+++ b/gap/PolygonalComplexes/constructing_families.gi
@@ -1,3 +1,483 @@
+
+#############################################################################
+##
+## A relevant 2-path in a simplicial surface S is a pair of edges of S sharing
+## exactly one vertex such that the two edges are not adjacent to one
+## common face.
+## Find all relevant 2-paths up to the action of the automorphism
+## group of the surface
+##
+if IsPackageMarkedForLoading("NautyTracesInterface", ">=0") then
+BindGlobal( "__SIMPLICIAL_AllEssentialTwoPaths",
+ function( surf )
+
+ local vertices, i, t, umbti, u, relpaths, mp, twosets, isgood,
+ aut, orbs, isNewInOrb, li;
+
+ umbti := UmbrellaTipDescriptorOfSurface(surf);
+ relpaths := [];
+
+ #check if a two-set t contains two neighbouring vertices
+ isgood := function(t,u)
+ if IsPerm(u) then
+ if t[1]^u=t[2] then return false; fi;
+ if t[2]^u=t[1] then return false; fi;
+ else
+ if Position(u,t[1]) = Position(u,t[2]) + 1 or
+ Position(u,t[1]) = Position(u,t[2]) - 1 then
+ return false;
+ fi;
+ fi;
+ return true;
+ end;
+
+ isNewInOrb := function(t)
+
+ local j;
+
+ if Length(orbs) = 0 then return true; fi;
+
+ for j in [1 .. Length(orbs)] do
+ if t in orbs[j] then return false; fi;
+ od;
+
+ return true;
+ end;
+
+
+ aut := AutomorphismGroupOnVertices(surf);
+ orbs := [];
+
+ for i in [1 .. Length(umbti)] do
+ if IsBound(umbti[i]) then
+ # Construct all 2-paths with middle vertex i
+ u := umbti[i];
+ if IsPerm(u) then
+ # vertex i is inner
+ mp := MovedPoints(u);
+ else
+ # vertex i is a boundary vertex.
+ mp := umbti[i];
+ fi;
+ # from every vertex in mp we can find a 2-path
+ # to any other via i. Just remove non-relevant paths
+ twosets := Combinations(mp, 2);
+ twosets := Filtered(twosets, t-> isgood(t,u));
+ li := List(twosets, t-> [t[1],i,t[2]]);
+ for t in li do
+ if isNewInOrb(t) then
+ Add(orbs, Orbit( aut, t, OnTuples) );
+ Add(relpaths, t);
+ fi;
+ od;
+ fi;
+ od;
+ return relpaths;
+end
+);
+
+
+# Compute up to isomorphism all surfaces that can be obtained from
+# the surface surf by a butterfly insertion along a relevant 2-path
+InstallMethod( AllSimplicialSurfacesByEssentialButterflyInsertion,
+ "for a simplicial surface",
+ [IsSimplicialSurface],
+ function(surf)
+
+ local allp, surfaces;
+
+ if not IsVertexFaithful(surf) then
+ Error("The given surface has to be vertex-faithful");
+ fi;
+
+ allp := __SIMPLICIAL_AllEssentialTwoPaths(surf);
+
+ surfaces := List(allp, t-> ButterflyInsertion(surf, t)[1]);
+
+
+ return IsomorphismRepresentatives(surfaces);
+
+end);
+fi;
+
+
+#######################################
+##
+## All Surfaces Of A Graph
+##
+
+InstallOtherMethod(AllSimplicialSurfacesOfDigraph,"for a digraph",
+ [IsDigraph],
+ function(digraph)
+ Error("AllSimplicialSurfacesOfDigraph: The package Digraph has to be available with version at least 1.9.0.");
+ end
+);
+
+InstallMethod(AllSimplicialSurfacesOfDigraph,"for a digraph and a Boolean",
+ [IsDigraph,IsBool],
+ function(digraph,vertexFaithful)
+ Error("AllSimplicialSurfacesOfDigraph: The package Digraph has to be available with version 1.10.0.");
+ end
+);
+
+if IsPackageMarkedForLoading( "Digraphs", ">=1.9.0" ) then
+BindGlobal("__SIMPLICIAL_EdgesFromCycle",
+ function(digraph,cycle)
+
+ local edgesOfCycle, i, edge;
+
+ edgesOfCycle:=[];
+ for i in [1..Length(cycle)] do
+ if i__SIMPLICIAL_IsNonSeparating(digraph,c));
+ else
+ allCycles:=DigraphAllUndirectedSimpleCircuits(digraph);
+ fi;
+
+ edgesOfGraph:=Filtered(DigraphEdges(digraph),e->not IsSortedList(e));
+
+ edgesOfCycles:=[];
+ for cycle in [1..Length(allCycles)] do;
+ edgesOfCycles[cycle]:=List(__SIMPLICIAL_EdgesFromCycle(digraph,allCycles[cycle]),e->Position(edgesOfGraph,e));
+ od;
+
+ possibleCyclesPairs:=[];
+ for e in [1..Length(edgesOfGraph)] do
+ possibleCyclesPairs[e]:=[];
+ od;
+
+ for cyclePair in IteratorOfCombinations([1..Length(allCycles)],2) do
+ commonEdges:=Intersection(edgesOfCycles[cyclePair[1]],edgesOfCycles[cyclePair[2]]);
+ if Length(commonEdges)=1 and vertexFaithful then
+ Add(possibleCyclesPairs[commonEdges[1]],cyclePair);
+ elif not vertexFaithful then
+ for e in commonEdges do
+ Add(possibleCyclesPairs[e],cyclePair);
+ od;
+ fi;
+ od;
+
+ faces:=[];
+
+ # The function returns a list that stores a Boolean list for each edge.
+ # An entry in the list is true if the edge is included in this cycle.
+ CyclesOfEdges:=function()
+ local cyclesOfEdges,e,cyclesOfEdge,cycle;
+ cyclesOfEdges:=[];
+
+ for e in [1..Length(edgesOfGraph)] do
+ cyclesOfEdge:=BlistList([1..Length(allCycles)],[]);
+ for cycle in [1..Length(allCycles)] do
+ if e in edgesOfCycles[cycle] then
+ cyclesOfEdge[cycle]:=true;
+ fi;
+ od;
+ cyclesOfEdges[e]:=cyclesOfEdge;
+ od;
+
+ return cyclesOfEdges;
+ end;;
+
+ cyclesOfEdges:=CyclesOfEdges();;
+
+ # The function checks whether the given cycle has at most one common edge with one element of cycles.
+ Possible:=function(cycle,cycles)
+ local c;
+ for c in cycles do
+ if Length(Intersection(edgesOfCycles[cycle],edgesOfCycles[c]))>1 then
+ return false;
+ fi;
+ od;
+ return true;
+ end;;
+
+ IsPartOf:=function(face,faces)
+ local f;
+ for f in faces do
+ if IsIsomorphic(f,face) then
+ return true;
+ fi;
+ od;
+ return false;
+ end;;
+
+ FindSurface:=function(graph)
+ local smallCy, cycle,cyclesOfFace,usedEdges,edgesOfCycle,c,edge,cyclesToUse;
+
+ # if we search vertex-faithful simplicial surfaces all cycles of length three and four have to be part of the resulting cycle combination
+ if vertexFaithful and IsIsomorphicDigraph(graph, CompleteDigraph(4)) then
+ smallCy:=Filtered(allCycles, c->Length(c)<4);
+ smallCy:=BlistList([1..Length(allCycles)],smallCy);
+ elif vertexFaithful then
+ smallCy:=Filtered(allCycles, c->Length(c)<5);
+ smallCy:=BlistList([1..Length(allCycles)],smallCy);
+ fi;
+
+ for cycle in [1..Length(allCycles)] do
+
+ cyclesOfFace:=BlistList([1..Length(allCycles)],[cycle]);
+
+ if vertexFaithful then
+ cyclesOfFace:=UnionBlist(cyclesOfFace, smallCy);
+ fi;
+
+ usedEdges:=ListWithIdenticalEntries(Length(edgesOfGraph),0);
+
+ edgesOfCycle:=[];
+ for c in ListBlist([1..Length(allCycles)],cyclesOfFace) do
+ edgesOfCycle:=Concatenation(edgesOfCycle,edgesOfCycles[c]);
+ od;
+
+ for edge in edgesOfCycle do
+ usedEdges[edge]:=usedEdges[edge]+1;
+ od;
+
+ if ForAll(usedEdges,i->i<3) then
+ cyclesToUse:=BlistList([1..Length(allCycles)],[cycle+1..Length(allCycles)]);
+ cyclesToUse:=DifferenceBlist(cyclesToUse,cyclesOfFace);
+
+ FindCycleComb(cyclesOfFace,usedEdges,1,graph,cyclesToUse);
+ fi;
+ od;
+ end;;
+
+ # This is a recursive function that searches an admissible cycle combination.
+ # usedEdges stores how often each edge is used.
+ # We assume that usedEdges is permissible, that mean each entry is at most two and the cycles overlap at most in one edge
+ # if we search vertex-faithful surfaces.
+ # vertexCycleComb is a Boolean list which stores all cycles we used so far.
+ # k is the position of the edge that we want to consider where all previous edges are already used twice. We start with the first edge.
+ # CyclesToUse is a Boolean list that stores all the cycles that we are currently allowed to use.
+ # A cycle must not be used if it contains an edge that has already been used twice.
+ FindCycleComb:=function(vertexCycleComb,usedEdges,k,graph,cyclesToUse)
+ local admissible, cycleRem, face,umbrellaDesk,kcycle,permissible,cycle,j,e,newUsedEdges,newVertexCycleComb,edgesOfCycle,newCyclesToUse,cy;
+
+ if ForAll(usedEdges,i->i=2) then
+ admissible:=true;
+ if vertexFaithful then
+ for cycle in ListBlist([1..Length(vertexCycleComb)],vertexCycleComb) do
+ cycleRem:=ShallowCopy(vertexCycleComb);
+ cycleRem[cycle]:=false;
+ if not Possible(cycle, ListBlist([1..Length(vertexCycleComb)],cycleRem)) then
+ admissible:=false;
+ fi;
+ od;
+ fi;
+
+ if admissible then
+ umbrellaDesk:=[];
+
+ for cycle in ListBlist([1..Length(vertexCycleComb)],vertexCycleComb) do
+ Add(umbrellaDesk,CycleFromList(allCycles[cycle]));
+ od;
+
+ face:=SimplicialSurfaceByUmbrellaDescriptor(umbrellaDesk);
+ if not IsPartOf(face,faces) then
+ Add(faces,face);
+ fi;
+ fi;
+ else
+ if usedEdges[k]=1 and SizeBlist(cyclesToUse)>0 then
+
+ kcycle:=IntersectionBlist(cyclesOfEdges[k],cyclesToUse);
+
+ # Checks which cycle we can add to our combination such that k is contained twice and the new combination is permissible.
+ for j in ListBlist([1..Length(kcycle)],kcycle) do
+
+ if not vertexFaithful or Possible(j,ListBlist([1..Length(allCycles)],vertexCycleComb))then
+
+ # permissible stores if the current vertexCycleComb together with the new cycle is admissible.
+ permissible:=true;
+
+ edgesOfCycle:=edgesOfCycles[j];
+
+ for e in edgesOfCycle do
+ if usedEdges[e]>=2 then
+ permissible:=false;
+ fi;
+ od;
+
+ if permissible then
+
+ newUsedEdges:=ShallowCopy(usedEdges);
+ for e in edgesOfCycle do
+ newUsedEdges[e]:=usedEdges[e]+1;
+ od;
+
+ newVertexCycleComb:=ShallowCopy(vertexCycleComb);
+ newVertexCycleComb[j]:=true;
+
+ newCyclesToUse:=DifferenceBlist(cyclesToUse,kcycle);
+
+ for e in edgesOfCycle do
+ if newUsedEdges[e]=2 and e>k then
+ newCyclesToUse:=DifferenceBlist(newCyclesToUse,cyclesOfEdges[e]);
+ fi;
+ od;
+ FindCycleComb(newVertexCycleComb,newUsedEdges,k+1,graph,newCyclesToUse);
+ fi;
+ fi;
+ od;
+ elif usedEdges[k]=0 and SizeBlist(cyclesToUse)>0 then
+
+ # Checks which cycle pair of k can be added to our cycle combination
+ for j in possibleCyclesPairs[k] do
+
+ if cyclesToUse[j[1]] and cyclesToUse[j[2]] and (not vertexFaithful or Possible(j[1],
+ ListBlist([1..Length(allCycles)],vertexCycleComb)) and Possible(j[2],ListBlist([1..Length(allCycles)],
+ vertexCycleComb))) then
+ edgesOfCycle:=Union(edgesOfCycles[j[1]],edgesOfCycles[j[2]]);
+
+ # permissible stores if the current vertexCycleComb together with the new cycle is admissible.
+ permissible:=true;
+
+ for e in edgesOfCycle do
+ if usedEdges[e]>=2 then
+ permissible:=false;
+ fi;
+ od;
+
+ if not vertexFaithful then
+ for e in Intersection(edgesOfCycles[j[1]],edgesOfCycles[j[2]]) do
+ if usedEdges[e]>=1 then
+ permissible:=false;
+ fi;
+ od;
+ fi;
+
+ if permissible then
+
+ newUsedEdges:=ShallowCopy(usedEdges);
+ for e in edgesOfCycle do
+ newUsedEdges[e]:=newUsedEdges[e]+1;
+ od;
+
+ if vertexFaithful then
+ newUsedEdges[k]:=newUsedEdges[k]+1;
+ else
+ for e in Intersection(edgesOfCycles[j[1]],edgesOfCycles[j[2]]) do
+ newUsedEdges[e]:=newUsedEdges[e]+1;
+ od;
+ fi;
+
+ newVertexCycleComb:=ShallowCopy(vertexCycleComb);
+ newVertexCycleComb[j[1]]:=true;
+ newVertexCycleComb[j[2]]:=true;
+
+ kcycle:=IntersectionBlist(cyclesOfEdges[k],cyclesToUse);
+ newCyclesToUse:=DifferenceBlist(cyclesToUse,kcycle);
+
+ for e in edgesOfCycle do
+ if newUsedEdges[e]=2 and e>k then
+ newCyclesToUse:=DifferenceBlist(newCyclesToUse,cyclesOfEdges[e]);
+ fi;
+ od;
+ FindCycleComb(newVertexCycleComb,newUsedEdges,k+1,graph,newCyclesToUse);
+ fi;
+ fi;
+ od;
+ elif usedEdges[k]=2 then
+ FindCycleComb(vertexCycleComb,usedEdges,k+1,graph,cyclesToUse);
+ fi;
+ fi;
+ end;;
+
+ FindSurface(digraph);
+
+ return faces;
+
+ end
+);
+fi;
+
+InstallOtherMethod(AllSimplicialSurfacesByFacesOfEdges ,"for a digraph",
+ [IsSimplicialSurface],
+ function(surface)
+ Error("AllSimplicialSurfacesByFacesOfEdges: The package Digraph has to be available with version at least 1.9.0.");
+ end
+);
+
+InstallMethod(AllSimplicialSurfacesByFacesOfEdges ,"for a digraph and a Boolean",
+ [IsSimplicialSurface,IsBool],
+ function(surface,vertexFaithful)
+ Error("AllSimplicialSurfacesByFacesOfEdges: The package Digraph has to be available with version 1.10.0.");
+ end
+);
+
+if IsPackageMarkedForLoading( "Digraphs", ">=1.9.0" ) then
+ InstallOtherMethod(AllSimplicialSurfacesByFacesOfEdges ,"for a simplicial surface",
+ [IsSimplicialSurface],
+ function(surface)
+ if not IsClosedSurface(surface) then
+ Error("AllSimplicialSurfacesByFacesOfEdges: The given surface has to be closed");
+ fi;
+ return AllSimplicialSurfacesOfDigraph(FaceDigraphsGraph(surface));
+ end
+ );
+
+ InstallMethod(AllSimplicialSurfacesByFacesOfEdges,"for a digraph and a Boolean",
+ [IsSimplicialSurface,IsBool],
+ function(surface,vertexFaithful)
+ if not IsClosedSurface(surface) then
+ Error("AllSimplicialSurfacesByFacesOfEdges: The given surface has to be closed");
+ fi;
+ return AllSimplicialSurfacesOfDigraph(FaceDigraphsGraph(surface),vertexFaithful);
+ end
+ );
+fi;
+
+
#######################################
##
## Reembedding of Simplicial Spheres
@@ -337,4 +817,216 @@ InstallMethod(ReembeddingsOfDigraph,
subdigraphs:=RemoveTwistedSubgraphs(subdigraphs,digraph);
return DigraphsToSurf(digraph,subdigraphs,facialCycles,rotationSystem);
end);
-fi;
\ No newline at end of file
+fi;
+
+
+
+#######################################
+##
+## Other examples
+##
+InstallMethod( OneFace, "", [], function()
+ return SimplicialSurfaceByVerticesInFaces( [[1,2,3]] );
+ end
+);
+
+InstallMethod( Butterfly, "", [], function()
+ return SimplicialSurfaceByVerticesInFaces( [[1,2,3],[1,3,4]] );
+ end
+);
+
+InstallMethod( JanusHead, "", [], function()
+ return SimplicialSurfaceByVerticesInFaces( 3, 2,
+ [ [1,2,3], [1,2,3] ] );
+ end
+);
+
+InstallMethod( SimplicialUmbrella, "for an integer at least 2", [IsPosInt],
+ function(nrFaces)
+ local verticesOfEdges, edgesOfFaces, i;
+
+ if nrFaces = 1 then
+ Error("SimplicialUmbrella: Argument has to be greater than 1.");
+ fi;
+
+ verticesOfEdges := [];
+ edgesOfFaces := [];
+ for i in [1..nrFaces-1] do
+ verticesOfEdges[i] := [i, nrFaces+1];
+ verticesOfEdges[nrFaces+i] := [i,i+1];
+
+ edgesOfFaces[i] := [i,i+1,nrFaces+i];
+ od;
+ verticesOfEdges[nrFaces] := [nrFaces, nrFaces+1];
+ verticesOfEdges[2*nrFaces] := [1, nrFaces];
+
+ edgesOfFaces[nrFaces] := [1,nrFaces, 2*nrFaces];
+
+ return SimplicialSurfaceByDownwardIncidenceNC([1..nrFaces+1],
+ [1..2*nrFaces], [1..nrFaces], verticesOfEdges, edgesOfFaces);
+ end
+);
+
+InstallMethod(SimplicialDoubleUmbrella, "for an integer at least 2", [IsPosInt],
+ function(nrFaces)
+ local umbr, verticesOfEdges, edgesOfFaces, i;
+
+ if nrFaces = 1 then
+ Error("SimplicialUmbrella: Argument has to be greater than 1.");
+ fi;
+
+ umbr:=SimplicialUmbrella(nrFaces);
+ verticesOfEdges:=ShallowCopy(VerticesOfEdges(umbr));
+ edgesOfFaces:=ShallowCopy(EdgesOfFaces(umbr));
+
+ for i in [1..nrFaces-1] do
+ edgesOfFaces[i+nrFaces] := [i+nrFaces,2*nrFaces+i,2*nrFaces+i+1];
+
+ verticesOfEdges[2*nrFaces+i] := [i,nrFaces+2];
+ od;
+ edgesOfFaces[2*nrFaces] := [2*nrFaces,2*nrFaces+nrFaces, 2*nrFaces+1];
+ verticesOfEdges[2*nrFaces+nrFaces]:=[nrFaces, nrFaces+2];
+
+ return SimplicialSurfaceByDownwardIncidenceNC(verticesOfEdges, edgesOfFaces);
+end);
+
+
+InstallMethod( SimplicialOpenGeodesic, "for an integer at least 1", [IsPosInt],
+ function(nrFaces)
+ local verticesOfFaces;
+
+ verticesOfFaces := List([1..nrFaces], i -> [i,i+1,i+2]);
+
+ return SimplicialSurfaceByVerticesInFacesNC([1..nrFaces+2], [1..nrFaces], verticesOfFaces);
+ end
+);
+InstallMethod( SimplicialStrip, "for an integer at least 1", [IsPosInt],
+ function(nrFaces)
+ return SimplicialOpenGeodesic(nrFaces);
+ end
+);
+
+InstallMethod( SimplicialClosedGeodesic, "for an integer at least 3", [IsPosInt],
+ function(nrFaces)
+ local verticesOfEdges, edgesOfFaces, i;
+
+ if nrFaces < 3 then
+ Error("SimplicialClosedGeodesic: Argument has to be greater than 2.");
+ fi;
+
+ verticesOfEdges := [];
+ for i in [1..nrFaces-1] do
+ verticesOfEdges[2*i-1] := [i, i+1];
+ verticesOfEdges[2*i] := [i, i+2];
+ od;
+ verticesOfEdges[2*nrFaces-2] := [1,nrFaces-1];
+ verticesOfEdges[2*nrFaces-1] := [1,nrFaces];
+ verticesOfEdges[2*nrFaces] := [2,nrFaces];
+
+ edgesOfFaces := List([1..nrFaces-1], i -> [2*i-1,2*i,2*i+1]);
+ edgesOfFaces[nrFaces] := [1,2*nrFaces-1,2*nrFaces];
+
+ return SimplicialSurfaceByDownwardIncidenceNC([1..nrFaces],
+ [1..2*nrFaces], [1..nrFaces], verticesOfEdges, edgesOfFaces);
+ end
+);
+InstallMethod( SimplicialGeodesic, "for an integer at least 3", [IsPosInt],
+ function(nrFaces)
+ return SimplicialClosedGeodesic(nrFaces);
+ end
+);
+
+# The length of the given list defines the number of faces in the geodesic which is subdivided
+# The i-th entry defines in how many faces the i-th face of the geodesic subdivided
+InstallMethod( SimplexRingByIsomorphismType, "for a list",[IsList],
+ function(list)
+ local k, sum, m, umbr, i, u, j;
+ if 0 in list then
+ Error("This is not a valid isomorphism type for a simplex ring.");
+ fi;
+ k:=Length(list);
+ sum:= Sum(list); # number of the faces n=n_1+...+n_k
+ m:=0; # number of faces that are used so far
+ umbr:=[];
+ # constructing the umbrella descriptor
+ if k > 2 then
+ # go through all n_i
+ for i in [1..k] do
+ # constructing the umbrella of the essential vertex
+ u:=[(m-1) mod sum +1]; # adding the predecessor face
+ for j in [1..list[i]+1] do # adding the faces made by subdivision and the last face to the umbrella
+ Add(u, (m+j-1)mod sum +1);
+ od;
+ Add(umbr,u);
+ # constructing the umbrella of the inessential vertices
+ if list[i]>1 then
+ for j in [1..list[i]-1] do
+ m:=m+1;
+ u:=[m,m+1];
+ #u:=[(m-1) mod sum+1,m mod sum+1]; # each umbrella has only those two faces
+ Add(umbr,u);
+ od;
+ m:=m+1;
+ else
+ m:=m+list[i];
+ fi;
+ od;
+ return SimplicialSurfaceByUmbrellaDescriptor(umbr);
+ elif k=1 then
+ return SimplicialUmbrella(list[1]);
+ else
+ Error("This is not a valid isomorphism type for a simplex ring.");
+ fi;
+end);
+
+
+# The length of the given list defines the number of faces in the strip which is subdivided
+# The i-th entry defines in how many faces the i-th face of the strip subdivided
+InstallMethod( SimplexStringByIsomorphismType, "for a list",[IsList],
+ function(list)
+ local k, sum, m, umbr, i, u, j;
+ if 0 in list then
+ Error("This is not a valid isomorphism type for a simplex string.");
+ fi;
+ k:=Length(list);
+ sum:= Sum(list); # number of the faces n=n_1+...+n_k
+ m:=0; # number of faces that are used so far
+ umbr:=[[1]];
+ # constructing the umbrella descriptor
+ if k > 2 then
+ # go through all n_i
+ for i in [1..k] do
+ # constructing the umbrella of the essential vertex
+ if i>1 then
+ u:=[(m-1) mod sum +1];
+ else
+ u:=[];
+ fi;
+ for j in [1..list[i]] do # adding the faces made by subdivision and the last face to the umbrella
+ Add(u, (m+j-1)mod sum +1);
+ od;
+ if i<>k then
+ Add(u, m+list[i]+1);
+ fi;
+ Add(umbr,u);
+ # constructing the umbrella of the inessential vertices
+ if list[i]>1 then
+ for j in [1..list[i]-1] do
+ m:=m+1;
+ u:=[m,m+1]; # each umbrella has only those two faces
+ Add(umbr,u);
+ od;
+ m:=m+1;
+ else
+ m:=m+list[i];
+ fi;
+ od;
+ Add(umbr,[m]);
+ #Error();
+ return SimplicialSurfaceByUmbrellaDescriptor(umbr);
+ elif k=1 then
+ #return SimplicialOneFace();
+ else
+ Error("This is not a valid isomorphism type for a simplex ring.");
+ fi;
+end);
\ No newline at end of file
diff --git a/gap/PolygonalComplexes/constructors.gi b/gap/PolygonalComplexes/constructors.gi
index a2448339..8f1fb775 100644
--- a/gap/PolygonalComplexes/constructors.gi
+++ b/gap/PolygonalComplexes/constructors.gi
@@ -489,7 +489,7 @@ InstallMethod(UmbrellaTipDescriptorOfSurface,
function(surf)
local vertex, umbdesc, edge, vertEdges, umbVertices, umbPath;
if not IsVertexFaithful(surf) then
- return fail;
+ Error("The given surface has to be vertex-faithful");
fi;
umbdesc:=[];
for vertex in Vertices(surf) do
diff --git a/gap/PolygonalComplexes/discs.gd b/gap/PolygonalComplexes/discs.gd
deleted file mode 100644
index 893ee6a7..00000000
--- a/gap/PolygonalComplexes/discs.gd
+++ /dev/null
@@ -1,80 +0,0 @@
-#! @Chapter Generating certain simplicial surfaces
-#! @ChapterLabel Generating
-
-#! This chapter introduces methods to find all simplicial surfaces with certain
-#! restrictions.
-#!
-
-#! @Section Essential discs
-#! @SectionLabel Discs_Essential
-
-
-#! This section contains the methods to compute all essential simplicial discs.
-
-
-#! @BeginGroup IsEssentialDisc
-#! @Description
-#! This function returns true if disc is an essential disc and false else. A
-#! simplicial surface
-#! disc is called an essential disc if disc is a connected
-#! simplicial surfaces of Euler characteristic 1 and every circular
-#! vertex-edge path of length 3 bounds a face of disc, and every
-#! boundary vertex has degree at least 2 and and no inner edge joins
-#! two boundary vertices.
-#!
-#! @BeginExampleSession
-#! gap> disc := SimplicialSurfaceByDownwardIncidence(
-#! > [ [ 1, 3 ], [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ],
-#! > [ 2, 6 ], [ 2, 7 ], [ 3, 7 ], [ 4, 7 ], [ 4, 8 ], [ 4, 5 ], [ 5, 6 ],
-#! > [ 6, 7 ], [ 7, 8 ], [ 5, 8 ] ],
-#! > [ [ 1, 2, 3 ], [ 1, 4, 5 ], [ 6, 7, 14 ], [ 2, 7, 8 ], [ 8, 9, 15 ],
-#! > [ 3, 9, 10 ], [ 4, 10, 11 ], [ 11, 12, 16 ], [ 12, 13, 17 ],
-#! > [ 5, 6, 13 ] ] );
-#! simplicial surface (8 vertices, 17 edges, and 10 faces)
-#! gap> IsConnectedSurface(disc);
-#! true
-#! gap> EulerCharacteristic(disc);
-#! 1
-#! gap> CounterOfVertices(disc);
-#! counter of vertices ([ 2, 3, 4, 5 ] degrees, and [ 1, 2, 3, 2 ] multiplicities)
-#! gap> IsEssentialDisc(disc);
-#! true
-#! @EndExampleSession
-#! @Arguments disc
-#! @Returns true or false
-DeclareOperation( "IsEssentialDisc", [IsTwistedPolygonalComplex] );
-#! @EndGroup
-
-#! @BeginGroup AllSimplicialSurfacesByEssentialButterflyInsertion
-#! @Description
-#! This function computes representatives of the isomorphism classes of
-#! all simplicial surfaces that can be obtained from
-#! the input surface surf by an essential butterfly insertion.
-#! An essential butterfly insertion is a butterfly insertion that does not
-#! create a 3-waist.
-#!
-#! @BeginLogSession
-#! gap> surface := SimplicialSurfaceByDownwardIncidence(
-#! > [ [ 1, 3 ], [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ],
-#! > [ 2, 6 ], [ 2, 7 ], [ 3, 7 ], [ 3, 8 ], [ 4, 8 ], [ 4, 5 ], [ 5, 6 ],
-#! > [ 6, 7 ], [ 7, 8 ], [ 5, 8 ] ],
-#! > [ [1, 2, 3], [1, 4, 5], [6, 7, 14], [2, 7, 8], [8, 9, 15],
-#! > [3, 9, 10], [10, 11, 16], [4, 11, 12], [12, 13, 17], [5, 6, 13] ]);
-#! simplicial surface (8 vertices, 17 edges, and 10 faces)
-#! gap> IsConnectedSurface(surface);
-#! true
-#! gap> EulerCharacteristic(surface);
-#! 1
-#! gap> AllSimplicialSurfacesByEssentialButterflyInsertion(surface);
-#! [ simplicial surface (9 vertices, 20 edges, and 12 faces),
-#! simplicial surface (9 vertices, 20 edges, and 12 faces)
-#! , simplicial surface (9 vertices, 20 edges, and 12 faces),
-#! simplicial surface (9 vertices, 20 edges, and 12 faces) ]
-#! @EndLogSession
-#! @Arguments surface
-#! @Returns a list of simplicial surfaces
-DeclareOperation( "AllSimplicialSurfacesByEssentialButterflyInsertion", [IsSimplicialSurface] );
-#! @EndGroup
-
-
-
diff --git a/gap/PolygonalComplexes/discs.gi b/gap/PolygonalComplexes/discs.gi
deleted file mode 100644
index 1508fba3..00000000
--- a/gap/PolygonalComplexes/discs.gi
+++ /dev/null
@@ -1,152 +0,0 @@
-
-
-#############################################################################
-##
-#F IsEssentialDisc( ) . . . . . . . . test whether is essential
-##
-## A simplicial surface is called an essential simplicial disc, if
-## it is a connected simplicial surface of Euler Characteristic 1, no
-## inner vertex has degree less than 4, no boundary vertex has degree 1,
-## no inner edge connects two boundary vertices and the disc has no 3-waists.
-##
-
-InstallMethod( IsEssentialDisc,
- "for a simplicial surface",
- [IsTwistedPolygonalComplex],
-
- function( disc )
-
- local bound, v, inner, innerE, e;
-
- if not IsSimplicialSurface(disc) then return false; fi;
-
- if not IsConnectedSurface(disc) then return false; fi;
- if EulerCharacteristic(disc)<>1 then return false; fi;
-
- bound := BoundaryVertices(disc);
- # ensure that all boundary vertices have degree at least 2
- for v in bound do
- if DegreeOfVertex(disc,v) < 2 then return false; fi;
- od;
- inner := InnerVertices(disc);
- # ensure that all inner vertices have degree at least 4
- for v in inner do
- if DegreeOfVertex(disc,v) <= 3 then return false; fi;
- od;
- innerE := InnerEdges(disc);
- # ensure that all inner edges do not have two boundary vertices
- for e in innerE do
- v := VerticesOfEdge(disc,e);
- if v[1] in bound and v[2] in bound then return false; fi;
- od;
- # ensure that the disc has no 3-waists
- if Length(AllThreeWaistsOfComplex(disc)) > 0 then return false; fi;
- return true;
-end
-);
-
-
-
-#############################################################################
-##
-## A relevant 2-path in an essential disc D is a pair of edges of D sharing
-## exactly one vertex W such that the two edges are not adjacent to one
-## common face.
-## Find all relevant 2-paths up to the action of the automorphism
-## group of the surface
-##
-if IsPackageMarkedForLoading("NautyTracesInterface", ">=0") then
-BindGlobal( "__SIMPLICIAL_AllEssentialTwoPaths",
- function( surf )
-
- local vertices, i, t, umbti, u, relpaths, mp, twosets, isgood,
- aut, orbs, isNewInOrb, li;
-
- umbti := UmbrellaTipDescriptorOfSurface(surf);
- relpaths := [];
-
- #check if a two-set t contains two neighbouring vertices
- isgood := function(t,u)
- if IsPerm(u) then
- if t[1]^u=t[2] then return false; fi;
- if t[2]^u=t[1] then return false; fi;
- else
- if Position(u,t[1]) = Position(u,t[2]) + 1 or
- Position(u,t[1]) = Position(u,t[2]) - 1 then
- return false;
- fi;
- fi;
- return true;
- end;
-
- isNewInOrb := function(t)
-
- local j;
-
- if Length(orbs) = 0 then return true; fi;
-
- for j in [1 .. Length(orbs)] do
- if t in orbs[j] then return false; fi;
- od;
-
- return true;
- end;
-
-
- aut := AutomorphismGroupOnVertices(surf);
- orbs := [];
-
- for i in [1 .. Length(umbti)] do
- if IsBound(umbti[i]) then
- # Construct all 2-paths with middle vertex i
- u := umbti[i];
- if IsPerm(u) then
- # vertex i is inner
- mp := MovedPoints(u);
- else
- # vertex i is a boundary vertex.
- mp := umbti[i];
- fi;
- # from every vertex in mp we can find a 2-path
- # to any other via i. Just remove non-relevant paths
- twosets := Combinations(mp, 2);
- twosets := Filtered(twosets, t-> isgood(t,u));
- li := List(twosets, t-> [t[1],i,t[2]]);
- for t in li do
- if isNewInOrb(t) then
- Add(orbs, Orbit( aut, t, OnTuples) );
- Add(relpaths, t);
- fi;
- od;
- fi;
- od;
-
-
-
- return relpaths;
-
-end
-);
-
-
-# Compute up to isomorphism all surfaces that can be obtained from
-# the surface surf by a butterfly insertion along a relevant 2-path
-
-InstallMethod( AllSimplicialSurfacesByEssentialButterflyInsertion,
- "for a simplicial surface",
- [IsSimplicialSurface],
-
-
- function(surf)
-
- local allp, surfaces;
-
- allp := __SIMPLICIAL_AllEssentialTwoPaths(surf);
-
- surfaces := List(allp, t-> ButterflyInsertion(surf, t)[1]);
-
-
- return IsomorphismRepresentatives(surfaces);
-
-end);
-fi;
\ No newline at end of file
diff --git a/gap/PolygonalComplexes/graphs.gd b/gap/PolygonalComplexes/graphs.gd
index f3167406..8e03ba1b 100644
--- a/gap/PolygonalComplexes/graphs.gd
+++ b/gap/PolygonalComplexes/graphs.gd
@@ -53,7 +53,6 @@
#! these sections are in general not necessary in practice.
#!
#! Section describes the edge graph and the face graph of a polygonal complex.
-#! They are used in practice like in .
#!
#! Section contains the isomorphism
#! method
@@ -283,8 +282,6 @@ DeclareAttribute( "ChamberAdjacencyGraph", IsTwistedPolygonalComplex );
#! These graphs are useful if it is not necessary to need all information of the complex.
#! The edge graph only describes the incidence structure of vertices and edges.
#! Instead, the face graph describes the incidence structure of edges and faces.
-#! Using method it is possible to get all surfaces
-#! that have a common face graph.
#!
#! The face graph and the edge graph of a polygonal complex are dual graphs of each other.
#! The dual graph of a planar graph G is a graph that has a vertex for each face of G
@@ -412,58 +409,6 @@ DeclareAttribute( "FaceDigraphsGraph", IsPolygonalComplex );
DeclareAttribute( "FaceNautyGraph", IsPolygonalComplex );
#! @EndGroup
-#! @BeginGroup AllSimplicialSurfacesOfDigraph
-#! @Description
-#! Return all (vertex-faithful) simplicial surfaces, that have digraph as face graph.
-#! If digraph is not a face graph of a (vertex-faithful) simplicial surface, the empty list is returned.
-#! The parameter vertexfaithful indicates whether only vertex-faithful simplicial surfaces are searched.
-#! The parameter vertexfaithful is by default false.
-#! digraph must be a cubic, connected, symmetric and simple digraph. The vertices of a simplicial
-#! surface can be identified with certain cycles in the face graph. This method searches possible combinations of cycles,
-#! with the cycles corresponding to the vertices of a simplicial surface.
-#!
-#!
-#! For example, consider the complete graph on four nodes:
-#!
-#! <br><img src="./images/_Wrapper_Image_FaceGraphTetra-1.svg"> </img> <br>
-#!
-#!
-#! \begin{center}
-#! \includegraphics{images/_Wrapper_Image_FaceGraphTetra.pdf}
-#! \end{center}
-#!
-#!
-#! Image omitted in terminal text
-#!
-#!
-#! @BeginLogSession
-#! gap> digraph:=CompleteDigraph(4);;
-#! gap> tet1 := AllSimplicialSurfacesOfDigraph(digraph,true);
-#! [ simplicial surface (4 vertices, 6 edges, and 4 faces) ]
-#! gap> IsIsomorphic(tet1[1],Tetrahedron());
-#! true
-#! @EndLogSession
-#! So the only vertex-faithful simplicial surface of the digraph is the tetrahedron.
-#! But there is another simplicial surface, which is not vertex-faithful:
-#! @BeginLogSession
-#! gap> list := AllSimplicialSurfacesOfDigraph(digraph,false);
-#! [ simplicial surface (4 vertices, 6 edges, and 4 faces),
-#! simplicial surface (3 vertices, 6 edges, and 4 faces)]
-#! gap> tet2 := Filtered(list,IsVertexFaithful);
-#! [ simplicial surface (4 vertices, 6 edges, and 4 faces) ]
-#! gap> IsIsomorphic(tet2[1],Tetrahedron());
-#! true
-#! @EndLogSession
-#!
-#! Since it takes a long time to compute all cycles, you should only call the method for digraphs with twelve or less nodes for vertexfaithful false.
-#! For vertexfaithful true, the method needs to consider only chordless and non-separating cycles. This makes the method fast for digraphs up to 28 nodes.
-#! In general, it is much faster to only look for vertex-faithful simplicial surfaces.
-#!
-#! @Arguments digraph[, vertexfaithful]
-#! @Returns a list
-DeclareOperation( "AllSimplicialSurfacesOfDigraph", [IsDigraph, IsBool]);
-#! @EndGroup
-
#! @Section Isomorphism testing
#! @SectionLabel Graphs_Isomorphism
diff --git a/gap/PolygonalComplexes/graphs.gi b/gap/PolygonalComplexes/graphs.gi
index 116b9717..8fc3d5b5 100644
--- a/gap/PolygonalComplexes/graphs.gi
+++ b/gap/PolygonalComplexes/graphs.gi
@@ -777,346 +777,6 @@ InstallMethod( OnEdgeFacePaths,
end
);
-#######################################
-##
-## All Surfaces Of A Graph
-##
-
-InstallOtherMethod(AllSimplicialSurfacesOfDigraph,"for a digraph",
- [IsDigraph],
- function(digraph)
- Error("ReembeddingsOfDigraph: The package Digraph has to be available with version at least 1.9.0.");
- end
-);
-
-InstallMethod(AllSimplicialSurfacesOfDigraph,"for a digraph and a Boolean",
- [IsDigraph,IsBool],
- function(digraph,vertexFaithful)
- Error("ReembeddingsOfDigraph: The package Digraph has to be available with version 1.10.0.");
- end
-);
-
-if IsPackageMarkedForLoading( "Digraphs", ">=1.9.0" ) then
-BindGlobal("__SIMPLICIAL_EdgesFromCycle",
- function(digraph,cycle)
-
- local edgesOfCycle, i, edge;
-
- edgesOfCycle:=[];
- for i in [1..Length(cycle)] do
- if i__SIMPLICIAL_IsNonSeparating(digraph,c));
- else
- allCycles:=DigraphAllUndirectedSimpleCircuits(digraph);
- fi;
-
- edgesOfGraph:=Filtered(DigraphEdges(digraph),e->not IsSortedList(e));
-
- edgesOfCycles:=[];
- for cycle in [1..Length(allCycles)] do;
- edgesOfCycles[cycle]:=List(__SIMPLICIAL_EdgesFromCycle(digraph,allCycles[cycle]),e->Position(edgesOfGraph,e));
- od;
-
- possibleCyclesPairs:=[];
- for e in [1..Length(edgesOfGraph)] do
- possibleCyclesPairs[e]:=[];
- od;
-
- for cyclePair in IteratorOfCombinations([1..Length(allCycles)],2) do
- commonEdges:=Intersection(edgesOfCycles[cyclePair[1]],edgesOfCycles[cyclePair[2]]);
- if Length(commonEdges)=1 and vertexFaithful then
- Add(possibleCyclesPairs[commonEdges[1]],cyclePair);
- elif not vertexFaithful then
- for e in commonEdges do
- Add(possibleCyclesPairs[e],cyclePair);
- od;
- fi;
- od;
-
- faces:=[];
-
- # The function returns a list that stores a Boolean list for each edge.
- # An entry in the list is true if the edge is included in this cycle.
- CyclesOfEdges:=function()
- local cyclesOfEdges,e,cyclesOfEdge,cycle;
- cyclesOfEdges:=[];
-
- for e in [1..Length(edgesOfGraph)] do
- cyclesOfEdge:=BlistList([1..Length(allCycles)],[]);
- for cycle in [1..Length(allCycles)] do
- if e in edgesOfCycles[cycle] then
- cyclesOfEdge[cycle]:=true;
- fi;
- od;
- cyclesOfEdges[e]:=cyclesOfEdge;
- od;
-
- return cyclesOfEdges;
- end;;
-
- cyclesOfEdges:=CyclesOfEdges();;
-
- # The function checks whether the given cycle has at most one common edge with one element of cycles.
- Possible:=function(cycle,cycles)
- local c;
- for c in cycles do
- if Length(Intersection(edgesOfCycles[cycle],edgesOfCycles[c]))>1 then
- return false;
- fi;
- od;
- return true;
- end;;
-
- IsPartOf:=function(face,faces)
- local f;
- for f in faces do
- if IsIsomorphic(f,face) then
- return true;
- fi;
- od;
- return false;
- end;;
-
- FindSurface:=function(graph)
- local smallCy, cycle,cyclesOfFace,usedEdges,edgesOfCycle,c,edge,cyclesToUse;
-
- # if we search vertex-faithful simplicial surfaces all cycles of length three and four have to be part of the resulting cycle combination
- if vertexFaithful and IsIsomorphicDigraph(graph, CompleteDigraph(4)) then
- smallCy:=Filtered(allCycles, c->Length(c)<4);
- smallCy:=BlistList([1..Length(allCycles)],smallCy);
- elif vertexFaithful then
- smallCy:=Filtered(allCycles, c->Length(c)<5);
- smallCy:=BlistList([1..Length(allCycles)],smallCy);
- fi;
-
- for cycle in [1..Length(allCycles)] do
-
- cyclesOfFace:=BlistList([1..Length(allCycles)],[cycle]);
-
- if vertexFaithful then
- cyclesOfFace:=UnionBlist(cyclesOfFace, smallCy);
- fi;
-
- usedEdges:=ListWithIdenticalEntries(Length(edgesOfGraph),0);
-
- edgesOfCycle:=[];
- for c in ListBlist([1..Length(allCycles)],cyclesOfFace) do
- edgesOfCycle:=Concatenation(edgesOfCycle,edgesOfCycles[c]);
- od;
-
- for edge in edgesOfCycle do
- usedEdges[edge]:=usedEdges[edge]+1;
- od;
-
- if ForAll(usedEdges,i->i<3) then
- cyclesToUse:=BlistList([1..Length(allCycles)],[cycle+1..Length(allCycles)]);
- cyclesToUse:=DifferenceBlist(cyclesToUse,cyclesOfFace);
-
- FindCycleComb(cyclesOfFace,usedEdges,1,graph,cyclesToUse);
- fi;
- od;
- end;;
-
- # This is a recursive function that searches an admissible cycle combination.
- # usedEdges stores how often each edge is used.
- # We assume that usedEdges is permissible, that mean each entry is at most two and the cycles overlap at most in one edge
- # if we search vertex-faithful surfaces.
- # vertexCycleComb is a Boolean list which stores all cycles we used so far.
- # k is the position of the edge that we want to consider where all previous edges are already used twice. We start with the first edge.
- # CyclesToUse is a Boolean list that stores all the cycles that we are currently allowed to use.
- # A cycle must not be used if it contains an edge that has already been used twice.
- FindCycleComb:=function(vertexCycleComb,usedEdges,k,graph,cyclesToUse)
- local admissible, cycleRem, face,umbrellaDesk,kcycle,permissible,cycle,j,e,newUsedEdges,newVertexCycleComb,edgesOfCycle,newCyclesToUse,cy;
-
- if ForAll(usedEdges,i->i=2) then
- admissible:=true;
- if vertexFaithful then
- for cycle in ListBlist([1..Length(vertexCycleComb)],vertexCycleComb) do
- cycleRem:=ShallowCopy(vertexCycleComb);
- cycleRem[cycle]:=false;
- if not Possible(cycle, ListBlist([1..Length(vertexCycleComb)],cycleRem)) then
- admissible:=false;
- fi;
- od;
- fi;
-
- if admissible then
- umbrellaDesk:=[];
-
- for cycle in ListBlist([1..Length(vertexCycleComb)],vertexCycleComb) do
- Add(umbrellaDesk,CycleFromList(allCycles[cycle]));
- od;
-
- face:=SimplicialSurfaceByUmbrellaDescriptor(umbrellaDesk);
- if not IsPartOf(face,faces) then
- Add(faces,face);
- fi;
- fi;
- else
- if usedEdges[k]=1 and SizeBlist(cyclesToUse)>0 then
-
- kcycle:=IntersectionBlist(cyclesOfEdges[k],cyclesToUse);
-
- # Checks which cycle we can add to our combination such that k is contained twice and the new combination is permissible.
- for j in ListBlist([1..Length(kcycle)],kcycle) do
-
- if not vertexFaithful or Possible(j,ListBlist([1..Length(allCycles)],vertexCycleComb))then
-
- # permissible stores if the current vertexCycleComb together with the new cycle is admissible.
- permissible:=true;
-
- edgesOfCycle:=edgesOfCycles[j];
-
- for e in edgesOfCycle do
- if usedEdges[e]>=2 then
- permissible:=false;
- fi;
- od;
-
- if permissible then
-
- newUsedEdges:=ShallowCopy(usedEdges);
- for e in edgesOfCycle do
- newUsedEdges[e]:=usedEdges[e]+1;
- od;
-
- newVertexCycleComb:=ShallowCopy(vertexCycleComb);
- newVertexCycleComb[j]:=true;
-
- newCyclesToUse:=DifferenceBlist(cyclesToUse,kcycle);
-
- for e in edgesOfCycle do
- if newUsedEdges[e]=2 and e>k then
- newCyclesToUse:=DifferenceBlist(newCyclesToUse,cyclesOfEdges[e]);
- fi;
- od;
- FindCycleComb(newVertexCycleComb,newUsedEdges,k+1,graph,newCyclesToUse);
- fi;
- fi;
- od;
- elif usedEdges[k]=0 and SizeBlist(cyclesToUse)>0 then
-
- # Checks which cycle pair of k can be added to our cycle combination
- for j in possibleCyclesPairs[k] do
-
- if cyclesToUse[j[1]] and cyclesToUse[j[2]] and (not vertexFaithful or Possible(j[1],
- ListBlist([1..Length(allCycles)],vertexCycleComb)) and Possible(j[2],ListBlist([1..Length(allCycles)],
- vertexCycleComb))) then
- edgesOfCycle:=Union(edgesOfCycles[j[1]],edgesOfCycles[j[2]]);
-
- # permissible stores if the current vertexCycleComb together with the new cycle is admissible.
- permissible:=true;
-
- for e in edgesOfCycle do
- if usedEdges[e]>=2 then
- permissible:=false;
- fi;
- od;
-
- if not vertexFaithful then
- for e in Intersection(edgesOfCycles[j[1]],edgesOfCycles[j[2]]) do
- if usedEdges[e]>=1 then
- permissible:=false;
- fi;
- od;
- fi;
-
- if permissible then
-
- newUsedEdges:=ShallowCopy(usedEdges);
- for e in edgesOfCycle do
- newUsedEdges[e]:=newUsedEdges[e]+1;
- od;
-
- if vertexFaithful then
- newUsedEdges[k]:=newUsedEdges[k]+1;
- else
- for e in Intersection(edgesOfCycles[j[1]],edgesOfCycles[j[2]]) do
- newUsedEdges[e]:=newUsedEdges[e]+1;
- od;
- fi;
-
- newVertexCycleComb:=ShallowCopy(vertexCycleComb);
- newVertexCycleComb[j[1]]:=true;
- newVertexCycleComb[j[2]]:=true;
-
- kcycle:=IntersectionBlist(cyclesOfEdges[k],cyclesToUse);
- newCyclesToUse:=DifferenceBlist(cyclesToUse,kcycle);
-
- for e in edgesOfCycle do
- if newUsedEdges[e]=2 and e>k then
- newCyclesToUse:=DifferenceBlist(newCyclesToUse,cyclesOfEdges[e]);
- fi;
- od;
- FindCycleComb(newVertexCycleComb,newUsedEdges,k+1,graph,newCyclesToUse);
- fi;
- fi;
- od;
- elif usedEdges[k]=2 then
- FindCycleComb(vertexCycleComb,usedEdges,k+1,graph,cyclesToUse);
- fi;
- fi;
- end;;
-
- FindSurface(digraph);
-
- return faces;
-
- end
-);
-fi;
-
#######################################
##
## Edge Insertion / Reduction
diff --git a/gap/PolygonalComplexes/properties.gd b/gap/PolygonalComplexes/properties.gd
index b035305a..7e44821c 100644
--- a/gap/PolygonalComplexes/properties.gd
+++ b/gap/PolygonalComplexes/properties.gd
@@ -186,6 +186,39 @@ DeclareProperty( "IsSimplexRing", IsTwistedPolygonalComplex);
DeclareProperty( "IsSimplexString", IsTwistedPolygonalComplex);
#! @EndGroup
+#! @BeginGroup IsEssentialDisc
+#! @Description
+#! This function returns true if disc is an essential disc and false else. A
+#! simplicial surface
+#! disc is called an essential disc if disc is a connected
+#! simplicial surfaces of Euler characteristic 1 and every circular
+#! vertex-edge path of length 3 bounds a face of disc, and every
+#! boundary vertex has degree at least 2 and and no inner edge joins
+#! two boundary vertices.
+#!
+#! @BeginExampleSession
+#! gap> disc := SimplicialSurfaceByDownwardIncidence(
+#! > [ [ 1, 3 ], [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ],
+#! > [ 2, 6 ], [ 2, 7 ], [ 3, 7 ], [ 4, 7 ], [ 4, 8 ], [ 4, 5 ], [ 5, 6 ],
+#! > [ 6, 7 ], [ 7, 8 ], [ 5, 8 ] ],
+#! > [ [ 1, 2, 3 ], [ 1, 4, 5 ], [ 6, 7, 14 ], [ 2, 7, 8 ], [ 8, 9, 15 ],
+#! > [ 3, 9, 10 ], [ 4, 10, 11 ], [ 11, 12, 16 ], [ 12, 13, 17 ],
+#! > [ 5, 6, 13 ] ] );
+#! simplicial surface (8 vertices, 17 edges, and 10 faces)
+#! gap> IsConnectedSurface(disc);
+#! true
+#! gap> EulerCharacteristic(disc);
+#! 1
+#! gap> CounterOfVertices(disc);
+#! counter of vertices ([ 2, 3, 4, 5 ] degrees, and [ 1, 2, 3, 2 ] multiplicities)
+#! gap> IsEssentialDisc(disc);
+#! true
+#! @EndExampleSession
+#! @Arguments disc
+#! @Returns true or false
+DeclareOperation( "IsEssentialDisc", [IsTwistedPolygonalComplex] );
+#! @EndGroup
+
#! @BeginGroup IsMultiTetrahedralSphere
#! @Description
#! Check whether the given twisted polygonal complex is a multitetrahedral
diff --git a/gap/PolygonalComplexes/properties.gi b/gap/PolygonalComplexes/properties.gi
index 4c8ca157..7dafb9d9 100644
--- a/gap/PolygonalComplexes/properties.gi
+++ b/gap/PolygonalComplexes/properties.gi
@@ -109,6 +109,51 @@ InstallMethod( IsSimplexString, "for a twisted polygonal complex",
end
);
+#############################################################################
+##
+#F IsEssentialDisc( ) . . . . . . . . test whether is essential
+##
+## A simplicial surface is called an essential simplicial disc, if
+## it is a connected simplicial surface of Euler Characteristic 1, no
+## inner vertex has degree less than 4, no boundary vertex has degree 1,
+## no inner edge connects two boundary vertices and the disc has no 3-waists.
+##
+
+InstallMethod( IsEssentialDisc,
+ "for a simplicial surface",
+ [IsTwistedPolygonalComplex],
+
+ function( disc )
+
+ local bound, v, inner, innerE, e;
+
+ if not IsSimplicialSurface(disc) then return false; fi;
+
+ if not IsConnectedSurface(disc) then return false; fi;
+ if EulerCharacteristic(disc)<>1 then return false; fi;
+
+ bound := BoundaryVertices(disc);
+ # ensure that all boundary vertices have degree at least 2
+ for v in bound do
+ if DegreeOfVertex(disc,v) < 2 then return false; fi;
+ od;
+ inner := InnerVertices(disc);
+ # ensure that all inner vertices have degree at least 4
+ for v in inner do
+ if DegreeOfVertex(disc,v) <= 3 then return false; fi;
+ od;
+ innerE := InnerEdges(disc);
+ # ensure that all inner edges do not have two boundary vertices
+ for e in innerE do
+ v := VerticesOfEdge(disc,e);
+ if v[1] in bound and v[2] in bound then return false; fi;
+ od;
+ # ensure that the disc has no 3-waists
+ if Length(AllThreeWaistsOfComplex(disc)) > 0 then return false; fi;
+ return true;
+end
+);
+
InstallMethod( IsMultiTetrahedralSphere, "for a twisted polygonal complex",
[IsTwistedPolygonalComplex],
function(complex)
diff --git a/init.g b/init.g
index f1ad2b11..060390a4 100644
--- a/init.g
+++ b/init.g
@@ -16,7 +16,6 @@ ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/graphs.gd" );
ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/modification.gd" );
ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/constructing_families.gd");
ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/embedding.gd" );
-ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/discs.gd" );
ReadPackage( "SimplicialSurfaces", "gap/Morphisms/morphisms.gd" );
diff --git a/read.g b/read.g
index f2ab65c1..cb8beb42 100644
--- a/read.g
+++ b/read.g
@@ -16,7 +16,6 @@ ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/distances.gi" );
ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/constructing_families.gi" );
ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/embedding.gi" );
ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/drawing.gi" );
-ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/discs.gi" );
ReadPackage( "SimplicialSurfaces", "gap/Morphisms/morphisms.gi" );
@@ -45,4 +44,5 @@ ReadPackage( "SimplicialSurfaces", "unit_tests/Test_VEFComplex.g" );
ReadPackage( "SimplicialSurfaces", "unit_tests/Test_Inferences_Morphisms.g" );
ReadPackage( "SimplicialSurfaces", "unit_tests/Test_UmbrellaDescriptor.g" );
ReadPackage( "SimplicialSurfaces", "unit_tests/Test_Graphs.g" );
+ReadPackage( "SimplicialSurfaces", "unit_tests/Test_Generating_Families.g" );
ReadPackage( "SimplicialSurfaces", "unit_tests/test_main.g" );
diff --git a/unit_tests/Test_Generating_Families.g b/unit_tests/Test_Generating_Families.g
new file mode 100644
index 00000000..1593bbb2
--- /dev/null
+++ b/unit_tests/Test_Generating_Families.g
@@ -0,0 +1,57 @@
+if IsPackageMarkedForLoading( "Digraphs", ">=1.9.0" ) then
+ BindGlobal( "__SIMPLICIAL_Test_AllSimplicialSurfacesOfDigraph", function()
+ local dig, surface, list1, list2;
+ surface:=SimplicialSurfaceByVerticesInFaces([[1,4,5],[1,4,6],[1,5,7],[1,6,7],[2,3,5],[2,3,6],[2,4,5],[2,4,6],[3,5,7],[3,6,7]]);
+ dig:=FaceDigraphsGraph(surface);
+
+ list2:=AllSimplicialSurfacesOfDigraph(dig);
+ Assert(0, Length(Filtered(list2,IsVertexFaithful))=1);
+ Assert(0,IsIsomorphic(Filtered(list2,IsVertexFaithful)[1],surface));
+ Assert(0,Length(list2)=11);
+
+ list1:=AllSimplicialSurfacesOfDigraph(dig,true);
+ Assert(0,Length(list1)=1);
+ Assert(0,IsIsomorphic(list1[1],surface));
+
+ dig:=DigraphByEdges([ [ 1, 2 ], [ 1, 4 ], [ 1, 5 ], [ 2, 1 ], [ 2, 3 ], [ 2, 6 ], [ 3, 2 ], [ 3, 4 ], [ 3, 5 ], [ 4, 1 ], [ 4, 3 ],
+ [ 4, 6 ], [ 5, 1 ],[ 5, 3 ], [ 5, 6 ], [ 6, 2 ], [ 6, 4 ], [ 6, 5 ] ]);
+ list1:=AllSimplicialSurfacesOfDigraph(dig,false);
+ list2:=AllSimplicialSurfacesOfDigraph(dig,true);
+ Assert(0,Length(list1)=2);
+ Assert(0,Length(list2)=0);
+
+ # One of the smallest face graph with more than one vertex-faithful surface
+ dig:=DigraphByEdges([ [ 1, 9 ], [ 9, 1 ], [ 1, 13 ], [ 13, 1 ], [ 1, 14 ], [ 14, 1 ], [ 2, 6 ], [ 6, 2 ], [ 2, 7 ], [ 7, 2 ], [ 2, 10 ],
+ [ 10, 2 ], [ 3, 10 ],[ 10, 3 ], [ 3, 15 ], [ 15, 3 ], [ 3, 16 ], [ 16, 3 ], [ 4, 6 ], [ 6, 4 ], [ 4, 8 ], [ 8, 4 ],
+ [ 4, 9 ], [ 9, 4 ], [ 5, 6 ], [ 6, 5 ], [ 5, 12 ], [ 12, 5 ],[ 5, 14 ], [ 14, 5 ], [ 7, 8 ], [ 8, 7 ], [ 7, 13 ], [ 13, 7 ],
+ [ 8, 11 ], [ 11, 8 ], [ 9, 10 ], [ 10, 9 ], [ 11, 12 ], [ 12, 11 ], [ 11, 15 ], [ 15, 11 ], [ 12, 16 ], [ 16, 12 ],
+ [ 13, 14 ], [ 14, 13 ], [ 15, 16 ], [ 16, 15 ] ]);
+ list1:=AllSimplicialSurfacesOfDigraph(dig,true);
+ Assert(0,Length(list1)=2);
+
+ Assert(0,Length(AllSimplicialSurfacesByFacesOfEdges (Tetrahedron()))=2);
+ Assert(0,Length(AllSimplicialSurfacesByFacesOfEdges (Tetrahedron(),true))=1);
+ end);
+else
+ BindGlobal( "__SIMPLICIAL_Test_AllSimplicialSurfacesOfDigraph", function() end);
+fi;
+
+
+if IsPackageMarkedForLoading( "Digraphs", ">=1.10.0" ) then
+ BindGlobal( "__SIMPLICIAL_Test_ReembeddingsOfDigraph", function()
+ local digraph, reemb1, reemb2, reemb3;
+ digraph:=CompleteDigraph(4);;
+
+ reemb1:=ReembeddingsOfDigraph(digraph,1,false);
+ Assert(0,Length(reemb1)=1);
+ Assert(0,NumberOfVertices(reemb1[1])=3);
+
+ reemb2:=ReembeddingsOfDigraph(digraph,1,true);
+ Assert(0,reemb2=[]);
+
+ reemb3:=ReembeddingsOfDigraph(digraph,2,false);
+ Assert(0,reemb2=[]);
+ end);
+else
+ BindGlobal( "__SIMPLICIAL_Test_ReembeddingsOfDigraph", function() end);
+fi;
\ No newline at end of file
diff --git a/unit_tests/Test_Graphs.g b/unit_tests/Test_Graphs.g
index 0986c5b6..0ec1284a 100644
--- a/unit_tests/Test_Graphs.g
+++ b/unit_tests/Test_Graphs.g
@@ -62,40 +62,6 @@ BindGlobal( "__SIMPLICIAL_Test_FaceDigraphsGraph", function()
Assert(0, Set(DigraphEdges(digButterfly))=Set(Filtered(Union(FacesOfEdges(butterfly),reversedButterfly),i->Length(i)=2)));
end);
-if IsPackageMarkedForLoading( "Digraphs", ">=1.9.0" ) then
- BindGlobal( "__SIMPLICIAL_Test_AllSimplicialSurfacesOfDigraph", function()
- local dig, surface, list1, list2;
- surface:=SimplicialSurfaceByVerticesInFaces([[1,4,5],[1,4,6],[1,5,7],[1,6,7],[2,3,5],[2,3,6],[2,4,5],[2,4,6],[3,5,7],[3,6,7]]);
- dig:=FaceDigraphsGraph(surface);
-
- list2:=AllSimplicialSurfacesOfDigraph(dig);
- Assert(0, Length(Filtered(list2,IsVertexFaithful))=1);
- Assert(0,IsIsomorphic(Filtered(list2,IsVertexFaithful)[1],surface));
- Assert(0,Length(list2)=11);
-
- list1:=AllSimplicialSurfacesOfDigraph(dig,true);
- Assert(0,Length(list1)=1);
- Assert(0,IsIsomorphic(list1[1],surface));
-
- dig:=DigraphByEdges([ [ 1, 2 ], [ 1, 4 ], [ 1, 5 ], [ 2, 1 ], [ 2, 3 ], [ 2, 6 ], [ 3, 2 ], [ 3, 4 ], [ 3, 5 ], [ 4, 1 ], [ 4, 3 ],
- [ 4, 6 ], [ 5, 1 ],[ 5, 3 ], [ 5, 6 ], [ 6, 2 ], [ 6, 4 ], [ 6, 5 ] ]);
- list1:=AllSimplicialSurfacesOfDigraph(dig,false);
- list2:=AllSimplicialSurfacesOfDigraph(dig,true);
- Assert(0,Length(list1)=2);
- Assert(0,Length(list2)=0);
-
- #One of the smallest face graph with more than one vertex-faithful surface
- dig:=DigraphByEdges([ [ 1, 9 ], [ 9, 1 ], [ 1, 13 ], [ 13, 1 ], [ 1, 14 ], [ 14, 1 ], [ 2, 6 ], [ 6, 2 ], [ 2, 7 ], [ 7, 2 ], [ 2, 10 ],
- [ 10, 2 ], [ 3, 10 ],[ 10, 3 ], [ 3, 15 ], [ 15, 3 ], [ 3, 16 ], [ 16, 3 ], [ 4, 6 ], [ 6, 4 ], [ 4, 8 ], [ 8, 4 ],
- [ 4, 9 ], [ 9, 4 ], [ 5, 6 ], [ 6, 5 ], [ 5, 12 ], [ 12, 5 ],[ 5, 14 ], [ 14, 5 ], [ 7, 8 ], [ 8, 7 ], [ 7, 13 ], [ 13, 7 ],
- [ 8, 11 ], [ 11, 8 ], [ 9, 10 ], [ 10, 9 ], [ 11, 12 ], [ 12, 11 ], [ 11, 15 ], [ 15, 11 ], [ 12, 16 ], [ 16, 12 ],
- [ 13, 14 ], [ 14, 13 ], [ 15, 16 ], [ 16, 15 ] ]);
- list1:=AllSimplicialSurfacesOfDigraph(dig,true);
- Assert(0,Length(list1)=2);
- end);
-else
- BindGlobal( "__SIMPLICIAL_Test_AllSimplicialSurfacesOfDigraph", function() end);
-fi;
if IsPackageMarkedForLoading( "GRAPE", ">=4.8.2" ) then
BindGlobal( "__SIMPLICIAL_Test_IncidenceGrapeGraph", function()
@@ -190,23 +156,3 @@ else
BindGlobal( "__SIMPLICIAL_Test_EdgeNautyGraph", function() end);
BindGlobal( "__SIMPLICIAL_Test_FaceNautyGraph", function() end);
fi;
-
-
-if IsPackageMarkedForLoading( "Digraphs", ">=1.10.0" ) then
- BindGlobal( "__SIMPLICIAL_Test_ReembeddingsOfDigraph", function()
- local digraph, reemb1, reemb2, reemb3;
- digraph:=CompleteDigraph(4);;
-
- reemb1:=ReembeddingsOfDigraph(digraph,1,false);
- Assert(0,Length(reemb1)=1);
- Assert(0,NumberOfVertices(reemb1[1])=3);
-
- reemb2:=ReembeddingsOfDigraph(digraph,1,true);
- Assert(0,reemb2=[]);
-
- reemb3:=ReembeddingsOfDigraph(digraph,2,false);
- Assert(0,reemb2=[]);
- end);
-else
- BindGlobal( "__SIMPLICIAL_Test_ReembeddingsOfDigraph", function() end);
-fi;
\ No newline at end of file