l3lab/ntp-mathlib huggingface dataset:
/-- A choice-free version of `StrictOrderedSemiring.toOrderedSemiring` to avoid using choice in
basic `Nat` lemmas. -/
@[reducible]
def StrictOrderedSemiring.toOrderedSemiring' [@DecidableRel α (· ≤ ·)] : OrderedSemiring α :=
  { ‹StrictOrderedSemiring α› with
    mul_le_mul_of_nonneg_left := fun a b c hab hc => by
      obtain rfl | hab := Decidable.eq_or_lt_of_le hab
      · rfl
      obtain rfl | hc := Decidable.eq_or_lt_of_le hc
      · simp
      · exact (mul_lt_mul_of_pos_left hab hc).le,
    mul_le_mul_of_nonneg_right := fun a b c hab hc => by
      

Proof state:
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedSemiring α
a✝ b✝ c✝ d : α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
src✝ : StrictOrderedSemiring α := inst✝¹
a b c : α
hab : a ≤ b
hc : 0 ≤ c
⊢ a * c ≤ b * c

Next tactic:
obtain rfl | hab := Decidable.eq_or_lt_of_le hab
/-- A choice-free version of `StrictOrderedSemiring.toOrderedSemiring` to avoid using choice in
basic `Nat` lemmas. -/
@[reducible]
def StrictOrderedSemiring.toOrderedSemiring' [@DecidableRel α (· ≤ ·)] : OrderedSemiring α :=
  { ‹StrictOrderedSemiring α› with
    mul_le_mul_of_nonneg_left := fun a b c hab hc => by
      obtain rfl | hab := Decidable.eq_or_lt_of_le hab
      · rfl
      obtain rfl | hc := Decidable.eq_or_lt_of_le hc
      · simp
      · exact (mul_lt_mul_of_pos_left hab hc).le,
    mul_le_mul_of_nonneg_right := fun a b c hab hc => by
      obtain rfl | hab := Decidable.eq_or_lt_of_le hab
      · 

Proof state:
case inl
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedSemiring α
a✝ b c✝ d : α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
src✝ : StrictOrderedSemiring α := inst✝¹
a c : α
hc : 0 ≤ c
hab : a ≤ a
⊢ a * c ≤ a * c

Next tactic:
rfl
/-- A choice-free version of `StrictOrderedSemiring.toOrderedSemiring` to avoid using choice in
basic `Nat` lemmas. -/
@[reducible]
def StrictOrderedSemiring.toOrderedSemiring' [@DecidableRel α (· ≤ ·)] : OrderedSemiring α :=
  { ‹StrictOrderedSemiring α› with
    mul_le_mul_of_nonneg_left := fun a b c hab hc => by
      obtain rfl | hab := Decidable.eq_or_lt_of_le hab
      · rfl
      obtain rfl | hc := Decidable.eq_or_lt_of_le hc
      · simp
      · exact (mul_lt_mul_of_pos_left hab hc).le,
    mul_le_mul_of_nonneg_right := fun a b c hab hc => by
      obtain rfl | hab := Decidable.eq_or_lt_of_le hab
      · rfl
      

Proof state:
case inr
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedSemiring α
a✝ b✝ c✝ d : α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
src✝ : StrictOrderedSemiring α := inst✝¹
a b c : α
hab✝ : a ≤ b
hc : 0 ≤ c
hab : a < b
⊢ a * c ≤ b * c

Next tactic:
obtain rfl | hc := Decidable.eq_or_lt_of_le hc
/-- A choice-free version of `StrictOrderedSemiring.toOrderedSemiring` to avoid using choice in
basic `Nat` lemmas. -/
@[reducible]
def StrictOrderedSemiring.toOrderedSemiring' [@DecidableRel α (· ≤ ·)] : OrderedSemiring α :=
  { ‹StrictOrderedSemiring α› with
    mul_le_mul_of_nonneg_left := fun a b c hab hc => by
      obtain rfl | hab := Decidable.eq_or_lt_of_le hab
      · rfl
      obtain rfl | hc := Decidable.eq_or_lt_of_le hc
      · simp
      · exact (mul_lt_mul_of_pos_left hab hc).le,
    mul_le_mul_of_nonneg_right := fun a b c hab hc => by
      obtain rfl | hab := Decidable.eq_or_lt_of_le hab
      · rfl
      obtain rfl | hc := Decidable.eq_or_lt_of_le hc
      · 

Proof state:
case inr.inl
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedSemiring α
a✝ b✝ c d : α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
src✝ : StrictOrderedSemiring α := inst✝¹
a b : α
hab✝ : a ≤ b
hab : a < b
hc : 0 ≤ 0
⊢ a * 0 ≤ b * 0

Next tactic:
simp
/-- A choice-free version of `StrictOrderedSemiring.toOrderedSemiring` to avoid using choice in
basic `Nat` lemmas. -/
@[reducible]
def StrictOrderedSemiring.toOrderedSemiring' [@DecidableRel α (· ≤ ·)] : OrderedSemiring α :=
  { ‹StrictOrderedSemiring α› with
    mul_le_mul_of_nonneg_left := fun a b c hab hc => by
      obtain rfl | hab := Decidable.eq_or_lt_of_le hab
      · rfl
      obtain rfl | hc := Decidable.eq_or_lt_of_le hc
      · simp
      · exact (mul_lt_mul_of_pos_left hab hc).le,
    mul_le_mul_of_nonneg_right := fun a b c hab hc => by
      obtain rfl | hab := Decidable.eq_or_lt_of_le hab
      · rfl
      obtain rfl | hc := Decidable.eq_or_lt_of_le hc
      · simp
      · 

Proof state:
case inr.inr
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedSemiring α
a✝ b✝ c✝ d : α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
src✝ : StrictOrderedSemiring α := inst✝¹
a b c : α
hab✝ : a ≤ b
hc✝ : 0 ≤ c
hab : a < b
hc : 0 < c
⊢ a * c ≤ b * c

Next tactic:
exact (mul_lt_mul_of_pos_right hab hc).le
@[simp]
theorem pow_pos (H : 0 < a) : ∀ n : ℕ, 0 < a ^ n
  | 0 => by
    

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedSemiring α
a b c d : α
H : 0 < a
⊢ 0 < a ^ 0

Next tactic:
nontriviality
@[simp]
theorem pow_pos (H : 0 < a) : ∀ n : ℕ, 0 < a ^ n
  | 0 => by
    nontriviality
    

Proof state:
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedSemiring α
a b c d : α
H : 0 < a
inst✝ : Nontrivial α
⊢ 0 < a ^ 0

Next tactic:
rw [pow_zero]
@[simp]
theorem pow_pos (H : 0 < a) : ∀ n : ℕ, 0 < a ^ n
  | 0 => by
    nontriviality
    rw [pow_zero]
    

Proof state:
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedSemiring α
a b c d : α
H : 0 < a
inst✝ : Nontrivial α
⊢ 0 < 1

Next tactic:
exact zero_lt_one
@[simp]
theorem pow_pos (H : 0 < a) : ∀ n : ℕ, 0 < a ^ n
  | 0 => by
    nontriviality
    rw [pow_zero]
    exact zero_lt_one
  | n + 1 => by
    

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedSemiring α
a b c d : α
H : 0 < a
n : ℕ
⊢ 0 < a ^ (n + 1)

Next tactic:
rw [pow_succ]
@[simp]
theorem pow_pos (H : 0 < a) : ∀ n : ℕ, 0 < a ^ n
  | 0 => by
    nontriviality
    rw [pow_zero]
    exact zero_lt_one
  | n + 1 => by
    rw [pow_succ]
    

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedSemiring α
a b c d : α
H : 0 < a
n : ℕ
⊢ 0 < a * a ^ n

Next tactic:
exact mul_pos H (pow_pos H _)
protected theorem Decidable.mul_lt_mul'' [@DecidableRel α (· ≤ ·)] (h1 : a < c) (h2 : b < d)
    (h3 : 0 ≤ a) (h4 : 0 ≤ b) : a * b < c * d :=
  h4.lt_or_eq_dec.elim (fun b0 => mul_lt_mul h1 h2.le b0 <| h3.trans h1.le) fun b0 => by
    

Proof state:
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedSemiring α
a b c d : α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
h1 : a < c
h2 : b < d
h3 : 0 ≤ a
h4 : 0 ≤ b
b0 : 0 = b
⊢ a * b < c * d

Next tactic:
rw [← b0, mul_zero]
protected theorem Decidable.mul_lt_mul'' [@DecidableRel α (· ≤ ·)] (h1 : a < c) (h2 : b < d)
    (h3 : 0 ≤ a) (h4 : 0 ≤ b) : a * b < c * d :=
  h4.lt_or_eq_dec.elim (fun b0 => mul_lt_mul h1 h2.le b0 <| h3.trans h1.le) fun b0 => by
    rw [← b0, mul_zero]; 

Proof state:
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedSemiring α
a b c d : α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
h1 : a < c
h2 : b < d
h3 : 0 ≤ a
h4 : 0 ≤ b
b0 : 0 = b
⊢ 0 < c * d

Next tactic:
exact mul_pos (h3.trans_lt h1) (h4.trans_lt h2)
theorem mul_lt_mul'' : a < c → b < d → 0 ≤ a → 0 ≤ b → a * b < c * d := by 

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedSemiring α
a b c d : α
⊢ a < c → b < d → 0 ≤ a → 0 ≤ b → a * b < c * d

Next tactic:
classical
  exact Decidable.mul_lt_mul''
theorem mul_lt_mul'' : a < c → b < d → 0 ≤ a → 0 ≤ b → a * b < c * d := by classical
  

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedSemiring α
a b c d : α
⊢ a < c → b < d → 0 ≤ a → 0 ≤ b → a * b < c * d

Next tactic:
exact Decidable.mul_lt_mul''
theorem lt_mul_left (hn : 0 < a) (hm : 1 < b) : a < b * a := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedSemiring α
a b c d : α
hn : 0 < a
hm : 1 < b
⊢ a < b * a

Next tactic:
convert mul_lt_mul_of_pos_right hm hn
theorem lt_mul_left (hn : 0 < a) (hm : 1 < b) : a < b * a := by
  convert mul_lt_mul_of_pos_right hm hn
  

Proof state:
case h.e'_3
α : Type u
β : Type u_1
inst✝ : StrictOrderedSemiring α
a b c d : α
hn : 0 < a
hm : 1 < b
⊢ a = 1 * a

Next tactic:
rw [one_mul]
theorem lt_mul_right (hn : 0 < a) (hm : 1 < b) : a < a * b := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedSemiring α
a b c d : α
hn : 0 < a
hm : 1 < b
⊢ a < a * b

Next tactic:
convert mul_lt_mul_of_pos_left hm hn
theorem lt_mul_right (hn : 0 < a) (hm : 1 < b) : a < a * b := by
  convert mul_lt_mul_of_pos_left hm hn
  

Proof state:
case h.e'_3
α : Type u
β : Type u_1
inst✝ : StrictOrderedSemiring α
a b c d : α
hn : 0 < a
hm : 1 < b
⊢ a = a * 1

Next tactic:
rw [mul_one]
instance (priority := 100) StrictOrderedRing.toStrictOrderedSemiring : StrictOrderedSemiring α :=
  { ‹StrictOrderedRing α›, (Ring.toSemiring : Semiring α) with
    le_of_add_le_add_left := @le_of_add_le_add_left α _ _ _,
    mul_lt_mul_of_pos_left := fun a b c h hc => by
      

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedRing α
a✝ b✝ c✝ : α
src✝¹ : StrictOrderedRing α := inst✝
src✝ : Semiring α := Ring.toSemiring
a b c : α
h : a < b
hc : 0 < c
⊢ c * a < c * b

Next tactic:
simpa only [mul_sub, sub_pos] using StrictOrderedRing.mul_pos _ _ hc (sub_pos.2 h)
instance (priority := 100) StrictOrderedRing.toStrictOrderedSemiring : StrictOrderedSemiring α :=
  { ‹StrictOrderedRing α›, (Ring.toSemiring : Semiring α) with
    le_of_add_le_add_left := @le_of_add_le_add_left α _ _ _,
    mul_lt_mul_of_pos_left := fun a b c h hc => by
      simpa only [mul_sub, sub_pos] using StrictOrderedRing.mul_pos _ _ hc (sub_pos.2 h),
    mul_lt_mul_of_pos_right := fun a b c h hc => by
      

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedRing α
a✝ b✝ c✝ : α
src✝¹ : StrictOrderedRing α := inst✝
src✝ : Semiring α := Ring.toSemiring
a b c : α
h : a < b
hc : 0 < c
⊢ a * c < b * c

Next tactic:
simpa only [sub_mul, sub_pos] using StrictOrderedRing.mul_pos _ _ (sub_pos.2 h) hc
/-- A choice-free version of `StrictOrderedRing.toOrderedRing` to avoid using choice in basic
`Int` lemmas. -/
@[reducible]
def StrictOrderedRing.toOrderedRing' [@DecidableRel α (· ≤ ·)] : OrderedRing α :=
  { ‹StrictOrderedRing α›, (Ring.toSemiring : Semiring α) with
    mul_nonneg := fun a b ha hb => by
      

Proof state:
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedRing α
a✝ b✝ c : α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
src✝¹ : StrictOrderedRing α := inst✝¹
src✝ : Semiring α := Ring.toSemiring
a b : α
ha : 0 ≤ a
hb : 0 ≤ b
⊢ 0 ≤ a * b

Next tactic:
obtain ha | ha := Decidable.eq_or_lt_of_le ha
/-- A choice-free version of `StrictOrderedRing.toOrderedRing` to avoid using choice in basic
`Int` lemmas. -/
@[reducible]
def StrictOrderedRing.toOrderedRing' [@DecidableRel α (· ≤ ·)] : OrderedRing α :=
  { ‹StrictOrderedRing α›, (Ring.toSemiring : Semiring α) with
    mul_nonneg := fun a b ha hb => by
      obtain ha | ha := Decidable.eq_or_lt_of_le ha
      · 

Proof state:
case inl
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedRing α
a✝ b✝ c : α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
src✝¹ : StrictOrderedRing α := inst✝¹
src✝ : Semiring α := Ring.toSemiring
a b : α
ha✝ : 0 ≤ a
hb : 0 ≤ b
ha : 0 = a
⊢ 0 ≤ a * b

Next tactic:
rw [← ha, zero_mul]
/-- A choice-free version of `StrictOrderedRing.toOrderedRing` to avoid using choice in basic
`Int` lemmas. -/
@[reducible]
def StrictOrderedRing.toOrderedRing' [@DecidableRel α (· ≤ ·)] : OrderedRing α :=
  { ‹StrictOrderedRing α›, (Ring.toSemiring : Semiring α) with
    mul_nonneg := fun a b ha hb => by
      obtain ha | ha := Decidable.eq_or_lt_of_le ha
      · rw [← ha, zero_mul]
      

Proof state:
case inr
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedRing α
a✝ b✝ c : α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
src✝¹ : StrictOrderedRing α := inst✝¹
src✝ : Semiring α := Ring.toSemiring
a b : α
ha✝ : 0 ≤ a
hb : 0 ≤ b
ha : 0 < a
⊢ 0 ≤ a * b

Next tactic:
obtain hb | hb := Decidable.eq_or_lt_of_le hb
/-- A choice-free version of `StrictOrderedRing.toOrderedRing` to avoid using choice in basic
`Int` lemmas. -/
@[reducible]
def StrictOrderedRing.toOrderedRing' [@DecidableRel α (· ≤ ·)] : OrderedRing α :=
  { ‹StrictOrderedRing α›, (Ring.toSemiring : Semiring α) with
    mul_nonneg := fun a b ha hb => by
      obtain ha | ha := Decidable.eq_or_lt_of_le ha
      · rw [← ha, zero_mul]
      obtain hb | hb := Decidable.eq_or_lt_of_le hb
      · 

Proof state:
case inr.inl
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedRing α
a✝ b✝ c : α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
src✝¹ : StrictOrderedRing α := inst✝¹
src✝ : Semiring α := Ring.toSemiring
a b : α
ha✝ : 0 ≤ a
hb✝ : 0 ≤ b
ha : 0 < a
hb : 0 = b
⊢ 0 ≤ a * b

Next tactic:
rw [← hb, mul_zero]
/-- A choice-free version of `StrictOrderedRing.toOrderedRing` to avoid using choice in basic
`Int` lemmas. -/
@[reducible]
def StrictOrderedRing.toOrderedRing' [@DecidableRel α (· ≤ ·)] : OrderedRing α :=
  { ‹StrictOrderedRing α›, (Ring.toSemiring : Semiring α) with
    mul_nonneg := fun a b ha hb => by
      obtain ha | ha := Decidable.eq_or_lt_of_le ha
      · rw [← ha, zero_mul]
      obtain hb | hb := Decidable.eq_or_lt_of_le hb
      · rw [← hb, mul_zero]
      · 

Proof state:
case inr.inr
α : Type u
β : Type u_1
inst✝¹ : StrictOrderedRing α
a✝ b✝ c : α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
src✝¹ : StrictOrderedRing α := inst✝¹
src✝ : Semiring α := Ring.toSemiring
a b : α
ha✝ : 0 ≤ a
hb✝ : 0 ≤ b
ha : 0 < a
hb : 0 < b
⊢ 0 ≤ a * b

Next tactic:
exact (StrictOrderedRing.mul_pos _ _ ha hb).le
theorem mul_lt_mul_of_neg_left (h : b < a) (hc : c < 0) : c * a < c * b := by
  

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

Next tactic:
simpa only [neg_mul, neg_lt_neg_iff] using mul_lt_mul_of_pos_left h (neg_pos_of_neg hc)
theorem mul_lt_mul_of_neg_right (h : b < a) (hc : c < 0) : a * c < b * c := by
  

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

Next tactic:
simpa only [mul_neg, neg_lt_neg_iff] using mul_lt_mul_of_pos_right h (neg_pos_of_neg hc)
theorem mul_pos_of_neg_of_neg {a b : α} (ha : a < 0) (hb : b < 0) : 0 < a * b := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedRing α
a✝ b✝ c a b : α
ha : a < 0
hb : b < 0
⊢ 0 < a * b

Next tactic:
simpa only [zero_mul] using mul_lt_mul_of_neg_right ha hb
/-- Variant of `mul_lt_of_lt_one_left` for `b` negative instead of positive. -/
theorem lt_mul_of_lt_one_left (hb : b < 0) (h : a < 1) : b < a * b := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedRing α
a b c : α
hb : b < 0
h : a < 1
⊢ b < a * b

Next tactic:
simpa only [one_mul] using mul_lt_mul_of_neg_right h hb
/-- Variant of `lt_mul_of_one_lt_left` for `b` negative instead of positive. -/
theorem mul_lt_of_one_lt_left (hb : b < 0) (h : 1 < a) : a * b < b := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedRing α
a b c : α
hb : b < 0
h : 1 < a
⊢ a * b < b

Next tactic:
simpa only [one_mul] using mul_lt_mul_of_neg_right h hb
/-- Variant of `mul_lt_of_lt_one_right` for `a` negative instead of positive. -/
theorem lt_mul_of_lt_one_right (ha : a < 0) (h : b < 1) : a < a * b := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedRing α
a b c : α
ha : a < 0
h : b < 1
⊢ a < a * b

Next tactic:
simpa only [mul_one] using mul_lt_mul_of_neg_left h ha
/-- Variant of `lt_mul_of_lt_one_right` for `a` negative instead of positive. -/
theorem mul_lt_of_one_lt_right (ha : a < 0) (h : 1 < b) : a * b < a := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : StrictOrderedRing α
a b c : α
ha : a < 0
h : 1 < b
⊢ a * b < a

Next tactic:
simpa only [mul_one] using mul_lt_mul_of_neg_left h ha
theorem nonneg_and_nonneg_or_nonpos_and_nonpos_of_mul_nonneg (hab : 0 ≤ a * b) :
    0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0 := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
hab : 0 ≤ a * b
⊢ 0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0

Next tactic:
refine' Decidable.or_iff_not_and_not.2 _
theorem nonneg_and_nonneg_or_nonpos_and_nonpos_of_mul_nonneg (hab : 0 ≤ a * b) :
    0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0 := by
  refine' Decidable.or_iff_not_and_not.2 _
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
hab : 0 ≤ a * b
⊢ ¬(¬(0 ≤ a ∧ 0 ≤ b) ∧ ¬(a ≤ 0 ∧ b ≤ 0))

Next tactic:
simp only [not_and, not_le]
theorem nonneg_and_nonneg_or_nonpos_and_nonpos_of_mul_nonneg (hab : 0 ≤ a * b) :
    0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0 := by
  refine' Decidable.or_iff_not_and_not.2 _
  simp only [not_and, not_le]; 

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
hab : 0 ≤ a * b
⊢ (0 ≤ a → b < 0) → ¬(a ≤ 0 → 0 < b)

Next tactic:
intro ab nab
theorem nonneg_and_nonneg_or_nonpos_and_nonpos_of_mul_nonneg (hab : 0 ≤ a * b) :
    0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0 := by
  refine' Decidable.or_iff_not_and_not.2 _
  simp only [not_and, not_le]; intro ab nab; 

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
hab : 0 ≤ a * b
ab : 0 ≤ a → b < 0
nab : a ≤ 0 → 0 < b
⊢ False

Next tactic:
apply not_lt_of_le hab _
theorem nonneg_and_nonneg_or_nonpos_and_nonpos_of_mul_nonneg (hab : 0 ≤ a * b) :
    0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0 := by
  refine' Decidable.or_iff_not_and_not.2 _
  simp only [not_and, not_le]; intro ab nab; apply not_lt_of_le hab _
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
hab : 0 ≤ a * b
ab : 0 ≤ a → b < 0
nab : a ≤ 0 → 0 < b
⊢ a * b < 0

Next tactic:
rcases lt_trichotomy 0 a with (ha | rfl | ha)
theorem nonneg_and_nonneg_or_nonpos_and_nonpos_of_mul_nonneg (hab : 0 ≤ a * b) :
    0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0 := by
  refine' Decidable.or_iff_not_and_not.2 _
  simp only [not_and, not_le]; intro ab nab; apply not_lt_of_le hab _
  rcases lt_trichotomy 0 a with (ha | rfl | ha)
  · 

Proof state:
case inl
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
hab : 0 ≤ a * b
ab : 0 ≤ a → b < 0
nab : a ≤ 0 → 0 < b
ha : 0 < a
⊢ a * b < 0

Next tactic:
exact mul_neg_of_pos_of_neg ha (ab ha.le)
theorem nonneg_and_nonneg_or_nonpos_and_nonpos_of_mul_nonneg (hab : 0 ≤ a * b) :
    0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0 := by
  refine' Decidable.or_iff_not_and_not.2 _
  simp only [not_and, not_le]; intro ab nab; apply not_lt_of_le hab _
  rcases lt_trichotomy 0 a with (ha | rfl | ha)
  · exact mul_neg_of_pos_of_neg ha (ab ha.le)
  · 

Proof state:
case inr.inl
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
b c d : α
hab : 0 ≤ 0 * b
ab : 0 ≤ 0 → b < 0
nab : 0 ≤ 0 → 0 < b
⊢ 0 * b < 0

Next tactic:
exact ((ab le_rfl).asymm (nab le_rfl)).elim
theorem nonneg_and_nonneg_or_nonpos_and_nonpos_of_mul_nonneg (hab : 0 ≤ a * b) :
    0 ≤ a ∧ 0 ≤ b ∨ a ≤ 0 ∧ b ≤ 0 := by
  refine' Decidable.or_iff_not_and_not.2 _
  simp only [not_and, not_le]; intro ab nab; apply not_lt_of_le hab _
  rcases lt_trichotomy 0 a with (ha | rfl | ha)
  · exact mul_neg_of_pos_of_neg ha (ab ha.le)
  · exact ((ab le_rfl).asymm (nab le_rfl)).elim
  · 

Proof state:
case inr.inr
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
hab : 0 ≤ a * b
ab : 0 ≤ a → b < 0
nab : a ≤ 0 → 0 < b
ha : a < 0
⊢ a * b < 0

Next tactic:
exact mul_neg_of_neg_of_pos ha (nab ha.le)
@[simp]
theorem zero_le_mul_left (h : 0 < c) : 0 ≤ c * b ↔ 0 ≤ b := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
h : 0 < c
⊢ 0 ≤ c * b ↔ 0 ≤ b

Next tactic:
convert mul_le_mul_left h
@[simp]
theorem zero_le_mul_left (h : 0 < c) : 0 ≤ c * b ↔ 0 ≤ b := by
  convert mul_le_mul_left h
  

Proof state:
case h.e'_1.h.e'_3
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
h : 0 < c
⊢ 0 = c * 0

Next tactic:
simp
@[simp]
theorem zero_le_mul_right (h : 0 < c) : 0 ≤ b * c ↔ 0 ≤ b := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
h : 0 < c
⊢ 0 ≤ b * c ↔ 0 ≤ b

Next tactic:
simpa using (mul_le_mul_right h : 0 * c ≤ b * c ↔ 0 ≤ b)
@[simp]
theorem bit0_le_bit0 : bit0 a ≤ bit0 b ↔ a ≤ b := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
⊢ bit0 a ≤ bit0 b ↔ a ≤ b

Next tactic:
rw [bit0, bit0, ← two_mul, ← two_mul, mul_le_mul_left (zero_lt_two : 0 < (2 : α))]
@[simp]
theorem bit0_lt_bit0 : bit0 a < bit0 b ↔ a < b := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
⊢ bit0 a < bit0 b ↔ a < b

Next tactic:
rw [bit0, bit0, ← two_mul, ← two_mul, mul_lt_mul_left (zero_lt_two : 0 < (2 : α))]
@[simp]
theorem one_le_bit1 : (1 : α) ≤ bit1 a ↔ 0 ≤ a := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
⊢ 1 ≤ bit1 a ↔ 0 ≤ a

Next tactic:
rw [bit1, le_add_iff_nonneg_left, bit0, ← two_mul, zero_le_mul_left (zero_lt_two : 0 < (2 : α))]
@[simp]
theorem one_lt_bit1 : (1 : α) < bit1 a ↔ 0 < a := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
⊢ 1 < bit1 a ↔ 0 < a

Next tactic:
rw [bit1, lt_add_iff_pos_left, bit0, ← two_mul, zero_lt_mul_left (zero_lt_two : 0 < (2 : α))]
@[simp]
theorem zero_le_bit0 : (0 : α) ≤ bit0 a ↔ 0 ≤ a := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
⊢ 0 ≤ bit0 a ↔ 0 ≤ a

Next tactic:
rw [bit0, ← two_mul, zero_le_mul_left (zero_lt_two : 0 < (2 : α))]
@[simp]
theorem zero_lt_bit0 : (0 : α) < bit0 a ↔ 0 < a := by
  

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedSemiring α
a b c d : α
⊢ 0 < bit0 a ↔ 0 < a

Next tactic:
rw [bit0, ← two_mul, zero_lt_mul_left (zero_lt_two : 0 < (2 : α))]
instance (priority := 100) LinearOrderedRing.noZeroDivisors : NoZeroDivisors α :=
  { ‹LinearOrderedRing α› with
    eq_zero_or_eq_zero_of_mul_eq_zero := by
      

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a b c : α
src✝ : LinearOrderedRing α := inst✝
⊢ ∀ {a b : α}, a * b = 0 → a = 0 ∨ b = 0

Next tactic:
intro a b hab
instance (priority := 100) LinearOrderedRing.noZeroDivisors : NoZeroDivisors α :=
  { ‹LinearOrderedRing α› with
    eq_zero_or_eq_zero_of_mul_eq_zero := by
      intro a b hab
      

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

Next tactic:
refine' Decidable.or_iff_not_and_not.2 fun h => _
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 => _; 

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c : α
src✝ : LinearOrderedRing α := inst✝
a b : α
hab : a * b = 0
h : ¬a = 0 ∧ ¬b = 0
⊢ False

Next tactic:
revert hab
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
      

Proof state:
α : Type u
β : Type u_1
inst✝ : LinearOrderedRing α
a✝ b✝ c : α
src✝ : LinearOrderedRing α := inst✝
a b : α
h : ¬a = 0 ∧ ¬b = 0
⊢ a * b = 0 → False

Next tactic:
cases' lt_or_gt_of_ne h.1 with ha ha
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 <;> 

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

Next tactic:
cases' lt_or_gt_of_ne h.2 with hb hb
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 <;> 

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

Next tactic:
cases' lt_or_gt_of_ne h.2 with hb hb