l3lab/ntp-mathlib huggingface dataset:
/-- For any `a : α`, the fiber over `some a` is the set of permutations
    where `a` is the only possible fixed point. -/
theorem RemoveNone.fiber_some (a : α) :
    RemoveNone.fiber (some a) = { f : Perm α | fixedPoints f ⊆ {a} } := by
  ext f
  constructor
  · rw [RemoveNone.mem_fiber]
    rintro ⟨F, F_derangement, F_none, rfl⟩ x x_fixed
    rw [mem_fixedPoints_iff] at x_fixed
    apply_fun some at x_fixed
    cases' Fx : F (some x) with y
    · rwa [removeNone_none F Fx, F_none, Option.some_inj, eq_comm] at x_fixed
    · exfalso
      rw [removeNone_some F ⟨y, Fx⟩] at x_fixed
      exact F_derangement _ x_fixed
  · intro h_opfp
    use Equiv.Perm.decomposeOption.symm (some a, f)
    constructor
    · intro x
      apply_fun fun x => Equiv.swap none (some a) x
      simp only [Perm.decomposeOption_symm_apply, swap_apply_self, Perm.coe_mul]
      cases' x with x
      · simp
      simp only [comp, optionCongr_apply, Option.map_some', swap_apply_self]
      by_cases x_vs_a : x = a
      · rw [x_vs_a, swap_apply_right]
        apply Option.some_ne_none
      have ne_1 : some x ≠ none := Option.some_ne_none _
      have ne_2 : some x ≠ some a := (Option.some_injective α).ne_iff.mpr x_vs_a
      rw [swap_apply_of_ne_of_ne ne_1 ne_2, (Option.some_injective α).ne_iff]
      intro contra
      

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
a : α
f : Perm α
h_opfp : f ∈ {f | fixedPoints ⇑f ⊆ {a}}
x : α
x_vs_a : ¬x = a
ne_1 : some x ≠ none
ne_2 : some x ≠ some a
contra : f x = x
⊢ False

Next tactic:
exact x_vs_a (h_opfp contra)
/-- For any `a : α`, the fiber over `some a` is the set of permutations
    where `a` is the only possible fixed point. -/
theorem RemoveNone.fiber_some (a : α) :
    RemoveNone.fiber (some a) = { f : Perm α | fixedPoints f ⊆ {a} } := by
  ext f
  constructor
  · rw [RemoveNone.mem_fiber]
    rintro ⟨F, F_derangement, F_none, rfl⟩ x x_fixed
    rw [mem_fixedPoints_iff] at x_fixed
    apply_fun some at x_fixed
    cases' Fx : F (some x) with y
    · rwa [removeNone_none F Fx, F_none, Option.some_inj, eq_comm] at x_fixed
    · exfalso
      rw [removeNone_some F ⟨y, Fx⟩] at x_fixed
      exact F_derangement _ x_fixed
  · intro h_opfp
    use Equiv.Perm.decomposeOption.symm (some a, f)
    constructor
    · intro x
      apply_fun fun x => Equiv.swap none (some a) x
      simp only [Perm.decomposeOption_symm_apply, swap_apply_self, Perm.coe_mul]
      cases' x with x
      · simp
      simp only [comp, optionCongr_apply, Option.map_some', swap_apply_self]
      by_cases x_vs_a : x = a
      · rw [x_vs_a, swap_apply_right]
        apply Option.some_ne_none
      have ne_1 : some x ≠ none := Option.some_ne_none _
      have ne_2 : some x ≠ some a := (Option.some_injective α).ne_iff.mpr x_vs_a
      rw [swap_apply_of_ne_of_ne ne_1 ne_2, (Option.some_injective α).ne_iff]
      intro contra
      exact x_vs_a (h_opfp contra)
    · 

Proof state:
case h.right
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
a : α
f : Perm α
h_opfp : f ∈ {f | fixedPoints ⇑f ⊆ {a}}
⊢ Perm.decomposeOption (Perm.decomposeOption.symm (some a, f)) = (some a, f)

Next tactic:
rw [apply_symm_apply]
/-- The set of derangements on `Option α` is equivalent to the union over `a : α`
    of "permutations with `a` the only possible fixed point". -/
def derangementsOptionEquivSigmaAtMostOneFixedPoint :
    derangements (Option α) ≃ Σa : α, { f : Perm α | fixedPoints f ⊆ {a} } := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
⊢ ↑(derangements (Option α)) ≃ (a : α) × ↑{f | fixedPoints ⇑f ⊆ {a}}

Next tactic:
have fiber_none_is_false : Equiv.RemoveNone.fiber (@none α) → False := by
    rw [Equiv.RemoveNone.fiber_none]
    exact IsEmpty.false
/-- The set of derangements on `Option α` is equivalent to the union over `a : α`
    of "permutations with `a` the only possible fixed point". -/
def derangementsOptionEquivSigmaAtMostOneFixedPoint :
    derangements (Option α) ≃ Σa : α, { f : Perm α | fixedPoints f ⊆ {a} } := by
  have fiber_none_is_false : Equiv.RemoveNone.fiber (@none α) → False := by
    

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
⊢ ↑(Equiv.RemoveNone.fiber none) → False

Next tactic:
rw [Equiv.RemoveNone.fiber_none]
/-- The set of derangements on `Option α` is equivalent to the union over `a : α`
    of "permutations with `a` the only possible fixed point". -/
def derangementsOptionEquivSigmaAtMostOneFixedPoint :
    derangements (Option α) ≃ Σa : α, { f : Perm α | fixedPoints f ⊆ {a} } := by
  have fiber_none_is_false : Equiv.RemoveNone.fiber (@none α) → False := by
    rw [Equiv.RemoveNone.fiber_none]
    

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
⊢ ↑∅ → False

Next tactic:
exact IsEmpty.false
/-- The set of derangements on `Option α` is equivalent to the union over `a : α`
    of "permutations with `a` the only possible fixed point". -/
def derangementsOptionEquivSigmaAtMostOneFixedPoint :
    derangements (Option α) ≃ Σa : α, { f : Perm α | fixedPoints f ⊆ {a} } := by
  have fiber_none_is_false : Equiv.RemoveNone.fiber (@none α) → False := by
    rw [Equiv.RemoveNone.fiber_none]
    exact IsEmpty.false
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
fiber_none_is_false : ↑(Equiv.RemoveNone.fiber none) → False
⊢ ↑(derangements (Option α)) ≃ (a : α) × ↑{f | fixedPoints ⇑f ⊆ {a}}

Next tactic:
calc
    derangements (Option α) ≃ Equiv.Perm.decomposeOption '' derangements (Option α) :=
      Equiv.image _ _
    _ ≃ Σa : Option α, ↥(Equiv.RemoveNone.fiber a) := setProdEquivSigma _
    _ ≃ Σa : α, ↥(Equiv.RemoveNone.fiber (some a)) :=
      sigmaOptionEquivOfSome _ fiber_none_is_false
    _ ≃ Σa : α, { f : Perm α | fixedPoints f ⊆ {a} } := by
      simp_rw [Equiv.RemoveNone.fiber_some]
      rfl
/-- The set of derangements on `Option α` is equivalent to the union over `a : α`
    of "permutations with `a` the only possible fixed point". -/
def derangementsOptionEquivSigmaAtMostOneFixedPoint :
    derangements (Option α) ≃ Σa : α, { f : Perm α | fixedPoints f ⊆ {a} } := by
  have fiber_none_is_false : Equiv.RemoveNone.fiber (@none α) → False := by
    rw [Equiv.RemoveNone.fiber_none]
    exact IsEmpty.false
  calc
    derangements (Option α) ≃ Equiv.Perm.decomposeOption '' derangements (Option α) :=
      Equiv.image _ _
    _ ≃ Σa : Option α, ↥(Equiv.RemoveNone.fiber a) := setProdEquivSigma _
    _ ≃ Σa : α, ↥(Equiv.RemoveNone.fiber (some a)) :=
      sigmaOptionEquivOfSome _ fiber_none_is_false
    _ ≃ Σa : α, { f : Perm α | fixedPoints f ⊆ {a} } := by
      

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
fiber_none_is_false : ↑(Equiv.RemoveNone.fiber none) → False
⊢ (a : α) × ↑(Equiv.RemoveNone.fiber (some a)) ≃ (a : α) × ↑{f | fixedPoints ⇑f ⊆ {a}}

Next tactic:
simp_rw [Equiv.RemoveNone.fiber_some]
/-- The set of derangements on `Option α` is equivalent to the union over `a : α`
    of "permutations with `a` the only possible fixed point". -/
def derangementsOptionEquivSigmaAtMostOneFixedPoint :
    derangements (Option α) ≃ Σa : α, { f : Perm α | fixedPoints f ⊆ {a} } := by
  have fiber_none_is_false : Equiv.RemoveNone.fiber (@none α) → False := by
    rw [Equiv.RemoveNone.fiber_none]
    exact IsEmpty.false
  calc
    derangements (Option α) ≃ Equiv.Perm.decomposeOption '' derangements (Option α) :=
      Equiv.image _ _
    _ ≃ Σa : Option α, ↥(Equiv.RemoveNone.fiber a) := setProdEquivSigma _
    _ ≃ Σa : α, ↥(Equiv.RemoveNone.fiber (some a)) :=
      sigmaOptionEquivOfSome _ fiber_none_is_false
    _ ≃ Σa : α, { f : Perm α | fixedPoints f ⊆ {a} } := by
      simp_rw [Equiv.RemoveNone.fiber_some]
      

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
fiber_none_is_false : ↑(Equiv.RemoveNone.fiber none) → False
⊢ (a : α) × ↑{f | fixedPoints ⇑f ⊆ {a}} ≃ (a : α) × ↑{f | fixedPoints ⇑f ⊆ {a}}

Next tactic:
rfl
theorem Int.isCoprime_iff_gcd_eq_one {m n : ℤ} : IsCoprime m n ↔ Int.gcd m n = 1 := by
  

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
m n : ℤ
⊢ IsCoprime m n ↔ gcd m n = 1

Next tactic:
constructor
theorem Int.isCoprime_iff_gcd_eq_one {m n : ℤ} : IsCoprime m n ↔ Int.gcd m n = 1 := by
  constructor
  · 

Proof state:
case mp
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
m n : ℤ
⊢ IsCoprime m n → gcd m n = 1

Next tactic:
rintro ⟨a, b, h⟩
theorem Int.isCoprime_iff_gcd_eq_one {m n : ℤ} : IsCoprime m n ↔ Int.gcd m n = 1 := by
  constructor
  · rintro ⟨a, b, h⟩
    

Proof state:
case mp.intro.intro
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
m n a b : ℤ
h : a * m + b * n = 1
⊢ gcd m n = 1

Next tactic:
have : 1 = m * a + n * b := by rwa [mul_comm m, mul_comm n, eq_comm]
theorem Int.isCoprime_iff_gcd_eq_one {m n : ℤ} : IsCoprime m n ↔ Int.gcd m n = 1 := by
  constructor
  · rintro ⟨a, b, h⟩
    have : 1 = m * a + n * b := by 

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
m n a b : ℤ
h : a * m + b * n = 1
⊢ 1 = m * a + n * b

Next tactic:
rwa [mul_comm m, mul_comm n, eq_comm]
theorem Int.isCoprime_iff_gcd_eq_one {m n : ℤ} : IsCoprime m n ↔ Int.gcd m n = 1 := by
  constructor
  · rintro ⟨a, b, h⟩
    have : 1 = m * a + n * b := by rwa [mul_comm m, mul_comm n, eq_comm]
    

Proof state:
case mp.intro.intro
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
m n a b : ℤ
h : a * m + b * n = 1
this : 1 = m * a + n * b
⊢ gcd m n = 1

Next tactic:
exact Nat.dvd_one.mp (Int.gcd_dvd_iff.mpr ⟨a, b, this⟩)
theorem Int.isCoprime_iff_gcd_eq_one {m n : ℤ} : IsCoprime m n ↔ Int.gcd m n = 1 := by
  constructor
  · rintro ⟨a, b, h⟩
    have : 1 = m * a + n * b := by rwa [mul_comm m, mul_comm n, eq_comm]
    exact Nat.dvd_one.mp (Int.gcd_dvd_iff.mpr ⟨a, b, this⟩)
  · 

Proof state:
case mpr
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
m n : ℤ
⊢ gcd m n = 1 → IsCoprime m n

Next tactic:
rw [← Int.ofNat_inj, IsCoprime, Int.gcd_eq_gcd_ab, mul_comm m, mul_comm n, Nat.cast_one]
theorem Int.isCoprime_iff_gcd_eq_one {m n : ℤ} : IsCoprime m n ↔ Int.gcd m n = 1 := by
  constructor
  · rintro ⟨a, b, h⟩
    have : 1 = m * a + n * b := by rwa [mul_comm m, mul_comm n, eq_comm]
    exact Nat.dvd_one.mp (Int.gcd_dvd_iff.mpr ⟨a, b, this⟩)
  · rw [← Int.ofNat_inj, IsCoprime, Int.gcd_eq_gcd_ab, mul_comm m, mul_comm n, Nat.cast_one]
    

Proof state:
case mpr
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
m n : ℤ
⊢ gcdA m n * m + gcdB m n * n = 1 → ∃ a b, a * m + b * n = 1

Next tactic:
intro h
theorem Int.isCoprime_iff_gcd_eq_one {m n : ℤ} : IsCoprime m n ↔ Int.gcd m n = 1 := by
  constructor
  · rintro ⟨a, b, h⟩
    have : 1 = m * a + n * b := by rwa [mul_comm m, mul_comm n, eq_comm]
    exact Nat.dvd_one.mp (Int.gcd_dvd_iff.mpr ⟨a, b, this⟩)
  · rw [← Int.ofNat_inj, IsCoprime, Int.gcd_eq_gcd_ab, mul_comm m, mul_comm n, Nat.cast_one]
    intro h
    

Proof state:
case mpr
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
m n : ℤ
h : gcdA m n * m + gcdB m n * n = 1
⊢ ∃ a b, a * m + b * n = 1

Next tactic:
exact ⟨_, _, h⟩
theorem Nat.isCoprime_iff_coprime {m n : ℕ} : IsCoprime (m : ℤ) n ↔ Nat.Coprime m n := by
  

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
m n : ℕ
⊢ IsCoprime ↑m ↑n ↔ Coprime m n

Next tactic:
rw [Int.isCoprime_iff_gcd_eq_one, Int.coe_nat_gcd]
theorem Nat.Coprime.cast {R : Type*} [CommRing R] {a b : ℕ} (h : Nat.Coprime a b) :
    IsCoprime (a : R) (b : R) := by
  

Proof state:
R✝ : Type u
I : Type v
inst✝¹ : CommSemiring R✝
x y z : R✝
s : I → R✝
t : Finset I
R : Type u_1
inst✝ : CommRing R
a b : ℕ
h : Coprime a b
⊢ IsCoprime ↑a ↑b

Next tactic:
rw [← isCoprime_iff_coprime] at h
theorem Nat.Coprime.cast {R : Type*} [CommRing R] {a b : ℕ} (h : Nat.Coprime a b) :
    IsCoprime (a : R) (b : R) := by
  rw [← isCoprime_iff_coprime] at h
  

Proof state:
R✝ : Type u
I : Type v
inst✝¹ : CommSemiring R✝
x y z : R✝
s : I → R✝
t : Finset I
R : Type u_1
inst✝ : CommRing R
a b : ℕ
h : IsCoprime ↑a ↑b
⊢ IsCoprime ↑a ↑b

Next tactic:
rw [← Int.cast_ofNat a, ← Int.cast_ofNat b]
theorem Nat.Coprime.cast {R : Type*} [CommRing R] {a b : ℕ} (h : Nat.Coprime a b) :
    IsCoprime (a : R) (b : R) := by
  rw [← isCoprime_iff_coprime] at h
  rw [← Int.cast_ofNat a, ← Int.cast_ofNat b]
  

Proof state:
R✝ : Type u
I : Type v
inst✝¹ : CommSemiring R✝
x y z : R✝
s : I → R✝
t : Finset I
R : Type u_1
inst✝ : CommRing R
a b : ℕ
h : IsCoprime ↑a ↑b
⊢ IsCoprime ↑↑a ↑↑b

Next tactic:
exact IsCoprime.intCast h
theorem ne_zero_or_ne_zero_of_nat_coprime {A : Type u} [CommRing A] [Nontrivial A] {a b : ℕ}
    (h : Nat.Coprime a b) : (a : A) ≠ 0 ∨ (b : A) ≠ 0 :=
  IsCoprime.ne_zero_or_ne_zero (R := A) <| by
    

Proof state:
R : Type u
I : Type v
inst✝² : CommSemiring R
x y z : R
s : I → R
t : Finset I
A : Type u
inst✝¹ : CommRing A
inst✝ : Nontrivial A
a b : ℕ
h : Nat.Coprime a b
⊢ IsCoprime ↑a ↑b

Next tactic:
simpa only [map_natCast] using IsCoprime.map (Nat.Coprime.isCoprime h) (Int.castRingHom A)
theorem IsCoprime.prod_left : (∀ i ∈ t, IsCoprime (s i) x) → IsCoprime (∏ i in t, s i) x :=
  Finset.induction_on t (fun _ ↦ isCoprime_one_left) fun b t hbt ih H ↦ by
    

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t✝ : Finset I
b : I
t : Finset I
hbt : b ∉ t
ih : (∀ i ∈ t, IsCoprime (s i) x) → IsCoprime (∏ i in t, s i) x
H : ∀ i ∈ insert b t, IsCoprime (s i) x
⊢ IsCoprime (∏ i in insert b t, s i) x

Next tactic:
rw [Finset.prod_insert hbt]
theorem IsCoprime.prod_left : (∀ i ∈ t, IsCoprime (s i) x) → IsCoprime (∏ i in t, s i) x :=
  Finset.induction_on t (fun _ ↦ isCoprime_one_left) fun b t hbt ih H ↦ by
    rw [Finset.prod_insert hbt]
    

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t✝ : Finset I
b : I
t : Finset I
hbt : b ∉ t
ih : (∀ i ∈ t, IsCoprime (s i) x) → IsCoprime (∏ i in t, s i) x
H : ∀ i ∈ insert b t, IsCoprime (s i) x
⊢ IsCoprime (s b * ∏ x in t, s x) x

Next tactic:
rw [Finset.forall_mem_insert] at H
theorem IsCoprime.prod_left : (∀ i ∈ t, IsCoprime (s i) x) → IsCoprime (∏ i in t, s i) x :=
  Finset.induction_on t (fun _ ↦ isCoprime_one_left) fun b t hbt ih H ↦ by
    rw [Finset.prod_insert hbt]
    rw [Finset.forall_mem_insert] at H
    

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t✝ : Finset I
b : I
t : Finset I
hbt : b ∉ t
ih : (∀ i ∈ t, IsCoprime (s i) x) → IsCoprime (∏ i in t, s i) x
H : IsCoprime (s b) x ∧ ∀ x_1 ∈ t, IsCoprime (s x_1) x
⊢ IsCoprime (s b * ∏ x in t, s x) x

Next tactic:
exact H.1.mul_left (ih H.2)
theorem IsCoprime.prod_right : (∀ i ∈ t, IsCoprime x (s i)) → IsCoprime x (∏ i in t, s i) := by
  

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
⊢ (∀ i ∈ t, IsCoprime x (s i)) → IsCoprime x (∏ i in t, s i)

Next tactic:
simpa only [isCoprime_comm] using IsCoprime.prod_left (R := R)
theorem IsCoprime.prod_left_iff : IsCoprime (∏ i in t, s i) x ↔ ∀ i ∈ t, IsCoprime (s i) x :=
  Finset.induction_on t (iff_of_true isCoprime_one_left fun _ ↦ by 

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
x✝ : I
⊢ x✝ ∈ ∅ → IsCoprime (s x✝) x

Next tactic:
simp
theorem IsCoprime.prod_left_iff : IsCoprime (∏ i in t, s i) x ↔ ∀ i ∈ t, IsCoprime (s i) x :=
  Finset.induction_on t (iff_of_true isCoprime_one_left fun _ ↦ by simp) fun b t hbt ih ↦ by
    

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t✝ : Finset I
b : I
t : Finset I
hbt : b ∉ t
ih : IsCoprime (∏ i in t, s i) x ↔ ∀ i ∈ t, IsCoprime (s i) x
⊢ IsCoprime (∏ i in insert b t, s i) x ↔ ∀ i ∈ insert b t, IsCoprime (s i) x

Next tactic:
rw [Finset.prod_insert hbt, IsCoprime.mul_left_iff, ih, Finset.forall_mem_insert]
theorem IsCoprime.prod_right_iff : IsCoprime x (∏ i in t, s i) ↔ ∀ i ∈ t, IsCoprime x (s i) := by
  

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
⊢ IsCoprime x (∏ i in t, s i) ↔ ∀ i ∈ t, IsCoprime x (s i)

Next tactic:
simpa only [isCoprime_comm] using IsCoprime.prod_left_iff (R := R)
theorem Finset.prod_dvd_of_coprime :
    ∀ (_ : (t : Set I).Pairwise (IsCoprime on s)) (_ : ∀ i ∈ t, s i ∣ z), (∏ x in t, s x) ∣ z :=
  Finset.induction_on t (fun _ _ ↦ one_dvd z)
    (by
      

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
⊢ ∀ ⦃a : I⦄ {s_1 : Finset I},
    a ∉ s_1 →
      (Set.Pairwise (↑s_1) (IsCoprime on s) → (∀ i ∈ s_1, s i ∣ z) → ∏ x in s_1, s x ∣ z) →
        Set.Pairwise (↑(insert a s_1)) (IsCoprime on s) → (∀ i ∈ insert a s_1, s i ∣ z) → ∏ x in insert a s_1, s x ∣ z

Next tactic:
intro a r har ih Hs Hs1
theorem Finset.prod_dvd_of_coprime :
    ∀ (_ : (t : Set I).Pairwise (IsCoprime on s)) (_ : ∀ i ∈ t, s i ∣ z), (∏ x in t, s x) ∣ z :=
  Finset.induction_on t (fun _ _ ↦ one_dvd z)
    (by
      intro a r har ih Hs Hs1
      

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
a : I
r : Finset I
har : a ∉ r
ih : Set.Pairwise (↑r) (IsCoprime on s) → (∀ i ∈ r, s i ∣ z) → ∏ x in r, s x ∣ z
Hs : Set.Pairwise (↑(insert a r)) (IsCoprime on s)
Hs1 : ∀ i ∈ insert a r, s i ∣ z
⊢ ∏ x in insert a r, s x ∣ z

Next tactic:
rw [Finset.prod_insert har]
theorem Finset.prod_dvd_of_coprime :
    ∀ (_ : (t : Set I).Pairwise (IsCoprime on s)) (_ : ∀ i ∈ t, s i ∣ z), (∏ x in t, s x) ∣ z :=
  Finset.induction_on t (fun _ _ ↦ one_dvd z)
    (by
      intro a r har ih Hs Hs1
      rw [Finset.prod_insert har]
      

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
a : I
r : Finset I
har : a ∉ r
ih : Set.Pairwise (↑r) (IsCoprime on s) → (∀ i ∈ r, s i ∣ z) → ∏ x in r, s x ∣ z
Hs : Set.Pairwise (↑(insert a r)) (IsCoprime on s)
Hs1 : ∀ i ∈ insert a r, s i ∣ z
⊢ s a * ∏ x in r, s x ∣ z

Next tactic:
have aux1 : a ∈ (↑(insert a r) : Set I) := Finset.mem_insert_self a r
theorem Finset.prod_dvd_of_coprime :
    ∀ (_ : (t : Set I).Pairwise (IsCoprime on s)) (_ : ∀ i ∈ t, s i ∣ z), (∏ x in t, s x) ∣ z :=
  Finset.induction_on t (fun _ _ ↦ one_dvd z)
    (by
      intro a r har ih Hs Hs1
      rw [Finset.prod_insert har]
      have aux1 : a ∈ (↑(insert a r) : Set I) := Finset.mem_insert_self a r
      

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
a : I
r : Finset I
har : a ∉ r
ih : Set.Pairwise (↑r) (IsCoprime on s) → (∀ i ∈ r, s i ∣ z) → ∏ x in r, s x ∣ z
Hs : Set.Pairwise (↑(insert a r)) (IsCoprime on s)
Hs1 : ∀ i ∈ insert a r, s i ∣ z
aux1 : a ∈ ↑(insert a r)
⊢ s a * ∏ x in r, s x ∣ z

Next tactic:
refine'
        (IsCoprime.prod_right fun i hir ↦
              Hs aux1 (Finset.mem_insert_of_mem hir) <| by
                rintro rfl
                exact har hir).mul_dvd
          (Hs1 a aux1) (ih (Hs.mono _) fun i hi ↦ Hs1 i <| Finset.mem_insert_of_mem hi)
theorem Finset.prod_dvd_of_coprime :
    ∀ (_ : (t : Set I).Pairwise (IsCoprime on s)) (_ : ∀ i ∈ t, s i ∣ z), (∏ x in t, s x) ∣ z :=
  Finset.induction_on t (fun _ _ ↦ one_dvd z)
    (by
      intro a r har ih Hs Hs1
      rw [Finset.prod_insert har]
      have aux1 : a ∈ (↑(insert a r) : Set I) := Finset.mem_insert_self a r
      refine'
        (IsCoprime.prod_right fun i hir ↦
              Hs aux1 (Finset.mem_insert_of_mem hir) <| by
                

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
a : I
r : Finset I
har : a ∉ r
ih : Set.Pairwise (↑r) (IsCoprime on s) → (∀ i ∈ r, s i ∣ z) → ∏ x in r, s x ∣ z
Hs : Set.Pairwise (↑(insert a r)) (IsCoprime on s)
Hs1 : ∀ i ∈ insert a r, s i ∣ z
aux1 : a ∈ ↑(insert a r)
i : I
hir : i ∈ r
⊢ a ≠ i

Next tactic:
rintro rfl
theorem Finset.prod_dvd_of_coprime :
    ∀ (_ : (t : Set I).Pairwise (IsCoprime on s)) (_ : ∀ i ∈ t, s i ∣ z), (∏ x in t, s x) ∣ z :=
  Finset.induction_on t (fun _ _ ↦ one_dvd z)
    (by
      intro a r har ih Hs Hs1
      rw [Finset.prod_insert har]
      have aux1 : a ∈ (↑(insert a r) : Set I) := Finset.mem_insert_self a r
      refine'
        (IsCoprime.prod_right fun i hir ↦
              Hs aux1 (Finset.mem_insert_of_mem hir) <| by
                rintro rfl
                

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
a : I
r : Finset I
har : a ∉ r
ih : Set.Pairwise (↑r) (IsCoprime on s) → (∀ i ∈ r, s i ∣ z) → ∏ x in r, s x ∣ z
Hs : Set.Pairwise (↑(insert a r)) (IsCoprime on s)
Hs1 : ∀ i ∈ insert a r, s i ∣ z
aux1 : a ∈ ↑(insert a r)
hir : a ∈ r
⊢ False

Next tactic:
exact har hir
theorem Finset.prod_dvd_of_coprime :
    ∀ (_ : (t : Set I).Pairwise (IsCoprime on s)) (_ : ∀ i ∈ t, s i ∣ z), (∏ x in t, s x) ∣ z :=
  Finset.induction_on t (fun _ _ ↦ one_dvd z)
    (by
      intro a r har ih Hs Hs1
      rw [Finset.prod_insert har]
      have aux1 : a ∈ (↑(insert a r) : Set I) := Finset.mem_insert_self a r
      refine'
        (IsCoprime.prod_right fun i hir ↦
              Hs aux1 (Finset.mem_insert_of_mem hir) <| by
                rintro rfl
                exact har hir).mul_dvd
          (Hs1 a aux1) (ih (Hs.mono _) fun i hi ↦ Hs1 i <| Finset.mem_insert_of_mem hi)
      

Proof state:
R : Type u
I : Type v
inst✝ : CommSemiring R
x y z : R
s : I → R
t : Finset I
a : I
r : Finset I
har : a ∉ r
ih : Set.Pairwise (↑r) (IsCoprime on s) → (∀ i ∈ r, s i ∣ z) → ∏ x in r, s x ∣ z
Hs : Set.Pairwise (↑(insert a r)) (IsCoprime on s)
Hs1 : ∀ i ∈ insert a r, s i ∣ z
aux1 : a ∈ ↑(insert a r)
⊢ ↑r ⊆ ↑(insert a r)

Next tactic:
simp only [Finset.coe_insert, Set.subset_insert]
theorem exists_sum_eq_one_iff_pairwise_coprime [DecidableEq I] (h : t.Nonempty) :
    (∃ μ : I → R, (∑ i in t, μ i * ∏ j in t \ {i}, s j) = 1) ↔
      Pairwise (IsCoprime on fun i : t ↦ s i) := by
  

Proof state:
R : Type u
I : Type v
inst✝¹ : CommSemiring R
x y z : R
s : I → R
t : Finset I
inst✝ : DecidableEq I
h : Finset.Nonempty t
⊢ (∃ μ, ∑ i in t, μ i * ∏ j in t \ {i}, s j = 1) ↔ Pairwise (IsCoprime on fun i => s ↑i)

Next tactic:
refine' h.cons_induction _ _
theorem exists_sum_eq_one_iff_pairwise_coprime [DecidableEq I] (h : t.Nonempty) :
    (∃ μ : I → R, (∑ i in t, μ i * ∏ j in t \ {i}, s j) = 1) ↔
      Pairwise (IsCoprime on fun i : t ↦ s i) := by
  refine' h.cons_induction _ _
  · 

Proof state:
case refine'_1
R : Type u
I : Type v
inst✝¹ : CommSemiring R
x y z : R
s : I → R
t : Finset I
inst✝ : DecidableEq I
h : Finset.Nonempty t
⊢ ∀ (a : I), (∃ μ, ∑ i in {a}, μ i * ∏ j in {a} \ {i}, s j = 1) ↔ Pairwise (IsCoprime on fun i => s ↑i)

Next tactic:
simp only [sum_singleton, Finset.sdiff_self, prod_empty, mul_one, exists_apply_eq,
               Pairwise, Ne.def, true_iff_iff]
theorem exists_sum_eq_one_iff_pairwise_coprime [DecidableEq I] (h : t.Nonempty) :
    (∃ μ : I → R, (∑ i in t, μ i * ∏ j in t \ {i}, s j) = 1) ↔
      Pairwise (IsCoprime on fun i : t ↦ s i) := by
  refine' h.cons_induction _ _
  · simp only [sum_singleton, Finset.sdiff_self, prod_empty, mul_one, exists_apply_eq,
               Pairwise, Ne.def, true_iff_iff]
    

Proof state:
case refine'_1
R : Type u
I : Type v
inst✝¹ : CommSemiring R
x y z : R
s : I → R
t : Finset I
inst✝ : DecidableEq I
h : Finset.Nonempty t
⊢ ∀ (a : I) ⦃i j : { x // x ∈ {a} }⦄, ¬i = j → (IsCoprime on fun i => s ↑i) i j

Next tactic:
rintro a ⟨i, hi⟩ ⟨j, hj⟩ h
theorem exists_sum_eq_one_iff_pairwise_coprime [DecidableEq I] (h : t.Nonempty) :
    (∃ μ : I → R, (∑ i in t, μ i * ∏ j in t \ {i}, s j) = 1) ↔
      Pairwise (IsCoprime on fun i : t ↦ s i) := by
  refine' h.cons_induction _ _
  · simp only [sum_singleton, Finset.sdiff_self, prod_empty, mul_one, exists_apply_eq,
               Pairwise, Ne.def, true_iff_iff]
    rintro a ⟨i, hi⟩ ⟨j, hj⟩ h
    

Proof state:
case refine'_1.mk.mk
R : Type u
I : Type v
inst✝¹ : CommSemiring R
x y z : R
s : I → R
t : Finset I
inst✝ : DecidableEq I
h✝ : Finset.Nonempty t
a i : I
hi : i ∈ {a}
j : I
hj : j ∈ {a}
h : ¬{ val := i, property := hi } = { val := j, property := hj }
⊢ (IsCoprime on fun i => s ↑i) { val := i, property := hi } { val := j, property := hj }

Next tactic:
rw [Finset.mem_singleton] at hi hj