Zulip Chat Archive
Stream: lean4
Topic: Lemma not working for ```rw``` when outside a proof
Sophie Morel (Dec 20 2023 at 14:00):
I'm asking this question here, because it looks like more of a Lean question than a math question per se.
I'm trying to shorten a proof by extracting a lemma that is used twice in it, rather than copy-pasting code. Except that if I state and prove the lemma outside of my bigger proof, rw
refuses to take it (so does erw
), with a did not find instance of the pattern
error. But it should be the same statement, shouldn't it ?
Here is a MWE:
import Mathlib.Tactic
import Mathlib.LinearAlgebra.Multilinear.Basic
variable {ι : Type*} {R : Type*} {M₁ : ι → Type*} {M₂ : Type*} (s : Set ι) [DecidableEq ι]
[(i : ι) → Decidable (i ∈ s)] (x : (i : ι) → M₁ i)
-- This is my rewriting lemma.
lemma truc (z : (i : s) → M₁ i) (i : s) (c : M₁ i) :
(fun j ↦ if h : j ∈ s then Function.update z i c ⟨j, h⟩ else x j) =
Function.update (fun j => if h : j ∈ s then z ⟨j, h⟩ else x j) i c := by
ext j
by_cases h : j = i.1
. rw [h, Function.update_same]
simp only [Subtype.coe_prop, Function.update_same, dite_eq_ite, ite_true]
. rw [Function.update_noteq h]
by_cases h' : j ∈ s
. simp only [h', ne_eq, dite_true]
have h'' : ¬ ⟨j, h'⟩ = i :=
fun he => by apply_fun (fun x => x.1) at he; exact h he
rw [Function.update_noteq h'']
. simp only [h', ne_eq, dite_false]
variable [Semiring R] [∀ i, AddCommMonoid (M₁ i)] [AddCommMonoid M₂]
[∀ i, Module R (M₁ i)] [Module R M₂]
def toMultilinearMap_set (f : MultilinearMap R M₁ M₂) (x : (i : ι) → M₁ i)
(s : Set ι) [(i : ι) → Decidable (i ∈ s)] :
MultilinearMap R (fun (i : s) => M₁ i) M₂ where
toFun z := f (fun i ↦ if h : i ∈ s then z ⟨i, h⟩ else x i)
map_add' z i a b := by
simp only
-- This is apparently the exact same thing as the rewriting lemma, except it is now a `have` statement inside the proof.
have machin : ∀ (c : M₁ i),
(fun j ↦ if h : j ∈ s then Function.update z i c ⟨j, h⟩ else x j) =
Function.update (fun j => if h : j ∈ s then z ⟨j, h⟩ else x j) i c := by
intro c; ext j
by_cases h : j = i.1
. rw [h, Function.update_same]
simp only [Subtype.coe_prop, Function.update_same, dite_eq_ite, ite_true]
. rw [Function.update_noteq h]
by_cases h' : j ∈ s
. simp only [h', ne_eq, dite_true]
have h'' : ¬ ⟨j, h'⟩ = i :=
fun he => by apply_fun (fun x => x.1) at he; exact h he
rw [Function.update_noteq h'']
. simp only [h', ne_eq, dite_false]
-- End of rewriting lemma.
rw [machin b] -- This works !
rw [truc (ι := ι) (M₁ := M₁) s x z i a] -- This does not. :-(
-- Error message : tactic 'rewrite' failed, did not find instance of the pattern in the target expression
-- fun j ↦ if h : j ∈ s then Function.update z i ?c { val := j, property := h } else x j
map_smul' := sorry
Ruben Van de Velde (Dec 20 2023 at 14:07):
map_add'
puts a DecidableEq ↑s
hypothesis in your context
Ruben Van de Velde (Dec 20 2023 at 14:08):
https://leanprover-community.github.io/mathlib4_docs/Mathlib/LinearAlgebra/Multilinear/Basic.html#Implementation-notes has some background
Ruben Van de Velde (Dec 20 2023 at 14:10):
This works:
import Mathlib.Tactic
import Mathlib.LinearAlgebra.Multilinear.Basic
variable {ι : Type*} {R : Type*} {M₁ : ι → Type*} {M₂ : Type*} (s : Set ι) [DecidableEq ι]
[(i : ι) → Decidable (i ∈ s)] (x : (i : ι) → M₁ i)
-- This is my rewriting lemma.
lemma truc (z : (i : s) → M₁ i) (i : s) (c : M₁ i) :
(fun j ↦ if h : j ∈ s then Function.update z i c ⟨j, h⟩ else x j) =
Function.update (fun j => if h : j ∈ s then z ⟨j, h⟩ else x j) i c := by
ext j
by_cases h : j = i.1
. rw [h, Function.update_same]
simp only [Subtype.coe_prop, Function.update_same, dite_eq_ite, ite_true]
. rw [Function.update_noteq h]
by_cases h' : j ∈ s
. simp only [h', ne_eq, dite_true]
have h'' : ¬ ⟨j, h'⟩ = i :=
fun he => by apply_fun (fun x => x.1) at he; exact h he
rw [Function.update_noteq h'']
. simp only [h', ne_eq, dite_false]
variable [Semiring R] [∀ i, AddCommMonoid (M₁ i)] [AddCommMonoid M₂]
[∀ i, Module R (M₁ i)] [Module R M₂]
def toMultilinearMap_set (f : MultilinearMap R M₁ M₂) (x : (i : ι) → M₁ i)
(s : Set ι) [(i : ι) → Decidable (i ∈ s)] :
MultilinearMap R (fun (i : s) => M₁ i) M₂ where
toFun z := f (fun i ↦ if h : i ∈ s then z ⟨i, h⟩ else x i)
map_add' z i a b := by
simp only
rename_i inst
obtain rfl := Subsingleton.elim inst Subtype.instDecidableEqSubtype
rw [truc (ι := ι) (M₁ := M₁) s x z i a]
sorry
map_smul' := sorry
Ruben Van de Velde (Dec 20 2023 at 14:11):
Or:
import Mathlib.Tactic
import Mathlib.LinearAlgebra.Multilinear.Basic
variable {ι : Type*} {R : Type*} {M₁ : ι → Type*} {M₂ : Type*} (s : Set ι) [DecidableEq ι]
[(i : ι) → Decidable (i ∈ s)] (x : (i : ι) → M₁ i)
-- This is my rewriting lemma.
lemma truc
[DecidableEq ↑s] -- Redundant hypothesis, but makes the lemma more general
(z : (i : s) → M₁ i) (i : s) (c : M₁ i) :
(fun j ↦ if h : j ∈ s then Function.update z i c ⟨j, h⟩ else x j) =
Function.update (fun j => if h : j ∈ s then z ⟨j, h⟩ else x j) i c := by
ext j
by_cases h : j = i.1
. rw [h, Function.update_same]
simp only [Subtype.coe_prop, Function.update_same, dite_eq_ite, ite_true]
. rw [Function.update_noteq h]
by_cases h' : j ∈ s
. simp only [h', ne_eq, dite_true]
have h'' : ¬ ⟨j, h'⟩ = i :=
fun he => by apply_fun (fun x => x.1) at he; exact h he
rw [Function.update_noteq h'']
. simp only [h', ne_eq, dite_false]
variable [Semiring R] [∀ i, AddCommMonoid (M₁ i)] [AddCommMonoid M₂]
[∀ i, Module R (M₁ i)] [Module R M₂]
def toMultilinearMap_set (f : MultilinearMap R M₁ M₂) (x : (i : ι) → M₁ i)
(s : Set ι) [(i : ι) → Decidable (i ∈ s)] :
MultilinearMap R (fun (i : s) => M₁ i) M₂ where
toFun z := f (fun i ↦ if h : i ∈ s then z ⟨i, h⟩ else x i)
map_add' z i a b := by
simp only
rw [truc (ι := ι) (M₁ := M₁) s x z i a]
sorry
map_smul' := sorry
Sophie Morel (Dec 20 2023 at 14:14):
Ruben Van de Velde said:
https://leanprover-community.github.io/mathlib4_docs/Mathlib/LinearAlgebra/Multilinear/Basic.html#Implementation-notes has some background
Ooooh, that's what they meant ! To be honest, I would not have known what to do even with that. Thank you very much !
Last updated: May 02 2025 at 03:31 UTC