#############################################################################
##
#W  random.gi               Manuel Delgado <mdelgado@fc.up.pt>
#W                          Pedro A. Garcia-Sanchez <pedro@ugr.es>
#W                          Jose Morais <josejoao@fc.up.pt>
##
##
#H  @(#)$Id: random.gi,v 0.95 $
##
#Y  Copyright 2005 by Manuel Delgado, 
#Y  Pedro Garcia-Sanchez and Jose Joao Morais
#Y  We adopt the copyright regulations of GAP as detailed in the 
#Y  copyright notice in the GAP manual.
##
#############################################################################


#############################################################################
##
#F  RandomListForNS(n,m)
##
##  Returns a set of length not greater than n of random integers in [1..m] 
##  whose GCD is 1.
##  It is used to create "random" numerical semigroups.
##
#############################################################################
InstallGlobalFunction(RandomListForNS, function(n,m)
    local d, i, r;
    d := 0;
    while d<>1 do    
        r := SSortedList(List([1 .. Random([1 .. n])], j -> Random([1 .. m])));
        d := Gcd(r);
    od;
    return r;    
end);



#############################################################################
##
#F  RandomNumericalSemigroup(n,m)
##
##  Returns a "random" numerical semigroup  with no more 
##  than n generators in [1..m].
##
#############################################################################
InstallGlobalFunction(RandomNumericalSemigroup, function(n,m)
    return(NumericalSemigroup(RandomListForNS(n,m)));
end);


#############################################################################
##
#F  RandomListRepresentingSubAdditiveFunction(m, a)
##
##  Produces a list representing a subadditive function which is periodic
##  with period m (or less). When possible, the images are in [a..20*a].
##  (Otherwise, the list of possible images is enlarged.)
##
#############################################################################
InstallGlobalFunction(RandomListRepresentingSubAdditiveFunction, function(m, a)
    local i, L, r, R;
    
    if not (IsPosInt(m) and IsPosInt(a)) then
        Error("This function takes two positive integers as arguments.");
    fi;

    R := [];
    L := [a..20*a];
    while Length(R) < m - 1 and L <> [] do
        r := RandomList(L);
        if ForAll(R, i-> not i mod m = r mod m) then
            if RepresentsPeriodicSubAdditiveFunction(Concatenation(R,[r,0])) then
                Add(R,r);
            fi;
        fi;
        L := Difference(L,[r]);
        if L = [] then
            L := [20*a+1..2*(a+1)];
            a := a+1;
        fi;
    od;
    Add(R,0);
    return(R);
end);



#############################################################################
##
#F  RandomProportionallyModularNumericalSemigroup(k)
##
##  Produces a "random" proportionally modular semigroup.
##
#############################################################################
InstallGlobalFunction(RandomProportionallyModularNumericalSemigroup, function(k)
    local a,b,c,l;
    a := Random([1..k]);
    b := Random([a+1..2*a]);
    c := Random([1..a]);
    l := Gcd(a,b,c);

    return(NumericalSemigroup("propmodular",a/l,b/l,c/l));
end);




#############################################################################
##
#F  RandomModularNumericalSemigroup(k)
##
##  Produces a "random" modular semigroup.
##
#############################################################################
InstallGlobalFunction(RandomModularNumericalSemigroup, function(k)
    local a,b,l;    
    a := Random([1..k]);
    b := Random([a+1..2*a]);
    l := Gcd(a,b);

    return(NumericalSemigroup("modular",a/l,b/l));
end);
