Zulip Chat Archive
Stream: new members
Topic: Why does this rewrite fail
Mark Fischer (Feb 14 2024 at 14:03):
I've been trying to come up with a better minimum working example, but since I don't understand the problem, it's a bit tough to replicate.
The following code fails at the indicated rewrite. Somehow I managed to use the "throw everything at the wall and see what sticks" approach to come up with a solution. So you can see that if I simp only [IndexList.length] at i before I try to rewrite, then I have a complete proof.
What I'm missing is why. Based on my limited understanding, simp at i should do the opposite, and make i no longer match the value in get_eq. What's happening?
(Sorry for the amount of code here)
import Mathlib
namespace Foo
structure IndexList {β : Type u} : Type u where
l : List β
idxs: Finset (Fin l.length)
@[simp]
def IndexList.length (l : @IndexList α) := l.idxs.card
def getElem (l : @IndexList α) (i : Fin l.length) : α := l.l[(l.idxs.sort LE.le)[i]]
def mem (a : α) (l : @IndexList α) : Prop := ∃i, getElem l i = a
theorem mem_finset_union_left {n : ℕ} (l r : Finset (Fin n)) (i : Fin l.card) : (l.sort LE.le)[i] ∈ (l ∪ r).sort LE.le := by
simp only [Finset.mem_sort, Finset.mem_union]
apply Or.inl ∘ (Finset.mem_sort LE.le).mp
exact List.mem_iff_get.mpr ⟨⟨i, by
simp only [Finset.length_sort, Fin.is_lt]
⟩, rfl⟩
theorem mem_indexlist_union_left (a : α) (l : List α) (is₁ is₂ : Finset (Fin l.length)) : mem a ⟨l, is₁⟩ → mem a ⟨l, is₁ ∪ is₂⟩ := by
intro ⟨i, get_i_eq_a⟩
have h₁ := mem_finset_union_left is₁ is₂ i
have ⟨i', get_eq⟩ := List.mem_iff_get.mp h₁
use ⟨i', by
convert i'.isLt
simp only [IndexList.length, Finset.length_sort]
⟩
-- simp only [IndexList.length] at i -- Uncomment this to fix
have h₂ : l.get (is₁.sort LE.le)[i] = a := get_i_eq_a
rw [← get_eq] at h₂ -- This rw fails
exact h₂
Mark Fischer (Feb 15 2024 at 17:08):
It seems to me like
have h₂ : l.get (is₁.sort LE.le)[i] = a := get_i_eq_a
is doing something mysterious. Somehow i is changed in a way I can't inspect via the infoview.
It feels like I should be able to finish the proof (or get close) with
convert get_i_eq_a
Mark Fischer (Feb 15 2024 at 17:32):
I can change the last few lines to
simp only [IndexList.length] at i
simp only [getElem] at get_i_eq_a
change l[(Finset.sort LE.le is₁)[i]] = a at get_i_eq_a
rw [← get_eq] at get_i_eq_a
exact get_i_eq_a
In the infoview, the change tactic shows no changes to get_i_eq_a's type (they're character for character identical), but without that line, the proof doesn't compile.
Kyle Miller (Feb 15 2024 at 18:00):
If you set set_option pp.explicit true, you can see that there are differences in h2. It appears that rw is not able to see through these differences when locating the expression.
Here are three options:
- Live with needing to unfold
IndexList.length - Change
IndexList.lengthfrom adefto anabbrev, which makes it reducible and in this case makes therwgo through. - Use
erwinstead ofrw, which is more forceful with reduction when trying to find matches.
Kyle Miller (Feb 15 2024 at 18:02):
Another option is figuring out why you have this difference, and somehow getting get_eq to be in the correct form.
Kyle Miller (Feb 15 2024 at 18:03):
(The mystery in l.get (is₁.sort LE.le)[i] is that if you change the type of i it causes it to elaborate slightly differently; some implicit arguments get syntactically-different-yet-defeq values.)
Mark Fischer (Feb 15 2024 at 18:54):
Thanks for the help! :)
set_option pp.explicit true certainly does show me more, but suddenly it's so much.
Doing a quick diff on get_i_eq_a and h₂ shows they're different for sure. So at least it's no longer a mystery what the change tactic is doing. Though I feel like I came to this solution (change the type) almost by accident, so I'm not confident I could do so again.
It feels a bit undirected/magical/lucky that the change tactic should elaborate slightly differently in a way that happens to help. Probably the thing to do is to come back around to this when I have a bit more experience under my belt. :)
Last updated: May 02 2025 at 03:31 UTC