Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/GAP/pkg/simpcomp/lib/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 18.2.2022 mit Größe 47 kB image not shown  

SSL normalsurface.gi   Sprache: unbekannt

 
################################################################################
##
##  simpcomp / normalsurface.gi
##
##  Normal surfaces
##
##  $Id$
##
################################################################################

SCNormalSurfaceFamily:=NewFamily("SCNormalSurfaceFamily",SCIsNormalSurface and IsMutable and IsCopyable);
SCNormalSurfaceType:=NewType(SCNormalSurfaceFamily,SCIsNormalSurface and IsAttributeStoringRep and IsListOrCollection);

#properties of which the values are displayed by ViewObj of SCNormalSurface 
SCIntFunc.SCNSViewProperties:=[ "Name", "Dim", "FVector", "EulerCharacteristic", "IsOrientable", "Homology", "TopologicalType" ];

#print simplicial complex info (in compact format)
#compact format: dim, chi, fvec, hom
InstallMethod(ViewObj,"for SCNormalSurface",
[SCIsNormalSurface],
function(sc)
 Print(SCIntFunc.StringEx(sc));
end);

#simplicial complex -> string method
InstallMethod(String,"for SCNormalSurface",
[SCIsNormalSurface],
function(sc)
 return SCIntFunc.StringEx(sc);
end);


#print simplicial complex info
InstallMethod(PrintObj,
"for SCNormalSurface",
[SCIsNormalSurface],
function(sc)
 Print(SCIntFunc.StringEx(sc));
end);

# create new complex as SCNormalSurface and empty attributes
SCIntFunc.SCNSNew:=
function()
 return Objectify(SCNormalSurfaceType,rec(Properties:=rec(), PropertiesTmp:=rec(forceCalc:=false), PropertyHandlers:=SCIntFunc.SCNSPropertyHandlers));
end;

# create new complex as SCNormalSurface with predefined attributes
SCIntFunc.SCNSNewWithProperties:=
function(props)
 return Objectify(SCNormalSurfaceType,rec(Properties:=ShallowCopy(props),  PropertiesTmp:=rec(forceCalc:=false), PropertyHandlers:=SCIntFunc.SCNSPropertyHandlers));
end;

################################################################################
##<#GAPDoc Label="NSOpPlusSCInt">
## <ManSection>
## <Meth Name="Operation + (SCNormalSurface, Integer)" Arg="complex, value"/>
## <Returns>the discrete normal surface passed as argument upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Positively shifts the vertex labels of <Arg>complex</Arg> (provided that all labels satisfy the property <C>IsAdditiveElement</C>) by the amount specified in <Arg>value</Arg>.
## <Example><![CDATA[
## gap> sl:=SCNSSlicing(SCBdSimplex(4),[[1],[2..5]]);;
## gap> sl.Facets;                                    
## [ [ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ] ], [ [ 1, 2 ], [ 1, 3 ], [ 1, 5 ] ], 
##   [ [ 1, 2 ], [ 1, 4 ], [ 1, 5 ] ], [ [ 1, 3 ], [ 1, 4 ], [ 1, 5 ] ] ]
## gap> sl:=sl + 2;;                                  
## gap> sl.Facets;  
## [ [ [ 3, 4 ], [ 3, 5 ], [ 3, 6 ] ], [ [ 3, 4 ], [ 3, 5 ], [ 3, 7 ] ], 
##   [ [ 3, 4 ], [ 3, 6 ], [ 3, 7 ] ], [ [ 3, 5 ], [ 3, 6 ], [ 3, 7 ] ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(
 \+,"for SCNormalSurface, Integer",
 [SCIsNormalSurface,IsInt],
function(complex, value)
 return SCIntFunc.OperationLabels(complex,function(x) return x+value; end);
end);

################################################################################
##<#GAPDoc Label="NSOpMinusSCInt">
## <ManSection>
## <Meth Name="Operation - (SCNormalSurface, Integer)" Arg="complex, value"/>
## <Returns>the discrete normal surface passed as argument upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Negatively shifts the vertex labels of <Arg>complex</Arg> (provided that all labels satisfy the property <C>IsAdditiveElement</C>) by the amount specified in <Arg>value</Arg>.
## <Example><![CDATA[
## gap> sl:=SCNSSlicing(SCBdSimplex(4),[[1],[2..5]]);;
## gap> sl.Facets;                                    
## [ [ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ] ], [ [ 1, 2 ], [ 1, 3 ], [ 1, 5 ] ], 
##   [ [ 1, 2 ], [ 1, 4 ], [ 1, 5 ] ], [ [ 1, 3 ], [ 1, 4 ], [ 1, 5 ] ] ]
## gap> sl:=sl - 2;;                                  
## gap> sl.Facets;  
## [ [ [ -1, 0 ], [ -1, 1 ], [ -1, 2 ] ], [ [ -1, 0 ], [ -1, 1 ], [ -1, 3 ] ], 
##   [ [ -1, 0 ], [ -1, 2 ], [ -1, 3 ] ], [ [ -1, 1 ], [ -1, 2 ], [ -1, 3 ] ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(
 \-,"for SCNormalSurface, Integer",
 [SCIsNormalSurface,IsInt],
function(complex, value)
 return complex+(-value);
end);

################################################################################
##<#GAPDoc Label="Operation * (SCNormalSurface, Integer)">
## <ManSection>
## <Meth Name="Operation * (SCNormalSurface, Integer" Arg="complex, value"/>
## <Returns>the discrete normal surface passed as argument upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Multiplies the vertex labels of <Arg>complex</Arg> (provided that all labels satisfy the property <C>IsAdditiveElement</C>) with the integer specified in <Arg>value</Arg>.
## <Example><![CDATA[
## gap> sl:=SCNSSlicing(SCBdSimplex(4),[[1],[2..5]]);;
## gap> sl.Facets;                                    
## [ [ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ] ], [ [ 1, 2 ], [ 1, 3 ], [ 1, 5 ] ], 
##   [ [ 1, 2 ], [ 1, 4 ], [ 1, 5 ] ], [ [ 1, 3 ], [ 1, 4 ], [ 1, 5 ] ] ]
## gap> sl:=sl * 2;;                                  
## gap> sl.Facets;  
## [ [ [ 2, 4 ], [ 2, 6 ], [ 2, 8 ] ], [ [ 2, 4 ], [ 2, 6 ], [ 2, 10 ] ], 
##   [ [ 2, 4 ], [ 2, 8 ], [ 2, 10 ] ], [ [ 2, 6 ], [ 2, 8 ], [ 2, 10 ] ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(
 \*,"for SCNormalSurface, Integer",
 [SCIsNormalSurface,IsInt],
function(complex, value)
 return SCIntFunc.OperationLabels(complex,function(x) return x*value; end);
end);

################################################################################
##<#GAPDoc Label="NSOpModSCInt">
## <ManSection>
## <Meth Name="Operation mod (SCNormalSurface, Integer)" Arg="complex, value"/>
## <Returns>the discrete normal surface passed as argument upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Takes all vertex labels of <Arg>complex</Arg> modulo the value specified in <Arg>value</Arg> (provided that all labels satisfy the property <C>IsAdditiveElement</C>). Warning: this might result in different vertices being assigned the same label or even invalid facet lists, so be careful.
## <Example><![CDATA[
## gap> sl:=SCNSSlicing(SCBdSimplex(4),[[1],[2..5]]);;    
## gap> sl.Facets;
## [ [ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ] ], [ [ 1, 2 ], [ 1, 3 ], [ 1, 5 ] ], 
##   [ [ 1, 2 ], [ 1, 4 ], [ 1, 5 ] ], [ [ 1, 3 ], [ 1, 4 ], [ 1, 5 ] ] ]
## gap> sl:=sl mod 2;;
## gap> sl.Facets;    
## [ [ [ 1, 0 ], [ 1, 1 ], [ 1, 0 ] ], [ [ 1, 0 ], [ 1, 1 ], [ 1, 1 ] ], 
##   [ [ 1, 0 ], [ 1, 0 ], [ 1, 1 ] ], [ [ 1, 1 ], [ 1, 0 ], [ 1, 1 ] ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(
 \mod,"for SCNormalSurface, Integer",
 [SCIsNormalSurface,IsInt],
function(complex, value)
 return SCIntFunc.OperationLabels(complex,function(x) return x mod value; end);
end);

################################################################################
##<#GAPDoc Label="NSOpUnionSCSC">
## <ManSection>
## <Meth Name="Operation Union (SCNormalSurface, SCNormalSurface)" Arg="complex1, complex2"/>
## <Returns>discrete normal surface of type <C>SCNormalSurface</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the union of two discrete normal surfaces by calling <Ref Meth="SCUnion"/>.
## <Example><![CDATA[
## gap> SCLib.SearchByAttribute("F = [ 10, 35, 50, 25 ]");
## [ [ 19, "S^3 (VT)" ] ]
## gap> c:=SCLib.Load(last[1][1]);;
## gap> sl1:=SCNSSlicing(c,[[1,3,5,7,9],[2,4,6,8,10]]);;
## gap> sl2:=sl1+10;;
## gap> SCTopologicalType(sl1);
## "T^2"
## gap> sl3:=Union(sl1,sl2);;
## gap> SCTopologicalType(sl3);
## "T^2 U T^2"
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(
 Union2,
 "for SCNormalSurface, SCNormalSurface",
 [SCIsNormalSurface,SCIsNormalSurface],
function(complex1,complex2)
 return SCUnion(complex1,complex2);
end);

InstallMethod(Size,
"for SCNormalSurface",
[SCIsNormalSurface],
function(complex)
 local f;
 
 f:=SCFVector(complex);
 
 if(f=fail) then
  return fail;
 else
  return Size(f);
 fi;
end);

InstallMethod(Length,
"for SCNormalSurface",
[SCIsNormalSurface],
function(complex)
 return Size(complex);
end);

InstallMethod(
 \[\],"for SCNormalSurface",
 [SCIsNormalSurface,IsPosInt],
function(complex, pos)
 local skel,f;

 f:=SCFVector(complex);
 if(f=fail) then
  return fail;
 fi;
 
 if(pos<1 or pos>Size(f)) then
  return [];
 fi;
 
 skel:=SCSkel(complex,pos-1);

 if(skel=fail) then
  return fail;
 fi;
 
 return skel;
end);

InstallMethod(
 IsBound\[\],"for SCNormalSurface",
 [SCIsNormalSurface,IsPosInt],
function(complex, pos)
 local f;
 f:=SCFVector(complex);
 
 if(f=fail) then
  return fail;
 else
  return pos>=1 and pos<=Size(f);
 fi;
end);

InstallMethod(
 Iterator,"for SCNormalSurface",
 [SCIsNormalSurface],
function(complex)
 local faces;
 faces:=SCFaceLattice(complex);

 if(faces=fail) then
  return fail;
 fi;
 
 return Iterator(faces);
end);

InstallMethod(
 IsSubset,"for SCNormalSurface",
 [SCIsNormalSurface,SCIsNormalSurface],
function(complex1,complex2)
 return SCIsSubcomplex(complex1,complex2);
end);

SCIntFunc.isValidNormalSurface:=function(facets)
  if(not IsList(facets) or not IsDuplicateFreeList(facets) or not ForAll(facets,x->IsList(x) and IsDuplicateFree(x) and (Size(x) in [3,4])) or not SCIntFunc.HasValidLabels(facets)) then
   return false;
  else
   return true;
  fi;
end;


################################################################################
##<#GAPDoc Label="SCNSFromFacets">
## <ManSection>
## <Meth Name="SCNSFromFacets" Arg="facets"/>
## <Returns>discrete normal surface of type <C>SCNormalSurface</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Constructor for a discrete normal surface from a facet list, see <Ref Meth="SCFromFacets"/> for details.
## <Example><![CDATA[
## gap> sl:=SCNSFromFacets([[1,2,3],[1,2,4,5],[1,3,4,6],[2,3,5,6],[4,5,6]]);
## [NormalSurface
## 
##  Properties known: Dim, Facets, Name, SCVertices.
## 
##  Name="unnamed discrete normal surface m"
##  Dim=2
## 
## /NormalSurface]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCNSFromFacets,
"for List",
[IsList],
function(facets)
 local obj,dim,faces,known,element,vertices,i,j,idx,lfacets;

 if(not SCIntFunc.isValidNormalSurface(facets)) then
  Info(InfoSimpcomp,1,"SCNormalSurface: invalid facet list.");
  return fail;
 fi;

 if(facets=[]) then
  obj:=SCNSEmpty();
 else

  lfacets:=Set(SCIntFunc.DeepCopy(facets));
  Perform(lfacets,Sort);
  vertices:=Union(lfacets);
  for i in [1..Size(lfacets)] do
   for j in [1..Size(lfacets[i])] do
    idx:=Position(vertices,lfacets[i][j]);
    if idx<>fail then
     lfacets[i][j]:=idx;
    else
     Info(InfoSimpcomp,1,"SCNSFromFacets: error in vertex index.");
     return fail;
    fi;
   od;
  od;

  obj:=SCIntFunc.SCNSNew();
  SetSCVertices(obj,vertices);
  SetSCDim(obj,2);
  SetSCFacetsEx(obj,lfacets);
  SetSCName(obj,Concatenation("unnamed complex ",String(SCSettings.ComplexCounter)));
  
  SCSettings.ComplexCounter:=SCSettings.ComplexCounter+1;
 fi;

 return obj;
end);

################################################################################
##<#GAPDoc Label="SCNS">
## <ManSection>
## <Meth Name="SCNS" Arg="facets"/>
## <Returns>discrete normal surface of type <C>SCNormalSurface</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Internally calls <Ref Meth="SCNSFromFacets"/>.
## <Example><![CDATA[
## gap> sl:=SCNS([[1,2,3],[1,2,4,5],[1,3,4,6],[2,3,5,6],[4,5,6]]);
## [NormalSurface
## 
##  Properties known: Dim, Facets, Name, SCVertices.
## 
##  Name="unnamed discrete normal surface n"
##  Dim=2
## 
## /NormalSurface]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCNS,
"for List",
[IsList],
function(facets)
 return SCNSFromFacets(facets);
end);

#print discrete normal surface info (in compact format)
#compact format: chi, fvec
InstallMethod(ViewObj,"for SCNormalSurface",
[SCIsNormalSurface],
 function(sl)
 Print(String(sl));
end);

##print simplicial complex info
InstallMethod(
PrintObj,"for SCNormalSurface",
[SCIsNormalSurface],
 function(sl)
  Print(String(sl));
end);


################################################################################
##<#GAPDoc Label="SCNSCopy">
## <ManSection>
## <Meth Name="SCCopy" Arg="complex"/>
## <Returns>discrete normal surface of type <C>SCNormalSurface</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Copies a &GAP; object of type <C>SCNormalSurface</C> (cf. <Ref Meth="SCCopy"/>).
## <Example><![CDATA[
## gap> sl:=SCNSSlicing(SCBdSimplex(4),[[1],[2..5]]);
## [NormalSurface
## 
##  Properties known: Chi, ConnectedComponents, Dim, F, Facets, Genus, IsConnect\
## ed, Name, Oriented, Subdivision, TopologicalType, SCVertices, Vertices.
## 
##  Name="slicing [ [ 1 ], [ 2, 3, 4, 5 ] ] of S^3_5"
##  Dim=2
##  Chi=2
##  F=[ 4, 6, 4 ]
##  IsConnected=true
##  TopologicalType="S^2"
## 
## /NormalSurface]
## gap> sl_2:=SCCopy(sl);                          
## [NormalSurface
## 
##  Properties known: Chi, ConnectedComponents, Dim, F, Facets, Genus, IsConnect\
## ed, Name, Oriented, Subdivision, TopologicalType, SCVertices, Vertices.
## 
##  Name="slicing [ [ 1 ], [ 2, 3, 4, 5 ] ] of S^3_5"
##  Dim=2
##  Chi=2
##  F=[ 4, 6, 4 ]
##  IsConnected=true
##  TopologicalType="S^2"
## 
## /NormalSurface]
## gap> IsIdenticalObj(sl,sl_2);                     
## false
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCCopy,
"for SCNormalSurface",
[SCIsNormalSurface],
function(complex)

 local a,c,attr;
 
 attr:=KnownAttributesOfObject(complex);
 c:=SCIntFunc.SCNSNew();
 if c = fail then
  return fail;
 fi;
 
 for a in attr do
  Setter(EvalString(a))(c,complex!.(a));
 od;
 return c;
end);

#check which faces already exist (by dimension)
#existNSFaces:=function(complex,size)

#  local faces;

#  faces:=SCPropertyByName(complex,"Faces");
#  if size<=4 then
#   if faces<>fail then
#    if size<=Size(faces) and IsBound(faces[size]) and faces[size]<>[] then
#     if(not IsList(faces[size]) or not IsDuplicateFreeList(faces[size]) or not ForAll(faces[size],x->IsList(x) and IsDuplicateFree(x) and Size(x) in [3,4])) then
#      Info(InfoSimpcomp,1,"existNSFaces: invalid face lattice found.");
#      return fail;
#     else
#      return true;
#     fi;
#    else
#     return false;
#    fi;
#   else
#    return false;
#   fi;
#  else
#   Info(InfoSimpcomp,1,"existNSFaces: Size must be equal or smaller then 4.");
#   return fail;
#  fi;
# end;


################################################################################
##<#GAPDoc Label="SCNSEmpty">
## <ManSection>
## <Func Name="SCNSEmpty" Arg=""/>
## <Returns>discrete normal surface of type <C>SCNormalSurface</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Generates an empty complex (of dimension <M>-1</M>), i. e. an object of type <C>SCNormalSurface</C> with empty facet list.
## <Example><![CDATA[
## gap> SCNSEmpty();
## [NormalSurface
## 
##  Properties known: Dim, Faces, Facets, Name, SCVertices.
## 
##  Name="empty discrete normal surface"
##  Dim=-1
## 
## /NormalSurface]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCNSEmpty,
function()
 local obj;

 obj:=SCIntFunc.SCNSNew();
 SetSCVertices(obj,[]);
 SetSCDim(obj,-1);
 SetSCFacetsEx(obj,[]);
 SetSCName(obj,"empty normal surface"); 
 SetFilterObj(obj,IsEmpty);
 
 return obj;
end);

################################################################################
##<#GAPDoc Label="SCNSDim">
## <ManSection>
## <Meth Name="SCDim" Arg="sl"/>
## <Returns>an integer upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the dimension of a discrete normal surface (which is always <M>2</M> if the slicing <Arg>sl</Arg> is not empty).
## <Example><![CDATA[
## gap> sl:=SCNSEmpty();;                                                    
## gap> SCDim(sl);                                                         
## -1
## gap> sl:=SCNSFromFacets([[1,2,3],[1,2,4,5],[1,3,4,6],[2,3,5,6],[4,5,6]]);;
## gap> SCDim(sl);                                                         
## 2
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCDim,
"for SCNormalSurface",
[SCIsNormalSurface],
function(sl)
 
 if SCIsEmpty(sl) then
  return -1;
 else
   return 2;
 fi;

end);

################################################################################
##<#GAPDoc Label="SCNSFVector">
## <ManSection>
## <Meth Name="SCFVector" Arg="sl"/>
## <Returns>a <M>1</M>, <M>3</M> or <M>4</M> tuple of (non-negative) integer values upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the <M>f</M>-vector of a discrete normal surface, i. e. the number of vertices, edges, triangles and quadrilaterals of <Arg>sl</Arg>, cf. <Ref Meth="SCFVector"/>.
## <Example><![CDATA[
## gap> list:=SCLib.SearchByName("S^2xS^1");;
## gap> c:=SCLib.Load(list[1][1]);;             
## gap> sl:=SCNSSlicing(c,[[1..5],[6..10]]);;
## gap> SCFVector(sl);                 
## [ 20, 40, 16, 8 ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCFVector,
"for SCNormalSurface and SCIsEmpty",
[SCIsNormalSurface and IsEmpty],
function(sl)
 return [0];
end);


InstallMethod(SCFVector,
"for SCNormalSurface",
[SCIsNormalSurface],
function(sl)

  local elements, f, faces, facets;


 facets:=SCFacetsEx(sl);
 if facets = fail then
  return fail;
 fi;
 f:=ShallowCopy(SCFVector(SCFromFacets(facets)));
 if f = fail then
  return fail;
 fi;
  
  if Length(f) =3 then
     return f;
  elif Length(f) =4 then
   f[3]:=f[3] - 4*f[4];
   f[2]:=f[2] - 2*f[4];
     return f;
  else
   Info(InfoSimpcomp,1,"SCFVector: illegal f-vector found: ",f);
   return fail;
  fi;
end);

################################################################################
##<#GAPDoc Label="SCNSEulerCharacteristic">
## <ManSection>
## <Meth Name="SCEulerCharacteristic" Arg="sl"/>
## <Returns>an integer upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the Euler characteristic of a discrete normal surface <Arg>sl</Arg>, cf. <Ref Meth="SCEulerCharacteristic"/>.
## <Example><![CDATA[
## gap> list:=SCLib.SearchByName("S^2xS^1");;  
## gap> c:=SCLib.Load(list[1][1]);;             
## gap> sl:=SCNSSlicing(c,[[1..5],[6..10]]);;
## gap> SCEulerCharacteristic(sl);                 
## 4
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCEulerCharacteristic,
"for SCNormalSurface",
[SCIsNormalSurface],
function(sl)

  local facets, f, chi;

   
  f:=SCFVector(sl);
  if(f=fail) then
   return fail;
  fi;
 
 if Length(f) = 1 then
    return f[1];
 elif Length(f) =3 then
     return f[1]-f[2]+f[3];
  elif Length(f) =4 then
     return f[1]-f[2]+f[3]+f[4];
  else
   Info(InfoSimpcomp,1,"SCEulerCharacteristic: illegal f-vector found: ",f,". ");
   return fail;
  fi;

end);


################################################################################
##<#GAPDoc Label="SCNSGenus">
## <ManSection>
## <Meth Name="SCGenus" Arg="sl"/>
## <Returns>a non-negative integer upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the genus of a discrete normal surface <Arg>sl</Arg>.
## <Example><![CDATA[
## gap> SCLib.SearchByName("(S^2xS^1)#20");
## [ [ 633, "(S^2xS^1)#20" ] ]
## gap> c:=SCLib.Load(last[1][1]);;               
## gap> c.F;                               
## [ 27, 298, 542, 271 ]
## gap> sl:=SCNSSlicing(c,[[1..12],[13..27]]);;
## gap> SCIsConnected(sl);
## true
## gap> SCGenus(sl);                     
## 7
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCGenus,
"for SCNormalSurface",
[SCIsNormalSurface],
function(sl)

  local facets, chi, g, conn;

   
  conn:=SCIsConnected(sl);
  if conn<>true then
   Info(InfoSimpcomp,1,"SCGenus: discrete normal surface needs to be connected and valid.");
   return fail;
 fi;
 
  chi:=SCEulerCharacteristic(sl);
  if(chi=fail) then
   return fail;
 fi;
   return (2-chi)/2;

end);

################################################################################
##<#GAPDoc Label="SCNSIsEmpty">
## <ManSection>
## <Meth Name="SCIsEmpty" Arg="complex"/>
## <Returns><K>true</K> or <K>false</K> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Checks if a normal surface <Arg>complex</Arg> is the empty complex, i. e. a <C>SCNormalSurface</C> object with empty facet list.
## <Example><![CDATA[
## gap> sl:=SCNS([]);;
## gap> SCIsEmpty(sl);
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCIsEmpty,
"for SCNormalSurface",
[SCIsNormalSurface],
function(complex)

 local facets, empty;

   
 facets:=SCFacetsEx(complex);
 if(facets=fail) then
  return fail;
 fi;

 empty:=facets=[];
 if empty = true then
  SetFilterObj(complex,IsEmpty);
 fi;
 return facets=[];
end);

################################################################################
##<#GAPDoc Label="SCNSUnion">
## <ManSection>
## <Meth Name="SCUnion" Arg="complex1, complex2"/>
## <Returns>normal surface of type <C>SCNormalSurface</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Forms the union of two normal surfaces <Arg>complex1</Arg> and <Arg>complex2</Arg> as the normal surface formed by the union of their facet sets. The two arguments are not altered. Note: for the union process the vertex labelings of the complexes are taken into account, see also <Ref Meth="Operation Union (SCNormalSurface, SCNormalSurface)" />. Facets occurring in both arguments are treated as one facet in the new complex.
## <Example><![CDATA[
## gap> list:=SCLib.SearchByAttribute("Dim=3 and F[1]=10");;
## gap> c:=SCLib.Load(list[1][1]);
## gap> sl1:=SCNSSlicing(c,[[1..5],[6..10]]);;
## gap> sl2:=sl1+10;;
## gap> sl3:=SCUnion(sl1,sl2);;
## gap> SCTopologicalType(sl3);
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCUnion,
"for SCNormalSurface and SCNormalSurface",
[SCIsNormalSurface,SCIsNormalSurface],
function(complex1,complex2)
 local facets,un,f1,f2;
 
 f1:=SCIntFunc.DeepCopy(SCFacets(complex1));
 f2:=SCIntFunc.DeepCopy(SCFacets(complex2));
 if f1 = fail or f2 = fail then
  return fail;
 fi;
 SCIntFunc.DeepSortList(f1);
 SCIntFunc.DeepSortList(f2);
 
 facets:=Union(f1,f2);
 if(fail in facets) then
  return fail;
 fi;

 un:=SCNSFromFacets(facets);

 if un = fail then
  Info(InfoSimpcomp,1,"SCUnion: can not unite complexes.");
  return fail;
 fi;
 
 if(SCName(complex1)<>fail and SCName(complex2)<>fail) then
  SCRename(un,Concatenation(SCName(complex1)," cup ",SCName(complex2)));
 fi;
 
 return un;
end);


################################################################################
##<#GAPDoc Label="SCNSIsConnected">
## <ManSection>
## <Meth Name="SCIsConnected" Arg="complex"/>
## <Returns><K>true</K> or <K>false</K> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Checks if a normal surface <Arg>complex</Arg> is connected.
## <Example><![CDATA[
## gap> list:=SCLib.SearchByAttribute("Dim=3 and F[1]=10");;
## gap> c:=SCLib.Load(list[1][1]);
## gap> sl:=SCNSSlicing(c,[[1..5],[6..10]]);
## gap> SCIsConnected(sl);
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCIsConnected,
"for SCNormalSurface and IsEmpty",
[SCIsNormalSurface and IsEmpty],
function(complex)
  return false;
end);

InstallMethod(SCIsConnected,
"for SCNormalSurface",
[SCIsNormalSurface],
function(complex)

 local vertices, star, connected,
  verticesComponent, innerVertices, treatedVertices, curv;
  

 vertices:=SCVertices(complex);
 if vertices=fail then
  return fail;
 fi;
 
 innerVertices:=[vertices[1]];
 treatedVertices:=[];
 verticesComponent:=[];
 
 while verticesComponent<>vertices and innerVertices<>[] do
  curv:=innerVertices[1];
  star:=SCStar(complex,[curv]);
  
  innerVertices:=Union(innerVertices,Difference(SCVertices(star),treatedVertices));
  
  AddSet(treatedVertices,curv);
  RemoveSet(innerVertices,curv);
  
  verticesComponent:=Union(verticesComponent,SCIntFunc.DeepCopy(SCVertices(star)));
 od;

 return verticesComponent=vertices;
end);

################################################################################
##<#GAPDoc Label="SCNSConnectedComponents">
## <ManSection>
## <Meth Name="SCConnectedComponents" Arg="complex"/>
## <Returns> a list of simplicial complexes of type <C>SCNormalSurface</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes all connected components of an arbitrary normal surface.
## <Example><![CDATA[
## gap> sl:=SCNSSlicing(SCBdCrossPolytope(4),[[1,2],[3..8]]);
## gap> cc:=SCConnectedComponents(sl);
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>                                         
################################################################################
InstallMethod(SCConnectedComponents,
"for SCNormalSurface",
[SCIsNormalSurface],
function(complex)

 local vertices, star, conncomps, verticesComponent, innerVertices, treatedVertices, name, i, labels, span, facets, sc;
 

 labels:=SCVertices(complex);
 if(labels=fail) then
  Info(InfoSimpcomp,1,"SCConnectedComponents: complex lacks vertex labels.");
  return fail;
 fi;

 facets:=SCFacetsEx(complex);
 vertices:=SCVerticesEx(complex);
 if facets=fail or vertices=fail then
  return fail;
 fi;
 
 conncomps:=[];
 while vertices<>[] do 
  innerVertices:=[vertices[1]];
  treatedVertices:=[];
  verticesComponent:=[];
  while verticesComponent<>vertices and innerVertices<>[] do
   star:=Filtered(facets,x->innerVertices[1] in x);
   AddSet(treatedVertices,innerVertices[1]);
   RemoveSet(innerVertices,innerVertices[1]);
   innerVertices:=Union(innerVertices,Difference(Union(star),treatedVertices));
   verticesComponent:=Union(verticesComponent,Union(star));
  od;
  span:=Filtered(facets,x->IsSubset(verticesComponent,x));
  Add(conncomps,span);
  vertices:=Difference(vertices,verticesComponent);
 od;

 
 name:=SCName(complex);
 if name = fail then
  return fail;
 fi;
 
 if(Size(conncomps)>0) then
  for i in [1..Length(conncomps)] do
   conncomps[i]:=SCNSFromFacets(SCIntFunc.RelabelSimplexList(conncomps[i],labels));
   SCRename(conncomps[i],Concatenation(["Connected component #",String(i)," of ",name])); 
  od;
 fi;
 
 SetSCIsConnected(complex,Size(conncomps)=1);
 return conncomps;

end);



################################################################################
##<#GAPDoc Label="SCNSSkelEx">
## <ManSection>
## <Meth Name="SCSkelEx" Arg="sl,k"/>
## <Returns>a face list (of <Arg>k+1</Arg>tuples) or a list of face lists upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes all faces of cardinality <Arg>k+1</Arg> in the standard labeling: <Arg>k</Arg> <M>= 0</M> computes the vertices,  <Arg>k</Arg> <M>= 1</M> computes the edges,  <Arg>k</Arg> <M>= 2</M> computes the triangles,  <Arg>k</Arg> <M>= 3</M> computes the quadrilaterals.<P/>
## 
## If <Arg>k</Arg> is a list (necessarily a sublist of <C>[ 0,1,2,3 ]</C>) all faces of all cardinalities contained in <Arg>k</Arg> are computed.
## <Example><![CDATA[
## gap> c:=SCBdSimplex(4);;              
## gap> sl:=SCNSSlicing(c,[[1],[2..5]]);;
## gap> SCSkelEx(sl,1);                            
## [ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 2, 3 ], [ 2, 4 ], [ 3, 4 ] ]
## ]]></Example>
## <Example><![CDATA[
## gap> c:=SCBdSimplex(4);;              
## gap> sl:=SCNSSlicing(c,[[1],[2..5]]);;
## gap> SCSkelEx(sl,3);                            
## [ ]
## gap> sl:=SCNSSlicing(c,[[1,2],[3..5]]);;
## gap> SCSkelEx(sl,3);                            
## [ [ 1, 2, 4, 5 ], [ 1, 3, 4, 6 ], [ 2, 3, 5, 6 ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCSkelExOp,
"for SCNormalSurface and Int",
[SCIsNormalSurface,IsInt],
function(sl, k)

 local element, faces, facets, i, ctr, edgecand;
 
 
 if(k<0 or k>3) then
   return [];
 fi;

 faces:=[];
  facets:=SCFacetsEx(sl);
  if facets = fail then
   return fail;
  fi;
 
 if k=0 then
  faces:=Union(List(facets,x->Combinations(x,1)));
 elif k=1 then
  edgecand:=Union(List(facets,x->Combinations(x,2)));
  faces:=[];
  for i in [1..Size(edgecand)] do
   ctr:=0;
   for element in  facets do
    if IsSubset(element,edgecand[i]) then
     ctr:=ctr+1;
    fi;
    if ctr=2 then
     Add(faces,edgecand[i]);
     break;
    fi;
   od;
  od;
 else
  faces:=Filtered(facets,x->Size(x)=k+1);
 fi; 

 return faces;


end);

################################################################################
##<#GAPDoc Label="SCNSSkel">
## <ManSection>
## <Meth Name="SCSkel" Arg="sl,k"/>
## <Returns>a face list (of <Arg>k+1</Arg>tuples) or a list of face lists upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes all faces of cardinality <Arg>k+1</Arg> in the original labeling: <Arg>k</Arg> <M>= 0</M> computes the vertices,  <Arg>k</Arg> <M>= 1</M> computes the edges,  <Arg>k</Arg> <M>= 2</M> computes the triangles,  <Arg>k</Arg> <M>= 3</M> computes the quadrilaterals.<P/>
## 
## If <Arg>k</Arg> is a list (necessarily a sublist of <C>[ 0,1,2,3 ]</C>) all faces of all cardinalities contained in <Arg>k</Arg> are computed.
## <Example><![CDATA[
## gap> c:=SCBdSimplex(4);;              
## gap> sl:=SCNSSlicing(c,[[1],[2..5]]);;
## gap> SCSkel(sl,1);                            
## [ [ [ 1, 2 ], [ 1, 3 ] ], [ [ 1, 2 ], [ 1, 4 ] ], [ [ 1, 2 ], [ 1, 5 ] ], 
##   [ [ 1, 3 ], [ 1, 4 ] ], [ [ 1, 3 ], [ 1, 5 ] ], [ [ 1, 4 ], [ 1, 5 ] ] ]
## ]]></Example>
## <Example><![CDATA[
## gap> c:=SCBdSimplex(4);;              
## gap> sl:=SCNSSlicing(c,[[1],[2..5]]);;
## gap> SCSkel(sl,3);                            
## [ ]
## gap> sl:=SCNSSlicing(c,[[1,2],[3..5]]);;
## gap> SCSkelEx(sl,3);                            
## [ [ [ 1, 3 ], [ 1, 4 ], [ 2, 3 ], [ 2, 4 ] ], 
##   [ [ 1, 3 ], [ 1, 5 ], [ 2, 3 ], [ 2, 5 ] ], 
##   [ [ 1, 4 ], [ 1, 5 ], [ 2, 4 ], [ 2, 5 ] ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCSkel,
"for SCNormalSurface and Int",
[SCIsNormalSurface,IsInt],
function(sl, k)
 
 local labels,skel;
 
 labels:=SCLabels(sl);
 if(labels=fail) then
  Info(InfoSimpcomp,1,"SCSkel: discrete normal surface lacks vertex labels.");
  return fail; 
 fi;
 
 if(IsList(k)) then
  skel:=List(SCSkelEx(sl,k),x->SCIntFunc.RelabelSimplexList(x,labels));
 else
  skel:=SCIntFunc.RelabelSimplexList(SCSkelEx(sl,k),labels);
 fi;
 
 return skel;
 
end);


################################################################################
##<#GAPDoc Label="SCNSFaceLatticeEx">
## <ManSection>
## <Meth Name="SCFaceLatticeEx" Arg="complex"/>
## <Returns>a list of face lists upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the face lattice of a discrete normal surface <Arg>sl</Arg> in the standard labeling. Triangles and quadrilaterals are stored separately (cf. <Ref Meth="SCSkelEx" />).
## <Example><![CDATA[
## gap> c:=SCBdSimplex(4);;              
## gap> sl:=SCNSSlicing(c,[[1,2],[3..5]]);;
## gap> SCFaceLatticeEx(sl);                            
## [ [ [ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ], [ 6 ] ], 
##   [ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 2, 3 ], [ 2, 5 ], 
##     [ 3, 6 ], [ 4, 5 ], [ 4, 6 ], [ 5, 6 ] ], 
##   [ [ 1, 2, 3 ], [ 4, 5, 6 ] ], 
##   [ [ 1, 2, 4, 5 ], [ 1, 3, 4, 6 ], [ 2, 3, 5, 6 ] ] ]
## gap> sl.F;
## [ 6, 9, 2, 3 ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCFaceLatticeEx,
"for SCNormalSurface and IsEmpty",
[SCIsNormalSurface and IsEmpty],
function(complex)
 return [];
end);

InstallMethod(SCFaceLatticeEx,
"for SCNormalSurface",
[SCIsNormalSurface],
function(complex)

 local faces,dim,i,f,chi,flag;

 faces:=[];
 for i in [0..3] do
   faces[i+1]:=SCSkelEx(complex,i);
  if(faces[i+1]=fail) then
   return fail;
  fi;
 od;

 return faces;

end);

################################################################################
##<#GAPDoc Label="SCNSFaceLattice">
## <ManSection>
## <Meth Name="SCFaceLattice" Arg="complex"/>
## <Returns>a list of facet lists upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the face lattice of a discrete normal surface <Arg>sl</Arg> in the original labeling. Triangles and quadrilaterals are stored separately (cf. <Ref Meth="SCSkel" />).
## <Example><![CDATA[
## gap> c:=SCBdSimplex(4);;              
## gap> sl:=SCNSSlicing(c,[[1,2],[3..5]]);;
## gap> SCFaceLattice(sl);                            
## [ [ [ [ 1, 3 ] ], [ [ 1, 4 ] ], [ [ 1, 5 ] ], [ [ 2, 3 ] ], [ [ 2, 4 ] ], 
##       [ [ 2, 5 ] ] ], 
##   [ [ [ 1, 3 ], [ 1, 4 ] ], [ [ 1, 3 ], [ 1, 5 ] ], [ [ 1, 3 ], [ 2, 3 ] ], 
##     [ [ 1, 4 ], [ 1, 5 ] ], [ [ 1, 4 ], [ 2, 4 ] ], [ [ 1, 5 ], [ 2, 5 ] ],
##     [ [ 2, 3 ], [ 2, 4 ] ], [ [ 2, 3 ], [ 2, 5 ] ], [ [ 2, 4 ], [ 2, 5 ] ] ], 
##   [ [ [ 1, 3 ], [ 1, 4 ], [ 1, 5 ] ], [ [ 2, 3 ], [ 2, 4 ], [ 2, 5 ] ] ], 
##   [ [ [ 1, 3 ], [ 1, 4 ], [ 2, 3 ], [ 2, 4 ] ], 
##     [ [ 1, 3 ], [ 1, 5 ], [ 2, 3 ], [ 2, 5 ] ], 
##     [ [ 1, 4 ], [ 1, 5 ], [ 2, 4 ], [ 2, 5 ] ] ] ]
## gap> sl.F;
## [ 6, 9, 2, 3 ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCFaceLattice,
"for SCNormalSurface and IsEmpty",
[SCIsNormalSurface and IsEmpty],
function(complex)
 return [];
end);

InstallMethod(SCFaceLattice,
"for SCNormalSurface",
[SCIsNormalSurface],
function(complex)

 local labels;
 labels:=SCLabels(complex);
 if labels = fail then
  return fail;
 fi;
 return List(SCFaceLatticeEx(complex),x->SCIntFunc.RelabelSimplexList(x,labels));

end);

################################################################################
##<#GAPDoc Label="SCNSTriangulation">
## <ManSection>
## <Meth Name="SCNSTriangulation" Arg="sl"/>
## <Returns>simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes a simplicial subdivision of a slicing <Arg>sl</Arg> without introducing new vertices. The subdivision is stored as a property of <Arg>sl</Arg> and thus is returned as an immutable object. Note that symmetry may be lost during the computation. 
## <Example><![CDATA[
## gap> SCLib.SearchByAttribute("F=[ 10, 35, 50, 25 ]");
## [ [ 19, "S^3 (VT)" ] ]
## gap> c:=SCLib.Load(last[1][1]);;
## gap> sl:=SCNSSlicing(c,[[1,3,5,7,9],[2,4,6,8,10]]);;
## gap> sl.F; 
## [ 9, 18, 0, 9 ]
## gap> sc:=SCNSTriangulation(sl);;
## gap> sc.F;
## [ 9, 27, 18 ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCNSTriangulation,
"for SCNormalSurface",
[SCIsNormalSurface],
  function(sl)

  local slfacets, scomplex, element, sc;

  slfacets:=SCFacetsEx(sl);
  if(slfacets=fail) then
   return fail;
  fi;

 # compute simplicial subdivision
 scomplex:=[];
 for element in slfacets do
  if Size(element)=3 then
   Add(scomplex,element);
  elif Size(element)=4 then
   Add(scomplex,element{[1..3]});
   Add(scomplex,element{[2..4]});
  fi;
  od;
  sc:=SCFromFacets(scomplex);
 if(sc=fail) then
   return fail;
  fi;
  
 return ShallowCopy(sc);

end);


################################################################################
##<#GAPDoc Label="SCNSHomology">
## <ManSection>
## <Meth Name="SCHomology" Arg="sl"/>
## <Returns>a list of homology groups upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the homology of a slicing <Arg>sl</Arg>. Internally, <Arg>sl</Arg> is triangulated (cf. <Ref Meth="SCNSTriangulation"/>) and simplicial homology is computed via <Ref Meth="SCHomology"/> using the triangulation.
## <Example><![CDATA[
## gap> SCLib.SearchByName("(S^2xS^1)#20");       
## [ [ 633, "(S^2xS^1)#20" ] ]
## gap> c:=SCLib.Load(last[1][1]);;
## gap> c.F;
## [ 27, 298, 542, 271 ]
## gap> sl:=SCNSSlicing(c,[[1..12],[13..27]]);;   
## gap> sl.Homology;
## [ [ 0, [  ] ], [ 14, [  ] ], [ 1, [  ] ] ]
## gap> sl:=SCNSSlicing(c,[[1..13],[14..27]]);;
## gap> sl.Homology;                       
## [ [ 1, [  ] ], [ 14, [  ] ], [ 2, [  ] ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCHomology,
"for SCNormalSurface",
[SCIsNormalSurface],
  function(sl)

  local scomplex, hom;

  scomplex:=SCNSTriangulation(sl);
  if scomplex=fail then
    return fail;
  fi;
  hom:=SCHomology(scomplex);
   return hom;

end); 
 
################################################################################
##<#GAPDoc Label="SCNSFpBettiNumbers">
## <ManSection>
## <Meth Name="SCFpBettiNumbers" Arg="sl,p"/>
## <Returns>a list of non-negative integers upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the Betti numbers modulo <Arg>p</Arg> of a slicing <Arg>sl</Arg>. Internally, <Arg>sl</Arg> is triangulated (using <Ref Meth="SCNSTriangulation"/>) and the Betti numbers are computed via <Ref Meth="SCFpBettiNumbers"/> using the triangulation.
## <Example><![CDATA[
## gap> SCLib.SearchByName("(S^2xS^1)#20");       
## [ [ 633, "(S^2xS^1)#20" ] ]
## gap> c:=SCLib.Load(last[1][1]);;
## gap> c.F;
## [ 27, 298, 542, 271 ]
## gap> sl:=SCNSSlicing(c,[[1..13],[14..27]]);;
## gap> SCFpBettiNumbers(sl,2);
## [ 2, 14, 2 ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCFpBettiNumbersOp,
"for SCNormalSurface and IsEmpty",
[SCIsNormalSurface and IsEmpty,IsInt],
function(complex,p)
 if not IsPrime(p) then
  Info(InfoSimpcomp,1,"SCFpBettiNumbersOp: second argument must be a prime.");
  return fail;
 fi;
 
 return [];
end);


InstallMethod(SCFpBettiNumbersOp,
"for SCNormalSurface and Prime",
[SCIsNormalSurface,IsInt],
function(sl,p)

  local scomplex, pbetti;

   
 if not IsPrime(p) then
  Info(InfoSimpcomp,1,"SCFpBettiNumbersOp: second argument must be a prime.");
  return fail;
 fi;

 scomplex:=SCNSTriangulation(sl);
  if scomplex=fail then
   return fail;
  fi;
  pbetti:=SCFpBettiNumbers(scomplex,p);
  if  pbetti=fail then
   return fail;
  fi;

   return pbetti;

end); 


################################################################################
##<#GAPDoc Label="SCNSTopologicalType">
## <ManSection>
## <Meth Name="SCTopologicalType" Arg="sl"/>
## <Returns>a string upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Determines the topological type of <Arg>sl</Arg> via the classification theorem for closed compact surfaces. If <Arg>sl</Arg> is not connected, the topological type of each connected component is computed.<P/>
## <Example><![CDATA[
## gap> SCLib.SearchByName("(S^2xS^1)#20");      
## [ [ 633, "(S^2xS^1)#20" ] ]
## gap> c:=SCLib.Load(last[1][1]);;
## gap> c.F;
## [ 27, 298, 542, 271 ]
## gap> for i in [1..26] do sl:=SCNSSlicing(c,[[1..i],[i+1..27]]); Print(sl.TopologicalType,"\n"); od;                                           
## S^2
## S^2
## S^2
## S^2
## S^2 U S^2
## S^2 U S^2
## S^2
## (T^2)#3
## (T^2)#5
## (T^2)#4
## (T^2)#3
## (T^2)#7
## (T^2)#7 U S^2
## (T^2)#7 U S^2
## (T^2)#7 U S^2
## (T^2)#8 U S^2
## (T^2)#7 U S^2
## (T^2)#8
## (T^2)#6
## (T^2)#6
## (T^2)#5
## (T^2)#3
## (T^2)#2
## T^2
## S^2
## S^2
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCTopologicalType,
"for SCNormalSurface",
[SCIsNormalSurface],
  function(sl) 
 
  local cc, c, scomplex, chi, f, g, dim, hom, name, element, ctr, ctype, conn;

  
  name:=SCName(sl);
  if name = fail then
   return fail;
  fi;

 #compute simplicial subdivision
  scomplex:=SCNSTriangulation(sl);
  if scomplex=fail then
   return fail;
  fi;
 
  hom:=SCHomology(scomplex);
 if hom=fail then
   return fail;
  fi;
  if hom[3]=[hom[1][1]+1,[]] then
   SetSCIsOrientable(sl,true);
  else
   SetSCIsOrientable(sl,false);
  fi;
  chi:=SCEulerCharacteristic(sl);
  conn:=SCIsConnected(sl);
  if conn then
   g:=SCGenus(sl);
   if g=fail then
    return fail;
   fi;
  fi;
  f:=SCFVector(sl);
  if chi=fail or f=fail then
   return fail;
  fi;
 
  ctype:="";
  cc:=SCConnectedComponents(sl);
  ctr:=0;
  for c in cc do
   ctr:=ctr+1;
   if name<>fail then
    SCRename(c,Concatenation([name,"_cc_#",String(ctr)]));
   else
    SCRename(c,Concatenation([name,"_cc_#",String(ctr)]));
   fi;
  
  # compute simplicial subdivision
   scomplex:=SCNSTriangulation(c);
   if scomplex=fail then
    return fail;
   fi;
  
   hom:=SCHomology(scomplex);
   if hom=fail then
    return fail;
   fi;
   SetSCIsConnected(c,true);
  
   if hom[3]=[hom[1][1]+1,[]] then
    SetSCIsOrientable(c,true);
   else
    SetSCIsOrientable(c,false);
   fi;
   chi:=SCEulerCharacteristic(c);
   g:=SCGenus(c);
   f:=SCFVector(c);
   if chi=fail or g=fail or f=fail then
    return fail;
   fi;
   if hom[1]=[0,[]] and hom[3]=[1,[]] then
    if g=0 then
     SetSCTopologicalType(c,"S^2");
    elif g=1 then
     SetSCTopologicalType(c,"T^2");
    elif g>1 then
     SetSCTopologicalType(c,Concatenation("(T^2)#",String(g)));
    fi;
   elif hom[1]=[0,[]] and hom[3]=[0,[]] then
    if g=1/2 then
     SetSCTopologicalType(c,"RP^2");
    elif g>1/2 then
     SetSCTopologicalType(c,Concatenation("(RP^2)#",String(2*g)));
    fi;
   fi;
  
   if ctr>1 then
    ctype:=Concatenation([ctype," U ",SCTopologicalType(c)]);
   else
    ctype:=Concatenation([ctype,SCTopologicalType(c)]);
   fi;
  od;

  return ctype;
 
end);

################################################################################
##<#GAPDoc Label="SCNSIsOrientable">
## <ManSection>
## <Meth Name="SCIsOrientable" Arg="sl"/>
## <Returns><K>true</K> or <K>false</K> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Checks if a discrete normal surface <Arg>sl</Arg> is orientable.
## <Example><![CDATA[
## gap> c:=SCBdSimplex(4);;
## gap> sl:=SCNSSlicing(c,[[1,2],[3,4,5]]);
## gap> SCIsOrientable(sl);
## true
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCIsOrientable,
"for SCNormalSurface and IsEmpty",
[SCIsNormalSurface and IsEmpty],
function(sl)
 return true;
end);

InstallMethod(SCIsOrientable,
"for SCNormalSurface",
[SCIsNormalSurface],
function(sl)

 local  hom;

 
 hom:=SCHomology(sl);
 if hom = fail then
  return fail;
 fi;
 
 if hom[1][1] + 1 = hom[3][1] then
   return true;
 else
   return false;
 fi;
end);


################################################################################
##<#GAPDoc Label="SCNSSlicing">
## <ManSection>
## <Func Name="SCNSSlicing" Arg="complex,slicing"/>
## <Returns>discrete normal surface of type <C>SCNormalSurface</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes a slicing defined by a partition <Arg>slicing</Arg> of the set of vertices of the <M>3</M>-dimensional combinatorial pseudomanifold  <Arg>complex</Arg>. In particular, <Arg>slicing</Arg> has to be a pair of lists of vertex labels and has to contain all vertex labels of <Arg>complex</Arg>.
## <Example><![CDATA[
## gap> SCLib.SearchByAttribute("F=[ 10, 35, 50, 25 ]");
## [ [ 19, "S^3 (VT)" ] ]
## gap> c:=SCLib.Load(last[1][1]);;                       
## gap> sl:=SCNSSlicing(c,[[1..5],[6..10]]);    
## [NormalSurface
## 
##  Properties known: Chi, ConnectedComponents, Dim, F, Facets, Genus, IsConnect\
## ed, Name, Oriented, Subdivision, TopologicalType, SCVertices, Vertices.
## 
##  Name="slicing [ [ 1, 2, 3 ], [ 4, 5, 6 ] ] of S^3 (VT)"
##  Dim=2
##  Chi=2
##  F=[ 9, 16, 4, 5 ]
##  IsConnected=true
##  TopologicalType="S^2"
## 
## /NormalSurface]
## gap> sl.Facets;
## [ [ [ 1, 4 ], [ 2, 4 ], [ 3, 4 ] ], 
##   [ [ 1, 6 ], [ 2, 6 ], [ 3, 6 ] ], 
##   [ [ 1, 4 ], [ 1, 5 ], [ 2, 4 ], [ 2, 5 ] ], 
##   [ [ 1, 5 ], [ 1, 6 ], [ 2, 5 ], [ 2, 6 ] ], 
##   [ [ 1, 4 ], [ 1, 6 ], [ 3, 4 ], [ 3, 6 ] ], 
##   [ [ 1, 4 ], [ 1, 5 ], [ 1, 6 ] ], 
##   [ [ 2, 4 ], [ 2, 5 ], [ 3, 4 ], [ 3, 5 ] ], 
##   [ [ 2, 5 ], [ 2, 6 ], [ 3, 5 ], [ 3, 6 ] ], 
##   [ [ 3, 4 ], [ 3, 5 ], [ 3, 6 ] ] ]
## gap> sl:=SCNSSlicing(c,[[1,3,5,7,9],[2,4,6,8,10]]);    
## [NormalSurface
## 
##  Properties known: Chi, ConnectedComponents, Dim, F, Facets, Genus, IsConnect\
## ed, Name, Oriented, Subdivision, TopologicalType, SCVertices, Vertices.
## 
##  Name="slicing [ [ 1, 3, 5 ], [ 2, 4, 6 ] ] of S^3 (VT)"
##  Dim=2
##  Chi=0
##  F=[ 9, 18, 0, 9 ]
##  IsConnected=true
##  TopologicalType="T^2"
## 
## /NormalSurface]
## gap> sl.Facets;                           
## [ [ [ 1, 2 ], [ 1, 4 ], [ 3, 2 ], [ 3, 4 ] ], 
##   [ [ 1, 2 ], [ 1, 6 ], [ 3, 2 ], [ 3, 6 ] ], 
##   [ [ 1, 2 ], [ 1, 4 ], [ 5, 2 ], [ 5, 4 ] ], 
##   [ [ 1, 2 ], [ 1, 6 ], [ 5, 2 ], [ 5, 6 ] ], 
##   [ [ 1, 4 ], [ 1, 6 ], [ 3, 4 ], [ 3, 6 ] ], 
##   [ [ 1, 4 ], [ 1, 6 ], [ 5, 4 ], [ 5, 6 ] ], 
##   [ [ 3, 2 ], [ 3, 4 ], [ 5, 2 ], [ 5, 4 ] ], 
##   [ [ 3, 2 ], [ 3, 6 ], [ 5, 2 ], [ 5, 6 ] ], 
##   [ [ 3, 4 ], [ 3, 6 ], [ 5, 4 ], [ 5, 6 ] ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCNSSlicing,
  function(complex,slicing)

  local sl, cc, c, vertices, facets, slfacets, scomplex, chi, f, g, dim, hom, name, tmp1, tmp2, i, element, str, ctr, type;

  if not SCIsSimplicialComplex(complex) then
   Info(InfoSimpcomp,1,"SCNSSlicing: first argument must be of type SCSimplicialComplex.");
   return fail;
  fi;
 
 dim:=SCDim(complex);
 if dim = fail or dim <> 3 then
  Info(InfoSimpcomp,1,"SCNSSlicing: first argument must be a simplicial complex of dimension 3.");
  return fail;
 fi;
 
  vertices:=SCVerticesEx(complex);
  facets:=SCFacetsEx(complex);
 if vertices = fail or facets = fail then
  return fail;
 fi;
  if(not IsList(slicing) or Size(slicing)<>2 or Union(slicing)<>vertices) then
   Info(InfoSimpcomp,1,"SCNSSlicing: slicing must be a partition of 'vertices'"); 
   return fail;
  fi;

  slfacets:=[];
  for i in [1..Size(facets)] do
  tmp1:=Intersection(facets[i], slicing[1]);
    tmp2:=Intersection(facets[i], slicing[2]);
  if tmp1<>[] and tmp2<>[] then
     Add(slfacets,Cartesian(tmp1,tmp2));
   fi;
  od;
 
 # create discrete normal surface from facets
  sl:=SCNS(slfacets);
  str:=String(slicing);
  name:=SCName(complex);
 
 type:=SCTopologicalType(sl);
  if  type=fail then
   return fail;
  fi;
  SetSCTopologicalType(sl,type);
 if name <> fail then
  SCRename(sl,Concatenation(["slicing ",str," of ",String(name)]));
 else
  SCRename(sl,Concatenation(["slicing ",str," of unnamed complex"]));
  fi;
 
  return sl;
 
end);


[ Verzeichnis aufwärts0.57unsichere Verbindung  Übersetzung europäischer Sprachen durch Browser  ]