/*
Magma code to randomly generate 150000 weights corresponding to terminal
weighted projective space, in dimensions 1..10. The resulting weights are
written to the files "rank_1_dim_N.txt", where N is the dimension.
*/

// Returns true iff PP(wts) is terminal. Assumes that the weights wts are
// well-formed.
// "Bounds on fake weighted projective space", doi:10.2996/kmj/1245982903,
// Theorem 3.5.
function is_terminal(wts)
    n:=#wts - 1;
    h:=&+wts;
    for k in [2..h-2] do
        s:=&+[Rationals() | FractionalPart(w * k / h) : w in wts];
        if s lt 2 or s gt n-1 then
            return false;
        end if;
    end for;
    return true;
end function;

// Returns true iff the weights wts satisfy the bounds require by a terminal
// wps. Assumes that wts are sorted in increasing order, and are well-formed.
// "Classifying terminal weighted projective space", arXiv:1304.3029 [math.AG],
// Proposition 2.3.
function satisfy_terminal_bound(wts)
    n:=#wts - 1;
    h:=&+wts;
    for i in [2..n] do
        if wts[i+1] / h ge 1 / (n - i + 2) then
            return false;
        end if;
    end for;
    return true;
end function;

// Returns a random sequence of weights of length n with entries in 1..max such
// that the corresponding weighted projective space is terminal. The returned
// weights will be sorted in increasing order.
function generate_weights(n,max)
    while true do
        wts:=[Random(1,max) : i in [0..n]];
        Sort(~wts);
        if satisfy_terminal_bound(wts) and IsWellformed(wts) and
                                                    is_terminal(wts) then
            return wts;
        end if;
    end while;
    assert false;
end function;

// Returns a string description of the weights wts.
function to_string(wts)
    return "[" cat Join([IntegerToString(w) : w in wts],",") cat "]";
end function;

// Seed the set of found weights with the classification in dimensions 1, 2,
// and 3.
found:={
    [1,1],
    [1,1,1],
    [1,1,1,1],
    [1,1,1,2],
    [1,1,2,3],
    [1,2,3,5],
    [1,3,4,5],
    [2,3,5,7],
    [3,4,5,7]
};

// The maximum entry in the weights
max_weight:=10;

// The maximum dimension
max_dim:=10;

// The number of weights to generate
num_wts:=150000;

// Generate num_wts terminal weights at random
t:=Cputime();
while #found lt num_wts do
    n:=Random(4,max_weight);
    Include(~found,generate_weights(n,max_weight*n));
    if (#found mod 1000) eq 0 then
        printf "[%o / %o] %os\n",#found,num_wts,Cputime(t);
    end if;
end while;

// Output the weights to a file, one file per dimension
outfile:="rank_1_dim_%o.txt";
for wts in found do
    f:=Sprintf(outfile,#wts-1);
    fprintf f,"%o\n",to_string(wts);
end for;
