l3lab/ntp-mathlib huggingface dataset:
theorem sq_le (h : 0 ≤ y) : x ^ 2 ≤ y ↔ -sqrt y ≤ x ∧ x ≤ sqrt y := by
  

Proof state:
x y : ℝ
h : 0 ≤ y
⊢ x ^ 2 ≤ y ↔ -sqrt y ≤ x ∧ x ≤ sqrt y

Next tactic:
constructor
theorem sq_le (h : 0 ≤ y) : x ^ 2 ≤ y ↔ -sqrt y ≤ x ∧ x ≤ sqrt y := by
  constructor
  · 

Proof state:
case mp
x y : ℝ
h : 0 ≤ y
⊢ x ^ 2 ≤ y → -sqrt y ≤ x ∧ x ≤ sqrt y

Next tactic:
simpa only [abs_le] using abs_le_sqrt
theorem sq_le (h : 0 ≤ y) : x ^ 2 ≤ y ↔ -sqrt y ≤ x ∧ x ≤ sqrt y := by
  constructor
  · simpa only [abs_le] using abs_le_sqrt
  · 

Proof state:
case mpr
x y : ℝ
h : 0 ≤ y
⊢ -sqrt y ≤ x ∧ x ≤ sqrt y → x ^ 2 ≤ y

Next tactic:
rw [← abs_le, ← sq_abs]
theorem sq_le (h : 0 ≤ y) : x ^ 2 ≤ y ↔ -sqrt y ≤ x ∧ x ≤ sqrt y := by
  constructor
  · simpa only [abs_le] using abs_le_sqrt
  · rw [← abs_le, ← sq_abs]
    

Proof state:
case mpr
x y : ℝ
h : 0 ≤ y
⊢ |x| ≤ sqrt y → |x| ^ 2 ≤ y

Next tactic:
exact (le_sqrt (abs_nonneg x) h).mp
@[simp]
theorem sqrt_inj (hx : 0 ≤ x) (hy : 0 ≤ y) : sqrt x = sqrt y ↔ x = y := by
  

Proof state:
x y : ℝ
hx : 0 ≤ x
hy : 0 ≤ y
⊢ sqrt x = sqrt y ↔ x = y

Next tactic:
simp [le_antisymm_iff, hx, hy]
@[simp]
theorem sqrt_eq_zero (h : 0 ≤ x) : sqrt x = 0 ↔ x = 0 := by 

Proof state:
x y : ℝ
h : 0 ≤ x
⊢ sqrt x = 0 ↔ x = 0

Next tactic:
simpa using sqrt_inj h le_rfl
theorem sqrt_eq_zero' : sqrt x = 0 ↔ x ≤ 0 := by
  

Proof state:
x y : ℝ
⊢ sqrt x = 0 ↔ x ≤ 0

Next tactic:
rw [sqrt, NNReal.coe_eq_zero, NNReal.sqrt_eq_zero, Real.toNNReal_eq_zero]
theorem sqrt_ne_zero (h : 0 ≤ x) : sqrt x ≠ 0 ↔ x ≠ 0 := by 

Proof state:
x y : ℝ
h : 0 ≤ x
⊢ sqrt x ≠ 0 ↔ x ≠ 0

Next tactic:
rw [not_iff_not, sqrt_eq_zero h]
theorem sqrt_ne_zero' : sqrt x ≠ 0 ↔ 0 < x := by 

Proof state:
x y : ℝ
⊢ sqrt x ≠ 0 ↔ 0 < x

Next tactic:
rw [← not_le, not_iff_not, sqrt_eq_zero']
@[simp]
theorem sqrt_pos : 0 < sqrt x ↔ 0 < x :=
  lt_iff_lt_of_le_iff_le (Iff.trans (by 

Proof state:
x y : ℝ
⊢ sqrt x ≤ 0 ↔ sqrt x = 0

Next tactic:
simp [le_antisymm_iff, sqrt_nonneg]
@[simp]
theorem sqrt_mul (hx : 0 ≤ x) (y : ℝ) : sqrt (x * y) = sqrt x * sqrt y := by
  

Proof state:
x : ℝ
hx : 0 ≤ x
y : ℝ
⊢ sqrt (x * y) = sqrt x * sqrt y

Next tactic:
simp_rw [sqrt, ← NNReal.coe_mul, NNReal.coe_eq, Real.toNNReal_mul hx, NNReal.sqrt_mul]
@[simp]
theorem sqrt_mul' (x) {y : ℝ} (hy : 0 ≤ y) : sqrt (x * y) = sqrt x * sqrt y := by
  

Proof state:
x y : ℝ
hy : 0 ≤ y
⊢ sqrt (x * y) = sqrt x * sqrt y

Next tactic:
rw [mul_comm, sqrt_mul hy, mul_comm]
@[simp]
theorem sqrt_inv (x : ℝ) : sqrt x⁻¹ = (sqrt x)⁻¹ := by
  

Proof state:
x : ℝ
⊢ sqrt x⁻¹ = (sqrt x)⁻¹

Next tactic:
rw [sqrt, Real.toNNReal_inv, NNReal.sqrt_inv, NNReal.coe_inv, sqrt]
@[simp]
theorem sqrt_div (hx : 0 ≤ x) (y : ℝ) : sqrt (x / y) = sqrt x / sqrt y := by
  

Proof state:
x : ℝ
hx : 0 ≤ x
y : ℝ
⊢ sqrt (x / y) = sqrt x / sqrt y

Next tactic:
rw [division_def, sqrt_mul hx, sqrt_inv, division_def]
@[simp]
theorem sqrt_div' (x) {y : ℝ} (hy : 0 ≤ y) : sqrt (x / y) = sqrt x / sqrt y := by
  

Proof state:
x y : ℝ
hy : 0 ≤ y
⊢ sqrt (x / y) = sqrt x / sqrt y

Next tactic:
rw [division_def, sqrt_mul' x (inv_nonneg.2 hy), sqrt_inv, division_def]
@[simp]
theorem div_sqrt : x / sqrt x = sqrt x := by
  

Proof state:
x : ℝ
⊢ x / sqrt x = sqrt x

Next tactic:
rcases le_or_lt x 0 with h | h
@[simp]
theorem div_sqrt : x / sqrt x = sqrt x := by
  rcases le_or_lt x 0 with h | h
  · 

Proof state:
case inl
x : ℝ
h : x ≤ 0
⊢ x / sqrt x = sqrt x

Next tactic:
rw [sqrt_eq_zero'.mpr h, div_zero]
@[simp]
theorem div_sqrt : x / sqrt x = sqrt x := by
  rcases le_or_lt x 0 with h | h
  · rw [sqrt_eq_zero'.mpr h, div_zero]
  · 

Proof state:
case inr
x : ℝ
h : 0 < x
⊢ x / sqrt x = sqrt x

Next tactic:
rw [div_eq_iff (sqrt_ne_zero'.mpr h), mul_self_sqrt h.le]
theorem sqrt_div_self' : sqrt x / x = 1 / sqrt x := by 

Proof state:
x : ℝ
⊢ sqrt x / x = 1 / sqrt x

Next tactic:
rw [← div_sqrt, one_div_div, div_sqrt]
theorem sqrt_div_self : sqrt x / x = (sqrt x)⁻¹ := by 

Proof state:
x : ℝ
⊢ sqrt x / x = (sqrt x)⁻¹

Next tactic:
rw [sqrt_div_self', one_div]
theorem lt_sqrt (hx : 0 ≤ x) : x < sqrt y ↔ x ^ 2 < y := by
  

Proof state:
x y : ℝ
hx : 0 ≤ x
⊢ x < sqrt y ↔ x ^ 2 < y

Next tactic:
rw [← sqrt_lt_sqrt_iff (sq_nonneg _), sqrt_sq hx]
theorem sq_lt : x ^ 2 < y ↔ -sqrt y < x ∧ x < sqrt y := by
  

Proof state:
x y : ℝ
⊢ x ^ 2 < y ↔ -sqrt y < x ∧ x < sqrt y

Next tactic:
rw [← abs_lt, ← sq_abs, lt_sqrt (abs_nonneg _)]
theorem lt_sq_of_sqrt_lt {x y : ℝ} (h : sqrt x < y) : x < y ^ 2 := by
  

Proof state:
x y : ℝ
h : sqrt x < y
⊢ x < y ^ 2

Next tactic:
have hy := x.sqrt_nonneg.trans_lt h
theorem lt_sq_of_sqrt_lt {x y : ℝ} (h : sqrt x < y) : x < y ^ 2 := by
  have hy := x.sqrt_nonneg.trans_lt h
  

Proof state:
x y : ℝ
h : sqrt x < y
hy : 0 < y
⊢ x < y ^ 2

Next tactic:
rwa [← sqrt_lt_sqrt_iff_of_pos (sq_pos_of_pos hy), sqrt_sq hy.le]
/-- The natural square root is at most the real square root -/
theorem nat_sqrt_le_real_sqrt {a : ℕ} : ↑(Nat.sqrt a) ≤ Real.sqrt ↑a := by
  

Proof state:
a : ℕ
⊢ ↑(Nat.sqrt a) ≤ sqrt ↑a

Next tactic:
rw [Real.le_sqrt (Nat.cast_nonneg _) (Nat.cast_nonneg _)]
/-- The natural square root is at most the real square root -/
theorem nat_sqrt_le_real_sqrt {a : ℕ} : ↑(Nat.sqrt a) ≤ Real.sqrt ↑a := by
  rw [Real.le_sqrt (Nat.cast_nonneg _) (Nat.cast_nonneg _)]
  

Proof state:
a : ℕ
⊢ ↑(Nat.sqrt a) ^ 2 ≤ ↑a

Next tactic:
norm_cast
/-- The natural square root is at most the real square root -/
theorem nat_sqrt_le_real_sqrt {a : ℕ} : ↑(Nat.sqrt a) ≤ Real.sqrt ↑a := by
  rw [Real.le_sqrt (Nat.cast_nonneg _) (Nat.cast_nonneg _)]
  norm_cast
  

Proof state:
a : ℕ
⊢ Nat.sqrt a ^ 2 ≤ a

Next tactic:
exact Nat.sqrt_le' a
/-- The real square root is at most the natural square root plus one -/
theorem real_sqrt_le_nat_sqrt_succ {a : ℕ} : Real.sqrt ↑a ≤ Nat.sqrt a + 1 := by
  

Proof state:
a : ℕ
⊢ sqrt ↑a ≤ ↑(Nat.sqrt a) + 1

Next tactic:
rw [Real.sqrt_le_iff]
/-- The real square root is at most the natural square root plus one -/
theorem real_sqrt_le_nat_sqrt_succ {a : ℕ} : Real.sqrt ↑a ≤ Nat.sqrt a + 1 := by
  rw [Real.sqrt_le_iff]
  

Proof state:
a : ℕ
⊢ 0 ≤ ↑(Nat.sqrt a) + 1 ∧ ↑a ≤ (↑(Nat.sqrt a) + 1) ^ 2

Next tactic:
constructor
/-- The real square root is at most the natural square root plus one -/
theorem real_sqrt_le_nat_sqrt_succ {a : ℕ} : Real.sqrt ↑a ≤ Nat.sqrt a + 1 := by
  rw [Real.sqrt_le_iff]
  constructor
  · 

Proof state:
case left
a : ℕ
⊢ 0 ≤ ↑(Nat.sqrt a) + 1

Next tactic:
norm_cast
/-- The real square root is at most the natural square root plus one -/
theorem real_sqrt_le_nat_sqrt_succ {a : ℕ} : Real.sqrt ↑a ≤ Nat.sqrt a + 1 := by
  rw [Real.sqrt_le_iff]
  constructor
  · norm_cast
    

Proof state:
case left
a : ℕ
⊢ 0 ≤ Nat.sqrt a + 1

Next tactic:
apply zero_le
/-- The real square root is at most the natural square root plus one -/
theorem real_sqrt_le_nat_sqrt_succ {a : ℕ} : Real.sqrt ↑a ≤ Nat.sqrt a + 1 := by
  rw [Real.sqrt_le_iff]
  constructor
  · norm_cast
    apply zero_le
  · 

Proof state:
case right
a : ℕ
⊢ ↑a ≤ (↑(Nat.sqrt a) + 1) ^ 2

Next tactic:
norm_cast
/-- The real square root is at most the natural square root plus one -/
theorem real_sqrt_le_nat_sqrt_succ {a : ℕ} : Real.sqrt ↑a ≤ Nat.sqrt a + 1 := by
  rw [Real.sqrt_le_iff]
  constructor
  · norm_cast
    apply zero_le
  · norm_cast
    

Proof state:
case right
a : ℕ
⊢ a ≤ (Nat.sqrt a + 1) ^ 2

Next tactic:
exact le_of_lt (Nat.lt_succ_sqrt' a)
/-- Although the instance `IsROrC.toStarOrderedRing` exists, it is locked behind the
`ComplexOrder` scope because currently the order on `ℂ` is not enabled globally. But we
want `StarOrderedRing ℝ` to be available globally, so we include this instance separately.
In addition, providing this instance here makes it available earlier in the import
hierarchy; otherwise in order to access it we would need to import `Data.IsROrC.Basic` -/
instance : StarOrderedRing ℝ :=
  StarOrderedRing.ofNonnegIff' add_le_add_left fun r => by
    

Proof state:
r : ℝ
⊢ 0 ≤ r ↔ ∃ s, r = star s * s

Next tactic:
refine ⟨fun hr => ⟨sqrt r, (mul_self_sqrt hr).symm⟩, ?_⟩
/-- Although the instance `IsROrC.toStarOrderedRing` exists, it is locked behind the
`ComplexOrder` scope because currently the order on `ℂ` is not enabled globally. But we
want `StarOrderedRing ℝ` to be available globally, so we include this instance separately.
In addition, providing this instance here makes it available earlier in the import
hierarchy; otherwise in order to access it we would need to import `Data.IsROrC.Basic` -/
instance : StarOrderedRing ℝ :=
  StarOrderedRing.ofNonnegIff' add_le_add_left fun r => by
    refine ⟨fun hr => ⟨sqrt r, (mul_self_sqrt hr).symm⟩, ?_⟩
    

Proof state:
r : ℝ
⊢ (∃ s, r = star s * s) → 0 ≤ r

Next tactic:
rintro ⟨s, rfl⟩
/-- Although the instance `IsROrC.toStarOrderedRing` exists, it is locked behind the
`ComplexOrder` scope because currently the order on `ℂ` is not enabled globally. But we
want `StarOrderedRing ℝ` to be available globally, so we include this instance separately.
In addition, providing this instance here makes it available earlier in the import
hierarchy; otherwise in order to access it we would need to import `Data.IsROrC.Basic` -/
instance : StarOrderedRing ℝ :=
  StarOrderedRing.ofNonnegIff' add_le_add_left fun r => by
    refine ⟨fun hr => ⟨sqrt r, (mul_self_sqrt hr).symm⟩, ?_⟩
    rintro ⟨s, rfl⟩
    

Proof state:
case intro
s : ℝ
⊢ 0 ≤ star s * s

Next tactic:
exact mul_self_nonneg s
@[nontriviality]
theorem of_subsingleton [Subsingleton M] (x y : M) : SameRay R x y := by
  

Proof state:
R : Type u_1
inst✝⁶ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
N : Type u_3
inst✝³ : AddCommMonoid N
inst✝² : Module R N
ι : Type u_4
inst✝¹ : DecidableEq ι
x✝ y✝ z : M
inst✝ : Subsingleton M
x y : M
⊢ SameRay R x y

Next tactic:
rw [Subsingleton.elim x 0]
@[nontriviality]
theorem of_subsingleton [Subsingleton M] (x y : M) : SameRay R x y := by
  rw [Subsingleton.elim x 0]
  

Proof state:
R : Type u_1
inst✝⁶ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
N : Type u_3
inst✝³ : AddCommMonoid N
inst✝² : Module R N
ι : Type u_4
inst✝¹ : DecidableEq ι
x✝ y✝ z : M
inst✝ : Subsingleton M
x y : M
⊢ SameRay R 0 y

Next tactic:
exact zero_left _
/-- `SameRay` is reflexive. -/
@[refl]
theorem refl (x : M) : SameRay R x x := by
  

Proof state:
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x✝ y z x : M
⊢ SameRay R x x

Next tactic:
nontriviality R
/-- `SameRay` is reflexive. -/
@[refl]
theorem refl (x : M) : SameRay R x x := by
  nontriviality R
  

Proof state:
R : Type u_1
inst✝⁶ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
N : Type u_3
inst✝³ : AddCommMonoid N
inst✝² : Module R N
ι : Type u_4
inst✝¹ : DecidableEq ι
x✝ y z x : M
inst✝ : Nontrivial R
⊢ SameRay R x x

Next tactic:
exact Or.inr (Or.inr <| ⟨1, 1, zero_lt_one, zero_lt_one, rfl⟩)
/-- `SameRay` is transitive unless the vector in the middle is zero and both other vectors are
nonzero. -/
theorem trans (hxy : SameRay R x y) (hyz : SameRay R y z) (hy : y = 0 → x = 0 ∨ z = 0) :
    SameRay R x z := by
  

Proof state:
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y z : M
hxy : SameRay R x y
hyz : SameRay R y z
hy : y = 0 → x = 0 ∨ z = 0
⊢ SameRay R x z

Next tactic:
rcases eq_or_ne x 0 with (rfl | hx)
/-- `SameRay` is transitive unless the vector in the middle is zero and both other vectors are
nonzero. -/
theorem trans (hxy : SameRay R x y) (hyz : SameRay R y z) (hy : y = 0 → x = 0 ∨ z = 0) :
    SameRay R x z := by
  rcases eq_or_ne x 0 with (rfl | hx); · 

Proof state:
case inl
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
y z : M
hyz : SameRay R y z
hxy : SameRay R 0 y
hy : y = 0 → 0 = 0 ∨ z = 0
⊢ SameRay R 0 z

Next tactic:
exact zero_left z
/-- `SameRay` is transitive unless the vector in the middle is zero and both other vectors are
nonzero. -/
theorem trans (hxy : SameRay R x y) (hyz : SameRay R y z) (hy : y = 0 → x = 0 ∨ z = 0) :
    SameRay R x z := by
  rcases eq_or_ne x 0 with (rfl | hx); · exact zero_left z
  

Proof state:
case inr
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y z : M
hxy : SameRay R x y
hyz : SameRay R y z
hy : y = 0 → x = 0 ∨ z = 0
hx : x ≠ 0
⊢ SameRay R x z

Next tactic:
rcases eq_or_ne z 0 with (rfl | hz)
/-- `SameRay` is transitive unless the vector in the middle is zero and both other vectors are
nonzero. -/
theorem trans (hxy : SameRay R x y) (hyz : SameRay R y z) (hy : y = 0 → x = 0 ∨ z = 0) :
    SameRay R x z := by
  rcases eq_or_ne x 0 with (rfl | hx); · exact zero_left z
  rcases eq_or_ne z 0 with (rfl | hz); · 

Proof state:
case inr.inl
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y : M
hxy : SameRay R x y
hx : x ≠ 0
hyz : SameRay R y 0
hy : y = 0 → x = 0 ∨ 0 = 0
⊢ SameRay R x 0

Next tactic:
exact zero_right x
/-- `SameRay` is transitive unless the vector in the middle is zero and both other vectors are
nonzero. -/
theorem trans (hxy : SameRay R x y) (hyz : SameRay R y z) (hy : y = 0 → x = 0 ∨ z = 0) :
    SameRay R x z := by
  rcases eq_or_ne x 0 with (rfl | hx); · exact zero_left z
  rcases eq_or_ne z 0 with (rfl | hz); · exact zero_right x
  

Proof state:
case inr.inr
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y z : M
hxy : SameRay R x y
hyz : SameRay R y z
hy : y = 0 → x = 0 ∨ z = 0
hx : x ≠ 0
hz : z ≠ 0
⊢ SameRay R x z

Next tactic:
rcases eq_or_ne y 0 with (rfl | hy)
/-- `SameRay` is transitive unless the vector in the middle is zero and both other vectors are
nonzero. -/
theorem trans (hxy : SameRay R x y) (hyz : SameRay R y z) (hy : y = 0 → x = 0 ∨ z = 0) :
    SameRay R x z := by
  rcases eq_or_ne x 0 with (rfl | hx); · exact zero_left z
  rcases eq_or_ne z 0 with (rfl | hz); · exact zero_right x
  rcases eq_or_ne y 0 with (rfl | hy);
  · 

Proof state:
case inr.inr.inl
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x z : M
hx : x ≠ 0
hz : z ≠ 0
hxy : SameRay R x 0
hyz : SameRay R 0 z
hy : 0 = 0 → x = 0 ∨ z = 0
⊢ SameRay R x z

Next tactic:
exact (hy rfl).elim (fun h => (hx h).elim) fun h => (hz h).elim
/-- `SameRay` is transitive unless the vector in the middle is zero and both other vectors are
nonzero. -/
theorem trans (hxy : SameRay R x y) (hyz : SameRay R y z) (hy : y = 0 → x = 0 ∨ z = 0) :
    SameRay R x z := by
  rcases eq_or_ne x 0 with (rfl | hx); · exact zero_left z
  rcases eq_or_ne z 0 with (rfl | hz); · exact zero_right x
  rcases eq_or_ne y 0 with (rfl | hy);
  · exact (hy rfl).elim (fun h => (hx h).elim) fun h => (hz h).elim
  

Proof state:
case inr.inr.inr
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y z : M
hxy : SameRay R x y
hyz : SameRay R y z
hy✝ : y = 0 → x = 0 ∨ z = 0
hx : x ≠ 0
hz : z ≠ 0
hy : y ≠ 0
⊢ SameRay R x z

Next tactic:
rcases hxy.exists_pos hx hy with ⟨r₁, r₂, hr₁, hr₂, h₁⟩
/-- `SameRay` is transitive unless the vector in the middle is zero and both other vectors are
nonzero. -/
theorem trans (hxy : SameRay R x y) (hyz : SameRay R y z) (hy : y = 0 → x = 0 ∨ z = 0) :
    SameRay R x z := by
  rcases eq_or_ne x 0 with (rfl | hx); · exact zero_left z
  rcases eq_or_ne z 0 with (rfl | hz); · exact zero_right x
  rcases eq_or_ne y 0 with (rfl | hy);
  · exact (hy rfl).elim (fun h => (hx h).elim) fun h => (hz h).elim
  rcases hxy.exists_pos hx hy with ⟨r₁, r₂, hr₁, hr₂, h₁⟩
  

Proof state:
case inr.inr.inr.intro.intro.intro.intro
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y z : M
hxy : SameRay R x y
hyz : SameRay R y z
hy✝ : y = 0 → x = 0 ∨ z = 0
hx : x ≠ 0
hz : z ≠ 0
hy : y ≠ 0
r₁ r₂ : R
hr₁ : 0 < r₁
hr₂ : 0 < r₂
h₁ : r₁ • x = r₂ • y
⊢ SameRay R x z

Next tactic:
rcases hyz.exists_pos hy hz with ⟨r₃, r₄, hr₃, hr₄, h₂⟩
/-- `SameRay` is transitive unless the vector in the middle is zero and both other vectors are
nonzero. -/
theorem trans (hxy : SameRay R x y) (hyz : SameRay R y z) (hy : y = 0 → x = 0 ∨ z = 0) :
    SameRay R x z := by
  rcases eq_or_ne x 0 with (rfl | hx); · exact zero_left z
  rcases eq_or_ne z 0 with (rfl | hz); · exact zero_right x
  rcases eq_or_ne y 0 with (rfl | hy);
  · exact (hy rfl).elim (fun h => (hx h).elim) fun h => (hz h).elim
  rcases hxy.exists_pos hx hy with ⟨r₁, r₂, hr₁, hr₂, h₁⟩
  rcases hyz.exists_pos hy hz with ⟨r₃, r₄, hr₃, hr₄, h₂⟩
  

Proof state:
case inr.inr.inr.intro.intro.intro.intro.intro.intro.intro.intro
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y z : M
hxy : SameRay R x y
hyz : SameRay R y z
hy✝ : y = 0 → x = 0 ∨ z = 0
hx : x ≠ 0
hz : z ≠ 0
hy : y ≠ 0
r₁ r₂ : R
hr₁ : 0 < r₁
hr₂ : 0 < r₂
h₁ : r₁ • x = r₂ • y
r₃ r₄ : R
hr₃ : 0 < r₃
hr₄ : 0 < r₄
h₂ : r₃ • y = r₄ • z
⊢ SameRay R x z

Next tactic:
refine' Or.inr (Or.inr <| ⟨r₃ * r₁, r₂ * r₄, mul_pos hr₃ hr₁, mul_pos hr₂ hr₄, _⟩)
/-- `SameRay` is transitive unless the vector in the middle is zero and both other vectors are
nonzero. -/
theorem trans (hxy : SameRay R x y) (hyz : SameRay R y z) (hy : y = 0 → x = 0 ∨ z = 0) :
    SameRay R x z := by
  rcases eq_or_ne x 0 with (rfl | hx); · exact zero_left z
  rcases eq_or_ne z 0 with (rfl | hz); · exact zero_right x
  rcases eq_or_ne y 0 with (rfl | hy);
  · exact (hy rfl).elim (fun h => (hx h).elim) fun h => (hz h).elim
  rcases hxy.exists_pos hx hy with ⟨r₁, r₂, hr₁, hr₂, h₁⟩
  rcases hyz.exists_pos hy hz with ⟨r₃, r₄, hr₃, hr₄, h₂⟩
  refine' Or.inr (Or.inr <| ⟨r₃ * r₁, r₂ * r₄, mul_pos hr₃ hr₁, mul_pos hr₂ hr₄, _⟩)
  

Proof state:
case inr.inr.inr.intro.intro.intro.intro.intro.intro.intro.intro
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y z : M
hxy : SameRay R x y
hyz : SameRay R y z
hy✝ : y = 0 → x = 0 ∨ z = 0
hx : x ≠ 0
hz : z ≠ 0
hy : y ≠ 0
r₁ r₂ : R
hr₁ : 0 < r₁
hr₂ : 0 < r₂
h₁ : r₁ • x = r₂ • y
r₃ r₄ : R
hr₃ : 0 < r₃
hr₄ : 0 < r₄
h₂ : r₃ • y = r₄ • z
⊢ (r₃ * r₁) • x = (r₂ * r₄) • z

Next tactic:
rw [mul_smul, mul_smul, h₁, ← h₂, smul_comm]
/-- A vector is in the same ray as a nonnegative multiple of itself. -/
theorem sameRay_nonneg_smul_right (v : M) {r : R} (h : 0 ≤ r) : SameRay R v (r • v) :=
  Or.inr <|
    h.eq_or_lt.imp (fun (h : 0 = r) => h ▸ zero_smul R v) fun h =>
      ⟨r, 1, h, by
        

Proof state:
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y z v : M
r : R
h✝ : 0 ≤ r
h : 0 < r
⊢ 0 < 1

Next tactic:
nontriviality R
/-- A vector is in the same ray as a nonnegative multiple of itself. -/
theorem sameRay_nonneg_smul_right (v : M) {r : R} (h : 0 ≤ r) : SameRay R v (r • v) :=
  Or.inr <|
    h.eq_or_lt.imp (fun (h : 0 = r) => h ▸ zero_smul R v) fun h =>
      ⟨r, 1, h, by
        nontriviality R
        

Proof state:
R : Type u_1
inst✝⁶ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
N : Type u_3
inst✝³ : AddCommMonoid N
inst✝² : Module R N
ι : Type u_4
inst✝¹ : DecidableEq ι
x y z v : M
r : R
h✝ : 0 ≤ r
h : 0 < r
inst✝ : Nontrivial R
⊢ 0 < 1

Next tactic:
exact zero_lt_one
/-- A vector is in the same ray as a nonnegative multiple of one it is in the same ray as. -/
theorem nonneg_smul_right {r : R} (h : SameRay R x y) (hr : 0 ≤ r) : SameRay R x (r • y) :=
  h.trans (sameRay_nonneg_smul_right y hr) fun hy => Or.inr <| by 

Proof state:
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y z : M
r : R
h : SameRay R x y
hr : 0 ≤ r
hy : y = 0
⊢ r • y = 0

Next tactic:
rw [hy, smul_zero]
/-- If two vectors are on the same ray then they remain so after applying a linear map. -/
theorem map (f : M →ₗ[R] N) (h : SameRay R x y) : SameRay R (f x) (f y) :=
  (h.imp fun hx => by 

Proof state:
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y z : M
f : M →ₗ[R] N
h : SameRay R x y
hx : x = 0
⊢ f x = 0

Next tactic:
rw [hx, map_zero]
/-- If two vectors are on the same ray then they remain so after applying a linear map. -/
theorem map (f : M →ₗ[R] N) (h : SameRay R x y) : SameRay R (f x) (f y) :=
  (h.imp fun hx => by rw [hx, map_zero]) <|
    Or.imp (fun hy => by 

Proof state:
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y z : M
f : M →ₗ[R] N
h : SameRay R x y
hy : y = 0
⊢ f y = 0

Next tactic:
rw [hy, map_zero]
/-- If two vectors are on the same ray then they remain so after applying a linear map. -/
theorem map (f : M →ₗ[R] N) (h : SameRay R x y) : SameRay R (f x) (f y) :=
  (h.imp fun hx => by rw [hx, map_zero]) <|
    Or.imp (fun hy => by rw [hy, map_zero]) fun ⟨r₁, r₂, hr₁, hr₂, h⟩ =>
      ⟨r₁, r₂, hr₁, hr₂, by 

Proof state:
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y z : M
f : M →ₗ[R] N
h✝ : SameRay R x y
x✝ : ∃ r₁ r₂, 0 < r₁ ∧ 0 < r₂ ∧ r₁ • x = r₂ • y
r₁ r₂ : R
hr₁ : 0 < r₁
hr₂ : 0 < r₂
h : r₁ • x = r₂ • y
⊢ r₁ • f x = r₂ • f y

Next tactic:
rw [← f.map_smul, ← f.map_smul, h]
/-- The images of two vectors under an injective linear map are on the same ray if and only if the
original vectors are on the same ray. -/
theorem _root_.Function.Injective.sameRay_map_iff {F : Type*} [LinearMapClass F R M N] {f : F}
    (hf : Function.Injective f) : SameRay R (f x) (f y) ↔ SameRay R x y := by
  

Proof state:
R : Type u_1
inst✝⁶ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
N : Type u_3
inst✝³ : AddCommMonoid N
inst✝² : Module R N
ι : Type u_4
inst✝¹ : DecidableEq ι
x y z : M
F : Type u_5
inst✝ : LinearMapClass F R M N
f : F
hf : Function.Injective ⇑f
⊢ SameRay R (f x) (f y) ↔ SameRay R x y

Next tactic:
simp only [SameRay, map_zero, ← hf.eq_iff, map_smul]
/-- If `x` and `y` are on the same ray as `z`, then so is `x + y`. -/
theorem add_left (hx : SameRay R x z) (hy : SameRay R y z) : SameRay R (x + y) z := by
  

Proof state:
R : Type u_1
inst✝⁵ : StrictOrderedCommSemiring R
M : Type u_2
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
N : Type u_3
inst✝² : AddCommMonoid N
inst✝¹ : Module R N
ι : Type u_4
inst✝ : DecidableEq ι
x y z : M
hx : SameRay R x z
hy : SameRay R y z
⊢ SameRay R (x + y) z

Next tactic:
rcases eq_or_ne x 0 with (rfl | hx₀)