l3lab/ntp-mathlib huggingface dataset:
theorem fract_inv_num_lt_num_of_pos {q : ℚ} (q_pos : 0 < q) : (fract q⁻¹).num < q.num := by
  -- we know that the numerator must be positive
  have q_num_pos : 0 < q.num := Rat.num_pos_iff_pos.mpr q_pos
  -- we will work with the absolute value of the numerator, which is equal to the numerator
  have q_num_abs_eq_q_num : (q.num.natAbs : ℤ) = q.num := Int.natAbs_of_nonneg q_num_pos.le
  set q_inv := (q.den : ℚ) / q.num with q_inv_def
  have q_inv_eq : q⁻¹ = q_inv := Rat.inv_def''
  suffices (q_inv - ⌊q_inv⌋).num < q.num by rwa [q_inv_eq]
  suffices ((q.den - q.num * ⌊q_inv⌋ : ℚ) / q.num).num < q.num by
    field_simp [this, ne_of_gt q_num_pos]
  suffices (q.den : ℤ) - q.num * ⌊q_inv⌋ < q.num by
    -- use that `q.num` and `q.den` are coprime to show that the numerator stays unreduced
    have : ((q.den - q.num * ⌊q_inv⌋ : ℚ) / q.num).num = q.den - q.num * ⌊q_inv⌋ := by
      suffices ((q.den : ℤ) - q.num * ⌊q_inv⌋).natAbs.Coprime q.num.natAbs from
        mod_cast Rat.num_div_eq_of_coprime q_num_pos this
      have tmp := Nat.coprime_sub_mul_floor_rat_div_of_coprime q.reduced.symm
      simpa only [Nat.cast_natAbs, abs_of_nonneg q_num_pos.le] using tmp
    rwa [this]
  -- to show the claim, start with the following inequality
  have q_inv_num_denom_ineq : q⁻¹.num - ⌊q⁻¹⌋ * q⁻¹.den < q⁻¹.den := by
    have : q⁻¹.num < (⌊q⁻¹⌋ + 1) * q⁻¹.den := Rat.num_lt_succ_floor_mul_den q⁻¹
    have : q⁻¹.num < ⌊q⁻¹⌋ * q⁻¹.den + q⁻¹.den := by rwa [right_distrib, one_mul] at this
    rwa [← sub_lt_iff_lt_add'] at this
  -- use that `q.num` and `q.den` are coprime to show that q_inv is the unreduced reciprocal
  -- of `q`
  have : q_inv.num = q.den ∧ q_inv.den = q.num.natAbs := by
    have coprime_q_denom_q_num : q.den.Coprime q.num.natAbs := q.reduced.symm
    have : Int.natAbs q.den = q.den := by simp
    rw [← this] at coprime_q_denom_q_num
    rw [q_inv_def]
    constructor
    · exact mod_cast Rat.num_div_eq_of_coprime q_num_pos coprime_q_denom_q_num
    · suffices (((q.den : ℚ) / q.num).den : ℤ) = q.num.natAbs by exact mod_cast this
      rw [q_num_abs_eq_q_num]
      

Proof state:
case right
q : ℚ
q_pos : 0 < q
q_num_pos : 0 < q.num
q_num_abs_eq_q_num : ↑(natAbs q.num) = q.num
q_inv : ℚ := ↑q.den / ↑q.num
q_inv_def : q_inv = ↑q.den / ↑q.num
q_inv_eq : q⁻¹ = q_inv
q_inv_num_denom_ineq : q⁻¹.num - ⌊q⁻¹⌋ * ↑q⁻¹.den < ↑q⁻¹.den
coprime_q_denom_q_num : Nat.Coprime (natAbs ↑q.den) (natAbs q.num)
this : natAbs ↑q.den = q.den
⊢ ↑(↑q.den / ↑q.num).den = q.num

Next tactic:
exact mod_cast Rat.den_div_eq_of_coprime q_num_pos coprime_q_denom_q_num
theorem fract_inv_num_lt_num_of_pos {q : ℚ} (q_pos : 0 < q) : (fract q⁻¹).num < q.num := by
  -- we know that the numerator must be positive
  have q_num_pos : 0 < q.num := Rat.num_pos_iff_pos.mpr q_pos
  -- we will work with the absolute value of the numerator, which is equal to the numerator
  have q_num_abs_eq_q_num : (q.num.natAbs : ℤ) = q.num := Int.natAbs_of_nonneg q_num_pos.le
  set q_inv := (q.den : ℚ) / q.num with q_inv_def
  have q_inv_eq : q⁻¹ = q_inv := Rat.inv_def''
  suffices (q_inv - ⌊q_inv⌋).num < q.num by rwa [q_inv_eq]
  suffices ((q.den - q.num * ⌊q_inv⌋ : ℚ) / q.num).num < q.num by
    field_simp [this, ne_of_gt q_num_pos]
  suffices (q.den : ℤ) - q.num * ⌊q_inv⌋ < q.num by
    -- use that `q.num` and `q.den` are coprime to show that the numerator stays unreduced
    have : ((q.den - q.num * ⌊q_inv⌋ : ℚ) / q.num).num = q.den - q.num * ⌊q_inv⌋ := by
      suffices ((q.den : ℤ) - q.num * ⌊q_inv⌋).natAbs.Coprime q.num.natAbs from
        mod_cast Rat.num_div_eq_of_coprime q_num_pos this
      have tmp := Nat.coprime_sub_mul_floor_rat_div_of_coprime q.reduced.symm
      simpa only [Nat.cast_natAbs, abs_of_nonneg q_num_pos.le] using tmp
    rwa [this]
  -- to show the claim, start with the following inequality
  have q_inv_num_denom_ineq : q⁻¹.num - ⌊q⁻¹⌋ * q⁻¹.den < q⁻¹.den := by
    have : q⁻¹.num < (⌊q⁻¹⌋ + 1) * q⁻¹.den := Rat.num_lt_succ_floor_mul_den q⁻¹
    have : q⁻¹.num < ⌊q⁻¹⌋ * q⁻¹.den + q⁻¹.den := by rwa [right_distrib, one_mul] at this
    rwa [← sub_lt_iff_lt_add'] at this
  -- use that `q.num` and `q.den` are coprime to show that q_inv is the unreduced reciprocal
  -- of `q`
  have : q_inv.num = q.den ∧ q_inv.den = q.num.natAbs := by
    have coprime_q_denom_q_num : q.den.Coprime q.num.natAbs := q.reduced.symm
    have : Int.natAbs q.den = q.den := by simp
    rw [← this] at coprime_q_denom_q_num
    rw [q_inv_def]
    constructor
    · exact mod_cast Rat.num_div_eq_of_coprime q_num_pos coprime_q_denom_q_num
    · suffices (((q.den : ℚ) / q.num).den : ℤ) = q.num.natAbs by exact mod_cast this
      rw [q_num_abs_eq_q_num]
      exact mod_cast Rat.den_div_eq_of_coprime q_num_pos coprime_q_denom_q_num
  

Proof state:
q : ℚ
q_pos : 0 < q
q_num_pos : 0 < q.num
q_num_abs_eq_q_num : ↑(natAbs q.num) = q.num
q_inv : ℚ := ↑q.den / ↑q.num
q_inv_def : q_inv = ↑q.den / ↑q.num
q_inv_eq : q⁻¹ = q_inv
q_inv_num_denom_ineq : q⁻¹.num - ⌊q⁻¹⌋ * ↑q⁻¹.den < ↑q⁻¹.den
this : q_inv.num = ↑q.den ∧ q_inv.den = natAbs q.num
⊢ ↑q.den - q.num * ⌊q_inv⌋ < q.num

Next tactic:
rwa [q_inv_eq, this.left, this.right, q_num_abs_eq_q_num, mul_comm] at q_inv_num_denom_ineq
theorem Finset.pairwiseDisjoint_range_singleton :
    (Set.range (singleton : α → Finset α)).PairwiseDisjoint id := by
  

Proof state:
α : Type u_1
ι : Type u_2
ι' : Type u_3
⊢ Set.PairwiseDisjoint (Set.range singleton) id

Next tactic:
rintro _ ⟨a, rfl⟩ _ ⟨b, rfl⟩ h
theorem Finset.pairwiseDisjoint_range_singleton :
    (Set.range (singleton : α → Finset α)).PairwiseDisjoint id := by
  rintro _ ⟨a, rfl⟩ _ ⟨b, rfl⟩ h
  

Proof state:
case intro.intro
α : Type u_1
ι : Type u_2
ι' : Type u_3
a b : α
h : {a} ≠ {b}
⊢ (Disjoint on id) {a} {b}

Next tactic:
exact disjoint_singleton.2 (ne_of_apply_ne _ h)
theorem PairwiseDisjoint.image_finset_of_le [DecidableEq ι] {s : Finset ι} {f : ι → α}
    (hs : (s : Set ι).PairwiseDisjoint f) {g : ι → ι} (hf : ∀ a, f (g a) ≤ f a) :
    (s.image g : Set ι).PairwiseDisjoint f := by
  

Proof state:
α : Type u_1
ι : Type u_2
ι' : Type u_3
inst✝² : SemilatticeInf α
inst✝¹ : OrderBot α
s✝ : Finset ι
f✝ : ι → α
inst✝ : DecidableEq ι
s : Finset ι
f : ι → α
hs : PairwiseDisjoint (↑s) f
g : ι → ι
hf : ∀ (a : ι), f (g a) ≤ f a
⊢ PairwiseDisjoint (↑(Finset.image g s)) f

Next tactic:
rw [coe_image]
theorem PairwiseDisjoint.image_finset_of_le [DecidableEq ι] {s : Finset ι} {f : ι → α}
    (hs : (s : Set ι).PairwiseDisjoint f) {g : ι → ι} (hf : ∀ a, f (g a) ≤ f a) :
    (s.image g : Set ι).PairwiseDisjoint f := by
  rw [coe_image]
  

Proof state:
α : Type u_1
ι : Type u_2
ι' : Type u_3
inst✝² : SemilatticeInf α
inst✝¹ : OrderBot α
s✝ : Finset ι
f✝ : ι → α
inst✝ : DecidableEq ι
s : Finset ι
f : ι → α
hs : PairwiseDisjoint (↑s) f
g : ι → ι
hf : ∀ (a : ι), f (g a) ≤ f a
⊢ PairwiseDisjoint (g '' ↑s) f

Next tactic:
exact hs.image_of_le hf
/-- Bind operation for `Set.PairwiseDisjoint`. In a complete lattice, you can use
`Set.PairwiseDisjoint.biUnion`. -/
theorem PairwiseDisjoint.biUnion_finset {s : Set ι'} {g : ι' → Finset ι} {f : ι → α}
    (hs : s.PairwiseDisjoint fun i' : ι' => (g i').sup f)
    (hg : ∀ i ∈ s, (g i : Set ι).PairwiseDisjoint f) : (⋃ i ∈ s, ↑(g i)).PairwiseDisjoint f := by
  

Proof state:
α : Type u_1
ι : Type u_2
ι' : Type u_3
inst✝¹ : Lattice α
inst✝ : OrderBot α
s : Set ι'
g : ι' → Finset ι
f : ι → α
hs : PairwiseDisjoint s fun i' => sup (g i') f
hg : ∀ i ∈ s, PairwiseDisjoint (↑(g i)) f
⊢ PairwiseDisjoint (⋃ i ∈ s, ↑(g i)) f

Next tactic:
rintro a ha b hb hab
/-- Bind operation for `Set.PairwiseDisjoint`. In a complete lattice, you can use
`Set.PairwiseDisjoint.biUnion`. -/
theorem PairwiseDisjoint.biUnion_finset {s : Set ι'} {g : ι' → Finset ι} {f : ι → α}
    (hs : s.PairwiseDisjoint fun i' : ι' => (g i').sup f)
    (hg : ∀ i ∈ s, (g i : Set ι).PairwiseDisjoint f) : (⋃ i ∈ s, ↑(g i)).PairwiseDisjoint f := by
  rintro a ha b hb hab
  

Proof state:
α : Type u_1
ι : Type u_2
ι' : Type u_3
inst✝¹ : Lattice α
inst✝ : OrderBot α
s : Set ι'
g : ι' → Finset ι
f : ι → α
hs : PairwiseDisjoint s fun i' => sup (g i') f
hg : ∀ i ∈ s, PairwiseDisjoint (↑(g i)) f
a : ι
ha : a ∈ ⋃ i ∈ s, ↑(g i)
b : ι
hb : b ∈ ⋃ i ∈ s, ↑(g i)
hab : a ≠ b
⊢ (Disjoint on f) a b

Next tactic:
simp_rw [Set.mem_iUnion] at ha hb
/-- Bind operation for `Set.PairwiseDisjoint`. In a complete lattice, you can use
`Set.PairwiseDisjoint.biUnion`. -/
theorem PairwiseDisjoint.biUnion_finset {s : Set ι'} {g : ι' → Finset ι} {f : ι → α}
    (hs : s.PairwiseDisjoint fun i' : ι' => (g i').sup f)
    (hg : ∀ i ∈ s, (g i : Set ι).PairwiseDisjoint f) : (⋃ i ∈ s, ↑(g i)).PairwiseDisjoint f := by
  rintro a ha b hb hab
  simp_rw [Set.mem_iUnion] at ha hb
  

Proof state:
α : Type u_1
ι : Type u_2
ι' : Type u_3
inst✝¹ : Lattice α
inst✝ : OrderBot α
s : Set ι'
g : ι' → Finset ι
f : ι → α
hs : PairwiseDisjoint s fun i' => sup (g i') f
hg : ∀ i ∈ s, PairwiseDisjoint (↑(g i)) f
a b : ι
hab : a ≠ b
ha : ∃ i, ∃ (_ : i ∈ s), a ∈ ↑(g i)
hb : ∃ i, ∃ (_ : i ∈ s), b ∈ ↑(g i)
⊢ (Disjoint on f) a b

Next tactic:
obtain ⟨c, hc, ha⟩ := ha
/-- Bind operation for `Set.PairwiseDisjoint`. In a complete lattice, you can use
`Set.PairwiseDisjoint.biUnion`. -/
theorem PairwiseDisjoint.biUnion_finset {s : Set ι'} {g : ι' → Finset ι} {f : ι → α}
    (hs : s.PairwiseDisjoint fun i' : ι' => (g i').sup f)
    (hg : ∀ i ∈ s, (g i : Set ι).PairwiseDisjoint f) : (⋃ i ∈ s, ↑(g i)).PairwiseDisjoint f := by
  rintro a ha b hb hab
  simp_rw [Set.mem_iUnion] at ha hb
  obtain ⟨c, hc, ha⟩ := ha
  

Proof state:
case intro.intro
α : Type u_1
ι : Type u_2
ι' : Type u_3
inst✝¹ : Lattice α
inst✝ : OrderBot α
s : Set ι'
g : ι' → Finset ι
f : ι → α
hs : PairwiseDisjoint s fun i' => sup (g i') f
hg : ∀ i ∈ s, PairwiseDisjoint (↑(g i)) f
a b : ι
hab : a ≠ b
hb : ∃ i, ∃ (_ : i ∈ s), b ∈ ↑(g i)
c : ι'
hc : c ∈ s
ha : a ∈ ↑(g c)
⊢ (Disjoint on f) a b

Next tactic:
obtain ⟨d, hd, hb⟩ := hb
/-- Bind operation for `Set.PairwiseDisjoint`. In a complete lattice, you can use
`Set.PairwiseDisjoint.biUnion`. -/
theorem PairwiseDisjoint.biUnion_finset {s : Set ι'} {g : ι' → Finset ι} {f : ι → α}
    (hs : s.PairwiseDisjoint fun i' : ι' => (g i').sup f)
    (hg : ∀ i ∈ s, (g i : Set ι).PairwiseDisjoint f) : (⋃ i ∈ s, ↑(g i)).PairwiseDisjoint f := by
  rintro a ha b hb hab
  simp_rw [Set.mem_iUnion] at ha hb
  obtain ⟨c, hc, ha⟩ := ha
  obtain ⟨d, hd, hb⟩ := hb
  

Proof state:
case intro.intro.intro.intro
α : Type u_1
ι : Type u_2
ι' : Type u_3
inst✝¹ : Lattice α
inst✝ : OrderBot α
s : Set ι'
g : ι' → Finset ι
f : ι → α
hs : PairwiseDisjoint s fun i' => sup (g i') f
hg : ∀ i ∈ s, PairwiseDisjoint (↑(g i)) f
a b : ι
hab : a ≠ b
c : ι'
hc : c ∈ s
ha : a ∈ ↑(g c)
d : ι'
hd : d ∈ s
hb : b ∈ ↑(g d)
⊢ (Disjoint on f) a b

Next tactic:
obtain hcd | hcd := eq_or_ne (g c) (g d)
/-- Bind operation for `Set.PairwiseDisjoint`. In a complete lattice, you can use
`Set.PairwiseDisjoint.biUnion`. -/
theorem PairwiseDisjoint.biUnion_finset {s : Set ι'} {g : ι' → Finset ι} {f : ι → α}
    (hs : s.PairwiseDisjoint fun i' : ι' => (g i').sup f)
    (hg : ∀ i ∈ s, (g i : Set ι).PairwiseDisjoint f) : (⋃ i ∈ s, ↑(g i)).PairwiseDisjoint f := by
  rintro a ha b hb hab
  simp_rw [Set.mem_iUnion] at ha hb
  obtain ⟨c, hc, ha⟩ := ha
  obtain ⟨d, hd, hb⟩ := hb
  obtain hcd | hcd := eq_or_ne (g c) (g d)
  · 

Proof state:
case intro.intro.intro.intro.inl
α : Type u_1
ι : Type u_2
ι' : Type u_3
inst✝¹ : Lattice α
inst✝ : OrderBot α
s : Set ι'
g : ι' → Finset ι
f : ι → α
hs : PairwiseDisjoint s fun i' => sup (g i') f
hg : ∀ i ∈ s, PairwiseDisjoint (↑(g i)) f
a b : ι
hab : a ≠ b
c : ι'
hc : c ∈ s
ha : a ∈ ↑(g c)
d : ι'
hd : d ∈ s
hb : b ∈ ↑(g d)
hcd : g c = g d
⊢ (Disjoint on f) a b

Next tactic:
exact hg d hd (by rwa [hcd] at ha) hb hab
/-- Bind operation for `Set.PairwiseDisjoint`. In a complete lattice, you can use
`Set.PairwiseDisjoint.biUnion`. -/
theorem PairwiseDisjoint.biUnion_finset {s : Set ι'} {g : ι' → Finset ι} {f : ι → α}
    (hs : s.PairwiseDisjoint fun i' : ι' => (g i').sup f)
    (hg : ∀ i ∈ s, (g i : Set ι).PairwiseDisjoint f) : (⋃ i ∈ s, ↑(g i)).PairwiseDisjoint f := by
  rintro a ha b hb hab
  simp_rw [Set.mem_iUnion] at ha hb
  obtain ⟨c, hc, ha⟩ := ha
  obtain ⟨d, hd, hb⟩ := hb
  obtain hcd | hcd := eq_or_ne (g c) (g d)
  · exact hg d hd (by 

Proof state:
α : Type u_1
ι : Type u_2
ι' : Type u_3
inst✝¹ : Lattice α
inst✝ : OrderBot α
s : Set ι'
g : ι' → Finset ι
f : ι → α
hs : PairwiseDisjoint s fun i' => sup (g i') f
hg : ∀ i ∈ s, PairwiseDisjoint (↑(g i)) f
a b : ι
hab : a ≠ b
c : ι'
hc : c ∈ s
ha : a ∈ ↑(g c)
d : ι'
hd : d ∈ s
hb : b ∈ ↑(g d)
hcd : g c = g d
⊢ a ∈ ↑(g d)

Next tactic:
rwa [hcd] at ha
/-- Bind operation for `Set.PairwiseDisjoint`. In a complete lattice, you can use
`Set.PairwiseDisjoint.biUnion`. -/
theorem PairwiseDisjoint.biUnion_finset {s : Set ι'} {g : ι' → Finset ι} {f : ι → α}
    (hs : s.PairwiseDisjoint fun i' : ι' => (g i').sup f)
    (hg : ∀ i ∈ s, (g i : Set ι).PairwiseDisjoint f) : (⋃ i ∈ s, ↑(g i)).PairwiseDisjoint f := by
  rintro a ha b hb hab
  simp_rw [Set.mem_iUnion] at ha hb
  obtain ⟨c, hc, ha⟩ := ha
  obtain ⟨d, hd, hb⟩ := hb
  obtain hcd | hcd := eq_or_ne (g c) (g d)
  · exact hg d hd (by rwa [hcd] at ha) hb hab
  · 

Proof state:
case intro.intro.intro.intro.inr
α : Type u_1
ι : Type u_2
ι' : Type u_3
inst✝¹ : Lattice α
inst✝ : OrderBot α
s : Set ι'
g : ι' → Finset ι
f : ι → α
hs : PairwiseDisjoint s fun i' => sup (g i') f
hg : ∀ i ∈ s, PairwiseDisjoint (↑(g i)) f
a b : ι
hab : a ≠ b
c : ι'
hc : c ∈ s
ha : a ∈ ↑(g c)
d : ι'
hd : d ∈ s
hb : b ∈ ↑(g d)
hcd : g c ≠ g d
⊢ (Disjoint on f) a b

Next tactic:
exact (hs hc hd (ne_of_apply_ne _ hcd)).mono (Finset.le_sup ha) (Finset.le_sup hb)
theorem pairwise_of_coe_toFinset_pairwise (hl : (l.toFinset : Set α).Pairwise r) (hn : l.Nodup) :
    l.Pairwise r := by
  

Proof state:
α : Type u_1
ι : Type u_2
ι' : Type u_3
β : Type u_4
inst✝ : DecidableEq α
r : α → α → Prop
l : List α
hl : Set.Pairwise (↑(toFinset l)) r
hn : Nodup l
⊢ Pairwise r l

Next tactic:
rw [coe_toFinset] at hl
theorem pairwise_of_coe_toFinset_pairwise (hl : (l.toFinset : Set α).Pairwise r) (hn : l.Nodup) :
    l.Pairwise r := by
  rw [coe_toFinset] at hl
  

Proof state:
α : Type u_1
ι : Type u_2
ι' : Type u_3
β : Type u_4
inst✝ : DecidableEq α
r : α → α → Prop
l : List α
hl : Set.Pairwise {a | a ∈ l} r
hn : Nodup l
⊢ Pairwise r l

Next tactic:
exact hn.pairwise_of_set_pairwise hl
theorem pairwise_iff_coe_toFinset_pairwise (hn : l.Nodup) (hs : Symmetric r) :
    (l.toFinset : Set α).Pairwise r ↔ l.Pairwise r := by
  

Proof state:
α : Type u_1
ι : Type u_2
ι' : Type u_3
β : Type u_4
inst✝ : DecidableEq α
r : α → α → Prop
l : List α
hn : Nodup l
hs : Symmetric r
⊢ Set.Pairwise (↑(toFinset l)) r ↔ Pairwise r l

Next tactic:
letI : IsSymm α r := ⟨hs⟩
theorem pairwise_iff_coe_toFinset_pairwise (hn : l.Nodup) (hs : Symmetric r) :
    (l.toFinset : Set α).Pairwise r ↔ l.Pairwise r := by
  letI : IsSymm α r := ⟨hs⟩
  

Proof state:
α : Type u_1
ι : Type u_2
ι' : Type u_3
β : Type u_4
inst✝ : DecidableEq α
r : α → α → Prop
l : List α
hn : Nodup l
hs : Symmetric r
this : IsSymm α r := { symm := hs }
⊢ Set.Pairwise (↑(toFinset l)) r ↔ Pairwise r l

Next tactic:
rw [coe_toFinset, hn.pairwise_coe]
theorem star_mem_star [InvolutiveStar α] : a⋆ ∈ s⋆ ↔ a ∈ s := by 

Proof state:
α : Type u_1
s t : Set α
a : α
inst✝ : InvolutiveStar α
⊢ a⋆ ∈ s⋆ ↔ a ∈ s

Next tactic:
simp only [mem_star, star_star]
@[simp]
theorem image_star [InvolutiveStar α] : Star.star '' s = s⋆ := by
  

Proof state:
α : Type u_1
s t : Set α
a : α
inst✝ : InvolutiveStar α
⊢ star '' s = s⋆

Next tactic:
simp only [← star_preimage]
@[simp]
theorem image_star [InvolutiveStar α] : Star.star '' s = s⋆ := by
  simp only [← star_preimage]
  

Proof state:
α : Type u_1
s t : Set α
a : α
inst✝ : InvolutiveStar α
⊢ star '' s = star ⁻¹' s

Next tactic:
rw [image_eq_preimage_of_inverse]
@[simp]
theorem image_star [InvolutiveStar α] : Star.star '' s = s⋆ := by
  simp only [← star_preimage]
  rw [image_eq_preimage_of_inverse] <;> 

Proof state:
case h₁
α : Type u_1
s t : Set α
a : α
inst✝ : InvolutiveStar α
⊢ Function.LeftInverse star star

Next tactic:
intro
@[simp]
theorem image_star [InvolutiveStar α] : Star.star '' s = s⋆ := by
  simp only [← star_preimage]
  rw [image_eq_preimage_of_inverse] <;> 

Proof state:
case h₂
α : Type u_1
s t : Set α
a : α
inst✝ : InvolutiveStar α
⊢ Function.RightInverse star star

Next tactic:
intro
@[simp]
theorem image_star [InvolutiveStar α] : Star.star '' s = s⋆ := by
  simp only [← star_preimage]
  rw [image_eq_preimage_of_inverse] <;> intro <;> 

Proof state:
case h₁
α : Type u_1
s t : Set α
a : α
inst✝ : InvolutiveStar α
x✝ : α
⊢ x✝⋆⋆ = x✝

Next tactic:
simp only [star_star]
@[simp]
theorem image_star [InvolutiveStar α] : Star.star '' s = s⋆ := by
  simp only [← star_preimage]
  rw [image_eq_preimage_of_inverse] <;> intro <;> 

Proof state:
case h₂
α : Type u_1
s t : Set α
a : α
inst✝ : InvolutiveStar α
x✝ : α
⊢ x✝⋆⋆ = x✝

Next tactic:
simp only [star_star]
@[simp]
instance [InvolutiveStar α] : InvolutiveStar (Set α) where
  star := Star.star
  star_involutive s := by 

Proof state:
α : Type u_1
s✝ t : Set α
a : α
inst✝ : InvolutiveStar α
s : Set α
⊢ s⋆⋆ = s

Next tactic:
simp only [← star_preimage, preimage_preimage, star_star, preimage_id']
theorem star_subset [InvolutiveStar α] {s t : Set α} : s⋆ ⊆ t ↔ s ⊆ t⋆ := by
  

Proof state:
α : Type u_1
s✝ t✝ : Set α
a : α
inst✝ : InvolutiveStar α
s t : Set α
⊢ s⋆ ⊆ t ↔ s ⊆ t⋆

Next tactic:
rw [← star_subset_star, star_star]
theorem star_singleton {β : Type*} [InvolutiveStar β] (x : β) : ({x} : Set β)⋆ = {x⋆} := by
  

Proof state:
α : Type u_1
s t : Set α
a : α
β : Type u_2
inst✝ : InvolutiveStar β
x : β
⊢ {x}⋆ = {x⋆}

Next tactic:
ext1 y
theorem star_singleton {β : Type*} [InvolutiveStar β] (x : β) : ({x} : Set β)⋆ = {x⋆} := by
  ext1 y
  

Proof state:
case h
α : Type u_1
s t : Set α
a : α
β : Type u_2
inst✝ : InvolutiveStar β
x y : β
⊢ y ∈ {x}⋆ ↔ y ∈ {x⋆}

Next tactic:
rw [mem_star, mem_singleton_iff, mem_singleton_iff, star_eq_iff_star_eq, eq_comm]
protected theorem star_mul [Mul α] [StarMul α] (s t : Set α) : (s * t)⋆ = t⋆ * s⋆ := by
 

Proof state:
α : Type u_1
s✝ t✝ : Set α
a : α
inst✝¹ : Mul α
inst✝ : StarMul α
s t : Set α
⊢ (s * t)⋆ = t⋆ * s⋆

Next tactic:
simp_rw [← image_star, ← image2_mul, image_image2, image2_image_left, image2_image_right,
   star_mul, image2_swap _ s t]
protected theorem star_add [AddMonoid α] [StarAddMonoid α] (s t : Set α) : (s + t)⋆ = s⋆ + t⋆ := by
 

Proof state:
α : Type u_1
s✝ t✝ : Set α
a : α
inst✝¹ : AddMonoid α
inst✝ : StarAddMonoid α
s t : Set α
⊢ (s + t)⋆ = s⋆ + t⋆

Next tactic:
simp_rw [← image_star, ← image2_add, image_image2, image2_image_left, image2_image_right,
   star_add]
@[simp]
instance [Star α] [TrivialStar α] : TrivialStar (Set α) where
  star_trivial s := by
    

Proof state:
α : Type u_1
s✝ t : Set α
a : α
inst✝¹ : Star α
inst✝ : TrivialStar α
s : Set α
⊢ s⋆ = s

Next tactic:
rw [← star_preimage]
@[simp]
instance [Star α] [TrivialStar α] : TrivialStar (Set α) where
  star_trivial s := by
    rw [← star_preimage]
    

Proof state:
α : Type u_1
s✝ t : Set α
a : α
inst✝¹ : Star α
inst✝ : TrivialStar α
s : Set α
⊢ star ⁻¹' s = s

Next tactic:
ext1
@[simp]
instance [Star α] [TrivialStar α] : TrivialStar (Set α) where
  star_trivial s := by
    rw [← star_preimage]
    ext1
    

Proof state:
case h
α : Type u_1
s✝ t : Set α
a : α
inst✝¹ : Star α
inst✝ : TrivialStar α
s : Set α
x✝ : α
⊢ x✝ ∈ star ⁻¹' s ↔ x✝ ∈ s

Next tactic:
simp [star_trivial]
protected theorem star_inv [Group α] [StarMul α] (s : Set α) : s⁻¹⋆ = s⋆⁻¹ := by
  

Proof state:
α : Type u_1
s✝ t : Set α
a : α
inst✝¹ : Group α
inst✝ : StarMul α
s : Set α
⊢ s⁻¹⋆ = s⋆⁻¹

Next tactic:
ext
protected theorem star_inv [Group α] [StarMul α] (s : Set α) : s⁻¹⋆ = s⋆⁻¹ := by
  ext
  

Proof state:
case h
α : Type u_1
s✝ t : Set α
a : α
inst✝¹ : Group α
inst✝ : StarMul α
s : Set α
x✝ : α
⊢ x✝ ∈ s⁻¹⋆ ↔ x✝ ∈ s⋆⁻¹

Next tactic:
simp only [mem_star, mem_inv, star_inv]
protected theorem star_inv' [DivisionSemiring α] [StarRing α] (s : Set α) : s⁻¹⋆ = s⋆⁻¹ := by
  

Proof state:
α : Type u_1
s✝ t : Set α
a : α
inst✝¹ : DivisionSemiring α
inst✝ : StarRing α
s : Set α
⊢ s⁻¹⋆ = s⋆⁻¹

Next tactic:
ext
protected theorem star_inv' [DivisionSemiring α] [StarRing α] (s : Set α) : s⁻¹⋆ = s⋆⁻¹ := by
  ext
  

Proof state:
case h
α : Type u_1
s✝ t : Set α
a : α
inst✝¹ : DivisionSemiring α
inst✝ : StarRing α
s : Set α
x✝ : α
⊢ x✝ ∈ s⁻¹⋆ ↔ x✝ ∈ s⋆⁻¹

Next tactic:
simp only [mem_star, mem_inv, star_inv']
@[simp]
lemma StarMemClass.star_coe_eq {S α : Type*} [InvolutiveStar α] [SetLike S α]
    [StarMemClass S α] (s : S) : star (s : Set α) = s := by
  

Proof state:
S : Type u_1
α : Type u_2
inst✝² : InvolutiveStar α
inst✝¹ : SetLike S α
inst✝ : StarMemClass S α
s : S
⊢ star ↑s = ↑s

Next tactic:
ext x
@[simp]
lemma StarMemClass.star_coe_eq {S α : Type*} [InvolutiveStar α] [SetLike S α]
    [StarMemClass S α] (s : S) : star (s : Set α) = s := by
  ext x
  

Proof state:
case h
S : Type u_1
α : Type u_2
inst✝² : InvolutiveStar α
inst✝¹ : SetLike S α
inst✝ : StarMemClass S α
s : S
x : α
⊢ x ∈ star ↑s ↔ x ∈ ↑s

Next tactic:
simp only [Set.mem_star, SetLike.mem_coe]
@[simp]
lemma StarMemClass.star_coe_eq {S α : Type*} [InvolutiveStar α] [SetLike S α]
    [StarMemClass S α] (s : S) : star (s : Set α) = s := by
  ext x
  simp only [Set.mem_star, SetLike.mem_coe]
  

Proof state:
case h
S : Type u_1
α : Type u_2
inst✝² : InvolutiveStar α
inst✝¹ : SetLike S α
inst✝ : StarMemClass S α
s : S
x : α
⊢ star x ∈ s ↔ x ∈ s

Next tactic:
exact ⟨by simpa only [star_star] using star_mem (s := s) (r := star x), star_mem⟩
@[simp]
lemma StarMemClass.star_coe_eq {S α : Type*} [InvolutiveStar α] [SetLike S α]
    [StarMemClass S α] (s : S) : star (s : Set α) = s := by
  ext x
  simp only [Set.mem_star, SetLike.mem_coe]
  exact ⟨by 

Proof state:
S : Type u_1
α : Type u_2
inst✝² : InvolutiveStar α
inst✝¹ : SetLike S α
inst✝ : StarMemClass S α
s : S
x : α
⊢ star x ∈ s → x ∈ s

Next tactic:
simpa only [star_star] using star_mem (s := s) (r := star x)
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
⊢ IsLocallySurjective T ↔ ∀ (x : ↑X), Function.Surjective ⇑((stalkFunctor C x).map T)

Next tactic:
constructor
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> 

Proof state:
case mp
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
⊢ IsLocallySurjective T → ∀ (x : ↑X), Function.Surjective ⇑((stalkFunctor C x).map T)

Next tactic:
intro hT
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> 

Proof state:
case mpr
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
⊢ (∀ (x : ↑X), Function.Surjective ⇑((stalkFunctor C x).map T)) → IsLocallySurjective T

Next tactic:
intro hT