Skip to content

Commit fab3be6

Browse files
committed
feat: more use of grind with Equiv (#31271)
Follow-up to #30909. There are several in flight Lean PRs that may improve the situation further: * leanprover/lean4#11088 * leanprover/lean4#11087 * leanprover/lean4#11086
1 parent b8da199 commit fab3be6

File tree

4 files changed

+35
-34
lines changed

4 files changed

+35
-34
lines changed

Mathlib/Logic/Equiv/Basic.lean

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ section
143143

144144
/-- A family of equivalences `∀ a, β₁ a ≃ β₂ a` generates an equivalence between `∀ a, β₁ a` and
145145
`∀ a, β₂ a`. -/
146-
@[simps]
146+
@[simps (attr := grind =)]
147147
def piCongrRight {β₁ β₂ : α → Sort*} (F : ∀ a, β₁ a ≃ β₂ a) : (∀ a, β₁ a) ≃ (∀ a, β₂ a) :=
148148
⟨Pi.map fun a ↦ F a, Pi.map fun a ↦ (F a).symm, fun H => funext <| by simp,
149149
fun H => funext <| by simp⟩
@@ -671,21 +671,20 @@ theorem symm_swap (a b : α) : (swap a b).symm = swap a b :=
671671
rfl
672672

673673
@[simp]
674-
theorem swap_eq_refl_iff {x y : α} : swap x y = Equiv.refl _ ↔ x = y := by
675-
refine ⟨fun h => (Equiv.refl _).injective ?_, fun h => h ▸ swap_self _⟩
676-
rw [← h, swap_apply_left, h, refl_apply]
674+
theorem swap_eq_refl_iff {x y : α} : swap x y = Equiv.refl _ ↔ x = y :=
675+
fun h => (Equiv.refl _).injective (by grind), by grind⟩
677676

678677
theorem swap_comp_apply {a b x : α} (π : Perm α) :
679678
π.trans (swap a b) x = if π x = a then b else if π x = b then a else π x := by
680679
cases π
681680
rfl
682681

683682
theorem swap_eq_update (i j : α) : (Equiv.swap i j : α → α) = update (update id j i) i j := by
684-
aesop
683+
grind
685684

686685
theorem comp_swap_eq_update (i j : α) (f : α → β) :
687686
f ∘ Equiv.swap i j = update (update f j (f i)) i (f j) := by
688-
aesop
687+
grind
689688

690689
@[simp]
691690
theorem symm_trans_swap_trans [DecidableEq β] (a b : α) (e : α ≃ β) :
@@ -699,15 +698,15 @@ theorem trans_swap_trans_symm [DecidableEq β] (a b : β) (e : α ≃ β) :
699698

700699
@[simp]
701700
theorem swap_apply_self (i j a : α) : swap i j (swap i j a) = a := by
702-
rw [← Equiv.trans_apply, Equiv.swap_swap, Equiv.refl_apply]
701+
grind
703702

704703
/-- A function is invariant to a swap if it is equal at both elements -/
705704
theorem apply_swap_eq_self {v : α → β} {i j : α} (hv : v i = v j) (k : α) :
706705
v (swap i j k) = v k := by
707706
grind
708707

709708
theorem swap_apply_eq_iff {x y z w : α} : swap x y z = w ↔ z = swap x y w := by
710-
rw [apply_eq_iff_eq_symm_apply, symm_swap]
709+
grind
711710

712711
theorem swap_apply_ne_self_iff {a b x : α} : swap a b x ≠ x ↔ a ≠ b ∧ (x = a ∨ x = b) := by
713712
grind
@@ -768,9 +767,10 @@ theorem Function.Injective.map_swap [DecidableEq α] [DecidableEq β] {f : α
768767
f (Equiv.swap x y z) = Equiv.swap (f x) (f y) (f z) := by
769768
conv_rhs => rw [Equiv.swap_apply_def]
770769
split_ifs with h₁ h₂
771-
· rw [hf h₁, Equiv.swap_apply_left]
770+
· -- We can't yet use `grind` here because of https://github.com/leanprover/lean4/issues/11088
771+
rw [hf h₁, Equiv.swap_apply_left]
772772
· rw [hf h₂, Equiv.swap_apply_right]
773-
· rw [Equiv.swap_apply_of_ne_of_ne (mt (congr_arg f) h₁) (mt (congr_arg f) h₂)]
773+
· grind
774774

775775
namespace Equiv
776776

@@ -827,7 +827,7 @@ lemma piCongrLeft_apply (f : ∀ a, P (e a)) (b : β) :
827827
(piCongrLeft P e) f b = e.apply_symm_apply b ▸ f (e.symm b) :=
828828
rfl
829829

830-
@[simp]
830+
@[simp, grind =]
831831
lemma piCongrLeft_symm_apply (g : ∀ b, P b) (a : α) :
832832
(piCongrLeft P e).symm g a = g (e a) :=
833833
piCongrLeft'_apply P e.symm g a
@@ -840,7 +840,7 @@ lemma piCongrLeft_refl (P : α → Sort*) : piCongrLeft P (.refl α) = .refl (
840840
LHS would have type `P b` while the RHS would have type `P (e (e.symm b))`. This lemma is a way
841841
around it in the case where `b` is of the form `e a`, so we can use `f a` instead of
842842
`f (e.symm (e a))`. -/
843-
@[simp]
843+
@[simp, grind =]
844844
lemma piCongrLeft_apply_apply (f : ∀ a, P (e a)) (a : α) :
845845
(piCongrLeft P e) f (e a) = f a :=
846846
piCongrLeft'_symm_apply_apply P e.symm f a
@@ -855,12 +855,12 @@ lemma piCongrLeft_apply_eq_cast {P : β → Sort v} {e : α ≃ β}
855855
theorem piCongrLeft_sumInl {ι ι' ι''} (π : ι'' → Type*) (e : ι ⊕ ι' ≃ ι'') (f : ∀ i, π (e (inl i)))
856856
(g : ∀ i, π (e (inr i))) (i : ι) :
857857
piCongrLeft π e (sumPiEquivProdPi (fun x => π (e x)) |>.symm (f, g)) (e (inl i)) = f i := by
858-
aesop
858+
grind
859859

860860
theorem piCongrLeft_sumInr {ι ι' ι''} (π : ι'' → Type*) (e : ι ⊕ ι' ≃ ι'') (f : ∀ i, π (e (inl i)))
861861
(g : ∀ i, π (e (inr i))) (j : ι') :
862862
piCongrLeft π e (sumPiEquivProdPi (fun x => π (e x)) |>.symm (f, g)) (e (inr j)) = g j := by
863-
aesop
863+
grind
864864

865865
end
866866

@@ -876,18 +876,18 @@ def piCongr : (∀ a, W a) ≃ ∀ b, Z b :=
876876
(Equiv.piCongrRight h₂).trans (Equiv.piCongrLeft _ h₁)
877877

878878
@[simp]
879-
theorem coe_piCongr_symm : ((h₁.piCongr h₂).symm :
880-
(∀ b, Z b) → ∀ a, W a) = fun f a => (h₂ a).symm (f (h₁ a)) :=
879+
theorem coe_piCongr_symm :
880+
((h₁.piCongr h₂).symm : (∀ b, Z b) → ∀ a, W a) = fun f a => (h₂ a).symm (f (h₁ a)) :=
881881
rfl
882882

883-
@[simp]
883+
@[simp, grind =]
884884
theorem piCongr_symm_apply (f : ∀ b, Z b) :
885885
(h₁.piCongr h₂).symm f = fun a => (h₂ a).symm (f (h₁ a)) :=
886886
rfl
887887

888-
@[simp]
888+
@[simp, grind =]
889889
theorem piCongr_apply_apply (f : ∀ a, W a) (a : α) : h₁.piCongr h₂ f (h₁ a) = h₂ a (f a) := by
890-
simp only [piCongr, piCongrRight, trans_apply, coe_fn_mk, piCongrLeft_apply_apply, Pi.map_apply]
890+
rw [piCongr, trans_apply, piCongrLeft_apply_apply, piCongrRight_apply, Pi.map_apply]
891891

892892
end
893893

Mathlib/Logic/Equiv/Prod.lean

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ open Sum
343343

344344
/-- The type of dependent functions on a sum type `ι ⊕ ι'` is equivalent to the type of pairs of
345345
functions on `ι` and on `ι'`. This is a dependent version of `Equiv.sumArrowEquivProdArrow`. -/
346-
@[simps]
346+
@[simps (attr := grind =)]
347347
def sumPiEquivProdPi {ι ι'} (π : ι ⊕ ι' → Type*) :
348348
(∀ i, π i) ≃ (∀ i, π (inl i)) × ∀ i', π (inr i') where
349349
toFun f := ⟨fun i => f (inl i), fun i' => f (inr i')⟩
@@ -352,7 +352,7 @@ def sumPiEquivProdPi {ι ι'} (π : ι ⊕ ι' → Type*) :
352352

353353
/-- The equivalence between a product of two dependent functions types and a single dependent
354354
function type. Basically a symmetric version of `Equiv.sumPiEquivProdPi`. -/
355-
@[simps!]
355+
@[simps! (attr := grind =)]
356356
def prodPiEquivSumPi {ι ι'} (π : ι → Type u) (π' : ι' → Type u) :
357357
((∀ i, π i) × ∀ i', π' i') ≃ ∀ i, Sum.elim π π' i :=
358358
sumPiEquivProdPi (Sum.elim π π') |>.symm
@@ -364,22 +364,22 @@ def sumArrowEquivProdArrow (α β γ : Type*) : (α ⊕ β → γ) ≃ (α →
364364
cases p
365365
rfl⟩
366366

367-
@[simp]
367+
@[simp, grind =]
368368
theorem sumArrowEquivProdArrow_apply_fst {α β γ} (f : α ⊕ β → γ) (a : α) :
369369
(sumArrowEquivProdArrow α β γ f).1 a = f (inl a) :=
370370
rfl
371371

372-
@[simp]
372+
@[simp, grind =]
373373
theorem sumArrowEquivProdArrow_apply_snd {α β γ} (f : α ⊕ β → γ) (b : β) :
374374
(sumArrowEquivProdArrow α β γ f).2 b = f (inr b) :=
375375
rfl
376376

377-
@[simp]
377+
@[simp, grind =]
378378
theorem sumArrowEquivProdArrow_symm_apply_inl {α β γ} (f : α → γ) (g : β → γ) (a : α) :
379379
((sumArrowEquivProdArrow α β γ).symm (f, g)) (inl a) = f a :=
380380
rfl
381381

382-
@[simp]
382+
@[simp, grind =]
383383
theorem sumArrowEquivProdArrow_symm_apply_inr {α β γ} (f : α → γ) (g : β → γ) (b : β) :
384384
((sumArrowEquivProdArrow α β γ).symm (f, g)) (inr b) = g b :=
385385
rfl
@@ -390,42 +390,42 @@ def sumProdDistrib (α β γ) : (α ⊕ β) × γ ≃ α × γ ⊕ β × γ :=
390390
fun s => s.elim (Prod.map inl id) (Prod.map inr id), by
391391
rintro ⟨_ | _, _⟩ <;> rfl, by rintro (⟨_, _⟩ | ⟨_, _⟩) <;> rfl⟩
392392

393-
@[simp]
393+
@[simp, grind =]
394394
theorem sumProdDistrib_apply_left {α β γ} (a : α) (c : γ) :
395395
sumProdDistrib α β γ (Sum.inl a, c) = Sum.inl (a, c) :=
396396
rfl
397397

398-
@[simp]
398+
@[simp, grind =]
399399
theorem sumProdDistrib_apply_right {α β γ} (b : β) (c : γ) :
400400
sumProdDistrib α β γ (Sum.inr b, c) = Sum.inr (b, c) :=
401401
rfl
402402

403-
@[simp]
403+
@[simp, grind =]
404404
theorem sumProdDistrib_symm_apply_left {α β γ} (a : α × γ) :
405405
(sumProdDistrib α β γ).symm (inl a) = (inl a.1, a.2) :=
406406
rfl
407407

408-
@[simp]
408+
@[simp, grind =]
409409
theorem sumProdDistrib_symm_apply_right {α β γ} (b : β × γ) :
410410
(sumProdDistrib α β γ).symm (inr b) = (inr b.1, b.2) :=
411411
rfl
412412

413413
/-- The product of an indexed sum of types (formally, a `Sigma`-type `Σ i, α i`) by a type `β` is
414414
equivalent to the sum of products `Σ i, (α i × β)`. -/
415-
@[simps apply symm_apply]
415+
@[simps (attr := grind =) apply symm_apply]
416416
def sigmaProdDistrib {ι : Type*} (α : ι → Type*) (β : Type*) : (Σ i, α i) × β ≃ Σ i, α i × β :=
417417
fun p => ⟨p.1.1, (p.1.2, p.2)⟩, fun p => (⟨p.1, p.2.1⟩, p.2.2), by grind, by grind⟩
418418

419419
/-- The product `Bool × α` is equivalent to `α ⊕ α`. -/
420-
@[simps]
420+
@[simps (attr := grind =)]
421421
def boolProdEquivSum (α) : Bool × α ≃ α ⊕ α where
422422
toFun p := if p.1 then (inr p.2) else (inl p.2)
423423
invFun := Sum.elim (Prod.mk false) (Prod.mk true)
424424
left_inv := by rintro ⟨_ | _, _⟩ <;> rfl
425425
right_inv := by rintro (_ | _) <;> rfl
426426

427427
/-- The function type `Bool → α` is equivalent to `α × α`. -/
428-
@[simps]
428+
@[simps (attr := grind =)]
429429
def boolArrowEquivProd (α : Type*) : (Bool → α) ≃ α × α where
430430
toFun f := (f false, f true)
431431
invFun p b := if b then p.2 else p.1

Mathlib/Logic/Equiv/Sum.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ def psumEquivSum (α β) : α ⊕' β ≃ α ⊕ β where
5151
right_inv s := by cases s <;> rfl
5252

5353
/-- If `α ≃ α'` and `β ≃ β'`, then `α ⊕ β ≃ α' ⊕ β'`. This is `Sum.map` as an equivalence. -/
54-
@[simps apply]
54+
@[simps (attr := grind =) apply]
5555
def sumCongr {α₁ α₂ β₁ β₂} (ea : α₁ ≃ α₂) (eb : β₁ ≃ β₂) : α₁ ⊕ β₁ ≃ α₂ ⊕ β₂ :=
5656
⟨Sum.map ea eb, Sum.map ea.symm eb.symm, fun x => by simp, fun x => by simp⟩
5757

58-
@[simp]
58+
@[simp, grind =]
5959
theorem sumCongr_trans {α₁ α₂ β₁ β₂ γ₁ γ₂} (e : α₁ ≃ β₁) (f : α₂ ≃ β₂) (g : β₁ ≃ γ₁) (h : β₂ ≃ γ₂) :
6060
(Equiv.sumCongr e f).trans (Equiv.sumCongr g h) = Equiv.sumCongr (e.trans g) (f.trans h) := by
6161
ext i

Mathlib/Logic/Function/Basic.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ variable {α : Sort u} {β : α → Sort v} {α' : Sort w} [DecidableEq α]
482482

483483

484484
/-- Replacing the value of a function at a given point by a given value. -/
485+
@[grind]
485486
def update (f : ∀ a, β a) (a' : α) (v : β a') (a : α) : β a :=
486487
if h : a = a' then Eq.ndrec v h.symm else f a
487488

0 commit comments

Comments
 (0)