Zulip Chat Archive
Stream: general
Topic: Coerce ring ideal to field ideal
Arnoud van der Leer (Apr 24 2021 at 16:35):
Hi there, it's me again. I am trying to complete the following proof. It should follow easily from mathlib, but apparently I am trying to prove something for an ideal of [ring R] while I have a hypothesis that says something about an ideal of [ring R upgraded to a field]. What am I missing?
lemma p2 {R: Type u} [comm_ring R] : is_field R → ∀ (I: ideal R), I = ⊥ ∨ I = ⊤ :=
begin
intros h,
have F := is_field.to_field R h,
have h2 := @ideal.eq_bot_or_top R F,
assumption,
end
Hanting Zhang (Apr 24 2021 at 16:38):
Arnoud van der Leer (Apr 24 2021 at 16:40):
Have you looked at the code?
Hanting Zhang (Apr 24 2021 at 16:45):
Argh, sorry, that was really bad of me. I see the problem now
Johan Commelin (Apr 24 2021 at 16:50):
@Arnoud van der Leer I'm afraid you need to reprove the eq_bot_or_top
lemma.
Johan Commelin (Apr 24 2021 at 16:51):
Oh, did you try convert h2
?
Kevin Buzzard (Apr 24 2021 at 16:52):
@Arnoud van der Leer can you post a #mwe? I cut and pasted your code but there were errors and I'm too lazy to fix them.
Arnoud van der Leer (Apr 24 2021 at 16:53):
@Johan Commelin
But if I have to reprove such a simple theorem, does that mean that every theorem about (R: Type u) [field R]
will have to reproved for (R: Type u) [comm_ring R] (h: is_field R)
and vice versa?
Kevin Buzzard (Apr 24 2021 at 16:53):
And is there a good reason you're using is_field
instead of [field R]
? This seems to be what's causing your problem, and I don't see any logical reason for doing it.
Kevin Buzzard (Apr 24 2021 at 16:54):
Yes maybe, and the moral is that you shouldn't be stating theorems like this at all I guess?
Arnoud van der Leer (Apr 24 2021 at 16:54):
convert h2
changes the goal to (∀ (I : ideal R), I = ⊥ ∨ I = ⊤) = ∀ (I : ideal R), I = ⊥ ∨ I = ⊤
.
Johan Commelin (Apr 24 2021 at 16:54):
@Arnoud van der Leer is_field
is a little bit of glue but isn't idiomatic.
Johan Commelin (Apr 24 2021 at 16:54):
So you should avoid it, whenever possible.
Arnoud van der Leer (Apr 24 2021 at 16:56):
@Kevin Buzzard
Oh, sorry, forgot the imports and universes
import ring_theory.ideal.basic
import algebra.field
universes u v
lemma p2 {R: Type u} [comm_ring R] : is_field R → ∀ (I: ideal R), I = ⊥ ∨ I = ⊤ :=
begin
intros h,
have F := is_field.to_field R h,
have h2 := @ideal.eq_bot_or_top R F,
convert h2,
assumption,
end
Kevin Buzzard (Apr 24 2021 at 16:57):
lemma p2 {R: Type u} [comm_ring R] : is_field R → ∀ (I: ideal R), I = ⊥ ∨ I = ⊤ :=
begin
intros h,
let F := is_field.to_field R h,
have h2 := @ideal.eq_bot_or_top R F,
convert h2,
end
Kevin Buzzard (Apr 24 2021 at 16:57):
Your problem was that F
is data, so needs to be defined with let
and not have
.
Arnoud van der Leer (Apr 24 2021 at 16:58):
The is_field
was because this is supposed to be part of a three-way equivalence (is there a nice way to prase this, by the way, or should I just make this two equivalences?) between
- R is a field
- R has only two ideals
- Any morphism from R into a nonzero ring is injective
And I thought if I took is_field instead of field, I would need to prove less for the other implications.
Arnoud van der Leer (Apr 24 2021 at 16:58):
Kevin Buzzard said:
Your problem was that
F
is data, so needs to be defined withlet
and nothave
.
Oooooh. Thank you!
Kevin Buzzard (Apr 24 2021 at 16:59):
import ring_theory.ideal.basic
import algebra.field
universes u v
lemma p2 {R: Type u} [comm_ring R] : is_field R → ∀ (I: ideal R), I = ⊥ ∨ I = ⊤ :=
begin
intros h,
letI := is_field.to_field R h,
apply ideal.eq_bot_or_top,
end
Your approach is unidiomatic so we have to jump through some hoops. letI
puts the field instance into the type class inference system, and now everything works as normal (you don't need the @)
Kevin Buzzard (Apr 24 2021 at 17:01):
Your explanation for why you're using is_field
is convincing, and is indeed the reason why is_field
is there. So you will have to learn to jump through the hoops :-) but that's what we're here for.
Kevin Buzzard (Apr 24 2021 at 17:02):
One of the differences between field
and is_field
is that is_field
lives in the Prop
universe, and field
lives in the Type
universe (because there is more data in field
than ring
due to a design decision; the inverse is an explicit input to a field
structure).
Kevin Buzzard (Apr 24 2021 at 17:05):
Another difference is that is_field
is a structure but field
is a class, so you will have to know something about how type class inference works. The typeclass system is a big database which keeps track of which things are groups, which things are rings etc. Normally you can just leave it alone, feed it with []
stuff at the beginning of your lemmas and defs, and it works fine -- you don't need to add to the database in the middle of a proof. But here what's happening is that half way through the proof you want to add something new to it because of the nature of what you're doing, and that's when letI
and haveI
come in handy because they enable you to do this.
Kevin Buzzard (Apr 24 2021 at 17:07):
There's no simple way to prove A <-> B <-> C in Lean without breaking it into two iff's, as far as I know. I think I've covered all your questions now :-)
Adam Topaz (Apr 24 2021 at 17:08):
Kevin Buzzard said:
There's no simple way to prove A <-> B <-> C in Lean without breaking it into two iff's, as far as I know. I think I've covered all your questions now :-)
There's a tfae
tactic, but I've never used it...
Johan Commelin (Apr 24 2021 at 17:10):
This is a perfect opportunity to use tfae
Bryan Gin-ge Chen (Apr 24 2021 at 17:11):
We have a few tfae
statements here and there in mathlib, but in my opinion they're a bit awkward to use because they require you to refer to numerical labels. See #3532 for a related feature request.
Kevin Buzzard (Apr 24 2021 at 17:11):
It's not a tactic, and I don't know the API for it :-)
import tactic
example (P Q R : Prop) (hPQ : P ↔ Q) (hQR : Q ↔ R) :
tfae [P, Q, R] :=
begin
simp [hPQ, hQR],
-- ⊢ [R, R, R].tfae
end
Bryan Gin-ge Chen (Apr 24 2021 at 17:12):
You're right, though the related tactic docs are under tactic#tfae .
Kevin Buzzard (Apr 24 2021 at 17:14):
import tactic
open list
example (P Q R : Prop) (hPQ : P ↔ Q) (hQR : Q ↔ R) :
tfae [P, Q, R] :=
begin
simp [hPQ, hQR, tfae_cons_of_mem, tfae_nil],
-- ⊢ [R, R, R].tfae -- aargh
sorry
end
lol
Bryan Gin-ge Chen (Apr 24 2021 at 17:15):
You just have to say the magic word at the end:
import tactic
example (P Q R : Prop) (hPQ : P ↔ Q) (hQR : Q ↔ R) :
tfae [P, Q, R] :=
begin
simp [hPQ, hQR],
tfae_finish,
end
Kevin Buzzard (Apr 24 2021 at 17:15):
example (P Q R : Prop) (hPQ : P ↔ Q) (hQR : Q ↔ R) :
tfae [P, Q, R] :=
begin
tfae_finish,
end
Johan Commelin (Apr 24 2021 at 17:16):
@Kevin Buzzard you want things like: tfae_have : 3 → 1,
Kevin Buzzard (Apr 24 2021 at 17:16):
Yes, I saw the docs now from Bryan's post.
Arnoud van der Leer (Apr 24 2021 at 17:57):
Kevin Buzzard said:
Another difference is that
is_field
is a structure butfield
is a class, so you will have to know something about how type class inference works. The typeclass system is a big database which keeps track of which things are groups, which things are rings etc. Normally you can just leave it alone, feed it with[]
stuff at the beginning of your lemmas and defs, and it works fine -- you don't need to add to the database in the middle of a proof. But here what's happening is that half way through the proof you want to add something new to it because of the nature of what you're doing, and that's whenletI
andhaveI
come in handy because they enable you to do this.
Thanks a lot for your explanations!
Last updated: Dec 20 2023 at 11:08 UTC