Zulip Chat Archive
Stream: mathlib4
Topic: Generalising lemma for instances
Gareth Ma (Nov 05 2023 at 17:25):
Hi, I have the following proof right now that doesn't work. However, if you replace all the α
with ℚ
then it works. My idea is that if alpha can be casted to Q then the proof should still work
instance {α : Type*} [OrderedRing α] [Coe α ℚ] : ∀ (z : α) (a : ℕ), Decidable (a ≤ ⌊(z : ℝ)⌋₊) := by
intro z a
by_cases hz : 0 ≤ z
· have : ⌊(z : ℝ)⌋₊ = ⌊(z : ℚ)⌋₊ := by
zify
rw [cast_floor_eq_int_floor, cast_floor_eq_int_floor, Rat.floor_cast] <;> norm_cast
/- Need to prove 0 ≤ Coe.coe z from 0 ≤ z -/
rw [this]
apply decLe
· rw [floor_eq_zero.mpr (by norm_cast ; linarith)]
/- Need to prove Coe.coe z < 1 from ¬0 ≤ z -/
apply decLe
What should the correct instances be? For example, this proof should work for Nat and Int because they can be casted to rationals in this natural way
Gareth Ma (Nov 05 2023 at 17:34):
(The proof is long because I want it to be computable)
Timo Carlin-Burns (Nov 05 2023 at 17:38):
for #mwe I had to add
import Mathlib
open Nat
Gareth Ma (Nov 05 2023 at 17:38):
Ah my bad
Gareth Ma (Nov 05 2023 at 17:41):
After thinking a bit, maybe it's not really possible, since the Coe
instance / coercion in general doesn't have any guarantee
Timo Carlin-Burns (Nov 05 2023 at 17:42):
import Mathlib
open Nat
instance {α : Type*} [Coe α ℚ] : ∀ (z : α) (a : ℕ), Decidable (a ≤ ⌊(z : ℝ)⌋₊) := by
intro z a
by_cases hz : 0 ≤ (z : ℚ) -- changed from `0 ≤ z`
· have : ⌊(z : ℝ)⌋₊ = ⌊(z : ℚ)⌋₊ := by
zify
rw [cast_floor_eq_int_floor, cast_floor_eq_int_floor, Rat.floor_cast] <;> norm_cast
rw [this]
apply decLe
· rw [floor_eq_zero.mpr (by norm_cast ; linarith)]
apply decLe
Timo Carlin-Burns (Nov 05 2023 at 17:44):
You don't even need an [OrderedRing α]
assumption
Timo Carlin-Burns (Nov 05 2023 at 17:45):
(z : ℝ)
in your goal is really (↑(↑z : ℚ) : ℝ)
, and since you've proven the result for all ℚ, you've also proven it for (↑z : ℚ)
Gareth Ma (Nov 05 2023 at 17:48):
Hmm I will try it out
Gareth Ma (Nov 05 2023 at 17:48):
Thanks!
Gareth Ma (Nov 05 2023 at 23:07):
Oops, just came back. It doesn't work as I wanted (as intended) since it's noncomputable:
import Mathlib
open Nat in
theorem inst1 {α : Type*} [Coe α ℚ] : ∀ (z : α) (a : ℕ), Decidable (a ≤ ⌊(z : ℝ)⌋₊) := by
intro z a
by_cases hz : 0 ≤ (z : ℚ) -- changed from `0 ≤ z`
· have : ⌊(z : ℝ)⌋₊ = ⌊(z : ℚ)⌋₊ := by
zify
rw [cast_floor_eq_int_floor, cast_floor_eq_int_floor, Rat.floor_cast] <;> norm_cast
rw [this]
apply decLe
· rw [floor_eq_zero.mpr (by norm_cast ; linarith)]
apply decLe
instance : Coe ℕ ℚ := ⟨fun a ↦ (a : ℚ)⟩
instance : Coe ℤ ℚ := ⟨fun a ↦ (a : ℚ)⟩
def f {α : Type} [Coe α ℚ] (z : α) (a : ℕ) := a ≤ ⌊(z : ℝ)⌋₊
/- failed to compile definition, consider marking it as 'noncomputable' because it depends on
'inst1', and it does not have executable code -/
instance (z : ℤ) (a : ℕ) : Decidable (f z a) := by
unfold f
exact inst1 _ _
/- Both of these are noncomputable now -/
#eval (3 : ℕ) ≤ ⌊((5 : ℤ) : ℝ)⌋₊
#eval f (3 : ℤ) 1
Gareth Ma (Nov 05 2023 at 23:09):
Unfortunately I don't think it's avoidable, so for now I have just replaced alpha with three different theorems for N Z and Q :)
Gareth Ma (Nov 05 2023 at 23:09):
Gareth Ma said:
After thinking a bit, maybe it's not really possible, since the
Coe
instance / coercion in general doesn't have any guarantee
Thinking back to this, what I want is an order-preserving embedding ("mathematically") instead of a type-theoretic Coe
, if that makes sense
Gareth Ma (Nov 05 2023 at 23:10):
In other words, something that can prove
Brendan Seamas Murphy (Nov 05 2023 at 23:17):
I think you want an order embedding (ie reflecting and preserving) so that you can conclude Coe.coe z < 1
from ¬(0 <= z)
Gareth Ma (Nov 05 2023 at 23:18):
Yes exactly! Does that exist in Mathlib?
Brendan Seamas Murphy (Nov 05 2023 at 23:19):
https://leanprover-community.github.io/mathlib4_docs/Mathlib/Order/Hom/Basic.html#OrderEmbedding
Gareth Ma (Nov 05 2023 at 23:20):
Thanks, let me try it
Eric Wieser (Nov 05 2023 at 23:35):
Why not:
import Mathlib
open Nat
instance {α : Type*} [Coe α ℚ] : ∀ (z : α) (a : ℕ), Decidable (a ≤ ⌊(z : ℝ)⌋₊) := by
infer_instance
Gareth Ma (Nov 05 2023 at 23:36):
It immediately says it's noncomputable
Gareth Ma (Nov 05 2023 at 23:36):
Again the point of the long proof is for it to be computable, otherwise I think something like decLe works immediately
Eric Wieser (Nov 05 2023 at 23:40):
I recommend first proving
import Mathlib
open Nat
theorem aux {α : Type*} [Coe α ℚ] (z : α) (a : ℕ) :
(a ≤ ⌊(z : ℝ)⌋₊) ↔ a ≤ (z : ℚ)
Eric Wieser (Nov 05 2023 at 23:41):
You almost never want to write a complex decidable instance, just write a lemma that converts the statement into sometime already Decidable
and use docs#decidable_of_iff
Gareth Ma (Nov 05 2023 at 23:42):
I will do that instead :)
Gareth Ma (Nov 05 2023 at 23:42):
Thanks everyone
Gareth Ma (Nov 05 2023 at 23:58):
Okay I just isolated the decidability statements into a new file, then copy and paste it a billion times (more like 12) :) It's probably still a better approach then whatever I was attempting above though hahah
Last updated: Dec 20 2023 at 11:08 UTC