Zulip Chat Archive
Stream: new members
Topic: I want to write a lemma eq_empty_iff_forall_not_mem
Nick_adfor (May 18 2025 at 06:19):
import Mathlib
lemma eq_empty_iff_forall_not_mem {α : Type*} {s : Finset α} :
s = ∅ ↔ ∀ x, x ∉ s := by
rw [Finset.ext_iff]
simp only [Finset.not_mem_empty, true_iff]
exact fun h x => h x
But it cannot run as vscode tell me that
type mismatch
fun h x => ?m.18219
has type
(h : ?m.18212) → (x : ?m.18220 h) → ?m.18221 h x : Sort (imax ?u.18211 ?u.18214 ?u.18217)
but is expected to have type
(∀ (a : α), a ∈ s ↔ False) ↔ ∀ (x : α), x ∉ s : Prop
Robin Arnez (May 18 2025 at 06:33):
You have an iff (↔) not an implication! Putting iff_false in the simp before should do the trick
Nick_adfor (May 18 2025 at 06:33):
import Mathlib
open Equiv Perm
def IsDoubleTransposition (σ : Perm (Fin 4)) : Prop :=
∃ (a b c d : Fin 4), a ≠ b ∧ c ≠ d ∧
Disjoint (support (swap a b)) (support (swap c d)) ∧
σ = swap a b * swap c d
def doubleTranspositions : List (Perm (Fin 4)) :=
[swap 0 1 * swap 2 3,
swap 0 2 * swap 1 3,
swap 0 3 * swap 1 2]
lemma mem_cons_iff_three {α : Type*} {x a b c : α} {l : List α} :
x ∈ [a, b, c] ++ l ↔ x = a ∨ x = b ∨ x = c ∨ x ∈ l := by
simp only [List.mem_cons, List.cons_append, List.mem_append]
lemma eq_empty_iff_forall_not_mem {α : Type*} {s : Finset α} :
s = ∅ ↔ ∀ x, x ∉ s := by
rw [Finset.ext_iff]
simp only [Finset.not_mem_empty, iff_false]
lemma mem_doubleTranspositions_iff {σ : Perm (Fin 4)} :
σ ∈ doubleTranspositions ↔ IsDoubleTransposition σ := by
constructor
· intro h
simp [doubleTranspositions] at h
rcases h with rfl | rfl | rfl
· exact ⟨0, 1, 2, 3, by decide, by decide, by decide, rfl⟩
· exact ⟨0, 2, 1, 3, by decide, by decide, by decide, rfl⟩
· exact ⟨0, 3, 1, 2, by decide, by decide, by decide, rfl⟩
intro h
rcases h with ⟨a, b, c, d, hab, hcd, hdisj, rfl⟩
have distinct : ∀ x ∈ ({a, b} : Finset (Fin 4)), ∀ y ∈ ({c, d} : Finset (Fin 4)), x ≠ y := by
intro x hx y hy
rw [Finset.disjoint_iff_inter_eq_empty, eq_empty_iff_forall_not_mem] at hdisj
exact hdisj ⟨x, hx, hy⟩
fin_cases a <;> fin_cases b <;> fin_cases c <;> fin_cases d <;>
try { simp [distinct, hab, hcd] at * } <;>
simp [doubleTranspositions, mem_cons_iff_three, *]
The whole code is here. I want to prove σ ∈ doubleTranspositions ↔ IsDoubleTransposition σ, and in it I need two lemmas to prove lemma mem_doubleTranspositions_iff
Nick_adfor (May 18 2025 at 06:35):
Robin Arnez said:
You have an iff (
↔) not an implication! Puttingiff_falsein thesimpbefore should do the trick
OK, thanks:
I fix it as
lemma eq_empty_iff_forall_not_mem {α : Type*} {s : Finset α} :
s = ∅ ↔ ∀ x, x ∉ s := by
rw [Finset.ext_iff]
simp only [Finset.not_mem_empty, iff_false]
Nick_adfor (May 18 2025 at 06:38):
For the whole proof, the part
have distinct : ∀ x ∈ ({a, b} : Finset (Fin 4)), ∀ y ∈ ({c, d} : Finset (Fin 4)), x ≠ y := by
intro x hx y hy
rw [Finset.disjoint_iff_inter_eq_empty, eq_empty_iff_forall_not_mem] at hdisj
exact hdisj ⟨x, hx, hy⟩
fin_cases a <;> fin_cases b <;> fin_cases c <;> fin_cases d <;>
try { simp [distinct, hab, hcd] at * } <;>
simp [doubleTranspositions, mem_cons_iff_three, *]
eq_empty_iff_forall_not_mem and mem_cons_iff_three should be my lemmas, but it does not work that well in the whole code.
Robin Arnez (May 18 2025 at 06:48):
You can use the decide +revert tactic for the last part:
· intro h
rcases h with ⟨a, b, c, d, hab, hcd, hdisj, rfl⟩
decide +revert
Sébastien Gouëzel (May 18 2025 at 06:50):
Since the whole proof is about finite objects, you can also brute-force your statement by checking it for all these objects, as in
lemma mem_doubleTranspositions_iff {σ : Perm (Fin 4)} :
σ ∈ doubleTranspositions ↔ IsDoubleTransposition σ := by
revert σ
simp only [doubleTranspositions, IsDoubleTransposition]
decide
Nick_adfor (May 18 2025 at 06:58):
Robin Arnez said:
You can use the
decide +reverttactic for the last part:· intro h rcases h with ⟨a, b, c, d, hab, hcd, hdisj, rfl⟩ decide +revert
Sébastien Gouëzel said:
Since the whole proof is about finite objects, you can also brute-force your statement by checking it for all these objects, as in
lemma mem_doubleTranspositions_iff {σ : Perm (Fin 4)} : σ ∈ doubleTranspositions ↔ IsDoubleTransposition σ := by revert σ simp only [doubleTranspositions, IsDoubleTransposition] decide
Thanks for all! I do not know that lean can check the code for all the finite objects, I think that I may need to write by myself, which truely confused me.
Nick_adfor (May 18 2025 at 07:00):
What about the part as follows? I may think it can be shortened, too.
· intro h
simp [doubleTranspositions] at h
rcases h with rfl | rfl | rfl
· exact ⟨0, 1, 2, 3, by decide, by decide, by decide, rfl⟩
· exact ⟨0, 2, 1, 3, by decide, by decide, by decide, rfl⟩
· exact ⟨0, 3, 1, 2, by decide, by decide, by decide, rfl⟩
Robin Arnez (May 18 2025 at 07:20):
I mean, instead of intro; simp; rcases you can do rintro (_ | ⟨_, _ | ⟨_, _ | ⟨_, _ | _⟩⟩⟩) although I would need some time to explain why that works
Nick_adfor (May 18 2025 at 07:30):
Robin Arnez said:
I mean, instead of
intro; simp; rcasesyou can dorintro (_ | ⟨_, _ | ⟨_, _ | ⟨_, _ | _⟩⟩⟩)although I would need some time to explain why that works
lemma mem_doubleTranspositions_iff {σ : Perm (Fin 4)} :
σ ∈ doubleTranspositions ↔ IsDoubleTransposition σ := by
constructor
· rintro (_ | ⟨_, _ | ⟨_, _ | ⟨_, _ | _⟩⟩⟩)
repeat
exact ⟨_, _, _, _, by decide, by decide, by decide, rfl⟩
· intro h
rcases h with ⟨a, b, c, d, hab, hcd, hdisj, rfl⟩
decide +revert
So the lemma is now like this. It is totally a magic! But I also need some time to explain why that works. And I do want to ask how can you write such a brief code even you cannot explain why it works? It might be a unbelievable ability for me to learn.
Sébastien Gouëzel (May 18 2025 at 07:38):
As I wrote above, an even better (and shorter) proof is
lemma mem_doubleTranspositions_iff {σ : Perm (Fin 4)} :
σ ∈ doubleTranspositions ↔ IsDoubleTransposition σ := by
revert σ
simp only [doubleTranspositions, IsDoubleTransposition]
decide
It says: expand the definition of doubleTranspositions and IsDoubleTransposition, and then check for each individual permutation that the result is true. Since there are finitely many permutations to check, it's fine.
Sébastien Gouëzel (May 18 2025 at 07:40):
Or the even shorter version
lemma mem_doubleTranspositions_iff {σ : Perm (Fin 4)} :
σ ∈ doubleTranspositions ↔ IsDoubleTransposition σ := by
simp only [doubleTranspositions, IsDoubleTransposition]
decide +revert
Nick_adfor (May 18 2025 at 07:41):
If I write
def allThreeCycles : List (Perm (Fin 4)) :=
[swap 0 1 * swap 0 2, -- (0 1 2)
swap 0 2 * swap 0 1, -- (0 2 1)
swap 0 1 * swap 0 3, -- (0 1 3)
swap 0 3 * swap 0 1, -- (0 3 1)
swap 0 2 * swap 0 3, -- (0 2 3)
swap 0 3 * swap 0 2, -- (0 3 2)
swap 1 2 * swap 1 3, -- (1 2 3)
swap 1 3 * swap 1 2] -- (1 3 2)
--lean does not have a good way to define a list of all 3-cycles, so I use swap products.
lemma mem_allThreeCycles_iff {σ : Perm (Fin 4)} :
σ ∈ allThreeCycles ↔ σ.IsThreeCycle := by
revert σ
simp only [allThreeCycles, IsThreeCycle]
decide
Then it cannot work. Why that? The tactic seems a failure for ThreeCycles.
Nick_adfor (May 18 2025 at 07:46):
Sébastien Gouëzel said:
Or the even shorter version
lemma mem_doubleTranspositions_iff {σ : Perm (Fin 4)} : σ ∈ doubleTranspositions ↔ IsDoubleTransposition σ := by simp only [doubleTranspositions, IsDoubleTransposition] decide +revert
I seem to know something. "decide + revert" means if it can decide, then decide, if cannot, then first revert, second decide. (I don't know if the explanation is right.)
Nick_adfor (May 18 2025 at 08:13):
lemma Equiv.Perm.IsThreeCycle.exists_swap_mul_swap {σ : Perm (Fin 4)}
(h : σ.IsThreeCycle) :
∃ a b c : Fin 4, a ≠ b ∧ a ≠ c ∧ b ≠ c ∧ σ = swap a b * swap a c := by
have : σ ∈ allThreeCycles := by sorry
I may seem to introduce a new lemma, and seems that it can "decie", too, but I do not know how to write this.
Last updated: Dec 20 2025 at 21:32 UTC