/-
Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Morenikeji Neri

! This file was ported from Lean 3 source module ring_theory.principal_ideal_domain
! leanprover-community/mathlib commit c085f3044fe585c575e322bfab45b3633c48d820
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.Algebra.EuclideanDomain.Instances
import Mathbin.RingTheory.UniqueFactorizationDomain

/-!
# Principal ideal rings and principal ideal domains

> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
> Any changes to this file require a corresponding PR to mathlib4.

A principal ideal ring (PIR) is a ring in which all left ideals are principal. A
principal ideal domain (PID) is an integral domain which is a principal ideal ring.

# Main definitions

Note that for principal ideal domains, one should use
`[is_domain R] [is_principal_ideal_ring R]`. There is no explicit definition of a PID.
Theorems about PID's are in the `principal_ideal_ring` namespace.

- `is_principal_ideal_ring`: a predicate on rings, saying that every left ideal is principal.
- `generator`: a generator of a principal ideal (or more generally submodule)
- `to_unique_factorization_monoid`: a PID is a unique factorization domain

# Main results

- `to_maximal_ideal`: a non-zero prime ideal in a PID is maximal.
- `euclidean_domain.to_principal_ideal_domain` : a Euclidean domain is a PID.

-/

universe u v

variable {R : Type u} {M : Type v}

open Set Function

open Submodule

open Classical

section

variable [Ring R] [AddCommGroup M] [Module R M]

#print Submodule.IsPrincipal /-
/- ./././Mathport/Syntax/Translate/Command.lean:388:30: infer kinds are unsupported in Lean 4: #[`principal] [] -/
/-- An `R`-submodule of `M` is principal if it is generated by one element. -/
@[mk_iff]
class Submodule.IsPrincipal (S : Submodule R M) : Prop where
  principal : ∃ a, S = span R {a}
#align submodule.is_principal Submodule.IsPrincipal
-/

/- warning: bot_is_principal -> bot_isPrincipal is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Ring.{u1} R] [_inst_2 : AddCommGroup.{u2} M] [_inst_3 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u2} M _inst_2)], Submodule.IsPrincipal.{u1, u2} R M _inst_1 _inst_2 _inst_3 (Bot.bot.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u2} M _inst_2) _inst_3) (Submodule.hasBot.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u2} M _inst_2) _inst_3))
but is expected to have type
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Ring.{u1} R] [_inst_2 : AddCommGroup.{u2} M] [_inst_3 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u2} M _inst_2)], Submodule.IsPrincipal.{u1, u2} R M _inst_1 _inst_2 _inst_3 (Bot.bot.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u2} M _inst_2) _inst_3) (Submodule.instBotSubmodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u2} M _inst_2) _inst_3))
Case conversion may be inaccurate. Consider using '#align bot_is_principal bot_isPrincipalₓ'. -/
instance bot_isPrincipal : (⊥ : Submodule R M).IsPrincipal :=
  ⟨⟨0, by simp⟩⟩
#align bot_is_principal bot_isPrincipal

/- warning: top_is_principal -> top_isPrincipal is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Ring.{u1} R], Submodule.IsPrincipal.{u1, u1} R R _inst_1 (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Top.top.{u1} (Submodule.{u1, u1} R R (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (Submodule.hasTop.{u1, u1} R R (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R _inst_1))))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Ring.{u1} R], Submodule.IsPrincipal.{u1, u1} R R _inst_1 (Ring.toAddCommGroup.{u1} R _inst_1) (instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRing.{u1} R _inst_1) (Top.top.{u1} (Submodule.{u1, u1} R R (Ring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)))) (instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRing.{u1} R _inst_1)) (Submodule.instTopSubmodule.{u1, u1} R R (Ring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)))) (instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRing.{u1} R _inst_1)))
Case conversion may be inaccurate. Consider using '#align top_is_principal top_isPrincipalₓ'. -/
instance top_isPrincipal : (⊤ : Submodule R R).IsPrincipal :=
  ⟨⟨1, Ideal.span_singleton_one.symm⟩⟩
#align top_is_principal top_isPrincipal

variable (R)

#print IsPrincipalIdealRing /-
/-- A ring is a principal ideal ring if all (left) ideals are principal. -/
@[mk_iff]
class IsPrincipalIdealRing (R : Type u) [Ring R] : Prop where
  principal : ∀ S : Ideal R, S.IsPrincipal
#align is_principal_ideal_ring IsPrincipalIdealRing
-/

attribute [instance] IsPrincipalIdealRing.principal

#print DivisionRing.isPrincipalIdealRing /-
instance (priority := 100) DivisionRing.isPrincipalIdealRing (K : Type u) [DivisionRing K] :
    IsPrincipalIdealRing K
    where principal S := by rcases Ideal.eq_bot_or_top S with (rfl | rfl) <;> infer_instance
#align division_ring.is_principal_ideal_ring DivisionRing.isPrincipalIdealRing
-/

end

namespace Submodule.IsPrincipal

variable [AddCommGroup M]

section Ring

variable [Ring R] [Module R M]

#print Submodule.IsPrincipal.generator /-
/-- `generator I`, if `I` is a principal submodule, is an `x ∈ M` such that `span R {x} = I` -/
noncomputable def generator (S : Submodule R M) [S.IsPrincipal] : M :=
  Classical.choose (principal S)
#align submodule.is_principal.generator Submodule.IsPrincipal.generator
-/

#print Submodule.IsPrincipal.span_singleton_generator /-
theorem span_singleton_generator (S : Submodule R M) [S.IsPrincipal] : span R {generator S} = S :=
  Eq.symm (Classical.choose_spec (principal S))
#align submodule.is_principal.span_singleton_generator Submodule.IsPrincipal.span_singleton_generator
-/

#print Ideal.span_singleton_generator /-
theorem Ideal.span_singleton_generator (I : Ideal R) [I.IsPrincipal] :
    Ideal.span ({generator I} : Set R) = I :=
  Eq.symm (Classical.choose_spec (principal I))
#align ideal.span_singleton_generator Ideal.span_singleton_generator
-/

#print Submodule.IsPrincipal.generator_mem /-
@[simp]
theorem generator_mem (S : Submodule R M) [S.IsPrincipal] : generator S ∈ S :=
  by
  conv_rhs => rw [← span_singleton_generator S]
  exact subset_span (mem_singleton _)
#align submodule.is_principal.generator_mem Submodule.IsPrincipal.generator_mem
-/

#print Submodule.IsPrincipal.mem_iff_eq_smul_generator /-
theorem mem_iff_eq_smul_generator (S : Submodule R M) [S.IsPrincipal] {x : M} :
    x ∈ S ↔ ∃ s : R, x = s • generator S := by
  simp_rw [@eq_comm _ x, ← mem_span_singleton, span_singleton_generator]
#align submodule.is_principal.mem_iff_eq_smul_generator Submodule.IsPrincipal.mem_iff_eq_smul_generator
-/

/- warning: submodule.is_principal.eq_bot_iff_generator_eq_zero -> Submodule.IsPrincipal.eq_bot_iff_generator_eq_zero is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : AddCommGroup.{u2} M] [_inst_2 : Ring.{u1} R] [_inst_3 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_2) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1)] (S : Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_2) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) [_inst_4 : Submodule.IsPrincipal.{u1, u2} R M _inst_2 _inst_1 _inst_3 S], Iff (Eq.{succ u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_2) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) S (Bot.bot.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_2) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (Submodule.hasBot.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_2) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3))) (Eq.{succ u2} M (Submodule.IsPrincipal.generator.{u1, u2} R M _inst_1 _inst_2 _inst_3 S _inst_4) (OfNat.ofNat.{u2} M 0 (OfNat.mk.{u2} M 0 (Zero.zero.{u2} M (AddZeroClass.toHasZero.{u2} M (AddMonoid.toAddZeroClass.{u2} M (SubNegMonoid.toAddMonoid.{u2} M (AddGroup.toSubNegMonoid.{u2} M (AddCommGroup.toAddGroup.{u2} M _inst_1)))))))))
but is expected to have type
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : AddCommGroup.{u2} M] [_inst_2 : Ring.{u1} R] [_inst_3 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_2) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1)] (S : Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_2) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) [_inst_4 : Submodule.IsPrincipal.{u1, u2} R M _inst_2 _inst_1 _inst_3 S], Iff (Eq.{succ u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_2) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) S (Bot.bot.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_2) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (Submodule.instBotSubmodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_2) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3))) (Eq.{succ u2} M (Submodule.IsPrincipal.generator.{u1, u2} R M _inst_1 _inst_2 _inst_3 S _inst_4) (OfNat.ofNat.{u2} M 0 (Zero.toOfNat0.{u2} M (NegZeroClass.toZero.{u2} M (SubNegZeroMonoid.toNegZeroClass.{u2} M (SubtractionMonoid.toSubNegZeroMonoid.{u2} M (SubtractionCommMonoid.toSubtractionMonoid.{u2} M (AddCommGroup.toDivisionAddCommMonoid.{u2} M _inst_1))))))))
Case conversion may be inaccurate. Consider using '#align submodule.is_principal.eq_bot_iff_generator_eq_zero Submodule.IsPrincipal.eq_bot_iff_generator_eq_zeroₓ'. -/
theorem eq_bot_iff_generator_eq_zero (S : Submodule R M) [S.IsPrincipal] :
    S = ⊥ ↔ generator S = 0 := by rw [← @span_singleton_eq_bot R M, span_singleton_generator]
#align submodule.is_principal.eq_bot_iff_generator_eq_zero Submodule.IsPrincipal.eq_bot_iff_generator_eq_zero

end Ring

section CommRing

variable [CommRing R] [Module R M]

#print Submodule.IsPrincipal.mem_iff_generator_dvd /-
theorem mem_iff_generator_dvd (S : Ideal R) [S.IsPrincipal] {x : R} : x ∈ S ↔ generator S ∣ x :=
  (mem_iff_eq_smul_generator S).trans (exists_congr fun a => by simp only [mul_comm, smul_eq_mul])
#align submodule.is_principal.mem_iff_generator_dvd Submodule.IsPrincipal.mem_iff_generator_dvd
-/

/- warning: submodule.is_principal.prime_generator_of_is_prime -> Submodule.IsPrincipal.prime_generator_of_isPrime is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_2 : CommRing.{u1} R] (S : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) [_inst_4 : Submodule.IsPrincipal.{u1, u1} R R (CommRing.toRing.{u1} R _inst_2) (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) S] [is_prime : Ideal.IsPrime.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) S], (Ne.{succ u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) S (Bot.bot.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (Submodule.hasBot.{u1, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))))) -> (Prime.{u1} R (CommSemiring.toCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2)) (Submodule.IsPrincipal.generator.{u1, u1} R R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (CommRing.toRing.{u1} R _inst_2) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) S _inst_4))
but is expected to have type
  forall {R : Type.{u1}} [_inst_2 : CommRing.{u1} R] (S : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) [_inst_4 : Submodule.IsPrincipal.{u1, u1} R R (CommRing.toRing.{u1} R _inst_2) (Ring.toAddCommGroup.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) S] [is_prime : Ideal.IsPrime.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) S], (Ne.{succ u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) S (Bot.bot.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (Submodule.instBotSubmodule.{u1, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))))) -> (Prime.{u1} R (CommSemiring.toCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2)) (Submodule.IsPrincipal.generator.{u1, u1} R R (Ring.toAddCommGroup.{u1} R (CommRing.toRing.{u1} R _inst_2)) (CommRing.toRing.{u1} R _inst_2) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) S _inst_4))
Case conversion may be inaccurate. Consider using '#align submodule.is_principal.prime_generator_of_is_prime Submodule.IsPrincipal.prime_generator_of_isPrimeₓ'. -/
theorem prime_generator_of_isPrime (S : Ideal R) [Submodule.IsPrincipal S] [is_prime : S.IsPrime]
    (ne_bot : S ≠ ⊥) : Prime (generator S) :=
  ⟨fun h => ne_bot ((eq_bot_iff_generator_eq_zero S).2 h), fun h =>
    is_prime.ne_top (S.eq_top_of_isUnit_mem (generator_mem S) h), fun _ _ => by
    simpa only [← mem_iff_generator_dvd S] using is_prime.2⟩
#align submodule.is_principal.prime_generator_of_is_prime Submodule.IsPrincipal.prime_generator_of_isPrime

/- warning: submodule.is_principal.generator_map_dvd_of_mem -> Submodule.IsPrincipal.generator_map_dvd_of_mem is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : AddCommGroup.{u2} M] [_inst_2 : CommRing.{u1} R] [_inst_3 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1)] {N : Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3} (ϕ : LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) M R (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) [_inst_4 : Submodule.IsPrincipal.{u1, u1} R R (CommRing.toRing.{u1} R _inst_2) (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (Submodule.map.{u1, u1, u2, u1, max u2 u1} R R M R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (RingHomSurjective.ids.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) M R (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (LinearMap.semilinearMapClass.{u1, u1, u2, u1} R R M R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))))) ϕ N)] {x : M}, (Membership.Mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (SetLike.hasMem.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) x N) -> (Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_2)))))) (Submodule.IsPrincipal.generator.{u1, u1} R R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (CommRing.toRing.{u1} R _inst_2) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (Submodule.map.{u1, u1, u2, u1, max u2 u1} R R M R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (RingHomSurjective.ids.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) M R (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (LinearMap.semilinearMapClass.{u1, u1, u2, u1} R R M R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))))) ϕ N) _inst_4) (coeFn.{max (succ u2) (succ u1), max (succ u2) (succ u1)} (LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) M R (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (fun (_x : LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) M R (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) => M -> R) (LinearMap.hasCoeToFun.{u1, u1, u2, u1} R R M R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))))) ϕ x))
but is expected to have type
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : AddCommGroup.{u2} M] [_inst_2 : CommRing.{u1} R] [_inst_3 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1)] {N : Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3} (ϕ : LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) M R (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2)))) [_inst_4 : Submodule.IsPrincipal.{u1, u1} R R (CommRing.toRing.{u1} R _inst_2) (Ring.toAddCommGroup.{u1} R (CommRing.toRing.{u1} R _inst_2)) (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2))) (Submodule.map.{u1, u1, u2, u1, max u1 u2} R R M R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2))) (RingHom.id.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (RingHomSurjective.ids.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) M R (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2)))) (LinearMap.instSemilinearMapClassLinearMap.{u1, u1, u2, u1} R R M R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2))) (RingHom.id.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) ϕ N)] {x : M}, (Membership.mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (SetLike.instMembership.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) x N) -> (Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_2)))))) (Submodule.IsPrincipal.generator.{u1, u1} R R (Ring.toAddCommGroup.{u1} R (CommRing.toRing.{u1} R _inst_2)) (CommRing.toRing.{u1} R _inst_2) (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2))) (Submodule.map.{u1, u1, u2, u1, max u1 u2} R R M R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (AddCommGroup.toAddCommMonoid.{u1} R (Ring.toAddCommGroup.{u1} R (CommRing.toRing.{u1} R _inst_2))) _inst_3 (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2))) (RingHom.id.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (RingHomSurjective.ids.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) M R (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2)))) (LinearMap.instSemilinearMapClassLinearMap.{u1, u1, u2, u1} R R M R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2))) (RingHom.id.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) ϕ N) _inst_4) (FunLike.coe.{max (succ u1) (succ u2), succ u2, succ u1} (LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) M R (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2)))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Module.LinearMap._hyg.6190 : M) => R) _x) (LinearMap.instFunLikeLinearMap.{u1, u1, u2, u1} R R M R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) _inst_3 (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2))) (RingHom.id.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) ϕ x))
Case conversion may be inaccurate. Consider using '#align submodule.is_principal.generator_map_dvd_of_mem Submodule.IsPrincipal.generator_map_dvd_of_memₓ'. -/
-- Note that the converse may not hold if `ϕ` is not injective.
theorem generator_map_dvd_of_mem {N : Submodule R M} (ϕ : M →ₗ[R] R) [(N.map ϕ).IsPrincipal] {x : M}
    (hx : x ∈ N) : generator (N.map ϕ) ∣ ϕ x :=
  by
  rw [← mem_iff_generator_dvd, Submodule.mem_map]
  exact ⟨x, hx, rfl⟩
#align submodule.is_principal.generator_map_dvd_of_mem Submodule.IsPrincipal.generator_map_dvd_of_mem

/- warning: submodule.is_principal.generator_submodule_image_dvd_of_mem -> Submodule.IsPrincipal.generator_submoduleImage_dvd_of_mem is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : AddCommGroup.{u2} M] [_inst_2 : CommRing.{u1} R] [_inst_3 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1)] {N : Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3} {O : Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3} (hNO : LE.le.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (Preorder.toLE.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (SetLike.partialOrder.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)))) N O) (ϕ : LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (coeSort.{succ u2, succ (succ u2)} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) Type.{u2} (SetLike.hasCoeToSort.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) O) R (Submodule.addCommMonoid.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) (Submodule.module.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) [_inst_4 : Submodule.IsPrincipal.{u1, u1} R R (CommRing.toRing.{u1} R _inst_2) (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (LinearMap.submoduleImage.{u1, u2, u1} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 R (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) O ϕ N)] {x : M} (hx : Membership.Mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (SetLike.hasMem.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) x N), Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_2)))))) (Submodule.IsPrincipal.generator.{u1, u1} R R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (CommRing.toRing.{u1} R _inst_2) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (LinearMap.submoduleImage.{u1, u2, u1} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 R (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) O ϕ N) _inst_4) (coeFn.{max (succ u2) (succ u1), max (succ u2) (succ u1)} (LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (coeSort.{succ u2, succ (succ u2)} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) Type.{u2} (SetLike.hasCoeToSort.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) O) R (Submodule.addCommMonoid.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) (Submodule.module.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (fun (_x : LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (coeSort.{succ u2, succ (succ u2)} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) Type.{u2} (SetLike.hasCoeToSort.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) O) R (Submodule.addCommMonoid.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) (Submodule.module.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)))) => (coeSort.{succ u2, succ (succ u2)} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) Type.{u2} (SetLike.hasCoeToSort.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) O) -> R) (LinearMap.hasCoeToFun.{u1, u1, u2, u1} R R (coeSort.{succ u2, succ (succ u2)} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) Type.{u2} (SetLike.hasCoeToSort.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) O) R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Submodule.addCommMonoid.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (AddCommGroup.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) (Submodule.module.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2))))) ϕ (Subtype.mk.{succ u2} M (fun (x : M) => Membership.Mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (SetLike.hasMem.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) x O) x (hNO x hx)))
but is expected to have type
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : AddCommGroup.{u2} M] [_inst_2 : CommRing.{u1} R] [_inst_3 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1)] {N : Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3} {O : Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3} (hNO : LE.le.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (Preorder.toLE.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (OmegaCompletePartialOrder.toPartialOrder.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (CompleteLattice.instOmegaCompletePartialOrder.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (Submodule.completeLattice.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3))))) N O) (ϕ : LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (Subtype.{succ u2} M (fun (x : M) => Membership.mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (SetLike.instMembership.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) x O)) R (Submodule.addCommMonoid.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) (Submodule.module.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2)))) [_inst_4 : Submodule.IsPrincipal.{u1, u1} R R (CommRing.toRing.{u1} R _inst_2) (Ring.toAddCommGroup.{u1} R (CommRing.toRing.{u1} R _inst_2)) (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2))) (LinearMap.submoduleImage.{u1, u2, u1} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 R (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2))) O ϕ N)] {x : M} (hx : Membership.mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (SetLike.instMembership.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) x N), Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_2)))))) (Submodule.IsPrincipal.generator.{u1, u1} R R (Ring.toAddCommGroup.{u1} R (CommRing.toRing.{u1} R _inst_2)) (CommRing.toRing.{u1} R _inst_2) (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2))) (LinearMap.submoduleImage.{u1, u2, u1} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 R (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2))) O ϕ N) _inst_4) (FunLike.coe.{max (succ u1) (succ u2), succ u2, succ u1} (LinearMap.{u1, u1, u2, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (RingHom.id.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2)))) (Subtype.{succ u2} M (fun (x : M) => Membership.mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (SetLike.instMembership.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) x O)) R (Submodule.addCommMonoid.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) (Submodule.module.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2)))) (Subtype.{succ u2} M (fun (x : M) => Membership.mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (SetLike.instMembership.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) x O)) (fun (_x : Subtype.{succ u2} M (fun (x : M) => Membership.mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (SetLike.instMembership.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) x O)) => (fun (x._@.Mathlib.Algebra.Module.LinearMap._hyg.6190 : Subtype.{succ u2} M (fun (x : M) => Membership.mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (SetLike.instMembership.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) x O)) => R) _x) (LinearMap.instFunLikeLinearMap.{u1, u1, u2, u1} R R (Subtype.{succ u2} M (fun (x : M) => Membership.mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (SetLike.instMembership.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) x O)) R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (Submodule.addCommMonoid.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) (Submodule.module.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3 O) (_private.Mathlib.RingTheory.Ideal.Operations.0.Ideal.instModuleToSemiringToAddCommMonoidToNonUnitalNonAssocSemiringToNonUnitalNonAssocRingToNonUnitalRingToNonUnitalCommRing.{u1, u1} R R (CommRing.toCommSemiring.{u1} R _inst_2) _inst_2 (Algebra.id.{u1} R (CommRing.toCommSemiring.{u1} R _inst_2))) (RingHom.id.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_2))))) ϕ (Subtype.mk.{succ u2} M (fun (x : M) => Membership.mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) (SetLike.instMembership.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_2)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_1) _inst_3)) x O) x (hNO x hx)))
Case conversion may be inaccurate. Consider using '#align submodule.is_principal.generator_submodule_image_dvd_of_mem Submodule.IsPrincipal.generator_submoduleImage_dvd_of_memₓ'. -/
-- Note that the converse may not hold if `ϕ` is not injective.
theorem generator_submoduleImage_dvd_of_mem {N O : Submodule R M} (hNO : N ≤ O) (ϕ : O →ₗ[R] R)
    [(ϕ.submoduleImage N).IsPrincipal] {x : M} (hx : x ∈ N) :
    generator (ϕ.submoduleImage N) ∣ ϕ ⟨x, hNO hx⟩ :=
  by
  rw [← mem_iff_generator_dvd, LinearMap.mem_submoduleImage_of_le hNO]
  exact ⟨x, hx, rfl⟩
#align submodule.is_principal.generator_submodule_image_dvd_of_mem Submodule.IsPrincipal.generator_submoduleImage_dvd_of_mem

end CommRing

end Submodule.IsPrincipal

namespace IsPrime

open Submodule.IsPrincipal Ideal

/- warning: is_prime.to_maximal_ideal -> IsPrime.to_maximal_ideal is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] {S : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))} [hpi : Ideal.IsPrime.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) S], (Ne.{succ u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) S (Bot.bot.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Submodule.hasBot.{u1, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) -> (Ideal.IsMaximal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) S)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] {S : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))} [hpi : Ideal.IsPrime.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) S], (Ne.{succ u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) S (Bot.bot.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Submodule.instBotSubmodule.{u1, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) -> (Ideal.IsMaximal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) S)
Case conversion may be inaccurate. Consider using '#align is_prime.to_maximal_ideal IsPrime.to_maximal_idealₓ'. -/
-- TODO -- for a non-ID one could perhaps prove that if p < q are prime then q maximal;
-- 0 isn't prime in a non-ID PIR but the Krull dimension is still <= 1.
-- The below result follows from this, but we could also use the below result to
-- prove this (quotient out by p).
theorem to_maximal_ideal [CommRing R] [IsDomain R] [IsPrincipalIdealRing R] {S : Ideal R}
    [hpi : IsPrime S] (hS : S ≠ ⊥) : IsMaximal S :=
  isMaximal_iff.2
    ⟨(ne_top_iff_one S).1 hpi.1, by
      intro T x hST hxS hxT
      cases' (mem_iff_generator_dvd _).1 (hST <| generator_mem S) with z hz
      cases hpi.mem_or_mem (show generator T * z ∈ S from hz ▸ generator_mem S)
      · have hTS : T ≤ S
        rwa [← T.span_singleton_generator, Ideal.span_le, singleton_subset_iff]
        exact (hxS <| hTS hxT).elim
      cases' (mem_iff_generator_dvd _).1 h with y hy
      have : generator S ≠ 0 := mt (eq_bot_iff_generator_eq_zero _).2 hS
      rw [← mul_one (generator S), hy, mul_left_comm, mul_right_inj' this] at hz
      exact hz.symm ▸ T.mul_mem_right _ (generator_mem T)⟩
#align is_prime.to_maximal_ideal IsPrime.to_maximal_ideal

end IsPrime

section

open EuclideanDomain

variable [EuclideanDomain R]

#print mod_mem_iff /-
theorem mod_mem_iff {S : Ideal R} {x y : R} (hy : y ∈ S) : x % y ∈ S ↔ x ∈ S :=
  ⟨fun hxy => div_add_mod x y ▸ S.add_mem (S.mul_mem_right _ hy) hxy, fun hx =>
    (mod_eq_sub_mul_div x y).symm ▸ S.sub_mem hx (S.mul_mem_right _ hy)⟩
#align mod_mem_iff mod_mem_iff
-/

#print EuclideanDomain.to_principal_ideal_domain /-
-- see Note [lower instance priority]
instance (priority := 100) EuclideanDomain.to_principal_ideal_domain : IsPrincipalIdealRing R
    where principal S :=
    ⟨if h : { x : R | x ∈ S ∧ x ≠ 0 }.Nonempty then
        have wf : WellFounded (EuclideanDomain.r : R → R → Prop) := EuclideanDomain.r_wellFounded
        have hmin :
          WellFounded.min wf { x : R | x ∈ S ∧ x ≠ 0 } h ∈ S ∧
            WellFounded.min wf { x : R | x ∈ S ∧ x ≠ 0 } h ≠ 0 :=
          WellFounded.min_mem wf { x : R | x ∈ S ∧ x ≠ 0 } h
        ⟨WellFounded.min wf { x : R | x ∈ S ∧ x ≠ 0 } h,
          Submodule.ext fun x =>
            ⟨fun hx =>
              div_add_mod x (WellFounded.min wf { x : R | x ∈ S ∧ x ≠ 0 } h) ▸
                (Ideal.mem_span_singleton.2 <|
                  dvd_add (dvd_mul_right _ _) <|
                    by
                    have :
                      x % WellFounded.min wf { x : R | x ∈ S ∧ x ≠ 0 } h ∉
                        { x : R | x ∈ S ∧ x ≠ 0 } :=
                      fun h₁ => WellFounded.not_lt_min wf _ h h₁ (mod_lt x hmin.2)
                    have : x % WellFounded.min wf { x : R | x ∈ S ∧ x ≠ 0 } h = 0 :=
                      by
                      simp only [not_and_or, Set.mem_setOf_eq, not_ne_iff] at this
                      cases this
                      cases this ((mod_mem_iff hmin.1).2 hx)
                      exact this
                    simp [*]),
              fun hx =>
              let ⟨y, hy⟩ := Ideal.mem_span_singleton.1 hx
              hy.symm ▸ S.mul_mem_right _ hmin.1⟩⟩
      else
        ⟨0,
          Submodule.ext fun a => by
            rw [← @Submodule.bot_coe R R _ _ _, span_eq, Submodule.mem_bot] <;>
              exact
                ⟨fun haS => by_contradiction fun ha0 => h ⟨a, ⟨haS, ha0⟩⟩, fun h₁ =>
                  h₁.symm ▸ S.zero_mem⟩⟩⟩
#align euclidean_domain.to_principal_ideal_domain EuclideanDomain.to_principal_ideal_domain
-/

end

#print IsField.isPrincipalIdealRing /-
theorem IsField.isPrincipalIdealRing {R : Type _} [CommRing R] (h : IsField R) :
    IsPrincipalIdealRing R :=
  @EuclideanDomain.to_principal_ideal_domain R (@Field.toEuclideanDomain R h.toField)
#align is_field.is_principal_ideal_ring IsField.isPrincipalIdealRing
-/

namespace PrincipalIdealRing

open IsPrincipalIdealRing

#print PrincipalIdealRing.isNoetherianRing /-
-- see Note [lower instance priority]
instance (priority := 100) isNoetherianRing [Ring R] [IsPrincipalIdealRing R] :
    IsNoetherianRing R :=
  isNoetherianRing_iff.2
    ⟨fun s : Ideal R =>
      by
      rcases(IsPrincipalIdealRing.principal s).principal with ⟨a, rfl⟩
      rw [← Finset.coe_singleton]
      exact ⟨{a}, SetLike.coe_injective rfl⟩⟩
#align principal_ideal_ring.is_noetherian_ring PrincipalIdealRing.isNoetherianRing
-/

/- warning: principal_ideal_ring.is_maximal_of_irreducible -> PrincipalIdealRing.isMaximal_of_irreducible is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] {p : R}, (Irreducible.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)) p) -> (Ideal.IsMaximal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) (Submodule.span.{u1, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Singleton.singleton.{u1, u1} R (Set.{u1} R) (Set.hasSingleton.{u1} R) p)))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] {p : R}, (Irreducible.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) p) -> (Ideal.IsMaximal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) (Submodule.span.{u1, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Singleton.singleton.{u1, u1} R (Set.{u1} R) (Set.instSingletonSet.{u1} R) p)))
Case conversion may be inaccurate. Consider using '#align principal_ideal_ring.is_maximal_of_irreducible PrincipalIdealRing.isMaximal_of_irreducibleₓ'. -/
theorem isMaximal_of_irreducible [CommRing R] [IsPrincipalIdealRing R] {p : R}
    (hp : Irreducible p) : Ideal.IsMaximal (span R ({p} : Set R)) :=
  ⟨⟨mt Ideal.span_singleton_eq_top.1 hp.1, fun I hI =>
      by
      rcases principal I with ⟨a, rfl⟩
      erw [Ideal.span_singleton_eq_top]
      rcases Ideal.span_singleton_le_span_singleton.1 (le_of_lt hI) with ⟨b, rfl⟩
      refine' (of_irreducible_mul hp).resolve_right (mt (fun hb => _) (not_le_of_lt hI))
      erw [Ideal.span_singleton_le_span_singleton, IsUnit.mul_right_dvd hb]⟩⟩
#align principal_ideal_ring.is_maximal_of_irreducible PrincipalIdealRing.isMaximal_of_irreducible

variable [CommRing R] [IsDomain R] [IsPrincipalIdealRing R]

/- warning: principal_ideal_ring.irreducible_iff_prime -> PrincipalIdealRing.irreducible_iff_prime is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] {p : R}, Iff (Irreducible.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)) p) (Prime.{u1} R (CommSemiring.toCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1)) p)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] {p : R}, Iff (Irreducible.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) p) (Prime.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)) p)
Case conversion may be inaccurate. Consider using '#align principal_ideal_ring.irreducible_iff_prime PrincipalIdealRing.irreducible_iff_primeₓ'. -/
theorem irreducible_iff_prime {p : R} : Irreducible p ↔ Prime p :=
  ⟨fun hp => (Ideal.span_singleton_prime hp.NeZero).1 <| (isMaximal_of_irreducible hp).IsPrime,
    Prime.irreducible⟩
#align principal_ideal_ring.irreducible_iff_prime PrincipalIdealRing.irreducible_iff_prime

/- warning: principal_ideal_ring.associates_irreducible_iff_prime -> PrincipalIdealRing.associates_irreducible_iff_prime is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] {p : Associates.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1))}, Iff (Irreducible.{u1} (Associates.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1))) (MonoidWithZero.toMonoid.{u1} (Associates.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1))) (CommMonoidWithZero.toMonoidWithZero.{u1} (Associates.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Associates.commMonoidWithZero.{u1} R (CommSemiring.toCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1))))) p) (Prime.{u1} (Associates.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Associates.commMonoidWithZero.{u1} R (CommSemiring.toCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1))) p)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] {p : Associates.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))}, Iff (Irreducible.{u1} (Associates.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))) (MonoidWithZero.toMonoid.{u1} (Associates.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))) (CommMonoidWithZero.toMonoidWithZero.{u1} (Associates.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))) (Associates.instCommMonoidWithZeroAssociatesToMonoidToMonoidWithZero.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2))))) p) (Prime.{u1} (Associates.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))) (Associates.instCommMonoidWithZeroAssociatesToMonoidToMonoidWithZero.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2))) p)
Case conversion may be inaccurate. Consider using '#align principal_ideal_ring.associates_irreducible_iff_prime PrincipalIdealRing.associates_irreducible_iff_primeₓ'. -/
theorem associates_irreducible_iff_prime : ∀ {p : Associates R}, Irreducible p ↔ Prime p :=
  Associates.irreducible_iff_prime_iff.1 fun _ => irreducible_iff_prime
#align principal_ideal_ring.associates_irreducible_iff_prime PrincipalIdealRing.associates_irreducible_iff_prime

section

open Classical

#print PrincipalIdealRing.factors /-
/-- `factors a` is a multiset of irreducible elements whose product is `a`, up to units -/
noncomputable def factors (a : R) : Multiset R :=
  if h : a = 0 then ∅ else Classical.choose (WfDvdMonoid.exists_factors a h)
#align principal_ideal_ring.factors PrincipalIdealRing.factors
-/

/- warning: principal_ideal_ring.factors_spec -> PrincipalIdealRing.factors_spec is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] (a : R), (Ne.{succ u1} R a (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))))))) -> (And (forall (b : R), (Membership.Mem.{u1, u1} R (Multiset.{u1} R) (Multiset.hasMem.{u1} R) b (PrincipalIdealRing.factors.{u1} R _inst_1 _inst_2 _inst_3 a)) -> (Irreducible.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)) b)) (Associated.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)) (Multiset.prod.{u1} R (CommRing.toCommMonoid.{u1} R _inst_1) (PrincipalIdealRing.factors.{u1} R _inst_1 _inst_2 _inst_3 a)) a))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] (a : R), (Ne.{succ u1} R a (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (CommMonoidWithZero.toZero.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)))))) -> (And (forall (b : R), (Membership.mem.{u1, u1} R (Multiset.{u1} R) (Multiset.instMembershipMultiset.{u1} R) b (PrincipalIdealRing.factors.{u1} R _inst_1 _inst_2 _inst_3 a)) -> (Irreducible.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) b)) (Associated.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (Multiset.prod.{u1} R (CommRing.toCommMonoid.{u1} R _inst_1) (PrincipalIdealRing.factors.{u1} R _inst_1 _inst_2 _inst_3 a)) a))
Case conversion may be inaccurate. Consider using '#align principal_ideal_ring.factors_spec PrincipalIdealRing.factors_specₓ'. -/
theorem factors_spec (a : R) (h : a ≠ 0) :
    (∀ b ∈ factors a, Irreducible b) ∧ Associated (factors a).Prod a :=
  by
  unfold factors; rw [dif_neg h]
  exact Classical.choose_spec (WfDvdMonoid.exists_factors a h)
#align principal_ideal_ring.factors_spec PrincipalIdealRing.factors_spec

/- warning: principal_ideal_ring.ne_zero_of_mem_factors -> PrincipalIdealRing.ne_zero_of_mem_factors is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_4 : CommRing.{u1} R] [_inst_5 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))] [_inst_6 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_4)] {a : R} {b : R}, (Ne.{succ u1} R a (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4)))))))))) -> (Membership.Mem.{u1, u1} R (Multiset.{u1} R) (Multiset.hasMem.{u1} R) b (PrincipalIdealRing.factors.{u1} R _inst_4 _inst_5 _inst_6 a)) -> (Ne.{succ u1} R b (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))))))))))
but is expected to have type
  forall {R : Type.{u1}} [_inst_4 : CommRing.{u1} R] [_inst_5 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))] [_inst_6 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_4)] {a : R} {b : R}, (Ne.{succ u1} R a (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (CommMonoidWithZero.toZero.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_4) _inst_5)))))) -> (Membership.mem.{u1, u1} R (Multiset.{u1} R) (Multiset.instMembershipMultiset.{u1} R) b (PrincipalIdealRing.factors.{u1} R _inst_4 _inst_5 _inst_6 a)) -> (Ne.{succ u1} R b (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (CommMonoidWithZero.toZero.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_4) _inst_5))))))
Case conversion may be inaccurate. Consider using '#align principal_ideal_ring.ne_zero_of_mem_factors PrincipalIdealRing.ne_zero_of_mem_factorsₓ'. -/
theorem ne_zero_of_mem_factors {R : Type v} [CommRing R] [IsDomain R] [IsPrincipalIdealRing R]
    {a b : R} (ha : a ≠ 0) (hb : b ∈ factors a) : b ≠ 0 :=
  Irreducible.ne_zero ((factors_spec a ha).1 b hb)
#align principal_ideal_ring.ne_zero_of_mem_factors PrincipalIdealRing.ne_zero_of_mem_factors

/- warning: principal_ideal_ring.mem_submonoid_of_factors_subset_of_units_subset -> PrincipalIdealRing.mem_submonoid_of_factors_subset_of_units_subset is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] (s : Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) {a : R}, (Ne.{succ u1} R a (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))))))) -> (forall (b : R), (Membership.Mem.{u1, u1} R (Multiset.{u1} R) (Multiset.hasMem.{u1} R) b (PrincipalIdealRing.factors.{u1} R _inst_1 _inst_2 _inst_3 a)) -> (Membership.Mem.{u1, u1} R (Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) (SetLike.hasMem.{u1, u1} (Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) R (Submonoid.setLike.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1))))))) b s)) -> (forall (c : Units.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1))), Membership.Mem.{u1, u1} R (Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) (SetLike.hasMem.{u1, u1} (Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) R (Submonoid.setLike.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1))))))) ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1))) R (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1))) R (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1))) R (coeBase.{succ u1, succ u1} (Units.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1))) R (Units.hasCoe.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) c) s) -> (Membership.Mem.{u1, u1} R (Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) (SetLike.hasMem.{u1, u1} (Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) R (Submonoid.setLike.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1))))))) a s)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] (s : Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) {a : R}, (Ne.{succ u1} R a (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (CommMonoidWithZero.toZero.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)))))) -> (forall (b : R), (Membership.mem.{u1, u1} R (Multiset.{u1} R) (Multiset.instMembershipMultiset.{u1} R) b (PrincipalIdealRing.factors.{u1} R _inst_1 _inst_2 _inst_3 a)) -> (Membership.mem.{u1, u1} R (Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) (SetLike.instMembership.{u1, u1} (Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) R (Submonoid.instSetLikeSubmonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1))))))) b s)) -> (forall (c : Units.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))), Membership.mem.{u1, u1} R (Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) (SetLike.instMembership.{u1, u1} (Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) R (Submonoid.instSetLikeSubmonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1))))))) (Units.val.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) c) s) -> (Membership.mem.{u1, u1} R (Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) (SetLike.instMembership.{u1, u1} (Submonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) R (Submonoid.instSetLikeSubmonoid.{u1} R (MulZeroOneClass.toMulOneClass.{u1} R (NonAssocSemiring.toMulZeroOneClass.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1))))))) a s)
Case conversion may be inaccurate. Consider using '#align principal_ideal_ring.mem_submonoid_of_factors_subset_of_units_subset PrincipalIdealRing.mem_submonoid_of_factors_subset_of_units_subsetₓ'. -/
theorem mem_submonoid_of_factors_subset_of_units_subset (s : Submonoid R) {a : R} (ha : a ≠ 0)
    (hfac : ∀ b ∈ factors a, b ∈ s) (hunit : ∀ c : Rˣ, (c : R) ∈ s) : a ∈ s :=
  by
  rcases(factors_spec a ha).2 with ⟨c, hc⟩
  rw [← hc]
  exact mul_mem (multiset_prod_mem _ hfac) (hunit _)
#align principal_ideal_ring.mem_submonoid_of_factors_subset_of_units_subset PrincipalIdealRing.mem_submonoid_of_factors_subset_of_units_subset

/- warning: principal_ideal_ring.ring_hom_mem_submonoid_of_factors_subset_of_units_subset -> PrincipalIdealRing.ringHom_mem_submonoid_of_factors_subset_of_units_subset is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_4 : CommRing.{u1} R] [_inst_5 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))] [_inst_6 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_4)] [_inst_7 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) (s : Submonoid.{u2} S (MulZeroOneClass.toMulOneClass.{u2} S (NonAssocSemiring.toMulZeroOneClass.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)))) (a : R), (Ne.{succ u1} R a (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4)))))))))) -> (forall (b : R), (Membership.Mem.{u1, u1} R (Multiset.{u1} R) (Multiset.hasMem.{u1} R) b (PrincipalIdealRing.factors.{u1} R _inst_4 _inst_5 _inst_6 a)) -> (Membership.Mem.{u2, u2} S (Submonoid.{u2} S (MulZeroOneClass.toMulOneClass.{u2} S (NonAssocSemiring.toMulZeroOneClass.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)))) (SetLike.hasMem.{u2, u2} (Submonoid.{u2} S (MulZeroOneClass.toMulOneClass.{u2} S (NonAssocSemiring.toMulZeroOneClass.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)))) S (Submonoid.setLike.{u2} S (MulZeroOneClass.toMulOneClass.{u2} S (NonAssocSemiring.toMulZeroOneClass.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7))))) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) (fun (_x : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) f b) s)) -> (forall (c : Units.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_4))), Membership.Mem.{u2, u2} S (Submonoid.{u2} S (MulZeroOneClass.toMulOneClass.{u2} S (NonAssocSemiring.toMulZeroOneClass.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)))) (SetLike.hasMem.{u2, u2} (Submonoid.{u2} S (MulZeroOneClass.toMulOneClass.{u2} S (NonAssocSemiring.toMulZeroOneClass.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)))) S (Submonoid.setLike.{u2} S (MulZeroOneClass.toMulOneClass.{u2} S (NonAssocSemiring.toMulZeroOneClass.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7))))) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) (fun (_x : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) f ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_4))) R (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_4))) R (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_4))) R (coeBase.{succ u1, succ u1} (Units.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_4))) R (Units.hasCoe.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_4)))))) c)) s) -> (Membership.Mem.{u2, u2} S (Submonoid.{u2} S (MulZeroOneClass.toMulOneClass.{u2} S (NonAssocSemiring.toMulZeroOneClass.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)))) (SetLike.hasMem.{u2, u2} (Submonoid.{u2} S (MulZeroOneClass.toMulOneClass.{u2} S (NonAssocSemiring.toMulZeroOneClass.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)))) S (Submonoid.setLike.{u2} S (MulZeroOneClass.toMulOneClass.{u2} S (NonAssocSemiring.toMulZeroOneClass.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7))))) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) (fun (_x : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) f a) s)
but is expected to have type
  forall {R : Type.{u2}} {S : Type.{u1}} [_inst_4 : CommRing.{u2} R] [_inst_5 : IsDomain.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))] [_inst_6 : IsPrincipalIdealRing.{u2} R (CommRing.toRing.{u2} R _inst_4)] [_inst_7 : Semiring.{u1} S] (f : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7)) (s : Submonoid.{u1} S (MulZeroOneClass.toMulOneClass.{u1} S (NonAssocSemiring.toMulZeroOneClass.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7)))) (a : R), (Ne.{succ u2} R a (OfNat.ofNat.{u2} R 0 (Zero.toOfNat0.{u2} R (CommMonoidWithZero.toZero.{u2} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u2} R (IsDomain.toCancelCommMonoidWithZero.{u2} R (CommRing.toCommSemiring.{u2} R _inst_4) _inst_5)))))) -> (forall (b : R), (Membership.mem.{u2, u2} R (Multiset.{u2} R) (Multiset.instMembershipMultiset.{u2} R) b (PrincipalIdealRing.factors.{u2} R _inst_4 _inst_5 _inst_6 a)) -> (Membership.mem.{u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) b) (Submonoid.{u1} S (MulZeroOneClass.toMulOneClass.{u1} S (NonAssocSemiring.toMulZeroOneClass.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7)))) (SetLike.instMembership.{u1, u1} (Submonoid.{u1} S (MulZeroOneClass.toMulOneClass.{u1} S (NonAssocSemiring.toMulZeroOneClass.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7)))) S (Submonoid.instSetLikeSubmonoid.{u1} S (MulZeroOneClass.toMulOneClass.{u1} S (NonAssocSemiring.toMulZeroOneClass.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7))))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7)) R S (NonUnitalNonAssocSemiring.toMul.{u2} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))))) (NonUnitalNonAssocSemiring.toMul.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7)) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7)) R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7) (RingHom.instRingHomClassRingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7))))) f b) s)) -> (forall (c : Units.{u2} R (MonoidWithZero.toMonoid.{u2} R (Semiring.toMonoidWithZero.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))))), Membership.mem.{u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Units.val.{u2} R (MonoidWithZero.toMonoid.{u2} R (Semiring.toMonoidWithZero.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)))) c)) (Submonoid.{u1} S (MulZeroOneClass.toMulOneClass.{u1} S (NonAssocSemiring.toMulZeroOneClass.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7)))) (SetLike.instMembership.{u1, u1} (Submonoid.{u1} S (MulZeroOneClass.toMulOneClass.{u1} S (NonAssocSemiring.toMulZeroOneClass.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7)))) S (Submonoid.instSetLikeSubmonoid.{u1} S (MulZeroOneClass.toMulOneClass.{u1} S (NonAssocSemiring.toMulZeroOneClass.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7))))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7)) R S (NonUnitalNonAssocSemiring.toMul.{u2} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))))) (NonUnitalNonAssocSemiring.toMul.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7)) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7)) R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7) (RingHom.instRingHomClassRingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7))))) f (Units.val.{u2} R (MonoidWithZero.toMonoid.{u2} R (Semiring.toMonoidWithZero.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)))) c)) s) -> (Membership.mem.{u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Submonoid.{u1} S (MulZeroOneClass.toMulOneClass.{u1} S (NonAssocSemiring.toMulZeroOneClass.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7)))) (SetLike.instMembership.{u1, u1} (Submonoid.{u1} S (MulZeroOneClass.toMulOneClass.{u1} S (NonAssocSemiring.toMulZeroOneClass.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7)))) S (Submonoid.instSetLikeSubmonoid.{u1} S (MulZeroOneClass.toMulOneClass.{u1} S (NonAssocSemiring.toMulZeroOneClass.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7))))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7)) R S (NonUnitalNonAssocSemiring.toMul.{u2} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))))) (NonUnitalNonAssocSemiring.toMul.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_7)) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7)) R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7) (RingHom.instRingHomClassRingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Semiring.toNonAssocSemiring.{u1} S _inst_7))))) f a) s)
Case conversion may be inaccurate. Consider using '#align principal_ideal_ring.ring_hom_mem_submonoid_of_factors_subset_of_units_subset PrincipalIdealRing.ringHom_mem_submonoid_of_factors_subset_of_units_subsetₓ'. -/
/-- If a `ring_hom` maps all units and all factors of an element `a` into a submonoid `s`, then it
also maps `a` into that submonoid. -/
theorem ringHom_mem_submonoid_of_factors_subset_of_units_subset {R S : Type _} [CommRing R]
    [IsDomain R] [IsPrincipalIdealRing R] [Semiring S] (f : R →+* S) (s : Submonoid S) (a : R)
    (ha : a ≠ 0) (h : ∀ b ∈ factors a, f b ∈ s) (hf : ∀ c : Rˣ, f c ∈ s) : f a ∈ s :=
  mem_submonoid_of_factors_subset_of_units_subset (s.comap f.toMonoidHom) ha h hf
#align principal_ideal_ring.ring_hom_mem_submonoid_of_factors_subset_of_units_subset PrincipalIdealRing.ringHom_mem_submonoid_of_factors_subset_of_units_subset

#print PrincipalIdealRing.to_uniqueFactorizationMonoid /-
-- see Note [lower instance priority]
/-- A principal ideal domain has unique factorization -/
instance (priority := 100) to_uniqueFactorizationMonoid : UniqueFactorizationMonoid R :=
  { (IsNoetherianRing.wfDvdMonoid : WfDvdMonoid R) with
    irreducible_iff_prime := fun _ => PrincipalIdealRing.irreducible_iff_prime }
#align principal_ideal_ring.to_unique_factorization_monoid PrincipalIdealRing.to_uniqueFactorizationMonoid
-/

end

end PrincipalIdealRing

section Surjective

open Submodule

variable {S N : Type _} [Ring R] [AddCommGroup M] [AddCommGroup N] [Ring S]

variable [Module R M] [Module R N]

/- warning: submodule.is_principal.of_comap -> Submodule.IsPrincipal.of_comap is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} {N : Type.{u3}} [_inst_1 : Ring.{u1} R] [_inst_2 : AddCommGroup.{u2} M] [_inst_3 : AddCommGroup.{u3} N] [_inst_5 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u2} M _inst_2)] [_inst_6 : Module.{u1, u3} R N (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u3} N _inst_3)] (f : LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u1} R _inst_1) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) M N (AddCommGroup.toAddCommMonoid.{u2} M _inst_2) (AddCommGroup.toAddCommMonoid.{u3} N _inst_3) _inst_5 _inst_6), (Function.Surjective.{succ u2, succ u3} M N (coeFn.{max (succ u2) (succ u3), max (succ u2) (succ u3)} (LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u1} R _inst_1) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) M N (AddCommGroup.toAddCommMonoid.{u2} M _inst_2) (AddCommGroup.toAddCommMonoid.{u3} N _inst_3) _inst_5 _inst_6) (fun (_x : LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u1} R _inst_1) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) M N (AddCommGroup.toAddCommMonoid.{u2} M _inst_2) (AddCommGroup.toAddCommMonoid.{u3} N _inst_3) _inst_5 _inst_6) => M -> N) (LinearMap.hasCoeToFun.{u1, u1, u2, u3} R R M N (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u2} M _inst_2) (AddCommGroup.toAddCommMonoid.{u3} N _inst_3) _inst_5 _inst_6 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) f)) -> (forall (S : Submodule.{u1, u3} R N (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u3} N _inst_3) _inst_6) [hI : Submodule.IsPrincipal.{u1, u2} R M _inst_1 _inst_2 _inst_5 (Submodule.comap.{u1, u1, u2, u3, max u2 u3} R R M N (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u2} M _inst_2) (AddCommGroup.toAddCommMonoid.{u3} N _inst_3) _inst_5 _inst_6 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u1} R _inst_1) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) M N (AddCommGroup.toAddCommMonoid.{u2} M _inst_2) (AddCommGroup.toAddCommMonoid.{u3} N _inst_3) _inst_5 _inst_6) (LinearMap.semilinearMapClass.{u1, u1, u2, u3} R R M N (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u1} R _inst_1) (AddCommGroup.toAddCommMonoid.{u2} M _inst_2) (AddCommGroup.toAddCommMonoid.{u3} N _inst_3) _inst_5 _inst_6 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) f S)], Submodule.IsPrincipal.{u1, u3} R N _inst_1 _inst_3 _inst_6 S)
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u3}} {N : Type.{u1}} [_inst_1 : Ring.{u2} R] [_inst_2 : AddCommGroup.{u3} M] [_inst_3 : AddCommGroup.{u1} N] [_inst_5 : Module.{u2, u3} R M (Ring.toSemiring.{u2} R _inst_1) (AddCommGroup.toAddCommMonoid.{u3} M _inst_2)] [_inst_6 : Module.{u2, u1} R N (Ring.toSemiring.{u2} R _inst_1) (AddCommGroup.toAddCommMonoid.{u1} N _inst_3)] (f : LinearMap.{u2, u2, u3, u1} R R (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u2} R _inst_1) (RingHom.id.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1))) M N (AddCommGroup.toAddCommMonoid.{u3} M _inst_2) (AddCommGroup.toAddCommMonoid.{u1} N _inst_3) _inst_5 _inst_6), (Function.Surjective.{succ u3, succ u1} M N (FunLike.coe.{max (succ u3) (succ u1), succ u3, succ u1} (LinearMap.{u2, u2, u3, u1} R R (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u2} R _inst_1) (RingHom.id.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1))) M N (AddCommGroup.toAddCommMonoid.{u3} M _inst_2) (AddCommGroup.toAddCommMonoid.{u1} N _inst_3) _inst_5 _inst_6) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Module.LinearMap._hyg.6190 : M) => N) _x) (LinearMap.instFunLikeLinearMap.{u2, u2, u3, u1} R R M N (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u2} R _inst_1) (AddCommGroup.toAddCommMonoid.{u3} M _inst_2) (AddCommGroup.toAddCommMonoid.{u1} N _inst_3) _inst_5 _inst_6 (RingHom.id.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)))) f)) -> (forall (S : Submodule.{u2, u1} R N (Ring.toSemiring.{u2} R _inst_1) (AddCommGroup.toAddCommMonoid.{u1} N _inst_3) _inst_6) [hI : Submodule.IsPrincipal.{u2, u3} R M _inst_1 _inst_2 _inst_5 (Submodule.comap.{u2, u2, u3, u1, max u3 u1} R R M N (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u2} R _inst_1) (AddCommGroup.toAddCommMonoid.{u3} M _inst_2) (AddCommGroup.toAddCommMonoid.{u1} N _inst_3) _inst_5 _inst_6 (RingHom.id.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1))) (LinearMap.{u2, u2, u3, u1} R R (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u2} R _inst_1) (RingHom.id.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1))) M N (AddCommGroup.toAddCommMonoid.{u3} M _inst_2) (AddCommGroup.toAddCommMonoid.{u1} N _inst_3) _inst_5 _inst_6) (LinearMap.instSemilinearMapClassLinearMap.{u2, u2, u3, u1} R R M N (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u2} R _inst_1) (AddCommGroup.toAddCommMonoid.{u3} M _inst_2) (AddCommGroup.toAddCommMonoid.{u1} N _inst_3) _inst_5 _inst_6 (RingHom.id.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)))) f S)], Submodule.IsPrincipal.{u2, u1} R N _inst_1 _inst_3 _inst_6 S)
Case conversion may be inaccurate. Consider using '#align submodule.is_principal.of_comap Submodule.IsPrincipal.of_comapₓ'. -/
theorem Submodule.IsPrincipal.of_comap (f : M →ₗ[R] N) (hf : Function.Surjective f)
    (S : Submodule R N) [hI : IsPrincipal (S.comap f)] : IsPrincipal S :=
  ⟨⟨f (IsPrincipal.generator (S.comap f)), by
      rw [← Set.image_singleton, ← Submodule.map_span, is_principal.span_singleton_generator,
        Submodule.map_comap_eq_of_surjective hf]⟩⟩
#align submodule.is_principal.of_comap Submodule.IsPrincipal.of_comap

/- warning: ideal.is_principal.of_comap -> Ideal.IsPrincipal.of_comap is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Ring.{u1} R] [_inst_4 : Ring.{u2} S] (f : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))), (Function.Surjective.{succ u1, succ u2} R S (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) (fun (_x : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) f)) -> (forall (I : Ideal.{u2} S (Ring.toSemiring.{u2} S _inst_4)) [hI : Submodule.IsPrincipal.{u1, u1} R R _inst_1 (NonUnitalNonAssocRing.toAddCommGroup.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Ideal.comap.{u1, u2, max u1 u2} R S (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} S _inst_4) (RingHom.ringHomClass.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) f I)], Submodule.IsPrincipal.{u2, u2} S S _inst_4 (NonUnitalNonAssocRing.toAddCommGroup.{u2} S (NonAssocRing.toNonUnitalNonAssocRing.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) (Semiring.toModule.{u2} S (Ring.toSemiring.{u2} S _inst_4)) I)
but is expected to have type
  forall {R : Type.{u2}} {S : Type.{u1}} [_inst_1 : Ring.{u2} R] [_inst_4 : Ring.{u1} S] (f : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))), (Function.Surjective.{succ u2, succ u1} R S (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) R S (NonUnitalNonAssocSemiring.toMul.{u2} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)))) (NonUnitalNonAssocSemiring.toMul.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4)))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4)) (RingHom.instRingHomClassRingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4)))))) f)) -> (forall (I : Ideal.{u1} S (Ring.toSemiring.{u1} S _inst_4)) [hI : Submodule.IsPrincipal.{u2, u2} R R _inst_1 (Ring.toAddCommGroup.{u2} R _inst_1) (Semiring.toModule.{u2} R (Ring.toSemiring.{u2} R _inst_1)) (Ideal.comap.{u2, u1, max u2 u1} R S (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} S _inst_4) (RingHom.instRingHomClassRingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) f I)], Submodule.IsPrincipal.{u1, u1} S S _inst_4 (Ring.toAddCommGroup.{u1} S _inst_4) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S _inst_4)) I)
Case conversion may be inaccurate. Consider using '#align ideal.is_principal.of_comap Ideal.IsPrincipal.of_comapₓ'. -/
theorem Ideal.IsPrincipal.of_comap (f : R →+* S) (hf : Function.Surjective f) (I : Ideal S)
    [hI : IsPrincipal (I.comap f)] : IsPrincipal I :=
  ⟨⟨f (IsPrincipal.generator (I.comap f)), by
      rw [Ideal.submodule_span_eq, ← Set.image_singleton, ← Ideal.map_span,
        Ideal.span_singleton_generator, Ideal.map_comap_of_surjective f hf]⟩⟩
#align ideal.is_principal.of_comap Ideal.IsPrincipal.of_comap

/- warning: is_principal_ideal_ring.of_surjective -> IsPrincipalIdealRing.of_surjective is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Ring.{u1} R] [_inst_4 : Ring.{u2} S] [_inst_7 : IsPrincipalIdealRing.{u1} R _inst_1] (f : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))), (Function.Surjective.{succ u1, succ u2} R S (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) (fun (_x : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) f)) -> (IsPrincipalIdealRing.{u2} S _inst_4)
but is expected to have type
  forall {R : Type.{u2}} {S : Type.{u1}} [_inst_1 : Ring.{u2} R] [_inst_4 : Ring.{u1} S] [_inst_7 : IsPrincipalIdealRing.{u2} R _inst_1] (f : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))), (Function.Surjective.{succ u2, succ u1} R S (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) R S (NonUnitalNonAssocSemiring.toMul.{u2} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)))) (NonUnitalNonAssocSemiring.toMul.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4)))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4)) (RingHom.instRingHomClassRingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4)))))) f)) -> (IsPrincipalIdealRing.{u1} S _inst_4)
Case conversion may be inaccurate. Consider using '#align is_principal_ideal_ring.of_surjective IsPrincipalIdealRing.of_surjectiveₓ'. -/
/-- The surjective image of a principal ideal ring is again a principal ideal ring. -/
theorem IsPrincipalIdealRing.of_surjective [IsPrincipalIdealRing R] (f : R →+* S)
    (hf : Function.Surjective f) : IsPrincipalIdealRing S :=
  ⟨fun I => Ideal.IsPrincipal.of_comap f hf I⟩
#align is_principal_ideal_ring.of_surjective IsPrincipalIdealRing.of_surjective

end Surjective

section

open Ideal

variable [CommRing R] [IsDomain R] [IsPrincipalIdealRing R] [GCDMonoid R]

#print span_gcd /-
theorem span_gcd (x y : R) : span ({gcd x y} : Set R) = span ({x, y} : Set R) :=
  by
  obtain ⟨d, hd⟩ := IsPrincipalIdealRing.principal (span ({x, y} : Set R))
  rw [submodule_span_eq] at hd
  rw [hd]
  suffices Associated d (gcd x y) by
    obtain ⟨D, HD⟩ := this
    rw [← HD]
    exact span_singleton_mul_right_unit D.is_unit _
  apply associated_of_dvd_dvd
  · rw [dvd_gcd_iff]
    constructor <;> rw [← Ideal.mem_span_singleton, ← hd, Ideal.mem_span_pair]
    · use 1, 0
      rw [one_mul, MulZeroClass.zero_mul, add_zero]
    · use 0, 1
      rw [one_mul, MulZeroClass.zero_mul, zero_add]
  · obtain ⟨r, s, rfl⟩ : ∃ r s, r * x + s * y = d := by
      rw [← Ideal.mem_span_pair, hd, Ideal.mem_span_singleton]
    apply dvd_add <;> apply dvd_mul_of_dvd_right
    exacts[gcd_dvd_left x y, gcd_dvd_right x y]
#align span_gcd span_gcd
-/

/- warning: gcd_dvd_iff_exists -> gcd_dvd_iff_exists is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] (a : R) (b : R) {z : R}, Iff (Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) (GCDMonoid.gcd.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2) _inst_4 a b) z) (Exists.{succ u1} R (fun (x : R) => Exists.{succ u1} R (fun (y : R) => Eq.{succ u1} R z (HAdd.hAdd.{u1, u1, u1} R R R (instHAdd.{u1} R (Distrib.toHasAdd.{u1} R (Ring.toDistrib.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (Ring.toDistrib.{u1} R (CommRing.toRing.{u1} R _inst_1)))) a x) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (Ring.toDistrib.{u1} R (CommRing.toRing.{u1} R _inst_1)))) b y)))))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] (a : R) (b : R) {z : R}, Iff (Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) (GCDMonoid.gcd.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2) _inst_4 a b) z) (Exists.{succ u1} R (fun (x : R) => Exists.{succ u1} R (fun (y : R) => Eq.{succ u1} R z (HAdd.hAdd.{u1, u1, u1} R R R (instHAdd.{u1} R (Distrib.toAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1))))))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocRing.toMul.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1))))) a x) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocRing.toMul.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1))))) b y)))))
Case conversion may be inaccurate. Consider using '#align gcd_dvd_iff_exists gcd_dvd_iff_existsₓ'. -/
theorem gcd_dvd_iff_exists (a b : R) {z} : gcd a b ∣ z ↔ ∃ x y, z = a * x + b * y := by
  simp_rw [mul_comm a, mul_comm b, @eq_comm _ z, ← Ideal.mem_span_pair, ← span_gcd,
    Ideal.mem_span_singleton]
#align gcd_dvd_iff_exists gcd_dvd_iff_exists

/- warning: exists_gcd_eq_mul_add_mul -> exists_gcd_eq_mul_add_mul is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] (a : R) (b : R), Exists.{succ u1} R (fun (x : R) => Exists.{succ u1} R (fun (y : R) => Eq.{succ u1} R (GCDMonoid.gcd.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2) _inst_4 a b) (HAdd.hAdd.{u1, u1, u1} R R R (instHAdd.{u1} R (Distrib.toHasAdd.{u1} R (Ring.toDistrib.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (Ring.toDistrib.{u1} R (CommRing.toRing.{u1} R _inst_1)))) a x) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (Ring.toDistrib.{u1} R (CommRing.toRing.{u1} R _inst_1)))) b y))))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] (a : R) (b : R), Exists.{succ u1} R (fun (x : R) => Exists.{succ u1} R (fun (y : R) => Eq.{succ u1} R (GCDMonoid.gcd.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2) _inst_4 a b) (HAdd.hAdd.{u1, u1, u1} R R R (instHAdd.{u1} R (Distrib.toAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1))))))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocRing.toMul.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1))))) a x) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocRing.toMul.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1))))) b y))))
Case conversion may be inaccurate. Consider using '#align exists_gcd_eq_mul_add_mul exists_gcd_eq_mul_add_mulₓ'. -/
/-- **Bézout's lemma** -/
theorem exists_gcd_eq_mul_add_mul (a b : R) : ∃ x y, gcd a b = a * x + b * y := by
  rw [← gcd_dvd_iff_exists]
#align exists_gcd_eq_mul_add_mul exists_gcd_eq_mul_add_mul

/- warning: gcd_is_unit_iff -> gcd_isUnit_iff is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] (x : R) (y : R), Iff (IsUnit.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)) (GCDMonoid.gcd.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2) _inst_4 x y)) (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) x y)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] (x : R) (y : R), Iff (IsUnit.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (GCDMonoid.gcd.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2) _inst_4 x y)) (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) x y)
Case conversion may be inaccurate. Consider using '#align gcd_is_unit_iff gcd_isUnit_iffₓ'. -/
theorem gcd_isUnit_iff (x y : R) : IsUnit (gcd x y) ↔ IsCoprime x y := by
  rw [IsCoprime, ← Ideal.mem_span_pair, ← span_gcd, ← span_singleton_eq_top, eq_top_iff_one]
#align gcd_is_unit_iff gcd_isUnit_iff

/- warning: is_coprime_of_dvd -> isCoprime_of_dvd is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] (x : R) (y : R), (Not (And (Eq.{succ u1} R x (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))))))) (Eq.{succ u1} R y (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))))))))) -> (forall (z : R), (Membership.Mem.{u1, u1} R (Set.{u1} R) (Set.hasMem.{u1} R) z (nonunits.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)))) -> (Ne.{succ u1} R z (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))))))) -> (Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) z x) -> (Not (Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) z y))) -> (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) x y)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] (x : R) (y : R), (Not (And (Eq.{succ u1} R x (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (CommMonoidWithZero.toZero.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)))))) (Eq.{succ u1} R y (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (CommMonoidWithZero.toZero.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)))))))) -> (forall (z : R), (Membership.mem.{u1, u1} R (Set.{u1} R) (Set.instMembershipSet.{u1} R) z (nonunits.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) -> (Ne.{succ u1} R z (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (CommMonoidWithZero.toZero.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)))))) -> (Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) z x) -> (Not (Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) z y))) -> (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) x y)
Case conversion may be inaccurate. Consider using '#align is_coprime_of_dvd isCoprime_of_dvdₓ'. -/
-- this should be proved for UFDs surely?
theorem isCoprime_of_dvd (x y : R) (nonzero : ¬(x = 0 ∧ y = 0))
    (H : ∀ z ∈ nonunits R, z ≠ 0 → z ∣ x → ¬z ∣ y) : IsCoprime x y :=
  by
  rw [← gcd_isUnit_iff]
  by_contra h
  refine' H _ h _ (gcd_dvd_left _ _) (gcd_dvd_right _ _)
  rwa [Ne, gcd_eq_zero_iff]
#align is_coprime_of_dvd isCoprime_of_dvd

/- warning: dvd_or_coprime -> dvd_or_coprime is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] (x : R) (y : R), (Irreducible.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)) x) -> (Or (Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) x y) (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) x y))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] (x : R) (y : R), (Irreducible.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) x) -> (Or (Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) x y) (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) x y))
Case conversion may be inaccurate. Consider using '#align dvd_or_coprime dvd_or_coprimeₓ'. -/
-- this should be proved for UFDs surely?
theorem dvd_or_coprime (x y : R) (h : Irreducible x) : x ∣ y ∨ IsCoprime x y :=
  by
  refine' or_iff_not_imp_left.2 fun h' => _
  apply isCoprime_of_dvd
  · rintro ⟨rfl, rfl⟩
    simpa using h
  · rintro z nu nz ⟨w, rfl⟩ dy
    refine' h' (dvd_trans _ dy)
    simpa using mul_dvd_mul_left z (isUnit_iff_dvd_one.1 <| (of_irreducible_mul h).resolve_left nu)
#align dvd_or_coprime dvd_or_coprime

/- warning: is_coprime_of_irreducible_dvd -> isCoprime_of_irreducible_dvd is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {x : R} {y : R}, (Not (And (Eq.{succ u1} R x (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))))))) (Eq.{succ u1} R y (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))))))))) -> (forall (z : R), (Irreducible.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)) z) -> (Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) z x) -> (Not (Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) z y))) -> (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) x y)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {x : R} {y : R}, (Not (And (Eq.{succ u1} R x (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (CommMonoidWithZero.toZero.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)))))) (Eq.{succ u1} R y (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (CommMonoidWithZero.toZero.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)))))))) -> (forall (z : R), (Irreducible.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) z) -> (Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) z x) -> (Not (Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) z y))) -> (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) x y)
Case conversion may be inaccurate. Consider using '#align is_coprime_of_irreducible_dvd isCoprime_of_irreducible_dvdₓ'. -/
theorem isCoprime_of_irreducible_dvd {x y : R} (nonzero : ¬(x = 0 ∧ y = 0))
    (H : ∀ z : R, Irreducible z → z ∣ x → ¬z ∣ y) : IsCoprime x y :=
  by
  apply isCoprime_of_dvd x y nonzero
  intro z znu znz zx zy
  obtain ⟨i, h1, h2⟩ := WfDvdMonoid.exists_irreducible_factor znu znz
  apply H i h1 <;>
    · apply dvd_trans h2
      assumption
#align is_coprime_of_irreducible_dvd isCoprime_of_irreducible_dvd

/- warning: is_coprime_of_prime_dvd -> isCoprime_of_prime_dvd is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {x : R} {y : R}, (Not (And (Eq.{succ u1} R x (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))))))) (Eq.{succ u1} R y (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1)))))))))))) -> (forall (z : R), (Prime.{u1} R (CommSemiring.toCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1)) z) -> (Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) z x) -> (Not (Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) z y))) -> (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) x y)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {x : R} {y : R}, (Not (And (Eq.{succ u1} R x (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (CommMonoidWithZero.toZero.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)))))) (Eq.{succ u1} R y (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (CommMonoidWithZero.toZero.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)))))))) -> (forall (z : R), (Prime.{u1} R (CancelCommMonoidWithZero.toCommMonoidWithZero.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)) z) -> (Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) z x) -> (Not (Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) z y))) -> (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) x y)
Case conversion may be inaccurate. Consider using '#align is_coprime_of_prime_dvd isCoprime_of_prime_dvdₓ'. -/
theorem isCoprime_of_prime_dvd {x y : R} (nonzero : ¬(x = 0 ∧ y = 0))
    (H : ∀ z : R, Prime z → z ∣ x → ¬z ∣ y) : IsCoprime x y :=
  isCoprime_of_irreducible_dvd nonzero fun z zi => H z <| GCDMonoid.prime_of_irreducible zi
#align is_coprime_of_prime_dvd isCoprime_of_prime_dvd

/- warning: irreducible.coprime_iff_not_dvd -> Irreducible.coprime_iff_not_dvd is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {p : R} {n : R}, (Irreducible.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)) p) -> (Iff (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) p n) (Not (Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) p n)))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {p : R} {n : R}, (Irreducible.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) p) -> (Iff (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) p n) (Not (Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) p n)))
Case conversion may be inaccurate. Consider using '#align irreducible.coprime_iff_not_dvd Irreducible.coprime_iff_not_dvdₓ'. -/
theorem Irreducible.coprime_iff_not_dvd {p n : R} (pp : Irreducible p) : IsCoprime p n ↔ ¬p ∣ n :=
  by
  constructor
  · intro co H
    apply pp.not_unit
    rw [isUnit_iff_dvd_one]
    apply IsCoprime.dvd_of_dvd_mul_left co
    rw [mul_one n]
    exact H
  · intro nd
    apply isCoprime_of_irreducible_dvd
    · rintro ⟨hp, -⟩
      exact pp.ne_zero hp
    rintro z zi zp zn
    exact nd ((zi.associated_of_dvd pp zp).symm.Dvd.trans zn)
#align irreducible.coprime_iff_not_dvd Irreducible.coprime_iff_not_dvd

#print Prime.coprime_iff_not_dvd /-
theorem Prime.coprime_iff_not_dvd {p n : R} (pp : Prime p) : IsCoprime p n ↔ ¬p ∣ n :=
  pp.Irreducible.coprime_iff_not_dvd
#align prime.coprime_iff_not_dvd Prime.coprime_iff_not_dvd
-/

/- warning: irreducible.dvd_iff_not_coprime -> Irreducible.dvd_iff_not_coprime is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {p : R} {n : R}, (Irreducible.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)) p) -> (Iff (Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) p n) (Not (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) p n)))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {p : R} {n : R}, (Irreducible.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) p) -> (Iff (Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) p n) (Not (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) p n)))
Case conversion may be inaccurate. Consider using '#align irreducible.dvd_iff_not_coprime Irreducible.dvd_iff_not_coprimeₓ'. -/
theorem Irreducible.dvd_iff_not_coprime {p n : R} (hp : Irreducible p) : p ∣ n ↔ ¬IsCoprime p n :=
  iff_not_comm.2 hp.coprime_iff_not_dvd
#align irreducible.dvd_iff_not_coprime Irreducible.dvd_iff_not_coprime

/- warning: irreducible.coprime_pow_of_not_dvd -> Irreducible.coprime_pow_of_not_dvd is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {p : R} {a : R} (m : Nat), (Irreducible.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)) p) -> (Not (Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) p a)) -> (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) a (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)))) p m))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {p : R} {a : R} (m : Nat), (Irreducible.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) p) -> (Not (Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) p a)) -> (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) a (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) p m))
Case conversion may be inaccurate. Consider using '#align irreducible.coprime_pow_of_not_dvd Irreducible.coprime_pow_of_not_dvdₓ'. -/
theorem Irreducible.coprime_pow_of_not_dvd {p a : R} (m : ℕ) (hp : Irreducible p) (h : ¬p ∣ a) :
    IsCoprime a (p ^ m) :=
  (hp.coprime_iff_not_dvd.2 h).symm.pow_right
#align irreducible.coprime_pow_of_not_dvd Irreducible.coprime_pow_of_not_dvd

/- warning: irreducible.coprime_or_dvd -> Irreducible.coprime_or_dvd is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {p : R}, (Irreducible.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)) p) -> (forall (i : R), Or (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) p i) (Dvd.Dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) p i))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {p : R}, (Irreducible.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) p) -> (forall (i : R), Or (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) p i) (Dvd.dvd.{u1} R (semigroupDvd.{u1} R (SemigroupWithZero.toSemigroup.{u1} R (NonUnitalSemiring.toSemigroupWithZero.{u1} R (NonUnitalRing.toNonUnitalSemiring.{u1} R (NonUnitalCommRing.toNonUnitalRing.{u1} R (CommRing.toNonUnitalCommRing.{u1} R _inst_1)))))) p i))
Case conversion may be inaccurate. Consider using '#align irreducible.coprime_or_dvd Irreducible.coprime_or_dvdₓ'. -/
theorem Irreducible.coprime_or_dvd {p : R} (hp : Irreducible p) (i : R) : IsCoprime p i ∨ p ∣ i :=
  (em _).imp_right hp.dvd_iff_not_coprime.2
#align irreducible.coprime_or_dvd Irreducible.coprime_or_dvd

/- warning: exists_associated_pow_of_mul_eq_pow' -> exists_associated_pow_of_mul_eq_pow' is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {a : R} {b : R} {c : R}, (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) a b) -> (forall {k : Nat}, (Eq.{succ u1} R (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (Ring.toDistrib.{u1} R (CommRing.toRing.{u1} R _inst_1)))) a b) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)))) c k)) -> (Exists.{succ u1} R (fun (d : R) => Associated.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (Ring.toMonoid.{u1} R (CommRing.toRing.{u1} R _inst_1)))) d k) a)))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] [_inst_2 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))] [_inst_3 : IsPrincipalIdealRing.{u1} R (CommRing.toRing.{u1} R _inst_1)] [_inst_4 : GCDMonoid.{u1} R (IsDomain.toCancelCommMonoidWithZero.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) _inst_2)] {a : R} {b : R} {c : R}, (IsCoprime.{u1} R (CommRing.toCommSemiring.{u1} R _inst_1) a b) -> (forall {k : Nat}, (Eq.{succ u1} R (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocRing.toMul.{u1} R (NonAssocRing.toNonUnitalNonAssocRing.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_1))))) a b) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) c k)) -> (Exists.{succ u1} R (fun (d : R) => Associated.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))))) d k) a)))
Case conversion may be inaccurate. Consider using '#align exists_associated_pow_of_mul_eq_pow' exists_associated_pow_of_mul_eq_pow'ₓ'. -/
theorem exists_associated_pow_of_mul_eq_pow' {a b c : R} (hab : IsCoprime a b) {k : ℕ}
    (h : a * b = c ^ k) : ∃ d, Associated (d ^ k) a :=
  exists_associated_pow_of_mul_eq_pow ((gcd_isUnit_iff _ _).mpr hab) h
#align exists_associated_pow_of_mul_eq_pow' exists_associated_pow_of_mul_eq_pow'

end

section PrincipalOfPrime

open Set Ideal

variable (R) [CommRing R]

#print nonPrincipals /-
/-- `non_principals R` is the set of all ideals of `R` that are not principal ideals. -/
def nonPrincipals :=
  { I : Ideal R | ¬I.IsPrincipal }
#align non_principals nonPrincipals
-/

#print nonPrincipals_def /-
theorem nonPrincipals_def {I : Ideal R} : I ∈ nonPrincipals R ↔ ¬I.IsPrincipal :=
  Iff.rfl
#align non_principals_def nonPrincipals_def
-/

variable {R}

#print nonPrincipals_eq_empty_iff /-
theorem nonPrincipals_eq_empty_iff : nonPrincipals R = ∅ ↔ IsPrincipalIdealRing R := by
  simp [Set.eq_empty_iff_forall_not_mem, isPrincipalIdealRing_iff, nonPrincipals_def]
#align non_principals_eq_empty_iff nonPrincipals_eq_empty_iff
-/

/- warning: non_principals_zorn -> nonPrincipals_zorn is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] (c : Set.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))), (HasSubset.Subset.{u1} (Set.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (Set.hasSubset.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) c (nonPrincipals.{u1} R _inst_1)) -> (IsChain.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (LE.le.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Preorder.toLE.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (PartialOrder.toPreorder.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (SetLike.partialOrder.{u1, u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) R (Submodule.setLike.{u1, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))))))) c) -> (forall {K : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))}, (Membership.Mem.{u1, u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Set.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (Set.hasMem.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) K c) -> (Exists.{succ u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (fun (I : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) => Exists.{0} (Membership.Mem.{u1, u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Set.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (Set.hasMem.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) I (nonPrincipals.{u1} R _inst_1)) (fun (H : Membership.Mem.{u1, u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Set.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (Set.hasMem.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) I (nonPrincipals.{u1} R _inst_1)) => forall (J : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))), (Membership.Mem.{u1, u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Set.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (Set.hasMem.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) J c) -> (LE.le.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Preorder.toLE.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (PartialOrder.toPreorder.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (SetLike.partialOrder.{u1, u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) R (Submodule.setLike.{u1, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))))) J I)))))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommRing.{u1} R] (c : Set.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))), (HasSubset.Subset.{u1} (Set.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (Set.instHasSubsetSet.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) c (nonPrincipals.{u1} R _inst_1)) -> (IsChain.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (fun (x._@.Mathlib.RingTheory.PrincipalIdealDomain._hyg.4580 : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (x._@.Mathlib.RingTheory.PrincipalIdealDomain._hyg.4582 : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) => LE.le.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Preorder.toLE.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (PartialOrder.toPreorder.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (OmegaCompletePartialOrder.toPartialOrder.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (CompleteLattice.instOmegaCompletePartialOrder.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Submodule.completeLattice.{u1, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))))))) x._@.Mathlib.RingTheory.PrincipalIdealDomain._hyg.4580 x._@.Mathlib.RingTheory.PrincipalIdealDomain._hyg.4582) c) -> (forall {K : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))}, (Membership.mem.{u1, u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Set.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (Set.instMembershipSet.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) K c) -> (Exists.{succ u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (fun (I : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) => And (Membership.mem.{u1, u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Set.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (Set.instMembershipSet.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) I (nonPrincipals.{u1} R _inst_1)) (forall (J : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))), (Membership.mem.{u1, u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Set.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) (Set.instMembershipSet.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))) J c) -> (LE.le.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Preorder.toLE.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (PartialOrder.toPreorder.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (OmegaCompletePartialOrder.toPartialOrder.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (CompleteLattice.instOmegaCompletePartialOrder.{u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))) (Submodule.completeLattice.{u1, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_1)))))))) J I)))))
Case conversion may be inaccurate. Consider using '#align non_principals_zorn nonPrincipals_zornₓ'. -/
/-- Any chain in the set of non-principal ideals has an upper bound which is non-principal.
(Namely, the union of the chain is such an upper bound.)
-/
theorem nonPrincipals_zorn (c : Set (Ideal R)) (hs : c ⊆ nonPrincipals R)
    (hchain : IsChain (· ≤ ·) c) {K : Ideal R} (hKmem : K ∈ c) :
    ∃ I ∈ nonPrincipals R, ∀ J ∈ c, J ≤ I :=
  by
  refine' ⟨Sup c, _, fun J hJ => le_supₛ hJ⟩
  rintro ⟨x, hx⟩
  have hxmem : x ∈ Sup c := hx.symm ▸ Submodule.mem_span_singleton_self x
  obtain ⟨J, hJc, hxJ⟩ := (Submodule.mem_supₛ_of_directed ⟨K, hKmem⟩ hchain.directed_on).1 hxmem
  have hSupJ : Sup c = J := le_antisymm (by simp [hx, Ideal.span_le, hxJ]) (le_supₛ hJc)
  specialize hs hJc
  rw [← hSupJ, hx, nonPrincipals_def] at hs
  exact hs ⟨⟨x, rfl⟩⟩
#align non_principals_zorn nonPrincipals_zorn

#print IsPrincipalIdealRing.of_prime /-
/-- If all prime ideals in a commutative ring are principal, so are all other ideals. -/
theorem IsPrincipalIdealRing.of_prime (H : ∀ P : Ideal R, P.IsPrime → P.IsPrincipal) :
    IsPrincipalIdealRing R :=
  by
  -- Suppose the set of `non_principals` is not empty.
  rw [← nonPrincipals_eq_empty_iff, Set.eq_empty_iff_forall_not_mem]
  intro J hJ
  -- We will show a maximal element `I ∈ non_principals R` (which exists by Zorn) is prime.
  obtain ⟨I, Ibad, -, Imax⟩ := zorn_nonempty_partialOrder₀ (nonPrincipals R) nonPrincipals_zorn _ hJ
  have Imax' : ∀ {J}, I < J → J.IsPrincipal :=
    by
    intro J hJ
    by_contra He
    exact hJ.ne (Imax _ ((nonPrincipals_def R).2 He) hJ.le).symm
  by_cases hI1 : I = ⊤
  · subst hI1
    exact Ibad top_isPrincipal
  -- Let `x y : R` with `x * y ∈ I` and suppose WLOG `y ∉ I`.
  refine' Ibad (H I ⟨hI1, fun x y hxy => or_iff_not_imp_right.mpr fun hy => _⟩)
  obtain ⟨a, ha⟩ : (I ⊔ span {y}).IsPrincipal :=
    Imax' (left_lt_sup.mpr (mt I.span_singleton_le_iff_mem.mp hy))
  -- Then `x ∈ I.colon (span {y})`, which is equal to `I` if it's not principal.
  suffices He : ¬(I.colon (span {y})).IsPrincipal
  · rw [←
      Imax _ ((nonPrincipals_def R).2 He) fun a ha =>
        Ideal.mem_colon_singleton.2 (mul_mem_right _ _ ha)]
    exact Ideal.mem_colon_singleton.2 hxy
  -- So suppose for the sake of contradiction that both `I ⊔ span {y}` and `I.colon (span {y})`
  -- are principal.
  rintro ⟨b, hb⟩
  -- We will show `I` is generated by `a * b`.
  refine'
    (nonPrincipals_def _).1 Ibad
      ⟨⟨a * b, (le_antisymm fun i hi => _) <| (span_singleton_mul_span_singleton a b).ge.trans _⟩⟩
  · have hisup : i ∈ I ⊔ span {y} := Ideal.mem_sup_left hi
    have : y ∈ I ⊔ span {y} := Ideal.mem_sup_right (Ideal.mem_span_singleton_self y)
    erw [ha, mem_span_singleton'] at hisup this
    obtain ⟨v, rfl⟩ := this
    obtain ⟨u, rfl⟩ := hisup
    have hucolon : u ∈ I.colon (span {v * a}) :=
      by
      rw [Ideal.mem_colon_singleton, mul_comm v, ← mul_assoc]
      exact mul_mem_right _ _ hi
    erw [hb, mem_span_singleton'] at hucolon
    obtain ⟨z, rfl⟩ := hucolon
    exact mem_span_singleton'.2 ⟨z, by ring⟩
  · rw [← Ideal.submodule_span_eq, ← ha, Ideal.sup_mul, sup_le_iff,
      span_singleton_mul_span_singleton, mul_comm y, Ideal.span_singleton_le_iff_mem]
    exact ⟨mul_le_right, Ideal.mem_colon_singleton.1 <| hb.symm ▸ Ideal.mem_span_singleton_self b⟩
#align is_principal_ideal_ring.of_prime IsPrincipalIdealRing.of_prime
-/

end PrincipalOfPrime