Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  affine.gi   Sprache: unbekannt

 
#############################################################################
##
#W  affine.gi           Manuel Delgado <mdelgado@fc.up.pt>
#W                      Pedro Garcia-Sanchez <pedro@ugr.es>
##
#Y  Copyright 2015-- Centro de Matemática da Universidade do Porto, Portugal and Universidad de Granada, Spain
#############################################################################
##
#if not TestPackageAvailability("4ti2Interface") = fail then
#    LoadPackage("4ti2");
#fi;
##


# using the parent InfoNumSgps
#InfoAffSgps:=NewInfoClass("InfoAffSgps");;
#SetInfoLevel(InfoAffSgps,1);;


######################################################################
# Computes the set of primitive elements of an affine semigroup, that
# is, the set of elements whose factorizations are involved in the
# minimal generators of the congruence associated to the monod
# (generators as a monoid; not to be confused with minimal presentations
# to this end, use BettiElementsOfAffineSemigroup)
# # REQUERIMENTS: 4ti2Interface
######################################################################

#InstallGlobalFunction(PrimitiveElementsOfAffineSemigroup,function(ls)
#    local dir, filename, exec, filestream, matrix,
#     facs, mat, trunc;# ls;


 #if not(IsAffineSemigroup(a)) then
 # Error("The argument must be an affine semigroup");
 #fi;

 #ls:=GeneratorsAS(a);

#    dir := DirectoryTemporary();
#    filename := Filename( dir, "gap_4ti2_temp_matrix" );
#
# mat:=TransposedMat(ls);
#    4ti2Interface_Write_Matrix_To_File( mat, Concatenation( filename, ".mat" ) );
#    exec := IO_FindExecutable( "graver" );
#    filestream := IO_Popen2( exec, [ filename ]);
#    while IO_ReadLine( filestream.stdout ) <> "" do od;
#    matrix := 4ti2Interface_Read_Matrix_From_File( Concatenation( filename, ".gra" ) );
#
#    trunc:=function(ls)
#  return List(ls, y->Maximum(y,0));
# end;

# matrix:=Set(matrix,trunc);
#    return Set(matrix, x->x*ls);
#end);


#########
#InstallGlobalFunction(ElasticityOfAffineSemigroup,
#        function(ls)
#     local dir, filename, exec, filestream, matrix,
#       mat, truncplus, truncminus;

#  if not(IsHomogeneousList(ls)) then
#   Error("The argument must be a homogeneous list.");
#  fi;

#  if not(ForAll(ls,IsListOfIntegersNS)) then
#   Error("The argument must be a list of lists of integers.");
#  fi;

#  if not(Length(Set(ls, Length))=1) then
#   Error("All lists in the first argument must have the same length.");
#  fi;

#     dir := DirectoryTemporary();
#     filename := Filename( dir, "gap_4ti2_temp_matrix" );

#  mat:=TransposedMat(ls);
#     4ti2Interface_Write_Matrix_To_File( mat, Concatenation( filename, ".mat" ) );
#     exec := IO_FindExecutable( "graver" );
#     filestream := IO_Popen2( exec, [ filename ]);
#     while IO_ReadLine( filestream.stdout ) <> "" do od;
#     matrix := 4ti2Interface_Read_Matrix_From_File( Concatenation( filename, ".gra" ) );

#     truncplus:=function(ls)
#   return Sum(List(ls, y->Maximum(y,0)));
#  end;

#     truncminus:=function(ls)
#   return Sum(List(ls, y->-Minimum(y,0)));
#  end;

#  return Maximum(Set(matrix, y->truncplus(y)/truncminus(y)));
# end);
#####





####################################################################
# Decides if the vector v belongs to the affine semigroup a
#
####################################################################
InstallMethod( \in,
        "for affine semigroups",
        [ IsHomogeneousList, IsAffineSemigroup],
        function( v, a )
    return BelongsToAffineSemigroup(v,a);
end);

InstallMethod(BelongsToAffineSemigroup,
        "To test whether an element of N^n belongs to an affine semigroup",
        true,
        [ IsHomogeneousList, IsAffineSemigroup and HasGenerators],50,

        function(v,a)
    local belongs, gen;

      #determines if an element x is in the affine semigroup
      # spanned by gen
    belongs:=function(x,gen)
 if gen=[] then
            return false;
 fi;

 if ForAll(x,i->i=0) then
            return true;
 fi;

 if ForAny(x,i->i<0) then
            return false;
 fi;

 return belongs(x-gen[1],gen) or belongs(x,gen{[2..Length(gen)]});
    end;

    if not(IsListOfIntegersNS(v)) then
      #Error("The first argument must be a list of integers.");
      return false;
    fi;

    gen:=Generators(a);
    if not(IsRectangularTable(Concatenation(gen,[v]))) then
      #Error("The dimension of the vector and the affine semigroup do not coincide.");
      return false;
    fi;

    return belongs(v,gen);

end);

InstallMethod(BelongsToAffineSemigroup,
        "To test whether a list of elements of N^n belongs to an affine semigroup",
        true,
        [ IsHomogeneousList, IsAffineSemigroup and HasEquations],100,

        function(v,a)
    local equ,eq,md,ev,i;

    equ:=Equations(a);
    if not(IsListOfIntegersNS(v)) then
      #Error("The first argument must be a list of integers.");
      return false;
    fi;
    if ForAny(v,x->x<0) then
        return false;
    fi;

    eq:=equ[1];
    md:=equ[2];
    if Length(eq[1])<>Length(v) then
       # Error("The dimension of the vector and the affine semigroup do not coincide.");
        return false;
    fi;
    ev:=ShallowCopy(eq*v);

    Info(InfoNumSgps,2,"Testing membership with equations.");

    for i in [1..Length(md)] do
        ev[i]:=ev[i] mod md[i];
    od;

    return ForAll(ev,x->x=0);

end);

InstallMethod(BelongsToAffineSemigroup,
        "To test whether a list of elements of N^n belongs to an affine semigroup",
        true,
        [ IsHomogeneousList, IsAffineSemigroup and HasPMInequality],100,

        function(v,a)
    local f, b, g, ineq;

    ineq:=PMInequality(a);
    if not(IsListOfIntegersNS(v)) then
      #Error("The first argument must be a list of integers.");
      return false;
    fi;
    if ForAny(v,x->x<0) then
        return false;
    fi;

    f:=ineq[1];
    b:=ineq[2];
    g:=ineq[3];
    if Length(ineq[1])<>Length(v) then
      #Error("The dimension of the vector and the affine semigroup do not coincide.");
      return false;
    fi;

    return ((f*v) mod b) <= g*v;

end);

InstallMethod(BelongsToAffineSemigroup,
        "To test whether an element of N^n belongs to an affine semigroup",
        true,
        [ IsHomogeneousList, IsAffineSemigroup and HasInequalities],70,

        function(v,a)
    local equ,ev;

    equ:=AffineSemigroupInequalities(a);
    if not(IsListOfIntegersNS(v)) then
      #Error("The first argument must be a list of integers.");
      return false;
    fi;
    if ForAny(v,x->x<0) then
        return false;
    fi;

    if Length(equ[1])<>Length(v) then
      #Error("The dimension of the vector and the affine semigroup do not coincide.");
      return false;
    fi;
    ev:=equ*v;

    Info(InfoNumSgps,2,"Testing membership with inequalities.");

    return ForAll(ev,x->x>=0);

end);

InstallMethod(BelongsToAffineSemigroup,
        "To test whether an element of N^n belongs to an affine semigroup",
        true,
        [ IsHomogeneousList, IsAffineSemigroup and HasGaps],70,
        function(v,a)
            local gaps;

            if not(IsListOfIntegersNS(v)) then
              #Error("The first argument must be a list of integers.");
              return false;
            fi;
            if ForAny(v,x->x<0) then
                return false;
            fi;
            gaps:=Gaps(a);
            if Length(gaps[1])<>Length(v) then
              #Error("The dimension of the vector and the affine semigroup do not coincide.");
              return false;
            fi;

            Info(InfoNumSgps,2,"Testing membership with gaps.");
            return not(v in gaps);
end);

#############################################################
# Computes a basis of a subgroup of Z^n with defining equations
# Ax =0 \in Z_m1\times\Z_mt \times Z^k, k is n-length(m),
# m=[m1,...,mt]
#############################################################
InstallGlobalFunction(BasisOfGroupGivenByEquations,function(A,m)
    local n,r, AA, i, er, b, homEqToBasis;

    # Compute a basis of a subgroup of Z^n with defining equations Ax=0
    homEqToBasis:=function(A)
 local snf, b, r, n;
 snf:= SmithNormalFormIntegerMatTransforms(A);
 r:=snf.rank;
 n:=Length(A[1]);
 b:=TransposedMat(snf.coltrans);
 return b{[r+1..n]};
    end;


    if not(IsRectangularTable(A) and ForAll(A,IsListOfIntegersNS)) then
        Error("The first argument must be a matrix.");
    fi;

    n:=Length(A[1]);
    r:=Length(A);

    if m=[] then
        AA:=ShallowCopy(TransposedMat(A));
    else
        if not(IsListOfIntegersNS(m)) then
            Error("The second argument must be a lists of integers.");
        fi;

        if not(ForAll(m,x->x>0)) then
            Error("The second argument must be a list of positive integers");
        fi;

        AA:=ShallowCopy(TransposedMat(A));
        er:=List([1..r],_->0);
        for i in [1..Length(m)] do
            if m[i]<>0 then
                er[i]:=m[i];
                Add(AA,ShallowCopy(er));
                er[i]:=0;
            fi;
        od;
    fi;
    AA:=TransposedMat(AA);

    b:=TransposedMat(homEqToBasis(AA));

    b:=b{[1..n]};
    return LLLReducedBasis(TransposedMat(b)).basis;
end);

#############################################################
#  Computes the defining equations of the group of Z^n
#  generated by M
#  the output is [A,m] such that Ax=0 mod m are the equations
############################################################
InstallGlobalFunction(EquationsOfGroupGeneratedBy,function(M)
    local A, m, snf, nones;

    if not(IsRectangularTable(M) and ForAll(M,IsListOfIntegersNS)) then
        Error("The first argument must be a matrix.");
    fi;

    snf:=SmithNormalFormIntegerMatTransforms(M);
    A:=TransposedMat(snf.coltrans);
    m:=DiagonalOfMat(snf.normal);
    nones:=Length(Filtered(m,x->x=1));

    m:=Filtered(DiagonalOfMat(snf.normal),x->x<>0);
    A:=A{[nones+1..Length(A)]};
    m:=m{[nones+1..Length(m)]};

    return [A,m];
end);


##############################################################
# Determines if there is a gluing of the two affine semigroups,
# and if so, returns the gluing of them; fail otherwise
##############################################################
InstallGlobalFunction(GluingOfAffineSemigroups,function(a1,a2)
    local int, d, intersectionOfSubgroups, g1, g2;


    #computes the intersection of two groups of Z^n
    # given by generators
    intersectionOfSubgroups:=function(g1,g2)
        local eq1, eq2, A, m;

        eq1:=EquationsOfGroupGeneratedBy(g1);
        eq2:=EquationsOfGroupGeneratedBy(g2);
        A:=Concatenation(eq1[1],eq2[1]);
        m:=Concatenation(eq1[2],eq2[2]);

        return BasisOfGroupGivenByEquations(A,m);
    end;

    if not(IsAffineSemigroup(a1)) or not(IsAffineSemigroup(a2)) then
        Error("The arguments must be affine semigroups.");
    fi;

    g1:=GeneratorsOfAffineSemigroup(a1);
    g2:=GeneratorsOfAffineSemigroup(a2);
    if not(IsRectangularTable(Concatenation(g1,g2)))then
        Error("The semigroups must have the same dimension.");
    fi;

    int:=intersectionOfSubgroups(g1,g2);
    if Length(int)<> 1 then
        return false;
    fi;

    d:=int[1];
    if ForAny(d, i->i<0) then
        d:=-d;
    fi;
    if BelongsToAffineSemigroup(d,a1) and
       BelongsToAffineSemigroup(d,a2) then
        return AffineSemigroup(Concatenation(g1,g2));
    fi;
    return fail;

end);

###################### ContejeanDevieAlgorithm

#############################################################################################
# l contains the list of coefficients of a system of linear equations. forten gives the
#  set of minimal generators of the affine semigroup of nonnegative soultions of this equation
##############################################################################################
InstallMethod(HilbertBasisOfSystemOfHomogeneousEquations,
        "Computes the Hilbert basis of a system of linear Diophantine equations, some evetually in congruences.",[IsHomogeneousList,IsHomogeneousList],1,
  function(ls,md)
  local  contejeanDevieAlgorithm, contejeanDevieAlgorithmWithCongruences, leq;

  ## local functions ...
    #less than or equal to with the usual partial order
  leq:= function(v1,v2)
      local v;
      v:=v2-v1;
      return (First(v,n->n<0)=fail);
  end;

  contejeanDevieAlgorithm:= function(l)
    local solutions, m, x, explored, candidates, tmp, k,zero, lx;


    Info(InfoNumSgps,2,"Using Contejean and Devie algorithm.");


    solutions:=[];
    explored:=[];

    #if not(IsRectangularTable(l)) then
    #  Error("The argument must be a matrix.");
    #fi;
    #if not(IsInt(l[1][1])) then
    #  Error("The matrix must be of integers.");
    #fi;


    m:=IdentityMat(Length(l[1]));
    zero:=List([1..Length(l)],_->0);
    candidates:=m;
    while (not(candidates=[])) do
      x:=candidates[1];
      explored:=Union([x],explored);
      candidates:=candidates{[2..Length(candidates)]};
      lx:=l*x;
      if(lx=zero) then
        solutions:=Union([x],solutions);
        #    Print(x);
      else
        tmp:=Set(Filtered(m,n->(lx*(l*n)<0)),y->y+x);
        tmp:=Difference(tmp,explored);
        tmp:=Filtered(tmp,n->(First(solutions,y->leq(y,n))=fail));
        candidates:=Union(candidates,tmp);
      fi;
    od;
    return solutions;
  end;

  contejeanDevieAlgorithmWithCongruences:=function(ls,md)
    local l,n,m,diag,dim,d, hil, zero;

    #if not(IsRectangularTable(ls)) then
    #  Error("The first argument must be a matrix.");
    #fi;

    if not(IsListOfIntegersNS(md)) or ForAny(md, x->not(IsPosInt(x))) then
      Error("The second argument must be a list of positive integers.");
    fi;

    n:=Length(ls);
    dim:=Length(ls[1]);
    m:=Length(md);
    if m>n then
      Error("There are more modulus than equations.");
    fi;

    diag:=Concatenation(md,List([1..n-m],_->0));
    d:=DiagonalMat(diag);
    l:=TransposedMat(Concatenation(TransposedMat(ls),d,-d));
    zero:=List([1..dim],_->0);

    hil:=Difference(List(contejeanDevieAlgorithm(l), x->x{[1..dim]}),[zero]);
    return hil;

    #return Filtered(hil, y->Filtered(hil,x->leq(x,y))=[y]);
  end;
  ## end of local functions ...
  Info(InfoNumSgps,1,"Using contejeanDevieAlgorithm for Hilbert Basis. Please, consider using NormalizInterface, 4ti2Interface or 4ti2gap.");
  #ls := arg[1][1];
  #md := arg[1][2];

  if not(IsRectangularTable(ls) and ForAll(ls,IsListOfIntegersNS)) then
    Error("The first argument must be a matrix of integers.");
  fi;

  if md = [] then
    return contejeanDevieAlgorithm(ls);
  else
    return contejeanDevieAlgorithmWithCongruences(ls,md);

  fi;
end);

##############################################################################################
#
# ls is a matrix of integers. It computes the set minimal nonzero nonnegative integer solutions
# of ls*x>=0
#
InstallMethod(HilbertBasisOfSystemOfHomogeneousInequalities,
        "Computes the Hilbert basis of a set of inequalities",
        [IsHomogeneousList],1,
        function(ls)
    local mat, neq, dim, id, hil,zero ;

    if not(IsRectangularTable(ls) and ForAll(ls,IsListOfIntegersNS)) then
      Error("The argument must be a matrix.");
    fi;

    neq:=Length(ls);
    dim:=Length(ls[1]);
    zero:=List([1..dim],_->0);

    id:=IdentityMat(neq);
    mat:=TransposedMat(Concatenation(TransposedMat(ls),-id));
    hil:=HilbertBasisOfSystemOfHomogeneousEquations(mat,[]);
    return List(hil,x->x{[1..dim]});


end);

########################################################################
# Computes the set of factorizations of v in terms of the elements of ls
# That is, a Hilbert basis for ls*X=v
# If ls contains vectors that generate a nonreduced monoid, then it
# may enter in an infinite loop
########################################################################
InstallMethod(FactorizationsVectorWRTList,
        "Computes the set of factorizations of the first argument in terms of the elements of the second",
        [IsHomogeneousList, IsMatrix],1,
        function(v,ls)
    local len, e1, opt1, opt2, i, mat, dim;
    # REQUERIMENTS: NormalizInterface
    #if NumSgpsCanUseNI then
    #    TryNextMethod();
    #fi;

    mat:=TransposedMat(Concatenation(ls,[-v]));

    if not(IsListOfIntegersNS(v)) then
        Error("The first argument must be a list of integers.");
    fi;

    if not(ForAll(ls,IsListOfIntegersNS)) then
        Error("The second argument must be a list of lists of integers.");
    fi;

    if not(IsRectangularTable(mat)) then
        Error("The list in the second argument must have the same length as the lists in the first argument.");
    fi;

    len:=Length(ls);
    if ls=[] then
        return [];
    fi;
    if ForAll(v,x->x=0) then
        return [List([1..len],_->0)];
    fi;
    if ForAny(v,x->x<0) then
        return [];
    fi;

    dim:=Length(ls[1]);
    if dim=1 then
        return FactorizationsIntegerWRTList(v[1],Flat(ls));
    fi;

    if Length(ls)=1 then

        i:=First([1..dim],x->ls[1][x]<>0);

        if i=fail then
            Error("The second argument cannot contain the zero vector.");
        fi;
        if (v[i] mod ls[1][i]=0) and v=v[i]/ls[1][i]*ls[1] then
            return [ [v[i]/ls[1][i]] ];
        fi;
        return [];
    fi;
    e1:=List([1..len-1],_->0);
    e1:=Concatenation([1],e1);
    opt1:=[];
    if ForAll(v-ls[1],x->x>=0) then
        opt1:=List(FactorizationsVectorWRTList(v-ls[1],ls), x->x+e1);
    fi;
    opt2:=List(FactorizationsVectorWRTList(v,ls{[2..len]}),
               x->Concatenation([0],x));
#    return Concatenation(opt1,opt2);
    return Union(opt1,opt2);
end);

###############################################################################
#O Factorizations
# Vactorizations of a vector in terms of the minimal generating set of the 
# affine semigroup
########################################################################
InstallMethod(Factorizations,
    "factorizations of an element in terms of the generators of the affine semigroup",
    [IsHomogeneousList,IsAffineSemigroup],
    function(n,a)
        local fac,gen;
        if not(n in a) then
            Error("The first argument is not an element of the second");
        fi;
        gen:=MinimalGeneratingSystem(a);
        fac:=FactorizationsVectorWRTList(n,gen);
        return fac;
    end);

InstallMethod(Factorizations,
    "factorizations of an element in terms of the generators of the affine semigroup",
    [IsAffineSemigroup,IsHomogeneousList],
    function(a,n)
        local fac,gen;
        if not(n in a) then
            Error("The second argument is not an element of the first");
        fi;
        gen:=MinimalGeneratingSystem(a);
        fac:=FactorizationsVectorWRTList(n,gen);
        return fac;
    end);


#######################################################################
#O CircuitsOfKernelCongruence
# computes a set of circuits (relations with minimal support) of the 
# kernel congruence of the monoid morphism associated to the matrix m
########################################################################
InstallMethod(CircuitsOfKernelCongruence,
  "Computes the set of circuits the kernel congruence of the monoid morphism associated to a matrix",
 [IsHomogeneousList],1,
function( m )
    local gens, positive, negative, cir,
        cols,rows, e, comb, c, i, circ, matt, sum, sp, sn;

    # computes x^+
    positive:=function(x)
        local p,i;

        p:=[];
        for i in [1..Length(x)] do
            p[i]:=Maximum(x[i],0);
        od;

        return p;
    end;

    # computes x^-
    negative:=function(x)
        local p,i;

        p:=[];
        for i in [1..Length(x)] do
            p[i]:=-Minimum(x[i],0);
        od;

        return p;
    end;


    if not(IsRectangularTable(m)) then
        Error("The argument must be an array of integers.");
    fi;
    if not(ForAll(m, l->ForAll(l, x->(x=0) or IsPosInt(x)))) then
        Error("The argument must be a matrix of nonnegative integers.");
    fi;

    #we compute the circuits as explained in Eisenbud-Sturmfels Lemma 8.8
    cols:=Length(m);
    rows:=Length(m[1]);
    e:=IdentityMat(cols);
    comb:=IteratorOfCombinations([1..cols],rows+1);
    circ:=[];
    #Print("Combinations ",comb,"\n");
    Info(InfoNumSgps,2,"Running over ",NrCombinations([1..cols],rows+1)," combinations to compute circuits");
    for c in comb do
        sum:=0;
        for i in [1..rows+1] do
            matt:=m{Difference(c,[c[i]])};
            #Print("c ",c," da ",matt,"\n");
            sum:=sum+(-1)^(i+1)*DeterminantIntMat(matt)*e[c[i]];
        od;
        if ForAny(sum, x->x<>0) then
            sum:=sum/Gcd(sum);
            sp:=positive(sum);
            sn:=negative(sum);
            Add(circ,[sp,sn]);
        fi;
    od;
 
    return circ;
end);


#######################################################################
#O PrimitiveRelationsOfKernelCongruence
# computes a set of primitive relations of the 
# kernel congruence of the monoid morphism associated to the matrix m
########################################################################
InstallMethod(PrimitiveRelationsOfKernelCongruence,
  "Computes the set of primitive relations the kernel congruence of the monoid morphism associated to a matrix",
 [IsHomogeneousList],1,
function( m )
    local gens,dim, sols,e,prim, msg,aid,zeroid,lft,prlft,id,zero,zeroes;

    if not(IsRectangularTable(m)) then
        Error("The argument must be an array of integers.");
    fi;
    if not(ForAll(m, l->ForAll(l, x->(x=0) or IsPosInt(x)))) then
        Error("The argument must be a matrix of nonnegative integers.");
    fi;

    Info(InfoNumSgps,2,"Using Lawrence lifting for computing primitive relations.");
    e:=Length(m);
    dim:=Length(m[1]);
    id:=IdentityMat(e);
    zero:=List([1..e],_->0);
    zeroes:=List([1..dim],_->zero);

    msg:=TransposedMat(m);
    aid:=TransposedMat(Concatenation(msg,id));
    zeroid:=TransposedMat(Concatenation(zeroes,id));

    lft:=(Concatenation(aid,zeroid));
    prlft:=GeneratorsOfKernelCongruence(lft);
    Info(InfoNumSgps,2,"The kernel congruence is of the lifting is ", prlft);

    prim:=Set(prlft, p->Set([p[1]{[e+1..e+e]},p[2]{[e+1..e+e]}]));
    return prim;
end);

############################################################
# computes a set of generators of the kernel congruence
# of the monoid morphism associated to the matrix m with
# nonnegative integer coefficients
############################################################
InstallMethod(GeneratorsOfKernelCongruence,
  "Computes a set of generators of the kernel congruence of the monoid morphism associated to a matrix",
 [IsHomogeneousList],1,
 function( m )

    local i, p, rel, rgb, msg, pol, ed, monomial, candidates, mp,
          R,id, ie, vars, mingen, exps, bintopair, dim, zero, gen,
          pres,c, rclass;

    # REQUERIMENTS: SingularInterface or Singular
    #if NumSgpsCanUseSI or NumSgpsCanUseSingular then
    #    TryNextMethod();
    #fi;

    bintopair:=function(p)
        local m1,m2, d1, d2;
        m1:=LeadingMonomialOfPolynomial(p, MonomialLexOrdering());
        m2:=m1-p;
        d1:=List([1..ed], i->DegreeIndeterminate(m1,i));;
        d2:=List([1..ed], i->DegreeIndeterminate(m2,i));;
        return Set([d1,d2]);
    end;

    if not(IsRectangularTable(m)) then
        Error("The argument must be a matrix of nonegative integers.");
    fi;

    if not(ForAll(m, l->ForAll(l, x->(x=0) or IsPosInt(x)))) then
        Error("The argument must be a matrix of nonnegative integers.");
    fi;

    msg:=ShallowCopy(m);
    ed:=Length(msg);
    if ed=0 then
        return [];
    fi;
    zero:=List([1..ed],_->0);
    dim:=Length(msg[1]);
    vars:=List([1..ed+dim],i->X(Rationals,i));
    R:=PolynomialRing(Rationals,vars);
    p:=List([1..ed], i->X(Rationals,i)-
            Product(List([1..dim], j->X(Rationals,j+ed)^msg[i][j])));
    rgb:=ReducedGroebnerBasis( p,
                 EliminationOrdering(List([1..dim],i->X(Rationals,i+ed))));
    rgb:=Filtered(rgb,
                 q->ForAll([1..dim], i->DegreeIndeterminate(q,i+ed)=0));
    candidates:=Set(rgb,q->bintopair(q));
    return candidates;
end);

############################################################
# computes a canonical basis of the kernel congruence
# of the monoid morphism associated to the matrix m with
# nonnegative integer coefficients wrt the term ordering
# the kernel is the pairs (x,y) such that xm=ym
############################################################
InstallMethod(CanonicalBasisOfKernelCongruence,
 "Computes a canonical basis for the congruence of of the monoid morphism associated to the matrix",
 [IsHomogeneousList, IsMonomialOrdering],1,
  function( m, ord )

    local i, p, rel, rgb, msg, pol, ed, monomial, candidates, mp,
          R,id, ie, vars, mingen, exps, bintopair, dim, zero, gen,
          pres,c, rclass;


    bintopair:=function(p)
        local m1,m2, d1, d2;
        m1:=LeadingMonomialOfPolynomial(p, ord);
        m2:=m1-p;
        d1:=List([1..ed], i->DegreeIndeterminate(m1,i));;
        d2:=List([1..ed], i->DegreeIndeterminate(m2,i));;
        return [d1,d2];
    end;

    if not(IsRectangularTable(m)) then
        Error("The argument must be a matrix of nonnegative integers.");
    fi;

    if not(ForAll(m, l->ForAll(l, x->(x=0) or IsPosInt(x)))) then
        Error("The argument must be a matrix of nonnegative integers.");
    fi;

    msg:=ShallowCopy(m);
    ed:=Length(msg);
    if ed=0 then
        return [];
    fi;
    zero:=List([1..ed],_->0);
    dim:=Length(msg[1]);
    vars:=List([1..ed+dim],i->X(Rationals,i));
    R:=PolynomialRing(Rationals,vars);
    p:=List([1..ed], i->X(Rationals,i)-
            Product(List([1..dim], j->X(Rationals,j+ed)^msg[i][j])));
    rgb:=ReducedGroebnerBasis( p,
                 EliminationOrdering(List([1..dim],i->X(Rationals,i+ed))));
    rgb:=Filtered(rgb,
                 q->ForAll([1..dim], i->DegreeIndeterminate(q,i+ed)=0));
  if rgb = [] then
   return [];
  fi;
  rgb:=ReducedGroebnerBasis(rgb,ord);
    candidates:=Set(rgb,q->bintopair(q));
    return candidates;
end);

############################################################
# computes the Graver basis of matrix with integer entries
############################################################
InstallMethod(GraverBasis,
        "Computes the Graver basis of the matrix",
        [IsHomogeneousList],1,
function(a)
  #PLAIN implementation
 local msg, mgs, ed, dim, prlft, lft,zero, zeroes, id, aid, zeroid;

    if not(IsRectangularTable(a) and ForAll(a,IsListOfIntegersNS)) then
        Error("The argument must be a matrix of integers.");
    fi;

    Info(InfoNumSgps,1,"Using Lawrence lifting for computing Graver Basis. Please, consider using NormalizInterface, 4ti2Interface or 4ti2gap.");
    mgs:=TransposedMat(a);
    ed:=Length(mgs);
    dim:=Length(mgs[1]);
    #lft:=LawrenceLiftingOfAffineSemigroup(a);
    #prlft:=MinimalPresentationOfAffineSemigroup(lft);
    id:=IdentityMat(ed);
    zero:=List([1..ed],_->0);
    zeroes:=List([1..dim],_->zero);

    msg:=TransposedMat(mgs);
    aid:=TransposedMat(Concatenation(msg,id));
    zeroid:=TransposedMat(Concatenation(zeroes,id));

    lft:=(Concatenation(aid,zeroid));
    prlft:=GeneratorsOfKernelCongruence(lft);
    Info(InfoNumSgps,2,"The kernel congruence is ", prlft);
    prlft:=Filtered(prlft, p->p[1]<>p[2]);
    return Set(Union(prlft), p->p{[1..ed]}-p{[ed+1..ed+ed]});
end);

############################################################
# computes a minimal presentation of a
############################################################
InstallMethod(MinimalPresentationOfAffineSemigroup,
 "Computes the minimal presentation of an affine semigroup",
 [IsAffineSemigroup],1,
 function( a )

    local i, p, rel, rgb, msg, pol, ed, monomial, candidates, mp,
          R,id, ie, vars, mingen, exps, bintopair, dim, zero, gen,
          pres,c, rclass;

    msg:=MinimalGenerators(a);
    ed:=Length(msg);
    if ed=0 then
        return [];
    fi;
    dim:=Length(msg[1]);
    candidates:=GeneratorsOfKernelCongruence(msg);
    candidates:=Set(candidates,c->c[1]*msg);
    Info(InfoNumSgps,2, "Candidates to Betti elements",candidates);
    pres:=[];
    for c in candidates do
        exps:=FactorizationsVectorWRTList(c,msg);
        rclass:=RClassesOfSetOfFactorizations(exps);
        if Length(rclass)>1 then
            pres:=Concatenation(pres,List([2..Length(rclass)],
                          i->Set([rclass[1][1],rclass[i][1]])));
        fi;
    od;
    return pres;
end);

InstallMethod(MinimalPresentation,
"Computes the minimal presentation of an affine semigroup",
[IsAffineSemigroup],
MinimalPresentationOfAffineSemigroup
);

###################################################################
# Betti elements of the affine semigroup a
###################################################################
InstallMethod(BettiElements,
 "Computes the Betti elements of an affine semigroup",
 [IsAffineSemigroup],1,
 function(a)
    local msg, pr;

    msg:=MinimalGenerators(a);

    pr:=MinimalPresentationOfAffineSemigroup(a);

    return Set(pr, p->p[1]*msg);

end);


#############################################################################
##
#P  IsUniquelyPresentedAffineSemigroup(a)
##
##  For an affine semigroup a, checks it it has a unique minimal presentation
##  Based in GS-O
##
#############################################################################
InstallMethod(IsUniquelyPresented,
         "Tests if the affine semigroup S has a unique minimal presentation",
         [IsAffineSemigroup],1,
        function(a)
    local gs;
    gs:=MinimalGenerators(a);
    return ForAll(BettiElementsOfAffineSemigroup(a),
                  b->Length(FactorizationsVectorWRTList(b,gs))=2);
end);

#############################################################################
##
#P  IsGenericAffineSemigroup(a)
##
##  For an affine semigroup a, checks it it has a generic presentation,
##  that is, in every relation all generators appear.
##  These semigroups are uniquely presented; see B-GS-G.
##
#############################################################################
InstallMethod(IsGenericAffineSemigroup,
         "Tests if the affine semigroup S has a generic presentation",
         [IsAffineSemigroup],1,
        function(a)
 local mp;
    mp:=MinimalPresentationOfAffineSemigroup(a);
    return ForAll(mp,p->Product(p[1]+p[2])<>0);
end);

InstallTrueMethod(IsUniquelyPresentedAffineSemigroup, IsGenericAffineSemigroup);

#############################################################################
##
#F ShadedSetOfElementInAffineSemigroup(x,a)
## computes the shading set of x in a as defined in
## -  Székely, L. A.; Wormald, N. C. Generating functions for the Frobenius problem
##      with 2 and 3 generators. Math. Chronicle 15 (1986), 49–57.
#############################################################################
InstallGlobalFunction(ShadedSetOfElementInAffineSemigroup, function(x,a)

    local msg;

    if not IsAffineSemigroup(a) then
        Error("The second argument must be an affine semigroup.\n");
    fi;

    if not ( x in a ) then
        Error("The first argument must be an element of the second.\n");
    fi;

    msg:=MinimalGenerators(a);
    return Filtered(Combinations(msg), c-> (x-Sum(c)) in a);
end);

###############################################################################
#F DeltaSetOfAffineSemigroup
# Computes the Delta set of the affine semigroup a
# uses the algorithm presented in [GSONW]
###########################################################################
InstallGlobalFunction(DeltaSetOfAffineSemigroup,
  function(a)

    local p, msg, candidates, zero, hgens, m;

    if not(IsAffineSemigroup(a)) then
      Error("The argument must be an affine semigroup");
    fi;

    m:=MinimalGenerators(a);

    if Length(m)=0 then
      return [];
    fi;
    zero:=List([1..Length(m[1])],_->0);
    msg:=List(Union(m,[zero]), x->Concatenation([1],x));
    candidates:=Set(CanonicalBasisOfKernelCongruence(msg, MonomialLexOrdering()), l->l[1][1]);
    RemoveSet(candidates,0);
    return candidates;
  end);

InstallMethod(DeltaSet,
    "for affine semigroups",
    [IsAffineSemigroup],
    DeltaSetOfAffineSemigroup);
    
######################################################################
# Computes the catenary degree of the affine semigroup a
######################################################################
InstallGlobalFunction(CatenaryDegreeOfAffineSemigroup,
        function(a)
    local betti, b, max, c, ls;
    if not(IsAffineSemigroup(a)) then
        Error("The argument must be an affine semigroup");
    fi;

    ls:=MinimalGenerators(a);

    Info(InfoNumSgps,2,"Computing the Betti elements of the affine semigroup.");
    betti:=BettiElementsOfAffineSemigroup(a);
    Info(InfoNumSgps,2,"The Betti elements are ",betti);
    max:=0;
    for b in betti do
        Info(InfoNumSgps,2,"Computing the catenary degree of ",b);
        c:=CatenaryDegreeOfSetOfFactorizations(
                   FactorizationsVectorWRTList(b,ls));
        Info(InfoNumSgps,2,"which equals ",c);
        if c>max then max:=c; fi;
    od;
    return max;
end);

InstallMethod(CatenaryDegree,
    "Computes the catenary degree of an affine semigroup",
    [IsAffineSemigroup],
    CatenaryDegreeOfAffineSemigroup);

######################################################################
# Computes the equal catenary degree of the affine semigroup a
# uses [GSOSN]
######################################################################
InstallGlobalFunction(EqualCatenaryDegreeOfAffineSemigroup,
        function(a)
    local ls, lsh, ah, primeq;

    if not(IsAffineSemigroup(a)) then
        Error("The argument must be an affine semigroup");
    fi;

    ls:=MinimalGenerators(a);
    lsh:=List(ls, x-> Concatenation(x,[1]));
    ah:=AffineSemigroup(lsh);
    primeq:=BettiElementsOfAffineSemigroup(ah);

    return Maximum(Set(primeq, x->CatenaryDegreeOfSetOfFactorizations(
            FactorizationsVectorWRTList(x,lsh))));

end);

######################################################################
# Computes the homogeneous catenary degree of the affine semigroup a
# uses [GSOSN]
######################################################################
InstallGlobalFunction(HomogeneousCatenaryDegreeOfAffineSemigroup,
        function(a)
    local ls, lsh, ah, primeq, one;

    if not(IsAffineSemigroup(a)) then
        Error("The argument must be an affine semigroup");
    fi;

    ls:=MinimalGenerators(a);
    if ls=[] then return 0;
    fi;

    lsh:=List(ls, x-> Concatenation(x,[1]));
    one:=List(ls[1],_->0);
    Add(one,1);
    Add(lsh,one);

    ah:=AffineSemigroup(lsh);
    primeq:=BettiElementsOfAffineSemigroup(ah);

    return Maximum(Set(primeq, x->CatenaryDegreeOfSetOfFactorizations(
            FactorizationsVectorWRTList(x,lsh))));

end);

######################################################################
# Computes the monotone catenary degree of the affine semigroup a
# uses [PH] and Alfredo Sanchez-R.-Navarro thesis
######################################################################
InstallGlobalFunction(MonotoneCatenaryDegreeOfAffineSemigroup,
        function(a)
    local ls, lsh, ah, primeq, one, dim;

    if not(IsAffineSemigroup(a)) then
        Error("The argument must be an affine semigroup");
    fi;

    ls:=MinimalGenerators(a);

    if ls=[] then return 0;
    fi;
    dim:=Length(ls[1]);

    lsh:=List(ls, x-> Concatenation(x,[1]));
    one:=List(ls[1],_->0);
    Add(one,1);
    Add(lsh,one);

    ah:=AffineSemigroup(lsh);
    primeq:=DegreesOfPrimitiveElementsOfAffineSemigroup(ah);
    primeq:=Set(primeq, x->x{[1..dim]});

    return Maximum(Set(primeq, x->MonotoneCatenaryDegreeOfSetOfFactorizations(
            FactorizationsVectorWRTList(x,ls))));

end);


###############################################################################
##
#O OmegaPrimalityOfElementInAffineSemigroup
#
# Computes the omega-primality of v in the monoid a
###########################################################################
InstallMethod(OmegaPrimalityOfElementInAffineSemigroup,
        "Computes the omega-primality of x in the monoid s",
        [IsHomogeneousList,IsAffineSemigroup],1,
        function(x,s)

    local i, j, p, rel, rgb, msg, pol, ed,  degree, monomial,  facts, fact, mp,id, reduce, nonnegative,
          mu1,A,B,C, lt, tl, exp, new;

    msg:=MinimalGenerators(s);
    ed:=Length(msg);
    mp:=MinimalPresentationOfAffineSemigroup(s);
    p := [];
    # list of exponents to monomial
    monomial:=function(l)
        local i;
        pol:=1;
        for i in [1..ed] do
            pol:=pol*Indeterminate(Rationals,i)^l[i];
        od;
        return pol;
    end;
    ## monomial to exponents
    exp:=function(mon)
        return List([1..ed],i-> DegreeIndeterminate(mon,i));
    end;
    ##computes the degree of a monomial
    degree:=function(mon)
        return Sum(exp(mon));
    end;
    ##nonnegative
    nonnegative:=function(l)
        return ForAll(l, x-> x>=0);
    end;

    for rel in mp do
        Add( p, monomial(rel[1])-monomial(rel[2]));
    od;

    facts:=FactorizationsVectorWRTList(x,msg);
    if facts=[] then
        return 0;
    fi;
    Info(InfoNumSgps,2,"Factorizations of the element :", facts);
    fact:=facts[Length(facts)];
    id:=IdentityMat(ed);

    for i in [1..ed] do
        Add(p,monomial(fact+id[i])-monomial(fact));
    od;

    # for j in [2..Length(facts)] do
    #     for i in [1..ed] do
    #         Add(p,monomial(facts[j]+id[i])-monomial(facts[j]));
    #     od;
    # od;

    Info(InfoNumSgps,2,"Computing a Groebner basis");
    #a canonical system of generators of sigma_I
    rgb := ReducedGroebnerBasis( p, MonomialGrevlexOrdering() );


    #normal form wrt rgb
    reduce:=function(r)
        return PolynomialReducedRemainder(r,rgb, MonomialGrevlexOrdering());
    end;

    #leading term
    lt:=function(r)
        return LeadingMonomialOfPolynomial(r,MonomialGrevlexOrdering());
    end;

    #tail
    tl:=function(r)
        return lt(r)-r;
    end;

    mu1:=reduce(monomial(fact));
    #A:=Set([mu1]);
    A:=Union(Set([mu1]),Set(facts,monomial));

    Info(InfoNumSgps,2,"Computing minimal elements of the ideal.");
    while true do
        B:=[];
        for i in A do
            for rel in rgb do
                new:=Lcm(i,tl(rel))/tl(rel)*lt(rel);
                if First(A, a->nonnegative(exp(new)-exp(a)))=fail then
                    AddSet(B,new);
                    Info(InfoNumSgps,2,"New possible minimal element: ",exp(new));
                fi;
            od;
        od;
        if IsSubset(A,B) then
            A:=Filtered(A, i->First(Difference(A,[i]), j-> nonnegative(exp(i)-exp(j)))=fail);
            return Maximum(Set(Set(A,exp),Sum));
        fi;
        A:=Union(A,B);
    od;
end);

InstallMethod(OmegaPrimality,
    "for an element in an affine semigroup",
    [IsHomogeneousList,IsAffineSemigroup],
    OmegaPrimalityOfElementInAffineSemigroup);


InstallMethod(OmegaPrimality,
    "for an element in an affine semigroup",
    [IsAffineSemigroup,IsHomogeneousList],
    function(a,l)
        return OmegaPrimalityOfElementInAffineSemigroup(l,a);
    end);


######################################################################
# Computes the omega primality of the affine semigroup a
######################################################################
InstallGlobalFunction(OmegaPrimalityOfAffineSemigroup,
        function(a)
    local ls;

    if not(IsAffineSemigroup(a)) then
        Error("The argument must be an affine semigroup");
    fi;

    ls:=MinimalGenerators(a);
    return Maximum(Set(ls, v-> OmegaPrimalityOfElementInAffineSemigroup(v,a)));
end);

InstallMethod(OmegaPrimality,
    "for affine semigroups",
    [IsAffineSemigroup],
    OmegaPrimalityOfAffineSemigroup);

#############################################################################
##
#F  ElasticityOfFactorizationsElementWRTAffineSemigroup(n,s)
##
##  Computes the quotient (maximum length)/(minimum lenght) of the
##  factorizations of an element <n> as linear combinations
##  with nonnegative coefficients of the minimal generators
##  of the semigroup <s>.
##
#############################################################################
InstallGlobalFunction(ElasticityOfFactorizationsElementWRTAffineSemigroup, function(n,s)
    local gen,max,min,lenfact;

    if not IsAffineSemigroup(s) then
        Error("The second argument must be an affine semigroup.\n");
    fi;

    if not IsListOfIntegersNS(n) then
        Error("The first argument must be a list of integers.\n");
    fi;

    if not (n in s) then
        Error("The first argument does not belong to the second.\n");
    fi; #this ensures that the lengths won't be zero

    gen:=MinimalGeneratingSystem(s);
    lenfact:=Set(FactorizationsVectorWRTList(n,gen),Sum);
    min:=Minimum(lenfact);
    max:=Maximum(lenfact);
    if min=0 then
        Error("The element seems to be the zero vector.\n");
    fi;

    return max/min;
end);

InstallMethod(Elasticity,
    "Elasticity of the factorizations of an element in an affine semigroup", 
    [IsHomogeneousList,IsAffineSemigroup],
    ElasticityOfFactorizationsElementWRTAffineSemigroup);

InstallMethod(Elasticity,
    "Elasticity of the factorizations in an affine semigroup of one of its elements", 
    [IsAffineSemigroup, IsHomogeneousList],
    function(a,v)
        return  ElasticityOfFactorizationsElementWRTAffineSemigroup(v,a);
    end);


#####################################################################
# Computes the elasticity of the affine semigroup a
#####################################################################
InstallGlobalFunction(ElasticityOfAffineSemigroup,
    function(s)

    local gens, positive, negative, cir, el,a, elt,
        cols,rows, e, comb, c, i, circ,mat, matt, sum, sp, sn;

    # computes x^+
    positive:=function(x)
        local p,i;

        p:=[];
        for i in [1..Length(x)] do
            p[i]:=Maximum(x[i],0);
        od;

        return p;
    end;

    # computes x^-
    negative:=function(x)
        local p,i;

        p:=[];
        for i in [1..Length(x)] do
            p[i]:=-Minimum(x[i],0);
        od;

        return p;
    end;


    if not(IsAffineSemigroup(s)) then
        Error("The argument must be an affine semigroup.");
    fi;
    gens:=MinimalGenerators(s);
    a:=TransposedMat(gens);
    el:=1;
    #we compute the circuits as explained in Eisenbud-Sturmfels Lemma 8.8
    rows:=Length(a);
    cols:=Length(a[1]);
    e:=IdentityMat(cols);
    mat:=TransposedMat(a);
    comb:=IteratorOfCombinations([1..cols],rows+1);
    #Print("Combinations ",comb,"\n");
    Info(InfoNumSgps,2,"Running over ",NrCombinations([1..cols],rows+1)," combinations to compute circuits");
    for c in comb do
        sum:=0;
        for i in [1..rows+1] do
            matt:=mat{Difference(c,[c[i]])};
            #Print("c ",c," da ",matt,"\n");
            sum:=sum+(-1)^(i+1)*DeterminantIntMat(matt)*e[c[i]];
        od;
        if ForAny(sum, x->x<>0) then
            sum:=sum/Gcd(sum);
            sp:=Sum(positive(sum));
            sn:=Sum(negative(sum));
            if sp>=sn then 
                elt:=sp/sn;
            else
                elt:=sn/sp;
            fi;
            if elt>el then 
                Info(InfoNumSgps,2, "new elasticity reached ", elt);
                el:=elt;
            fi;
        fi;
    od;
 
    return el;
end);

InstallMethod(Elasticity, 
    "Computes the elasticity of an affine semigroup",
    [IsAffineSemigroup],
    ElasticityOfAffineSemigroup
    );

###################################################################
#lawrence Lifting
###################################################################
InstallGlobalFunction(LawrenceLiftingOfAffineSemigroup,function(a)
 local dim,ed, msg, id, lft, zero, zeroes, aid, zeroid;

    if not(IsAffineSemigroup(a)) then
        Error("The argument must be an affine semigroup.");
    fi;

    msg:=MinimalGenerators(a);
    ed:=Length(msg);
    dim:=Length(msg[1]);
    id:=IdentityMat(ed);
    zero:=List([1..ed],_->0);
    zeroes:=List([1..dim],_->zero);

    msg:=TransposedMat(msg);
    aid:=TransposedMat(Concatenation(msg,id));
    zeroid:=TransposedMat(Concatenation(zeroes,id));



    lft:=(Concatenation(aid,zeroid));
    return AffineSemigroup(lft);
end);

#####################################################
# Degrees of primitive elements with Lawrence lifting
#####################################################
InstallMethod(DegreesOfPrimitiveElementsOfAffineSemigroup,
        "Computes the set of primitive elements of an affine semigroup",
        [IsAffineSemigroup],1,
        function(a)
 local msg, mgs, ed, dim, prlft, lft,zero, zeroes, id, aid, zeroid;

    Info(InfoNumSgps,2,"Using Lawrence lifting for computing primitive elements.");
    mgs:=MinimalGenerators(a);
    ed:=Length(mgs);
    dim:=Length(mgs[1]);
    #lft:=LawrenceLiftingOfAffineSemigroup(a);
    #prlft:=MinimalPresentationOfAffineSemigroup(lft);
    id:=IdentityMat(ed);
    zero:=List([1..ed],_->0);
    zeroes:=List([1..dim],_->zero);

    msg:=TransposedMat(mgs);
    aid:=TransposedMat(Concatenation(msg,id));
    zeroid:=TransposedMat(Concatenation(zeroes,id));

    lft:=(Concatenation(aid,zeroid));
    prlft:=GeneratorsOfKernelCongruence(lft);
    Info(InfoNumSgps,2,"The kernel congruence is ", prlft);

    return Union(Set(prlft, p->(p[1]{[ed+1..ed+ed]})*mgs),mgs);
end);

#####################################################################
# Computes the tame degree of the affine semigroup a
#####################################################################
InstallMethod(TameDegreeOfAffineSemigroup,
        "Computes the tame degree of an affine semigroup",
        [IsAffineSemigroup],1,
        function(a)
  local prim, tams, p, max, ls;

  ls:=MinimalGenerators(a);

  Info(InfoNumSgps,2,"Computing primitive elements of ", ls);
  prim:=DegreesOfPrimitiveElementsOfAffineSemigroup(a);
  Info(InfoNumSgps,2,"Primitive elements of ", ls, ": ",prim);
  max:=0;
  for p in prim do
    Info(InfoNumSgps,2,"Computing the tame degree of ",p);
    tams:=TameDegreeOfSetOfFactorizations(
                  FactorizationsVectorWRTList(p,ls));
    Info(InfoNumSgps,2,"The tame degree of ",p, " is ",tams);
    if tams>max then
      max:=tams;
    fi;
  od;
  return max;
end);

InstallMethod(TameDegree,
    "Tame degree for affine semigroups",
    [IsAffineSemigroup],
    TameDegreeOfAffineSemigroup);

###############################################################################
##
##########################################################################
##
#F NumSgpsUseNormaliz
#  Loads the package NormalizInterface and reads affine-extra-ni
##########################################################################
InstallGlobalFunction(NumSgpsUseNormaliz, function()
    if LoadPackage("NormalizInterface")=true then
        ReadPackage("numericalsgps", "gap/affine-extra-ni.gi");
        NumSgpsCanUseNI:=true;
        return true;
    else
        return fail;
    fi;

end);


##########################################################################
##
#F NumSgpsUseSingular
#  Loads the package singular and reads affine-extra-s
##########################################################################
InstallGlobalFunction(NumSgpsUseSingular, function()
    if IsPackageMarkedForLoading("SingularInterface","0.0") then
        Print("SingularInterface is already loaded and it is incompatible with Singular.\n");
        return fail;
    fi;

    if NumSgpsCanUseSingular then
        return true;
    fi;
    
    if LoadPackage("singular")=true then
        ReadPackage("numericalsgps", "gap/affine-extra-s.gi");
        ReadPackage("numericalsgps", "gap/polynomials-extra-s.gd");
        ReadPackage("numericalsgps", "gap/polynomials-extra-s.gi");
        NumSgpsCanUseSingular:=true;
        if NumSgpsCanUse4ti2 then
          ReadPackage("numericalsgps","gap/apery-extra-4ti2i-sing.gi");
        fi;
        return true;
    else
        return fail;
    fi;

end);

##########################################################################
##
#F NumSgpsUseSingularInterface
#  Loads the package SingularInterface and reads affine-extra-si
##########################################################################
InstallGlobalFunction(NumSgpsUseSingularInterface, function()
    if IsPackageMarkedForLoading("Singular","0.0") then
        Print("Singular is already loaded and it is incompatible with SingularInterface.\n");
        return fail;
    fi;

    if LoadPackage("SingularInterface")=true then
        ReadPackage("numericalsgps", "gap/affine-extra-si.gi");
        NumSgpsCanUseSI:=true;
        return true;
    else
        return fail;
    fi;

end);

##########################################################################
##
#F NumSgpsUse4ti2
#  Loads the package 4ti2Interface and reads affine-extra-4ti2
##########################################################################
InstallGlobalFunction(NumSgpsUse4ti2, function()
    if LoadPackage("4ti2Interface")=true then
        ReadPackage("numericalsgps", "gap/affine-extra-4ti2.gi");
        ReadPackage("numericalsgps", "gap/frobenius-extra-4ti2i.gi");
        if NumSgpsCanUseSingular then
          ReadPackage("numericalsgps","gap/apery-extra-4ti2i-sing.gi");
        fi;
        NumSgpsCanUse4ti2:=true;
        return true;
    else
        return fail;
    fi;

end);

##########################################################################
##
#F NumSgpsUse4ti2gap
#  Loads the package 4ti2gap and reads affine-extra-4ti2gap
##########################################################################
InstallGlobalFunction(NumSgpsUse4ti2gap, function()
    if LoadPackage("4ti2gap")=true then
        ReadPackage("numericalsgps", "gap/affine-extra-4ti2gap.gi");
        ReadPackage("numericalsgps", "gap/frobenius-extra-4ti2gap.gi");
        NumSgpsCanUse4ti2gap:=true;
        return true;
    else
        return fail;
    fi;

end);

##########################################################################
##
#F NumSgpsUseGradedModules
#  Loads the package GradedModules and reads affine-extra-gm
##########################################################################
# InstallGlobalFunction(NumSgpsUseGradedModules, function()
#     if LoadPackage("GradedModules")=true then
#         ReadPackage("numericalsgps", "gap/affine-extra-gm.gi");
#         NumSgpsCanUseGradedModules:=true;
#         return true;
#     else
#         return fail;
#     fi;
# end);

[ Dauer der Verarbeitung: 0.7 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge