data.finset.pi_inductionMathlib.Data.Finset.PiInduction

This file has been ported!

Changes since the initial port

The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.

Changes in mathlib3

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(last sync)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -55,7 +55,7 @@ theorem induction_on_pi_of_choice (r : ∀ i, α i → Finset (α i) → Prop)
     have hx' : x ∉ g i := by rw [hg, update_same]; apply not_mem_erase
     obtain rfl : f = update g i (insert x (g i)) := by
       rw [hg, update_idem, update_same, insert_erase x_mem, update_eq_self]
-    clear hg; rw [update_same, erase_insert hx'] at hr 
+    clear hg; rw [update_same, erase_insert hx'] at hr
     refine' step _ _ _ hr (ihs (univ.sigma g) _ _ rfl)
     rw [ssubset_iff_of_subset (sigma_mono (subset.refl _) _)]
     exacts [⟨⟨i, x⟩, mem_sigma.2 ⟨mem_univ _, by simp⟩, by simp [hx']⟩,
Diff
@@ -3,8 +3,8 @@ Copyright (c) 2021 Yury Kudryashov. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Yury Kudryashov
 -/
-import Mathbin.Data.Fintype.Lattice
-import Mathbin.Data.Finset.Sigma
+import Data.Fintype.Lattice
+import Data.Finset.Sigma
 
 #align_import data.finset.pi_induction from "leanprover-community/mathlib"@"a11f9106a169dd302a285019e5165f8ab32ff433"
 
Diff
@@ -2,15 +2,12 @@
 Copyright (c) 2021 Yury Kudryashov. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Yury Kudryashov
-
-! This file was ported from Lean 3 source module data.finset.pi_induction
-! leanprover-community/mathlib commit a11f9106a169dd302a285019e5165f8ab32ff433
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Data.Fintype.Lattice
 import Mathbin.Data.Finset.Sigma
 
+#align_import data.finset.pi_induction from "leanprover-community/mathlib"@"a11f9106a169dd302a285019e5165f8ab32ff433"
+
 /-!
 # Induction principles for `Π i, finset (α i)`
 
Diff
@@ -39,6 +39,7 @@ variable {ι : Type _} {α : ι → Type _} [Finite ι] [DecidableEq ι] [∀ i,
 
 namespace Finset
 
+#print Finset.induction_on_pi_of_choice /-
 /-- General theorem for `finset.induction_on_pi`-style induction principles. -/
 theorem induction_on_pi_of_choice (r : ∀ i, α i → Finset (α i) → Prop)
     (H_ex : ∀ (i) (s : Finset (α i)) (hs : s.Nonempty), ∃ x ∈ s, r i x (s.eraseₓ x))
@@ -63,6 +64,7 @@ theorem induction_on_pi_of_choice (r : ∀ i, α i → Finset (α i) → Prop)
     exacts [⟨⟨i, x⟩, mem_sigma.2 ⟨mem_univ _, by simp⟩, by simp [hx']⟩,
       (@le_update_iff _ _ _ _ g g i _).2 ⟨subset_insert _ _, fun _ _ => le_rfl⟩]
 #align finset.induction_on_pi_of_choice Finset.induction_on_pi_of_choice
+-/
 
 #print Finset.induction_on_pi /-
 /-- Given a predicate on functions `Π i, finset (α i)` defined on a finite type, it is true on all
Diff
@@ -57,10 +57,10 @@ theorem induction_on_pi_of_choice (r : ∀ i, α i → Finset (α i) → Prop)
     have hx' : x ∉ g i := by rw [hg, update_same]; apply not_mem_erase
     obtain rfl : f = update g i (insert x (g i)) := by
       rw [hg, update_idem, update_same, insert_erase x_mem, update_eq_self]
-    clear hg; rw [update_same, erase_insert hx'] at hr
+    clear hg; rw [update_same, erase_insert hx'] at hr 
     refine' step _ _ _ hr (ihs (univ.sigma g) _ _ rfl)
     rw [ssubset_iff_of_subset (sigma_mono (subset.refl _) _)]
-    exacts[⟨⟨i, x⟩, mem_sigma.2 ⟨mem_univ _, by simp⟩, by simp [hx']⟩,
+    exacts [⟨⟨i, x⟩, mem_sigma.2 ⟨mem_univ _, by simp⟩, by simp [hx']⟩,
       (@le_update_iff _ _ _ _ g g i _).2 ⟨subset_insert _ _, fun _ _ => le_rfl⟩]
 #align finset.induction_on_pi_of_choice Finset.induction_on_pi_of_choice
 
Diff
@@ -81,6 +81,7 @@ theorem induction_on_pi {p : (∀ i, Finset (α i)) → Prop} (f : ∀ i, Finset
 #align finset.induction_on_pi Finset.induction_on_pi
 -/
 
+#print Finset.induction_on_pi_max /-
 /-- Given a predicate on functions `Π i, finset (α i)` defined on a finite type, it is true on all
 maps provided that it is true on `λ _, ∅` and for any function `g : Π i, finset (α i)`, an index
 `i : ι`, and an element`x : α i` that is strictly greater than all elements of `g i`, `p g` implies
@@ -97,7 +98,9 @@ theorem induction_on_pi_max [∀ i, LinearOrder (α i)] {p : (∀ i, Finset (α
   induction_on_pi_of_choice (fun i x s => ∀ y ∈ s, y < x)
     (fun i s hs => ⟨s.max' hs, s.max'_mem hs, fun y => s.lt_max'_of_mem_erase_max' _⟩) f h0 step
 #align finset.induction_on_pi_max Finset.induction_on_pi_max
+-/
 
+#print Finset.induction_on_pi_min /-
 /-- Given a predicate on functions `Π i, finset (α i)` defined on a finite type, it is true on all
 maps provided that it is true on `λ _, ∅` and for any function `g : Π i, finset (α i)`, an index
 `i : ι`, and an element`x : α i` that is strictly less than all elements of `g i`, `p g` implies
@@ -113,6 +116,7 @@ theorem induction_on_pi_min [∀ i, LinearOrder (α i)] {p : (∀ i, Finset (α
     p f :=
   @induction_on_pi_max ι (fun i => (α i)ᵒᵈ) _ _ _ _ _ _ h0 step
 #align finset.induction_on_pi_min Finset.induction_on_pi_min
+-/
 
 end Finset
 
Diff
@@ -39,12 +39,6 @@ variable {ι : Type _} {α : ι → Type _} [Finite ι] [DecidableEq ι] [∀ i,
 
 namespace Finset
 
-/- warning: finset.induction_on_pi_of_choice -> Finset.induction_on_pi_of_choice is a dubious translation:
-lean 3 declaration is
-  forall {ι : Type.{u1}} {α : ι -> Type.{u2}} [_inst_1 : Finite.{succ u1} ι] [_inst_2 : DecidableEq.{succ u1} ι] [_inst_3 : forall (i : ι), DecidableEq.{succ u2} (α i)] (r : forall (i : ι), (α i) -> (Finset.{u2} (α i)) -> Prop), (forall (i : ι) (s : Finset.{u2} (α i)), (Finset.Nonempty.{u2} (α i) s) -> (Exists.{succ u2} (α i) (fun (x : α i) => Exists.{0} (Membership.Mem.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.hasMem.{u2} (α i)) x s) (fun (H : Membership.Mem.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.hasMem.{u2} (α i)) x s) => r i x (Finset.erase.{u2} (α i) (fun (a : α i) (b : α i) => _inst_3 i a b) s x))))) -> (forall {p : (forall (i : ι), Finset.{u2} (α i)) -> Prop} (f : forall (i : ι), Finset.{u2} (α i)), (p (fun (_x : ι) => EmptyCollection.emptyCollection.{u2} (Finset.{u2} (α _x)) (Finset.hasEmptyc.{u2} (α _x)))) -> (forall (g : forall (i : ι), Finset.{u2} (α i)) (i : ι) (x : α i), (r i x (g i)) -> (p g) -> (p (Function.update.{succ u1, succ u2} ι (fun (i : ι) => Finset.{u2} (α i)) (fun (a : ι) (b : ι) => _inst_2 a b) g i (Insert.insert.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.hasInsert.{u2} (α i) (fun (a : α i) (b : α i) => _inst_3 i a b)) x (g i))))) -> (p f))
-but is expected to have type
-  forall {ι : Type.{u1}} {α : ι -> Type.{u2}} [_inst_1 : Finite.{succ u1} ι] [_inst_2 : DecidableEq.{succ u1} ι] [_inst_3 : forall (i : ι), DecidableEq.{succ u2} (α i)] (r : forall (i : ι), (α i) -> (Finset.{u2} (α i)) -> Prop), (forall (i : ι) (s : Finset.{u2} (α i)), (Finset.Nonempty.{u2} (α i) s) -> (Exists.{succ u2} (α i) (fun (x : α i) => And (Membership.mem.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.instMembershipFinset.{u2} (α i)) x s) (r i x (Finset.erase.{u2} (α i) (fun (a : α i) (b : α i) => _inst_3 i a b) s x))))) -> (forall {p : (forall (i : ι), Finset.{u2} (α i)) -> Prop} (f : forall (i : ι), Finset.{u2} (α i)), (p (fun (_x : ι) => EmptyCollection.emptyCollection.{u2} (Finset.{u2} (α _x)) (Finset.instEmptyCollectionFinset.{u2} (α _x)))) -> (forall (g : forall (i : ι), Finset.{u2} (α i)) (i : ι) (x : α i), (r i x (g i)) -> (p g) -> (p (Function.update.{succ u1, succ u2} ι (fun (i : ι) => Finset.{u2} (α i)) (fun (a : ι) (b : ι) => _inst_2 a b) g i (Insert.insert.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.instInsertFinset.{u2} (α i) (fun (a : α i) (b : α i) => _inst_3 i a b)) x (g i))))) -> (p f))
-Case conversion may be inaccurate. Consider using '#align finset.induction_on_pi_of_choice Finset.induction_on_pi_of_choiceₓ'. -/
 /-- General theorem for `finset.induction_on_pi`-style induction principles. -/
 theorem induction_on_pi_of_choice (r : ∀ i, α i → Finset (α i) → Prop)
     (H_ex : ∀ (i) (s : Finset (α i)) (hs : s.Nonempty), ∃ x ∈ s, r i x (s.eraseₓ x))
@@ -87,12 +81,6 @@ theorem induction_on_pi {p : (∀ i, Finset (α i)) → Prop} (f : ∀ i, Finset
 #align finset.induction_on_pi Finset.induction_on_pi
 -/
 
-/- warning: finset.induction_on_pi_max -> Finset.induction_on_pi_max is a dubious translation:
-lean 3 declaration is
-  forall {ι : Type.{u1}} {α : ι -> Type.{u2}} [_inst_1 : Finite.{succ u1} ι] [_inst_2 : DecidableEq.{succ u1} ι] [_inst_3 : forall (i : ι), DecidableEq.{succ u2} (α i)] [_inst_4 : forall (i : ι), LinearOrder.{u2} (α i)] {p : (forall (i : ι), Finset.{u2} (α i)) -> Prop} (f : forall (i : ι), Finset.{u2} (α i)), (p (fun (_x : ι) => EmptyCollection.emptyCollection.{u2} (Finset.{u2} (α _x)) (Finset.hasEmptyc.{u2} (α _x)))) -> (forall (g : forall (i : ι), Finset.{u2} (α i)) (i : ι) (x : α i), (forall (y : α i), (Membership.Mem.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.hasMem.{u2} (α i)) y (g i)) -> (LT.lt.{u2} (α i) (Preorder.toHasLt.{u2} (α i) (PartialOrder.toPreorder.{u2} (α i) (SemilatticeInf.toPartialOrder.{u2} (α i) (Lattice.toSemilatticeInf.{u2} (α i) (LinearOrder.toLattice.{u2} (α i) (_inst_4 i)))))) y x)) -> (p g) -> (p (Function.update.{succ u1, succ u2} ι (fun (i : ι) => Finset.{u2} (α i)) (fun (a : ι) (b : ι) => _inst_2 a b) g i (Insert.insert.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.hasInsert.{u2} (α i) (fun (a : α i) (b : α i) => _inst_3 i a b)) x (g i))))) -> (p f)
-but is expected to have type
-  forall {ι : Type.{u1}} {α : ι -> Type.{u2}} [_inst_1 : Finite.{succ u1} ι] [_inst_2 : DecidableEq.{succ u1} ι] [_inst_3 : forall (i : ι), DecidableEq.{succ u2} (α i)] [_inst_4 : forall (i : ι), LinearOrder.{u2} (α i)] {p : (forall (i : ι), Finset.{u2} (α i)) -> Prop} (f : forall (i : ι), Finset.{u2} (α i)), (p (fun (_x : ι) => EmptyCollection.emptyCollection.{u2} (Finset.{u2} (α _x)) (Finset.instEmptyCollectionFinset.{u2} (α _x)))) -> (forall (g : forall (i : ι), Finset.{u2} (α i)) (i : ι) (x : α i), (forall (y : α i), (Membership.mem.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.instMembershipFinset.{u2} (α i)) y (g i)) -> (LT.lt.{u2} (α i) (Preorder.toLT.{u2} (α i) (PartialOrder.toPreorder.{u2} (α i) (SemilatticeInf.toPartialOrder.{u2} (α i) (Lattice.toSemilatticeInf.{u2} (α i) (DistribLattice.toLattice.{u2} (α i) (instDistribLattice.{u2} (α i) (_inst_4 i))))))) y x)) -> (p g) -> (p (Function.update.{succ u1, succ u2} ι (fun (i : ι) => Finset.{u2} (α i)) (fun (a : ι) (b : ι) => _inst_2 a b) g i (Insert.insert.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.instInsertFinset.{u2} (α i) (fun (a : α i) (b : α i) => _inst_3 i a b)) x (g i))))) -> (p f)
-Case conversion may be inaccurate. Consider using '#align finset.induction_on_pi_max Finset.induction_on_pi_maxₓ'. -/
 /-- Given a predicate on functions `Π i, finset (α i)` defined on a finite type, it is true on all
 maps provided that it is true on `λ _, ∅` and for any function `g : Π i, finset (α i)`, an index
 `i : ι`, and an element`x : α i` that is strictly greater than all elements of `g i`, `p g` implies
@@ -110,12 +98,6 @@ theorem induction_on_pi_max [∀ i, LinearOrder (α i)] {p : (∀ i, Finset (α
     (fun i s hs => ⟨s.max' hs, s.max'_mem hs, fun y => s.lt_max'_of_mem_erase_max' _⟩) f h0 step
 #align finset.induction_on_pi_max Finset.induction_on_pi_max
 
-/- warning: finset.induction_on_pi_min -> Finset.induction_on_pi_min is a dubious translation:
-lean 3 declaration is
-  forall {ι : Type.{u1}} {α : ι -> Type.{u2}} [_inst_1 : Finite.{succ u1} ι] [_inst_2 : DecidableEq.{succ u1} ι] [_inst_3 : forall (i : ι), DecidableEq.{succ u2} (α i)] [_inst_4 : forall (i : ι), LinearOrder.{u2} (α i)] {p : (forall (i : ι), Finset.{u2} (α i)) -> Prop} (f : forall (i : ι), Finset.{u2} (α i)), (p (fun (_x : ι) => EmptyCollection.emptyCollection.{u2} (Finset.{u2} (α _x)) (Finset.hasEmptyc.{u2} (α _x)))) -> (forall (g : forall (i : ι), Finset.{u2} (α i)) (i : ι) (x : α i), (forall (y : α i), (Membership.Mem.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.hasMem.{u2} (α i)) y (g i)) -> (LT.lt.{u2} (α i) (Preorder.toHasLt.{u2} (α i) (PartialOrder.toPreorder.{u2} (α i) (SemilatticeInf.toPartialOrder.{u2} (α i) (Lattice.toSemilatticeInf.{u2} (α i) (LinearOrder.toLattice.{u2} (α i) (_inst_4 i)))))) x y)) -> (p g) -> (p (Function.update.{succ u1, succ u2} ι (fun (i : ι) => Finset.{u2} (α i)) (fun (a : ι) (b : ι) => _inst_2 a b) g i (Insert.insert.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.hasInsert.{u2} (α i) (fun (a : α i) (b : α i) => _inst_3 i a b)) x (g i))))) -> (p f)
-but is expected to have type
-  forall {ι : Type.{u1}} {α : ι -> Type.{u2}} [_inst_1 : Finite.{succ u1} ι] [_inst_2 : DecidableEq.{succ u1} ι] [_inst_3 : forall (i : ι), DecidableEq.{succ u2} (α i)] [_inst_4 : forall (i : ι), LinearOrder.{u2} (α i)] {p : (forall (i : ι), Finset.{u2} (α i)) -> Prop} (f : forall (i : ι), Finset.{u2} (α i)), (p (fun (_x : ι) => EmptyCollection.emptyCollection.{u2} (Finset.{u2} (α _x)) (Finset.instEmptyCollectionFinset.{u2} (α _x)))) -> (forall (g : forall (i : ι), Finset.{u2} (α i)) (i : ι) (x : α i), (forall (y : α i), (Membership.mem.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.instMembershipFinset.{u2} (α i)) y (g i)) -> (LT.lt.{u2} (α i) (Preorder.toLT.{u2} (α i) (PartialOrder.toPreorder.{u2} (α i) (SemilatticeInf.toPartialOrder.{u2} (α i) (Lattice.toSemilatticeInf.{u2} (α i) (DistribLattice.toLattice.{u2} (α i) (instDistribLattice.{u2} (α i) (_inst_4 i))))))) x y)) -> (p g) -> (p (Function.update.{succ u1, succ u2} ι (fun (i : ι) => Finset.{u2} (α i)) (fun (a : ι) (b : ι) => _inst_2 a b) g i (Insert.insert.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.instInsertFinset.{u2} (α i) (fun (a : α i) (b : α i) => _inst_3 i a b)) x (g i))))) -> (p f)
-Case conversion may be inaccurate. Consider using '#align finset.induction_on_pi_min Finset.induction_on_pi_minₓ'. -/
 /-- Given a predicate on functions `Π i, finset (α i)` defined on a finite type, it is true on all
 maps provided that it is true on `λ _, ∅` and for any function `g : Π i, finset (α i)`, an index
 `i : ι`, and an element`x : α i` that is strictly less than all elements of `g i`, `p g` implies
Diff
@@ -56,19 +56,14 @@ theorem induction_on_pi_of_choice (r : ∀ i, α i → Finset (α i) → Prop)
   cases nonempty_fintype ι
   induction' hs : univ.sigma f using Finset.strongInductionOn with s ihs generalizing f; subst s
   cases' eq_empty_or_nonempty (univ.sigma f) with he hne
-  · convert h0
-    simpa [funext_iff] using he
+  · convert h0; simpa [funext_iff] using he
   · rcases sigma_nonempty.1 hne with ⟨i, -, hi⟩
     rcases H_ex i (f i) hi with ⟨x, x_mem, hr⟩
-    set g := update f i ((f i).eraseₓ x) with hg
-    clear_value g
-    have hx' : x ∉ g i := by
-      rw [hg, update_same]
-      apply not_mem_erase
+    set g := update f i ((f i).eraseₓ x) with hg; clear_value g
+    have hx' : x ∉ g i := by rw [hg, update_same]; apply not_mem_erase
     obtain rfl : f = update g i (insert x (g i)) := by
       rw [hg, update_idem, update_same, insert_erase x_mem, update_eq_self]
-    clear hg
-    rw [update_same, erase_insert hx'] at hr
+    clear hg; rw [update_same, erase_insert hx'] at hr
     refine' step _ _ _ hr (ihs (univ.sigma g) _ _ rfl)
     rw [ssubset_iff_of_subset (sigma_mono (subset.refl _) _)]
     exacts[⟨⟨i, x⟩, mem_sigma.2 ⟨mem_univ _, by simp⟩, by simp [hx']⟩,
Diff
@@ -92,7 +92,12 @@ theorem induction_on_pi {p : (∀ i, Finset (α i)) → Prop} (f : ∀ i, Finset
 #align finset.induction_on_pi Finset.induction_on_pi
 -/
 
-#print Finset.induction_on_pi_max /-
+/- warning: finset.induction_on_pi_max -> Finset.induction_on_pi_max is a dubious translation:
+lean 3 declaration is
+  forall {ι : Type.{u1}} {α : ι -> Type.{u2}} [_inst_1 : Finite.{succ u1} ι] [_inst_2 : DecidableEq.{succ u1} ι] [_inst_3 : forall (i : ι), DecidableEq.{succ u2} (α i)] [_inst_4 : forall (i : ι), LinearOrder.{u2} (α i)] {p : (forall (i : ι), Finset.{u2} (α i)) -> Prop} (f : forall (i : ι), Finset.{u2} (α i)), (p (fun (_x : ι) => EmptyCollection.emptyCollection.{u2} (Finset.{u2} (α _x)) (Finset.hasEmptyc.{u2} (α _x)))) -> (forall (g : forall (i : ι), Finset.{u2} (α i)) (i : ι) (x : α i), (forall (y : α i), (Membership.Mem.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.hasMem.{u2} (α i)) y (g i)) -> (LT.lt.{u2} (α i) (Preorder.toHasLt.{u2} (α i) (PartialOrder.toPreorder.{u2} (α i) (SemilatticeInf.toPartialOrder.{u2} (α i) (Lattice.toSemilatticeInf.{u2} (α i) (LinearOrder.toLattice.{u2} (α i) (_inst_4 i)))))) y x)) -> (p g) -> (p (Function.update.{succ u1, succ u2} ι (fun (i : ι) => Finset.{u2} (α i)) (fun (a : ι) (b : ι) => _inst_2 a b) g i (Insert.insert.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.hasInsert.{u2} (α i) (fun (a : α i) (b : α i) => _inst_3 i a b)) x (g i))))) -> (p f)
+but is expected to have type
+  forall {ι : Type.{u1}} {α : ι -> Type.{u2}} [_inst_1 : Finite.{succ u1} ι] [_inst_2 : DecidableEq.{succ u1} ι] [_inst_3 : forall (i : ι), DecidableEq.{succ u2} (α i)] [_inst_4 : forall (i : ι), LinearOrder.{u2} (α i)] {p : (forall (i : ι), Finset.{u2} (α i)) -> Prop} (f : forall (i : ι), Finset.{u2} (α i)), (p (fun (_x : ι) => EmptyCollection.emptyCollection.{u2} (Finset.{u2} (α _x)) (Finset.instEmptyCollectionFinset.{u2} (α _x)))) -> (forall (g : forall (i : ι), Finset.{u2} (α i)) (i : ι) (x : α i), (forall (y : α i), (Membership.mem.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.instMembershipFinset.{u2} (α i)) y (g i)) -> (LT.lt.{u2} (α i) (Preorder.toLT.{u2} (α i) (PartialOrder.toPreorder.{u2} (α i) (SemilatticeInf.toPartialOrder.{u2} (α i) (Lattice.toSemilatticeInf.{u2} (α i) (DistribLattice.toLattice.{u2} (α i) (instDistribLattice.{u2} (α i) (_inst_4 i))))))) y x)) -> (p g) -> (p (Function.update.{succ u1, succ u2} ι (fun (i : ι) => Finset.{u2} (α i)) (fun (a : ι) (b : ι) => _inst_2 a b) g i (Insert.insert.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.instInsertFinset.{u2} (α i) (fun (a : α i) (b : α i) => _inst_3 i a b)) x (g i))))) -> (p f)
+Case conversion may be inaccurate. Consider using '#align finset.induction_on_pi_max Finset.induction_on_pi_maxₓ'. -/
 /-- Given a predicate on functions `Π i, finset (α i)` defined on a finite type, it is true on all
 maps provided that it is true on `λ _, ∅` and for any function `g : Π i, finset (α i)`, an index
 `i : ι`, and an element`x : α i` that is strictly greater than all elements of `g i`, `p g` implies
@@ -109,9 +114,13 @@ theorem induction_on_pi_max [∀ i, LinearOrder (α i)] {p : (∀ i, Finset (α
   induction_on_pi_of_choice (fun i x s => ∀ y ∈ s, y < x)
     (fun i s hs => ⟨s.max' hs, s.max'_mem hs, fun y => s.lt_max'_of_mem_erase_max' _⟩) f h0 step
 #align finset.induction_on_pi_max Finset.induction_on_pi_max
--/
 
-#print Finset.induction_on_pi_min /-
+/- warning: finset.induction_on_pi_min -> Finset.induction_on_pi_min is a dubious translation:
+lean 3 declaration is
+  forall {ι : Type.{u1}} {α : ι -> Type.{u2}} [_inst_1 : Finite.{succ u1} ι] [_inst_2 : DecidableEq.{succ u1} ι] [_inst_3 : forall (i : ι), DecidableEq.{succ u2} (α i)] [_inst_4 : forall (i : ι), LinearOrder.{u2} (α i)] {p : (forall (i : ι), Finset.{u2} (α i)) -> Prop} (f : forall (i : ι), Finset.{u2} (α i)), (p (fun (_x : ι) => EmptyCollection.emptyCollection.{u2} (Finset.{u2} (α _x)) (Finset.hasEmptyc.{u2} (α _x)))) -> (forall (g : forall (i : ι), Finset.{u2} (α i)) (i : ι) (x : α i), (forall (y : α i), (Membership.Mem.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.hasMem.{u2} (α i)) y (g i)) -> (LT.lt.{u2} (α i) (Preorder.toHasLt.{u2} (α i) (PartialOrder.toPreorder.{u2} (α i) (SemilatticeInf.toPartialOrder.{u2} (α i) (Lattice.toSemilatticeInf.{u2} (α i) (LinearOrder.toLattice.{u2} (α i) (_inst_4 i)))))) x y)) -> (p g) -> (p (Function.update.{succ u1, succ u2} ι (fun (i : ι) => Finset.{u2} (α i)) (fun (a : ι) (b : ι) => _inst_2 a b) g i (Insert.insert.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.hasInsert.{u2} (α i) (fun (a : α i) (b : α i) => _inst_3 i a b)) x (g i))))) -> (p f)
+but is expected to have type
+  forall {ι : Type.{u1}} {α : ι -> Type.{u2}} [_inst_1 : Finite.{succ u1} ι] [_inst_2 : DecidableEq.{succ u1} ι] [_inst_3 : forall (i : ι), DecidableEq.{succ u2} (α i)] [_inst_4 : forall (i : ι), LinearOrder.{u2} (α i)] {p : (forall (i : ι), Finset.{u2} (α i)) -> Prop} (f : forall (i : ι), Finset.{u2} (α i)), (p (fun (_x : ι) => EmptyCollection.emptyCollection.{u2} (Finset.{u2} (α _x)) (Finset.instEmptyCollectionFinset.{u2} (α _x)))) -> (forall (g : forall (i : ι), Finset.{u2} (α i)) (i : ι) (x : α i), (forall (y : α i), (Membership.mem.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.instMembershipFinset.{u2} (α i)) y (g i)) -> (LT.lt.{u2} (α i) (Preorder.toLT.{u2} (α i) (PartialOrder.toPreorder.{u2} (α i) (SemilatticeInf.toPartialOrder.{u2} (α i) (Lattice.toSemilatticeInf.{u2} (α i) (DistribLattice.toLattice.{u2} (α i) (instDistribLattice.{u2} (α i) (_inst_4 i))))))) x y)) -> (p g) -> (p (Function.update.{succ u1, succ u2} ι (fun (i : ι) => Finset.{u2} (α i)) (fun (a : ι) (b : ι) => _inst_2 a b) g i (Insert.insert.{u2, u2} (α i) (Finset.{u2} (α i)) (Finset.instInsertFinset.{u2} (α i) (fun (a : α i) (b : α i) => _inst_3 i a b)) x (g i))))) -> (p f)
+Case conversion may be inaccurate. Consider using '#align finset.induction_on_pi_min Finset.induction_on_pi_minₓ'. -/
 /-- Given a predicate on functions `Π i, finset (α i)` defined on a finite type, it is true on all
 maps provided that it is true on `λ _, ∅` and for any function `g : Π i, finset (α i)`, an index
 `i : ι`, and an element`x : α i` that is strictly less than all elements of `g i`, `p g` implies
@@ -127,7 +136,6 @@ theorem induction_on_pi_min [∀ i, LinearOrder (α i)] {p : (∀ i, Finset (α
     p f :=
   @induction_on_pi_max ι (fun i => (α i)ᵒᵈ) _ _ _ _ _ _ h0 step
 #align finset.induction_on_pi_min Finset.induction_on_pi_min
--/
 
 end Finset
 

Changes in mathlib4

mathlib3
mathlib4
chore(Data/Finset/PiInduction): remove porting note about clear_value (#12100)

This tactic now exists.

Diff
@@ -49,8 +49,7 @@ theorem induction_on_pi_of_choice (r : ∀ i, α i → Finset (α i) → Prop)
   · rcases sigma_nonempty.1 hne with ⟨i, -, hi⟩
     rcases H_ex i (f i) hi with ⟨x, x_mem, hr⟩
     set g := update f i ((f i).erase x) with hg
--- Porting note: this tactic does not exist yet
---  clear_value g
+    clear_value g
     have hx' : x ∉ g i := by
       rw [hg, update_same]
       apply not_mem_erase
chore: reduce imports (#9830)

This uses the improved shake script from #9772 to reduce imports across mathlib. The corresponding noshake.json file has been added to #9772.

Co-authored-by: Mario Carneiro <di.gama@gmail.com>

Diff
@@ -3,8 +3,8 @@ Copyright (c) 2021 Yury Kudryashov. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Yury Kudryashov
 -/
-import Mathlib.Data.Fintype.Lattice
 import Mathlib.Data.Finset.Sigma
+import Mathlib.Data.Fintype.Card
 
 #align_import data.finset.pi_induction from "leanprover-community/mathlib"@"f93c11933efbc3c2f0299e47b8ff83e9b539cbf6"
 
chore(*): use ∃ x ∈ s, _ instead of ∃ (x) (_ : x ∈ s), _ (#9215)

Follow-up #9184

Diff
@@ -71,9 +71,7 @@ maps provided that it is true on `fun _ ↦ ∅` and for any function `g : ∀ i
 See also `Finset.induction_on_pi_max` and `Finset.induction_on_pi_min` for specialized versions
 that require `∀ i, LinearOrder (α i)`.  -/
 theorem induction_on_pi {p : (∀ i, Finset (α i)) → Prop} (f : ∀ i, Finset (α i)) (h0 : p fun _ ↦ ∅)
-    (step :
-      ∀ (g : ∀ i, Finset (α i)) (i : ι) (x : α i) (_ : x ∉ g i),
-        p g → p (update g i (insert x (g i)))) :
+    (step : ∀ (g : ∀ i, Finset (α i)) (i : ι), ∀ x ∉ g i, p g → p (update g i (insert x (g i)))) :
     p f :=
   induction_on_pi_of_choice (fun _ x s ↦ x ∉ s) (fun _ s ⟨x, hx⟩ ↦ ⟨x, hx, not_mem_erase x s⟩) f
     h0 step
chore(*): use ∃ x ∈ s, _ instead of ∃ (x) (_ : x ∈ s), _ (#9184)

Search for [∀∃].*(_ and manually replace some occurrences with more readable versions. In case of , the new expressions are defeq to the old ones. In case of , they differ by exists_prop.

In some rare cases, golf proofs that needed fixing.

Diff
@@ -35,7 +35,7 @@ namespace Finset
 
 /-- General theorem for `Finset.induction_on_pi`-style induction principles. -/
 theorem induction_on_pi_of_choice (r : ∀ i, α i → Finset (α i) → Prop)
-    (H_ex : ∀ (i) (s : Finset (α i)) (_ : s.Nonempty), ∃ x ∈ s, r i x (s.erase x))
+    (H_ex : ∀ (i) (s : Finset (α i)), s.Nonempty → ∃ x ∈ s, r i x (s.erase x))
     {p : (∀ i, Finset (α i)) → Prop} (f : ∀ i, Finset (α i)) (h0 : p fun _ ↦ ∅)
     (step :
       ∀ (g : ∀ i, Finset (α i)) (i : ι) (x : α i),
chore: remove uses of cases' (#9171)

I literally went through and regex'd some uses of cases', replacing them with rcases; this is meant to be a low effort PR as I hope that tools can do this in the future.

rcases is an easier replacement than cases, though with better tools we could in future do a second pass converting simple rcases added here (and existing ones) to cases.

Diff
@@ -43,7 +43,7 @@ theorem induction_on_pi_of_choice (r : ∀ i, α i → Finset (α i) → Prop)
     p f := by
   cases nonempty_fintype ι
   induction' hs : univ.sigma f using Finset.strongInductionOn with s ihs generalizing f; subst s
-  cases' eq_empty_or_nonempty (univ.sigma f) with he hne
+  rcases eq_empty_or_nonempty (univ.sigma f) with he | hne
   · convert h0 using 1
     simpa [funext_iff] using he
   · rcases sigma_nonempty.1 hne with ⟨i, -, hi⟩
chore: banish Type _ and Sort _ (#6499)

We remove all possible occurences of Type _ and Sort _ in favor of Type* and Sort*.

This has nice performance benefits.

Diff
@@ -29,7 +29,7 @@ finite set, finite type, induction, function
 
 open Function
 
-variable {ι : Type _} {α : ι → Type _} [Finite ι] [DecidableEq ι] [∀ i, DecidableEq (α i)]
+variable {ι : Type*} {α : ι → Type*} [Finite ι] [DecidableEq ι] [∀ i, DecidableEq (α i)]
 
 namespace Finset
 
chore: script to replace headers with #align_import statements (#5979)

Open in Gitpod

Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -2,15 +2,12 @@
 Copyright (c) 2021 Yury Kudryashov. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Yury Kudryashov
-
-! This file was ported from Lean 3 source module data.finset.pi_induction
-! leanprover-community/mathlib commit f93c11933efbc3c2f0299e47b8ff83e9b539cbf6
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Data.Fintype.Lattice
 import Mathlib.Data.Finset.Sigma
 
+#align_import data.finset.pi_induction from "leanprover-community/mathlib"@"f93c11933efbc3c2f0299e47b8ff83e9b539cbf6"
+
 /-!
 # Induction principles for `∀ i, Finset (α i)`
 
feat: tactic congr! and improvement to convert (#2566)

This introduces a tactic congr! that is an analogue to mathlib 3's congr'. It is a more insistent version of congr that makes use of more congruence lemmas (including user congruence lemmas), propext, funext, and Subsingleton instances. It also has a feature to lift reflexive relations to equalities. Along with funext, the tactic does intros, allowing congr! to get access to function bodies; the introduced variables can be named using rename_i if needed.

This also modifies convert to use congr! rather than congr, which makes it work more like the mathlib3 version of the tactic.

Diff
@@ -47,7 +47,7 @@ theorem induction_on_pi_of_choice (r : ∀ i, α i → Finset (α i) → Prop)
   cases nonempty_fintype ι
   induction' hs : univ.sigma f using Finset.strongInductionOn with s ihs generalizing f; subst s
   cases' eq_empty_or_nonempty (univ.sigma f) with he hne
-  · convert h0
+  · convert h0 using 1
     simpa [funext_iff] using he
   · rcases sigma_nonempty.1 hne with ⟨i, -, hi⟩
     rcases H_ex i (f i) hi with ⟨x, x_mem, hr⟩
@@ -118,4 +118,3 @@ theorem induction_on_pi_min [∀ i, LinearOrder (α i)] {p : (∀ i, Finset (α
 #align finset.induction_on_pi_min Finset.induction_on_pi_min
 
 end Finset
-
feat : port Data.Finset.PiInduction (#1859)

Dependencies 2 + 181

182 files ported (98.9%)
82388 lines ported (99.8%)
Show graph

The unported dependencies are