From 3c49a5f694a8669218e9431d25df9e1c91562be1 Mon Sep 17 00:00:00 2001 From: MeikeWeiss Date: Wed, 27 Aug 2025 10:20:15 +0200 Subject: [PATCH 1/6] reordering --- doc/SimplicialSurfaces.xml | 1 - .../constructing_families.gd | 142 ++++- .../constructing_families.gi | 509 +++++++++++++++++- gap/PolygonalComplexes/discs.gd | 80 --- gap/PolygonalComplexes/discs.gi | 152 ------ gap/PolygonalComplexes/graphs.gd | 55 -- gap/PolygonalComplexes/graphs.gi | 340 ------------ init.g | 1 - read.g | 1 - 9 files changed, 638 insertions(+), 643 deletions(-) delete mode 100644 gap/PolygonalComplexes/discs.gd delete mode 100644 gap/PolygonalComplexes/discs.gi 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/PolygonalComplexes/constructing_families.gd b/gap/PolygonalComplexes/constructing_families.gd index 28c57569..09dc2cd1 100644 --- a/gap/PolygonalComplexes/constructing_families.gd +++ b/gap/PolygonalComplexes/constructing_families.gd @@ -1,8 +1,140 @@ -#! @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 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 + + + +#! @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. +#! 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 + +#! @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 diff --git a/gap/PolygonalComplexes/constructing_families.gi b/gap/PolygonalComplexes/constructing_families.gi index 1193f7e0..c64e176a 100644 --- a/gap/PolygonalComplexes/constructing_families.gi +++ b/gap/PolygonalComplexes/constructing_families.gi @@ -1,21 +1,514 @@ +############################################################################# +## +#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; + + ####################################### ## -## Reembedding of Simplicial Spheres +## All Surfaces Of A Graph ## -InstallMethod( ReembeddingsOfDigraph, "for a 3-connected planar graph, a genus and a boolean", -[IsDigraph, IsInt, IsBool], function(digraph, g, orientable) - Error("ReembeddingsOfDigraph: The package Digraph has to be available with version at least 1.10.0."); +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 ); -InstallMethod(ReembeddingsOfSimplicialSphere,"for a vertex-faithful simplicial sphere, a genus and a boolean", - [IsSimplicialSurface, IsInt, IsBool], - function(surf, g, orientable) - Error("ReembeddingsOfSimplicialSphere: The package Digraph has to be available with version at least 1.10.0."); +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; + + +####################################### +## +## Reembedding of Simplicial Spheres +## + +#InstallMethod( ReembeddingsOfDigraph, "for a 3-connected planar graph, a genus and a boolean", +#[IsDigraph, IsInt, IsBool], function(digraph, g, orientable) +# Error("ReembeddingsOfDigraph: The package Digraph has to be available with version at least 1.10.0."); +# end +#); + +#InstallMethod(ReembeddingsOfSimplicialSphere,"for a vertex-faithful simplicial sphere, a genus and a boolean", +# [IsSimplicialSurface, IsInt, IsBool], +# function(surf, g, orientable) +# Error("ReembeddingsOfSimplicialSphere: The package Digraph has to be available with version at least 1.10.0."); +# end +#); + if IsPackageMarkedForLoading( "Digraphs", ">=1.10.0" ) then # Algorithm from Enami and Weiß # Computes for a given vertex-faithful simplicial sphere 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/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..2a646ebe 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" ); From 985264737536193cefce0849775ab1241e3a4677 Mon Sep 17 00:00:00 2001 From: MeikeWeiss Date: Wed, 27 Aug 2025 14:34:01 +0200 Subject: [PATCH 2/6] more reordering and documentation --- gap/Library/library.gd | 280 +-------------- gap/Library/library.gi | 213 +----------- .../constructing_families.gd | 324 ++++++++++++++++-- .../constructing_families.gi | 275 ++++++++++++--- gap/PolygonalComplexes/constructors.gi | 2 +- gap/PolygonalComplexes/properties.gd | 33 ++ gap/PolygonalComplexes/properties.gi | 45 +++ 7 files changed, 593 insertions(+), 579 deletions(-) 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 09dc2cd1..35d2e4d1 100644 --- a/gap/PolygonalComplexes/constructing_families.gd +++ b/gap/PolygonalComplexes/constructing_families.gd @@ -3,51 +3,241 @@ #! 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 Essential discs -#! @SectionLabel Discs_Essential +#! @Section Simplex String and Rings +#! @SectionLabel Strings_Rings -#! This section contains the methods to compute all essential simplicial discs. +#! 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 IsEssentialDisc +#! @BeginGroup SimplexStringByIsomorphismType #! @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. -#! +#! 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> 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); +#! 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 -#! gap> EulerCharacteristic(disc); -#! 1 -#! gap> CounterOfVertices(disc); -#! counter of vertices ([ 2, 3, 4, 5 ] degrees, and [ 1, 2, 3, 2 ] multiplicities) -#! gap> IsEssentialDisc(disc); +#! @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 -#! @Arguments disc -#! @Returns true or false -DeclareOperation( "IsEssentialDisc", [IsTwistedPolygonalComplex] ); +#! +#! @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. #! @@ -183,4 +373,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 c64e176a..bdc25996 100644 --- a/gap/PolygonalComplexes/constructing_families.gi +++ b/gap/PolygonalComplexes/constructing_families.gi @@ -1,54 +1,8 @@ -############################################################################# -## -#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 +## 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 @@ -118,27 +72,24 @@ BindGlobal( "__SIMPLICIAL_AllEssentialTwoPaths", 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]); @@ -830,4 +781,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/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) From 8f612d54f9bf70f89d15dba5b92cce899d5bd2ae Mon Sep 17 00:00:00 2001 From: MeikeWeiss Date: Wed, 27 Aug 2025 14:48:52 +0200 Subject: [PATCH 3/6] reorder tests --- unit_tests/Test_Generating_Families.g | 54 +++++++++++++++++++++++++++ unit_tests/Test_Graphs.g | 54 --------------------------- 2 files changed, 54 insertions(+), 54 deletions(-) create mode 100644 unit_tests/Test_Generating_Families.g diff --git a/unit_tests/Test_Generating_Families.g b/unit_tests/Test_Generating_Families.g new file mode 100644 index 00000000..f44fb990 --- /dev/null +++ b/unit_tests/Test_Generating_Families.g @@ -0,0 +1,54 @@ +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( "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 From d34eb6359365a1b176b64ca3fa42f54616b5c9b3 Mon Sep 17 00:00:00 2001 From: MeikeWeiss Date: Wed, 27 Aug 2025 15:03:09 +0200 Subject: [PATCH 4/6] fixed tests --- read.g | 1 + 1 file changed, 1 insertion(+) diff --git a/read.g b/read.g index 2a646ebe..cb8beb42 100644 --- a/read.g +++ b/read.g @@ -44,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" ); From 2ae474b308f504291d5d93b3bfa0141c28815721 Mon Sep 17 00:00:00 2001 From: MeikeWeiss Date: Thu, 28 Aug 2025 09:57:55 +0200 Subject: [PATCH 5/6] add alternative by AllEdgeFaceEquivalentSurfaces --- .../constructing_families.gd | 30 +++++--- .../constructing_families.gi | 68 ++++++++++++++----- unit_tests/Test_Generating_Families.g | 3 + 3 files changed, 75 insertions(+), 26 deletions(-) diff --git a/gap/PolygonalComplexes/constructing_families.gd b/gap/PolygonalComplexes/constructing_families.gd index 35d2e4d1..d90a8652 100644 --- a/gap/PolygonalComplexes/constructing_families.gd +++ b/gap/PolygonalComplexes/constructing_families.gd @@ -274,13 +274,15 @@ DeclareOperation( "AllSimplicialSurfacesByEssentialButterflyInsertion", [IsSimpl #! @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. +#! 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: @@ -313,15 +315,23 @@ DeclareOperation( "AllSimplicialSurfacesByEssentialButterflyInsertion", [IsSimpl #! [ simplicial surface (4 vertices, 6 edges, and 4 faces) ] #! gap> IsIsomorphic(tet2[1],Tetrahedron()); #! true +#! gap> AllEdgeFaceEquivalentSurfaces(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 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. +#! 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( "AllEdgeFaceEquivalentSurfaces", [IsSimplicialSurface, IsBool]); #! @EndGroup #! @BeginGroup Reembedding diff --git a/gap/PolygonalComplexes/constructing_families.gi b/gap/PolygonalComplexes/constructing_families.gi index bdc25996..113a5bbd 100644 --- a/gap/PolygonalComplexes/constructing_families.gi +++ b/gap/PolygonalComplexes/constructing_families.gi @@ -109,14 +109,14 @@ fi; InstallOtherMethod(AllSimplicialSurfacesOfDigraph,"for a digraph", [IsDigraph], function(digraph) - Error("ReembeddingsOfDigraph: The package Digraph has to be available with version at least 1.9.0."); + 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("ReembeddingsOfDigraph: The package Digraph has to be available with version 1.10.0."); + Error("AllSimplicialSurfacesOfDigraph: The package Digraph has to be available with version 1.10.0."); end ); @@ -176,8 +176,8 @@ InstallMethod(AllSimplicialSurfacesOfDigraph,"for a digraph and a Boolean", cycle,cyclePair,IsPartOf,possibleCyclesPairs,commonEdges,Possible,e; if IsMultiDigraph(digraph) or DigraphHasLoops(digraph) or not IsSymmetricDigraph(digraph) or not IsConnectedDigraph(digraph) then - Error("SimplicialSurfaceOfDigraph: Given digraph has to be simple, symmetric and connected"); - fi; + Error("SimplicialSurfaceOfDigraph: Given digraph has to be simple, symmetric and connected"); + fi; if vertexFaithful then allCycles:=DigraphAllChordlessCycles(digraph); allCycles:=Filtered(allCycles,c->__SIMPLICIAL_IsNonSeparating(digraph,c)); @@ -441,24 +441,60 @@ InstallMethod(AllSimplicialSurfacesOfDigraph,"for a digraph and a Boolean", ); fi; +InstallOtherMethod(AllEdgeFaceEquivalentSurfaces,"for a digraph", + [IsSimplicialSurface], + function(surface) + Error("AllEdgeFaceEquivalentSurfaces: The package Digraph has to be available with version at least 1.9.0."); + end +); + +InstallMethod(AllEdgeFaceEquivalentSurfaces,"for a digraph and a Boolean", + [IsSimplicialSurface,IsBool], + function(surface,vertexFaithful) + Error("AllEdgeFaceEquivalentSurfaces: The package Digraph has to be available with version 1.10.0."); + end +); + +if IsPackageMarkedForLoading( "Digraphs", ">=1.9.0" ) then + InstallOtherMethod(AllEdgeFaceEquivalentSurfaces,"for a simplicial surface", + [IsSimplicialSurface], + function(surface) + if not IsClosedSurface(surface) then + Error("AllEdgeFaceEquivalentSurfaces: The given surface has to be closed"); + fi; + return AllSimplicialSurfacesOfDigraph(FaceDigraphsGraph(surface)); + end + ); + + InstallMethod(AllEdgeFaceEquivalentSurfaces,"for a digraph and a Boolean", + [IsSimplicialSurface,IsBool], + function(surface,vertexFaithful) + if not IsClosedSurface(surface) then + Error("AllEdgeFaceEquivalentSurfaces: The given surface has to be closed"); + fi; + return AllSimplicialSurfacesOfDigraph(FaceDigraphsGraph(surface),vertexFaithful); + end + ); +fi; + ####################################### ## ## Reembedding of Simplicial Spheres ## -#InstallMethod( ReembeddingsOfDigraph, "for a 3-connected planar graph, a genus and a boolean", -#[IsDigraph, IsInt, IsBool], function(digraph, g, orientable) -# Error("ReembeddingsOfDigraph: The package Digraph has to be available with version at least 1.10.0."); -# end -#); - -#InstallMethod(ReembeddingsOfSimplicialSphere,"for a vertex-faithful simplicial sphere, a genus and a boolean", -# [IsSimplicialSurface, IsInt, IsBool], -# function(surf, g, orientable) -# Error("ReembeddingsOfSimplicialSphere: The package Digraph has to be available with version at least 1.10.0."); -# end -#); +InstallMethod( ReembeddingsOfDigraph, "for a 3-connected planar graph, a genus and a boolean", +[IsDigraph, IsInt, IsBool], function(digraph, g, orientable) + Error("ReembeddingsOfDigraph: The package Digraph has to be available with version at least 1.10.0."); + end +); + +InstallMethod(ReembeddingsOfSimplicialSphere,"for a vertex-faithful simplicial sphere, a genus and a boolean", + [IsSimplicialSurface, IsInt, IsBool], + function(surf, g, orientable) + Error("ReembeddingsOfSimplicialSphere: The package Digraph has to be available with version at least 1.10.0."); + end +); if IsPackageMarkedForLoading( "Digraphs", ">=1.10.0" ) then # Algorithm from Enami and Weiß diff --git a/unit_tests/Test_Generating_Families.g b/unit_tests/Test_Generating_Families.g index f44fb990..161ced24 100644 --- a/unit_tests/Test_Generating_Families.g +++ b/unit_tests/Test_Generating_Families.g @@ -28,6 +28,9 @@ if IsPackageMarkedForLoading( "Digraphs", ">=1.9.0" ) then [ 13, 14 ], [ 14, 13 ], [ 15, 16 ], [ 16, 15 ] ]); list1:=AllSimplicialSurfacesOfDigraph(dig,true); Assert(0,Length(list1)=2); + + Assert(0,Length(AllEdgeFaceEquivalentSurfaces(Tetrahedron()))=2); + Assert(0,Length(AllEdgeFaceEquivalentSurfaces(Tetrahedron(),true))=1); end); else BindGlobal( "__SIMPLICIAL_Test_AllSimplicialSurfacesOfDigraph", function() end); From 23e1e271dd0a411c4ecc0dcfe49a4cdac616eaa8 Mon Sep 17 00:00:00 2001 From: MeikeWeiss Date: Thu, 28 Aug 2025 14:57:42 +0200 Subject: [PATCH 6/6] renaming --- gap/PolygonalComplexes/constructing_families.gd | 4 ++-- gap/PolygonalComplexes/constructing_families.gi | 16 ++++++++-------- unit_tests/Test_Generating_Families.g | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/gap/PolygonalComplexes/constructing_families.gd b/gap/PolygonalComplexes/constructing_families.gd index d90a8652..f225f0ea 100644 --- a/gap/PolygonalComplexes/constructing_families.gd +++ b/gap/PolygonalComplexes/constructing_families.gd @@ -315,7 +315,7 @@ DeclareOperation( "AllSimplicialSurfacesByEssentialButterflyInsertion", [IsSimpl #! [ simplicial surface (4 vertices, 6 edges, and 4 faces) ] #! gap> IsIsomorphic(tet2[1],Tetrahedron()); #! true -#! gap> AllEdgeFaceEquivalentSurfaces(Tetrahedron()); +#! gap> AllSimplicialSurfacesByFacesOfEdges (Tetrahedron()); #! [ simplicial surface (4 vertices, 6 edges, and 4 faces), #! simplicial surface (3 vertices, 6 edges, and 4 faces) ] #! @EndLogSession @@ -331,7 +331,7 @@ DeclareOperation( "AllSimplicialSurfacesByEssentialButterflyInsertion", [IsSimpl DeclareOperation( "AllSimplicialSurfacesOfDigraph", [IsDigraph, IsBool]); #! @Arguments surface[, vertexfaithful] #! @Returns a list -DeclareOperation( "AllEdgeFaceEquivalentSurfaces", [IsSimplicialSurface, IsBool]); +DeclareOperation( "AllSimplicialSurfacesByFacesOfEdges", [IsSimplicialSurface, IsBool]); #! @EndGroup #! @BeginGroup Reembedding diff --git a/gap/PolygonalComplexes/constructing_families.gi b/gap/PolygonalComplexes/constructing_families.gi index 113a5bbd..505213a9 100644 --- a/gap/PolygonalComplexes/constructing_families.gi +++ b/gap/PolygonalComplexes/constructing_families.gi @@ -441,36 +441,36 @@ InstallMethod(AllSimplicialSurfacesOfDigraph,"for a digraph and a Boolean", ); fi; -InstallOtherMethod(AllEdgeFaceEquivalentSurfaces,"for a digraph", +InstallOtherMethod(AllSimplicialSurfacesByFacesOfEdges ,"for a digraph", [IsSimplicialSurface], function(surface) - Error("AllEdgeFaceEquivalentSurfaces: The package Digraph has to be available with version at least 1.9.0."); + Error("AllSimplicialSurfacesByFacesOfEdges: The package Digraph has to be available with version at least 1.9.0."); end ); -InstallMethod(AllEdgeFaceEquivalentSurfaces,"for a digraph and a Boolean", +InstallMethod(AllSimplicialSurfacesByFacesOfEdges ,"for a digraph and a Boolean", [IsSimplicialSurface,IsBool], function(surface,vertexFaithful) - Error("AllEdgeFaceEquivalentSurfaces: The package Digraph has to be available with version 1.10.0."); + Error("AllSimplicialSurfacesByFacesOfEdges: The package Digraph has to be available with version 1.10.0."); end ); if IsPackageMarkedForLoading( "Digraphs", ">=1.9.0" ) then - InstallOtherMethod(AllEdgeFaceEquivalentSurfaces,"for a simplicial surface", + InstallOtherMethod(AllSimplicialSurfacesByFacesOfEdges ,"for a simplicial surface", [IsSimplicialSurface], function(surface) if not IsClosedSurface(surface) then - Error("AllEdgeFaceEquivalentSurfaces: The given surface has to be closed"); + Error("AllSimplicialSurfacesByFacesOfEdges: The given surface has to be closed"); fi; return AllSimplicialSurfacesOfDigraph(FaceDigraphsGraph(surface)); end ); - InstallMethod(AllEdgeFaceEquivalentSurfaces,"for a digraph and a Boolean", + InstallMethod(AllSimplicialSurfacesByFacesOfEdges,"for a digraph and a Boolean", [IsSimplicialSurface,IsBool], function(surface,vertexFaithful) if not IsClosedSurface(surface) then - Error("AllEdgeFaceEquivalentSurfaces: The given surface has to be closed"); + Error("AllSimplicialSurfacesByFacesOfEdges: The given surface has to be closed"); fi; return AllSimplicialSurfacesOfDigraph(FaceDigraphsGraph(surface),vertexFaithful); end diff --git a/unit_tests/Test_Generating_Families.g b/unit_tests/Test_Generating_Families.g index 161ced24..1593bbb2 100644 --- a/unit_tests/Test_Generating_Families.g +++ b/unit_tests/Test_Generating_Families.g @@ -29,8 +29,8 @@ if IsPackageMarkedForLoading( "Digraphs", ">=1.9.0" ) then list1:=AllSimplicialSurfacesOfDigraph(dig,true); Assert(0,Length(list1)=2); - Assert(0,Length(AllEdgeFaceEquivalentSurfaces(Tetrahedron()))=2); - Assert(0,Length(AllEdgeFaceEquivalentSurfaces(Tetrahedron(),true))=1); + Assert(0,Length(AllSimplicialSurfacesByFacesOfEdges (Tetrahedron()))=2); + Assert(0,Length(AllSimplicialSurfacesByFacesOfEdges (Tetrahedron(),true))=1); end); else BindGlobal( "__SIMPLICIAL_Test_AllSimplicialSurfacesOfDigraph", function() end);