diff --git a/src/tests/util/numerics/primes.cpp b/src/tests/util/numerics/primes.cpp index a2ea9a1099..9235720d93 100644 --- a/src/tests/util/numerics/primes.cpp +++ b/src/tests/util/numerics/primes.cpp @@ -24,8 +24,20 @@ static void tst1() { std::cout << "\n"; } +static void tst2() { + prime_iterator it; + for (unsigned i = 0; i < 100000; i++) { + uint64 p = it.next(); + lean_assert(is_prime(p)); + if (i % 1000 == 0) + std::cout << p << " "; std::cout.flush(); + } + std::cout << "\n"; +} + int main() { tst1(); + tst2(); return has_violations() ? 1 : 0; } diff --git a/src/util/numerics/primes.cpp b/src/util/numerics/primes.cpp index 6b623e921f..5a38cb587e 100644 --- a/src/util/numerics/primes.cpp +++ b/src/util/numerics/primes.cpp @@ -106,4 +106,21 @@ uint64 prime_iterator::next() { return g_prime_generator(idx); } } + +bool is_prime(uint64 p) { + // Naive is_prime implementation that tests for divisors up to sqrt(p), + // and skips multiples of 2 and 3 + if (p == 2 || p == 3) + return true; + uint64 i = 5; + while (i*i <= p) { + if (p % i == 0) + return false; + i += 2; + if (p % i == 0) + return false; + i += 3; + } + return true; +} } diff --git a/src/util/numerics/primes.h b/src/util/numerics/primes.h index 7cb33fd1ba..04dab63414 100644 --- a/src/util/numerics/primes.h +++ b/src/util/numerics/primes.h @@ -7,13 +7,14 @@ Author: Leonardo de Moura #include "util/uint64.h" namespace lean { -/** - \brief Prime number iterator. It can be used to enumerate the first LEAN_PRIME_LIST_MAX_SIZE primes. -*/ +/** \brief Prime number iterator. It can be used to enumerate the first LEAN_PRIME_LIST_MAX_SIZE primes. */ class prime_iterator { unsigned m_idx; public: prime_iterator(); + /** \brief Return the next prime */ uint64 next(); }; +/** \brief Return true iff \c p is a prime number. */ +bool is_prime(uint64 p); }