Zulip Chat Archive
Stream: new members
Topic: Need help understanding behaviour of Fin
Kevin Cheung (Apr 02 2024 at 15:03):
I am a bit puzzled by what's happening in the code below:
import Mathlib.Data.Fin.Basic
-- import Mathlib.Data.Real.Sqrt
def z := (5 : Fin 3) -- Why does this work?
#check z -- This shows z : Fin 3.
def f (n : Fin 5) := n * 2
#reduce f (9 : ℤ) -- This gives a type error.
The error for the last line:
application type mismatch
f 9
argument
9
has type
ℤ : Type
but is expected to have type
Fin 5 : Type
Interestingly, if I replace the import with import Mathlib.Data.Real.Sqrt
, there is no error anywhere. If anyone could shed some light on what's happening, it'll be greatly appreciated.
Mario Carneiro (Apr 02 2024 at 15:12):
Fin 3
has an OfNat
instance in core, meaning that (5 : Fin 3)
compiles (it wraps BTW), but there is no NatCast
instance and IntCast
doesn't even exist in core, so
#check fun n : Nat => (n : Fin 3)
#check fun n : Int => (n : Fin 3)
do not compile. Mathlib adds instances of these classes for any ring, and Fin 3
is a ring, so after importing enough of mathlib it does compile (it wraps)
Kevin Cheung (Apr 02 2024 at 15:14):
I see. Is there a way for disable this kind of casting (i.e. disallowing wrapping)?
Kevin Cheung (Apr 02 2024 at 15:16):
Should one use Finset.range 3
instead of Fin 3
?
Mario Carneiro (Apr 02 2024 at 15:17):
In principle yes. The reason the OfNat A n
class takes n
as a parameter is so that you can specify separately that a type has only certain numbers, so you could make (3 : MyFin 5)
compile and (5 : MyFin 3)
not. But I don't think you can get rid of the existing instance on Fin
itself without using attribute [-instance]
, which isn't a very long term solution since it's file-local
Mario Carneiro (Apr 02 2024 at 15:19):
Kevin Cheung said:
Should one use
Finset.range 3
instead ofFin 3
?
These have different types (one is a Finset
and the other is a type), they aren't directly interchangeable. Maybe it would help to elaborate on what you need this for?
Kevin Cheung (Apr 02 2024 at 15:21):
I am wondering how to formulate something that involves
wonder if it's better to use Finset.range
or Fin
for the indexing.
Kevin Cheung (Apr 02 2024 at 15:23):
For example,
import Mathlib.Algebra.BigOperators.Fin
import Mathlib.Data.Finset.Basic
import Mathlib.Data.Real.Sqrt
theorem my_cauchy_schwarz (n : ℕ) (a : Fin n → ℝ) (b : Fin n → ℝ) :
(∑ i : Fin n, (a i) * (b i) ) ≤ Real.sqrt (∑ i : Fin n, (a i) ^ 2) * Real.sqrt (∑ i : Fin n, (b i) ^ 2) := by sorry
Mario Carneiro (Apr 02 2024 at 15:24):
that's actually still not enough information. The translation of sequences in traditional mathematics can be quite varied depending on what else is going on in the statement; often the conclusion is to use arbitrary finite indexing sets, sets of values or in some cases completely reformulating the statement (e.g. using filters)
Mario Carneiro (Apr 02 2024 at 15:24):
In your my_cauchy_schwarz
example, I would be inclined to use an arbitrary sum over a Finset
there
Kevin Cheung (Apr 02 2024 at 15:25):
Mario Carneiro said:
In your
my_cauchy_schwarz
example, I would be inclined to use an arbitrary sum over aFinset
there
What would that look like, if you don't mind giving more details?
Mario Carneiro (Apr 02 2024 at 15:25):
import Mathlib.Algebra.BigOperators.Fin
import Mathlib.Data.Finset.Basic
import Mathlib.Data.Real.Sqrt
open BigOperators
theorem my_cauchy_schwarz (s : Finset α) (a : α → ℝ) (b : α → ℝ) :
(∑ i in s, (a i) * (b i) ) ≤ Real.sqrt (∑ i in s, (a i) ^ 2) * Real.sqrt (∑ i in s, (b i) ^ 2) := by sorry
Mario Carneiro (Apr 02 2024 at 15:27):
this directly specializes to the statement you gave:
theorem my_cauchy_schwarz' (n : ℕ) (a : Fin n → ℝ) (b : Fin n → ℝ) :
(∑ i : Fin n, (a i) * (b i) ) ≤ Real.sqrt (∑ i : Fin n, (a i) ^ 2) * Real.sqrt (∑ i : Fin n, (b i) ^ 2) :=
my_cauchy_schwarz ..
Kevin Cheung (Apr 02 2024 at 15:28):
Interesting. Thank you.
Kevin Cheung (Apr 02 2024 at 15:29):
I always get confused between Finset.range
and Fin
.
Mario Carneiro (Apr 02 2024 at 15:31):
Finset A
is a finite subset of elements of A
. Finset.range n : Finset Nat
is the collection of all numbers less than n
, as a Finset
of natural numbers. Fin n
is an abstract type with n
elements, which can be naturally embedded in Nat
using the .val
function
Kevin Cheung (Apr 02 2024 at 17:27):
Thank you for the explanation.
Yaël Dillies (Apr 02 2024 at 18:10):
Here is the mathlib statement for reference: docs#sum_mul_le_sqrt_mul_sqrt
Kevin Cheung (Apr 02 2024 at 19:11):
Mario Carneiro said:
this directly specializes to the statement you gave:
theorem my_cauchy_schwarz' (n : ℕ) (a : Fin n → ℝ) (b : Fin n → ℝ) : (∑ i : Fin n, (a i) * (b i) ) ≤ Real.sqrt (∑ i : Fin n, (a i) ^ 2) * Real.sqrt (∑ i : Fin n, (b i) ^ 2) := my_cauchy_schwarz ..
What does ..
in my_cauchy_schwarz ..
do?
Adam Topaz (Apr 02 2024 at 19:15):
The ..
means "put as many _
as needed"
Kevin Cheung (Apr 02 2024 at 19:18):
Hmm. In this case, I had to put four _
but my_cauchy_schwarz
seems to take three arguments. Is one of them implicit here?
Adam Topaz (Apr 02 2024 at 19:21):
I only had to put 3:
import Mathlib.Algebra.BigOperators.Fin
import Mathlib.Data.Finset.Basic
import Mathlib.Data.Real.Sqrt
open BigOperators
theorem my_cauchy_schwarz (s : Finset α) (a : α → ℝ) (b : α → ℝ) :
(∑ i in s, (a i) * (b i) ) ≤ Real.sqrt (∑ i in s, (a i) ^ 2) * Real.sqrt (∑ i in s, (b i) ^ 2) := by sorry
theorem my_cauchy_schwarz' (n : ℕ) (a : Fin n → ℝ) (b : Fin n → ℝ) :
(∑ i : Fin n, (a i) * (b i) ) ≤ Real.sqrt (∑ i : Fin n, (a i) ^ 2) * Real.sqrt (∑ i : Fin n, (b i) ^ 2) :=
my_cauchy_schwarz _ _ _
Kevin Cheung (Apr 02 2024 at 19:21):
There is some magic that I still don't understand. If we have s : Finset α
, how does ∑ i in s
get specialized into ∑ i : Fin n
?
Adam Topaz (Apr 02 2024 at 19:22):
s
gets specialized to \top : Finset (Fin n)
Yaël Dillies (Apr 02 2024 at 19:22):
∑ i : Fin n
is notation for ∑ i in (univ : Finset (Fin n))
Adam Topaz (Apr 02 2024 at 19:23):
right, univ
not top
.
Yaël Dillies (Apr 02 2024 at 19:23):
Same thing soon (hopefully) :smile: :fingers_crossed:
Kevin Cheung (Apr 02 2024 at 19:26):
Adam Topaz said:
I only had to put 3:
import Mathlib.Algebra.BigOperators.Fin import Mathlib.Data.Finset.Basic import Mathlib.Data.Real.Sqrt open BigOperators theorem my_cauchy_schwarz (s : Finset α) (a : α → ℝ) (b : α → ℝ) : (∑ i in s, (a i) * (b i) ) ≤ Real.sqrt (∑ i in s, (a i) ^ 2) * Real.sqrt (∑ i in s, (b i) ^ 2) := by sorry theorem my_cauchy_schwarz' (n : ℕ) (a : Fin n → ℝ) (b : Fin n → ℝ) : (∑ i : Fin n, (a i) * (b i) ) ≤ Real.sqrt (∑ i : Fin n, (a i) ^ 2) * Real.sqrt (∑ i : Fin n, (b i) ^ 2) := my_cauchy_schwarz _ _ _
I see why. I had autoimplicit = false and declared α explicitly.
Kevin Cheung (Apr 02 2024 at 19:28):
Yaël Dillies said:
Same thing soon (hopefully) :smile: :fingers_crossed:
There is a difference between univ
and top
?
Yaël Dillies (Apr 02 2024 at 19:29):
They are definitionally equal (so Finset.univ = ⊤
can be proved by rfl
), however they are not syntactically equal (so you can't use a lemma about one to rewrite the other)
Kevin Cheung (Apr 02 2024 at 20:04):
I see.
Last updated: May 02 2025 at 03:31 UTC