Zulip Chat Archive
Stream: maths
Topic: one_ne_zero in commutative rings: funny types
Julian Gilbey (Feb 19 2020 at 17:31):
I'm playing with lean, and trying to prove an "easy" result, namely that nilpotent elements are zero divisors. I've got very stuck, though, trying to prove that 1 is not 0. Here's where I've got to...
variables {α : Type u} [comm_ring α] def zero_divisor (x : α) := ∃ z, z ≠ 0 ∧ z * x = 0 def nilpotent (x : α) := ∃ n : nat, n > 0 ∧ x^n = 0 -- set_option pp.all true lemma zero_divisor_of_nilpotent { x : α } [ decidable_eq α ] [ zero_ne_one_class α ] (h : nilpotent (x : α)) : zero_divisor x := begin simp [nilpotent, zero_divisor] at *, obtain ⟨m, mprop⟩ := nat.find_x h, cases m with d, exfalso, exact (nat.not_lt_zero _ mprop.left.left), use (x ^ d), split, have := ((mprop.right d) (nat.lt_succ_self d)), intros h1, cases d with e, simp at h1, have h0 : (1 : α) ≠ 0, exact one_ne_zero, sorry, sorry, sorry, end
At this point (the first sorry
), I just want to say exact h0 h1
. But though they appear to be the right things, they are completely different, as shown by pp.all
, and this application of exact
completely fails. How on earth do I use one_ne_zero
, then?!
Thanks!
Johan Commelin (Feb 19 2020 at 17:33):
@Julian Gilbey I think an apology is in place... the library is very bad here.
Johan Commelin (Feb 19 2020 at 17:33):
I completely understand your confusion.
Johan Commelin (Feb 19 2020 at 17:33):
Short answer: use nonzero_comm_ring
and remove zero_ne_one_class
Johan Commelin (Feb 19 2020 at 17:33):
Then everything should work fine.
Johan Commelin (Feb 19 2020 at 17:35):
Long answer: zero_ne_one_class
is not a "property", but it includes the data of an element 0
, an element 1
+ the assertion that they are not equal. But these elements 0
and 1
are completely unrelated from the 0
and 1
provided by comm_ring
.
Johan Commelin (Feb 19 2020 at 17:35):
In other words, zero_ne_one_class
is completely useless
Johan Commelin (Feb 19 2020 at 17:35):
(Except that there are some technical reasons why one might want it for library development.)
Julian Gilbey (Feb 19 2020 at 17:35):
Aww, thanks!!
Johan Commelin (Feb 19 2020 at 17:35):
But for end users... it's just useless
Julian Gilbey (Feb 19 2020 at 17:42):
It doesn't seem to have helped, though. I've changed zero_ne_one_class
to nonzero_comm_ring
, and then changed this part of the argument to
simp at h1, have h0 : 0 ≠ (1 : α), exact zero_ne_one, exact h0 h1.symm,
but it's equally unhappy. How to I get the "correct" version of zero_ne_one
, or do I need to so something different?
Thanks!
Johan Commelin (Feb 19 2020 at 17:43):
Which instances do you now have?
Johan Commelin (Feb 19 2020 at 17:43):
Can you copy-paste your tactic state? (I.e., the goal window)
Johan Commelin (Feb 19 2020 at 17:44):
My guess is that it is still finding the wrong 0
and 1
because you have too many such elements.
Johan Commelin (Feb 19 2020 at 17:45):
@Julian Gilbey There should be no comm_ring \alpha
left in your code. Only nonzero_comm_ring \alpha
.
Julian Gilbey (Feb 19 2020 at 17:45):
It's long...
3 goals case nat.zero α : Type u, _inst_1 : comm_ring.{u} α, x : α, _inst_2 : decidable_eq.{u+1} α, _inst_3 : nonzero_comm_ring.{u} α, h : @Exists.{1} nat (λ (n : nat), and (@has_lt.lt.{0} nat nat.has_lt (@has_zero.zero.{0} nat nat.has_zero) n) (@eq.{u+1} α (@has_pow.pow.{u 0} α nat (@monoid.has_pow.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1))) x n) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1))))))), mprop : and ((λ (n : nat), and (@has_lt.lt.{0} nat nat.has_lt (@has_zero.zero.{0} nat nat.has_zero) n) (@eq.{u+1} α (@has_pow.pow.{u 0} α nat (@monoid.has_pow.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1))) x n) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1))))))) (nat.succ nat.zero)) (∀ (m : nat), @has_lt.lt.{0} nat nat.has_lt m (nat.succ nat.zero) → not ((λ (n : nat), and (@has_lt.lt.{0} nat nat.has_lt (@has_zero.zero.{0} nat nat.has_zero) n) (@eq.{u+1} α (@has_pow.pow.{u 0} α nat (@monoid.has_pow.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1))) x n) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1))))))) m)), this : not ((λ (n : nat), and (@has_lt.lt.{0} nat nat.has_lt (@has_zero.zero.{0} nat nat.has_zero) n) (@eq.{u+1} α (@has_pow.pow.{u 0} α nat (@monoid.has_pow.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1))) x n) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1))))))) nat.zero), h1 : @eq.{u+1} α (@has_one.one.{u} α (@monoid.to_has_one.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1)))) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1))))) ⊢ false case nat.succ α : Type u, _inst_1 : comm_ring.{u} α, x : α, _inst_2 : decidable_eq.{u+1} α, _inst_3 : nonzero_comm_ring.{u} α, h : @Exists.{1} nat (λ (n : nat), and (@has_lt.lt.{0} nat nat.has_lt (@has_zero.zero.{0} nat nat.has_zero) n) (@eq.{u+1} α (@has_pow.pow.{u 0} α nat (@monoid.has_pow.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1))) x n) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1))))))), e : nat, mprop : and ((λ (n : nat), and (@has_lt.lt.{0} nat nat.has_lt (@has_zero.zero.{0} nat nat.has_zero) n) (@eq.{u+1} α (@has_pow.pow.{u 0} α nat (@monoid.has_pow.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1))) x n) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1))))))) (nat.succ (nat.succ e))) (∀ (m : nat), @has_lt.lt.{0} nat nat.has_lt m (nat.succ (nat.succ e)) → not ((λ (n : nat), and (@has_lt.lt.{0} nat nat.has_lt (@has_zero.zero.{0} nat nat.has_zero) n) (@eq.{u+1} α (@has_pow.pow.{u 0} α nat (@monoid.has_pow.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1))) x n) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1))))))) m)), this : not ((λ (n : nat), and (@has_lt.lt.{0} nat nat.has_lt (@has_zero.zero.{0} nat nat.has_zero) n) (@eq.{u+1} α (@has_pow.pow.{u 0} α nat (@monoid.has_pow.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1))) x n) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1))))))) (nat.succ e)), h1 : @eq.{u+1} α (@has_pow.pow.{u 0} α nat (@monoid.has_pow.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1))) x (nat.succ e)) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1))))) ⊢ false α : Type u, _inst_1 : comm_ring.{u} α, x : α, _inst_2 : decidable_eq.{u+1} α, _inst_3 : nonzero_comm_ring.{u} α, h : @Exists.{1} nat (λ (n : nat), and (@has_lt.lt.{0} nat nat.has_lt (@has_zero.zero.{0} nat nat.has_zero) n) (@eq.{u+1} α (@has_pow.pow.{u 0} α nat (@monoid.has_pow.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1))) x n) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1))))))), d : nat, mprop : and ((λ (n : nat), and (@has_lt.lt.{0} nat nat.has_lt (@has_zero.zero.{0} nat nat.has_zero) n) (@eq.{u+1} α (@has_pow.pow.{u 0} α nat (@monoid.has_pow.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1))) x n) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1))))))) (nat.succ d)) (∀ (m : nat), @has_lt.lt.{0} nat nat.has_lt m (nat.succ d) → not ((λ (n : nat), and (@has_lt.lt.{0} nat nat.has_lt (@has_zero.zero.{0} nat nat.has_zero) n) (@eq.{u+1} α (@has_pow.pow.{u 0} α nat (@monoid.has_pow.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1))) x n) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1))))))) m)) ⊢ @eq.{u+1} α (@has_mul.mul.{u} α (@mul_zero_class.to_has_mul.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1)))) (@has_pow.pow.{u 0} α nat (@monoid.has_pow.{u} α (@ring.to_monoid.{u} α (@comm_ring.to_ring.{u} α _inst_1))) x d) x) (@has_zero.zero.{u} α (@mul_zero_class.to_has_zero.{u} α (@semiring.to_mul_zero_class.{u} α (@ring.to_semiring.{u} α (@comm_ring.to_ring.{u} α _inst_1)))))
Johan Commelin (Feb 19 2020 at 17:45):
_inst_1 : comm_ring.{u} α,
is the culprit.
Johan Commelin (Feb 19 2020 at 17:45):
Oooh, you could paste it without pp.all
set to true
.
Johan Commelin (Feb 19 2020 at 17:46):
Remove [comm_ring \alpha]
from your variables, and you should be good to go.
Julian Gilbey (Feb 19 2020 at 17:49):
Woo-hoo, thanks!!
Julian Gilbey (Feb 19 2020 at 17:50):
Johan Commelin said:
Oooh, you could paste it without
pp.all
set totrue
.
Without pp.all
set to true
, it just said that both h0
and h1
said 0 (not) equal to 1, so didn't give any hint as to what was wrong ;-)
Kevin Buzzard (Feb 19 2020 at 18:08):
Yes but there would still be visibly too many instances
Mario Carneiro (Feb 19 2020 at 20:06):
Johan Commelin said:
Long answer:
zero_ne_one_class
is not a "property", but it includes the data of an element0
, an element1
+ the assertion that they are not equal. But these elements0
and1
are completely unrelated from the0
and1
provided bycomm_ring
.In other words,
zero_ne_one_class
is completely useless
Interestingly, a comm ring with two random elements unequal is a nonzero ring, since a zero ring is a singleton. So it does work! (although you may have to get the order of the two instances right so that you get 0
and 1
coming from the comm_ring
instead of the random values in the zero_ne_one_class
.)
Johan Commelin (Feb 19 2020 at 20:07):
Ok, sure... but this is a very convoluted way of getting there...
Last updated: Dec 20 2023 at 11:08 UTC