1#############################################################################
2##
3##  SimplicialSet.gi             SCO package                  Simon Goertzen
4##
5##  Copyright 2007-2008 Lehrstuhl B für Mathematik, RWTH Aachen
6##
7##  The Simplicial Set data type and constructor.
8##
9#############################################################################
10
11##
12DeclareRepresentation( "IsSimplicialSetRep",
13        IsSimplicialSet, [ "simplicial_set", "orbifold_triangulation", "regular", "singular", "connectivity", "dimension"  ] );
14
15##
16BindGlobal( "SimplicialSetFamily",
17        NewFamily( "SimplicialSetFamily" ) );
18
19##
20BindGlobal( "SimplicialSetType",
21        NewType( SimplicialSetFamily, IsSimplicialSetRep ) );
22
23##  <#GAPDoc Label="SimplicialSet">
24##  <ManSection>
25##  <Meth Arg="ot" Name="SimplicialSet" Label="constructor"/>
26##  <Returns>SimplicialSet</Returns>
27##  <Description>
28##  The constructor for simplicial sets based on an orbifold triangulation <A>ot</A>.
29##  This just sets up the object without any computations.
30##  These can be triggered later, either explicitly or by <Ref Meth="SimplicialSet" Label="data access"/>.
31##  <Example><![CDATA[
32##  gap> Teardrop;
33##  <OrbifoldTriangulation "Teardrop" of dimension 2. 4 simplices on 4 vertices wi\
34##  th Isotropy on 1 vertex and nontrivial mu-maps>
35##  gap> S := SimplicialSet( Teardrop );
36##  <The simplicial set of the orbifold triangulation "Teardrop", computed up to d\
37##  imension 0 with Length vector [ 4 ]>
38##  ]]></Example>
39##  </Description>
40##  </ManSection>
41##  <#/GAPDoc>
42##
43InstallMethod( SimplicialSet, "constructor",
44        [ IsOrbifoldTriangulation ],
45  function( ot )
46    local ss, a;
47    ss := rec( );
48    ss.orbifold_triangulation := ot;
49    ss.dimension := 0;
50    ss.0 := Set( ot!.max_simplices, x->[x] );
51    ss.simplicial_set := [];
52    ss.simplicial_set[1] := ss!.0;
53    ss.regular := [];
54    ss.singular := [];
55    ss.connectivity := [];
56    ss.last_faces := [];
57    for a in ot!.vertices do
58        ss.connectivity[a] := Filtered( ot!.max_simplices, x -> a in x );
59        ss.last_faces[a] := List( ss.connectivity[a], x -> [ x ] );
60        if not IsBound( ot!.isotropy.( a ) ) or Order( ot!.isotropy.( a ) ) = 1 then
61            Add( ss.regular, a );
62        else
63            Add( ss.singular, a );
64        fi;
65    od;
66    return Objectify( SimplicialSetType, ss );
67  end
68);
69
70##  <#GAPDoc Label="SimplicialSet2">
71##  <ManSection>
72##  <Meth Arg="S, i" Name="SimplicialSet" Label="data access"/>
73##  <Returns>List <A>S</A>_<A>i</A></Returns>
74##  <Description>
75##  This returns the components of dimension <A>i</A> of the simplicial set <A>S</A>.
76##  Should be used to access existing data instead of using <C>S!.simplicial_set[ i + 1 ]</C>,
77##  as it has the additional side effect of computing <A>S</A> up to dimension <A>i</A>, thus
78##  always returning the desired result.
79##  <Example><![CDATA[
80##  gap> S := SimplicialSet( Teardrop );
81##  <The simplicial set of the orbifold triangulation "Teardrop", computed up to d\
82##  imension 0 with Length vector [ 4 ]>
83##  gap> S!.simplicial_set[1];
84##  [ [ [ 1, 2, 3 ] ], [ [ 1, 2, 4 ] ], [ [ 1, 3, 4 ] ], [ [ 2, 3, 4 ] ] ]
85##  gap> S!.simplicial_set[2];;
86##  Error, List Element: <list>[2] must have an assigned value
87##  gap> SimplicialSet( S, 0 );
88##  [ [ [ 1, 2, 3 ] ], [ [ 1, 2, 4 ] ], [ [ 1, 3, 4 ] ], [ [ 2, 3, 4 ] ] ]
89##  gap> SimplicialSet( S, 1 );;
90##  gap> S;
91##  <The simplicial set of the orbifold triangulation "Teardrop", computed up to d\
92##  imension 1 with Length vector [ 4, 12 ]>
93##  ]]></Example>
94##  </Description>
95##  </ManSection>
96##  <#/GAPDoc>
97##
98InstallMethod( SimplicialSet, "creation and accessment of the simplicial set up to the neccessary index",
99        [ IsSimplicialSet, IsInt ],
100  function( ss, n );
101    if ss!.dimension < n then
102        Extend( ss, n );
103    fi;
104    return ss!.simplicial_set[ n + 1 ];
105  end
106);
107
108##  <#GAPDoc Label="ComputeNextDimension">
109##  <ManSection>
110##  <Meth Arg="S" Name="ComputeNextDimension"/>
111##  <Returns><A>S</A></Returns>
112##  <Description>
113##  This computes the component of the next dimension of
114##  the simplicial set <A>S</A>. <A>S</A> is extended
115##  as a side effect.
116##  <Example><![CDATA[
117##  gap> S;
118##  <The simplicial set of the orbifold triangulation "Teardrop", computed up to d\
119##  imension 1 with Length vector [ 4, 12 ]>
120##  gap> ComputeNextDimension( S );
121##  <The simplicial set of the orbifold triangulation "Teardrop", computed up to d\
122##  imension 2 with Length vector [ 4, 12, 22 ]>
123##  ]]></Example>
124##  </Description>
125##  </ManSection>
126##  <#/GAPDoc>
127##
128InstallMethod( ComputeNextDimension,
129        [ IsSimplicialSet ],
130  function( ss )
131    local dim, last, conn, P, u, a, x, y, z, g;
132    last := ss!.last_faces;
133    conn := ss!.connectivity;
134    P := [];
135    u := [];
136    for a in ss!.regular do
137        P[a] := Concatenation( List( last[a], x->List( Filtered( conn[a], y->y>x[1] ), z->Concatenation( [ z, () ], x ) ) ) );
138        last[a] := P[a];
139        u := Union( u, P[a] );
140    od;
141    for a in ss!.singular do
142        P[a] := [];
143        for x in last[a] do
144            for g in Elements( ss!.orbifold_triangulation!.isotropy.( a ) ) do
145                for y in conn[a] do
146                    if y > x[1] or ( x[1] = y and Order( g ) <> 1 ) then #this is the key to reducing simplicial set length
147                        Append( P[a], [ Concatenation( [ y, g ], x ) ]);
148                    fi;
149                od;
150            od;
151        od;
152        last[a] := P[a];
153        u := Union( u, P[a] );
154    od;
155    ss!.dimension := ss!.dimension + 1;
156    dim := ss!.dimension;
157    ss!.(String( dim )) := Set( u );
158    ss!.simplicial_set[ dim + 1 ] := ss!.(String( dim ));
159    return ss;
160  end
161);
162
163##  <#GAPDoc Label="Extend">
164##  <ManSection>
165##  <Meth Arg="S, i" Name="Extend"/>
166##  <Returns><A>S</A></Returns>
167##  <Description>
168##  This computes the components of the simplicial set <A>S</A>
169##  up to dimension <A>i</A>. <A>S</A> is extended as a side effect.
170##  This method is equivalent to calling <Ref Meth="ComputeNextDimension"/>
171##  the appropriate number of times.
172##  <Example><![CDATA[
173##  gap> S;
174##  <The simplicial set of the orbifold triangulation "Teardrop", computed up to d\
175##  imension 2 with Length vector [ 4, 12, 22 ]>
176##  gap> Extend( S, 5 );
177##  <The simplicial set of the orbifold triangulation "Teardrop", computed up to d\
178##  imension 5 with Length vector [ 4, 12, 22, 33, 51, 73 ]>
179##  ]]></Example>
180##  </Description>
181##  </ManSection>
182##  <#/GAPDoc>
183##
184InstallMethod( Extend,
185        [ IsSimplicialSet, IsInt ],
186  function( ss, n )
187    while ss!.dimension < n do
188        ComputeNextDimension( ss );
189    od;
190    return ss;
191  end
192);
193
194##
195InstallMethod( ViewObj,
196        [ IsSimplicialSet ],
197  function( ss )
198    local info, str;
199    info := ss!.orbifold_triangulation!.info;
200    if info <> "" then
201        str := Concatenation( "The simplicial set of the orbifold triangulation \"", info, "\"," );
202    else
203        str := "A simplicial set";
204    fi;
205    str := Concatenation( "<", str, " computed up to dimension ", String( ss!.dimension ), " with Length vector ", String( List( ss!.simplicial_set, Length ) ), ">" );
206    Print( str );
207  end
208);
209
210##
211InstallMethod( PrintObj,
212        [ IsSimplicialSet ],
213  function( ss )
214    Print( "Extend( SimplicialSet( ", ss!.orbifold_triangulation, " ), ", ss!.dimension, " )\n" );
215  end
216);
217
218##
219InstallMethod( Display,
220        [ IsSimplicialSet ],
221  function( ss )
222    local s;
223    Display( List( ss!.simplicial_set, function( s ) if Length( s ) < 1000 then return s; else return [ "..." ]; fi; end ) );
224  end
225);
226