|
#############################################################################
##
#W irreducibles.gi Manuel Delgado <mdelgado@fc.up.pt>
#W Pedro A. Garcia-Sanchez <pedro@ugr.es>
#W Jose Morais <josejoao@fc.up.pt>
##
#Y Copyright 2005 by Manuel Delgado,
#Y Pedro Garcia-Sanchez and Jose Joao Morais
#Y We adopt the copyright regulations of GAP as detailed in the
#Y copyright notice in the GAP manual.
##
#############################################################################
#############################################################################
##
#F RemoveMinimalGeneratorFromNumericalSemigroup(n,s)
##
## Computes the numerical semigroup obtained from s after removing from s
## its minimal generator n: s\{n}.
##
#############################################################################
InstallGlobalFunction(RemoveMinimalGeneratorFromNumericalSemigroup, function(n,s)
local msg, multiplicity, ap, position;
if(not(IsInt(n))) then
Error("The first argument must be an integer.\n");
fi;
if(not(IsNumericalSemigroup(s))) then
Error("The second argument must be a numerical semigroup.\n");
fi;
msg:=MinimalGeneratingSystemOfNumericalSemigroup(s);
multiplicity:=MultiplicityOfNumericalSemigroup(s);
if (not(n in msg)) then
Error(n," must be a minimal generator of ",s,".\n");
fi;
if (n<>multiplicity) then
ap:=AperyListOfNumericalSemigroupWRTElement(s,multiplicity);
ap[1]:=multiplicity;
position:=Position(ap,n);
ap[position]:=n+multiplicity;
return NumericalSemigroup(ap);
else
if(msg=[1]) then
return(NumericalSemigroup([2,3]));
fi;
ap:=AperyListOfNumericalSemigroupWRTElement(s,msg[2]);
ap[1]:=msg[2];
position:=Position(ap,n);
ap[position]:=n+msg[2];
return NumericalSemigroup(ap);
fi;
end);
#############################################################################
##
#F AddSpecialGapOfNumericalSemigroup(g,s)
##
## Adds the special gap g to the numerical semigroup s and
## returns the resulting numerical semigroup: s\cup {g}.
##
#############################################################################
InstallGlobalFunction(AddSpecialGapOfNumericalSemigroup, function(g,s)
local eh, primedivisorsg, candidates, fh, divisorsfh;
if(not(IsInt(g))) then
Error("The first argument must be an integer.\n");
fi;
if(not(IsNumericalSemigroup(s))) then
Error("The second argument must be a numerical semigroup.\n");
fi;
eh:=SpecialGapsOfNumericalSemigroup(s);
if(not(g in eh)) then
Error(g," must be a special gap of ",s,".\n");
fi;
if(g=1) then
return NumericalSemigroup(1);
fi;
primedivisorsg:=Set(FactorsInt(g));
candidates:=List(primedivisorsg,x->g/x);
fh:=ShallowCopy(FundamentalGapsOfNumericalSemigroup(s));
RemoveSet(fh,g);
divisorsfh:=Union(List(fh,x->Set(DivisorsInt(x))));
##0.97 divisorsfh:=Union(List(fh,x->Set(FactorsInt(x))));
candidates:=Filtered(candidates,x->not(x in divisorsfh));
fh:=Union(fh,candidates);
return NumericalSemigroupByFundamentalGaps(fh);
end);
#############################################################################
##
#F AnIrreducibleNumericalSemigroupWithFrobeniusNumber(f)
##
## Produces an irreducible numerical semigroup by using
## "Every positive integer is the Frobenius number of an irreducible...".
##
#############################################################################
InstallGlobalFunction(AnIrreducibleNumericalSemigroupWithFrobeniusNumber, function(f)
local alpha,q;
if(not(IsInt(f))) then
Error("The argument must be an integer.\n");
fi;
if(f=0 or f<-1) then
# Print(f," is not a suitable integer.\n");
return fail;
fi;
if(f mod 2<>0) then
return NumericalSemigroup([2,f+2]);
fi;
if(f mod 3<>0) then
return NumericalSemigroup([3,f/2+3,f+3]);
fi;
if(f mod 4<>0) then
return NumericalSemigroup([4,f/2+2,f/2+4]);
fi;
#if we reach this point, then 2|f, 3|f and 4|f
alpha:=First([1..((f-(f mod 9))/9+1)],n->(f mod 3^(n+1)<>0));
q:=f/3^alpha;
return NumericalSemigroup([3^(alpha+1),q/2+3,3^alpha*q/4+q/2+3,3^alpha*q/2+q/2+3]);
end);
#############################################################################
##
#F IrreducibleNumericalSemigroupsWithFrobeniusNumber(f)
##
## Computes the set of irreducible numerical semigroups with given
## Frobenius number f, following Theorem 2.9 in [BR13]
## -V. Blanco, J.C. Rosales, The tree of irreducible numerical semigroups with fixed
## Frobenius number, Forum Math.
#############################################################################
InstallGlobalFunction(IrreducibleNumericalSemigroupsWithFrobeniusNumber, function(f)
local cf, irr, B, s, lsons, sons;
if(not(IsInt(f))) then
Error("The argument must be an integer.\n");
fi;
if f<-1 or f =0 then
return [];#Error(f," is not a valid Frobenius number.\n");
fi;
if f=-1 then
return [NumericalSemigroup(1)];
fi;
sons:=function(s) #implements Th. 2.9, the sons of an
# irreducible numerical semigroup
local small,candidates, f, minimal, m;
small:=SmallElementsOfNumericalSemigroup(s);
f:=FrobeniusNumber(s);
m:=MultiplicityOfNumericalSemigroup(s);
minimal:=function(x) #checks if x is a minimal generator
# smaller than or equal to f+1
return Filtered(small, y-> (y<x) and (x-y) in small)=[0];
end;
#canditadates are the elements fulfilling (i)-(v) in Th. 2.9
candidates:=Filtered(small, x-> (x>f/2) and (x<f) and
not(2*x-f in small) and not(3*x=2*f) and not(4*x=3*f)
and (f-x<m) and (minimal(x)));
return List(candidates, x->
NumericalSemigroupBySmallElements(Set(Concatenation(Difference(small,[x]),[f-x]))));
end;
#cf is the root of the tree of irreducible numerical semigroups with Frobenius number f
# as stated in Th. 2.9
if IsEvenInt(f) then
cf:=NumericalSemigroupBySmallElements(Concatenation([0],[((f/2+1))..(f-1)],[f+1]));
else
cf:=NumericalSemigroupBySmallElements(Concatenation([0],[((f+1)/2)..(f-1)],[f+1]));
fi;
B:=[cf];
irr:=[cf];
#we keep computing the sons in the tree for every new irreducible numerical semigroup
while B<>[] do
s:=B[1];
B:=B{[2..Length(B)]};
lsons:=sons(s);
Append(irr,lsons);
Append(B,lsons);
od;
for s in irr do
Setter(IsIrreducibleNumericalSemigroup)(s,true);
od;
return irr;
end);
#############################################################################
##
#F IrreducibleNumericalSemigroupsWithFrobeniusNumberAndMultiplicity(F,m)
##
## Computes the set of irreducible numerical semigroups with multipliciy m
## and Frobenius number F. The algorithm is based on "The set of numerical
## semigroups of a given multiplicity and Frobenius number"
## arXiv:1904.05551 [math.GR]
##
#############################################################################
InstallGlobalFunction(IrreducibleNumericalSemigroupsWithFrobeniusNumberAndMultiplicity,
function(F,m)
local sons, p,r, sgCmf, Cmf, A, Irrmf, s, lsons;
if (not(IsInt(F))) or (not(IsInt(m))) then
Error("The arguments must be two integers.\n");
fi;
if F<-1 or F=0 then
return [];#Error(f," is not a valid Frobenius number.\n");
fi;
if m<=0 then
return [];#Error(m," is not a valid Multiplicity.\n");
fi;
if F=-1 and m = 1 then
return [NumericalSemigroup(1)];
fi;
if m > (F+2)/2 or RemInt(F,m) = 0 then
return [];
fi;
if m=2 then
# return [NumericalSemigroupByMinimalGenerators([m,F+m])];
return [NumericalSemigroup([m,F+m])];
fi;
if m=3 and IsEvenInt(F) then
# return [NumericalSemigroupByMinimalGenerators([m,F/2+m,F+m])];
return [NumericalSemigroup([m,F/2+m,F+m])];
fi;
sons:=function(s,F)
local small, m, r, msg, candidates;
small:=SmallElementsOfNumericalSemigroup(s);
m:=small[2];
r:=First(small,i->RemInt(i,m) <> 0);
msg:=function(x)
return Filtered(small, y-> (y<x) and (x-y) in small)=[0];
end;
candidates:=Filtered(small, x-> (x>F/2) and (x<F)
and not(2*x-F in small) and not(3*x=2*F)
and not(4*x=3*F) and (F-x>m) and (F-x<r)
and (msg(x)));
return List(candidates, x->
NumericalSemigroupBySmallElements(Set(Concatenation(
Difference(small,[x]),[F-x]))));
end;
p := RemInt(F,2);
r := RemInt((F+2-p)/2,m);
if r = 0 then
r:=m;
fi;
sgCmf := (F+2-p)/2 + Difference([0 .. (m-1)], [m-r, r-(2-p)]);
# Cmf := NumericalSemigroupByMinimalGenerators(Concatenation([m],sgCmf));
Cmf := NumericalSemigroup(Concatenation([m],sgCmf));
A:=[Cmf];
Irrmf:=A;
while A<>[] do
s:=A[1];
A:=A{[2..Length(A)]};
lsons:=sons(s,F);
Append(Irrmf,lsons);
Append(A,lsons);
od;
for s in Irrmf do
Setter(IsIrreducibleNumericalSemigroup)(s,true);
od;
return Set(Irrmf);
end);
#############################################################################
##
#F OverSemigroupsNumericalSemigroup(s)
##
## Computes the set of numerical semigroups containing s.
## The algorithm is based on
## "The oversemigroups of a numerical semigroup", Semigroup Forum.
##
#############################################################################
InstallGlobalFunction(OverSemigroupsNumericalSemigroup, function(s)
local t, sg, A, O;
#A the output
#t current semigroup for which we compute unitary extensions
#O list of over semigroups of t
#sg special gaps of t
if(not(IsNumericalSemigroup(s))) then
Error("The argument must be a numerical semigroup.\n");
fi;
if(s=NumericalSemigroup(1)) then
return [s];
fi;
t:=s;
sg:=SpecialGapsOfNumericalSemigroup(t); #which must be different from [-1]
A:=[NumericalSemigroup(1),t];
O:=List(sg,g->AddSpecialGapOfNumericalSemigroup(g,t));
while(O<>[]) do
t:=O[1];
O:=O{[2..Length(O)]};
if(not(t in A)) then
A:=Union(A,[t]);
sg:=SpecialGapsOfNumericalSemigroup(t);
O:=Union(O,List(sg,g->AddSpecialGapOfNumericalSemigroup(g,t)));
fi;
od;
return A;
end);
InstallMethod(OverSemigroups,
"of a numerical semigroup",
[IsNumericalSemigroup],
OverSemigroupsNumericalSemigroup);
#############################################################################
##
#F DecomposeIntoIrreducibles(s)
##
## Returns a list of irreducible numerical semigroups
## such that its intersection is s.
## This decomposition is minimal, and is inspired in
## Algorithm 26 of "The oversemigroups of a numerical semigroup".
##
#############################################################################
InstallGlobalFunction(DecomposeIntoIrreducibles, function(s)
local sg, caux, I, C, B, pair, i, I2, j, l, dec, si;
#sg contains the special gaps of s
#B auxiliar ser used to construct C and I
#I will include irreducibles containing s
#C non irreducibles
#caux(t) is to compute those elements in gs that are not in t
#II auxiliar set of irreducibles
if(not(IsNumericalSemigroup(s))) then
Error("The argument must be a numerical semigroup.\n");
fi;
if(s=NumericalSemigroup(1)) then
Setter(IsIrreducibleNumericalSemigroup)(s,true);
return [s];
fi;
sg:=SpecialGapsOfNumericalSemigroup(s);
if (Length(sg)=1) then
Setter(IsIrreducibleNumericalSemigroup)(s,true);
return [s];
fi;
caux:=function(t)
return Filtered(sg,g->not(BelongsToNumericalSemigroup(g,t)));
end;
I:=[];
C:=[s];
B:=[];
while(not(C=[])) do
B:=Union(List(C,sp->List(SpecialGapsOfNumericalSemigroup(sp),g->AddSpecialGapOfNumericalSemigroup(g,sp))));
B:=Filtered(B,b->not(caux(b)=[]));
B:=Filtered(B,b->Filtered(I,i->IsSubsemigroupOfNumericalSemigroup(i,b))=[]);
C:=Filtered(B,b->not(Length(SpecialGapsOfNumericalSemigroup(b))=1));
I:=Union(I,Difference(B,C));
od;
I:=List(I,i->[i,caux(i)]);
while(true) do
pair := fail;
for i in I do
I2 := [];
for j in I do
if not j = i then
Add(I2, j);
fi;
od;
l := [];
for j in I2 do
Add(l, j[2]);
od;
if Union(l) = sg then
pair := i;
break;
fi;
od;
if(pair=fail) then
dec:=List(I, x -> x[1]);
for si in dec do
Setter(IsIrreducibleNumericalSemigroup)(si,true);
od;
return dec;
fi;
I2 := [];
for j in I do
if not j = pair then
Add(I2, j);
fi;
od;
I := I2;
Unbind(I2);
od;
dec:=List(I, x -> x[1]);
for si in dec do
Setter(IsIrreducibleNumericalSemigroup)(si,true);
od;
return dec;
end);
#############################################################################
##
#P IsIrreducibleNumericalSemigroup(s)
##
## Checks whether or not s is an irreducible numerical semigroup.
##
#############################################################################
InstallMethod(IsIrreducibleNumericalSemigroup,
"Tests whether the semigroup is irreducible", [IsNumericalSemigroup],1,
function(s)
if HasIsSymmetricNumericalSemigroup(s) and (IsSymmetricNumericalSemigroup(s)) then
return true;
fi;
if HasIsPseudoSymmetricNumericalSemigroup(s) and (IsPseudoSymmetricNumericalSemigroup(s)) then
return true;
fi;
return Length(GapsOfNumericalSemigroup(s))<=(FrobeniusNumberOfNumericalSemigroup(s)+2)/2;
end);
InstallMethod(IsIrreducible,
"Tests wheter the semigroup is irreducible",
[IsNumericalSemigroup], IsIrreducibleNumericalSemigroup
);
#############################################################################
##
#F IsSymmetricNumericalSemigroup(s)
##
## Checks whether or not s is a symmetric numerical semigroup.
##
#############################################################################
InstallMethod(IsSymmetricNumericalSemigroup,
"Tests wheter the semigroup is symmetric",
[IsNumericalSemigroup],1,
function(s)
if HasGenerators(s) and Length(Generators(s))<=3 then
return IsFreeNumericalSemigroup(s);
fi;
return GenusOfNumericalSemigroup(s)=(FrobeniusNumberOfNumericalSemigroup(s)+1)/2;
end);
InstallTrueMethod(IsIrreducibleNumericalSemigroup, IsSymmetricNumericalSemigroup);
#############################################################################
##
#P IsPseudoSymmetricNumericalSemigroup(s)
##
## Checks whether or not s is a pseudosymmetric numerical semigroup.
##
#############################################################################
InstallMethod(IsPseudoSymmetricNumericalSemigroup,
"Tests wheter the semigroup is pseudosymmetric",
[IsNumericalSemigroup],1,function(s)
local sg;
return GenusOfNumericalSemigroup(s)=(FrobeniusNumberOfNumericalSemigroup(s)+2)/2;
end);
InstallTrueMethod(IsIrreducibleNumericalSemigroup, IsPseudoSymmetricNumericalSemigroup);
#####################################################################
## Almost-symmetric numerical semigroups
## See [BF97] and [RGS13]
# -J. C. Rosales, P. A. García-Sánchez, Constructing almost symmetric numerical
# semigroups from almost irreducible numerical semigroups, Comm. Algebra.
#####################################################################
##
#P IsAlmostSymmetricNumericalSemigroup(arg)
##
## The argument is a numerical semigroup. The output is True or False depending
## on if the semigroup is almost symmetric or not, see [BF97]
##
#####################################################################
InstallMethod(IsAlmostSymmetricNumericalSemigroup,
"Tests whether the semigroup is almost symmetric",
[IsNumericalSemigroup],1,
function(s)
return 2*GenusOfNumericalSemigroup(s)=FrobeniusNumber(s)+TypeOfNumericalSemigroup(s);
end);
InstallTrueMethod(IsAlmostSymmetricNumericalSemigroup, IsIrreducibleNumericalSemigroup);
#####################################################################
##
#F AlmostSymmetricNumericalSemigrupsFromIrreducible(s)
##
## The argument is an irreducible numerical semigroup. The output is the set of
## almost-symmetric numerical semigroups obtained from s, as explained in
## Theorem 3 in [RGS13]
##
#####################################################################
InstallGlobalFunction(AlmostSymmetricNumericalSemigroupsFromIrreducible,function(s)
local msg, pow, conditionb, f,cand, small, sa;
if not IsNumericalSemigroup(s) then
Error("The argument must be a numerical semigroup.\n");
fi;
if not IsIrreducibleNumericalSemigroup(s) then
Error("The argument must be an irreducible numerical semigroup.\n");
fi;
#implements Condition (b) in Proposition 1 of [RGS13]
conditionb:=function(l)
local cart;
cart:=Filtered(Cartesian(l,l),p->p[1]<=p[2]);
return ForAll(cart, p-> (p[1]+p[2]-f in l) or not(p[1]+p[2]-f in s));
end;
f:=FrobeniusNumber(s);
small:=SmallElementsOfNumericalSemigroup(s);
#chooses minimal generators between f/2 and f, and then tests Condition (b)
msg:=Filtered(MinimalGeneratingSystemOfNumericalSemigroup(s), x-> (f/2<x) and (x<f));
pow:=Combinations(msg);
cand:=Filtered(pow, conditionb);
cand:=Set(cand,l->NumericalSemigroupBySmallElementsNC(Difference(small,l)));
for sa in cand do
Setter(IsAlmostSymmetricNumericalSemigroup)(sa,true);
od;
return cand;
end);
#####################################################################
##
#F AlmostSymmetricNumericalSemigroupsFromIrreducibleAndGivenType(s,t)
##
## The arguments are an irreducible numerical semigroup and a
## positive integer t. The output is the set of
## almost-symmetric numerical semigroups obtained from s, as
## explained in [BOR18], with tye t.
##
#####################################################################
InstallGlobalFunction(AlmostSymmetricNumericalSemigroupsFromIrreducibleAndGivenType,function(s,t)
local msg, pow, conditionb, f,cand, small, sa;
if not IsNumericalSemigroup(s) then
Error("The first argument must be a numerical semigroup.\n");
fi;
if not IsIrreducibleNumericalSemigroup(s) then
Error("The first argument must be an irreducible numerical semigroup.\n");
fi;
if not(IsInt(t)) then
Error("The second argument must be an integer");
fi;
if t<1 then
return []; #Error("The second argument must be an integer greater than or equal to one");
fi;
#implements Condition (c) in Proposition 4 of [BOR18]
conditionb:=function(l)
local cart;
cart:=Filtered(Cartesian(l,l),p->p[1]<=p[2]);
return ForAll(cart, p-> (p[1]+p[2]-f in l) or not(p[1]+p[2]-f in s));
end;
f:=FrobeniusNumber(s);
small:=SmallElementsOfNumericalSemigroup(s);
if IsOddInt(f+t) then
return Set([]);
fi;
#chooses minimal generators between f/2 and f, and then tests Condition (b)
msg:=Filtered(MinimalGeneratingSystemOfNumericalSemigroup(s), x-> (f/2<x) and (x<f));
pow:=Combinations(msg,CeilingOfRational(t/2)-1);
cand:=Filtered(pow, conditionb);
cand:=Set(cand,l->NumericalSemigroupBySmallElementsNC(Difference(small,l)));
for sa in cand do
Setter(IsAlmostSymmetricNumericalSemigroup)(sa,true);
od;
return cand;
end);
#####################################################################
##
#F AlmostSymmetricNumericalSemigroupsWithFrobeniusNumberAndType(f,t)
##
## The arguments are two positive integers. The output is the set of
## almost-symmetric numerical semigroups obtained with type t and
## Frobenius number f.
##
#####################################################################
InstallGlobalFunction(AlmostSymmetricNumericalSemigroupsWithFrobeniusNumberAndType,function(f,t)
if(not(IsInt(f)) or not(IsInt(t))) then
Error("The arguments must be integers.\n");
fi;
if f<-1 or f =0 then
return []; #Error(f," is not a valid Frobenius number.\n");
fi;
if f=-1 then
return [NumericalSemigroup(1)];
fi;
return Union(Set(IrreducibleNumericalSemigroupsWithFrobeniusNumber(f),s->AlmostSymmetricNumericalSemigroupsFromIrreducibleAndGivenType(s,t)));
end);
#####################################################################
##
#F AlmostSymmetricNumericalSemigroupsWithFrobeniusNumber(f,[ts])
##
## The arguments integers. The output is the set of all almost-symmetric
## numerical semigroups with Frobenius number f, and if ts is specified
## these semigroups have at least type ts [BOR18].
##
#####################################################################
InstallGlobalFunction(AlmostSymmetricNumericalSemigroupsWithFrobeniusNumber,function(F,ts...)
local L,sg,PF,Ga,N,auxiliar,auxiliar2, mt, outlist;
if not(IsInt(F)) then
Error("The first argument must be an integer");
fi;
if F<-1 or F=0 then
return [];
fi;
if Length(ts)>1 then
Error("The number of arguments must be one (Frobenius number) or two (Frobenius number and lower bound for type)");
fi;
if Length(ts)=1 then
if not(IsInt(ts[1])) then
Error("The second argument must be an integer");
fi;
if ts[1]<1 then
Error("The second argument must be an integer greater than or equal to one");
fi;
mt:=ts[1];
if IsOddInt(F+mt) then
mt:=mt+1;
fi;
else # no ts specified
mt:=1;
fi;
if F < 3 then
return Filtered([NumericalSemigroupByGaps([1 .. F])], s->Type(s)>=mt);
fi;
L:=[[[F+1 .. 2*F+1],[1 .. F],[1 .. F]]];
if mt >= F-1 then
return [NumericalSemigroupByGaps(L[1][3])];
fi;
sg:=Union([F-1],[F+1 .. 2*F+1]);
PF:=Difference([1 .. F],[F-1,1]);
Ga:=Difference([1 .. F],[F-1]);
Append(L,[[sg,PF,Ga]]);
if mt >= F-3 then
outlist:= List(L, t->NumericalSemigroupByGaps(t[3]));
return outlist;
fi;
if F < 5 then
return Filtered(List(L, t->NumericalSemigroupByGaps(t[3])), s->Type(s)>=mt);
fi;
auxiliar := function(sg,PF,Ga)
local L,m,t,i,sg1,PF1,Ga1;
L := []; m:=sg[1]; t:=Length(PF); F:=PF[t];
for i in [t-1 .. m-1] do
sg1:=Union([i],sg);
PF1:=Difference(PF,[i,F-i]);
Ga1:=Difference(Ga,[i]);
if IsSubset(Ga1,Filtered(Ga1-i,j->(j>0))) and (Intersection(PF1+i, Ga1) = [ ]) then
Append(L,[[sg1,PF1,Ga1]]);
fi;
od;
return L;
end;
N:=[[sg,PF,Ga]];
repeat
N:=Concatenation(List(N, t->CallFuncList(auxiliar,t)));
Append(L,N);
until Length(N[1][2]) < mt+2;
outlist:= List(L, t->NumericalSemigroupByGaps(t[3]));
for sg in outlist do
Setter(IsAlmostSymmetricNumericalSemigroup)(sg,true);
od;
return outlist;
end);
#############################################################################
##
#F AsGluingOfNumericalSemigroups
##
## returns all partitions {A1,A2} of the minimal generating set of s such
## that s is a gluing of <A1> and <A2> by gcd(A1)gcd(A2)
##
#############################################################################
InstallGlobalFunction(AsGluingOfNumericalSemigroups,function(s)
local msg,partitions, gluing;
if not IsNumericalSemigroup(s) then
Error("The argument must be a numerical semigroup.\n");
fi;
gluing:=function(l1,l2) #this function checks if for a couple of
# lists of integers, the numerical semigroup
# generated by [l1,l2] is the gluing of those
# generated by l1/d1 and l2/d2
local d1, d2, t1, t2, s1, s2;
d1:=Gcd(l1);
d2:=Gcd(l2);
if (not(Gcd(d1,d2)=1)) then
return false;
fi;
s1:=NumericalSemigroup(l1/d1);
s2:=NumericalSemigroup(l2/d2);
return (not(d1 in l2/d2) and not(d2 in l1/d1)) and ((d1 in s2) and (d2 in s1));
end;
msg:=MinimalGeneratingSystemOfNumericalSemigroup(s);
partitions:=PartitionsSet(msg,2);
return Filtered(partitions, p->gluing(p[1],p[2]));
end);
#############################################################################
##
#P IsACompleteIntersectionNumericalSemigroup
##
##returns true if the numerical semigroup is a complete intersection,
## that is, the cardinality of a (any) minimal presentation equals
## its embedding dimension minus one
##
#############################################################################
InstallMethod(IsACompleteIntersectionNumericalSemigroup,
"Tests if the semigroup is a complete intersection",
[IsNumericalSemigroup],1,
function(s)
## if the semigroup is not symmetric, then it not a complete intersection
if HasIsSymmetricNumericalSemigroup(s) and (not IsSymmetricNumericalSemigroup(s)) then
return false;
fi;
return Length(MinimalPresentationOfNumericalSemigroup(s))=EmbeddingDimensionOfNumericalSemigroup(s)-1;
end);
InstallTrueMethod(IsSymmetricNumericalSemigroup, IsACompleteIntersectionNumericalSemigroup);
#############################################################################
##
#P IsFreeNumericalSemigroup
##
# # returns true if the numerical semigroup is a free semigroup, in the sense of
# # Bertin and Carbonne [BC77]
##
#############################################################################
InstallMethod(IsFreeNumericalSemigroup,
"Tests if the semigroup is free", [IsNumericalSemigroup],1,
function(s)
local gluing, msg;
## if the semigroup is not symmetric, then it not free (deprecated)
if HasIsSymmetricNumericalSemigroup(s) and (not IsSymmetricNumericalSemigroup(s)) then
return false;
fi;
gluing:=function(l1,l2) #this function checks if for a couple of
# lists of integers, the numerical semigroup
# generated by [l1,l2] is the gluing of those
# generated by l1/d1 and l2/d2
local d1, d2, t1, t2, s1, s2;
d1:=Gcd(l1);
d2:=Gcd(l2);
if (not(Gcd(d1,d2)=1)) then
return false;
fi;
s1:=NumericalSemigroup(l1/d1);
s2:=NumericalSemigroup(l2/d2);
return (not(d1 in l2) and not(d2 in l1)) and ((d1 in s2) and (d2 in s1));
end;
msg:=MinimalGeneratingSystemOfNumericalSemigroup(s);
if Length(msg)<=2 then
return true;
fi;
if Length(msg)=3 then
return Length(AsGluingOfNumericalSemigroups(s))>0;
fi;
return ForAny(msg, m-> gluing([m],Difference(msg,[m])) and
IsFreeNumericalSemigroup(NumericalSemigroup(Difference(msg,[m])/Gcd(Difference(msg,[m])))));
end);
InstallTrueMethod(IsACompleteIntersectionNumericalSemigroup, IsFreeNumericalSemigroup);
#############################################################################
##
#P IsTelescopicNumericalSemigroup
##
## returns true if the numerical semigroup is telescopic [KP95],
## that is, free for the ordering n_1<...<n_e, with n_i the minimal generators
##
#############################################################################
InstallMethod(IsTelescopicNumericalSemigroup,
"Tests if the semigroup is telescopic", [IsNumericalSemigroup],1,
function(s)
local gluing, msg, max;
## if the semigroup is not symmetric, then it not telescopic
if HasIsSymmetricNumericalSemigroup(s) and (not IsSymmetricNumericalSemigroup(s)) then
return false;
fi;
gluing:=function(l1,l2) #this function checks if for a couple of
# lists of integers, the numerical semigroup
# generated by [l1,l2] is the gluing of those
# generated by l1/d1 and l2/d2
local d1, d2, t1, t2, s1, s2;
d1:=Gcd(l1);
d2:=Gcd(l2);
if (not(Gcd(d1,d2)=1)) then
return false;
fi;
s1:=NumericalSemigroup(l1/d1);
s2:=NumericalSemigroup(l2/d2);
return (not(d1 in l2) and not(d2 in l1)) and ((d1 in s2) and (d2 in s1));
end;
msg:=MinimalGeneratingSystemOfNumericalSemigroup(s);
max:=Maximum(msg);
if Length(msg)<=2 then
return true;
fi;
return gluing([max],Difference(msg,[max])) and
IsTelescopicNumericalSemigroup(NumericalSemigroup(Difference(msg,[max])/Gcd(Difference(msg,[max]))));
end);
InstallTrueMethod(IsFreeNumericalSemigroup, IsTelescopicNumericalSemigroup);
#############################################################################
##
#P IsNumericalSemigroupAssociatedIrreduciblePlanarCurveSingularity
##
## returns true if the numerical semigroup is a telescopic numerical semigroup,
## and in addition for all i, d_i n_i < d_{i+1}n_{i+1}, con d_i=gcd{n_j | j<i} [Z86]
##
#############################################################################
InstallMethod(IsNumericalSemigroupAssociatedIrreduciblePlanarCurveSingularity,
"Tests if the semigroup is the semigroup associated to an irreducible planar curve singularity",
[IsNumericalSemigroup],1,
function(s)
local gluing, msg, max, di, dip1, rest, maxrest;
## if the semigroup is not symmetric, then it not planar
if HasIsSymmetricNumericalSemigroup(s) and (not IsSymmetricNumericalSemigroup(s)) then
return false;
fi;
gluing:=function(l1,l2) #this function checks if for a couple of
# lists of integers, the numerical semigroup
# generated by [l1,l2] is the gluing of those
# generated by l1/d1 and l2/d2
local d1, d2, t1, t2, s1, s2;
d1:=Gcd(l1);
d2:=Gcd(l2);
if (not(Gcd(d1,d2)=1)) then
return false;
fi;
s1:=NumericalSemigroup(l1/d1);
s2:=NumericalSemigroup(l2/d2);
return (not(d1 in l2) and not(d2 in l1)) and ((d1 in s2) and (d2 in s1));
end;
msg:=MinimalGeneratingSystemOfNumericalSemigroup(s);
if Length(msg)<=2 then
return true;
fi;
max:=Maximum(msg);
rest:=Difference(msg,[max]);
maxrest:=Maximum(rest);
di:=Gcd(Difference(rest,[maxrest]));
dip1:=Gcd(rest);
return gluing([max],rest) and (di*maxrest< dip1*max) and
IsNumericalSemigroupAssociatedIrreduciblePlanarCurveSingularity( NumericalSemigroup(rest/Gcd(rest)) );
end);
InstallTrueMethod(IsTelescopicNumericalSemigroup, IsNumericalSemigroupAssociatedIrreduciblePlanarCurveSingularity);
#############################################################################
##
#P IsUniversallyFreeNumericalSemigroup
##
## returns true if the numerical semigroup is free for all possible
## arrangements of its generators
##
#############################################################################
InstallMethod(IsUniversallyFreeNumericalSemigroup,
"Tests if the semigroup is universally free", [IsNumericalSemigroup],1,
function(s)
local isfree, msg, gluing, g, i, sigma,e, arr;
gluing:=function ( l1, l2 )
local d1, d2, t1, t2, s1, s2;
d1 := Gcd( l1 );
d2 := Gcd( l2 );
if not Gcd( d1, d2 ) = 1 then
return false;
fi;
s1 := NumericalSemigroup( l1 / d1 );
s2 := NumericalSemigroup( l2 / d2 );
return not d1 in l2 and not d2 in l1 and (d1 in s2 and d2 in s1);
end;
isfree:=function ( l )
local l1, l1g, lst, g;
if Length( l ) <= 2 then
return true;
fi;
lst := l[Length( l )];
l1 := l{[ 1 .. Length( l ) - 1 ]};
g := Gcd( l1 );
l1g := l1 / g;
return gluing( l1, [ lst ] ) and isfree( l1g );
end;
msg:=MinimalGenerators(s);
# return ForAll(PermutationsList(msg), isfree);
e:=EmbeddingDimension(s);
g:=SymmetricGroup(e);
i:=Iterator(g);
for sigma in i do
arr:=List([1..e], x-> x^sigma);
if not(isfree(msg{arr})) then
Info(InfoNumSgps,2,"Fails for the arrangment", msg{arr},"\n");
return false;
fi;
od;
return true;
end);
InstallTrueMethod(IsTelescopicNumericalSemigroup, IsUniversallyFreeNumericalSemigroup);
#############################################################################
##
#F NumericalSemigroupsPlanarSingularityWithFrobeniusNumber
##
## returns the set of numerical semigroups associated to irreducible
## planar curves with Frobenius number given, as explained in [AGS13]
##
#############################################################################
InstallGlobalFunction(NumericalSemigroupsPlanarSingularityWithFrobeniusNumber, function(f)
local pcs, out, i, s;
if(not(IsInt(f))) then
Error("The argument must be an integer.\n");
fi;
pcs:=function(f) #we first compute the list of all possible minimal generating systems
local dkcand, dk, rk, fp, candr, bound, total, pcscond;
if (f<-1) or (f mod 2=0) then
return [];
fi;
if (f=-1) then
return [[1]];
fi;
if (f=1) then
return [[2,3]];
fi;
#irreducible planar curve conditition
pcscond:=function(l,d,r)
local rest, max, dl;
if Length(l)=1 then
return true;
fi;
max:=Maximum(l);
rest:=Difference(l,[max]);
dl:=Gcd(rest);
return max*d*dl < r;
end;
total:=[[2,f+2]]; #this one is always
for rk in [4..f-1] do
bound:=Minimum(rk-1, Int((f+1)/(rk-1)+1), RootInt(f+1)+1);
dkcand:=Filtered([2..bound],d->(Gcd(d,rk)=1)and((f+rk) mod d=0));
for dk in dkcand do
fp:=(f+rk*(1-dk))/dk;
candr:=Filtered(pcs(fp), l-> (rk> Maximum(l)*dk) and pcscond(l,dk,rk) and (rk in NumericalSemigroup(l)));
#Print(fp,candr,"\n");
candr:=List(candr, l-> Concatenation(l*dk, [rk]));
total:=Union(total,candr);
od;
od;
return total;
end;
out:=[];
for i in pcs(f) do
s:=NumericalSemigroup(i);
Setter(IsNumericalSemigroupAssociatedIrreduciblePlanarCurveSingularity)(s,true);
Add(out,s);
od;
return out;
end);
#############################################################################
##
#F TelescopicNumericalSemigroupsWithFrobeniusNumber
##
## returns the set of telescopic numerical semigroups with Frobenius number
## given, as explained in [AGS13]
##
#############################################################################
InstallGlobalFunction(TelescopicNumericalSemigroupsWithFrobeniusNumber,function(f)
local tel, s, i, out;
if(not(IsInt(f))) then
Error("The argument must be an integer.\n");
fi;
tel:=function(f) #we first compute the list of all possible minimal generating systems
local dkcand, dk, rk, fp, candr, bound, total;
if (f<-1) or (f mod 2=0) then
return [];
fi;
if (f=-1) then
return [[1]];
fi;
if (f=1) then
return [[2,3]];
fi;
total:=[[2,f+2]]; #this one is always
for rk in [4..f-1] do
bound:=Minimum(rk-1, Int((f+1)/(rk-1)+1), RootInt(f+1)+1);
dkcand:=Filtered([2..bound],d->(Gcd(d,rk)=1)and((f+rk) mod d=0));
for dk in dkcand do
fp:=(f+rk*(1-dk))/dk;
candr:=Filtered(tel(fp), l-> (rk> Maximum(l)*dk) and (rk in NumericalSemigroup(l)));
candr:=List(candr, l-> Concatenation(l*dk, [rk]));
total:=Union(total,candr);
od;
od;
return total;
end;
out:=[];
for i in tel(f) do
s:=NumericalSemigroup(i);
Setter(IsTelescopicNumericalSemigroup)(s,true);
Add(out,s);
od;
return out;
end);
#############################################################################
##
#F FreeNumericalSemigroupsWithFrobeniusNumber
##
## returns the set of free numerical semigroups with Frobenius number
## given, as explained in [AGS13]
##
#############################################################################
InstallGlobalFunction(FreeNumericalSemigroupsWithFrobeniusNumber,function(f)
local free, s, i, out;
if(not(IsInt(f))) then
Error("The argument must be an integer.\n");
fi;
free:=function(f)#we first compute the list of all possible minimal generating systems
local dkcand, dk, rk, fp, candr, bound, total;
if (f<-1) or (f mod 2=0) then
return [];
fi;
if (f=-1) then
return [[1]];
fi;
if (f=1) then
return [[2,3]];
fi;
total:=[[2,f+2]];
for rk in [4..f-1] do
bound:=(Int((f+1)/(rk-1)+1));
dkcand:=Filtered([2..bound],d->(Gcd(d,rk)=1)and((f+rk) mod d=0));
for dk in dkcand do
fp:=(f+rk*(1-dk))/dk;
candr:=Filtered(free(fp), l-> not(rk in l) and (rk in NumericalSemigroup(l)));
#Print(fp,candr,"\n");
candr:=List(candr, l-> Union(l*dk, [rk]));
total:=Union(total,candr);
od;
od;
return total;
end;
out:=[];
for i in free(f) do
s:=NumericalSemigroup(i);
Setter(IsFreeNumericalSemigroup)(s,true);
Add(out,s);
od;
return out;
end);
#############################################################################
##
#F CompleteIntersectionNumericalSemigroupsWithFrobeniusNumber
##
## returns the set of comple intersection numerical semigroups with Frobenius number
## given, as explained in [AGS13]
##
#############################################################################
InstallGlobalFunction(CompleteIntersectionNumericalSemigroupsWithFrobeniusNumber,function(f)
local ci, s, i, out;
if(not(IsInt(f))) then
Error("The argument must be an integer.\n");
fi;
ci:=function(f)
local d2cand, d1, d2, pairfcand, fcand1, fcand2, cand1, cand2, bound, total, partial, p;
if (f<-1) or (f mod 2=0) then
return [];
fi;
if (f=-1) then
return [[1]];
fi;
if (f=1) then
return [[2,3]];
fi;
total:=[[2,f+2]];
for d1 in [3..f-1] do
bound:=Minimum(d1-1,Int((f+1)/(d1-1)+1)); #we consider d2<d1
d2cand:=Filtered([2..bound],d->(Gcd(d,d1)=1));
# Print(f,":",d1,"->",d2cand,"\n");
for d2 in d2cand do
if((f+d1) mod d2=0) then
cand2:=Filtered(ci((f+d1*(1-d2))/d2), l-> not(d1 in l) and (d1 in NumericalSemigroup(l)));
partial:=List(cand2, l-> Union([d1],d2*l));
total:=Union(total,partial); cand2:=[]; partial:=[];
elif((f+d2) mod d1=0) then
cand1:=Filtered(ci((f+d2*(1-d1))/d1), l-> not(d2 in l) and (d2 in NumericalSemigroup(l)));
partial:=List(cand1, l-> Union(d1*l,[d2]));
total:=Union(total,partial); cand1:=[]; partial:=[];
fi;
if(f-d1*d2>0) then
pairfcand:=FactorizationsIntegerWRTList(f-d1*d2,[d2,d1]);
pairfcand:=Filtered(pairfcand, p-> (p[1] mod 2=1) and (p[2] mod 2=1));
for p in pairfcand do
cand1:=Filtered(ci(p[2]), l-> not(d2 in l) and (d2 in NumericalSemigroup(l)));
cand2:=Filtered(ci(p[1]), l-> not(d1 in l) and (d1 in NumericalSemigroup(l)));
partial:=List(Cartesian(cand1,cand2), pp-> Union(d1*pp[1],d2*pp[2]));
total:=Union(total,partial);
od;
fi;
od;
od;
return total;
end;
if(not(IsInt(f))) then
Error("The argument must be an integer.\n");
fi;
out:=[];
for i in ci(f) do
s:=NumericalSemigroup(i);
Setter(IsACompleteIntersectionNumericalSemigroup)(s,true);
Add(out,s);
od;
return out;
end);
#####################################################################
## Generalized Gorenstein numerical semigroups
## See [G-I-K-T] [G-K]
#####################################################################
##
#P IsGeneralizedGorenstein(arg)
##
## The argument is a numerical semigroup. The output is True or False depending
## on if the semigroup has the generalized Gorenstein property
##
#####################################################################
InstallMethod(IsGeneralizedGorenstein,
"Tests whether the semigroup is generalized Gorenstein",
[IsNumericalSemigroup],1,
function(H)
local K, R, S,m,c,soc,b,f,PF,flg,r,i;
K:=CanonicalIdeal(H);
R:=[0]+H;
m:=MaximalIdeal(H);
if K=R then
return true;
fi;
if 3*K=2*K then
S:=2*K;
c:=R-S;
soc:=Intersection(c-m,R);
if Length(Difference(soc,c)) <> 1 then
return false;
else
b:=Difference(soc,c)[1];
f:=FrobeniusNumber(H);
PF:=PseudoFrobenius(H);
flg:= true;
r:= Type(H);
for i in [1..(r-1)] do
if f+b <> PF[i] + PF[r-i] then
flg := false;
fi;
od;
return flg;
fi;
else
return false;
fi;
end);
InstallTrueMethod(IsAlmostSymmetricNumericalSemigroup, IsSymmetricNumericalSemigroup);
#####################################################################
##
#P IsNearlyGorenstein(arg)
##
## The argument is a numerical semigroup. The output is True or False depending
## on if the semigroup is nearly Gorenstein
##
#####################################################################
InstallMethod(IsNearlyGorenstein,
"Tests whether the semigroup is nearly Gorenstein",
[IsNumericalSemigroup],1,
function(S)
local T,msg;
T:=TraceIdeal(S);
msg:=MinimalGenerators(S);
return ForAll(msg, g->g in T);
end);
InstallTrueMethod(IsNearlyGorenstein, IsAlmostSymmetricNumericalSemigroup);
#####################################################################
##
#O NearlyGorensteinVectors(arg)
##
## The argument is a numerical semigroup S. The output is a lists of
## lists. If ni is the ith generator of S, in the ith position of the
## list it returns all pseudo-Frobenius numbers f of S such that
## ni+f-f' is in S for all f a pseudo-Frobenius number of S.
##
#####################################################################
InstallMethod(NearlyGorensteinVectors,
"Returns all possible nearly-Gorenstein vectors",
[IsNumericalSemigroup], 1,
function(s)
local pf, msg;
msg:=MinimalGenerators(s);
pf:=PseudoFrobenius(s);
return List(msg, g-> Filtered(pf, f-> ForAll(pf, h-> g+f-h in s)));
end);
#####################################################################
##
#P IsGeneralizedAlmostSymmetric(S)
##
## The argument is a numerical semigroup. The output is True or False depending
## on if S is a generalized almost symmetric numerical semigroup, see [DS21]
##
#####################################################################
InstallMethod(IsGeneralizedAlmostSymmetric,
"Tests whether the semigroup is a GAS semigroup",
[IsNumericalSemigroup],1,
function(S)
local PF,K,A,B,i,j;
PF:=PseudoFrobenius(S);
K:=CanonicalIdeal(S);
A:=Difference(K+K,K);
if Length(A)<2 then
return true;
fi;
if Length(A)>1 then
A:=Maximum(PF)-A;
B:=Concatenation(MinimalGenerators(S),[0]);
if IsSubsetSet(B,A) then
Sort(A);
for i in [2..Length(A)] do
for j in [i+1..Length(A)] do
if (A[j]-A[i] in PF) then
return false;
fi;
od;
od;
fi;
fi;
return true;
end);
[ Dauer der Verarbeitung: 0.53 Sekunden
(vorverarbeitet)
]
|