1############################################################################# 2## 3#W affine.gi Manuel Delgado <mdelgado@fc.up.pt> 4#W Pedro Garcia-Sanchez <pedro@ugr.es> 5## 6#Y Copyright 2015-- Centro de Matemática da Universidade do Porto, Portugal and Universidad de Granada, Spain 7############################################################################# 8## 9#if not TestPackageAvailability("4ti2Interface") = fail then 10# LoadPackage("4ti2"); 11#fi; 12## 13 14 15# using the parent InfoNumSgps 16#InfoAffSgps:=NewInfoClass("InfoAffSgps");; 17#SetInfoLevel(InfoAffSgps,1);; 18 19 20###################################################################### 21# Computes the set of primitive elements of an affine semigroup, that 22# is, the set of elements whose factorizations are involved in the 23# minimal generators of the congruence associated to the monod 24# (generators as a monoid; not to be confused with minimal presentations 25# to this end, use BettiElementsOfAffineSemigroup) 26# # REQUERIMENTS: 4ti2Interface 27###################################################################### 28 29#InstallGlobalFunction(PrimitiveElementsOfAffineSemigroup,function(ls) 30# local dir, filename, exec, filestream, matrix, 31# facs, mat, trunc;# ls; 32 33 34 #if not(IsAffineSemigroup(a)) then 35 # Error("The argument must be an affine semigroup"); 36 #fi; 37 38 #ls:=GeneratorsAS(a); 39 40# dir := DirectoryTemporary(); 41# filename := Filename( dir, "gap_4ti2_temp_matrix" ); 42# 43# mat:=TransposedMat(ls); 44# 4ti2Interface_Write_Matrix_To_File( mat, Concatenation( filename, ".mat" ) ); 45# exec := IO_FindExecutable( "graver" ); 46# filestream := IO_Popen2( exec, [ filename ]); 47# while IO_ReadLine( filestream.stdout ) <> "" do od; 48# matrix := 4ti2Interface_Read_Matrix_From_File( Concatenation( filename, ".gra" ) ); 49# 50# trunc:=function(ls) 51# return List(ls, y->Maximum(y,0)); 52# end; 53 54# matrix:=Set(matrix,trunc); 55# return Set(matrix, x->x*ls); 56#end); 57 58 59######### 60#InstallGlobalFunction(ElasticityOfAffineSemigroup, 61# function(ls) 62# local dir, filename, exec, filestream, matrix, 63# mat, truncplus, truncminus; 64 65# if not(IsHomogeneousList(ls)) then 66# Error("The argument must be a homogeneous list."); 67# fi; 68 69# if not(ForAll(ls,IsListOfIntegersNS)) then 70# Error("The argument must be a list of lists of integers."); 71# fi; 72 73# if not(Length(Set(ls, Length))=1) then 74# Error("All lists in the first argument must have the same length."); 75# fi; 76 77# dir := DirectoryTemporary(); 78# filename := Filename( dir, "gap_4ti2_temp_matrix" ); 79 80# mat:=TransposedMat(ls); 81# 4ti2Interface_Write_Matrix_To_File( mat, Concatenation( filename, ".mat" ) ); 82# exec := IO_FindExecutable( "graver" ); 83# filestream := IO_Popen2( exec, [ filename ]); 84# while IO_ReadLine( filestream.stdout ) <> "" do od; 85# matrix := 4ti2Interface_Read_Matrix_From_File( Concatenation( filename, ".gra" ) ); 86 87# truncplus:=function(ls) 88# return Sum(List(ls, y->Maximum(y,0))); 89# end; 90 91# truncminus:=function(ls) 92# return Sum(List(ls, y->-Minimum(y,0))); 93# end; 94 95# return Maximum(Set(matrix, y->truncplus(y)/truncminus(y))); 96# end); 97##### 98 99 100 101 102 103#################################################################### 104# Decides if the vector v belongs to the affine semigroup a 105# 106#################################################################### 107InstallMethod( \in, 108 "for affine semigroups", 109 [ IsHomogeneousList, IsAffineSemigroup], 110 function( v, a ) 111 return BelongsToAffineSemigroup(v,a); 112end); 113 114InstallMethod(BelongsToAffineSemigroup, 115 "To test whether an element of N^n belongs to an affine semigroup", 116 true, 117 [ IsHomogeneousList, IsAffineSemigroup and HasGenerators],50, 118 119 function(v,a) 120 local belongs, gen; 121 122 #determines if an element x is in the affine semigroup 123 # spanned by gen 124 belongs:=function(x,gen) 125 if gen=[] then 126 return false; 127 fi; 128 129 if ForAll(x,i->i=0) then 130 return true; 131 fi; 132 133 if ForAny(x,i->i<0) then 134 return false; 135 fi; 136 137 return belongs(x-gen[1],gen) or belongs(x,gen{[2..Length(gen)]}); 138 end; 139 140 if not(IsListOfIntegersNS(v)) then 141 Error("The first argument must be a list of integers."); 142 fi; 143 144 gen:=Generators(a); 145 if not(IsRectangularTable(Concatenation(gen,[v]))) then 146 Error("The dimension of the vector and the affine semigroup do not coincide."); 147 fi; 148 149 return belongs(v,gen); 150 151end); 152 153InstallMethod(BelongsToAffineSemigroup, 154 "To test whether a list of elements of N^n belongs to an affine semigroup", 155 true, 156 [ IsHomogeneousList, IsAffineSemigroup and HasEquations],100, 157 158 function(v,a) 159 local equ,eq,md,ev,i; 160 161 equ:=Equations(a); 162 if not(IsListOfIntegersNS(v)) then 163 Error("The first argument must be a list of integers."); 164 fi; 165 if ForAny(v,x->x<0) then 166 return false; 167 fi; 168 169 eq:=equ[1]; 170 md:=equ[2]; 171 if Length(eq[1])<>Length(v) then 172 Error("The dimension of the vector and the affine semigroup do not coincide."); 173 fi; 174 ev:=ShallowCopy(eq*v); 175 176 Info(InfoNumSgps,2,"Testing membership with equations."); 177 178 for i in [1..Length(md)] do 179 ev[i]:=ev[i] mod md[i]; 180 od; 181 182 return ForAll(ev,x->x=0); 183 184end); 185 186InstallMethod(BelongsToAffineSemigroup, 187 "To test whether a list of elements of N^n belongs to an affine semigroup", 188 true, 189 [ IsHomogeneousList, IsAffineSemigroup and HasPMInequality],100, 190 191 function(v,a) 192 local f, b, g, ineq; 193 194 ineq:=PMInequality(a); 195 if not(IsListOfIntegersNS(v)) then 196 Error("The first argument must be a list of integers."); 197 fi; 198 if ForAny(v,x->x<0) then 199 return false; 200 fi; 201 202 f:=ineq[1]; 203 b:=ineq[2]; 204 g:=ineq[3]; 205 if Length(ineq[1])<>Length(v) then 206 Error("The dimension of the vector and the affine semigroup do not coincide."); 207 fi; 208 209 return ((f*v) mod b) <= g*v; 210 211end); 212 213InstallMethod(BelongsToAffineSemigroup, 214 "To test whether an element of N^n belongs to an affine semigroup", 215 true, 216 [ IsHomogeneousList, IsAffineSemigroup and HasInequalities],70, 217 218 function(v,a) 219 local equ,ev; 220 221 equ:=AffineSemigroupInequalities(a); 222 if not(IsListOfIntegersNS(v)) then 223 Error("The first argument must be a list of integers."); 224 fi; 225 if ForAny(v,x->x<0) then 226 return false; 227 fi; 228 229 if Length(equ[1])<>Length(v) then 230 Error("The dimension of the vector and the affine semigroup do not coincide."); 231 fi; 232 ev:=equ*v; 233 234 Info(InfoNumSgps,2,"Testing membership with inequalities."); 235 236 return ForAll(ev,x->x>=0); 237 238end); 239 240InstallMethod(BelongsToAffineSemigroup, 241 "To test whether an element of N^n belongs to an affine semigroup", 242 true, 243 [ IsHomogeneousList, IsAffineSemigroup and HasGaps],70, 244 function(v,a) 245 local gaps; 246 247 if not(IsListOfIntegersNS(v)) then 248 Error("The first argument must be a list of integers."); 249 fi; 250 if ForAny(v,x->x<0) then 251 return false; 252 fi; 253 gaps:=Gaps(a); 254 if Length(gaps[1])<>Length(v) then 255 Error("The dimension of the vector and the affine semigroup do not coincide."); 256 fi; 257 258 Info(InfoNumSgps,2,"Testing membership with gaps."); 259 return not(v in gaps); 260end); 261 262############################################################# 263# Computes a basis of a subgroup of Z^n with defining equations 264# Ax =0 \in Z_m1\times\Z_mt \times Z^k, k is n-length(m), 265# m=[m1,...,mt] 266############################################################# 267InstallGlobalFunction(BasisOfGroupGivenByEquations,function(A,m) 268 local n,r, AA, i, er, b, homEqToBasis; 269 270 # Compute a basis of a subgroup of Z^n with defining equations Ax=0 271 homEqToBasis:=function(A) 272 local snf, b, r, n; 273 snf:= SmithNormalFormIntegerMatTransforms(A); 274 r:=snf.rank; 275 n:=Length(A[1]); 276 b:=TransposedMat(snf.coltrans); 277 return b{[r+1..n]}; 278 end; 279 280 281 if not(IsRectangularTable(A)) then 282 Error("The first argument must be a matrix."); 283 fi; 284 if not(IsInt(A[1][1])) then 285 Error("The first argument must be a matrix of integers."); 286 fi; 287 288 n:=Length(A[1]); 289 r:=Length(A); 290 291 if m=[] then 292 AA:=ShallowCopy(TransposedMat(A)); 293 else 294 if not(IsListOfIntegersNS(m)) then 295 Error("The second argument must be a lists of integers."); 296 fi; 297 298 if not(ForAll(m,x->x>0)) then 299 Error("The second argument must be a list of positive integers"); 300 fi; 301 302 AA:=ShallowCopy(TransposedMat(A)); 303 er:=List([1..r],_->0); 304 for i in [1..Length(m)] do 305 if m[i]<>0 then 306 er[i]:=m[i]; 307 Add(AA,ShallowCopy(er)); 308 er[i]:=0; 309 fi; 310 od; 311 fi; 312 AA:=TransposedMat(AA); 313 314 b:=TransposedMat(homEqToBasis(AA)); 315 316 b:=b{[1..n]}; 317 return LLLReducedBasis(TransposedMat(b)).basis; 318end); 319 320############################################################# 321# Computes the defining equations of the group of Z^n 322# generated by M 323# the output is [A,m] such that Ax=0 mod m are the equations 324############################################################ 325InstallGlobalFunction(EquationsOfGroupGeneratedBy,function(M) 326 local A, m, snf, nones; 327 328 if not(IsRectangularTable(M)) then 329 Error("The first argument must be a matrix."); 330 fi; 331 if not(IsInt(M[1][1])) then 332 Error("The first argument must be a matrix of integers."); 333 fi; 334 335 snf:=SmithNormalFormIntegerMatTransforms(M); 336 A:=TransposedMat(snf.coltrans); 337 m:=DiagonalOfMat(snf.normal); 338 nones:=Length(Filtered(m,x->x=1)); 339 340 m:=Filtered(DiagonalOfMat(snf.normal),x->x<>0); 341 A:=A{[nones+1..Length(A)]}; 342 m:=m{[nones+1..Length(m)]}; 343 344 return [A,m]; 345end); 346 347 348############################################################## 349# Determines if there is a gluing of the two affine semigroups, 350# and if so, returns the gluing of them; fail otherwise 351############################################################## 352InstallGlobalFunction(GluingOfAffineSemigroups,function(a1,a2) 353 local int, d, intersectionOfSubgroups, g1, g2; 354 355 356 #computes the intersection of two groups of Z^n 357 # given by generators 358 intersectionOfSubgroups:=function(g1,g2) 359 local eq1, eq2, A, m; 360 361 eq1:=EquationsOfGroupGeneratedBy(g1); 362 eq2:=EquationsOfGroupGeneratedBy(g2); 363 A:=Concatenation(eq1[1],eq2[1]); 364 m:=Concatenation(eq1[2],eq2[2]); 365 366 return BasisOfGroupGivenByEquations(A,m); 367 end; 368 369 if not(IsAffineSemigroup(a1)) or not(IsAffineSemigroup(a2)) then 370 Error("The arguments must be affine semigroups."); 371 fi; 372 373 g1:=GeneratorsOfAffineSemigroup(a1); 374 g2:=GeneratorsOfAffineSemigroup(a2); 375 if not(IsRectangularTable(Concatenation(g1,g2)))then 376 Error("The semigroups must have the same dimension."); 377 fi; 378 379 int:=intersectionOfSubgroups(g1,g2); 380 if Length(int)<> 1 then 381 return false; 382 fi; 383 384 d:=int[1]; 385 if ForAny(d, i->i<0) then 386 d:=-d; 387 fi; 388 if BelongsToAffineSemigroup(d,a1) and 389 BelongsToAffineSemigroup(d,a2) then 390 return AffineSemigroup(Concatenation(g1,g2)); 391 fi; 392 return fail; 393 394end); 395 396###################### ContejeanDevieAlgorithm 397 398############################################################################################# 399# l contains the list of coefficients of a system of linear equations. forten gives the 400# set of minimal generators of the affine semigroup of nonnegative soultions of this equation 401############################################################################################## 402InstallMethod(HilbertBasisOfSystemOfHomogeneousEquations, 403 "Computes the Hilbert basis of a system of linear Diophantine equations, some evetually in congruences.",[IsRectangularTable,IsHomogeneousList],1, 404 function(ls,md) 405 local contejeanDevieAlgorithm, contejeanDevieAlgorithmWithCongruences, leq; 406 407 ## local functions ... 408 #less than or equal to with the usual partial order 409 leq:= function(v1,v2) 410 local v; 411 v:=v2-v1; 412 return (First(v,n->n<0)=fail); 413 end; 414 415 contejeanDevieAlgorithm:= function(l) 416 local solutions, m, x, explored, candidates, tmp, k,zero, lx; 417 418 419 Info(InfoNumSgps,2,"Using Contejean and Devie algorithm."); 420 421 422 solutions:=[]; 423 explored:=[]; 424 425 #if not(IsRectangularTable(l)) then 426 # Error("The argument must be a matrix."); 427 #fi; 428 if not(IsInt(l[1][1])) then 429 Error("The matrix must be of integers."); 430 fi; 431 432 433 m:=IdentityMat(Length(l[1])); 434 zero:=List([1..Length(l)],_->0); 435 candidates:=m; 436 while (not(candidates=[])) do 437 x:=candidates[1]; 438 explored:=Union([x],explored); 439 candidates:=candidates{[2..Length(candidates)]}; 440 lx:=l*x; 441 if(lx=zero) then 442 solutions:=Union([x],solutions); 443 # Print(x); 444 else 445 tmp:=Set(Filtered(m,n->(lx*(l*n)<0)),y->y+x); 446 tmp:=Difference(tmp,explored); 447 tmp:=Filtered(tmp,n->(First(solutions,y->leq(y,n))=fail)); 448 candidates:=Union(candidates,tmp); 449 fi; 450 od; 451 return solutions; 452 end; 453 454 contejeanDevieAlgorithmWithCongruences:=function(ls,md) 455 local l,n,m,diag,dim,d, hil, zero; 456 457 #if not(IsRectangularTable(ls)) then 458 # Error("The first argument must be a matrix."); 459 #fi; 460 461 if not(IsListOfIntegersNS(md)) or ForAny(md, x->not(IsPosInt(x))) then 462 Error("The second argument must be a list of positive integers."); 463 fi; 464 465 n:=Length(ls); 466 dim:=Length(ls[1]); 467 m:=Length(md); 468 if m>n then 469 Error("There are more modulus than equations."); 470 fi; 471 472 diag:=Concatenation(md,List([1..n-m],_->0)); 473 d:=DiagonalMat(diag); 474 l:=TransposedMat(Concatenation(TransposedMat(ls),d,-d)); 475 zero:=List([1..dim],_->0); 476 477 hil:=Difference(List(contejeanDevieAlgorithm(l), x->x{[1..dim]}),[zero]); 478 return hil; 479 480 #return Filtered(hil, y->Filtered(hil,x->leq(x,y))=[y]); 481 end; 482 ## end of local functions ... 483 Info(InfoNumSgps,1,"Using contejeanDevieAlgorithm for Hilbert Basis. Please, consider using NormalizInterface, 4ti2Interface or 4ti2gap."); 484 #ls := arg[1][1]; 485 #md := arg[1][2]; 486 if md = [] then 487 return contejeanDevieAlgorithm(ls); 488 else 489 return contejeanDevieAlgorithmWithCongruences(ls,md); 490 491 fi; 492end); 493 494############################################################################################## 495# 496# ls is a matrix of integers. It computes the set minimal nonzero nonnegative integer solutions 497# of ls*x>=0 498# 499InstallMethod(HilbertBasisOfSystemOfHomogeneousInequalities, 500 "Computes the Hilbert basis of a set of inequalities", 501 [IsRectangularTable],1, 502 function(ls) 503 local mat, neq, dim, id, hil,zero ; 504 #if not(IsRectangularTable(ls)) then 505 # Error("The argument must be a matrix."); 506 #fi; 507 if not(IsInt(ls[1][1])) then 508 Error("The matrix must be of integers."); 509 fi; 510 511 neq:=Length(ls); 512 dim:=Length(ls[1]); 513 zero:=List([1..dim],_->0); 514 515 id:=IdentityMat(neq); 516 mat:=TransposedMat(Concatenation(TransposedMat(ls),-id)); 517 hil:=HilbertBasisOfSystemOfHomogeneousEquations(mat,[]); 518 return List(hil,x->x{[1..dim]}); 519 520 521end); 522 523######################################################################## 524# Computes the set of factorizations of v in terms of the elements of ls 525# That is, a Hilbert basis for ls*X=v 526# If ls contains vectors that generate a nonreduced monoid, then it 527# may enter in an infinite loop 528######################################################################## 529InstallMethod(FactorizationsVectorWRTList, 530 "Computes the set of factorizations of the first argument in terms of the elements of the second", 531 [IsHomogeneousList, IsMatrix],1, 532 function(v,ls) 533 local len, e1, opt1, opt2, i, mat, dim; 534 # REQUERIMENTS: NormalizInterface 535 #if NumSgpsCanUseNI then 536 # TryNextMethod(); 537 #fi; 538 539 mat:=TransposedMat(Concatenation(ls,[-v])); 540 541 if not(IsListOfIntegersNS(v)) then 542 Error("The first argument must be a list of integers."); 543 fi; 544 545 if not(ForAll(ls,IsListOfIntegersNS)) then 546 Error("The second argument must be a list of lists of integers."); 547 fi; 548 549 if not(IsRectangularTable(mat)) then 550 Error("The list in the second argument must have the same length as the lists in the first argument."); 551 fi; 552 553 len:=Length(ls); 554 if ls=[] then 555 return []; 556 fi; 557 if ForAll(v,x->x=0) then 558 return [List([1..len],_->0)]; 559 fi; 560 if ForAny(v,x->x<0) then 561 return []; 562 fi; 563 564 if Length(ls)=1 then 565 dim:=Length(ls[1]); 566 567 i:=First([1..dim],x->ls[1][x]<>0); 568 569 if i=fail then 570 Error("The second argument cannot contain the zero vector."); 571 fi; 572 if (v[i] mod ls[1][i]=0) and v=v[i]/ls[1][i]*ls[1] then 573 return [ [v[i]/ls[1][i]] ]; 574 fi; 575 return []; 576 fi; 577 e1:=List([1..len-1],_->0); 578 e1:=Concatenation([1],e1); 579 opt1:=[]; 580 if ForAll(v-ls[1],x->x>=0) then 581 opt1:=List(FactorizationsVectorWRTList(v-ls[1],ls), x->x+e1); 582 fi; 583 opt2:=List(FactorizationsVectorWRTList(v,ls{[2..len]}), 584 x->Concatenation([0],x)); 585# return Concatenation(opt1,opt2); 586 return Union(opt1,opt2); 587end); 588 589############################################################################### 590#O Factorizations 591# Vactorizations of a vector in terms of the minimal generating set of the 592# affine semigroup 593######################################################################## 594InstallMethod(Factorizations, 595 "factorizations of an element in terms of the generators of the affine semigroup", 596 [IsHomogeneousList,IsAffineSemigroup], 597 function(n,a) 598 local fac,gen; 599 if not(n in a) then 600 Error("The first argument is not an element of the second"); 601 fi; 602 gen:=MinimalGeneratingSystem(a); 603 fac:=FactorizationsVectorWRTList(n,gen); 604 return fac; 605 end); 606 607InstallMethod(Factorizations, 608 "factorizations of an element in terms of the generators of the affine semigroup", 609 [IsAffineSemigroup,IsHomogeneousList], 610 function(a,n) 611 local fac,gen; 612 if not(n in a) then 613 Error("The second argument is not an element of the first"); 614 fi; 615 gen:=MinimalGeneratingSystem(a); 616 fac:=FactorizationsVectorWRTList(n,gen); 617 return fac; 618 end); 619 620 621############################################################ 622# computes a set of generators of the kernel congruence 623# of the monoid morphism associated to the matrix m with 624# nonnegative integer coefficients 625############################################################ 626InstallMethod(GeneratorsOfKernelCongruence, 627 "Computes a set of generators of the kernel congruence of the monoid morphism associated to a matrix", 628 [IsRectangularTable],1, 629 function( m ) 630 631 local i, p, rel, rgb, msg, pol, ed, monomial, candidates, mp, 632 R,id, ie, vars, mingen, exps, bintopair, dim, zero, gen, 633 pres,c, rclass; 634 635 # REQUERIMENTS: SingularInterface or Singular 636 #if NumSgpsCanUseSI or NumSgpsCanUseSingular then 637 # TryNextMethod(); 638 #fi; 639 640 bintopair:=function(p) 641 local m1,m2, d1, d2; 642 m1:=LeadingMonomialOfPolynomial(p, MonomialLexOrdering()); 643 m2:=m1-p; 644 d1:=List([1..ed], i->DegreeIndeterminate(m1,i));; 645 d2:=List([1..ed], i->DegreeIndeterminate(m2,i));; 646 return Set([d1,d2]); 647 end; 648 649 if not(ForAll(m, l->ForAll(l, x->(x=0) or IsPosInt(x)))) then 650 Error("The argument must be a matrix of nonnegative integer."); 651 fi; 652 653 msg:=ShallowCopy(m); 654 ed:=Length(msg); 655 if ed=0 then 656 return []; 657 fi; 658 zero:=List([1..ed],_->0); 659 dim:=Length(msg[1]); 660 vars:=List([1..ed+dim],i->X(Rationals,i)); 661 R:=PolynomialRing(Rationals,vars); 662 p:=List([1..ed], i->X(Rationals,i)- 663 Product(List([1..dim], j->X(Rationals,j+ed)^msg[i][j]))); 664 rgb:=ReducedGroebnerBasis( p, 665 EliminationOrdering(List([1..dim],i->X(Rationals,i+ed)))); 666 rgb:=Filtered(rgb, 667 q->ForAll([1..dim], i->DegreeIndeterminate(q,i+ed)=0)); 668 candidates:=Set(rgb,q->bintopair(q)); 669 return candidates; 670end); 671 672############################################################ 673# computes a canonical basis of the kernel congruence 674# of the monoid morphism associated to the matrix m with 675# nonnegative integer coefficients wrt the term ordering 676# the kernel is the pairs (x,y) such that xm=ym 677############################################################ 678InstallMethod(CanonicalBasisOfKernelCongruence, 679 "Computes a canonical basis for the congruence of of the monoid morphism associated to the matrix", 680 [IsRectangularTable, IsMonomialOrdering],1, 681 function( m, ord ) 682 683 local i, p, rel, rgb, msg, pol, ed, monomial, candidates, mp, 684 R,id, ie, vars, mingen, exps, bintopair, dim, zero, gen, 685 pres,c, rclass; 686 687 688 bintopair:=function(p) 689 local m1,m2, d1, d2; 690 m1:=LeadingMonomialOfPolynomial(p, ord); 691 m2:=m1-p; 692 d1:=List([1..ed], i->DegreeIndeterminate(m1,i));; 693 d2:=List([1..ed], i->DegreeIndeterminate(m2,i));; 694 return [d1,d2]; 695 end; 696 697 if not(ForAll(m, l->ForAll(l, x->(x=0) or IsPosInt(x)))) then 698 Error("The argument must be a matrix of nonnegative integers."); 699 fi; 700 701 msg:=ShallowCopy(m); 702 ed:=Length(msg); 703 if ed=0 then 704 return []; 705 fi; 706 zero:=List([1..ed],_->0); 707 dim:=Length(msg[1]); 708 vars:=List([1..ed+dim],i->X(Rationals,i)); 709 R:=PolynomialRing(Rationals,vars); 710 p:=List([1..ed], i->X(Rationals,i)- 711 Product(List([1..dim], j->X(Rationals,j+ed)^msg[i][j]))); 712 rgb:=ReducedGroebnerBasis( p, 713 EliminationOrdering(List([1..dim],i->X(Rationals,i+ed)))); 714 rgb:=Filtered(rgb, 715 q->ForAll([1..dim], i->DegreeIndeterminate(q,i+ed)=0)); 716 if rgb = [] then 717 return []; 718 fi; 719 rgb:=ReducedGroebnerBasis(rgb,ord); 720 candidates:=Set(rgb,q->bintopair(q)); 721 return candidates; 722end); 723 724############################################################ 725# computes the Graver basis of matrix with integer entries 726############################################################ 727InstallMethod(GraverBasis, 728 "Computes the Graver basis of the matrix", 729 [IsRectangularTable],1, 730function(a) 731 #PLAIN implementation 732 local msg, mgs, ed, dim, prlft, lft,zero, zeroes, id, aid, zeroid; 733 734 if not(IsInt(a[1][1])) then 735 Error("The entries of the matrix must be integers."); 736 fi; 737 Info(InfoNumSgps,1,"Using Lawrence lifting for computing Graver Basis. Please, consider using NormalizInterface, 4ti2Interface or 4ti2gap."); 738 mgs:=TransposedMat(a); 739 ed:=Length(mgs); 740 dim:=Length(mgs[1]); 741 #lft:=LawrenceLiftingOfAffineSemigroup(a); 742 #prlft:=MinimalPresentationOfAffineSemigroup(lft); 743 id:=IdentityMat(ed); 744 zero:=List([1..ed],_->0); 745 zeroes:=List([1..dim],_->zero); 746 747 msg:=TransposedMat(mgs); 748 aid:=TransposedMat(Concatenation(msg,id)); 749 zeroid:=TransposedMat(Concatenation(zeroes,id)); 750 751 lft:=(Concatenation(aid,zeroid)); 752 prlft:=GeneratorsOfKernelCongruence(lft); 753 Info(InfoNumSgps,2,"The kernel congruence is ", prlft); 754 prlft:=Filtered(prlft, p->p[1]<>p[2]); 755 return Set(Union(prlft), p->p{[1..ed]}-p{[ed+1..ed+ed]}); 756end); 757 758############################################################ 759# computes a minimal presentation of a 760############################################################ 761InstallMethod(MinimalPresentationOfAffineSemigroup, 762 "Computes the minimal presentation of an affine semigroup", 763 [IsAffineSemigroup],1, 764 function( a ) 765 766 local i, p, rel, rgb, msg, pol, ed, monomial, candidates, mp, 767 R,id, ie, vars, mingen, exps, bintopair, dim, zero, gen, 768 pres,c, rclass; 769 770 msg:=MinimalGenerators(a); 771 ed:=Length(msg); 772 if ed=0 then 773 return []; 774 fi; 775 dim:=Length(msg[1]); 776 candidates:=GeneratorsOfKernelCongruence(msg); 777 candidates:=Set(candidates,c->c[1]*msg); 778 Info(InfoNumSgps,2, "Candidates to Betti elements",candidates); 779 pres:=[]; 780 for c in candidates do 781 exps:=FactorizationsVectorWRTList(c,msg); 782 rclass:=RClassesOfSetOfFactorizations(exps); 783 if Length(rclass)>1 then 784 pres:=Concatenation(pres,List([2..Length(rclass)], 785 i->Set([rclass[1][1],rclass[i][1]]))); 786 fi; 787 od; 788 return pres; 789end); 790 791InstallMethod(MinimalPresentation, 792"Computes the minimal presentation of an affine semigroup", 793[IsAffineSemigroup], 794MinimalPresentationOfAffineSemigroup 795); 796 797################################################################### 798# Betti elements of the affine semigroup a 799################################################################### 800InstallMethod(BettiElements, 801 "Computes the Betti elements of an affine semigroup", 802 [IsAffineSemigroup],1, 803 function(a) 804 local msg, pr; 805 806 msg:=MinimalGenerators(a); 807 808 pr:=MinimalPresentationOfAffineSemigroup(a); 809 810 return Set(pr, p->p[1]*msg); 811 812end); 813 814 815############################################################################# 816## 817#P IsUniquelyPresentedAffineSemigroup(a) 818## 819## For an affine semigroup a, checks it it has a unique minimal presentation 820## Based in GS-O 821## 822############################################################################# 823InstallMethod(IsUniquelyPresented, 824 "Tests if the affine semigroup S has a unique minimal presentation", 825 [IsAffineSemigroup],1, 826 function(a) 827 local gs; 828 gs:=MinimalGenerators(a); 829 return ForAll(BettiElementsOfAffineSemigroup(a), 830 b->Length(FactorizationsVectorWRTList(b,gs))=2); 831end); 832 833############################################################################# 834## 835#P IsGenericAffineSemigroup(a) 836## 837## For an affine semigroup a, checks it it has a generic presentation, 838## that is, in every relation all generators appear. 839## These semigroups are uniquely presented; see B-GS-G. 840## 841############################################################################# 842InstallMethod(IsGenericAffineSemigroup, 843 "Tests if the affine semigroup S has a generic presentation", 844 [IsAffineSemigroup],1, 845 function(a) 846 local mp; 847 mp:=MinimalPresentationOfAffineSemigroup(a); 848 return ForAll(mp,p->Product(p[1]+p[2])<>0); 849end); 850 851InstallTrueMethod(IsUniquelyPresentedAffineSemigroup, IsGenericAffineSemigroup); 852 853############################################################################# 854## 855#F ShadedSetOfElementInAffineSemigroup(x,a) 856## computes the shading set of x in a as defined in 857## - Székely, L. A.; Wormald, N. C. Generating functions for the Frobenius problem 858## with 2 and 3 generators. Math. Chronicle 15 (1986), 49–57. 859############################################################################# 860InstallGlobalFunction(ShadedSetOfElementInAffineSemigroup, function(x,a) 861 862 local msg; 863 864 if not IsAffineSemigroup(a) then 865 Error("The second argument must be an affine semigroup.\n"); 866 fi; 867 868 if not ( x in a ) then 869 Error("The first argument must be an element of the second.\n"); 870 fi; 871 872 msg:=MinimalGenerators(a); 873 return Filtered(Combinations(msg), c-> (x-Sum(c)) in a); 874end); 875 876############################################################################### 877#F DeltaSetOfAffineSemigroup 878# Computes the Delta set of the affine semigroup a 879# uses the algorithm presented in [GSONW] 880########################################################################### 881InstallGlobalFunction(DeltaSetOfAffineSemigroup, 882 function(a) 883 884 local p, msg, candidates, zero, hgens, m; 885 886 if not(IsAffineSemigroup(a)) then 887 Error("The argument must be an affine semigroup"); 888 fi; 889 890 m:=MinimalGenerators(a); 891 892 if Length(m)=0 then 893 return []; 894 fi; 895 zero:=List([1..Length(m[1])],_->0); 896 msg:=List(Union(m,[zero]), x->Concatenation([1],x)); 897 candidates:=Set(CanonicalBasisOfKernelCongruence(msg, MonomialLexOrdering()), l->l[1][1]); 898 RemoveSet(candidates,0); 899 return candidates; 900 end); 901 902InstallMethod(DeltaSet, 903 "for affine semigroups", 904 [IsAffineSemigroup], 905 DeltaSetOfAffineSemigroup); 906 907###################################################################### 908# Computes the catenary degree of the affine semigroup a 909###################################################################### 910InstallGlobalFunction(CatenaryDegreeOfAffineSemigroup, 911 function(a) 912 local betti, b, max, c, ls; 913 if not(IsAffineSemigroup(a)) then 914 Error("The argument must be an affine semigroup"); 915 fi; 916 917 ls:=MinimalGenerators(a); 918 919 Info(InfoNumSgps,2,"Computing the Betti elements of the affine semigroup."); 920 betti:=BettiElementsOfAffineSemigroup(a); 921 Info(InfoNumSgps,2,"The Betti elements are ",betti); 922 max:=0; 923 for b in betti do 924 Info(InfoNumSgps,2,"Computing the catenary degree of ",b); 925 c:=CatenaryDegreeOfSetOfFactorizations( 926 FactorizationsVectorWRTList(b,ls)); 927 Info(InfoNumSgps,2,"which equals ",c); 928 if c>max then max:=c; fi; 929 od; 930 return max; 931end); 932 933InstallMethod(CatenaryDegree, 934 "Computes the catenary degree of an affine semigroup", 935 [IsAffineSemigroup], 936 CatenaryDegreeOfAffineSemigroup); 937 938###################################################################### 939# Computes the equal catenary degree of the affine semigroup a 940# uses [GSOSN] 941###################################################################### 942InstallGlobalFunction(EqualCatenaryDegreeOfAffineSemigroup, 943 function(a) 944 local ls, lsh, ah, primeq; 945 946 if not(IsAffineSemigroup(a)) then 947 Error("The argument must be an affine semigroup"); 948 fi; 949 950 ls:=MinimalGenerators(a); 951 lsh:=List(ls, x-> Concatenation(x,[1])); 952 ah:=AffineSemigroup(lsh); 953 primeq:=BettiElementsOfAffineSemigroup(ah); 954 955 return Maximum(Set(primeq, x->CatenaryDegreeOfSetOfFactorizations( 956 FactorizationsVectorWRTList(x,lsh)))); 957 958end); 959 960###################################################################### 961# Computes the homogeneous catenary degree of the affine semigroup a 962# uses [GSOSN] 963###################################################################### 964InstallGlobalFunction(HomogeneousCatenaryDegreeOfAffineSemigroup, 965 function(a) 966 local ls, lsh, ah, primeq, one; 967 968 if not(IsAffineSemigroup(a)) then 969 Error("The argument must be an affine semigroup"); 970 fi; 971 972 ls:=MinimalGenerators(a); 973 if ls=[] then return 0; 974 fi; 975 976 lsh:=List(ls, x-> Concatenation(x,[1])); 977 one:=List(ls[1],_->0); 978 Add(one,1); 979 Add(lsh,one); 980 981 ah:=AffineSemigroup(lsh); 982 primeq:=BettiElementsOfAffineSemigroup(ah); 983 984 return Maximum(Set(primeq, x->CatenaryDegreeOfSetOfFactorizations( 985 FactorizationsVectorWRTList(x,lsh)))); 986 987end); 988 989###################################################################### 990# Computes the monotone catenary degree of the affine semigroup a 991# uses [PH] and Alfredo Sanchez-R.-Navarro thesis 992###################################################################### 993InstallGlobalFunction(MonotoneCatenaryDegreeOfAffineSemigroup, 994 function(a) 995 local ls, lsh, ah, primeq, one, dim; 996 997 if not(IsAffineSemigroup(a)) then 998 Error("The argument must be an affine semigroup"); 999 fi; 1000 1001 ls:=MinimalGenerators(a); 1002 1003 if ls=[] then return 0; 1004 fi; 1005 dim:=Length(ls[1]); 1006 1007 lsh:=List(ls, x-> Concatenation(x,[1])); 1008 one:=List(ls[1],_->0); 1009 Add(one,1); 1010 Add(lsh,one); 1011 1012 ah:=AffineSemigroup(lsh); 1013 primeq:=DegreesOfPrimitiveElementsOfAffineSemigroup(ah); 1014 primeq:=Set(primeq, x->x{[1..dim]}); 1015 1016 return Maximum(Set(primeq, x->MonotoneCatenaryDegreeOfSetOfFactorizations( 1017 FactorizationsVectorWRTList(x,ls)))); 1018 1019end); 1020 1021 1022############################################################################### 1023## 1024#O OmegaPrimalityOfElementInAffineSemigroup 1025# 1026# Computes the omega-primality of v in the monoid a 1027########################################################################### 1028InstallMethod(OmegaPrimalityOfElementInAffineSemigroup, 1029 "Computes the omega-primality of x in the monoid s", 1030 [IsHomogeneousList,IsAffineSemigroup],1, 1031 function(x,s) 1032 1033 local i, j, p, rel, rgb, msg, pol, ed, degree, monomial, facts, fact, mp,id, reduce, nonnegative, 1034 mu1,A,B,C, lt, tl, exp, new; 1035 1036 msg:=MinimalGenerators(s); 1037 ed:=Length(msg); 1038 mp:=MinimalPresentationOfAffineSemigroup(s); 1039 p := []; 1040 # list of exponents to monomial 1041 monomial:=function(l) 1042 local i; 1043 pol:=1; 1044 for i in [1..ed] do 1045 pol:=pol*Indeterminate(Rationals,i)^l[i]; 1046 od; 1047 return pol; 1048 end; 1049 ## monomial to exponents 1050 exp:=function(mon) 1051 return List([1..ed],i-> DegreeIndeterminate(mon,i)); 1052 end; 1053 ##computes the degree of a monomial 1054 degree:=function(mon) 1055 return Sum(exp(mon)); 1056 end; 1057 ##nonnegative 1058 nonnegative:=function(l) 1059 return ForAll(l, x-> x>=0); 1060 end; 1061 1062 for rel in mp do 1063 Add( p, monomial(rel[1])-monomial(rel[2])); 1064 od; 1065 1066 facts:=FactorizationsVectorWRTList(x,msg); 1067 if facts=[] then 1068 return 0; 1069 fi; 1070 Info(InfoNumSgps,2,"Factorizations of the element :", facts); 1071 fact:=facts[Length(facts)]; 1072 id:=IdentityMat(ed); 1073 1074 for i in [1..ed] do 1075 Add(p,monomial(fact+id[i])-monomial(fact)); 1076 od; 1077 1078 # for j in [2..Length(facts)] do 1079 # for i in [1..ed] do 1080 # Add(p,monomial(facts[j]+id[i])-monomial(facts[j])); 1081 # od; 1082 # od; 1083 1084 Info(InfoNumSgps,2,"Computing a Groebner basis"); 1085 #a canonical system of generators of sigma_I 1086 rgb := ReducedGroebnerBasis( p, MonomialGrevlexOrdering() ); 1087 1088 1089 #normal form wrt rgb 1090 reduce:=function(r) 1091 return PolynomialReducedRemainder(r,rgb, MonomialGrevlexOrdering()); 1092 end; 1093 1094 #leading term 1095 lt:=function(r) 1096 return LeadingMonomialOfPolynomial(r,MonomialGrevlexOrdering()); 1097 end; 1098 1099 #tail 1100 tl:=function(r) 1101 return lt(r)-r; 1102 end; 1103 1104 mu1:=reduce(monomial(fact)); 1105 #A:=Set([mu1]); 1106 A:=Union(Set([mu1]),Set(facts,monomial)); 1107 1108 Info(InfoNumSgps,2,"Computing minimal elements of the ideal."); 1109 while true do 1110 B:=[]; 1111 for i in A do 1112 for rel in rgb do 1113 new:=Lcm(i,tl(rel))/tl(rel)*lt(rel); 1114 if First(A, a->nonnegative(exp(new)-exp(a)))=fail then 1115 AddSet(B,new); 1116 Info(InfoNumSgps,2,"New possible minimal element: ",exp(new)); 1117 fi; 1118 od; 1119 od; 1120 if IsSubset(A,B) then 1121 A:=Filtered(A, i->First(Difference(A,[i]), j-> nonnegative(exp(i)-exp(j)))=fail); 1122 return Maximum(Set(Set(A,exp),Sum)); 1123 fi; 1124 A:=Union(A,B); 1125 od; 1126end); 1127 1128InstallMethod(OmegaPrimality, 1129 "for an element in an affine semigroup", 1130 [IsHomogeneousList,IsAffineSemigroup], 1131 OmegaPrimalityOfElementInAffineSemigroup); 1132 1133 1134InstallMethod(OmegaPrimality, 1135 "for an element in an affine semigroup", 1136 [IsAffineSemigroup,IsHomogeneousList], 1137 function(a,l) 1138 return OmegaPrimalityOfElementInAffineSemigroup(l,a); 1139 end); 1140 1141 1142###################################################################### 1143# Computes the omega primality of the affine semigroup a 1144###################################################################### 1145InstallGlobalFunction(OmegaPrimalityOfAffineSemigroup, 1146 function(a) 1147 local ls; 1148 1149 if not(IsAffineSemigroup(a)) then 1150 Error("The argument must be an affine semigroup"); 1151 fi; 1152 1153 ls:=MinimalGenerators(a); 1154 return Maximum(Set(ls, v-> OmegaPrimalityOfElementInAffineSemigroup(v,a))); 1155end); 1156 1157InstallMethod(OmegaPrimality, 1158 "for affine semigroups", 1159 [IsAffineSemigroup], 1160 OmegaPrimalityOfAffineSemigroup); 1161 1162############################################################################# 1163## 1164#F ElasticityOfFactorizationsElementWRTAffineSemigroup(n,s) 1165## 1166## Computes the quotient (maximum length)/(minimum lenght) of the 1167## factorizations of an element <n> as linear combinations 1168## with nonnegative coefficients of the minimal generators 1169## of the semigroup <s>. 1170## 1171############################################################################# 1172InstallGlobalFunction(ElasticityOfFactorizationsElementWRTAffineSemigroup, function(n,s) 1173 local gen,max,min,lenfact; 1174 1175 if not IsAffineSemigroup(s) then 1176 Error("The second argument must be an affine semigroup.\n"); 1177 fi; 1178 1179 if not IsListOfIntegersNS(n) then 1180 Error("The first argument must be a list of integers.\n"); 1181 fi; 1182 1183 if not (n in s) then 1184 Error("The first argument does not belong to the second.\n"); 1185 fi; #this ensures that the lengths won't be zero 1186 1187 gen:=MinimalGeneratingSystem(s); 1188 lenfact:=Set(FactorizationsVectorWRTList(n,gen),Sum); 1189 min:=Minimum(lenfact); 1190 max:=Maximum(lenfact); 1191 if min=0 then 1192 Error("The element seems to be the zero vector.\n"); 1193 fi; 1194 1195 return max/min; 1196end); 1197 1198InstallMethod(Elasticity, 1199 "Elasticity of the factorizations of an element in an affine semigroup", 1200 [IsHomogeneousList,IsAffineSemigroup], 1201 ElasticityOfFactorizationsElementWRTAffineSemigroup); 1202 1203InstallMethod(Elasticity, 1204 "Elasticity of the factorizations in an affine semigroup of one of its elements", 1205 [IsAffineSemigroup, IsHomogeneousList], 1206 function(a,v) 1207 return ElasticityOfFactorizationsElementWRTAffineSemigroup(v,a); 1208 end); 1209 1210 1211##################################################################### 1212# Computes the elasticity of the affine semigroup a 1213##################################################################### 1214InstallGlobalFunction(ElasticityOfAffineSemigroup, 1215 function(s) 1216 1217 local gens, positive, negative, cir, el,a, elt, 1218 cols,rows, e, comb, c, i, circ,mat, matt, sum, sp, sn; 1219 1220 # computes x^+ 1221 positive:=function(x) 1222 local p,i; 1223 1224 p:=[]; 1225 for i in [1..Length(x)] do 1226 p[i]:=Maximum(x[i],0); 1227 od; 1228 1229 return p; 1230 end; 1231 1232 # computes x^- 1233 negative:=function(x) 1234 local p,i; 1235 1236 p:=[]; 1237 for i in [1..Length(x)] do 1238 p[i]:=-Minimum(x[i],0); 1239 od; 1240 1241 return p; 1242 end; 1243 1244 1245 if not(IsAffineSemigroup(s)) then 1246 Error("The argument must be an affine semigroup."); 1247 fi; 1248 gens:=MinimalGenerators(s); 1249 a:=TransposedMat(gens); 1250 el:=1; 1251 #we compute the circuits as explained in Eisenbud-Sturmfels Lemma 8.8 1252 rows:=Length(a); 1253 cols:=Length(a[1]); 1254 e:=IdentityMat(cols); 1255 mat:=TransposedMat(a); 1256 comb:=IteratorOfCombinations([1..cols],rows+1); 1257 #Print("Combinations ",comb,"\n"); 1258 Info(InfoNumSgps,2,"Running over ",NrCombinations([1..cols],rows+1)," combinations to compute circuits"); 1259 for c in comb do 1260 sum:=0; 1261 for i in [1..rows+1] do 1262 matt:=mat{Difference(c,[c[i]])}; 1263 #Print("c ",c," da ",matt,"\n"); 1264 sum:=sum+(-1)^(i+1)*DeterminantIntMat(matt)*e[c[i]]; 1265 od; 1266 if ForAny(sum, x->x<>0) then 1267 sum:=sum/Gcd(sum); 1268 sp:=Sum(positive(sum)); 1269 sn:=Sum(negative(sum)); 1270 if sp>=sn then 1271 elt:=sp/sn; 1272 else 1273 elt:=sn/sp; 1274 fi; 1275 if elt>el then 1276 Info(InfoNumSgps,2, "new elasticity reached ", elt); 1277 el:=elt; 1278 fi; 1279 fi; 1280 od; 1281 1282 return el; 1283end); 1284 1285InstallMethod(Elasticity, 1286 "Computes the elasticity of an affine semigroup", 1287 [IsAffineSemigroup], 1288 ElasticityOfAffineSemigroup 1289 ); 1290 1291################################################################### 1292#lawrence Lifting 1293################################################################### 1294InstallGlobalFunction(LawrenceLiftingOfAffineSemigroup,function(a) 1295 local dim,ed, msg, id, lft, zero, zeroes, aid, zeroid; 1296 1297 if not(IsAffineSemigroup(a)) then 1298 Error("The argument must be an affine semigroup."); 1299 fi; 1300 1301 msg:=MinimalGenerators(a); 1302 ed:=Length(msg); 1303 dim:=Length(msg[1]); 1304 id:=IdentityMat(ed); 1305 zero:=List([1..ed],_->0); 1306 zeroes:=List([1..dim],_->zero); 1307 1308 msg:=TransposedMat(msg); 1309 aid:=TransposedMat(Concatenation(msg,id)); 1310 zeroid:=TransposedMat(Concatenation(zeroes,id)); 1311 1312 1313 1314 lft:=(Concatenation(aid,zeroid)); 1315 return AffineSemigroup(lft); 1316end); 1317 1318##################################################### 1319# Degrees of primitive elements with Lawrence lifting 1320##################################################### 1321InstallMethod(DegreesOfPrimitiveElementsOfAffineSemigroup, 1322 "Computes the set of primitive elements of an affine semigroup", 1323 [IsAffineSemigroup],1, 1324 function(a) 1325 local msg, mgs, ed, dim, prlft, lft,zero, zeroes, id, aid, zeroid; 1326 1327 Info(InfoNumSgps,2,"Using Lawrence lifting for computing primitive elements."); 1328 mgs:=MinimalGenerators(a); 1329 ed:=Length(mgs); 1330 dim:=Length(mgs[1]); 1331 #lft:=LawrenceLiftingOfAffineSemigroup(a); 1332 #prlft:=MinimalPresentationOfAffineSemigroup(lft); 1333 id:=IdentityMat(ed); 1334 zero:=List([1..ed],_->0); 1335 zeroes:=List([1..dim],_->zero); 1336 1337 msg:=TransposedMat(mgs); 1338 aid:=TransposedMat(Concatenation(msg,id)); 1339 zeroid:=TransposedMat(Concatenation(zeroes,id)); 1340 1341 lft:=(Concatenation(aid,zeroid)); 1342 prlft:=GeneratorsOfKernelCongruence(lft); 1343 Info(InfoNumSgps,2,"The kernel congruence is ", prlft); 1344 1345 return Union(Set(prlft, p->(p[1]{[ed+1..ed+ed]})*mgs),mgs); 1346end); 1347 1348##################################################################### 1349# Computes the tame degree of the affine semigroup a 1350##################################################################### 1351InstallMethod(TameDegreeOfAffineSemigroup, 1352 "Computes the tame degree of an affine semigroup", 1353 [IsAffineSemigroup],1, 1354 function(a) 1355 local prim, tams, p, max, ls; 1356 1357 ls:=MinimalGenerators(a); 1358 1359 Info(InfoNumSgps,2,"Computing primitive elements of ", ls); 1360 prim:=DegreesOfPrimitiveElementsOfAffineSemigroup(a); 1361 Info(InfoNumSgps,2,"Primitive elements of ", ls, ": ",prim); 1362 max:=0; 1363 for p in prim do 1364 Info(InfoNumSgps,2,"Computing the tame degree of ",p); 1365 tams:=TameDegreeOfSetOfFactorizations( 1366 FactorizationsVectorWRTList(p,ls)); 1367 Info(InfoNumSgps,2,"The tame degree of ",p, " is ",tams); 1368 if tams>max then 1369 max:=tams; 1370 fi; 1371 od; 1372 return max; 1373end); 1374 1375InstallMethod(TameDegree, 1376 "Tame degree for affine semigroups", 1377 [IsAffineSemigroup], 1378 TameDegreeOfAffineSemigroup); 1379 1380############################################################################### 1381## 1382########################################################################## 1383## 1384#F NumSgpsUseNormaliz 1385# Loads the package NormalizInterface and reads affine-extra-ni 1386########################################################################## 1387InstallGlobalFunction(NumSgpsUseNormaliz, function() 1388 if LoadPackage("NormalizInterface")=true then 1389 ReadPackage("numericalsgps", "gap/affine-extra-ni.gi"); 1390 NumSgpsCanUseNI:=true; 1391 return true; 1392 else 1393 return fail; 1394 fi; 1395 1396end); 1397 1398 1399########################################################################## 1400## 1401#F NumSgpsUseSingular 1402# Loads the package singular and reads affine-extra-s 1403########################################################################## 1404InstallGlobalFunction(NumSgpsUseSingular, function() 1405 if IsPackageMarkedForLoading("SingularInterface","0.0") then 1406 Print("SingularInterface is already loaded and it is incompatible with Singular.\n"); 1407 return fail; 1408 fi; 1409 1410 if NumSgpsCanUseSingular then 1411 return true; 1412 fi; 1413 1414 if LoadPackage("singular")=true then 1415 ReadPackage("numericalsgps", "gap/affine-extra-s.gi"); 1416 ReadPackage("numericalsgps", "gap/polynomials-extra-s.gd"); 1417 ReadPackage("numericalsgps", "gap/polynomials-extra-s.gi"); 1418 NumSgpsCanUseSingular:=true; 1419 if NumSgpsCanUse4ti2 then 1420 ReadPackage("numericalsgps","gap/apery-extra-4ti2i-sing.gi"); 1421 fi; 1422 return true; 1423 else 1424 return fail; 1425 fi; 1426 1427end); 1428 1429########################################################################## 1430## 1431#F NumSgpsUseSingularInterface 1432# Loads the package SingularInterface and reads affine-extra-si 1433########################################################################## 1434InstallGlobalFunction(NumSgpsUseSingularInterface, function() 1435 if IsPackageMarkedForLoading("Singular","0.0") then 1436 Print("Singular is already loaded and it is incompatible with SingularInterface.\n"); 1437 return fail; 1438 fi; 1439 1440 if LoadPackage("SingularInterface")=true then 1441 ReadPackage("numericalsgps", "gap/affine-extra-si.gi"); 1442 NumSgpsCanUseSI:=true; 1443 return true; 1444 else 1445 return fail; 1446 fi; 1447 1448end); 1449 1450########################################################################## 1451## 1452#F NumSgpsUse4ti2 1453# Loads the package 4ti2Interface and reads affine-extra-4ti2 1454########################################################################## 1455InstallGlobalFunction(NumSgpsUse4ti2, function() 1456 if LoadPackage("4ti2Interface")=true then 1457 ReadPackage("numericalsgps", "gap/affine-extra-4ti2.gi"); 1458 ReadPackage("numericalsgps", "gap/frobenius-extra-4ti2i.gi"); 1459 if NumSgpsCanUseSingular then 1460 ReadPackage("numericalsgps","gap/apery-extra-4ti2i-sing.gi"); 1461 fi; 1462 NumSgpsCanUse4ti2:=true; 1463 return true; 1464 else 1465 return fail; 1466 fi; 1467 1468end); 1469 1470########################################################################## 1471## 1472#F NumSgpsUse4ti2gap 1473# Loads the package 4ti2gap and reads affine-extra-4ti2gap 1474########################################################################## 1475InstallGlobalFunction(NumSgpsUse4ti2gap, function() 1476 if LoadPackage("4ti2gap")=true then 1477 ReadPackage("numericalsgps", "gap/affine-extra-4ti2gap.gi"); 1478 ReadPackage("numericalsgps", "gap/frobenius-extra-4ti2gap.gi"); 1479 NumSgpsCanUse4ti2gap:=true; 1480 return true; 1481 else 1482 return fail; 1483 fi; 1484 1485end); 1486 1487########################################################################## 1488## 1489#F NumSgpsUseGradedModules 1490# Loads the package GradedModules and reads affine-extra-gm 1491########################################################################## 1492InstallGlobalFunction(NumSgpsUseGradedModules, function() 1493 if LoadPackage("GradedModules")=true then 1494 ReadPackage("numericalsgps", "gap/affine-extra-gm.gi"); 1495 NumSgpsCanUseGradedModules:=true; 1496 return true; 1497 else 1498 return fail; 1499 fi; 1500 1501end); 1502