l3lab/ntp-mathlib huggingface dataset:
theorem Prime.dvd_of_pow_dvd_pow_mul_pow_of_square_not_dvd [CancelCommMonoidWithZero α] {p a b : α}
    {n : ℕ} (hp : Prime p) (hpow : p ^ n.succ ∣ a ^ n.succ * b ^ n) (hb : ¬p ^ 2 ∣ b) : p ∣ a := by
  -- Suppose `p ∣ b`, write `b = p * x` and `hy : a ^ n.succ * b ^ n = p ^ n.succ * y`.
  cases' hp.dvd_or_dvd ((dvd_pow_self p (Nat.succ_ne_zero n)).trans hpow) with H hbdiv
  · exact hp.dvd_of_dvd_pow H
  obtain ⟨x, rfl⟩ := hp.dvd_of_dvd_pow hbdiv
  obtain ⟨y, hy⟩ := hpow
  -- Then we can divide out a common factor of `p ^ n` from the equation `hy`.
  

Proof state:
case inr.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : CancelCommMonoidWithZero α
p a : α
n : ℕ
hp : Prime p
x : α
hb : ¬p ^ 2 ∣ p * x
hbdiv : p ∣ (p * x) ^ n
y : α
hy : a ^ Nat.succ n * (p * x) ^ n = p ^ Nat.succ n * y
⊢ p ∣ a

Next tactic:
have : a ^ n.succ * x ^ n = p * y := by
    refine' mul_left_cancel₀ (pow_ne_zero n hp.ne_zero) _
    rw [← mul_assoc _ p, ← pow_succ', ← hy, mul_pow, ← mul_assoc (a ^ n.succ), mul_comm _ (p ^ n),
      mul_assoc]
theorem Prime.dvd_of_pow_dvd_pow_mul_pow_of_square_not_dvd [CancelCommMonoidWithZero α] {p a b : α}
    {n : ℕ} (hp : Prime p) (hpow : p ^ n.succ ∣ a ^ n.succ * b ^ n) (hb : ¬p ^ 2 ∣ b) : p ∣ a := by
  -- Suppose `p ∣ b`, write `b = p * x` and `hy : a ^ n.succ * b ^ n = p ^ n.succ * y`.
  cases' hp.dvd_or_dvd ((dvd_pow_self p (Nat.succ_ne_zero n)).trans hpow) with H hbdiv
  · exact hp.dvd_of_dvd_pow H
  obtain ⟨x, rfl⟩ := hp.dvd_of_dvd_pow hbdiv
  obtain ⟨y, hy⟩ := hpow
  -- Then we can divide out a common factor of `p ^ n` from the equation `hy`.
  have : a ^ n.succ * x ^ n = p * y := by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : CancelCommMonoidWithZero α
p a : α
n : ℕ
hp : Prime p
x : α
hb : ¬p ^ 2 ∣ p * x
hbdiv : p ∣ (p * x) ^ n
y : α
hy : a ^ Nat.succ n * (p * x) ^ n = p ^ Nat.succ n * y
⊢ a ^ Nat.succ n * x ^ n = p * y

Next tactic:
refine' mul_left_cancel₀ (pow_ne_zero n hp.ne_zero) _
theorem Prime.dvd_of_pow_dvd_pow_mul_pow_of_square_not_dvd [CancelCommMonoidWithZero α] {p a b : α}
    {n : ℕ} (hp : Prime p) (hpow : p ^ n.succ ∣ a ^ n.succ * b ^ n) (hb : ¬p ^ 2 ∣ b) : p ∣ a := by
  -- Suppose `p ∣ b`, write `b = p * x` and `hy : a ^ n.succ * b ^ n = p ^ n.succ * y`.
  cases' hp.dvd_or_dvd ((dvd_pow_self p (Nat.succ_ne_zero n)).trans hpow) with H hbdiv
  · exact hp.dvd_of_dvd_pow H
  obtain ⟨x, rfl⟩ := hp.dvd_of_dvd_pow hbdiv
  obtain ⟨y, hy⟩ := hpow
  -- Then we can divide out a common factor of `p ^ n` from the equation `hy`.
  have : a ^ n.succ * x ^ n = p * y := by
    refine' mul_left_cancel₀ (pow_ne_zero n hp.ne_zero) _
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : CancelCommMonoidWithZero α
p a : α
n : ℕ
hp : Prime p
x : α
hb : ¬p ^ 2 ∣ p * x
hbdiv : p ∣ (p * x) ^ n
y : α
hy : a ^ Nat.succ n * (p * x) ^ n = p ^ Nat.succ n * y
⊢ p ^ n * (a ^ Nat.succ n * x ^ n) = p ^ n * (p * y)

Next tactic:
rw [← mul_assoc _ p, ← pow_succ', ← hy, mul_pow, ← mul_assoc (a ^ n.succ), mul_comm _ (p ^ n),
      mul_assoc]
theorem Prime.dvd_of_pow_dvd_pow_mul_pow_of_square_not_dvd [CancelCommMonoidWithZero α] {p a b : α}
    {n : ℕ} (hp : Prime p) (hpow : p ^ n.succ ∣ a ^ n.succ * b ^ n) (hb : ¬p ^ 2 ∣ b) : p ∣ a := by
  -- Suppose `p ∣ b`, write `b = p * x` and `hy : a ^ n.succ * b ^ n = p ^ n.succ * y`.
  cases' hp.dvd_or_dvd ((dvd_pow_self p (Nat.succ_ne_zero n)).trans hpow) with H hbdiv
  · exact hp.dvd_of_dvd_pow H
  obtain ⟨x, rfl⟩ := hp.dvd_of_dvd_pow hbdiv
  obtain ⟨y, hy⟩ := hpow
  -- Then we can divide out a common factor of `p ^ n` from the equation `hy`.
  have : a ^ n.succ * x ^ n = p * y := by
    refine' mul_left_cancel₀ (pow_ne_zero n hp.ne_zero) _
    rw [← mul_assoc _ p, ← pow_succ', ← hy, mul_pow, ← mul_assoc (a ^ n.succ), mul_comm _ (p ^ n),
      mul_assoc]
  -- So `p ∣ a` (and we're done) or `p ∣ x`, which can't be the case since it implies `p^2 ∣ b`.
  

Proof state:
case inr.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : CancelCommMonoidWithZero α
p a : α
n : ℕ
hp : Prime p
x : α
hb : ¬p ^ 2 ∣ p * x
hbdiv : p ∣ (p * x) ^ n
y : α
hy : a ^ Nat.succ n * (p * x) ^ n = p ^ Nat.succ n * y
this : a ^ Nat.succ n * x ^ n = p * y
⊢ p ∣ a

Next tactic:
refine' hp.dvd_of_dvd_pow ((hp.dvd_or_dvd ⟨_, this⟩).resolve_right fun hdvdx => hb _)
theorem Prime.dvd_of_pow_dvd_pow_mul_pow_of_square_not_dvd [CancelCommMonoidWithZero α] {p a b : α}
    {n : ℕ} (hp : Prime p) (hpow : p ^ n.succ ∣ a ^ n.succ * b ^ n) (hb : ¬p ^ 2 ∣ b) : p ∣ a := by
  -- Suppose `p ∣ b`, write `b = p * x` and `hy : a ^ n.succ * b ^ n = p ^ n.succ * y`.
  cases' hp.dvd_or_dvd ((dvd_pow_self p (Nat.succ_ne_zero n)).trans hpow) with H hbdiv
  · exact hp.dvd_of_dvd_pow H
  obtain ⟨x, rfl⟩ := hp.dvd_of_dvd_pow hbdiv
  obtain ⟨y, hy⟩ := hpow
  -- Then we can divide out a common factor of `p ^ n` from the equation `hy`.
  have : a ^ n.succ * x ^ n = p * y := by
    refine' mul_left_cancel₀ (pow_ne_zero n hp.ne_zero) _
    rw [← mul_assoc _ p, ← pow_succ', ← hy, mul_pow, ← mul_assoc (a ^ n.succ), mul_comm _ (p ^ n),
      mul_assoc]
  -- So `p ∣ a` (and we're done) or `p ∣ x`, which can't be the case since it implies `p^2 ∣ b`.
  refine' hp.dvd_of_dvd_pow ((hp.dvd_or_dvd ⟨_, this⟩).resolve_right fun hdvdx => hb _)
  

Proof state:
case inr.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : CancelCommMonoidWithZero α
p a : α
n : ℕ
hp : Prime p
x : α
hb : ¬p ^ 2 ∣ p * x
hbdiv : p ∣ (p * x) ^ n
y : α
hy : a ^ Nat.succ n * (p * x) ^ n = p ^ Nat.succ n * y
this : a ^ Nat.succ n * x ^ n = p * y
hdvdx : p ∣ x ^ n
⊢ p ^ 2 ∣ p * x

Next tactic:
obtain ⟨z, rfl⟩ := hp.dvd_of_dvd_pow hdvdx
theorem Prime.dvd_of_pow_dvd_pow_mul_pow_of_square_not_dvd [CancelCommMonoidWithZero α] {p a b : α}
    {n : ℕ} (hp : Prime p) (hpow : p ^ n.succ ∣ a ^ n.succ * b ^ n) (hb : ¬p ^ 2 ∣ b) : p ∣ a := by
  -- Suppose `p ∣ b`, write `b = p * x` and `hy : a ^ n.succ * b ^ n = p ^ n.succ * y`.
  cases' hp.dvd_or_dvd ((dvd_pow_self p (Nat.succ_ne_zero n)).trans hpow) with H hbdiv
  · exact hp.dvd_of_dvd_pow H
  obtain ⟨x, rfl⟩ := hp.dvd_of_dvd_pow hbdiv
  obtain ⟨y, hy⟩ := hpow
  -- Then we can divide out a common factor of `p ^ n` from the equation `hy`.
  have : a ^ n.succ * x ^ n = p * y := by
    refine' mul_left_cancel₀ (pow_ne_zero n hp.ne_zero) _
    rw [← mul_assoc _ p, ← pow_succ', ← hy, mul_pow, ← mul_assoc (a ^ n.succ), mul_comm _ (p ^ n),
      mul_assoc]
  -- So `p ∣ a` (and we're done) or `p ∣ x`, which can't be the case since it implies `p^2 ∣ b`.
  refine' hp.dvd_of_dvd_pow ((hp.dvd_or_dvd ⟨_, this⟩).resolve_right fun hdvdx => hb _)
  obtain ⟨z, rfl⟩ := hp.dvd_of_dvd_pow hdvdx
  

Proof state:
case inr.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : CancelCommMonoidWithZero α
p a : α
n : ℕ
hp : Prime p
y z : α
hb : ¬p ^ 2 ∣ p * (p * z)
hbdiv : p ∣ (p * (p * z)) ^ n
hy : a ^ Nat.succ n * (p * (p * z)) ^ n = p ^ Nat.succ n * y
this : a ^ Nat.succ n * (p * z) ^ n = p * y
hdvdx : p ∣ (p * z) ^ n
⊢ p ^ 2 ∣ p * (p * z)

Next tactic:
rw [pow_two, ← mul_assoc]
theorem Prime.dvd_of_pow_dvd_pow_mul_pow_of_square_not_dvd [CancelCommMonoidWithZero α] {p a b : α}
    {n : ℕ} (hp : Prime p) (hpow : p ^ n.succ ∣ a ^ n.succ * b ^ n) (hb : ¬p ^ 2 ∣ b) : p ∣ a := by
  -- Suppose `p ∣ b`, write `b = p * x` and `hy : a ^ n.succ * b ^ n = p ^ n.succ * y`.
  cases' hp.dvd_or_dvd ((dvd_pow_self p (Nat.succ_ne_zero n)).trans hpow) with H hbdiv
  · exact hp.dvd_of_dvd_pow H
  obtain ⟨x, rfl⟩ := hp.dvd_of_dvd_pow hbdiv
  obtain ⟨y, hy⟩ := hpow
  -- Then we can divide out a common factor of `p ^ n` from the equation `hy`.
  have : a ^ n.succ * x ^ n = p * y := by
    refine' mul_left_cancel₀ (pow_ne_zero n hp.ne_zero) _
    rw [← mul_assoc _ p, ← pow_succ', ← hy, mul_pow, ← mul_assoc (a ^ n.succ), mul_comm _ (p ^ n),
      mul_assoc]
  -- So `p ∣ a` (and we're done) or `p ∣ x`, which can't be the case since it implies `p^2 ∣ b`.
  refine' hp.dvd_of_dvd_pow ((hp.dvd_or_dvd ⟨_, this⟩).resolve_right fun hdvdx => hb _)
  obtain ⟨z, rfl⟩ := hp.dvd_of_dvd_pow hdvdx
  rw [pow_two, ← mul_assoc]
  

Proof state:
case inr.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : CancelCommMonoidWithZero α
p a : α
n : ℕ
hp : Prime p
y z : α
hb : ¬p ^ 2 ∣ p * (p * z)
hbdiv : p ∣ (p * (p * z)) ^ n
hy : a ^ Nat.succ n * (p * (p * z)) ^ n = p ^ Nat.succ n * y
this : a ^ Nat.succ n * (p * z) ^ n = p * y
hdvdx : p ∣ (p * z) ^ n
⊢ p * p ∣ p * p * z

Next tactic:
exact dvd_mul_right _ _
theorem prime_pow_succ_dvd_mul {α : Type*} [CancelCommMonoidWithZero α] {p x y : α} (h : Prime p)
    {i : ℕ} (hxy : p ^ (i + 1) ∣ x * y) : p ^ (i + 1) ∣ x ∨ p ∣ y := by
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : CancelCommMonoidWithZero α
p x y : α
h : Prime p
i : ℕ
hxy : p ^ (i + 1) ∣ x * y
⊢ p ^ (i + 1) ∣ x ∨ p ∣ y

Next tactic:
rw [or_iff_not_imp_right]
theorem prime_pow_succ_dvd_mul {α : Type*} [CancelCommMonoidWithZero α] {p x y : α} (h : Prime p)
    {i : ℕ} (hxy : p ^ (i + 1) ∣ x * y) : p ^ (i + 1) ∣ x ∨ p ∣ y := by
  rw [or_iff_not_imp_right]
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : CancelCommMonoidWithZero α
p x y : α
h : Prime p
i : ℕ
hxy : p ^ (i + 1) ∣ x * y
⊢ ¬p ∣ y → p ^ (i + 1) ∣ x

Next tactic:
intro hy
theorem prime_pow_succ_dvd_mul {α : Type*} [CancelCommMonoidWithZero α] {p x y : α} (h : Prime p)
    {i : ℕ} (hxy : p ^ (i + 1) ∣ x * y) : p ^ (i + 1) ∣ x ∨ p ∣ y := by
  rw [or_iff_not_imp_right]
  intro hy
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : CancelCommMonoidWithZero α
p x y : α
h : Prime p
i : ℕ
hxy : p ^ (i + 1) ∣ x * y
hy : ¬p ∣ y
⊢ p ^ (i + 1) ∣ x

Next tactic:
induction' i with i ih generalizing x
theorem prime_pow_succ_dvd_mul {α : Type*} [CancelCommMonoidWithZero α] {p x y : α} (h : Prime p)
    {i : ℕ} (hxy : p ^ (i + 1) ∣ x * y) : p ^ (i + 1) ∣ x ∨ p ∣ y := by
  rw [or_iff_not_imp_right]
  intro hy
  induction' i with i ih generalizing x
  · 

Proof state:
case zero
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : CancelCommMonoidWithZero α
p y : α
h : Prime p
hy : ¬p ∣ y
x : α
hxy : p ^ (Nat.zero + 1) ∣ x * y
⊢ p ^ (Nat.zero + 1) ∣ x

Next tactic:
rw [pow_one] at hxy ⊢
theorem prime_pow_succ_dvd_mul {α : Type*} [CancelCommMonoidWithZero α] {p x y : α} (h : Prime p)
    {i : ℕ} (hxy : p ^ (i + 1) ∣ x * y) : p ^ (i + 1) ∣ x ∨ p ∣ y := by
  rw [or_iff_not_imp_right]
  intro hy
  induction' i with i ih generalizing x
  · rw [pow_one] at hxy ⊢
    

Proof state:
case zero
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : CancelCommMonoidWithZero α
p y : α
h : Prime p
hy : ¬p ∣ y
x : α
hxy : p ∣ x * y
⊢ p ∣ x

Next tactic:
exact (h.dvd_or_dvd hxy).resolve_right hy
theorem prime_pow_succ_dvd_mul {α : Type*} [CancelCommMonoidWithZero α] {p x y : α} (h : Prime p)
    {i : ℕ} (hxy : p ^ (i + 1) ∣ x * y) : p ^ (i + 1) ∣ x ∨ p ∣ y := by
  rw [or_iff_not_imp_right]
  intro hy
  induction' i with i ih generalizing x
  · rw [pow_one] at hxy ⊢
    exact (h.dvd_or_dvd hxy).resolve_right hy
  

Proof state:
case succ
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : CancelCommMonoidWithZero α
p y : α
h : Prime p
hy : ¬p ∣ y
i : ℕ
ih : ∀ {x : α}, p ^ (i + 1) ∣ x * y → p ^ (i + 1) ∣ x
x : α
hxy : p ^ (Nat.succ i + 1) ∣ x * y
⊢ p ^ (Nat.succ i + 1) ∣ x

Next tactic:
rw [pow_succ] at hxy ⊢
theorem prime_pow_succ_dvd_mul {α : Type*} [CancelCommMonoidWithZero α] {p x y : α} (h : Prime p)
    {i : ℕ} (hxy : p ^ (i + 1) ∣ x * y) : p ^ (i + 1) ∣ x ∨ p ∣ y := by
  rw [or_iff_not_imp_right]
  intro hy
  induction' i with i ih generalizing x
  · rw [pow_one] at hxy ⊢
    exact (h.dvd_or_dvd hxy).resolve_right hy
  rw [pow_succ] at hxy ⊢
  

Proof state:
case succ
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : CancelCommMonoidWithZero α
p y : α
h : Prime p
hy : ¬p ∣ y
i : ℕ
ih : ∀ {x : α}, p ^ (i + 1) ∣ x * y → p ^ (i + 1) ∣ x
x : α
hxy : p * p ^ (i + 1) ∣ x * y
⊢ p * p ^ (i + 1) ∣ x

Next tactic:
obtain ⟨x', rfl⟩ := (h.dvd_or_dvd (dvd_of_mul_right_dvd hxy)).resolve_right hy
theorem prime_pow_succ_dvd_mul {α : Type*} [CancelCommMonoidWithZero α] {p x y : α} (h : Prime p)
    {i : ℕ} (hxy : p ^ (i + 1) ∣ x * y) : p ^ (i + 1) ∣ x ∨ p ∣ y := by
  rw [or_iff_not_imp_right]
  intro hy
  induction' i with i ih generalizing x
  · rw [pow_one] at hxy ⊢
    exact (h.dvd_or_dvd hxy).resolve_right hy
  rw [pow_succ] at hxy ⊢
  obtain ⟨x', rfl⟩ := (h.dvd_or_dvd (dvd_of_mul_right_dvd hxy)).resolve_right hy
  

Proof state:
case succ.intro
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : CancelCommMonoidWithZero α
p y : α
h : Prime p
hy : ¬p ∣ y
i : ℕ
ih : ∀ {x : α}, p ^ (i + 1) ∣ x * y → p ^ (i + 1) ∣ x
x' : α
hxy : p * p ^ (i + 1) ∣ p * x' * y
⊢ p * p ^ (i + 1) ∣ p * x'

Next tactic:
rw [mul_assoc] at hxy
theorem prime_pow_succ_dvd_mul {α : Type*} [CancelCommMonoidWithZero α] {p x y : α} (h : Prime p)
    {i : ℕ} (hxy : p ^ (i + 1) ∣ x * y) : p ^ (i + 1) ∣ x ∨ p ∣ y := by
  rw [or_iff_not_imp_right]
  intro hy
  induction' i with i ih generalizing x
  · rw [pow_one] at hxy ⊢
    exact (h.dvd_or_dvd hxy).resolve_right hy
  rw [pow_succ] at hxy ⊢
  obtain ⟨x', rfl⟩ := (h.dvd_or_dvd (dvd_of_mul_right_dvd hxy)).resolve_right hy
  rw [mul_assoc] at hxy
  

Proof state:
case succ.intro
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : CancelCommMonoidWithZero α
p y : α
h : Prime p
hy : ¬p ∣ y
i : ℕ
ih : ∀ {x : α}, p ^ (i + 1) ∣ x * y → p ^ (i + 1) ∣ x
x' : α
hxy : p * p ^ (i + 1) ∣ p * (x' * y)
⊢ p * p ^ (i + 1) ∣ p * x'

Next tactic:
exact mul_dvd_mul_left p (ih ((mul_dvd_mul_iff_left h.ne_zero).mp hxy))
@[simp]
theorem not_irreducible_one [Monoid α] : ¬Irreducible (1 : α) := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : Monoid α
⊢ ¬Irreducible 1

Next tactic:
simp [irreducible_iff]
theorem not_irreducible_pow {α} [Monoid α] {x : α} {n : ℕ} (hn : n ≠ 1) :
    ¬ Irreducible (x ^ n) := by
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
n : ℕ
hn : n ≠ 1
⊢ ¬Irreducible (x ^ n)

Next tactic:
cases n with
  | zero => simp
  | succ n =>
    intro ⟨h₁, h₂⟩
    have := h₂ _ _ (pow_succ _ _)
    rw [isUnit_pow_iff (Nat.succ_ne_succ.mp hn), or_self] at this
    exact h₁ (this.pow _)
theorem not_irreducible_pow {α} [Monoid α] {x : α} {n : ℕ} (hn : n ≠ 1) :
    ¬ Irreducible (x ^ n) := by
  cases n with
  

Proof state:
case zero
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
hn : Nat.zero ≠ 1
⊢ ¬Irreducible (x ^ Nat.zero)

Next tactic:
| zero => simp
theorem not_irreducible_pow {α} [Monoid α] {x : α} {n : ℕ} (hn : n ≠ 1) :
    ¬ Irreducible (x ^ n) := by
  cases n with
  | zero => 

Proof state:
case zero
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
hn : Nat.zero ≠ 1
⊢ ¬Irreducible (x ^ Nat.zero)

Next tactic:
simp
theorem not_irreducible_pow {α} [Monoid α] {x : α} {n : ℕ} (hn : n ≠ 1) :
    ¬ Irreducible (x ^ n) := by
  cases n with
  | zero => simp
  

Proof state:
case succ
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
n : ℕ
hn : Nat.succ n ≠ 1
⊢ ¬Irreducible (x ^ Nat.succ n)

Next tactic:
| succ n =>
    intro ⟨h₁, h₂⟩
    have := h₂ _ _ (pow_succ _ _)
    rw [isUnit_pow_iff (Nat.succ_ne_succ.mp hn), or_self] at this
    exact h₁ (this.pow _)
theorem not_irreducible_pow {α} [Monoid α] {x : α} {n : ℕ} (hn : n ≠ 1) :
    ¬ Irreducible (x ^ n) := by
  cases n with
  | zero => simp
  | succ n =>
    

Proof state:
case succ
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
n : ℕ
hn : Nat.succ n ≠ 1
⊢ ¬Irreducible (x ^ Nat.succ n)

Next tactic:
intro ⟨h₁, h₂⟩
theorem not_irreducible_pow {α} [Monoid α] {x : α} {n : ℕ} (hn : n ≠ 1) :
    ¬ Irreducible (x ^ n) := by
  cases n with
  | zero => simp
  | succ n =>
    intro ⟨h₁, h₂⟩
    

Proof state:
case succ
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
n : ℕ
hn : Nat.succ n ≠ 1
h₁ : ¬IsUnit (x ^ Nat.succ n)
h₂ : ∀ (a b : α), x ^ Nat.succ n = a * b → IsUnit a ∨ IsUnit b
⊢ False

Next tactic:
have := h₂ _ _ (pow_succ _ _)
theorem not_irreducible_pow {α} [Monoid α] {x : α} {n : ℕ} (hn : n ≠ 1) :
    ¬ Irreducible (x ^ n) := by
  cases n with
  | zero => simp
  | succ n =>
    intro ⟨h₁, h₂⟩
    have := h₂ _ _ (pow_succ _ _)
    

Proof state:
case succ
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
n : ℕ
hn : Nat.succ n ≠ 1
h₁ : ¬IsUnit (x ^ Nat.succ n)
h₂ : ∀ (a b : α), x ^ Nat.succ n = a * b → IsUnit a ∨ IsUnit b
this : IsUnit x ∨ IsUnit (x ^ n)
⊢ False

Next tactic:
rw [isUnit_pow_iff (Nat.succ_ne_succ.mp hn), or_self] at this
theorem not_irreducible_pow {α} [Monoid α] {x : α} {n : ℕ} (hn : n ≠ 1) :
    ¬ Irreducible (x ^ n) := by
  cases n with
  | zero => simp
  | succ n =>
    intro ⟨h₁, h₂⟩
    have := h₂ _ _ (pow_succ _ _)
    rw [isUnit_pow_iff (Nat.succ_ne_succ.mp hn), or_self] at this
    

Proof state:
case succ
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
n : ℕ
hn : Nat.succ n ≠ 1
h₁ : ¬IsUnit (x ^ Nat.succ n)
h₂ : ∀ (a b : α), x ^ Nat.succ n = a * b → IsUnit a ∨ IsUnit b
this : IsUnit x
⊢ False

Next tactic:
exact h₁ (this.pow _)
theorem irreducible_or_factor {α} [Monoid α] (x : α) (h : ¬IsUnit x) :
    Irreducible x ∨ ∃ a b, ¬IsUnit a ∧ ¬IsUnit b ∧ a * b = x := by
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
h : ¬IsUnit x
⊢ Irreducible x ∨ ∃ a b, ¬IsUnit a ∧ ¬IsUnit b ∧ a * b = x

Next tactic:
haveI := Classical.dec
theorem irreducible_or_factor {α} [Monoid α] (x : α) (h : ¬IsUnit x) :
    Irreducible x ∨ ∃ a b, ¬IsUnit a ∧ ¬IsUnit b ∧ a * b = x := by
  haveI := Classical.dec
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
h : ¬IsUnit x
this : (p : Prop) → Decidable p
⊢ Irreducible x ∨ ∃ a b, ¬IsUnit a ∧ ¬IsUnit b ∧ a * b = x

Next tactic:
refine' or_iff_not_imp_right.2 fun H => _
theorem irreducible_or_factor {α} [Monoid α] (x : α) (h : ¬IsUnit x) :
    Irreducible x ∨ ∃ a b, ¬IsUnit a ∧ ¬IsUnit b ∧ a * b = x := by
  haveI := Classical.dec
  refine' or_iff_not_imp_right.2 fun H => _
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
h : ¬IsUnit x
this : (p : Prop) → Decidable p
H : ¬∃ a b, ¬IsUnit a ∧ ¬IsUnit b ∧ a * b = x
⊢ Irreducible x

Next tactic:
simp? [h, irreducible_iff] at H ⊢ says
    simp only [exists_and_left, not_exists, not_and, irreducible_iff, h, not_false_eq_true,
      true_and] at H ⊢
theorem irreducible_or_factor {α} [Monoid α] (x : α) (h : ¬IsUnit x) :
    Irreducible x ∨ ∃ a b, ¬IsUnit a ∧ ¬IsUnit b ∧ a * b = x := by
  haveI := Classical.dec
  refine' or_iff_not_imp_right.2 fun H => _
  simp? [h, irreducible_iff] at H ⊢ says
    

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
h : ¬IsUnit x
this : (p : Prop) → Decidable p
H : ¬∃ a b, ¬IsUnit a ∧ ¬IsUnit b ∧ a * b = x
⊢ Irreducible x

Next tactic:
simp only [exists_and_left, not_exists, not_and, irreducible_iff, h, not_false_eq_true,
      true_and] at H ⊢
theorem irreducible_or_factor {α} [Monoid α] (x : α) (h : ¬IsUnit x) :
    Irreducible x ∨ ∃ a b, ¬IsUnit a ∧ ¬IsUnit b ∧ a * b = x := by
  haveI := Classical.dec
  refine' or_iff_not_imp_right.2 fun H => _
  simp? [h, irreducible_iff] at H ⊢ says
    simp only [exists_and_left, not_exists, not_and, irreducible_iff, h, not_false_eq_true,
      true_and] at H ⊢
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
h : ¬IsUnit x
this : (p : Prop) → Decidable p
H : ∀ (x_1 : α), ¬IsUnit x_1 → ∀ (x_2 : α), ¬IsUnit x_2 → ¬x_1 * x_2 = x
⊢ ∀ (a b : α), x = a * b → IsUnit a ∨ IsUnit b

Next tactic:
refine' fun a b h => by_contradiction fun o => _
theorem irreducible_or_factor {α} [Monoid α] (x : α) (h : ¬IsUnit x) :
    Irreducible x ∨ ∃ a b, ¬IsUnit a ∧ ¬IsUnit b ∧ a * b = x := by
  haveI := Classical.dec
  refine' or_iff_not_imp_right.2 fun H => _
  simp? [h, irreducible_iff] at H ⊢ says
    simp only [exists_and_left, not_exists, not_and, irreducible_iff, h, not_false_eq_true,
      true_and] at H ⊢
  refine' fun a b h => by_contradiction fun o => _
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
h✝ : ¬IsUnit x
this : (p : Prop) → Decidable p
H : ∀ (x_1 : α), ¬IsUnit x_1 → ∀ (x_2 : α), ¬IsUnit x_2 → ¬x_1 * x_2 = x
a b : α
h : x = a * b
o : ¬(IsUnit a ∨ IsUnit b)
⊢ False

Next tactic:
simp? [not_or] at o says simp only [not_or] at o
theorem irreducible_or_factor {α} [Monoid α] (x : α) (h : ¬IsUnit x) :
    Irreducible x ∨ ∃ a b, ¬IsUnit a ∧ ¬IsUnit b ∧ a * b = x := by
  haveI := Classical.dec
  refine' or_iff_not_imp_right.2 fun H => _
  simp? [h, irreducible_iff] at H ⊢ says
    simp only [exists_and_left, not_exists, not_and, irreducible_iff, h, not_false_eq_true,
      true_and] at H ⊢
  refine' fun a b h => by_contradiction fun o => _
  simp? [not_or] at o says 

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
h✝ : ¬IsUnit x
this : (p : Prop) → Decidable p
H : ∀ (x_1 : α), ¬IsUnit x_1 → ∀ (x_2 : α), ¬IsUnit x_2 → ¬x_1 * x_2 = x
a b : α
h : x = a * b
o : ¬(IsUnit a ∨ IsUnit b)
⊢ False

Next tactic:
simp only [not_or] at o
theorem irreducible_or_factor {α} [Monoid α] (x : α) (h : ¬IsUnit x) :
    Irreducible x ∨ ∃ a b, ¬IsUnit a ∧ ¬IsUnit b ∧ a * b = x := by
  haveI := Classical.dec
  refine' or_iff_not_imp_right.2 fun H => _
  simp? [h, irreducible_iff] at H ⊢ says
    simp only [exists_and_left, not_exists, not_and, irreducible_iff, h, not_false_eq_true,
      true_and] at H ⊢
  refine' fun a b h => by_contradiction fun o => _
  simp? [not_or] at o says simp only [not_or] at o
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
α : Type u_5
inst✝ : Monoid α
x : α
h✝ : ¬IsUnit x
this : (p : Prop) → Decidable p
H : ∀ (x_1 : α), ¬IsUnit x_1 → ∀ (x_2 : α), ¬IsUnit x_2 → ¬x_1 * x_2 = x
a b : α
h : x = a * b
o : ¬IsUnit a ∧ ¬IsUnit b
⊢ False

Next tactic:
exact H _ o.1 _ o.2 h.symm
/-- If `p` and `q` are irreducible, then `p ∣ q` implies `q ∣ p`. -/
theorem Irreducible.dvd_symm [Monoid α] {p q : α} (hp : Irreducible p) (hq : Irreducible q) :
    p ∣ q → q ∣ p := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : Monoid α
p q : α
hp : Irreducible p
hq : Irreducible q
⊢ p ∣ q → q ∣ p

Next tactic:
rintro ⟨q', rfl⟩
/-- If `p` and `q` are irreducible, then `p ∣ q` implies `q ∣ p`. -/
theorem Irreducible.dvd_symm [Monoid α] {p q : α} (hp : Irreducible p) (hq : Irreducible q) :
    p ∣ q → q ∣ p := by
  rintro ⟨q', rfl⟩
  

Proof state:
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : Monoid α
p : α
hp : Irreducible p
q' : α
hq : Irreducible (p * q')
⊢ p * q' ∣ p

Next tactic:
rw [IsUnit.mul_right_dvd (Or.resolve_left (of_irreducible_mul hq) hp.not_unit)]
theorem irreducible_units_mul (a : αˣ) (b : α) : Irreducible (↑a * b) ↔ Irreducible b := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : Monoid α
a : αˣ
b : α
⊢ Irreducible (↑a * b) ↔ Irreducible b

Next tactic:
simp only [irreducible_iff, Units.isUnit_units_mul, and_congr_right_iff]
theorem irreducible_units_mul (a : αˣ) (b : α) : Irreducible (↑a * b) ↔ Irreducible b := by
  simp only [irreducible_iff, Units.isUnit_units_mul, and_congr_right_iff]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : Monoid α
a : αˣ
b : α
⊢ ¬IsUnit b →
    ((∀ (a_2 b_1 : α), ↑a * b = a_2 * b_1 → IsUnit a_2 ∨ IsUnit b_1) ↔
      ∀ (a b_1 : α), b = a * b_1 → IsUnit a ∨ IsUnit b_1)

Next tactic:
refine' fun _ => ⟨fun h A B HAB => _, fun h A B HAB => _⟩