1#############################################################################
2##
3#W  polynomials-extra-s.gi  Manuel Delgado <mdelgado@fc.up.pt>
4#W                          Pedro A. Garcia-Sanchez <pedro@ugr.es>
5##
6##
7#Y  Copyright 2016 by Manuel Delgado and Pedro Garcia-Sanchez
8#Y  We adopt the copyright regulations of GAP as detailed in the
9#Y  copyright notice in the GAP manual.
10##
11#############################################################################
12
13#################################################################
14##
15# F SemigroupOfValuesOfPlaneCurve(f)
16##  Computes the semigroup of values {mult(f,g) | g curve} of a plane curve
17##   with one place at the infinity in the variables X(Rationals,1) and X(Rationals,2)
18##  This function needs NumSgpsCanUseSingular to be enabled, either by loading the
19##  package singular prior to numericalsgps, or by using NumSgpsUseSingular.
20##  The function makes use of `semigroup` in the `alexpoly` singular library
21##
22#################################################################
23InstallGlobalFunction(SemigroupOfValuesOfPlaneCurve,
24  function(f)
25  local l,x,y,R,T, gens, wgens, w1, w2, c, inf, GBASIStmp, Rtmp;
26
27  inf:=function(u,v)
28      return [Minimum(u[1],v[1]),Minimum(u[2],v[2])];
29  end;
30
31  if not(IsPolynomial(f)) then
32    Error("The argument must be a polynomial\n");
33  fi;
34
35  R:=PolynomialRing(Rationals,[X(Rationals,1),X(Rationals,2)]);
36  if not(f in R) then
37          Error("The argument must be a polynomial in ", R,"\n");
38  fi;
39
40  T:=SingularBaseRing;
41  SingularLibrary("alexpoly.lib");
42  Rtmp:=SingularBaseRing;
43  GBASIStmp:=GBASIS;
44  GBASIS:=SINGULARGBASIS;
45  SingularSetBaseRing( R );
46  x:=R.1;;
47  y:=R.2;;
48  l:=SingularInterface("semigroup",[f],"list");
49  SingularSetBaseRing( T );
50  gens:=l[1];
51  wgens:=l[2];
52  c:=l[3];
53  if IsInt(gens[1]) then #numerical semigroup
54    SingularSetBaseRing(Rtmp);
55    GBASIS:=GBASIStmp;
56    return NumericalSemigroup(gens);
57  fi;
58
59  if Length(gens[1])=2 then # good sem dim two
60    if not(ForAll(Union(gens,wgens), x->x[1]<=c[1] and x[2]<=c[2])) then
61      #c:=Reversed(c);
62      #wgens:=Reversed(wgens);
63      Info(InfoNumSgps,2,"Warning: w-generators or generators not smaller than the conductor");
64      gens:=List(gens, x->inf(x,c));
65      wgens:=List(wgens,x->inf(x,c));
66    fi;
67    w1:=wgens[1];
68    gens:=Union(gens,List([w1[1]..c[1]], i->[i,w1[2]]));
69    w2:=wgens[2];
70    gens:=Union(gens,List([w2[2]..c[2]], i->[w2[1],i]));
71    Info(InfoNumSgps,2,"Generators ", gens);
72    Info(InfoNumSgps,2,"Conductor ", c);
73    SingularSetBaseRing(Rtmp);
74    GBASIS:=GBASIStmp;
75    return GoodSemigroup(gens,c);
76  fi;
77  SingularSetBaseRing(Rtmp);
78  GBASIS:=GBASIStmp;
79  return l;
80end);
81