l3lab/ntp-mathlib huggingface dataset:
@[to_additive]
theorem mulSupport_extend_one {f : α → M} {g : α → N} (hf : f.Injective) :
    mulSupport (f.extend g 1) = f '' mulSupport g :=
  mulSupport_extend_one_subset.antisymm <| by
    

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
f : α → M
g : α → N
hf : Injective f
⊢ f '' mulSupport g ⊆ mulSupport (extend f g 1)

Next tactic:
rintro _ ⟨x, hx, rfl⟩
@[to_additive]
theorem mulSupport_extend_one {f : α → M} {g : α → N} (hf : f.Injective) :
    mulSupport (f.extend g 1) = f '' mulSupport g :=
  mulSupport_extend_one_subset.antisymm <| by
    rintro _ ⟨x, hx, rfl⟩; 

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
f : α → M
g : α → N
hf : Injective f
x : α
hx : x ∈ mulSupport g
⊢ f x ∈ mulSupport (extend f g 1)

Next tactic:
rwa [mem_mulSupport, hf.extend_apply]
@[to_additive]
theorem mulSupport_disjoint_iff {f : α → M} {s : Set α} :
    Disjoint (mulSupport f) s ↔ EqOn f 1 s := by
  

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
f : α → M
s : Set α
⊢ Disjoint (mulSupport f) s ↔ EqOn f 1 s

Next tactic:
simp_rw [← subset_compl_iff_disjoint_right, mulSupport_subset_iff', not_mem_compl_iff, EqOn,
    Pi.one_apply]
@[to_additive]
theorem disjoint_mulSupport_iff {f : α → M} {s : Set α} :
    Disjoint s (mulSupport f) ↔ EqOn f 1 s := by
  

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
f : α → M
s : Set α
⊢ Disjoint s (mulSupport f) ↔ EqOn f 1 s

Next tactic:
rw [disjoint_comm, mulSupport_disjoint_iff]
@[to_additive (attr := simp)]
theorem mulSupport_eq_empty_iff {f : α → M} : mulSupport f = ∅ ↔ f = 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
f : α → M
⊢ mulSupport f = ∅ ↔ f = 1

Next tactic:
simp_rw [← subset_empty_iff, mulSupport_subset_iff', funext_iff]
@[to_additive (attr := simp)]
theorem mulSupport_eq_empty_iff {f : α → M} : mulSupport f = ∅ ↔ f = 1 := by
  simp_rw [← subset_empty_iff, mulSupport_subset_iff', funext_iff]
  

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
f : α → M
⊢ (∀ x ∉ ∅, f x = 1) ↔ ∀ (a : α), f a = OfNat.ofNat 1 a

Next tactic:
simp
@[to_additive (attr := simp)]
theorem mulSupport_nonempty_iff {f : α → M} : (mulSupport f).Nonempty ↔ f ≠ 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
f : α → M
⊢ Set.Nonempty (mulSupport f) ↔ f ≠ 1

Next tactic:
rw [nonempty_iff_ne_empty, Ne.def, mulSupport_eq_empty_iff]
@[to_additive]
theorem range_subset_insert_image_mulSupport (f : α → M) :
    range f ⊆ insert 1 (f '' mulSupport f) := by
  

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
f : α → M
⊢ range f ⊆ insert 1 (f '' mulSupport f)

Next tactic:
simpa only [range_subset_iff, mem_insert_iff, or_iff_not_imp_left] using
    fun x (hx : x ∈ mulSupport f) => mem_image_of_mem f hx
@[to_additive]
lemma range_eq_image_or_of_mulSupport_subset {f : α → M} {k : Set α} (h : mulSupport f ⊆ k) :
    range f = f '' k ∨ range f = insert 1 (f '' k) := by
  

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
f : α → M
k : Set α
h : mulSupport f ⊆ k
⊢ range f = f '' k ∨ range f = insert 1 (f '' k)

Next tactic:
apply (wcovby_insert _ _).eq_or_eq (image_subset_range _ _)
@[to_additive]
lemma range_eq_image_or_of_mulSupport_subset {f : α → M} {k : Set α} (h : mulSupport f ⊆ k) :
    range f = f '' k ∨ range f = insert 1 (f '' k) := by
  apply (wcovby_insert _ _).eq_or_eq (image_subset_range _ _)
  

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
f : α → M
k : Set α
h : mulSupport f ⊆ k
⊢ range f ≤ insert 1 (f '' k)

Next tactic:
exact (range_subset_insert_image_mulSupport f).trans (insert_subset_insert (image_subset f h))
@[to_additive]
theorem mulSupport_const {c : M} (hc : c ≠ 1) : (mulSupport fun _ : α => c) = Set.univ := by
  

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
c : M
hc : c ≠ 1
⊢ (mulSupport fun x => c) = univ

Next tactic:
ext x
@[to_additive]
theorem mulSupport_const {c : M} (hc : c ≠ 1) : (mulSupport fun _ : α => c) = Set.univ := by
  ext x
  

Proof state:
case h
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
c : M
hc : c ≠ 1
x : α
⊢ (x ∈ mulSupport fun x => c) ↔ x ∈ univ

Next tactic:
simp [hc]
@[to_additive]
theorem mulSupport_binop_subset (op : M → N → P) (op1 : op 1 1 = 1) (f : α → M) (g : α → N) :
    (mulSupport fun x => op (f x) (g x)) ⊆ mulSupport f ∪ mulSupport g := fun x hx =>
  not_or_of_imp fun hf hg => hx <| by 

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
op : M → N → P
op1 : op 1 1 = 1
f : α → M
g : α → N
x : α
hx : x ∈ mulSupport fun x => op (f x) (g x)
hf : f x = 1
hg : g x = 1
⊢ (fun x => op (f x) (g x)) x = 1

Next tactic:
simp only [hf, hg, op1]
@[to_additive]
theorem mulSupport_comp_subset {g : M → N} (hg : g 1 = 1) (f : α → M) :
    mulSupport (g ∘ f) ⊆ mulSupport f := fun x => mt fun h => by 

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
g : M → N
hg : g 1 = 1
f : α → M
x : α
h : f x = 1
⊢ (g ∘ f) x = 1

Next tactic:
simp only [(· ∘ ·), *]
@[to_additive]
theorem mulSupport_comp_eq_of_range_subset {g : M → N} {f : α → M}
    (hg : ∀ {x}, x ∈ range f → (g x = 1 ↔ x = 1)) :
    mulSupport (g ∘ f) = mulSupport f :=
  Set.ext fun x ↦ not_congr <| by 

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
g : M → N
f : α → M
hg : ∀ {x : M}, x ∈ range f → (g x = 1 ↔ x = 1)
x : α
⊢ (g ∘ f) x = 1 ↔ f x = 1

Next tactic:
rw [Function.comp, hg (mem_range_self x)]
@[to_additive support_prod_mk]
theorem mulSupport_prod_mk (f : α → M) (g : α → N) :
    (mulSupport fun x => (f x, g x)) = mulSupport f ∪ mulSupport g :=
  Set.ext fun x => by
    

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
f : α → M
g : α → N
x : α
⊢ (x ∈ mulSupport fun x => (f x, g x)) ↔ x ∈ mulSupport f ∪ mulSupport g

Next tactic:
simp only [mulSupport, not_and_or, mem_union, mem_setOf_eq, Prod.mk_eq_one, Ne.def]
@[to_additive support_prod_mk']
theorem mulSupport_prod_mk' (f : α → M × N) :
    mulSupport f = (mulSupport fun x => (f x).1) ∪ mulSupport fun x => (f x).2 := by
  

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
f : α → M × N
⊢ mulSupport f = (mulSupport fun x => (f x).1) ∪ mulSupport fun x => (f x).2

Next tactic:
simp only [← mulSupport_prod_mk]
@[to_additive]
theorem mulSupport_along_fiber_subset (f : α × β → M) (a : α) :
    (mulSupport fun b => f (a, b)) ⊆ (mulSupport f).image Prod.snd :=
  fun x hx => ⟨(a, x), by 

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝² : One M
inst✝¹ : One N
inst✝ : One P
f : α × β → M
a : α
x : β
hx : x ∈ mulSupport fun b => f (a, b)
⊢ (a, x) ∈ mulSupport f ∧ (a, x).2 = x

Next tactic:
simpa using hx
@[to_additive]
theorem mulSupport_pow [Monoid M] (f : α → M) (n : ℕ) :
    (mulSupport fun x => f x ^ n) ⊆ mulSupport f := by
  

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝ : Monoid M
f : α → M
n : ℕ
⊢ (mulSupport fun x => f x ^ n) ⊆ mulSupport f

Next tactic:
induction' n with n hfn
@[to_additive]
theorem mulSupport_pow [Monoid M] (f : α → M) (n : ℕ) :
    (mulSupport fun x => f x ^ n) ⊆ mulSupport f := by
  induction' n with n hfn
  · 

Proof state:
case zero
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝ : Monoid M
f : α → M
⊢ (mulSupport fun x => f x ^ Nat.zero) ⊆ mulSupport f

Next tactic:
simp [pow_zero, mulSupport_one]
@[to_additive]
theorem mulSupport_pow [Monoid M] (f : α → M) (n : ℕ) :
    (mulSupport fun x => f x ^ n) ⊆ mulSupport f := by
  induction' n with n hfn
  · simp [pow_zero, mulSupport_one]
  · 

Proof state:
case succ
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝ : Monoid M
f : α → M
n : ℕ
hfn : (mulSupport fun x => f x ^ n) ⊆ mulSupport f
⊢ (mulSupport fun x => f x ^ Nat.succ n) ⊆ mulSupport f

Next tactic:
simpa only [pow_succ] using (mulSupport_mul f _).trans (union_subset Subset.rfl hfn)
@[to_additive]
theorem mulSupport_mul_inv : (mulSupport fun x => f x * (g x)⁻¹) ⊆ mulSupport f ∪ mulSupport g :=
  mulSupport_binop_subset (fun a b => a * b⁻¹) (by 

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝ : DivisionMonoid G
f g : α → G
⊢ (fun a b => a * b⁻¹) 1 1 = 1

Next tactic:
simp
@[simp]
theorem support_mul [MulZeroClass R] [NoZeroDivisors R] (f g : α → R) :
    (support fun x => f x * g x) = support f ∩ support g := ext fun x ↦ by 

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝¹ : MulZeroClass R
inst✝ : NoZeroDivisors R
f g : α → R
x : α
⊢ (x ∈ support fun x => f x * g x) ↔ x ∈ support f ∩ support g

Next tactic:
simp [not_or]
theorem support_mul_subset_left [MulZeroClass R] (f g : α → R) :
    (support fun x => f x * g x) ⊆ support f := fun x hfg hf => hfg <| by 

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝ : MulZeroClass R
f g : α → R
x : α
hfg : x ∈ support fun x => f x * g x
hf : f x = 0
⊢ (fun x => f x * g x) x = 0

Next tactic:
simp only [hf, zero_mul]
theorem support_mul_subset_right [MulZeroClass R] (f g : α → R) :
    (support fun x => f x * g x) ⊆ support g := fun x hfg hg => hfg <| by 

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝ : MulZeroClass R
f g : α → R
x : α
hfg : x ∈ support fun x => f x * g x
hg : g x = 0
⊢ (fun x => f x * g x) x = 0

Next tactic:
simp only [hg, mul_zero]
@[simp]
theorem support_div [GroupWithZero G₀] (f g : α → G₀) :
    (support fun x => f x / g x) = support f ∩ support g := by 

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝ : GroupWithZero G₀
f g : α → G₀
⊢ (support fun x => f x / g x) = support f ∩ support g

Next tactic:
simp [div_eq_mul_inv]
theorem mulSupport_one_sub' [One R] [AddGroup R] (f : α → R) : mulSupport (1 - f) = support f := by
  

Proof state:
α : Type u_1
β : Type u_2
A : Type u_3
B : Type u_4
M : Type u_5
N : Type u_6
P : Type u_7
R : Type u_8
S : Type u_9
G : Type u_10
M₀ : Type u_11
G₀ : Type u_12
ι : Sort u_13
inst✝¹ : One R
inst✝ : AddGroup R
f : α → R
⊢ mulSupport (1 - f) = support f

Next tactic:
rw [sub_eq_add_neg, mulSupport_one_add', support_neg']
@[to_additive]
theorem image_inter_mulSupport_eq {s : Set β} {g : β → α} :
    g '' s ∩ mulSupport f = g '' (s ∩ mulSupport (f ∘ g)) := by
  

Proof state:
α : Type u_1
β : Type u_2
M : Type u_3
inst✝ : One M
f : α → M
s : Set β
g : β → α
⊢ g '' s ∩ mulSupport f = g '' (s ∩ mulSupport (f ∘ g))

Next tactic:
rw [mulSupport_comp_eq_preimage f g, image_inter_preimage]
@[to_additive]
theorem mulSupport_mulSingle_one : mulSupport (mulSingle a (1 : B)) = ∅ := by 

Proof state:
A : Type u_1
B : Type u_2
inst✝¹ : DecidableEq A
inst✝ : One B
a : A
b : B
⊢ mulSupport (mulSingle a 1) = ∅

Next tactic:
simp
@[to_additive (attr := simp)]
theorem mulSupport_mulSingle_of_ne (h : b ≠ 1) : mulSupport (mulSingle a b) = {a} :=
  mulSupport_mulSingle_subset.antisymm fun x (hx : x = a) => by
    

Proof state:
A : Type u_1
B : Type u_2
inst✝¹ : DecidableEq A
inst✝ : One B
a : A
b : B
h : b ≠ 1
x : A
hx : x = a
⊢ x ∈ mulSupport (mulSingle a b)

Next tactic:
rwa [mem_mulSupport, hx, mulSingle_eq_same]
@[to_additive]
theorem mulSupport_mulSingle [DecidableEq B] :
    mulSupport (mulSingle a b) = if b = 1 then ∅ else {a} := by 

Proof state:
A : Type u_1
B : Type u_2
inst✝² : DecidableEq A
inst✝¹ : One B
a : A
b : B
inst✝ : DecidableEq B
⊢ mulSupport (mulSingle a b) = if b = 1 then ∅ else {a}

Next tactic:
split_ifs with h
@[to_additive]
theorem mulSupport_mulSingle [DecidableEq B] :
    mulSupport (mulSingle a b) = if b = 1 then ∅ else {a} := by split_ifs with h <;> 

Proof state:
case pos
A : Type u_1
B : Type u_2
inst✝² : DecidableEq A
inst✝¹ : One B
a : A
b : B
inst✝ : DecidableEq B
h : b = 1
⊢ mulSupport (mulSingle a b) = ∅

Next tactic:
simp [h]
@[to_additive]
theorem mulSupport_mulSingle [DecidableEq B] :
    mulSupport (mulSingle a b) = if b = 1 then ∅ else {a} := by split_ifs with h <;> 

Proof state:
case neg
A : Type u_1
B : Type u_2
inst✝² : DecidableEq A
inst✝¹ : One B
a : A
b : B
inst✝ : DecidableEq B
h : ¬b = 1
⊢ mulSupport (mulSingle a b) = {a}

Next tactic:
simp [h]
@[to_additive]
theorem mulSupport_mulSingle_disjoint {b' : B} (hb : b ≠ 1) (hb' : b' ≠ 1) {i j : A} :
    Disjoint (mulSupport (mulSingle i b)) (mulSupport (mulSingle j b')) ↔ i ≠ j := by
  

Proof state:
A : Type u_1
B : Type u_2
inst✝¹ : DecidableEq A
inst✝ : One B
a : A
b b' : B
hb : b ≠ 1
hb' : b' ≠ 1
i j : A
⊢ Disjoint (mulSupport (mulSingle i b)) (mulSupport (mulSingle j b')) ↔ i ≠ j

Next tactic:
rw [mulSupport_mulSingle_of_ne hb, mulSupport_mulSingle_of_ne hb', disjoint_singleton]
/-- Composition of morphisms of `Pointed`. -/
@[simps]
def comp {X Y Z : Pointed.{u}} (f : Pointed.Hom X Y) (g : Pointed.Hom Y Z) : Pointed.Hom X Z :=
  ⟨g.toFun ∘ f.toFun, by 

Proof state:
α : Type u_1
β : Type u_2
X Y Z : Pointed
f : Pointed.Hom X Y
g : Pointed.Hom Y Z
⊢ (g.toFun ∘ f.toFun) X.point = Z.point

Next tactic:
rw [Function.comp_apply, f.map_point, g.map_point]
/-- `typeToPointed` is the free functor. -/
def typeToPointedForgetAdjunction : typeToPointed ⊣ forget Pointed :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => f.toFun ∘ Option.some
          invFun := fun f => ⟨fun o => o.elim Y.point f, rfl⟩
          left_inv := fun f => by
            

Proof state:
α : Type u_1
β : Type u_2
X : Type ?u.7456
Y : Pointed
f : typeToPointed.obj X ⟶ Y
⊢ (fun f =>
        { toFun := fun o => Option.elim o Y.point f,
          map_point :=
            (_ :
              (fun o => Option.elim o Y.point f) (typeToPointed.obj X).point =
                (fun o => Option.elim o Y.point f) (typeToPointed.obj X).point) })
      ((fun f => f.toFun ∘ some) f) =
    f

Next tactic:
apply Pointed.Hom.ext
/-- `typeToPointed` is the free functor. -/
def typeToPointedForgetAdjunction : typeToPointed ⊣ forget Pointed :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => f.toFun ∘ Option.some
          invFun := fun f => ⟨fun o => o.elim Y.point f, rfl⟩
          left_inv := fun f => by
            apply Pointed.Hom.ext
            

Proof state:
case toFun
α : Type u_1
β : Type u_2
X : Type ?u.7456
Y : Pointed
f : typeToPointed.obj X ⟶ Y
⊢ ((fun f =>
          { toFun := fun o => Option.elim o Y.point f,
            map_point :=
              (_ :
                (fun o => Option.elim o Y.point f) (typeToPointed.obj X).point =
                  (fun o => Option.elim o Y.point f) (typeToPointed.obj X).point) })
        ((fun f => f.toFun ∘ some) f)).toFun =
    f.toFun

Next tactic:
funext x
/-- `typeToPointed` is the free functor. -/
def typeToPointedForgetAdjunction : typeToPointed ⊣ forget Pointed :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => f.toFun ∘ Option.some
          invFun := fun f => ⟨fun o => o.elim Y.point f, rfl⟩
          left_inv := fun f => by
            apply Pointed.Hom.ext
            funext x
            

Proof state:
case toFun.h
α : Type u_1
β : Type u_2
X : Type ?u.7456
Y : Pointed
f : typeToPointed.obj X ⟶ Y
x : (typeToPointed.obj X).X
⊢ Pointed.Hom.toFun
      ((fun f =>
          { toFun := fun o => Option.elim o Y.point f,
            map_point :=
              (_ :
                (fun o => Option.elim o Y.point f) (typeToPointed.obj X).point =
                  (fun o => Option.elim o Y.point f) (typeToPointed.obj X).point) })
        ((fun f => f.toFun ∘ some) f))
      x =
    Pointed.Hom.toFun f x

Next tactic:
cases x
/-- `typeToPointed` is the free functor. -/
def typeToPointedForgetAdjunction : typeToPointed ⊣ forget Pointed :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => f.toFun ∘ Option.some
          invFun := fun f => ⟨fun o => o.elim Y.point f, rfl⟩
          left_inv := fun f => by
            apply Pointed.Hom.ext
            funext x
            cases x
            · 

Proof state:
case toFun.h.none
α : Type u_1
β : Type u_2
X : Type ?u.7456
Y : Pointed
f : typeToPointed.obj X ⟶ Y
⊢ Pointed.Hom.toFun
      ((fun f =>
          { toFun := fun o => Option.elim o Y.point f,
            map_point :=
              (_ :
                (fun o => Option.elim o Y.point f) (typeToPointed.obj X).point =
                  (fun o => Option.elim o Y.point f) (typeToPointed.obj X).point) })
        ((fun f => f.toFun ∘ some) f))
      none =
    Pointed.Hom.toFun f none

Next tactic:
exact f.map_point.symm
/-- `typeToPointed` is the free functor. -/
def typeToPointedForgetAdjunction : typeToPointed ⊣ forget Pointed :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => f.toFun ∘ Option.some
          invFun := fun f => ⟨fun o => o.elim Y.point f, rfl⟩
          left_inv := fun f => by
            apply Pointed.Hom.ext
            funext x
            cases x
            · exact f.map_point.symm
            · 

Proof state:
case toFun.h.some
α : Type u_1
β : Type u_2
X : Type ?u.7456
Y : Pointed
f : typeToPointed.obj X ⟶ Y
val✝ : X
⊢ Pointed.Hom.toFun
      ((fun f =>
          { toFun := fun o => Option.elim o Y.point f,
            map_point :=
              (_ :
                (fun o => Option.elim o Y.point f) (typeToPointed.obj X).point =
                  (fun o => Option.elim o Y.point f) (typeToPointed.obj X).point) })
        ((fun f => f.toFun ∘ some) f))
      (some val✝) =
    Pointed.Hom.toFun f (some val✝)

Next tactic:
rfl
instance Monic.decidable [DecidableEq R] : Decidable (Monic p) := by 

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : DecidableEq R
⊢ Decidable (Monic p)

Next tactic:
unfold Monic
instance Monic.decidable [DecidableEq R] : Decidable (Monic p) := by unfold Monic; 

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : DecidableEq R
⊢ Decidable (leadingCoeff p = 1)

Next tactic:
infer_instance
@[nontriviality]
theorem degree_of_subsingleton [Subsingleton R] : degree p = ⊥ := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Subsingleton R
⊢ degree p = ⊥

Next tactic:
rw [Subsingleton.elim p 0, degree_zero]
@[nontriviality]
theorem natDegree_of_subsingleton [Subsingleton R] : natDegree p = 0 := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Subsingleton R
⊢ natDegree p = 0

Next tactic:
rw [Subsingleton.elim p 0, natDegree_zero]
theorem degree_eq_natDegree (hp : p ≠ 0) : degree p = (natDegree p : WithBot ℕ) := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
hp : p ≠ 0
⊢ degree p = ↑(natDegree p)

Next tactic:
let ⟨n, hn⟩ := not_forall.1 (mt Option.eq_none_iff_forall_not_mem.2 (mt degree_eq_bot.1 hp))
theorem degree_eq_natDegree (hp : p ≠ 0) : degree p = (natDegree p : WithBot ℕ) := by
  let ⟨n, hn⟩ := not_forall.1 (mt Option.eq_none_iff_forall_not_mem.2 (mt degree_eq_bot.1 hp))
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
hp : p ≠ 0
n : ℕ
hn : ¬n ∉ degree p
⊢ degree p = ↑(natDegree p)

Next tactic:
have hn : degree p = some n := Classical.not_not.1 hn
theorem degree_eq_natDegree (hp : p ≠ 0) : degree p = (natDegree p : WithBot ℕ) := by
  let ⟨n, hn⟩ := not_forall.1 (mt Option.eq_none_iff_forall_not_mem.2 (mt degree_eq_bot.1 hp))
  have hn : degree p = some n := Classical.not_not.1 hn
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
hp : p ≠ 0
n : ℕ
hn✝ : ¬n ∉ degree p
hn : degree p = Option.some n
⊢ degree p = ↑(natDegree p)

Next tactic:
rw [natDegree, hn]
theorem degree_eq_natDegree (hp : p ≠ 0) : degree p = (natDegree p : WithBot ℕ) := by
  let ⟨n, hn⟩ := not_forall.1 (mt Option.eq_none_iff_forall_not_mem.2 (mt degree_eq_bot.1 hp))
  have hn : degree p = some n := Classical.not_not.1 hn
  rw [natDegree, hn]; 

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
hp : p ≠ 0
n : ℕ
hn✝ : ¬n ∉ degree p
hn : degree p = Option.some n
⊢ Option.some n = ↑(WithBot.unbot' 0 (Option.some n))

Next tactic:
rfl
theorem degree_eq_iff_natDegree_eq {p : R[X]} {n : ℕ} (hp : p ≠ 0) :
    p.degree = n ↔ p.natDegree = n := by 

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
hp : p ≠ 0
⊢ degree p = ↑n ↔ natDegree p = n

Next tactic:
rw [degree_eq_natDegree hp]