Zulip Chat Archive
Stream: mathlib4
Topic: I encountered a summation problem in Lean4
Planck Anderson (Jul 26 2025 at 09:02):
A finite summation expression equals 0. I used apply Finset.sum_eq_zero, and after using split_ifs, I found that when x = a, the expression equals -1; when x = b, it equals 1; and in all other cases, it equals 0. I don't know how to exclude these two cases and compute them separately.
Yaël Dillies (Jul 26 2025 at 09:04):
Can you provide a #mwe ?
Planck Anderson (Jul 26 2025 at 09:10):
The goal is :(you know I am dealing with some matrix multiplication as I am formalizeing gaussian elimination.)
⊢ (∑ x,
(if a = x then 1 else if True ∧ x = i then -M.R a j / M.R i j else 0) *
if x = i then 1 else if x > i ∧ True then M.R x j / M.R i j else 0) =
0
After I apply Finset.sum_eq_zero, it become like this
⊢ ∀ x ∈ Finset.univ,
((if a = x then 1 else if True ∧ x = i then -M.R a j / M.R i j else 0) *
if x = i then 1 else if x > i ∧ True then M.R x j / M.R i j else 0) =
0
After
intro p hp
simp
split_ifs
· exfalso
expose_names;rw [← h_1, h_2] at h_ai; exact (lt_irrefl p) h_ai
I found some contradiction
p : Fin n
hp : p ∈ Finset.univ
h✝¹ : p = i
h✝ : ¬a = p
⊢ -M.R a j / M.R i j = 0
and
p : Fin n
hp : p ∈ Finset.univ
h✝² : ¬p = i
h✝¹ : i < p
h✝ : a = p
⊢ M.R p j / M.R i j = 0
Yaël Dillies (Jul 26 2025 at 09:12):
Thanks! But this is not a #mwe: If you click on this button, then you willl see that your code block is broken and that I can't see the same infoview as you do
Planck Anderson (Jul 26 2025 at 09:14):
lemma Gaussian.gaussian_elimination_row_eq_left_mul (i : Fin n) (j : Fin m) (h : M.R i j ≠ 0) :
∃ (P : GL (Fin n) K), P.1 • M = M.gaussian_elimination_step_row i j := by
have id_eqzero (a b : Fin n) (h: a ≠ b): (1 : Matrix (Fin n) (Fin n) K) a b = 0 := by simp [h]
have id_eqone (a b : Fin n) (h: a = b): (1 : Matrix (Fin n) (Fin n) K) a b = 1 := by sorry
have h_mul (A : Matrix (Fin n) (Fin n) K) (B : Matrix (Fin n) (Fin n) K) (C : Matrix (Fin n) (Fin n) K) (i : Fin n) (j : Fin n): (A * B) i j - (C * B) i j = ((A - C) * B) i j := by sorry
have h_mul'(A : Fin n → K) (B : Fin n → K) (j : Fin n): A j - B j = (A - B) j := by sorry
let P_mat : Matrix (Fin n) (Fin n) K := fun k l =>
if k = l then 1
else if k > i ∧ l = i then -(M.R k j) / (M.R i j)
else 0
let P_inv : Matrix (Fin n) (Fin n) K := fun k l =>
if k = l then 1
else if k > i ∧ l = i then (M.R k j) / (M.R i j)
else 0
have h_inv1 : P_mat * P_inv = 1 := by
ext a b
simp only [P_mat, P_inv, Matrix.mul_apply]
by_cases h_ab : a = b
rw [h_ab]
rw [← Finset.sum_add_sum_compl {b}]
simp
apply Finset.sum_eq_zero
intro p hp
have : p ≠ b := by simpa using hp
simp [this]
intro hp1 hp2
split_ifs
· exfalso
(expose_names; exact this (id (Eq.symm h_1)))
· exfalso
expose_names
obtain ⟨h_21, h_22⟩ := h_2
rw [hp2] at h_21
exact (lt_self_iff_false i).mp h_21
rfl
by_cases h_ai : a > i
by_cases h_bi : b = i
simp only [h_ai, h_bi, id_eqzero _ _ h_ab]
apply Finset.sum_eq_zero
intro p hp
simp
split_ifs
· exfalso
expose_names;rw [← h_1, h_2] at h_ai; exact (lt_irrefl p) h_ai
· sorry
· sorry
· rfl
rfl
simp only [h_ai, h_bi, id_eqzero _ _ h_ab]
apply Finset.sum_eq_zero
intro p hp
simp
intro p'
split_ifs
· exfalso
expose_names;exact h_ab (h_1.trans p')
· exfalso
expose_names;exact h_bi ((Eq.symm p').trans h_2)
rfl
simp only [h_ai, id_eqzero _ _ h_ab]
apply Finset.sum_eq_zero
intro p hp
simp
split_ifs
· exfalso
expose_names;exact h_ab (h_2.trans h_1)
· rfl
· exfalso
expose_names;obtain ⟨h_21, h_22⟩ := h_2;rw [← h_3] at h_21;exact h_ai h_21
rfl
rfl
Planck Anderson (Jul 26 2025 at 09:15):
I am so sorry
Yaël Dillies (Jul 26 2025 at 09:15):
You're still missing imports :slight_smile:
Planck Anderson (Jul 26 2025 at 09:24):
it will be some cruddy code
Kenny Lau (Jul 26 2025 at 09:25):
@Planck Anderson well, you took a wrong turn in your proof and obtained an unprovable goal
Kenny Lau (Jul 26 2025 at 09:25):
so go back where you came from
Kenny Lau (Jul 26 2025 at 09:25):
and use sum_subset instead
Planck Anderson (Jul 26 2025 at 09:25):
thanks a lot!
Planck Anderson (Jul 26 2025 at 09:28):
@Kenny Lau yeah but it seems sum_subset does not work
image.png
Planck Anderson (Jul 26 2025 at 09:33):
(someone deleted this)
Planck Anderson (Jul 26 2025 at 09:37):
@Yaël Dillies there will be a lot of matrix multiplications here, I feel so sad to deal with a lot of summation... :melting_face:
Ruben Van de Velde (Jul 26 2025 at 10:37):
You shouldn't use Lean.Grind.* lemmas directly, I don't think
Dexin Zhang (Jul 26 2025 at 13:55):
docs#Finset.sum_erase_add can separate one element from a sum
Planck Anderson (Jul 27 2025 at 22:58):
I have solved this problem. use Finset.sum_eq_add_sum_diff_singleton to exclude the two special situations
Planck Anderson (Jul 27 2025 at 22:59):
anyway, thanks for your guys help, love you guys, I like lean community and it is really warm, you guys are really approachable and glad to help others.
Planck Anderson (Jul 27 2025 at 23:04):
Now I am here, sad to deal with some matrix multiplication, especially some matrix are not determinate.
import Mathlib
#check Matrix
variable {α : Type*}
open Matrix Equiv Nat List
section Basic
variable {n m} (M : Matrix (Fin n) (Fin m) α)
def swap_rows (i j : Fin n) : Matrix (Fin n) (Fin m) α :=
M.submatrix (swap i j : Perm (Fin n)) id
def swap_cols (i j : Fin m) : Matrix (Fin n) (Fin m) α :=
(swap_rows M.transpose i j).transpose
def gaussian_update [Add α] [Mul α] [Sub α]
(i k : Fin n) (a b : α) : (Fin m) → α :=
if k ≤ i then M k else a • M k - b • M i
def gaussian_update_row [Add α] [Mul α] [Sub α]
(i : Fin n) (j : Fin m):
Matrix (Fin n) (Fin m) α :=
fun k => gaussian_update M i k (M i j) (M k j)
end Basic
@[ext]
structure Gaussian (n m α) [Ring α] where
P : Matrix (Fin n) (Fin n) α
R : Matrix (Fin n) (Fin m) α
Q : Matrix (Fin m) (Fin m) α
M : Matrix (Fin n) (Fin m) α
hm : P * M * Q = R
-- P M Q = [I_r, 0;
-- 0, 0]
instance {n m α} [Ring α] : SMul (Matrix (Fin n) (Fin n) α) (Gaussian n m α) where
smul := fun P B => (⟨P * B.P, P * B.R, B.Q, B.M, by simp [B.hm, Matrix.mul_assoc];⟩ : Gaussian n m α)
instance {n m α} [Ring α] : SMul (Matrix (Fin m) (Fin m) α) (Gaussian n m α) where
smul := fun Q B => (⟨B.P, B.R * Q, B.Q * Q, B.M, by rw [← B.hm]; simp [Matrix.mul_assoc];⟩ : Gaussian n m α)
section Gauss
variable {n m} [Ring α] (M : Gaussian n m α) [NeZero n] [NeZero m]
def find_pivot_col [LinearOrder α] (M : Fin n → α) (i : Fin n): Fin n :=
(argmax (abs ∘ M) ((finRange n).rtake (n - i))).getD 0
def Gaussian.gaussian_elimination_step_row (i : Fin n) (j : Fin m)
: Gaussian n m α where
P := fun k => gaussian_update M.P i k (M.R i j) (M.R k j)
R := gaussian_update_row M.R i j
Q := M.Q
M := M.M
hm := by
funext k
simp only [gaussian_update, gaussian_update_row, Matrix.mul_apply_eq_vecMul,
Matrix.vecMul_vecMul, ← M.hm]
split_ifs with h_le
simp
simp [sub_vecMul, Matrix.vecMul_smul, Matrix.vecMul_smul]
end Gauss
section PrimaryTransformation
variable {m n : ℕ} {i : Fin n} {j : Fin m} {K : Type*} [CommRing K] (M : Gaussian n m K)
#check (⟨1,1,by simp, by simp⟩: GL (Fin n) K)
@[simp]
def row_trans_matrix (M : Gaussian n m K) (i : Fin n) (j : Fin m) : Matrix (Fin n) (Fin n) K :=
fun k l =>
if k = l then 1
else if k > i ∧ l = i then -(M.R k j)
else 0
@[simp]
def row_trans_matrix_inv (M : Gaussian n m K) (i : Fin n) (j : Fin m) : Matrix (Fin n) (Fin n) K :=
fun k l =>
if k = l then 1
else if k > i ∧ l = i then (M.R k j)
else 0
lemma id_eqzero (a b : Fin n) (h: a ≠ b): (1 : Matrix (Fin n) (Fin n) K) a b = 0 := by simp [h]
lemma id_eqone (a b : Fin n) (h: a = b): (1 : Matrix (Fin n) (Fin n) K) a b = 1 := by rw[← h]; exact one_apply_eq a
lemma row_trans_matrix_mul_inv_eq_one (M : Gaussian n m K) (i : Fin n) (j : Fin m) :
row_trans_matrix M i j * row_trans_matrix_inv M i j = 1 := by
ext a b
simp only [row_trans_matrix, row_trans_matrix_inv, Matrix.mul_apply]
by_cases h_ab : a = b
rw [h_ab]
rw [← Finset.sum_add_sum_compl {b}]
simp
apply Finset.sum_eq_zero
intro p hp
have : p ≠ b := by simpa using hp
simp [this]
intro hp1 hp2
split_ifs
· exfalso
(expose_names;exact this (id (Eq.symm h)))
· exfalso
expose_names
rw [hp2] at h
exact h (Eq.symm h_1.2)
ring
by_cases h_ai : a > i
by_cases h_bi : b = i
simp only [h_ai, id_eqzero _ _ h_ab]
have h_be0: b ∈ Finset.univ := by exact Finset.mem_univ b
rw [Finset.sum_eq_add_sum_diff_singleton (Finset.mem_univ a)]
have h_be: b ∈ Finset.univ \ {a} := by rw [Finset.mem_sdiff];constructor;exact h_be0;exact Finset.notMem_singleton.mpr fun a_1 => h_ab (id (Eq.symm a_1))
rw [Finset.sum_eq_add_sum_diff_singleton h_be]
have h_be1: i < a ∧ b = i := by constructor;apply h_ai;exact h_bi
have h_be3: ¬ a = i := by exact Fin.ne_of_gt h_ai
simp only [h_ab, h_be1, h_bi, h_be3]
simp
apply Finset.sum_eq_zero
intro p hp
split_ifs
· exfalso;expose_names;rw [h_1, h] at h_be3;exact h_be3 rfl
· exfalso;expose_names
have hineq1 : p ≠ i := by rw [Finset.mem_sdiff] at hp;obtain ⟨h_1, h_2⟩ := hp;exact ne_of_not_mem_cons h_2
apply hineq1 h
· exfalso;expose_names
have hineq2 : p ≠ a := by rw [Finset.mem_sdiff] at hp;obtain ⟨h_1, h_2⟩ := hp;rw [Finset.mem_sdiff] at h_1;obtain ⟨h_3, h_4⟩ := h_1;exact ne_of_not_mem_cons h_4
apply hineq2 (Eq.symm h_2)
· ring
ring
simp only [h_ai, h_bi, id_eqzero _ _ h_ab]
apply Finset.sum_eq_zero
intro p hp
simp
intro p'
split_ifs
· exfalso
expose_names;rw [h, p'] at h_ab;exact h_ab rfl
· exfalso
expose_names;rw [h_1] at p';apply absurd (Eq.symm p') h_bi
ring
simp only [h_ai, id_eqzero _ _ h_ab]
apply Finset.sum_eq_zero
intro p hp
simp
split_ifs
· exfalso
expose_names;rw [← h_1] at h;exact h_ab h
· rfl
· exfalso
expose_names;obtain ⟨h_21, h_22⟩ := h_2;exact h_ai h_1.1
ring
ring
lemma row_trans_matrix_inv_mul_eq_one (M : Gaussian n m K) (i : Fin n) (j : Fin m) :
row_trans_matrix_inv M i j * row_trans_matrix M i j = 1 := by
ext a b
simp only [row_trans_matrix_inv, row_trans_matrix, Matrix.mul_apply]
by_cases h_ab : a = b
rw [h_ab]
rw [← Finset.sum_add_sum_compl {b}]
simp
apply Finset.sum_eq_zero
intro p hp
have : p ≠ b := by simpa using hp
simp [this]
intro hp1 hp2
split_ifs
· exfalso
(expose_names;exact this (id (Eq.symm h)))
· exfalso
expose_names
rw [hp2] at h
exact h (Eq.symm h_1.2)
ring
by_cases h_ai : a > i
by_cases h_bi : b = i
simp only [h_ai, id_eqzero _ _ h_ab]
have h_be0: b ∈ Finset.univ := by exact Finset.mem_univ b
rw [Finset.sum_eq_add_sum_diff_singleton (Finset.mem_univ a)]
have h_be: b ∈ Finset.univ \ {a} := by rw [Finset.mem_sdiff];constructor;exact h_be0;exact Finset.notMem_singleton.mpr fun a_1 => h_ab (id (Eq.symm a_1))
rw [Finset.sum_eq_add_sum_diff_singleton h_be]
have h_be1: i < a ∧ b = i := by constructor;apply h_ai;exact h_bi
have h_be3: ¬ a = i := by exact Fin.ne_of_gt h_ai
simp only [h_ab, h_be1, h_bi, h_be3]
simp
apply Finset.sum_eq_zero
intro p hp
split_ifs
· exfalso;expose_names;rw [h_1, h] at h_be3;exact h_be3 rfl
· exfalso;expose_names
have hineq1 : p ≠ i := by rw [Finset.mem_sdiff] at hp;obtain ⟨h_1, h_2⟩ := hp;exact ne_of_not_mem_cons h_2
apply hineq1 h
· exfalso;expose_names
have hineq2 : p ≠ a := by rw [Finset.mem_sdiff] at hp;obtain ⟨h_1, h_2⟩ := hp;rw [Finset.mem_sdiff] at h_1;obtain ⟨h_3, h_4⟩ := h_1;exact ne_of_not_mem_cons h_4
apply hineq2 (Eq.symm h_2)
· ring
ring
simp only [h_ai, h_bi, id_eqzero _ _ h_ab]
apply Finset.sum_eq_zero
intro p hp
simp
intro p'
split_ifs
· exfalso
expose_names;rw [h, p'] at h_ab;exact h_ab rfl
· exfalso
expose_names;rw [h_1] at p';apply absurd (Eq.symm p') h_bi
ring
simp only [h_ai, id_eqzero _ _ h_ab]
apply Finset.sum_eq_zero
intro p hp
simp
split_ifs
· exfalso
expose_names;rw [← h_1] at h;exact h_ab h
· rfl
· exfalso
expose_names;obtain ⟨h_21, h_22⟩ := h_2;exact h_ai h_1.1
ring
ring --证明过程完全一模一样,不知道怎么简化
lemma Gaussian.gaussian_elimination_row_eq_left_mul :
∃ (P : GL (Fin n) K), P.1 • M = M.gaussian_elimination_step_row i j := by
have h_mul₁ (A : Matrix (Fin n) (Fin n) K) (B : Matrix (Fin n) (Fin n) K) (C : Matrix (Fin n) (Fin n) K) (i : Fin n) (j : Fin n): (A * B) i j - (C * B) i j = ((A - C) * B) i j := by simp only [Matrix.mul_apply];rw [← Finset.sum_sub_distrib]; congr; funext k; simp [sub_mul]
have h_mul₂ (A : Matrix (Fin n) (Fin n) K) (B : Matrix (Fin n) (Fin m) K) (C : Matrix (Fin n) (Fin n) K) (i : Fin n) (j : Fin m): (A * B) i j - (C * B) i j = ((A - C) * B) i j := by simp only [Matrix.mul_apply];rw [← Finset.sum_sub_distrib]; congr; funext k; simp [sub_mul]
let P_mat := row_trans_matrix M i j
let P_inv := row_trans_matrix_inv M i j
let P : GL (Fin n) K := ⟨P_mat, P_inv, row_trans_matrix_mul_inv_eq_one M i j, row_trans_matrix_inv_mul_eq_one M i j⟩
use P
have h₁: P.1 • M = ⟨P.1 * M.P, P.1 * M.R, M.Q, M.M, by simp [M.hm, Matrix.mul_assoc];⟩ := by
exact rfl
have h₂: M.gaussian_elimination_step_row i j = ⟨fun k => gaussian_update M.P i k (M.R i j) (M.R k j), fun k => gaussian_update M.R i k (M.R i j) (M.R k j), M.Q, M.M, by
funext k
simp only [gaussian_update, gaussian_update_row, Matrix.mul_apply_eq_vecMul,
Matrix.vecMul_vecMul, ← M.hm]
split_ifs with h_le
simp
simp [sub_vecMul, Matrix.vecMul_smul, Matrix.vecMul_smul];⟩ := by rfl
rw [h₁, h₂]
congr
· ext
simp only [Gaussian.gaussian_elimination_step_row, gaussian_update, P, P_mat, row_trans_matrix]
rw [← sub_eq_zero]
nth_rewrite 2 [← Matrix.one_mul M.P]
split_ifs with h_ki
rw [h_mul₁]
simp only [Matrix.mul_apply]
apply Finset.sum_eq_zero
intro p hp
simp
split_ifs
expose_names;simp only [id_eqone _ _ h];ring
exfalso;expose_names;apply lt_irrefl i_1;exact (lt_of_le_of_lt h_ki h_1.1)
expose_names;simp only [id_eqzero _ _ h];ring
rw [Pi.sub_apply]
sorry
ext
simp only [Gaussian.gaussian_elimination_step_row, gaussian_update, P, P_mat]
rw [← sub_eq_zero]
nth_rewrite 3 [← Matrix.one_mul M.R]
split_ifs with h_ki
nth_rewrite 2 [← Matrix.one_mul M.R]
rw [h_mul₂]
simp only [Matrix.mul_apply]
apply Finset.sum_eq_zero
intro p hp
simp
split_ifs
expose_names;simp only [id_eqone _ _ h];ring --i=p
exfalso;expose_names;apply lt_irrefl i_1;exact (lt_of_le_of_lt h_ki h_1.1)
expose_names;simp only [id_eqzero _ _ h];ring
simp
sorry
end PrimaryTransformation
Last updated: Dec 20 2025 at 21:32 UTC