Zulip Chat Archive
Stream: new members
Topic: Strugling with coercion of dependent types and Vectors
Lars (Oct 28 2024 at 14:29):
Hi all,
I've been struggling quite a bit with the following. I have Mathlib.Vectors for which I want to define some rewrite rules. But if the Vectors have equivalent but different types, I am unable to do this. For example here I have a vector with types:
- Vector ℤ (k + 1 - (i + 1))
- Vector ℤ (k + 1 - 1 - i)
But proving the following, I first had to use a 'cast' with ▸ and furthermore I could not finish my proof.
This is the example. Any clue what I could do better here?
import Mathlib.Tactic
open Mathlib
lemma h : (k + 1 - 1 - i = k + 1 - (i + 1)) := by
  simp
lemma vector_drop_tail {a: Vector Int (k+1)}:
  Vector.drop (i+1) a  = h ▸ (Vector.drop (i) a.tail) := by
  rw [Vector.drop, Vector.drop]
  match a with
  | ⟨a::as, a_l⟩ =>
    rw [Vector.tail]
    simp
    -- rfl -- This fails
    sorry
Daniel Weber (Oct 28 2024 at 14:44):
You can try to use docs#Mathlib.Vector.congr
Daniel Weber (Oct 28 2024 at 14:52):
import Mathlib.Tactic
open Mathlib
lemma h : (k + 1 - 1 - i = k + 1 - (i + 1)) := by
  simp
@[simp]
theorem Mathlib.Vector.toList_congr (v : Mathlib.Vector α n) (h : n = m) :
    (v.congr h).toList = v.toList := rfl
@[simp]
theorem Mathlib.Vector.tail_toList {α : Type*} {n : ℕ} (v : Vector α n) : v.tail.toList = v.toList.tail := by
  cases' v with a _
  cases a <;> rfl
lemma vector_drop_tail {a: Vector Int (k+1)}:
  Vector.drop (i+1) a  = (Vector.drop (i) a.tail).congr h := by
  apply Vector.toList_injective
  simp
Lars (Oct 28 2024 at 15:07):
Thanks this is great, congr helps a lot!
Lars (Oct 28 2024 at 15:37):
Another question, which was I guess actually the thing I ran into.
Can I prove equality of arbitrary functions, when they are equal modulo the congr of their arguments.
So for instance, I have the following:
def vector_sum : Vector Int k →  Int
| ⟨[], _⟩ => 0
| ⟨x :: xs, xl⟩ => x + vector_sum ⟨xs, congrArg Nat.pred xl⟩
lemma apply_congr (a: Vector Int (k+1)):
  vector_sum (Vector.drop (i+1) a) = vector_sum (Vector.drop (i) a.tail) := by
  rw [vector_drop_tail]
  sorry -- ???
Daniel Weber (Oct 28 2024 at 15:41):
You can first prove
@[simp]
lemma vector_sum_congr (v : Mathlib.Vector Int n) (h : n = m) :
    vector_sum (v.congr h) = vector_sum v := by
  subst h
  rfl
and then it's just simp. (You can also use congr 1 and then prove the HEq , but that's usually unpleasant to work with)
Lars (Oct 28 2024 at 16:02):
Ah that is so great, thanks a bunch. I was struggling over this for over a week..
Anyway, would it then note make sense to add things like the following to Mathlib? I could make a pull request if needed (or you, since it's really your ideas)
@[simp]
lemma Vector.cong_arg (f: ∀ k, Mathlib.Vector α k → β) (v : Mathlib.Vector α n) (h : n = m) :
    f m (v.congr h) = f n v := by
  subst h
  rfl
Daniel Weber (Oct 28 2024 at 16:09):
I think this makes sense as a lemma, but I think it might be quite inefficient as @[simp] (the discrimination tree is @Eq _ _ _). Feel free to make a PR
Last updated: May 02 2025 at 03:31 UTC