The code below works, but when I try to run it using P17 the compiler throws an error about the gcd proc. Using P17 causes gcd to be called on the order of 250,000 times, as modpg = 510510
Here's the code.
# Create constant parameters for chosen PG at compile time
proc genPGparameters(prime: int): (int, int, int, seq[int]) =
echo("generating parameters for P", prime)
let primes = [2, 3, 5, 7, 11, 13, 17, 19, 23]
var modpg = 1; var excluded_primescnt = 0
for prm in primes:
excluded_primescnt += 1; modpg *= prm; if prm == prime: break
var pc = 3; var residues: seq[int]; residues = @[]
while pc < modpg:
if gcd(modpg, pc) == 1: residues.add(pc)
pc += 2
residues.add(modpg + 1)
let rescnt = residues.len
result = (modpg, rescnt, excluded_primescnt, residues)
# Generate at compile time the parameters for P17
const parameters = genPGparameters(17)
Here's the relevant compiler output.
generating parameters for P17
stack trace: (most recent call last)
ssozp17x1d5bparnew128.nim(59)
ssozp17x1d5bparnew128.nim(52) genPGparameters
lib/pure/math.nim(439) gcd
lib/pure/math.nim(439, 15) Error: interpretation requires too many iterations
➜ nim
I can't see how gcd could care how many times it's being called, so it seems it must be the compiler not liking it being called past a certain number.
Whatever the reason, how do I get this code to finish compiling?
I'm trying to understand what you are suggesting with your response, especially because what I ultimately want to do in this instance I will want to do with other bigger generators.
What I assume you are saying is helper is some Nim source program that will produce the output that gemPGparameters does. The expression you give will then execute helper at run time and provide its results to const parameters at its compile time. Is this interpretation correct?
What I ultimately want to do is create a family of const parameters for different prime generators at compile time. Then when the program executes it will select which parameters to use based on the input value.
For P17 the residues array has 92,160 values, P19 has 1,658,880, P23 has 36,495,360.
So I ultimately want a lot of values computed and stored at compile time.
Your response suggests the current compiler won't accommodate this amount of data generation at compile time. I guess my question is why?
Why not create a compiler directive to remove any time/data constraints to compile time activity? Make the compiler do what the programmer wants.
Also, just from your response I don't have enough detailed information to make your suggestion work. Is this suggestion verified to provide the results I want? If so, can you give a detailed example of how to implement it?
I understand Nim is still young and in core fundamental development, so I hope you take this situation into consideration for future compiler development. I've been able to do a lot with Nim as it is (and I understand it), so these improvements will greatly extend its usefulness to the class of problems I am now working on.
Thanks for taking this into consideration.
What I assume you are saying is helper is some Nim source program that will produce the output that gemPGparameters does. The expression you give will then execute helper at run time and provide its results to const parameters at its compile time. Is this interpretation correct?
Exactly.
Your response suggests the current compiler won't accommodate this amount of data generation at compile time. I guess my question is why?
Well we don't want the compiler to run into infinite loops. And we cannot solve the halting problem either, so instead we restrict the number of back jumps in the VM. Btw the limit is currently at 1_500_000 which was enough for anything.
Why not create a compiler directive to remove any time/data constraints to compile time activity? Make the compiler do what the programmer wants.
Could be an option but since compile-time evaluation is slower than native code by a factor of about 20 I don't think this is doing potential client users of your module any favours. staticExec has been designed for these things, it can even cache the results.