Zulip Chat Archive
Stream: new members
Topic: How to decide prime without `Classical.choice`
Yijun Leng (Oct 15 2024 at 09:02):
Prime can be decided without LEM and Classical.choice
(correct me if I'm wrong)
My failed try
import Mathlib
import Mathlib.Tactic.Tauto
import Mathlib.Data.Nat.Prime.Defs
theorem hello : True :=
if Nat.Prime 10
then
by tauto
else
by tauto
lemma hello : True := by
cases Nat.decidablePrime 10 with
| isTrue _ => simp
| isFalse _ => simp
#print axioms hello
-- depends on axioms: [propext, Classical.choice, Quot.sound]
I want to decide prime without Classical.choice
Yijun Leng (Oct 15 2024 at 09:03):
related discussions
https://leanprover.zulipchat.com/#narrow/stream/348111-batteries/topic/Batteries.20and.20LEM/near/472756638
Ruben Van de Velde (Oct 15 2024 at 09:25):
Why?
Philippe Duchon (Oct 15 2024 at 09:42):
Primeness in is clearly decidable, so if the Lean version depends on additional axioms, I would suspect it is because it is written in a much more general context where things are not always decidable? (like, since operations in are not computable, I suspect primeness in is not decidable either)
(Is primeness a word? Not sure)
Yijun Leng (Oct 15 2024 at 09:46):
Ruben Van de Velde said:
Why?
I come from coq and I prefer constructive logic
Yijun Leng (Oct 15 2024 at 09:48):
is there any tactic specific to Decidable
and can avoid LEM ?
Riccardo Brasca (Oct 15 2024 at 09:53):
Mathlib is not designed to use constructive logic. By this I mean that if you start using tactics it's very difficult to avoid choice. This is because we essentially didn't pay too much attention to do so, even if in principle it is possible.
Kevin Buzzard (Oct 15 2024 at 10:26):
You could certainly write your own decidability instance for the predicate because it's certainly decidable. The moment you do this though, you run into the issue that there are people who just want an abstract decidability algorithm and those who actually want to run something because they care about examples, ie "theoretical decidability" v "decidability in practice". The mathlib approach in general is just to ignore all of these questions because we're mostly focused on proving theorems in classical mathematics.
Eric Wieser (Oct 15 2024 at 10:30):
To be clear, your objection is that
#print axioms Nat.decidablePrime
emits Classical.choice
, right?
Eric Wieser (Oct 15 2024 at 10:30):
Kevin Buzzard said:
ie "theoretical decidability" v "decidability in practice". The mathlib approach in general is just to ignore all of these questions because we're mostly focused on proving theorems in classical mathematics.
I don't think this is true. Nat.decidablePrime
is an example of something that is "decidable in practice" (as it is computable), but might not be considered "theoretically decidable" to a strict constructivist.
Yijun Leng (Oct 15 2024 at 10:31):
Eric Wieser said:
To be clear, your objection is that
#print axioms Nat.decidablePrime
emits
Classical.choice
, right?
yes
Eric Wieser (Oct 15 2024 at 10:33):
The presence of Classical.choice
here does not mean "the decision procedure uses the axiom of choice", but rather "the proof that the decision procedure is correct uses the axiom of choice".
Eric Wieser (Oct 15 2024 at 10:35):
If it were the former, then Lean would additionally tell you it was noncomputable
Luigi Massacci (Oct 15 2024 at 10:50):
As a further example
theorem hello'' : ¬(Nat.Prime 10) := by norm_num
#print axioms hello''
-- depends on axioms: [propext]
Yijun Leng (Oct 15 2024 at 10:51):
Luigi Massacci said:
As a further example
theorem hello'' : ¬(Nat.Prime 10) := by norm_num #print axioms hello'' -- depends on axioms: [propext]
nice
But I need to judge prime on variable in practise
Kevin Buzzard (Oct 15 2024 at 10:54):
Then you don't need an abstract decidability proof, you need a practical algorithm
Kevin Buzzard (Oct 15 2024 at 10:59):
And mathlib has the abstract prerequisites you'll need to write such an algorithm, but nobody wrote a practical algorithm yet as far as I know. Most algorithms one uses in practice are probabilistic but of course there are good non-probabilistic ones nowadays after the breakthroughs from the beginning of this century. But proving such an algorithm correct might be a nontrivial project.
Eric Wieser (Oct 15 2024 at 10:59):
Kevin, isn't docs#Nat.decidablePrime precisely the algorithm in question?
Kevin Buzzard (Oct 15 2024 at 11:00):
Without even looking at the code I would confidently guess that this is an exponential time algorithm. Polynomial time algorithms for primality testing have been known for around 20 years.
Kevin Buzzard (Oct 15 2024 at 11:04):
However probabilistic poly time algorithms are much older, and when you're at the point where the chances that the algorithm is failing is smaller than the chance that a gamma ray flipped a bit then this is in practice good enough for most people in practice.
Eric Wieser (Oct 15 2024 at 11:04):
#eval Nat.Prime 109139149179199
takes about 1.5s, so I guess "practical" really depends on how large the inputs @lengyijun cares about are
Eric Wieser (Oct 15 2024 at 11:05):
If they only care about n = 10
, a practical algorithm is return false
!
Kevin Buzzard (Oct 15 2024 at 11:06):
? isprime(109139149179199)
%5 = 1
? ##
*** last result: cpu time 0 ms, real time 0 ms.
Pari-GP seems to be infinitely faster! (modulo rounding errors)
Luigi Massacci (Oct 15 2024 at 11:13):
Kevin Buzzard said:
Without even looking at the code I would confidently guess that this is an exponential time algorithm. Polynomial time algorithms for primality testing have been known for around 20 years.
Do you mean exponential time in the number of bits? Because minFac
just does the very basic “keep dividing until you get to ” thing, so it is in fact poly-time in
Yaël Dillies (Oct 15 2024 at 13:06):
Luigi Massacci said:
Do you mean exponential time in the number of bits?
Yes, because that's the size of the input
Kyle Miller (Oct 15 2024 at 22:36):
Just to check @lengyijun, are you aware that even if #print axioms
shows Classical.choice
that Nat.Prime
can still be computable? If I write
def calcIsPrime (n : Nat) : Bool := decide (Nat.Prime n)
then since there are no warnings, Lean has succeeded in compiling it to executable code.
This isn't even just a compiler trick. In this case, it also is reducible:
#reduce decide (Nat.Prime 131)
-- true
#reduce decide (Nat.Prime 132)
-- false
Yijun Leng (Oct 17 2024 at 11:57):
I'm working on https://github.com/lengyijun/goldbach_tm
I hope all theorems don't depend on Classical.choice
Henrik Böving (Oct 17 2024 at 12:00):
Why?
Yijun Leng (Oct 17 2024 at 12:02):
Henrik Böving said:
Why?
prime should be decidable without Classical.choice
Ruben Van de Velde (Oct 17 2024 at 12:21):
Most people here don't care about that. You're unlikely to convince anyone by just blandly asserting that this should be a goal
Mario Carneiro (Oct 18 2024 at 22:19):
Kevin Buzzard said:
Without even looking at the code I would confidently guess that this is an exponential time algorithm. Polynomial time algorithms for primality testing have been known for around 20 years.
Note that this conflates "polynomial time" and "practical algorithm". The AKS algorithm is generally not regarded as practically useful, compared to probabilistic algorithms that run much faster.
Mario Carneiro (Oct 18 2024 at 22:20):
I think some elliptic curve algorithms (which are subexponential) are not probabilistic and still run faster in practice than AKS except on some really stupidly large primes
Kevin Buzzard (Oct 19 2024 at 08:05):
If they're not polynomial then I can guarantee that they'll not run faster than AKS on some really stupidly large primes :-) And of course this set does represent 100% of primes :-)
Daniel Weber (Oct 19 2024 at 08:14):
Apparently ECPP is conjectured to be asymptotically faster than AKS
Kevin Buzzard (Oct 19 2024 at 10:45):
Ah so indeed I'm wrong! The ECPP algorithm seems to be "polynomial time most of the time" but not (yet?) provably poly time. So perhaps that's the one we want. There might be some large random primes where AKS is better but I hadn't until now grokked that a non poly time algo can often be poly time anyway (so my 100% claim falls over). I guess this is also true for the simplex algorithm.
Philippe Duchon (Oct 19 2024 at 17:21):
This is, in a sense, proved for the simplex algorithm. IIRC, every neighborhood of an instance contains mostly instances for which the simplex algorithm performs efficiently (though I am not sure of the exact statement).
Last updated: May 02 2025 at 03:31 UTC