Zulip Chat Archive
Stream: mathlib4
Topic: Data.Nat.EvenOddRec
Shreyas Srinivas (Dec 21 2022 at 12:31):
I noticed that Nat.odd_even_rec
has not been taken up yet. I'd like to take it up. Is there anything I should know (for e.g. : this file being on the "not to be ported" list?)
Shreyas Srinivas (Dec 21 2022 at 12:35):
Fixed: Also I don't see data.nat.bits
and init.data.nat.bitwise
in master yet. I thought this was already merged (see: mathlib4#1095
Shreyas Srinivas (Dec 21 2022 at 12:49):
Arien Malec (Dec 21 2022 at 15:52):
I looked at it briefly --- it uses bit1
, bit0
and theorems about bit
and bit0/1
heavily so probably wants some design thought to use a more sensible definition of parity or blaze on.
Shreyas Srinivas (Dec 21 2022 at 15:55):
Is this something that needs to be done during or after the port?
Mario Carneiro (Dec 21 2022 at 15:58):
it's best to just translate as is for now; deprecate anything with bit0
/bit1
in the statement and put a TODO on any proofs that require referencing deprecated definitions (but otherwise translate them as normal), and do it all in a section deprecated
where you turn off the linter (and put another TODO on that)
Shreyas Srinivas (Dec 21 2022 at 16:33):
In addition, the purpose of this file is to give users the option to avoid using bit0
and bit1
. So it seems like a good idea to port it. I will try to finish by tonight (CET)
Shreyas Srinivas (Dec 22 2022 at 00:37):
So, I just started making the non-trivial fixes. In doing so there was a problem with lean not being able to fill in the implicit parameters of binary_rec_eq. So I supplied them. I got one of the strangest errors I have seen thus far:
Hb : ∀ (z : P 0), brecPind false 0 z = z
application type mismatch
binary_rec_eq (Hb h0)
argument
Hb h0
has type
@Eq (P (bit false 0)) (brecPind false 0 h0) h0 : Prop
but is expected to have type
@Eq (P (bit false 0)) (brecPind false 0 h0) h0 : Prop
Shreyas Srinivas (Dec 22 2022 at 00:39):
(deleted)
Shreyas Srinivas (Dec 22 2022 at 00:41):
Here's the #mwe:
import Mathlib.Data.Nat.Basic
import Mathlib.Init.Data.Nat.Bitwise
namespace Nat
@[elab_as_elim]
def evenOddRec {P : ℕ → Sort _} (h0 : P 0) (h_even : ∀ (n) (ih : P n), P (2 * n))
(h_odd : ∀ (n) (ih : P n), P (2 * n + 1)) (n : ℕ) : P n := by
refine' binaryRec h0 (fun b i hi => _) n
cases b
· simpa [bit, bit0_val i] using h_even i hi
· simpa [bit, bit1_val i] using h_odd i hi
#align nat.even_odd_rec Nat.evenOddRec
@[simp]
theorem even_odd_rec_zero (P : ℕ → Sort _) (h0 : P 0) (h_even : ∀ i, P i → P (2 * i))
(h_odd : ∀ i, P i → P (2 * i + 1)) : @evenOddRec _ h0 h_even h_odd 0 = h0 :=
binary_rec_zero _ _
#align nat.even_odd_rec_zero Nat.even_odd_rec_zero
@[simp]
theorem even_odd_rec_even (n : ℕ) (P : ℕ → Sort _) (h0 : P 0) (h_even : ∀ i, P i → P (2 * i))
(h_odd : ∀ i, P i → P (2 * i + 1)) (H : h_even 0 h0 = h0) :
@evenOddRec _ h0 h_even h_odd (2 * n) = h_even n (evenOddRec h0 h_even h_odd n) := by
have bit_val_zero : ∀ n, 2 * n = bit false n := by
intro
rw[bit_val, cond]
simp
have bit_val_one : ∀ n, 2*n+1 = bit true n := by
intro
rw [bit_val, cond]
let brecPind : (b : Bool) → (n : ℕ) → P n -> P (bit b n):= λ (b : Bool) (n : ℕ) (h_n : P n) => by
cases b
case false =>
have h_2n : P (2*n) := h_even n h_n
rw [bit_val_zero] at h_2n
exact h_2n
case true =>
have h_2n_1 : P (2*n + 1) := h_odd n h_n
rw [bit_val_one] at h_2n_1
exact h_2n_1
have Hb: ∀ z, brecPind false 0 z = z := sorry
refine @binary_rec_eq P h0 (fun b n => _) (Hb h0) false n
· exact (bit0_eq_two_mul _).symm
· exact (bit0_eq_two_mul _).symm
· apply heq_of_cast_eq
rfl
· exact H
@[simp]
theorem even_odd_rec_odd (n : ℕ) (P : ℕ → Sort _) (h0 : P 0) (h_even : ∀ i, P i → P (2 * i))
(h_odd : ∀ i, P i → P (2 * i + 1)) (H : h_even 0 h0 = h0) :
@evenOddRec _ h0 h_even h_odd (2 * n + 1) = h_odd n (evenOddRec h0 h_even h_odd n) := by
convert binary_rec_eq _ true n
· exact (bit0_eq_two_mul _).symm
· exact (bit0_eq_two_mul _).symm
· apply heq_of_cast_eq
rfl
· exact H
end Nat
Shreyas Srinivas (Dec 22 2022 at 00:41):
You can see the other theorem in its pristine lean3 form for comparison. The proofs are almost entirely identical
Shreyas Srinivas (Dec 22 2022 at 00:43):
The question is, how does this error even make sense?
argument
Hb h0
has type
@Eq (P (bit false 0)) (brecPind false 0 h0) h0 : Prop
but is expected to have type
@Eq (P (bit false 0)) (brecPind false 0 h0) h0 : Prop
Kevin Buzzard (Dec 22 2022 at 00:45):
If you switch pp.all
on you'll see they're different.
Shreyas Srinivas (Dec 22 2022 at 00:47):
But @Eq
seems to suggest that all implicit parameters are already in there
Kevin Buzzard (Dec 22 2022 at 00:48):
yeah you're right, I don't see why they can't match.
Kevin Buzzard (Dec 22 2022 at 00:48):
Oh but pp.all shows more than just the implicit parameters -- everything has to match -- but I don't see why it won't match.
Shreyas Srinivas (Dec 22 2022 at 00:54):
Ok I think I fixed it.
Kevin Buzzard (Dec 22 2022 at 00:56):
Nice. I would really not recommend doing what you're doing though: you're defining brecPind
in tactic mode with rw
so there will be random stuck eq.rec
s in your definition and it will be hell to work with.
Shreyas Srinivas (Dec 22 2022 at 00:57):
What's the cleaner method?
Kevin Buzzard (Dec 22 2022 at 00:57):
I don't know enough about Lean 4 to answer this :-(
Kevin Buzzard (Dec 22 2022 at 00:59):
But this approach is not being used in the Lean 3 file. Did you have to diverge from the autoported file for some reason?
Shreyas Srinivas (Dec 22 2022 at 01:00):
Yeah
You can see the proof of the theorem after. These two proofs are exactly identical (except true vs false)
Shreyas Srinivas (Dec 22 2022 at 01:00):
even_odd_rec_odd
Shreyas Srinivas (Dec 22 2022 at 01:01):
The error you get there is
don't know how to synthesize implicit argument
@binary_rec_eq ?m.5713 ?m.5714 ?m.5715 ?m.5716 true n
Shreyas Srinivas (Dec 22 2022 at 01:03):
The second one is the mathlib3 version with the minor corrections necessary for mathlib4 (tt => true, ff => false)
Kevin Buzzard (Dec 22 2022 at 01:04):
I would be tempted to convert @binary_rec_eq _ _ _ _ true n
and then try and fill in the blanks
Shreyas Srinivas (Dec 22 2022 at 01:05):
Doesn't work. The first two blanks are easy to fill. This still leaves the blank for the parameter f
which is where brecPind
comes in
Shreyas Srinivas (Dec 22 2022 at 01:11):
Also, I am learning that unfold looks for names only in _root_.
. It wont unfold brecPind
Kevin Buzzard (Dec 22 2022 at 01:15):
yeah this sort of thing is hell, and a very long way from my area of expertise (I'm a mathematician).
Shreyas Srinivas (Dec 22 2022 at 01:16):
Here's a funny goal when I use brecPind: instMulNat = { mul := Nat.add }
Shreyas Srinivas (Dec 22 2022 at 01:17):
I am beginning to think lean4 believes 2+2 = potato
Kevin Buzzard (Dec 22 2022 at 01:27):
Lean 3 convert
seems more powerful than Lean 4 convert
here?
Shreyas Srinivas (Dec 22 2022 at 01:30):
or probably even broken
Shreyas Srinivas (Dec 22 2022 at 01:31):
As far as I know this is false. In another case
it asked me to show n=2
, without any relevant additional hypothesis.
Shreyas Srinivas (Dec 22 2022 at 01:33):
My limited understanding of lean tactics is that they make sound transformations
Kevin Buzzard (Dec 22 2022 at 01:34):
Shreyas Srinivas said:
Also, I am learning that unfold looks for names only in
_root_.
. It wont unfoldbrecPind
You could try defining it outside the proof. In Lean 3 we use a trick called eq_to_hom
which given a proof that a = b
will give you a map from P a
to P b
, and we have a bunch of API around it.
Shreyas Srinivas (Dec 22 2022 at 01:35):
I don't think that works in this case. We will have to parametrise on the predicate P
. This will bring us back to square one
Shreyas Srinivas (Dec 22 2022 at 01:36):
In any case, I worked around the unfold
limitation`
Shreyas Srinivas (Dec 22 2022 at 01:36):
convert
's doc-string says it is actually an improved version of refine
which means it is less strict about providing complete terms. So it is odd that it cannot handle implicit terms that lean3's version can, or that it can produce absurd looking goals.
Mario Carneiro (Dec 22 2022 at 01:38):
it's not odd that convert
will produce false goals sometimes, this usually means it has gone too deep and you need to use convert ... using 1
or so
Kevin Buzzard (Dec 22 2022 at 01:41):
The issue is that convert
refuses to eat binary_rec_eq _ true n
in Lean 4 whereas it did so in Lean 3 -- the tactic fails in Lean 4.
Mario Carneiro (Dec 22 2022 at 01:42):
would be nice if there was an MWE that didn't require me to pull the branch...
Kevin Buzzard (Dec 22 2022 at 01:42):
You can see the problem in the MWE posted above. Forget about the long broken proof: the proof after is
@[simp]
theorem even_odd_rec_odd (n : ℕ) (P : ℕ → Sort _) (h0 : P 0) (h_even : ∀ i, P i → P (2 * i))
(h_odd : ∀ i, P i → P (2 * i + 1)) (H : h_even 0 h0 = h0) :
@evenOddRec _ h0 h_even h_odd (2 * n + 1) = h_odd n (evenOddRec h0 h_even h_odd n) := by
convert binary_rec_eq _ true n
· exact (bit0_eq_two_mul _).symm
· exact (bit0_eq_two_mul _).symm
· apply heq_of_cast_eq
rfl
· exact H
This is what the autoporter produced. But the convert
fails and I've just spent an hour trying to make it not fail, and failed.
Shreyas Srinivas (Dec 22 2022 at 01:42):
Shreyas Srinivas said:
Here's the #mwe:
import Mathlib.Data.Nat.Basic import Mathlib.Init.Data.Nat.Bitwise namespace Nat @[elab_as_elim] def evenOddRec {P : ℕ → Sort _} (h0 : P 0) (h_even : ∀ (n) (ih : P n), P (2 * n)) (h_odd : ∀ (n) (ih : P n), P (2 * n + 1)) (n : ℕ) : P n := by refine' binaryRec h0 (fun b i hi => _) n cases b · simpa [bit, bit0_val i] using h_even i hi · simpa [bit, bit1_val i] using h_odd i hi #align nat.even_odd_rec Nat.evenOddRec @[simp] theorem even_odd_rec_zero (P : ℕ → Sort _) (h0 : P 0) (h_even : ∀ i, P i → P (2 * i)) (h_odd : ∀ i, P i → P (2 * i + 1)) : @evenOddRec _ h0 h_even h_odd 0 = h0 := binary_rec_zero _ _ #align nat.even_odd_rec_zero Nat.even_odd_rec_zero @[simp] theorem even_odd_rec_even (n : ℕ) (P : ℕ → Sort _) (h0 : P 0) (h_even : ∀ i, P i → P (2 * i)) (h_odd : ∀ i, P i → P (2 * i + 1)) (H : h_even 0 h0 = h0) : @evenOddRec _ h0 h_even h_odd (2 * n) = h_even n (evenOddRec h0 h_even h_odd n) := by have bit_val_zero : ∀ n, 2 * n = bit false n := by intro rw[bit_val, cond] simp have bit_val_one : ∀ n, 2*n+1 = bit true n := by intro rw [bit_val, cond] let brecPind : (b : Bool) → (n : ℕ) → P n -> P (bit b n):= λ (b : Bool) (n : ℕ) (h_n : P n) => by cases b case false => have h_2n : P (2*n) := h_even n h_n rw [bit_val_zero] at h_2n exact h_2n case true => have h_2n_1 : P (2*n + 1) := h_odd n h_n rw [bit_val_one] at h_2n_1 exact h_2n_1 refine @binary_rec_eq P h0 brecPind H false n · exact (bit0_eq_two_mul _).symm · exact (bit0_eq_two_mul _).symm · apply heq_of_cast_eq rfl · exact H @[simp] theorem even_odd_rec_odd (n : ℕ) (P : ℕ → Sort _) (h0 : P 0) (h_even : ∀ i, P i → P (2 * i)) (h_odd : ∀ i, P i → P (2 * i + 1)) (H : h_even 0 h0 = h0) : @evenOddRec _ h0 h_even h_odd (2 * n + 1) = h_odd n (evenOddRec h0 h_even h_odd n) := by convert binary_rec_eq _ true n · exact (bit0_eq_two_mul _).symm · exact (bit0_eq_two_mul _).symm · apply heq_of_cast_eq rfl · exact H end Nat
Here
Shreyas Srinivas (Dec 22 2022 at 01:42):
It's the entire file because I wanted to show multiple things
Shreyas Srinivas (Dec 22 2022 at 01:43):
Made some changes
Shreyas Srinivas (Dec 22 2022 at 01:46):
- The lean3 proof of
even_odd_rec_odd
andeven_odd_rec_even
are identical - If you open the #mwe now. In
even_odd_rec_even
I had to insert explicit arguments (same aseven_odd_rec_odd
, but I left it untouched for reference). These produced absurd case distinctions.
Mario Carneiro (Dec 22 2022 at 01:46):
this MWE shouldn't need any imports at all
Kevin Buzzard (Dec 22 2022 at 01:46):
You need binaryRec
Mario Carneiro (Dec 22 2022 at 01:47):
then state it
Kevin Buzzard (Dec 22 2022 at 01:47):
It compiles fine on mathlib master and building the imports is also super-quick
Shreyas Srinivas (Dec 22 2022 at 01:47):
Bitwise is necessary. binaryRec, binary_rec_eq, and all basic Nat stuff
Shreyas Srinivas (Dec 22 2022 at 01:47):
It also works quickly on the lean4 playground
Mario Carneiro (Dec 22 2022 at 01:48):
I've been building since 5 minutes ago -_-
Kevin Buzzard (Dec 22 2022 at 01:48):
you need bodd
and all the other stuff Shreyas has been porting over the last few days. A mathlib-free MWE would be horrible
Mario Carneiro (Dec 22 2022 at 01:48):
switching branches is super painful because of the nightly bumps
Kevin Buzzard (Dec 22 2022 at 01:48):
Is it possible to make tools to make MWEs?
Shreyas Srinivas (Dec 22 2022 at 01:48):
Mario Carneiro (Dec 22 2022 at 01:49):
I tried that and failed on the imports
Shreyas Srinivas (Dec 22 2022 at 01:49):
You can open this on the playground
Mario Carneiro (Dec 22 2022 at 01:49):
because I was on a branch from yesterday I guess
Mario Carneiro (Dec 22 2022 at 01:50):
but for an MWE there are way too many lines
Shreyas Srinivas (Dec 22 2022 at 01:50):
I used the playground button on the screenshot
Shreyas Srinivas (Dec 22 2022 at 01:51):
Mario Carneiro said:
because I was on a branch from yesterday I guess
It's one def, one trivial theorem, and two nearly identical theorems. At best, the first trivial theorem could be removed, but that might also cause problems. The other two theorems depend on the def.
Shreyas Srinivas (Dec 22 2022 at 01:52):
And both these theorems have the same issue.
- In the first one, I show what happens when you give explicit arguments to the convert line.
- In the second one, I leave the lean3 version of the proof as is, so you can see the issue with the mathlib3 version of the proof.
Shreyas Srinivas (Dec 22 2022 at 01:52):
I don't see any meaningful ways to reduce this.
Mario Carneiro (Dec 22 2022 at 01:54):
import Mathlib.Data.Nat.Basic
def bit (b : Bool) : ℕ → ℕ := cond b bit1 bit0
theorem bit0_val (n : Nat) : bit0 n = 2 * n := sorry
theorem bit1_val (n : Nat) : bit1 n = 2 * n + 1 := sorry
def binaryRec {C : Nat → Sort u} (z : C 0) (f : ∀ b n, C n → C (bit b n)) : ∀ n, C n := sorry
theorem binary_rec_eq {C : Nat → Sort u} {z : C 0} {f : ∀ b n, C n → C (bit b n)}
(h : f false 0 z = z) (b n) : binaryRec z f (bit b n) = f b n (binaryRec z f n) := sorry
@[elab_as_elim]
def evenOddRec {P : ℕ → Sort _} (h0 : P 0) (h_even : ∀ (n) (ih : P n), P (2 * n))
(h_odd : ∀ (n) (ih : P n), P (2 * n + 1)) (n : ℕ) : P n := by
refine' binaryRec h0 (fun b i hi => _) n
cases b
· simpa [bit, bit0_val i] using h_even i hi
· simpa [bit, bit1_val i] using h_odd i hi
@[simp]
theorem even_odd_rec_odd (n : ℕ) (P : ℕ → Sort _) (h0 : P 0) (h_even : ∀ i, P i → P (2 * i))
(h_odd : ∀ i, P i → P (2 * i + 1)) (H : h_even 0 h0 = h0) :
@evenOddRec _ h0 h_even h_odd (2 * n + 1) = h_odd n (evenOddRec h0 h_even h_odd n) := by
convert binary_rec_eq _ true n
Mario Carneiro (Dec 22 2022 at 01:55):
you can get rid of nat.basic too if you remove the \N
syntax, but we don't need to go full mathlib-free here since convert
is a mathlib tactic anyway
Kevin Buzzard (Dec 22 2022 at 02:02):
yeah but you've sorried a bunch of data now, so if you get the convert
working then it might not work in the actual use case?
Mario Carneiro (Dec 22 2022 at 02:03):
true, if definition unfolding is involved then you should provide the bodies of defs
Kevin Buzzard (Dec 22 2022 at 02:09):
In this case it would take a lot longer to make the mwe (with only proofs sorried) than it would take you to compile Data.Nat.Basic :-( It can take a super-long time to make mathlib-free mwes now, this is why I was asking about auto-generating them (apparently they can do it in Coq?)
Mario Carneiro (Dec 22 2022 at 02:09):
Auto-generating MWEs would be very cool
Mario Carneiro (Dec 22 2022 at 02:09):
I think there are a couple levels we have to unlock before we can get there though
Mario Carneiro (Dec 22 2022 at 02:10):
But the set of things that come to bear on a single line of proof is generally approximately constant
Mario Carneiro (Dec 22 2022 at 02:11):
(unless it's a really bad definition-unfolding proof or a typeclass problem)
Shreyas Srinivas (Dec 22 2022 at 02:12):
Mario Carneiro said:
Auto-generating MWEs would be very cool
Could this not be hard to debug though? Especially in tactic heavy proofs
Mario Carneiro (Dec 22 2022 at 02:12):
why?
Shreyas Srinivas (Dec 22 2022 at 02:12):
Kevin Buzzard said:
yeah but you've sorried a bunch of data now, so if you get the
convert
working then it might not work in the actual use case?
This for example
Mario Carneiro (Dec 22 2022 at 02:12):
the other tactics in the proof are hopefully not relevant and can be removed
Mario Carneiro (Dec 22 2022 at 02:13):
As long as convert
doesn't unfold the definition, it doesn't matter what's behind it
Mario Carneiro (Dec 22 2022 at 02:13):
In this case I belatedly realized you are unfolding evenOddRec
to binaryRec
in this line of proof so we need that definition, but not the stack leading up to binaryRec
Shreyas Srinivas (Dec 22 2022 at 02:31):
In broad terms: Tactics are doing very useful, but invisible work behind the scenes . It takes time to hone one's understanding about their exact behaviour. So one can only make educated guesses about what causes the error one observes using the tactic state output (and maybe pp). For example, if Kevin had not pointed out that sorrying out things might remove errors in downstream tactic uses, I would assume that such an example is in fact adequate.
Mario Carneiro (Dec 22 2022 at 02:32):
I think it's fine to start with aggressive sorrying and re-add stuff if it turns out it was oversimplified
Mario Carneiro (Dec 22 2022 at 02:34):
@[elab_as_elim]
def evenOddRec {P : ℕ → Sort _} (h0 : P 0) (h_even : ∀ (n) (ih : P n), P (2 * n))
(h_odd : ∀ (n) (ih : P n), P (2 * n + 1)) (n : ℕ) : P n :=
binaryRec h0 (fun
| false, i, hi => (bit0_val i ▸ h_even i hi : P (bit0 i))
| true, i, hi => (bit1_val i ▸ h_odd i hi : P (bit1 i))) n
@[simp]
theorem even_odd_rec_even (n : ℕ) (P : ℕ → Sort _) (h0 : P 0) (h_even : ∀ i, P i → P (2 * i))
(h_odd : ∀ i, P i → P (2 * i + 1)) (H : h_even 0 h0 = h0) :
@evenOddRec _ h0 h_even h_odd (2 * n) = h_even n (evenOddRec h0 h_even h_odd n) :=
have : ∀ a, bit false n = a → HEq (@evenOddRec _ h0 h_even h_odd a) _
| _, rfl => by rw [evenOddRec, binary_rec_eq]; apply eq_rec_heq; exact H
eq_of_heq (this _ (bit0_val _))
@[simp]
theorem even_odd_rec_odd (n : ℕ) (P : ℕ → Sort _) (h0 : P 0) (h_even : ∀ i, P i → P (2 * i))
(h_odd : ∀ i, P i → P (2 * i + 1)) (H : h_even 0 h0 = h0) :
@evenOddRec _ h0 h_even h_odd (2 * n + 1) = h_odd n (evenOddRec h0 h_even h_odd n) :=
have : ∀ a, bit true n = a → HEq (@evenOddRec _ h0 h_even h_odd a) _
| _, rfl => by rw [evenOddRec, binary_rec_eq]; apply eq_rec_heq; exact H
eq_of_heq (this _ (bit1_val _))
Shreyas Srinivas (Dec 22 2022 at 02:40):
okay that worked wow!
Shreyas Srinivas (Dec 22 2022 at 02:40):
I will commit this as is, but I am going to spend some time understanding this afterwards
Shreyas Srinivas (Dec 22 2022 at 03:03):
So in this proof you used heterogeneous equality, which I am guessing coerces equality between values of different types. Is there like a comprehensive list of ways this can go wrong (apart from the congr
issue)? It seems quite handy for functional programmers, so I can see this getting wrongly used
Shreyas Srinivas (Dec 22 2022 at 03:07):
Data.Nat.EvenOddRec
passed all checks and is ready to merge.
Mario Carneiro (Dec 22 2022 at 03:31):
Shreyas Srinivas said:
So in this proof you used heterogeneous equality, which I am guessing coerces equality between values of different types. Is there like a comprehensive list of ways this can go wrong (apart from the
congr
issue)? It seems quite handy for functional programmers, when dealing with representation issues, so I can potentially see this getting wrongly used
This sort of thing is what we call "DTT hell". It hopefully doesn't come up that often, but this is the standard trick for dealing with it: do induction on some equality with a carefully chosen "motive" (that is, the type of the have
statement in this example) to do dependent rewrites. Most of lean's tactics will not handle this situation well, either complaining "the motive is not type correct" or doing nothing at all, so you have to do it manually in this way.
Mario Carneiro (Dec 22 2022 at 03:32):
the heterogeneous equality is needed to make the motive typecheck, since the LHS has type P a
and the RHS has type P (2 * n)
Mario Carneiro (Dec 22 2022 at 03:35):
I'm not sure exactly what you mean by ways this can go wrong. This is a proof technique, it has a limited range of applicability but if it works then it works
Shreyas Srinivas (Dec 22 2022 at 03:47):
Mario Carneiro said:
Shreyas Srinivas said:
So in this proof you used heterogeneous equality, which I am guessing coerces equality between values of different types. Is there like a comprehensive list of ways this can go wrong (apart from the
congr
issue)? It seems quite handy for functional programmers, when dealing with representation issues, so I can potentially see this getting wrongly usedThis sort of thing is what we call "DTT hell". It hopefully doesn't come up that often, but this is the standard trick for dealing with it: do induction on some equality with a carefully chosen "motive" (that is, the type of the
have
statement in this example) to do dependent rewrites. Most of lean's tactics will not handle this situation well, either complaining "the motive is not type correct" or doing nothing at all, so you have to do it manually in this way.
By "going wrong" I am referring to the note of caution inside docs4#HEq
Shreyas Srinivas (Dec 22 2022 at 03:49):
But I think I get the gist
Shreyas Srinivas (Dec 22 2022 at 03:49):
Thanks
Shreyas Srinivas (Dec 22 2022 at 19:25):
Hi,
I noticed that mathlib4#1148 has not been merged yet. Is there some issue with this PR that needs fixing?
Kevin Buzzard (Dec 22 2022 at 19:30):
It has no reviews and at the time of writing it doesn't even have a green tick. We don't yet know if there are issues with this PR that need fixing because it looks like nobody got round to looking at it yet other than Reid, who fixed some naming. Wel'l get there. Is this file on the critical line to any of the standard targets like data.real.basic ? Usually when I review I start at the top of #queue4 and probably when you get the green tick back you'll be at the bottom of that queue? I'm not sure about how the order works to be honest.
Shreyas Srinivas (Dec 22 2022 at 19:33):
Ah okay, I noticed a fresh commit from @Reid Barton
Shreyas Srinivas (Dec 22 2022 at 19:34):
Some names were fixed to meet the lean4 style. As I recall it, it was green last night.
Kevin Buzzard (Dec 22 2022 at 19:59):
Feel free to review other PRs on #queue4 ; this will get yours to the top quicker.
Last updated: Dec 20 2023 at 11:08 UTC