1#############################################################################
2##
3##  ToricVarieties.gi         ToricVarieties package
4##
5##  Copyright 2011-2016, Sebastian Gutsche, TU Kaiserslautern
6##                        Martin Bies, ITP Heidelberg
7##
8##  The category of toric varieties
9##
10#############################################################################
11
12#################################
13##
14## Global Variables
15##
16#################################
17
18InstallValue( TORIC_VARIETIES,
19        rec(
20            category := rec(
21                            description := "toric varieties",
22                            short_description := "toric varieties",
23                            MorphismConstructor := ToricMorphism,
24                            ),
25            CoxRingIndet := "x",
26           )
27);
28
29#################################
30##
31## Representations
32##
33#################################
34
35DeclareRepresentation( "IsToricVarietyRep",
36                       IsToricVariety and IsAttributeStoringRep,
37                       [ ]
38                      );
39
40DeclareRepresentation( "IsSheafRep",
41                       IsToricVarietyRep and IsAttributeStoringRep,
42                       [ "Sheaf" ]
43                      );
44
45DeclareRepresentation( "IsCombinatorialRep",
46                       IsToricVarietyRep and IsAttributeStoringRep,
47                       [ ]
48                      );
49
50DeclareRepresentation( "IsFanRep",
51                       IsCombinatorialRep,
52                       [ ]
53                      );
54
55DeclareRepresentation( "IsLazyToricVarietyRep",
56                       IsToricVarietyRep and IsAttributeStoringRep,
57                       [ ]
58                      );
59
60DeclareRepresentation( "IsCategoryOfToricVarietiesRep",
61                       IsHomalgCategory,
62                       [ ]
63                      );
64
65##################################
66##
67## Family and Type
68##
69##################################
70
71BindGlobal( "TheFamilyOfToricVarietes",
72        NewFamily( "TheFamilyOfToricVarietes" , IsToricVariety ) );
73
74BindGlobal( "TheTypeFanToricVariety",
75        NewType( TheFamilyOfToricVarietes,
76                 IsFanRep ) );
77
78BindGlobal( "TheTypeCategoryOfToricVarieties",
79        NewType( TheFamilyOfHomalgCategories,
80                IsCategoryOfToricVarietiesRep ) );
81
82BindGlobal( "TheTypeLazyToricVariety",
83        NewType( TheFamilyOfToricVarietes,
84                 IsLazyToricVarietyRep ) );
85
86##################################
87##
88## Properties
89##
90##################################
91
92##
93InstallMethod( HomalgCategory,
94               "for varieties",
95               [ IsToricVariety ],
96
97  function( variety )
98
99    if not IsBound( variety!.category ) then
100
101        variety!.category := ShallowCopy( TORIC_VARIETIES.category );
102
103        variety!.category.containers := rec( );
104
105        Objectify( TheTypeCategoryOfToricVarieties,
106                   variety!.category
107                 );
108
109    fi;
110
111    return variety!.category;
112
113end );
114
115##
116InstallMethod( IsNormalVariety,
117               " for convex varieties",
118               [ IsFanRep ],
119
120  function( variety )
121
122    return true;
123
124end );
125
126##
127InstallMethod( IsAffine,
128               " for convex varieties",
129               [ IsFanRep ],
130
131  function( variety )
132    local fan_of_variety, weil_divisor;
133
134    fan_of_variety := FanOfVariety( variety );
135
136    if Length( MaximalCones( fan_of_variety ) ) = 1 then
137
138        for weil_divisor in WeilDivisorsOfVariety( variety ) do
139
140            if HasIsCartier( weil_divisor ) then
141
142                SetIsPrincipal( weil_divisor, IsCartier( weil_divisor ) );
143
144            fi;
145
146        od;
147
148        return true;
149
150    fi;
151
152    return false;
153
154end );
155
156# ##
157# InstallMethod( IsProjective,
158#                "for convex varieties",
159#                [ IsToricVariety ],
160#
161#   function( variety )
162#     local rays, maximal_cones, number_of_rays, number_of_cones, rank_of_charactergrid, maximal_cone_grid,
163#           rank_of_maximal_cone_grid, map_for_difference_of_elements, map_for_scalar_products, total_map,
164#           current_row, i, j, k, cartier_data_group, morphism_to_cartier_data_group,
165#           zero_ray, map_from_cartier_data_group_to_divisors, one_matrix, zero_matrix, difference_morphism;
166#
167#     rays := RayGenerators( FanOfVariety( variety ) );
168#
169#     maximal_cones := RaysInMaximalCones( FanOfVariety( variety ) );
170#
171#     number_of_rays := Length( rays );
172#
173#     number_of_cones := Length( maximal_cones );
174#
175#     rank_of_charactergrid := Rank( CharacterLattice( variety ) );
176#
177#     maximal_cone_grid := number_of_cones * CharacterLattice( variety );
178#
179#     rank_of_maximal_cone_grid := number_of_cones * rank_of_charactergrid;
180#
181#     map_for_difference_of_elements := [ ];
182#
183#     map_for_scalar_products := [ ];
184#
185#     for i in [ 2 .. number_of_cones ] do
186#
187#         for j in [ 1 .. i-1 ] do
188#
189#             current_row := List( [ 1 .. rank_of_maximal_cone_grid ], function( k )
190#                                                       if i*rank_of_charactergrid >= k and k > (i-1)*rank_of_charactergrid then
191#                                                           return 1;
192#                                                       elif j*rank_of_charactergrid >= k and k > (j-1)*rank_of_charactergrid then
193#                                                           return -1;
194#                                                       fi;
195#                                                       return 0;
196#                                                     end );
197#
198#             Add( map_for_difference_of_elements, current_row );
199#
200#             current_row := maximal_cones[ i ] + maximal_cones[ j ];
201#
202#             current_row := List( current_row, function( k ) if k = 2 then return 1; fi; return 0; end );
203#
204#             current_row := List( [ 1 .. number_of_rays ], k -> current_row[ k ] * rays[ k ] );
205#
206#             Add( map_for_scalar_products, Flat( current_row ) );
207#
208#         od;
209#
210#     od;
211#
212#     map_for_difference_of_elements := Involution( HomalgMatrix( map_for_difference_of_elements, HOMALG_MATRICES.ZZ ) );
213#
214#     map_for_scalar_products := HomalgMatrix( map_for_scalar_products, HOMALG_MATRICES.ZZ );
215#
216#     total_map := map_for_difference_of_elements * map_for_scalar_products;
217#
218#     total_map := HomalgMap( total_map, maximal_cone_grid, "free" );
219#
220#     cartier_data_group := KernelSubobject( total_map );
221#
222#     morphism_to_cartier_data_group := MorphismHavingSubobjectAsItsImage( cartier_data_group );
223#     ##FIXME: Save this group, dont compute it twice. Its expensive.
224#
225#     one_matrix := IdentityMat( rank_of_charactergrid );
226#
227#     zero_matrix := ListWithIdenticalEntries( rank_of_charactergrid, 0 );
228#
229#     for i in [ 1 .. number_of_cones - 1 ] do
230#
231#         for j in [ i + 1 .. number_of_cones ] do
232#
233#             difference_morphism := ListWithIdenticalEntries( rank_of_charactergrid, 0 );
234#
235#             for k in [ 1 .. rank_of_charactergrid ] do
236#
237#                 difference_morphism[ k ] := ListWithIdenticalEntries( i-1, zero_matrix );
238#
239#                 Add( difference_morphism[ k ], one_matrix[ k ] );
240#
241#                 difference_morphism[ k ] := Concatenation( difference_morphism[ k ], ListWithIdenticalEntries( j - i - 1, zero_matrix ) );
242#
243#                 Add( difference_morphism[ k ], -one_matrix[ k ] );
244#
245#                 difference_morphism[ k ] := Concatenation( difference_morphism[ k ], ListWithIdenticalEntries( number_of_cones - j, zero_matrix ) );
246#
247#                 difference_morphism[ k ] := Flat( difference_morphism[ k ] );
248#
249#             od;
250#
251#             difference_morphism := HomalgMatrix( difference_morphism, HOMALG_MATRICES.ZZ );
252#
253#             difference_morphism := Involution( difference_morphism );
254#
255#             difference_morphism := HomalgMap( difference_morphism, maximal_cone_grid, "free" );
256#
257#             difference_morphism := PreCompose( morphism_to_cartier_data_group, difference_morphism );
258#
259#             if IsZero( difference_morphism ) then
260#
261#                 return false;
262#
263#             fi;
264#
265#         od;
266#
267#     od;
268#
269#     return true;
270#
271# end );
272
273##
274InstallMethod( IsProjective,
275               "for convex varieties",
276               [ IsFanRep and IsComplete ],
277
278  function( variety )
279
280    if Dimension( variety ) > 2 then
281
282        return IsRegularFan( FanOfVariety( variety ) );
283
284    fi;
285
286    TryNextMethod();
287
288end );
289
290##
291InstallMethod( IsProjective,
292               "for convex varieties",
293               [ IsToricVariety and IsComplete ],
294
295  function( variety )
296
297    if Dimension( variety ) <= 2 then
298
299        return true;
300
301    fi;
302
303    TryNextMethod();
304
305end );
306
307##
308InstallMethod( IsProjective,
309               "for convex varieties",
310               [ IsToricVariety and HasIsComplete ],
311
312  function( variety )
313
314    if not IsComplete( variety ) then
315
316        return false;
317
318    fi;
319
320    TryNextMethod();
321
322end );
323
324##
325RedispatchOnCondition( IsProjective, true, [ IsToricVariety ], [ IsComplete ], 0 );
326
327##
328InstallMethod( IsSmooth,
329               " for convex varieties",
330               [ IsFanRep ],
331
332  function( variety )
333
334    return IsSmooth( FanOfVariety( variety ) );
335
336end );
337
338##
339InstallMethod( IsComplete,
340               " for convex varieties",
341               [ IsFanRep ],
342
343  function( variety )
344
345    return IsComplete( FanOfVariety( variety ) );
346
347end );
348
349##
350InstallMethod( HasTorusfactor,
351               " for convex varieties",
352               [ IsFanRep ],
353
354  function( variety )
355
356    return not IsFullDimensional( FanOfVariety( variety ) );
357
358end );
359
360##
361InstallMethod( HasNoTorusfactor,
362               " for convex varieties",
363               [ IsFanRep ],
364
365  function( variety )
366
367    return not HasTorusfactor( variety );
368
369end );
370
371##
372InstallMethod( IsOrbifold,
373               " for convex varieties",
374               [ IsFanRep ],
375
376  function( variety )
377
378    return IsSimplicial( FanOfVariety( variety ) );
379
380end );
381
382InstallMethod( IsSimplicial,
383               " for convex varieties",
384               [ IsFanRep ],
385
386  function( variety )
387
388    return IsOrbifold( variety );
389
390end );
391
392##################################
393##
394## Attributes
395##
396##################################
397
398##
399InstallMethod( Dimension,
400               " for convex varieties",
401               [ IsFanRep ],
402
403  function( variety )
404
405    return AmbientSpaceDimension( FanOfVariety( variety ) );
406
407end );
408
409##
410InstallMethod( DimensionOfTorusfactor,
411               "for convex varieties",
412               [ IsFanRep ],
413
414  function( variety )
415    local dimension_of_fan, ambient_dimension;
416
417    if not HasTorusfactor( variety ) then
418
419        return 0;
420    fi;
421
422    dimension_of_fan := Dimension( FanOfVariety( variety ) );
423
424    ambient_dimension := Dimension( variety );
425
426    return ambient_dimension - dimension_of_fan;
427
428end );
429
430##
431InstallMethod( AffineOpenCovering,
432               " for convex varieties",
433               [ IsFanRep ],
434
435  function( variety )
436    local cones, cover_varieties;
437
438    cones := MaximalCones( FanOfVariety( variety ) );
439
440    cover_varieties := List( cones, ToricVariety );
441
442    cover_varieties := List( cover_varieties, i -> ToricSubvariety( i, variety ) );
443
444    return cover_varieties;
445
446end );
447
448##
449InstallMethod( IsProductOf,
450               " for convex varieties",
451               [ IsToricVariety ],
452
453  function( variety )
454
455    return [ variety ];
456
457end );
458
459##
460InstallMethod( TorusInvariantDivisorGroup,
461               "for toric varieties",
462               [ IsFanRep ],
463
464  function( variety )
465    local rays;
466
467    if Length( IsProductOf( variety ) ) > 1 then
468
469        return DirectSum( List( IsProductOf( variety ), TorusInvariantDivisorGroup ) );
470
471    fi;
472
473    rays := Length( RayGenerators( FanOfVariety( variety ) ) );
474
475    return rays * HOMALG_MATRICES.ZZ;
476
477end );
478
479##
480InstallMethod( MapFromCharacterToPrincipalDivisor,
481               " for convex varieties",
482               [ IsFanRep ],
483
484  function( variety )
485    local dim_of_variety, rays, ray_matrix;
486
487    ## the following code makes the fragile assumption (which cannot be
488    ## guaranteed by the convex-geometry oracle) that the ordering
489    ## of the rays in the product fan correponds to the order of the
490    ## the factors in the product, i.e., for X x Y the assumption would be
491    ## the rays of X appear first then followed by the ones of Y.
492    #if Length( IsProductOf( variety ) ) > 1 then
493    #
494    #    return DiagonalMorphism( List( IsProductOf( variety ), MapFromCharacterToPrincipalDivisor ) );
495    #
496    #fi;
497
498    dim_of_variety := Dimension( variety );
499
500    rays := RayGenerators( FanOfVariety( variety ) );
501
502    ray_matrix := HomalgMatrix( Flat( rays ), Length( rays ), dim_of_variety, HOMALG_MATRICES.ZZ );
503
504    ray_matrix := Involution( ray_matrix );
505
506    return HomalgMap( ray_matrix, CharacterLattice( variety ), TorusInvariantDivisorGroup( variety ) );
507
508end );
509
510##
511InstallMethod( MapFromWeilDivisorsToClassGroup,
512               " for convex varieties",
513               [ IsFanRep ],
514  function( variety )
515
516    return ByASmallerPresentation( CokernelEpi( MapFromCharacterToPrincipalDivisor( variety ) ) );
517
518end );
519
520# ##
521# InstallMethod( ClassGroup,
522#                " for convex varieties",
523#                [ IsFanRep ],
524#
525#   function( variety )
526#
527#     if Length( IsProductOf( variety ) ) > 1 then
528#
529#         return Sum( List( IsProductOf( variety ), ClassGroup ) );
530#
531#     fi;
532#
533#     return Cokernel( MapFromCharacterToPrincipalDivisor( variety ) );
534#
535# end );
536
537##
538InstallMethod( CharacterLattice,
539               "for convex toric varieties.",
540               [ IsCombinatorialRep ],
541
542  function( variety )
543
544    return ContainingGrid( FanOfVariety( variety ) );
545
546end );
547
548##
549InstallMethod( CoxRing,
550               "for convex varieties.",
551               [ IsToricVariety ],
552
553  function( variety )
554
555    return CoxRing( variety, TORIC_VARIETIES.CoxRingIndet );
556
557end );
558
559# ##FIXME
560# InstallMethod( CoxRing,
561#                "for convex toric varieties.",
562#                [ IsToricVariety, IsString ],
563#
564#   function( variety, variable )
565#
566#     Error( "Cox ring not defined for varieties with torus factor\n" );
567#
568# end );
569
570##
571RedispatchOnCondition( CoxRing, true, [ IsToricVariety ], [ HasNoTorusfactor ], 0 );
572
573##
574RedispatchOnCondition( CoxRing, true, [ IsToricVariety, IsString ], [ HasNoTorusfactor ], 0 );
575
576##
577InstallMethod( CoxRing,
578               "for convex toric varieties.",
579               [ IsToricVariety and HasNoTorusfactor, IsList ],
580
581  function( variety, variable_names )
582    local var_list, raylist, indeterminates, ring, class_list;
583
584    # test for valid input
585    if not IsString( variable_names ) then
586        Error( "the variable names must be specified as a string" );
587    fi;
588
589    # identify the individual names and the ray generators
590    var_list := SplitString( variable_names, "," );
591    raylist := RayGenerators( FanOfVariety( variety ) );
592
593    # check for valid input and, if provided, form list of final variable names
594    if ( Length( var_list ) <> 1 and Length( var_list ) <> Length( raylist ) ) then
595        Error( "either one variable name, or a variable name for each ray generator must be specified" );
596    fi;
597
598    if Length( var_list ) = 1 then
599        indeterminates := List( [ 1 .. Length( raylist ) ], i -> JoinStringsWithSeparator( [ var_list[ 1 ], i ], "_" ) );
600        indeterminates := JoinStringsWithSeparator( indeterminates, "," );
601    else
602        indeterminates := var_list;
603    fi;
604
605    ring := GradedRing( DefaultGradedFieldForToricVarieties() * indeterminates );
606
607    SetDegreeGroup( ring, ClassGroup( variety ) );
608
609    indeterminates := Indeterminates( ring );
610
611    class_list := List( TorusInvariantPrimeDivisors( variety ), i -> ClassOfDivisor( i ) );
612
613    SetWeightsOfIndeterminates( ring, class_list );
614
615    SetCoxRing( variety, ring );
616
617    return ring;
618
619end );
620
621##
622InstallMethod( ListOfVariablesOfCoxRing,
623               "for toric varieties with cox rings",
624               [ IsToricVariety ],
625
626  function( variety )
627    local cox_ring, variable_list, string_list, i;
628
629    if not HasCoxRing( variety ) then
630
631        Error( "no cox ring has no variables\n" );
632
633    fi;
634
635    cox_ring := CoxRing( variety );
636
637    variable_list := Indeterminates( cox_ring );
638
639    string_list := [ ];
640
641    for i in variable_list do
642
643        Add( string_list, String( i ) );
644
645    od;
646
647    return string_list;
648
649end );
650
651##
652InstallMethod( IrrelevantIdeal,
653               "for toric varieties",
654               [ IsToricVariety and IsAffine ],
655
656  function( variety )
657    local cox_ring, irrelevant_ideal;
658
659    cox_ring := CoxRing( variety );
660
661    irrelevant_ideal := HomalgMatrix( [ 1 ], 1, 1, cox_ring );
662
663    return LeftSubmodule( irrelevant_ideal );
664
665end );
666
667##
668InstallMethod( IrrelevantIdeal,
669               " for toric varieties",
670               [ IsFanRep ],
671
672  function( variety )
673    local cox_ring, maximal_cones, indeterminates, irrelevant_ideal, i, j;
674
675    cox_ring := CoxRing( variety );
676
677    maximal_cones := RaysInMaximalCones( FanOfVariety( variety ) );
678
679    indeterminates := Indeterminates( cox_ring );
680
681    irrelevant_ideal := [ 1 .. Length( maximal_cones ) ];
682
683
684    for i in [ 1 .. Length( maximal_cones ) ] do
685
686        irrelevant_ideal[ i ] := 1;
687
688        for j in [ 1 .. Length( maximal_cones[ i ] ) ] do
689
690            irrelevant_ideal[ i ] := irrelevant_ideal[ i ] * indeterminates[ j ]^( 1 - maximal_cones[ i ][ j ] );
691
692        od;
693
694    od;
695
696    irrelevant_ideal := HomalgMatrix( irrelevant_ideal, Length( irrelevant_ideal ), 1, cox_ring );
697
698    return LeftSubmodule( irrelevant_ideal );
699
700end );
701
702# compute the Stanley-Reissner ideal (using GradedModules)
703InstallMethod( SRIdeal,
704               "for toric varieties",
705               [ IsToricVariety ],
706  function( variety )
707    local primitive_collections, SR_generators, I, k, buffer, SR_ideal;
708
709    # compute primitive collections of the fan
710    primitive_collections := PrimitiveCollections( FanOfVariety( variety ) );
711
712    # form monomial from the primivite collections
713    SR_generators := [];
714    for I in primitive_collections do
715        buffer := Indeterminates( CoxRing( variety ) )[ I[ 1 ] ];
716        for k in [ 2 .. Length( I ) ] do
717           buffer := buffer * Indeterminates( CoxRing( variety ) )[ I[ k ] ];
718        od;
719        Add( SR_generators, buffer );
720    od;
721
722    # construct and return the ideal
723    SR_ideal := GradedLeftSubmodule( SR_generators, CoxRing( variety ) );
724    OnBasisOfPresentation( SR_ideal );
725    return SR_ideal;
726
727end );
728
729##
730InstallMethod( MorphismFromCoxVariety,
731               "for toric varieties",
732               [ IsFanRep ],
733
734  function( variety )
735    local fan, rays, rays_for_cox_variety, cones_for_cox_variety, fan_for_cox_variety, cox_variety, i, j;
736
737    fan := FanOfVariety( variety );
738
739    rays := RayGenerators( fan );
740
741    rays_for_cox_variety := IdentityMat( Length( rays ) );
742
743    cones_for_cox_variety := RaysInMaximalCones( fan );
744
745    fan_for_cox_variety := List( cones_for_cox_variety, i -> [ ] );
746
747    for i in [ 1 .. Length( cones_for_cox_variety ) ] do
748
749        for j in [ 1 .. Length( rays ) ] do
750
751            if cones_for_cox_variety[ i ][ j ] = 1 then
752
753                Add( fan_for_cox_variety[ i ], rays_for_cox_variety[ j ] );
754
755            fi;
756
757        od;
758
759    od;
760
761    fan_for_cox_variety := Fan( fan_for_cox_variety );
762
763    cox_variety := ToricVariety( fan_for_cox_variety );
764
765    return ToricMorphism( cox_variety, rays, variety );
766
767end );
768
769##
770InstallMethod( CartierTorusInvariantDivisorGroup,
771               " for conv toric varieties",
772               [ IsCombinatorialRep and HasNoTorusfactor ],
773
774  function( variety )
775    local rays, maximal_cones, number_of_rays, number_of_cones, rank_of_charactergrid, maximal_cone_grid,
776          rank_of_maximal_cone_grid, map_for_difference_of_elements, map_for_scalar_products, total_map,
777          current_row, i, j, k, cartier_data_group, morphism_to_cartier_data_group,
778          zero_ray, map_from_cartier_data_group_to_divisors;
779
780    rays := RayGenerators( FanOfVariety( variety ) );
781
782    maximal_cones := RaysInMaximalCones( FanOfVariety( variety ) );
783
784    number_of_rays := Length( rays );
785
786    number_of_cones := Length( maximal_cones );
787
788    rank_of_charactergrid := Rank( CharacterLattice( variety ) );
789
790    maximal_cone_grid := number_of_cones * CharacterLattice( variety );
791
792    rank_of_maximal_cone_grid := number_of_cones * rank_of_charactergrid;
793
794    map_for_difference_of_elements := [ ];
795
796    map_for_scalar_products := [ ];
797
798    for i in [ 2 .. number_of_cones ] do
799
800        for j in [ 1 .. i-1 ] do
801
802            current_row := List( [ 1 .. rank_of_maximal_cone_grid ], function( k )
803                                                      if i*rank_of_charactergrid >= k and k > (i-1)*rank_of_charactergrid then
804                                                          return 1;
805                                                      elif j*rank_of_charactergrid >= k and k > (j-1)*rank_of_charactergrid then
806                                                          return -1;
807                                                      fi;
808                                                      return 0;
809                                                    end );
810
811            Add( map_for_difference_of_elements, current_row );
812
813            current_row := maximal_cones[ i ] + maximal_cones[ j ];
814
815            current_row := List( current_row, function( k ) if k = 2 then return 1; fi; return 0; end );
816
817            current_row := List( [ 1 .. number_of_rays ], k -> current_row[ k ] * rays[ k ] );
818
819            Add( map_for_scalar_products, Flat( current_row ) );
820
821        od;
822
823    od;
824
825    map_for_difference_of_elements := Involution( HomalgMatrix( map_for_difference_of_elements, HOMALG_MATRICES.ZZ ) );
826
827    map_for_scalar_products := HomalgMatrix( map_for_scalar_products, HOMALG_MATRICES.ZZ );
828
829    total_map := map_for_difference_of_elements * map_for_scalar_products;
830
831    total_map := HomalgMap( total_map, maximal_cone_grid, "free" );
832
833    cartier_data_group := KernelSubobject( total_map );
834
835    morphism_to_cartier_data_group := MorphismHavingSubobjectAsItsImage( cartier_data_group );
836
837    zero_ray := ListWithIdenticalEntries( rank_of_charactergrid, 0 );
838
839    map_from_cartier_data_group_to_divisors := [ ];
840
841    for i in [ 1 .. number_of_rays ] do
842
843        current_row := [ ];
844
845        j := 1;
846
847        while maximal_cones[ j ][ i ] = 0 and j <= number_of_cones do
848
849            Add( current_row, zero_ray );
850
851            j := j + 1;
852
853        od;
854
855        if j > number_of_cones then
856
857            Error( "there seems to be a ray which is in no max cone. Something went wrong\n" );
858
859        fi;
860
861        Add( current_row, rays[ i ] );
862
863        j := j + 1;
864
865        while j <= number_of_cones do
866
867            Add( current_row, zero_ray );
868
869            j := j + 1;
870
871        od;
872
873        current_row := Flat( current_row );
874
875        Add( map_from_cartier_data_group_to_divisors, current_row );
876
877    od;
878
879    map_from_cartier_data_group_to_divisors := HomalgMatrix( map_from_cartier_data_group_to_divisors, HOMALG_MATRICES.ZZ );
880
881    map_from_cartier_data_group_to_divisors := Involution( map_from_cartier_data_group_to_divisors );
882
883    map_from_cartier_data_group_to_divisors := HomalgMap( map_from_cartier_data_group_to_divisors, Range( morphism_to_cartier_data_group ), TorusInvariantDivisorGroup( variety ) );
884
885    return ImageSubobject( map_from_cartier_data_group_to_divisors );
886
887end );
888
889##
890RedispatchOnCondition( CartierTorusInvariantDivisorGroup, true, [ IsCombinatorialRep ], [ HasNoTorusfactor ], 0 );
891
892##
893InstallMethod( FanOfVariety,
894               "for products",
895               [ IsToricVariety ],
896
897  function( variety )
898    local factors, fans_of_factors;
899
900    factors := IsProductOf( variety );
901
902    if Length( factors ) > 1 then
903
904        fans_of_factors := List( factors, FanOfVariety );
905
906        return Product( fans_of_factors );
907
908    fi;
909
910    TryNextMethod();
911
912end );
913
914##
915InstallMethod( CotangentSheaf,
916               "for toric varieties",
917               [ IsToricVariety and IsSmooth and HasNoTorusfactor ],
918
919  ZariskiCotangentSheaf
920
921);
922
923##
924RedispatchOnCondition( CotangentSheaf, true, [ IsToricVariety ], [ IsSmooth and HasNoTorusfactor ], 0 );
925
926##
927InstallMethod( ZariskiCotangentSheaf,
928               "for toric varieties",
929               [ IsToricVariety and IsOrbifold and HasNoTorusfactor ],
930
931  ZariskiCotangentSheafViaEulerSequence
932
933);
934
935##
936InstallGlobalFunction( ZariskiCotangentSheafViaPoincareResidueMap,
937  function( variety )
938    local cox_ring, variables, factor_module_morphisms, ray_matrix, dim, source_module, i,
939          product_morphism;
940
941    cox_ring := CoxRing( variety );
942
943    dim := Dimension( variety );
944
945    ray_matrix := RayGenerators( FanOfVariety( variety ) );
946
947    variables := Indeterminates( cox_ring );
948
949    source_module := dim * cox_ring;
950
951    factor_module_morphisms := [ ];
952
953    factor_module_morphisms := List( [ 1 .. Length( ray_matrix ) ],
954        function( i )
955          local current_morphism;
956
957          current_morphism := Involution( HomalgMatrix( [ ray_matrix[ i ] ], cox_ring ) );
958
959          return GradedMap( current_morphism, source_module, 1 * cox_ring / GradedLeftSubmodule( [ variables[ i ] ], cox_ring ) );
960
961        end );
962
963    product_morphism := Iterated( factor_module_morphisms, ProductMorphism );
964
965    return Kernel( product_morphism );
966
967end );
968
969##
970InstallGlobalFunction( ZariskiCotangentSheafViaEulerSequence,
971  function( variety )
972    local cox_ring, variables, source_module, prime_divisors, cokernel_epi,
973          product_morphism, kernel_module;
974
975    cox_ring := CoxRing( variety );
976
977    prime_divisors := TorusInvariantPrimeDivisors( variety );
978
979    variables := Indeterminates( cox_ring );
980
981    source_module := List( [ 1 .. Length( prime_divisors ) ], i -> cox_ring^( -ClassOfDivisor( prime_divisors[ i ] ) ) );
982
983    source_module := Sum( source_module );
984
985    product_morphism := HomalgDiagonalMatrix( variables, cox_ring );
986
987    cokernel_epi := MapFromWeilDivisorsToClassGroup( variety );
988
989    cokernel_epi := GradedMap( UnderlyingNonGradedRing( cox_ring ) * cokernel_epi, cox_ring );
990
991    product_morphism := GradedMap( product_morphism, source_module, Source( cokernel_epi ) );
992
993    product_morphism := PreCompose( product_morphism, cokernel_epi );
994
995    kernel_module := Kernel( product_morphism );
996
997    SetRankOfObject( kernel_module, Dimension( variety ) );
998
999    return kernel_module;
1000
1001end );
1002
1003##
1004RedispatchOnCondition( ZariskiCotangentSheaf, true, [ IsToricVariety ], [ IsOrbifold and HasNoTorusfactor ], 0 );
1005
1006##
1007InstallMethod( ithBettiNumber,
1008               "for toric varieties",
1009               [ IsFanRep, IsInt ],
1010
1011  function( variety, i )
1012    local k, f_vector, dim, betti_number;
1013
1014    if i mod 2 <> 0 then
1015
1016        return 0;
1017
1018    fi;
1019
1020    k := i / 2;
1021
1022    f_vector := FVector( FanOfVariety( variety ) );
1023
1024    dim := Dimension( variety );
1025
1026    betti_number := Sum( [ k .. dim ], i -> ( -1 )^( i - k ) * Binomial( i, k ) * f_vector[ dim - i ] );
1027
1028    return betti_number;
1029
1030end );
1031
1032##
1033InstallMethod( EulerCharacteristic,
1034               "for smooth varieties",
1035               [ IsFanRep and IsSmooth ],
1036
1037  function( variety )
1038    local f_vector;
1039
1040    f_vector := FVector( FanOfVariety( variety ) );
1041
1042    return f_vector[ Dimension( variety ) ];
1043
1044end );
1045
1046##################################
1047##
1048## Methods
1049##
1050##################################
1051
1052##
1053InstallMethod( UnderlyingSheaf,
1054               " getter for the sheaf",
1055               [ IsToricVariety ],
1056
1057  function( variety )
1058
1059    if IsBound( variety!.Sheaf ) then
1060
1061        return variety!.Sheaf;
1062
1063    else
1064
1065        Error( "no sheaf\n" );
1066
1067    fi;
1068
1069end );
1070
1071##
1072InstallMethod( CoordinateRingOfTorus,
1073               " for affine convex varieties",
1074               [ IsToricVariety ],
1075
1076  function( variety )
1077    local n, variables;
1078
1079    # extract the dimension
1080    n := Dimension( variety );
1081
1082    # and produce a standard list of variables
1083    variables := List( [ 1 .. n ], k -> Concatenation( "x", String( k ) ) );
1084
1085    # then hand this input to the method below
1086    return CoordinateRingOfTorus( variety, variables );
1087
1088end );
1089
1090##
1091InstallMethod( CoordinateRingOfTorus,
1092               " for affine convex varieties",
1093               [ IsToricVariety, IsList ],
1094
1095  function( variety, variables )
1096    local n, ring, i, relations;
1097
1098    if HasCoordinateRingOfTorus( variety ) then
1099
1100        return CoordinateRingOfTorus( variety );
1101
1102    fi;
1103
1104#     if Length( IsProductOf( variety ) ) > 1 then
1105#
1106#         n := IsProductOf( variety );
1107#
1108#         if ForAll( n, HasCoordinateRingOfTorus ) then
1109#
1110#             ring := Product( List( n, CoordinateRingOfTorus ) );
1111#
1112#             SetCoordinateRingOfTorus( variety, ring );
1113#
1114#             return ring;
1115#
1116#         fi;
1117#
1118#     fi;
1119
1120    n := Dimension( variety );
1121
1122    if ( not Length( variables ) = 2 * n ) and ( not Length( variables ) = n ) then
1123
1124        Error( "incorrect number of indets\n" );
1125
1126    fi;
1127
1128    if Length( variables ) = n then
1129
1130        variables := List( variables, i -> [ i, JoinStringsWithSeparator( [i,"_"], "" ) ] );
1131
1132        variables := List( variables, i -> JoinStringsWithSeparator( i, "," ) );
1133
1134    fi;
1135
1136    variables := JoinStringsWithSeparator( variables );
1137
1138    ring := DefaultFieldForToricVarieties() * variables;
1139
1140    variables := Indeterminates( ring );
1141
1142    relations := [ 1..n ];
1143
1144    for i in [ 1 .. n ] do
1145
1146        relations[ i ] := variables[ 2*i - 1 ] * variables[ 2*i ] - 1;
1147
1148    od;
1149
1150    ring := ring / relations;
1151
1152    SetCoordinateRingOfTorus( variety, ring );
1153
1154    return ring;
1155
1156end );
1157
1158##
1159InstallMethod( CoordinateRingOfTorus,
1160               " for toric varieties and a string",
1161               [ IsToricVariety, IsString ],
1162
1163  function( variety, string )
1164    local variable;
1165
1166    variable := SplitString( string, "," );
1167
1168    if Length( variable ) = 1 then
1169
1170        TryNextMethod();
1171
1172    fi;
1173
1174    return CoordinateRingOfTorus( variety, variable );
1175
1176end );
1177
1178##
1179InstallMethod( CoordinateRingOfTorus,
1180               " for toric varieties and a string",
1181               [ IsToricVariety, IsString ],
1182
1183  function( variety, string )
1184    local variable_list;
1185
1186    variable_list := Dimension( variety );
1187
1188    variable_list := List( [ 1 .. variable_list ], i -> JoinStringsWithSeparator( [ string, i ], "" ) );
1189
1190    return CoordinateRingOfTorus( variety, variable_list );
1191
1192end );
1193
1194##
1195InstallMethod( ListOfVariablesOfCoordinateRingOfTorus,
1196               "for toric varieties with cox rings",
1197               [ IsToricVariety ],
1198
1199  function( variety )
1200    local coord_ring, variable_list, string_list, i;
1201
1202    coord_ring := CoordinateRingOfTorus( variety );
1203
1204    variable_list := Indeterminates( coord_ring );
1205
1206    string_list := [ ];
1207
1208    for i in variable_list do
1209
1210        Add( string_list, String( i ) );
1211
1212    od;
1213
1214    return string_list;
1215
1216end );
1217
1218##
1219InstallMethod( \*,
1220               "for toric varieties",
1221               [ IsFanRep, IsFanRep ],
1222
1223  function( variety1, variety2 )
1224    local product_variety;
1225
1226    product_variety := rec( WeilDivisors := WeakPointerObj( [ ] ) );
1227
1228    ObjectifyWithAttributes( product_variety, TheTypeFanToricVariety
1229                            );
1230
1231    SetIsProductOf( product_variety, Flat( [ IsProductOf( variety1 ), IsProductOf( variety2 ) ] ) );
1232
1233    return product_variety;
1234
1235end );
1236
1237##
1238InstallMethod( CharacterToRationalFunction,
1239               "for toric varieties",
1240               [ IsHomalgElement, IsToricVariety ],
1241
1242  function( character, variety )
1243
1244    return CharacterToRationalFunction( UnderlyingListOfRingElements( character ), variety );
1245
1246end );
1247
1248##
1249InstallMethod( CharacterToRationalFunction,
1250               " for toric varieties",
1251               [ IsList, IsToricVariety ],
1252
1253  function( character, variety )
1254    local ring, generators_of_ring, rational_function, i;
1255
1256    ring := CoordinateRingOfTorus( variety );
1257
1258    generators_of_ring := ListOfVariablesOfCoordinateRingOfTorus( variety );
1259
1260    rational_function := "1";
1261
1262    for i in [ 1 .. Length( generators_of_ring )/2 ] do
1263
1264        if character[ i ] < 0 then
1265
1266            rational_function := JoinStringsWithSeparator( [ rational_function ,
1267                                                             JoinStringsWithSeparator( [ generators_of_ring[ 2 * i ], String( - character[ i ] ) ], "^" ) ],
1268                                                              "*" );
1269
1270        else
1271
1272            rational_function := JoinStringsWithSeparator( [ rational_function ,
1273                                                            JoinStringsWithSeparator( [ generators_of_ring[ 2 * i -1 ], String( character[ i ] ) ], "^" ) ],
1274                                                            "*" );
1275
1276        fi;
1277
1278    od;
1279
1280    return HomalgRingElement( rational_function, ring );
1281
1282end );
1283
1284##
1285InstallMethod( TorusInvariantPrimeDivisors,
1286               " for toric varieties",
1287               [ IsToricVariety ],
1288
1289  function( variety )
1290    local divisors;
1291
1292    divisors := TorusInvariantDivisorGroup( variety );
1293
1294    divisors := GeneratingElements( divisors );
1295
1296    Apply( divisors, i -> CreateDivisor( i, variety ) );
1297
1298    List( divisors, function( j ) SetIsPrimedivisor( j, true ); return 0; end );
1299
1300    return divisors;
1301
1302end );
1303
1304##
1305InstallMethod( WeilDivisorsOfVariety,
1306               " for toric varieties",
1307               [ IsToricVariety ],
1308
1309  function( variety )
1310
1311    return variety!.WeilDivisors;
1312
1313end );
1314
1315##
1316InstallMethod( EQ,
1317               "for toric varieties",
1318               [ IsToricVariety, IsToricVariety ],
1319
1320  function( variety1, variety2 )
1321
1322    return IsIdenticalObj( variety1, variety2 );
1323
1324end );
1325
1326##
1327InstallMethod( Fan,
1328               " for toric varieties",
1329               [ IsToricVariety ],
1330
1331  function( variety )
1332
1333    return FanOfVariety( variety );
1334
1335end );
1336
1337##
1338InstallMethod( Factors,
1339               "for toric varieties",
1340               [ IsToricVariety ],
1341
1342  IsProductOf
1343
1344);
1345
1346##
1347InstallMethod( BlowUpOnIthMinimalTorusOrbit,
1348               "for toric varieties",
1349               [ IsToricVariety, IsInt ],
1350
1351  function( variety, i )
1352    local new_vari;
1353
1354    new_vari := ToricVariety( StarSubdivisionOfIthMaximalCone( FanOfVariety( variety ), i ) );
1355
1356    return new_vari;
1357
1358end );
1359
1360##
1361InstallMethod( NrOfqRationalPoints,
1362               "for smooth toric varieties",
1363               [ IsFanRep and IsSmooth, IsInt ],
1364
1365  function( variety, card_of_field )
1366    local f_vector, dim, nr_of_points;
1367
1368    dim := Dimension( variety );
1369
1370    f_vector := FVector( FanOfVariety( variety ) );
1371
1372    nr_of_points := ( card_of_field - 1 )^dim + Sum( [ 0 .. dim - 1 ], i -> ( card_of_field - 1 )^( i ) * f_vector( dim - i ) );
1373
1374    return nr_of_points;
1375
1376end);
1377
1378##################################
1379##
1380## Constructors
1381##
1382##################################
1383
1384##
1385InstallMethod( ToricVariety,
1386               " for homalg fans",
1387               [ IsFan ],
1388
1389  function( fan )
1390    local variety;
1391
1392    if not IsPointed( fan ) then
1393
1394        Error( "input fan must only contain strictly convex cones\n" );
1395
1396    fi;
1397
1398    variety := rec( WeilDivisors := WeakPointerObj( [ ] ) );
1399
1400    ObjectifyWithAttributes(
1401                             variety, TheTypeFanToricVariety,
1402                             FanOfVariety, fan
1403                            );
1404
1405    return variety;
1406
1407end );
1408
1409##
1410InstallMethod( ToricVariety,
1411               " for lists of rays, cones and weights for the variables in the Cox ring",
1412               [ IsList, IsList, IsList ],
1413  function( rays, cones, degrees )
1414    local vars;
1415
1416    # install standard list of variable names
1417    vars := JoinStringsWithSeparator(
1418                 List( [ 1 .. Length( rays ) ],
1419                        i -> JoinStringsWithSeparator( [ TORIC_VARIETIES.CoxRingIndet, i ], "_" ) ), "," );
1420
1421    # and return result from method below
1422    return ToricVariety( rays, cones, degrees, vars );
1423
1424end );
1425
1426##
1427InstallMethod( ToricVariety,
1428               " for lists of rays, cones, gradings and variable names",
1429               [ IsList, IsList, IsList, IsList ],
1430  function( rays, cones, gradings, indeterminates )
1431    local fan, var_names_buffer, var_names, variety, rays_in_fan, shuffled_gradings, shuffled_var_names, i, pos, matrix1, matrix2, map;
1432
1433    # construct the fan and test that it is pointed
1434    fan := Fan( rays, cones );
1435    if not IsPointed( fan ) then
1436
1437        Error( "input fan must only contain strictly convex cones\n" );
1438
1439    fi;
1440
1441    # check that gradings are of correct lengths
1442    if not Length( gradings ) = Length( rays ) then
1443
1444        Error( "For each ray generators a grading has to be provided" );
1445        return false;
1446
1447    fi;
1448
1449    # test if the var_names have been given as correct input
1450    if not IsString( indeterminates ) then
1451        Error( "the variables names have to be provided as string" );
1452    fi;
1453
1454    # next seperate them by ","
1455    var_names_buffer := SplitString( indeterminates, "," );
1456    if ( Length( var_names_buffer ) <> 1 and Length( var_names_buffer ) <> Length( rays ) ) then
1457        Error( "either one variable name, or a variable name for each ray generator must be specified" );
1458    fi;
1459    if Length( var_names_buffer ) = 1 then
1460        var_names := List( [ 1 .. Length( rays ) ],
1461                                i -> JoinStringsWithSeparator( [ var_names_buffer[ 1 ], i ], "_" ) );
1462    else
1463        var_names := var_names_buffer;
1464    fi;
1465
1466    variety := rec( WeilDivisors := WeakPointerObj( [ ] ) );
1467
1468    ObjectifyWithAttributes(
1469                             variety, TheTypeFanToricVariety,
1470                             FanOfVariety, fan
1471                            );
1472
1473    # The ray generators in fan = Fan( rays, cones ) are shuffled w.r.t. the provided inputlist rays.
1474    # Let us therefore determine the permutation matrix
1475    rays_in_fan := RayGenerators( FanOfVariety( variety ) );
1476    shuffled_gradings := [];
1477    shuffled_var_names := [];
1478    for i in [ 1 .. Length( rays_in_fan ) ] do
1479        pos := Position( rays, rays_in_fan[ i ] );
1480        shuffled_gradings[ i ] := gradings[ pos ];
1481        shuffled_var_names[ i ] := var_names[ pos ];
1482    od;
1483
1484    # if vari does not have a torus factor, then the gradings are set by the cokernel
1485    # of the matrix, in which the rays are the rows (Cox-Schenk-Little, theorem 4.1.3)
1486    # we proceed under this assumption thus
1487    if HasTorusfactor( variety ) then
1488        Error( Concatenation( "The method of setting the gradings by hand is currently supported ",
1489                              "only for toric variety without torus factor" ) );
1490        return false;
1491    fi;
1492
1493    # now check, that the provided gradings are valid
1494    matrix1 := HomalgMatrix( rays_in_fan, HOMALG_MATRICES.ZZ );
1495    matrix2 := HomalgMatrix( shuffled_gradings, HOMALG_MATRICES.ZZ );
1496    if not IsZero( Involution( matrix2 ) * matrix1 ) then
1497
1498      Error( "corrupted input - the given gradings must form (a) cokernel of the ray generators of the given fan" );
1499
1500    fi;
1501
1502    # now use this information to set the map from WeilDivisors to the class group
1503    map := HomalgMap( shuffled_gradings,
1504                      TorusInvariantDivisorGroup( variety ),
1505                      Length( shuffled_gradings[ 1 ] ) * HOMALG_MATRICES.ZZ
1506                     );
1507    SetMapFromWeilDivisorsToClassGroup( variety, map );
1508
1509    # finally install the Cox ring with the prescribed names
1510    # this here needs to join the shuffled_var_names by "," Banane
1511    CoxRing( variety, JoinStringsWithSeparator( shuffled_var_names, "," ) );
1512
1513    # and return the variety
1514    return variety;
1515
1516end );
1517
1518
1519InstallMethod( DeriveToricVarietiesFromGrading,
1520               "for a list of lists of integers and a boolean",
1521               [ IsList, IsBool ],
1522  function( grading, single_result_desired )
1523    local i, j, myZ, rays, fans, limit, varieties, shuffled_grading, variety, map;
1524
1525    # (step0) check for valid input
1526
1527    # input must be a list of lists
1528    if ForAny( grading, IsInt ) then
1529        Error( "The gradings must be given as list of lists (of integers) " );
1530        return;
1531    fi;
1532
1533    # are the gradings all of the same length
1534    if Length( DuplicateFreeList( List( [ 1 .. Length( grading ) ], i -> Length( grading[ i ] ) ) ) ) > 1 then
1535      Error( "The gradings must all be of the same length " );
1536      return;
1537    fi;
1538
1539    # are the entries of the gradings integers?
1540    for i in [ 1 .. Length( grading ) ] do
1541      for j in [ 1 .. Length( grading[ i ] ) ] do
1542        if not IsInt( grading[ i ][ j ] ) then
1543          Error( "All entries of the gradings must be integers " );
1544          return;
1545        fi;
1546      od;
1547    od;
1548
1549
1550    # (step1) compute the fans compatible with these gradings
1551    myZ := HomalgRingOfIntegers();
1552    rays := EntriesOfHomalgMatrixAsListList( SyzygiesOfColumns( HomalgMatrix( grading, myZ ) ) );
1553    fans := FansFromTriangulation( rays );
1554
1555    # (step3) process the fans further
1556    varieties := [];
1557
1558    # (step 3.1) adapt to required output
1559    if single_result_desired then
1560        limit := 1;
1561    else
1562        limit := Length( fans );
1563    fi;
1564
1565    # (step 3.2) process the number of required varieties
1566    for i in [ 1 .. limit ] do
1567
1568        # and check its properties
1569        if not IsPointed( fans[ i ] ) then
1570
1571            Error( "input fan must only contain strictly convex cones" );
1572
1573        elif not IsFullDimensional( fans[ i ] ) then
1574
1575            Error( "currently the construction from gradings is only supported for toric varieties without torus factor" );
1576
1577        fi;
1578
1579        # then construct the variety
1580        variety := rec( WeilDivisors := WeakPointerObj( [ ] ), DegreeXLayers := rec() );
1581        ObjectifyWithAttributes(
1582                                variety, TheTypeFanToricVariety,
1583                                FanOfVariety, fans[ i ]
1584                                );
1585
1586        # the ray generators got shuffled, so we need to shuffle the gradings accordingly
1587        shuffled_grading := [];
1588        for j in [ 1 .. Length( TransposedMat( grading ) ) ] do
1589            Add( shuffled_grading, TransposedMat( grading )[ Position( rays, RayGenerators( fans[ i ] )[ j ] ) ] );
1590        od;
1591
1592        # identify the map from the Weil divisors to the class group
1593        map := HomalgMap( shuffled_grading,
1594                          TorusInvariantDivisorGroup( variety ),
1595                          Length( shuffled_grading[ 1 ] ) * HOMALG_MATRICES.ZZ
1596                        );
1597
1598        # and set this map accordingly
1599        SetMapFromWeilDivisorsToClassGroup( variety, map );
1600
1601        # and save this variety
1602        varieties[ i ] := variety;
1603
1604    od;
1605
1606    # (step 3.3) adjust output to required output
1607    if single_result_desired then
1608      varieties := varieties[ 1 ];
1609    fi;
1610
1611    # (step4) return the result
1612    return varieties;
1613
1614end );
1615
1616InstallMethod( ToricVarietiesFromGrading,
1617               "for a list of lists of integers",
1618               [ IsList ],
1619  function( grading )
1620
1621        return DeriveToricVarietiesFromGrading( grading, false );
1622
1623end );
1624
1625InstallMethod( ToricVarietyFromGrading,
1626               "for a list of lists of integers",
1627               [ IsList ],
1628  function( grading )
1629
1630        return DeriveToricVarietiesFromGrading( grading, true );
1631
1632end );
1633
1634
1635##
1636InstallMethod( ToricVariety,
1637               "for lists of attributes",
1638               [ IsList ],
1639
1640  function( attributes )
1641    local variety, i;
1642
1643    variety := rec( WeilDivisors := WeakPointerObj( [ ] ) );
1644
1645    ObjectifyWithAttributes( variety, TheTypeLazyToricVariety );
1646
1647    for i in attributes do
1648
1649        if IsList( i ) and Length( i ) = 2 then
1650
1651            Setter( i[ 1 ] )( variety, i[ 2 ] );
1652
1653        else
1654
1655            Setter( i )( variety, true );
1656
1657        fi;
1658
1659    od;
1660
1661    return variety;
1662
1663end );
1664
1665#################################
1666##
1667## InfoMethod
1668##
1669#################################
1670
1671##
1672InstallMethod( NameOfVariety,
1673               "for products",
1674               [ IsToricVariety and HasIsProductOf ],
1675
1676  function( variety )
1677    local prod;
1678
1679    prod := IsProductOf( variety );
1680
1681    if Length( prod ) = 1 then
1682
1683        TryNextMethod();
1684
1685    fi;
1686
1687    prod := List( prod, NameOfVariety );
1688
1689    return JoinStringsWithSeparator( prod, "*" );
1690
1691end );
1692
1693##
1694InstallMethod( NameOfVariety,
1695               "for toric varieties",
1696               [ IsToricVariety ],
1697
1698  function( variety )
1699    local dimension, raygenerators_in_maxcones, raygenerators, i;
1700
1701    dimension := Dimension( variety );
1702
1703    raygenerators := RayGenerators( Fan( variety ) );
1704
1705    if Length( raygenerators ) = 0 then
1706
1707        return "|A^0";
1708
1709    fi;
1710
1711    if IsAffine( variety ) then
1712
1713        if Set( RayGenerators( ConeOfVariety( variety ) ) ) = Set( IdentityMat( dimension ) ) then
1714
1715            dimension := String( dimension );
1716
1717            return JoinStringsWithSeparator( [ "|A^", dimension ], "" );
1718
1719        fi;
1720
1721    fi;
1722
1723    if IsComplete( variety ) then
1724
1725        raygenerators_in_maxcones := List( MaximalCones( FanOfVariety( variety ) ), RayGenerators );
1726
1727        raygenerators_in_maxcones := Set( List( raygenerators_in_maxcones ), Set );
1728
1729        raygenerators := Set( IdentityMat( dimension ) );
1730
1731        Add( raygenerators, - Sum( raygenerators ) );
1732
1733        raygenerators := Combinations( raygenerators, dimension );
1734
1735        raygenerators := Set( List( raygenerators, Set ) );
1736
1737        if raygenerators = raygenerators_in_maxcones then
1738
1739            return JoinStringsWithSeparator( [ "|P^", String( dimension ) ], "" );
1740
1741        fi;
1742
1743        if dimension = 2 then
1744
1745            raygenerators := Set( [ Set( [ [ 1,0 ], [ 0, 1 ] ] ), Set( [ [ 1,0 ], [ 0,-1 ] ] ) ] );
1746
1747            raygenerators_in_maxcones := Difference( raygenerators_in_maxcones, raygenerators );
1748
1749            if Length( raygenerators_in_maxcones ) = 2 then
1750
1751                if ForAny( raygenerators_in_maxcones, i -> IsSubset( i , [ [ 0, -1 ] ] ) ) and
1752                   ForAny( raygenerators_in_maxcones, i -> IsSubset( i , [ [ 0, 1 ] ] ) ) then
1753
1754                    raygenerators_in_maxcones := Intersection( raygenerators_in_maxcones );
1755
1756                    if Length( raygenerators_in_maxcones ) = 1 then
1757
1758                        raygenerators_in_maxcones := raygenerators_in_maxcones[ 1 ];
1759
1760                        if raygenerators_in_maxcones[ 1 ] = -1 then
1761
1762                            return JoinStringsWithSeparator( [ "H_", String( raygenerators_in_maxcones[ 2 ] ) ], "" );
1763
1764                        fi;
1765
1766                    fi;
1767
1768                fi;
1769
1770            fi;
1771
1772        fi;
1773
1774    fi;
1775
1776    TryNextMethod();
1777
1778end );
1779
1780##
1781InstallOtherMethod( StructureDescription,
1782               "for toric varieties",
1783               [ IsToricVariety ],
1784
1785  NameOfVariety
1786
1787);
1788
1789#################################
1790##
1791## Display
1792##
1793#################################
1794
1795##
1796InstallMethod( ViewObj,
1797               " for toric varieties",
1798               [ IsToricVariety ],
1799
1800  function( var )
1801    local proj;
1802
1803    proj := false;
1804
1805    Print( "<A" );
1806
1807    if HasIsAffine( var ) then
1808
1809        if IsAffine( var ) then
1810
1811            Print( "n affine");
1812
1813        fi;
1814
1815    fi;
1816
1817    if HasIsProjective( var ) then
1818
1819        if IsProjective( var ) then
1820
1821            Print( " projective");
1822
1823            proj := true;
1824
1825        fi;
1826
1827    fi;
1828
1829    if HasIsNormalVariety( var ) then
1830
1831        if IsNormalVariety( var ) then
1832
1833            Print( " normal");
1834
1835        fi;
1836
1837    fi;
1838
1839    if HasIsSmooth( var ) then
1840
1841        if IsSmooth( var ) then
1842
1843            Print( " smooth");
1844
1845        else
1846
1847            Print( " non smooth" );
1848
1849        fi;
1850
1851    fi;
1852
1853    if HasIsComplete( var ) then
1854
1855        if IsComplete( var ) then
1856
1857            if not proj then
1858
1859                Print( " complete");
1860
1861            fi;
1862
1863        fi;
1864
1865    fi;
1866
1867    if IsToricSubvariety( var ) then
1868
1869        Print( " toric subvariety" );
1870
1871    else
1872
1873        Print( " toric variety" );
1874
1875    fi;
1876
1877    if HasDimension( var ) then
1878
1879        Print( " of dimension ", Dimension( var ) );
1880
1881    fi;
1882
1883    if HasHasTorusfactor( var ) then
1884
1885        if HasTorusfactor( var ) then
1886
1887            Print(" with a torus factor of dimension ", DimensionOfTorusfactor( var ) );
1888
1889        fi;
1890
1891
1892    fi;
1893
1894    if HasIsProductOf( var ) then
1895
1896        if Length( IsProductOf( var ) ) > 1 then
1897
1898            Print(" which is a product of ", Length( IsProductOf( var ) ), " toric varieties" );
1899
1900        fi;
1901
1902    fi;
1903
1904    Print( ">" );
1905
1906end );
1907
1908##
1909InstallMethod( Display,
1910               " for toric varieties",
1911               [ IsToricVariety ],
1912
1913  function( var )
1914    local proj;
1915
1916    proj := false;
1917
1918    Print( "A" );
1919
1920    if HasIsAffine( var ) then
1921
1922        if IsAffine( var ) then
1923
1924            Print( "n affine");
1925
1926        fi;
1927
1928    fi;
1929
1930    if HasIsProjective( var ) then
1931
1932        if IsProjective( var ) then
1933
1934            Print( " projective");
1935
1936            proj := true;
1937
1938        fi;
1939
1940    fi;
1941
1942    if HasIsNormalVariety( var ) then
1943
1944        if IsNormalVariety( var ) then
1945
1946            Print( " normal");
1947
1948        fi;
1949
1950    fi;
1951
1952    if HasIsSmooth( var ) then
1953
1954        if IsSmooth( var ) then
1955
1956            Print( " smooth");
1957
1958        else
1959
1960            Print( " non smooth" );
1961
1962        fi;
1963
1964    fi;
1965
1966    if HasIsComplete( var ) then
1967
1968        if IsComplete( var ) then
1969
1970            if not proj then
1971
1972                Print( " complete");
1973
1974            fi;
1975
1976        fi;
1977
1978    fi;
1979
1980    if IsToricVariety( var ) and not IsToricSubvariety( var ) then
1981
1982        Print( " toric variety" );
1983
1984    elif IsToricSubvariety( var ) then
1985
1986        Print( " toric subvariety" );
1987
1988    fi;
1989
1990    if HasDimension( var ) then
1991
1992        Print( " of dimension ", Dimension( var ) );
1993
1994    fi;
1995
1996    if HasHasTorusfactor( var ) then
1997
1998        if HasTorusfactor( var ) then
1999
2000            Print(" with a torus factor of dimension ", DimensionOfTorusfactor( var ) );
2001
2002        fi;
2003
2004
2005    fi;
2006
2007    if HasIsProductOf( var ) then
2008
2009        if Length( IsProductOf( var ) ) > 1 then
2010
2011            Print(" which is a product of ", Length( IsProductOf( var ) ), " toric varieties" );
2012
2013        fi;
2014
2015    fi;
2016
2017    Print( ".\n" );
2018
2019    if HasCoordinateRingOfTorus( var ) then
2020
2021        Print( " The torus of the variety is ", CoordinateRingOfTorus( var ),".\n" );
2022
2023    fi;
2024
2025    if HasClassGroup( var ) then
2026
2027        Print( " The class group is ", ClassGroup( var ) );
2028
2029        if HasCoxRing( var ) then
2030
2031            Print( " and the Cox ring is ", CoxRing( var ) );
2032
2033        fi;
2034
2035        Print( ".\n" );
2036
2037    fi;
2038
2039    if HasPicardGroup( var ) then
2040
2041        Print( "The Picard group is ", PicardGroup( var ) );
2042
2043    fi;
2044
2045end );
2046