l3lab/ntp-mathlib huggingface dataset:
instance (priority := 100) LinearOrderedRing.noZeroDivisors : NoZeroDivisors α :=
  { ‹LinearOrderedRing α› with
    eq_zero_or_eq_zero_of_mul_eq_zero := by
      intro a b hab
      refine' Decidable.or_iff_not_and_not.2 fun h => _; revert hab
      cases' lt_or_gt_of_ne h.1 with ha ha <;> cases' lt_or_gt_of_ne h.2 with hb hb
      

Proof state:
case inl.inl
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c : α
src✝ : LinearOrderedRing α := inst✝
a b : α
h : ¬a = 0 ∧ ¬b = 0
ha : a < 0
hb : b < 0
⊢ a * b = 0 → False
case inl.inr
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c : α
src✝ : LinearOrderedRing α := inst✝
a b : α
h : ¬a = 0 ∧ ¬b = 0
ha : a < 0
hb : b > 0
⊢ a * b = 0 → False
case inr.inl
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c : α
src✝ : LinearOrderedRing α := inst✝
a b : α
h : ¬a = 0 ∧ ¬b = 0
ha : a > 0
hb : b < 0
⊢ a * b = 0 → False
case inr.inr
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c : α
src✝ : LinearOrderedRing α := inst✝
a b : α
h : ¬a = 0 ∧ ¬b = 0
ha : a > 0
hb : b > 0
⊢ a * b = 0 → False

Next tactic:
exacts [(mul_pos_of_neg_of_neg ha hb).ne.symm, (mul_neg_of_neg_of_pos ha hb).ne,
        (mul_neg_of_pos_of_neg ha hb).ne, (mul_pos ha hb).ne.symm]
instance (priority := 100) LinearOrderedRing.isDomain : IsDomain α :=
  { (inferInstance : Nontrivial α) with
    mul_left_cancel_of_ne_zero := fun {a b c} ha h => by
      

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c✝ : α
src✝ : Nontrivial α := inferInstance
a b c : α
ha : a ≠ 0
h : a * b = a * c
⊢ b = c

Next tactic:
rw [← sub_eq_zero, ← mul_sub] at h
instance (priority := 100) LinearOrderedRing.isDomain : IsDomain α :=
  { (inferInstance : Nontrivial α) with
    mul_left_cancel_of_ne_zero := fun {a b c} ha h => by
      rw [← sub_eq_zero, ← mul_sub] at h
      

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c✝ : α
src✝ : Nontrivial α := inferInstance
a b c : α
ha : a ≠ 0
h : a * (b - c) = 0
⊢ b = c

Next tactic:
exact sub_eq_zero.1 ((eq_zero_or_eq_zero_of_mul_eq_zero h).resolve_left ha)
instance (priority := 100) LinearOrderedRing.isDomain : IsDomain α :=
  { (inferInstance : Nontrivial α) with
    mul_left_cancel_of_ne_zero := fun {a b c} ha h => by
      rw [← sub_eq_zero, ← mul_sub] at h
      exact sub_eq_zero.1 ((eq_zero_or_eq_zero_of_mul_eq_zero h).resolve_left ha),
    mul_right_cancel_of_ne_zero := fun {a b c} hb h => by
      

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c✝ : α
src✝ : Nontrivial α := inferInstance
a b c : α
hb : b ≠ 0
h : a * b = c * b
⊢ a = c

Next tactic:
rw [← sub_eq_zero, ← sub_mul] at h
instance (priority := 100) LinearOrderedRing.isDomain : IsDomain α :=
  { (inferInstance : Nontrivial α) with
    mul_left_cancel_of_ne_zero := fun {a b c} ha h => by
      rw [← sub_eq_zero, ← mul_sub] at h
      exact sub_eq_zero.1 ((eq_zero_or_eq_zero_of_mul_eq_zero h).resolve_left ha),
    mul_right_cancel_of_ne_zero := fun {a b c} hb h => by
      rw [← sub_eq_zero, ← sub_mul] at h
      

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c✝ : α
src✝ : Nontrivial α := inferInstance
a b c : α
hb : b ≠ 0
h : (a - c) * b = 0
⊢ a = c

Next tactic:
exact sub_eq_zero.1 ((eq_zero_or_eq_zero_of_mul_eq_zero h).resolve_right hb)
theorem mul_neg_iff : a * b < 0 ↔ 0 < a ∧ b < 0 ∨ a < 0 ∧ 0 < b := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a b c : α
⊢ a * b < 0 ↔ 0 < a ∧ b < 0 ∨ a < 0 ∧ 0 < b

Next tactic:
rw [← neg_pos, neg_mul_eq_mul_neg, mul_pos_iff, neg_pos, neg_lt_zero]
/-- Out of three elements of a `LinearOrderedRing`, two must have the same sign. -/
theorem mul_nonneg_of_three (a b c : α) : 0 ≤ a * b ∨ 0 ≤ b * c ∨ 0 ≤ c * a := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c✝ a b c : α
⊢ 0 ≤ a * b ∨ 0 ≤ b * c ∨ 0 ≤ c * a

Next tactic:
iterate 3 rw [mul_nonneg_iff]
/-- Out of three elements of a `LinearOrderedRing`, two must have the same sign. -/
theorem mul_nonneg_of_three (a b c : α) : 0 ≤ a * b ∨ 0 ≤ b * c ∨ 0 ≤ c * a := by
  iterate 3 

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c✝ a b c : α
⊢ 0 ≤ a * b ∨ 0 ≤ b * c ∨ 0 ≤ c * a

Next tactic:
rw [mul_nonneg_iff]
/-- Out of three elements of a `LinearOrderedRing`, two must have the same sign. -/
theorem mul_nonneg_of_three (a b c : α) : 0 ≤ a * b ∨ 0 ≤ b * c ∨ 0 ≤ c * a := by
  iterate 3 

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c✝ a b c : α
⊢ (0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0) ∨ 0 ≤ b * c ∨ 0 ≤ c * a

Next tactic:
rw [mul_nonneg_iff]
/-- Out of three elements of a `LinearOrderedRing`, two must have the same sign. -/
theorem mul_nonneg_of_three (a b c : α) : 0 ≤ a * b ∨ 0 ≤ b * c ∨ 0 ≤ c * a := by
  iterate 3 

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c✝ a b c : α
⊢ (0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0) ∨ (0 ≤ b ∧ 0 ≤ c ∨ b ≤ 0 ∧ c ≤ 0) ∨ 0 ≤ c * a

Next tactic:
rw [mul_nonneg_iff]
/-- Out of three elements of a `LinearOrderedRing`, two must have the same sign. -/
theorem mul_nonneg_of_three (a b c : α) : 0 ≤ a * b ∨ 0 ≤ b * c ∨ 0 ≤ c * a := by
  iterate 3 rw [mul_nonneg_iff]
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c✝ a b c : α
⊢ (0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0) ∨ (0 ≤ b ∧ 0 ≤ c ∨ b ≤ 0 ∧ c ≤ 0) ∨ 0 ≤ c ∧ 0 ≤ a ∨ c ≤ 0 ∧ a ≤ 0

Next tactic:
have or_a := le_total 0 a
/-- Out of three elements of a `LinearOrderedRing`, two must have the same sign. -/
theorem mul_nonneg_of_three (a b c : α) : 0 ≤ a * b ∨ 0 ≤ b * c ∨ 0 ≤ c * a := by
  iterate 3 rw [mul_nonneg_iff]
  have or_a := le_total 0 a
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c✝ a b c : α
or_a : 0 ≤ a ∨ a ≤ 0
⊢ (0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0) ∨ (0 ≤ b ∧ 0 ≤ c ∨ b ≤ 0 ∧ c ≤ 0) ∨ 0 ≤ c ∧ 0 ≤ a ∨ c ≤ 0 ∧ a ≤ 0

Next tactic:
have or_b := le_total 0 b
/-- Out of three elements of a `LinearOrderedRing`, two must have the same sign. -/
theorem mul_nonneg_of_three (a b c : α) : 0 ≤ a * b ∨ 0 ≤ b * c ∨ 0 ≤ c * a := by
  iterate 3 rw [mul_nonneg_iff]
  have or_a := le_total 0 a
  have or_b := le_total 0 b
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c✝ a b c : α
or_a : 0 ≤ a ∨ a ≤ 0
or_b : 0 ≤ b ∨ b ≤ 0
⊢ (0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0) ∨ (0 ≤ b ∧ 0 ≤ c ∨ b ≤ 0 ∧ c ≤ 0) ∨ 0 ≤ c ∧ 0 ≤ a ∨ c ≤ 0 ∧ a ≤ 0

Next tactic:
have or_c := le_total 0 c
/-- Out of three elements of a `LinearOrderedRing`, two must have the same sign. -/
theorem mul_nonneg_of_three (a b c : α) : 0 ≤ a * b ∨ 0 ≤ b * c ∨ 0 ≤ c * a := by
  iterate 3 rw [mul_nonneg_iff]
  have or_a := le_total 0 a
  have or_b := le_total 0 b
  have or_c := le_total 0 c
  -- Porting note used to be by `itauto` from here
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c✝ a b c : α
or_a : 0 ≤ a ∨ a ≤ 0
or_b : 0 ≤ b ∨ b ≤ 0
or_c : 0 ≤ c ∨ c ≤ 0
⊢ (0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0) ∨ (0 ≤ b ∧ 0 ≤ c ∨ b ≤ 0 ∧ c ≤ 0) ∨ 0 ≤ c ∧ 0 ≤ a ∨ c ≤ 0 ∧ a ≤ 0

Next tactic:
exact Or.elim or_c
    (fun (h0 : 0 ≤ c) =>
      Or.elim or_b
        (fun (h1 : 0 ≤ b) =>
            Or.elim or_a (fun (h2 : 0 ≤ a) => Or.inl (Or.inl ⟨h2, h1⟩))
              (fun (_ : a ≤ 0) => Or.inr (Or.inl (Or.inl ⟨h1, h0⟩))))
        (fun (h1 : b ≤ 0) =>
            Or.elim or_a (fun (h3 : 0 ≤ a) => Or.inr (Or.inr (Or.inl ⟨h0, h3⟩)))
              (fun (h3 : a ≤ 0) => Or.inl (Or.inr ⟨h3, h1⟩))))
    (fun (h0 : c ≤ 0) =>
      Or.elim or_b
        (fun (h4 : 0 ≤ b) =>
            Or.elim or_a (fun (h5 : 0 ≤ a) => Or.inl (Or.inl ⟨h5, h4⟩))
              (fun (h5 : a ≤ 0) => Or.inr (Or.inr (Or.inr ⟨h0, h5⟩))))
        (fun (h4 : b ≤ 0) =>
            Or.elim or_a (fun (_ : 0 ≤ a) => Or.inr (Or.inl (Or.inr ⟨h4, h0⟩)))
              (fun (h6 : a ≤ 0) => Or.inl (Or.inr ⟨h6, h4⟩))))
theorem mul_nonpos_iff : a * b ≤ 0 ↔ 0 ≤ a ∧ b ≤ 0 ∨ a ≤ 0 ∧ 0 ≤ b := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a b c : α
⊢ a * b ≤ 0 ↔ 0 ≤ a ∧ b ≤ 0 ∨ a ≤ 0 ∧ 0 ≤ b

Next tactic:
rw [← neg_nonneg, neg_mul_eq_mul_neg, mul_nonneg_iff, neg_nonneg, neg_nonpos]
theorem lt_of_mul_lt_mul_of_nonpos_left (h : c * a < c * b) (hc : c ≤ 0) : b < a :=
  lt_of_mul_lt_mul_left (by 

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a b c : α
h : c * a < c * b
hc : c ≤ 0
⊢ -c * b < -c * a

Next tactic:
rwa [neg_mul, neg_mul, neg_lt_neg_iff]
theorem lt_of_mul_lt_mul_of_nonpos_right (h : a * c < b * c) (hc : c ≤ 0) : b < a :=
  lt_of_mul_lt_mul_right (by 

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a b c : α
h : a * c < b * c
hc : c ≤ 0
⊢ b * -c < a * -c

Next tactic:
rwa [mul_neg, mul_neg, neg_lt_neg_iff]
@[simp]
theorem mul_self_pos {a : α} : 0 < a * a ↔ a ≠ 0 := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b c a : α
⊢ 0 < a * a ↔ a ≠ 0

Next tactic:
constructor
@[simp]
theorem mul_self_pos {a : α} : 0 < a * a ↔ a ≠ 0 := by
  constructor
  · 

Proof state:
case mp
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b c a : α
⊢ 0 < a * a → a ≠ 0

Next tactic:
rintro h rfl
@[simp]
theorem mul_self_pos {a : α} : 0 < a * a ↔ a ≠ 0 := by
  constructor
  · rintro h rfl
    

Proof state:
case mp
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a b c : α
h : 0 < 0 * 0
⊢ False

Next tactic:
rw [mul_zero] at h
@[simp]
theorem mul_self_pos {a : α} : 0 < a * a ↔ a ≠ 0 := by
  constructor
  · rintro h rfl
    rw [mul_zero] at h
    

Proof state:
case mp
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a b c : α
h : 0 < 0
⊢ False

Next tactic:
exact h.false
@[simp]
theorem mul_self_pos {a : α} : 0 < a * a ↔ a ≠ 0 := by
  constructor
  · rintro h rfl
    rw [mul_zero] at h
    exact h.false
  · 

Proof state:
case mpr
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b c a : α
⊢ a ≠ 0 → 0 < a * a

Next tactic:
intro h
@[simp]
theorem mul_self_pos {a : α} : 0 < a * a ↔ a ≠ 0 := by
  constructor
  · rintro h rfl
    rw [mul_zero] at h
    exact h.false
  · intro h
    

Proof state:
case mpr
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b c a : α
h : a ≠ 0
⊢ 0 < a * a

Next tactic:
cases' h.lt_or_lt with h h
@[simp]
theorem mul_self_pos {a : α} : 0 < a * a ↔ a ≠ 0 := by
  constructor
  · rintro h rfl
    rw [mul_zero] at h
    exact h.false
  · intro h
    cases' h.lt_or_lt with h h
    

Proof state:
case mpr.inl
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b c a : α
h✝ : a ≠ 0
h : a < 0
⊢ 0 < a * a
case mpr.inr α : Type u β : Type u_1 inst✝ : LinearOrderedRing α a✝ b c a : α h✝ : a ≠ 0 h : 0 < a ⊢ 0 < a * a

Next tactic:
exacts [mul_pos_of_neg_of_neg h h, mul_pos h h]
/-- The sum of two squares is zero iff both elements are zero. -/
theorem mul_self_add_mul_self_eq_zero {x y : α} : x * x + y * y = 0 ↔ x = 0 ∧ y = 0 := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a b c x y : α
⊢ x * x + y * y = 0 ↔ x = 0 ∧ y = 0

Next tactic:
rw [add_eq_zero_iff', mul_self_eq_zero, mul_self_eq_zero]
/-- The sum of two squares is zero iff both elements are zero. -/
theorem mul_self_add_mul_self_eq_zero {x y : α} : x * x + y * y = 0 ↔ x = 0 ∧ y = 0 := by
  rw [add_eq_zero_iff', mul_self_eq_zero, mul_self_eq_zero] <;> 

Proof state:
case ha
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a b c x y : α
⊢ 0 ≤ x * x

Next tactic:
apply mul_self_nonneg
/-- The sum of two squares is zero iff both elements are zero. -/
theorem mul_self_add_mul_self_eq_zero {x y : α} : x * x + y * y = 0 ↔ x = 0 ∧ y = 0 := by
  rw [add_eq_zero_iff', mul_self_eq_zero, mul_self_eq_zero] <;> 

Proof state:
case hb
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a b c x y : α
⊢ 0 ≤ y * y

Next tactic:
apply mul_self_nonneg
theorem max_mul_mul_le_max_mul_max (b c : α) (ha : 0 ≤ a) (hd : 0 ≤ d) :
    max (a * b) (d * c) ≤ max a c * max d b :=
  have ba : b * a ≤ max d b * max c a :=
    mul_le_mul (le_max_right d b) (le_max_right c a) ha (le_trans hd (le_max_left d b))
  have cd : c * d ≤ max a c * max b d :=
    mul_le_mul (le_max_right a c) (le_max_right b d) hd (le_trans ha (le_max_left a c))
  max_le (by 

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedCommRing α
a b✝ c✝ d b c : α
ha : 0 ≤ a
hd : 0 ≤ d
ba : b * a ≤ max d b * max c a
cd : c * d ≤ max a c * max b d
⊢ a * b ≤ max a c * max d b

Next tactic:
simpa [mul_comm, max_comm] using ba
theorem max_mul_mul_le_max_mul_max (b c : α) (ha : 0 ≤ a) (hd : 0 ≤ d) :
    max (a * b) (d * c) ≤ max a c * max d b :=
  have ba : b * a ≤ max d b * max c a :=
    mul_le_mul (le_max_right d b) (le_max_right c a) ha (le_trans hd (le_max_left d b))
  have cd : c * d ≤ max a c * max b d :=
    mul_le_mul (le_max_right a c) (le_max_right b d) hd (le_trans ha (le_max_left a c))
  max_le (by simpa [mul_comm, max_comm] using ba) (by 

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedCommRing α
a b✝ c✝ d b c : α
ha : 0 ≤ a
hd : 0 ≤ d
ba : b * a ≤ max d b * max c a
cd : c * d ≤ max a c * max b d
⊢ d * c ≤ max a c * max d b

Next tactic:
simpa [mul_comm, max_comm] using cd
/-- If `hJ : J ⊆ supp v` then `onQuotVal hJ` is the induced function on `R / J` as a function.
Note: it's just the function; the valuation is `onQuot hJ`. -/
def onQuotVal {J : Ideal R} (hJ : J ≤ supp v) : R ⧸ J → Γ₀ := fun q =>
  Quotient.liftOn' q v fun a b h =>
    calc
      v a = v (b + -(-a + b)) := by 

Proof state:
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v : Valuation R Γ₀
J : Ideal R
hJ : J ≤ supp v
q : R ⧸ J
a b : R
h : Setoid.r a b
⊢ v a = v (b + -(-a + b))

Next tactic:
simp
theorem self_le_supp_comap (J : Ideal R) (v : Valuation (R ⧸ J) Γ₀) :
    J ≤ (v.comap (Ideal.Quotient.mk J)).supp := by
  

Proof state:
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v✝ : Valuation R Γ₀
J : Ideal R
v : Valuation (R ⧸ J) Γ₀
⊢ J ≤ supp (comap (Ideal.Quotient.mk J) v)

Next tactic:
rw [comap_supp, ← Ideal.map_le_iff_le_comap]
theorem self_le_supp_comap (J : Ideal R) (v : Valuation (R ⧸ J) Γ₀) :
    J ≤ (v.comap (Ideal.Quotient.mk J)).supp := by
  rw [comap_supp, ← Ideal.map_le_iff_le_comap]
  

Proof state:
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v✝ : Valuation R Γ₀
J : Ideal R
v : Valuation (R ⧸ J) Γ₀
⊢ Ideal.map (Ideal.Quotient.mk J) J ≤ supp v

Next tactic:
simp
@[simp]
theorem comap_onQuot_eq (J : Ideal R) (v : Valuation (R ⧸ J) Γ₀) :
    (v.comap (Ideal.Quotient.mk J)).onQuot (v.self_le_supp_comap J) = v :=
  ext <| by
    

Proof state:
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v✝ : Valuation R Γ₀
J : Ideal R
v : Valuation (R ⧸ J) Γ₀
⊢ ∀ (r : R ⧸ J), (onQuot (comap (Ideal.Quotient.mk J) v) (_ : J ≤ supp (comap (Ideal.Quotient.mk J) v))) r = v r

Next tactic:
rintro ⟨x⟩
@[simp]
theorem comap_onQuot_eq (J : Ideal R) (v : Valuation (R ⧸ J) Γ₀) :
    (v.comap (Ideal.Quotient.mk J)).onQuot (v.self_le_supp_comap J) = v :=
  ext <| by
    rintro ⟨x⟩
    

Proof state:
case mk
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v✝ : Valuation R Γ₀
J : Ideal R
v : Valuation (R ⧸ J) Γ₀
r✝ : R ⧸ J
x : R
⊢ (onQuot (comap (Ideal.Quotient.mk J) v) (_ : J ≤ supp (comap (Ideal.Quotient.mk J) v))) (Quot.mk Setoid.r x) =
    v (Quot.mk Setoid.r x)

Next tactic:
rfl
/-- The quotient valuation on `R / J` has support `(supp v) / J` if `J ⊆ supp v`. -/
theorem supp_quot {J : Ideal R} (hJ : J ≤ supp v) :
    supp (v.onQuot hJ) = (supp v).map (Ideal.Quotient.mk J) := by
  

Proof state:
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v : Valuation R Γ₀
J : Ideal R
hJ : J ≤ supp v
⊢ supp (onQuot v hJ) = Ideal.map (Ideal.Quotient.mk J) (supp v)

Next tactic:
apply le_antisymm
/-- The quotient valuation on `R / J` has support `(supp v) / J` if `J ⊆ supp v`. -/
theorem supp_quot {J : Ideal R} (hJ : J ≤ supp v) :
    supp (v.onQuot hJ) = (supp v).map (Ideal.Quotient.mk J) := by
  apply le_antisymm
  · 

Proof state:
case a
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v : Valuation R Γ₀
J : Ideal R
hJ : J ≤ supp v
⊢ supp (onQuot v hJ) ≤ Ideal.map (Ideal.Quotient.mk J) (supp v)

Next tactic:
rintro ⟨x⟩ hx
/-- The quotient valuation on `R / J` has support `(supp v) / J` if `J ⊆ supp v`. -/
theorem supp_quot {J : Ideal R} (hJ : J ≤ supp v) :
    supp (v.onQuot hJ) = (supp v).map (Ideal.Quotient.mk J) := by
  apply le_antisymm
  · rintro ⟨x⟩ hx
    

Proof state:
case a.mk
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v : Valuation R Γ₀
J : Ideal R
hJ : J ≤ supp v
x✝ : R ⧸ J
x : R
hx : Quot.mk Setoid.r x ∈ supp (onQuot v hJ)
⊢ Quot.mk Setoid.r x ∈ Ideal.map (Ideal.Quotient.mk J) (supp v)

Next tactic:
apply Ideal.subset_span
/-- The quotient valuation on `R / J` has support `(supp v) / J` if `J ⊆ supp v`. -/
theorem supp_quot {J : Ideal R} (hJ : J ≤ supp v) :
    supp (v.onQuot hJ) = (supp v).map (Ideal.Quotient.mk J) := by
  apply le_antisymm
  · rintro ⟨x⟩ hx
    apply Ideal.subset_span
    

Proof state:
case a.mk.a
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v : Valuation R Γ₀
J : Ideal R
hJ : J ≤ supp v
x✝ : R ⧸ J
x : R
hx : Quot.mk Setoid.r x ∈ supp (onQuot v hJ)
⊢ Quot.mk Setoid.r x ∈ ⇑(Ideal.Quotient.mk J) '' ↑(supp v)

Next tactic:
exact ⟨x, hx, rfl⟩
/-- The quotient valuation on `R / J` has support `(supp v) / J` if `J ⊆ supp v`. -/
theorem supp_quot {J : Ideal R} (hJ : J ≤ supp v) :
    supp (v.onQuot hJ) = (supp v).map (Ideal.Quotient.mk J) := by
  apply le_antisymm
  · rintro ⟨x⟩ hx
    apply Ideal.subset_span
    exact ⟨x, hx, rfl⟩
  · 

Proof state:
case a
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v : Valuation R Γ₀
J : Ideal R
hJ : J ≤ supp v
⊢ Ideal.map (Ideal.Quotient.mk J) (supp v) ≤ supp (onQuot v hJ)

Next tactic:
rw [Ideal.map_le_iff_le_comap]
/-- The quotient valuation on `R / J` has support `(supp v) / J` if `J ⊆ supp v`. -/
theorem supp_quot {J : Ideal R} (hJ : J ≤ supp v) :
    supp (v.onQuot hJ) = (supp v).map (Ideal.Quotient.mk J) := by
  apply le_antisymm
  · rintro ⟨x⟩ hx
    apply Ideal.subset_span
    exact ⟨x, hx, rfl⟩
  · rw [Ideal.map_le_iff_le_comap]
    

Proof state:
case a
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v : Valuation R Γ₀
J : Ideal R
hJ : J ≤ supp v
⊢ supp v ≤ Ideal.comap (Ideal.Quotient.mk J) (supp (onQuot v hJ))

Next tactic:
intro x hx
/-- The quotient valuation on `R / J` has support `(supp v) / J` if `J ⊆ supp v`. -/
theorem supp_quot {J : Ideal R} (hJ : J ≤ supp v) :
    supp (v.onQuot hJ) = (supp v).map (Ideal.Quotient.mk J) := by
  apply le_antisymm
  · rintro ⟨x⟩ hx
    apply Ideal.subset_span
    exact ⟨x, hx, rfl⟩
  · rw [Ideal.map_le_iff_le_comap]
    intro x hx
    

Proof state:
case a
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v : Valuation R Γ₀
J : Ideal R
hJ : J ≤ supp v
x : R
hx : x ∈ supp v
⊢ x ∈ Ideal.comap (Ideal.Quotient.mk J) (supp (onQuot v hJ))

Next tactic:
exact hx
theorem supp_quot_supp : supp (v.onQuot le_rfl) = 0 := by
  

Proof state:
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v : Valuation R Γ₀
⊢ supp (onQuot v (_ : supp v ≤ supp v)) = 0

Next tactic:
rw [supp_quot]
theorem supp_quot_supp : supp (v.onQuot le_rfl) = 0 := by
  rw [supp_quot]
  

Proof state:
R : Type u_1
Γ₀ : Type u_2
inst✝¹ : CommRing R
inst✝ : LinearOrderedCommMonoidWithZero Γ₀
v : Valuation R Γ₀
⊢ Ideal.map (Ideal.Quotient.mk (supp v)) (supp v) = 0

Next tactic:
exact Ideal.map_quotient_self _
/-- Let `P` be a prime ideal, `x ∈ P \ P²` and `x ∉ Q` for all prime ideals `Q ≠ P`.
Then `P` is generated by `x`. -/
theorem Ideal.eq_span_singleton_of_mem_of_not_mem_sq_of_not_mem_prime_ne {P : Ideal R}
    (hP : P.IsPrime) [IsDomain R] [IsDedekindDomain R] {x : R} (x_mem : x ∈ P) (hxP2 : x ∉ P ^ 2)
    (hxQ : ∀ Q : Ideal R, IsPrime Q → Q ≠ P → x ∉ Q) : P = Ideal.span {x} := by
  

Proof state:
R : Type u_1
inst✝² : CommRing R
P : Ideal R
hP : IsPrime P
inst✝¹ : IsDomain R
inst✝ : IsDedekindDomain R
x : R
x_mem : x ∈ P
hxP2 : x ∉ P ^ 2
hxQ : ∀ (Q : Ideal R), IsPrime Q → Q ≠ P → x ∉ Q
⊢ P = span {x}

Next tactic:
letI := Classical.decEq (Ideal R)
/-- Let `P` be a prime ideal, `x ∈ P \ P²` and `x ∉ Q` for all prime ideals `Q ≠ P`.
Then `P` is generated by `x`. -/
theorem Ideal.eq_span_singleton_of_mem_of_not_mem_sq_of_not_mem_prime_ne {P : Ideal R}
    (hP : P.IsPrime) [IsDomain R] [IsDedekindDomain R] {x : R} (x_mem : x ∈ P) (hxP2 : x ∉ P ^ 2)
    (hxQ : ∀ Q : Ideal R, IsPrime Q → Q ≠ P → x ∉ Q) : P = Ideal.span {x} := by
  letI := Classical.decEq (Ideal R)
  

Proof state:
R : Type u_1
inst✝² : CommRing R
P : Ideal R
hP : IsPrime P
inst✝¹ : IsDomain R
inst✝ : IsDedekindDomain R
x : R
x_mem : x ∈ P
hxP2 : x ∉ P ^ 2
hxQ : ∀ (Q : Ideal R), IsPrime Q → Q ≠ P → x ∉ Q
this : DecidableEq (Ideal R) := Classical.decEq (Ideal R)
⊢ P = span {x}

Next tactic:
have hx0 : x ≠ 0 := by
    rintro rfl
    exact hxP2 (zero_mem _)
/-- Let `P` be a prime ideal, `x ∈ P \ P²` and `x ∉ Q` for all prime ideals `Q ≠ P`.
Then `P` is generated by `x`. -/
theorem Ideal.eq_span_singleton_of_mem_of_not_mem_sq_of_not_mem_prime_ne {P : Ideal R}
    (hP : P.IsPrime) [IsDomain R] [IsDedekindDomain R] {x : R} (x_mem : x ∈ P) (hxP2 : x ∉ P ^ 2)
    (hxQ : ∀ Q : Ideal R, IsPrime Q → Q ≠ P → x ∉ Q) : P = Ideal.span {x} := by
  letI := Classical.decEq (Ideal R)
  have hx0 : x ≠ 0 := by
    

Proof state:
R : Type u_1
inst✝² : CommRing R
P : Ideal R
hP : IsPrime P
inst✝¹ : IsDomain R
inst✝ : IsDedekindDomain R
x : R
x_mem : x ∈ P
hxP2 : x ∉ P ^ 2
hxQ : ∀ (Q : Ideal R), IsPrime Q → Q ≠ P → x ∉ Q
this : DecidableEq (Ideal R) := Classical.decEq (Ideal R)
⊢ x ≠ 0

Next tactic:
rintro rfl
/-- Let `P` be a prime ideal, `x ∈ P \ P²` and `x ∉ Q` for all prime ideals `Q ≠ P`.
Then `P` is generated by `x`. -/
theorem Ideal.eq_span_singleton_of_mem_of_not_mem_sq_of_not_mem_prime_ne {P : Ideal R}
    (hP : P.IsPrime) [IsDomain R] [IsDedekindDomain R] {x : R} (x_mem : x ∈ P) (hxP2 : x ∉ P ^ 2)
    (hxQ : ∀ Q : Ideal R, IsPrime Q → Q ≠ P → x ∉ Q) : P = Ideal.span {x} := by
  letI := Classical.decEq (Ideal R)
  have hx0 : x ≠ 0 := by
    rintro rfl
    

Proof state:
R : Type u_1
inst✝² : CommRing R
P : Ideal R
hP : IsPrime P
inst✝¹ : IsDomain R
inst✝ : IsDedekindDomain R
this : DecidableEq (Ideal R) := Classical.decEq (Ideal R)
x_mem : 0 ∈ P
hxP2 : 0 ∉ P ^ 2
hxQ : ∀ (Q : Ideal R), IsPrime Q → Q ≠ P → 0 ∉ Q
⊢ False

Next tactic:
exact hxP2 (zero_mem _)
/-- Let `P` be a prime ideal, `x ∈ P \ P²` and `x ∉ Q` for all prime ideals `Q ≠ P`.
Then `P` is generated by `x`. -/
theorem Ideal.eq_span_singleton_of_mem_of_not_mem_sq_of_not_mem_prime_ne {P : Ideal R}
    (hP : P.IsPrime) [IsDomain R] [IsDedekindDomain R] {x : R} (x_mem : x ∈ P) (hxP2 : x ∉ P ^ 2)
    (hxQ : ∀ Q : Ideal R, IsPrime Q → Q ≠ P → x ∉ Q) : P = Ideal.span {x} := by
  letI := Classical.decEq (Ideal R)
  have hx0 : x ≠ 0 := by
    rintro rfl
    exact hxP2 (zero_mem _)
  

Proof state:
R : Type u_1
inst✝² : CommRing R
P : Ideal R
hP : IsPrime P
inst✝¹ : IsDomain R
inst✝ : IsDedekindDomain R
x : R
x_mem : x ∈ P
hxP2 : x ∉ P ^ 2
hxQ : ∀ (Q : Ideal R), IsPrime Q → Q ≠ P → x ∉ Q
this : DecidableEq (Ideal R) := Classical.decEq (Ideal R)
hx0 : x ≠ 0
⊢ P = span {x}

Next tactic:
by_cases hP0 : P = ⊥
/-- Let `P` be a prime ideal, `x ∈ P \ P²` and `x ∉ Q` for all prime ideals `Q ≠ P`.
Then `P` is generated by `x`. -/
theorem Ideal.eq_span_singleton_of_mem_of_not_mem_sq_of_not_mem_prime_ne {P : Ideal R}
    (hP : P.IsPrime) [IsDomain R] [IsDedekindDomain R] {x : R} (x_mem : x ∈ P) (hxP2 : x ∉ P ^ 2)
    (hxQ : ∀ Q : Ideal R, IsPrime Q → Q ≠ P → x ∉ Q) : P = Ideal.span {x} := by
  letI := Classical.decEq (Ideal R)
  have hx0 : x ≠ 0 := by
    rintro rfl
    exact hxP2 (zero_mem _)
  by_cases hP0 : P = ⊥
  · 

Proof state:
case pos
R : Type u_1
inst✝² : CommRing R
P : Ideal R
hP : IsPrime P
inst✝¹ : IsDomain R
inst✝ : IsDedekindDomain R
x : R
x_mem : x ∈ P
hxP2 : x ∉ P ^ 2
hxQ : ∀ (Q : Ideal R), IsPrime Q → Q ≠ P → x ∉ Q
this : DecidableEq (Ideal R) := Classical.decEq (Ideal R)
hx0 : x ≠ 0
hP0 : P = ⊥
⊢ P = span {x}

Next tactic:
subst hP0