File: Mathlib/LinearAlgebra/Ray.lean

full_name: SameRay
code: /-- Two vectors are in the same ray if either one of them is zero or some positive multiples of them
are equal (in the typical case over a field, this means one of them is a nonnegative multiple of
the other). -/
def SameRay (v₁ v₂ : M) : Prop 
goal: Prop

full_name: SameRay.zero_left
code: @[simp]
theorem zero_left (y : M) : SameRay R 0 y 
goal: SameRay R 0 y

full_name: SameRay.zero_right
code: @[simp]
theorem zero_right (x : M) : SameRay R x 0 
goal: SameRay R x 0

full_name: SameRay.of_subsingleton
code: @[nontriviality]
theorem of_subsingleton [Subsingleton M] (x y : M) : SameRay R x y 
goal: SameRay R x y

full_name: SameRay.of_subsingleton'
code: @[nontriviality]
theorem of_subsingleton' [Subsingleton R] (x y : M) : SameRay R x y 
goal: SameRay R x y

full_name: SameRay.refl
code: /-- `SameRay` is reflexive. -/
@[refl]
theorem refl (x : M) : SameRay R x x 
goal: SameRay R x x

full_name: SameRay.rfl
code: protected theorem rfl : SameRay R x x 
goal: SameRay R x x

full_name: SameRay.symm
code: /-- `SameRay` is symmetric. -/
@[symm]
theorem symm (h : SameRay R x y) : SameRay R y x 
goal: SameRay R y x

full_name: SameRay.exists_pos
code: /-- If `x` and `y` are nonzero vectors on the same ray, then there exist positive numbers `r₁ r₂`
such that `r₁ • x = r₂ • y`. -/
theorem exists_pos (h : SameRay R x y) (hx : x ≠ 0) (hy : y ≠ 0) :
    ∃ r₁ r₂ : R, 0 < r₁ ∧ 0 < r₂ ∧ r₁ • x = r₂ • y 
goal: ∃ r₁ r₂, 0 < r₁ ∧ 0 < r₂ ∧ r₁ • x = r₂ • y

full_name: SameRay.sameRay_comm
code: theorem sameRay_comm : SameRay R x y ↔ SameRay R y x 
goal: SameRay R x y ↔ SameRay R y x

full_name: SameRay.trans
code: /-- `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 
goal: SameRay R x z

full_name: SameRay.sameRay_nonneg_smul_right
code: /-- A vector is in the same ray as a nonnegative multiple of itself. -/
lemma sameRay_nonneg_smul_right (v : M) (h : 0 ≤ a) : SameRay R v (a • v) 
goal: SameRay R v (a • v)

full_name: SameRay.sameRay_nonneg_smul_left
code: /-- A nonnegative multiple of a vector is in the same ray as that vector. -/
lemma sameRay_nonneg_smul_left (v : M) (ha : 0 ≤ a) : SameRay R (a • v) v 
goal: SameRay R (a • v) v

full_name: SameRay.sameRay_pos_smul_right
code: /-- A vector is in the same ray as a positive multiple of itself. -/
lemma sameRay_pos_smul_right (v : M) (ha : 0 < a) : SameRay R v (a • v) 
goal: SameRay R v (a • v)

full_name: SameRay.sameRay_pos_smul_left
code: /-- A positive multiple of a vector is in the same ray as that vector. -/
lemma sameRay_pos_smul_left (v : M) (ha : 0 < a) : SameRay R (a • v) v 
goal: SameRay R (a • v) v

full_name: SameRay.nonneg_smul_right
code: /-- A vector is in the same ray as a nonnegative multiple of one it is in the same ray as. -/
lemma nonneg_smul_right (h : SameRay R x y) (ha : 0 ≤ a) : SameRay R x (a • y) 
goal: SameRay R x (a • y)

full_name: SameRay.nonneg_smul_left
code: /-- A nonnegative multiple of a vector is in the same ray as one it is in the same ray as. -/
lemma nonneg_smul_left (h : SameRay R x y) (ha : 0 ≤ a) : SameRay R (a • x) y 
goal: SameRay R (a • x) y

full_name: SameRay.pos_smul_right
code: /-- A vector is in the same ray as a positive multiple of one it is in the same ray as. -/
theorem pos_smul_right (h : SameRay R x y) (ha : 0 < a) : SameRay R x (a • y) 
goal: SameRay R x (a • y)

full_name: SameRay.pos_smul_left
code: /-- A positive multiple of a vector is in the same ray as one it is in the same ray as. -/
theorem pos_smul_left (h : SameRay R x y) (hr : 0 < a) : SameRay R (a • x) y 
goal: SameRay R (a • x) y

full_name: SameRay.map
code: /-- 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) 
goal: SameRay R (f x) (f y)

full_name: Function.Injective.sameRay_map_iff
code: /-- 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*} [FunLike F M N] [LinearMapClass F R M N]
    {f : F} (hf : Function.Injective f) :
    SameRay R (f x) (f y) ↔ SameRay R x y 
goal: SameRay R (f x) (f y) ↔ SameRay R x y

full_name: SameRay.sameRay_map_iff
code: /-- The images of two vectors under a linear equivalence are on the same ray if and only if the
original vectors are on the same ray. -/
@[simp]
theorem sameRay_map_iff (e : M ≃ₗ[R] N) : SameRay R (e x) (e y) ↔ SameRay R x y 
goal: SameRay R (e x) (e y) ↔ SameRay R x y

full_name: SameRay.smul
code: /-- If two vectors are on the same ray then both scaled by the same action are also on the same
ray. -/
theorem smul {S : Type*} [Monoid S] [DistribMulAction S M] [SMulCommClass R S M]
    (h : SameRay R x y) (s : S) : SameRay R (s • x) (s • y) 
goal: SameRay R (s • x) (s • y)

full_name: SameRay.add_left
code: /-- 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 
goal: SameRay R (x + y) z

full_name: SameRay.add_right
code: /-- If `y` and `z` are on the same ray as `x`, then so is `y + z`. -/
theorem add_right (hy : SameRay R x y) (hz : SameRay R x z) : SameRay R x (y + z) 
goal: SameRay R x (y + z)

full_name: RayVector
code: /-- Nonzero vectors, as used to define rays. This type depends on an unused argument `R` so that
`RayVector.Setoid` can be an instance. -/
@[nolint unusedArguments]
def RayVector (R M : Type*) [Zero M] 
goal: Type u_6

full_name: RayVector.coe
code: instance RayVector.coe [Zero M] : CoeOut (RayVector R M) M 
goal: CoeOut (RayVector R M) M

full_name: instNonemptyRayVectorOfNontrivial
code: instance {R M : Type*} [Zero M] [Nontrivial M] : Nonempty (RayVector R M) 
goal: Nonempty (RayVector R M)

full_name: RayVector.Setoid
code: /-- The setoid of the `SameRay` relation for the subtype of nonzero vectors. -/
instance RayVector.Setoid : Setoid (RayVector R M) 
goal: Setoid (RayVector R M)

full_name: Module.Ray
code: /-- A ray (equivalence class of nonzero vectors with common positive multiples) in a module. -/
-- Porting note(#5171): removed has_nonempty_instance nolint, no such linter
def Module.Ray 
goal: Type u_2

full_name: equiv_iff_sameRay
code: /-- Equivalence of nonzero vectors, in terms of `SameRay`. -/
theorem equiv_iff_sameRay {v₁ v₂ : RayVector R M} : v₁ ≈ v₂ ↔ SameRay R (v₁ : M) v₂ 
goal: v₁ ≈ v₂ ↔ SameRay R ↑v₁ ↑v₂

full_name: rayOfNeZero
code: /-- The ray given by a nonzero vector. -/
def rayOfNeZero (v : M) (h : v ≠ 0) : Module.Ray R M 
goal: Module.Ray R M

full_name: Module.Ray.ind
code: /-- An induction principle for `Module.Ray`, used as `induction x using Module.Ray.ind`. -/
theorem Module.Ray.ind {C : Module.Ray R M → Prop} (h : ∀ (v) (hv : v ≠ 0), C (rayOfNeZero R v hv))
    (x : Module.Ray R M) : C x 
goal: C x

full_name: instNonemptyRayOfNontrivial
code: instance [Nontrivial M] : Nonempty (Module.Ray R M) 
goal: Nonempty (Module.Ray R M)

full_name: ray_eq_iff
code: /-- The rays given by two nonzero vectors are equal if and only if those vectors
satisfy `SameRay`. -/
theorem ray_eq_iff {v₁ v₂ : M} (hv₁ : v₁ ≠ 0) (hv₂ : v₂ ≠ 0) :
    rayOfNeZero R _ hv₁ = rayOfNeZero R _ hv₂ ↔ SameRay R v₁ v₂ 
goal: rayOfNeZero R v₁ hv₁ = rayOfNeZero R v₂ hv₂ ↔ SameRay R v₁ v₂

full_name: ray_pos_smul
code: /-- The ray given by a positive multiple of a nonzero vector. -/
@[simp]
theorem ray_pos_smul {v : M} (h : v ≠ 0) {r : R} (hr : 0 < r) (hrv : r • v ≠ 0) :
    rayOfNeZero R (r • v) hrv = rayOfNeZero R v h 
goal: rayOfNeZero R (r • v) hrv = rayOfNeZero R v h

full_name: RayVector.mapLinearEquiv
code: /-- An equivalence between modules implies an equivalence between ray vectors. -/
def RayVector.mapLinearEquiv (e : M ≃ₗ[R] N) : RayVector R M ≃ RayVector R N 
goal: RayVector R M ≃ RayVector R N

full_name: Module.Ray.map
code: /-- An equivalence between modules implies an equivalence between rays. -/
def Module.Ray.map (e : M ≃ₗ[R] N) : Module.Ray R M ≃ Module.Ray R N 
goal: Module.Ray R M ≃ Module.Ray R N

full_name: Module.Ray.map_apply
code: @[simp]
theorem Module.Ray.map_apply (e : M ≃ₗ[R] N) (v : M) (hv : v ≠ 0) :
    Module.Ray.map e (rayOfNeZero _ v hv) = rayOfNeZero _ (e v) (e.map_ne_zero_iff.2 hv) 
goal: (Module.Ray.map e) (rayOfNeZero R v hv) = rayOfNeZero R (e v) ⋯

full_name: Module.Ray.map_refl
code: @[simp]
theorem Module.Ray.map_refl : (Module.Ray.map <| LinearEquiv.refl R M) = Equiv.refl _ 
goal: Module.Ray.map (LinearEquiv.refl R M) = Equiv.refl (Module.Ray R M)

full_name: Module.Ray.map_symm
code: @[simp]
theorem Module.Ray.map_symm (e : M ≃ₗ[R] N) : (Module.Ray.map e).symm = Module.Ray.map e.symm 
goal: (Module.Ray.map e).symm = Module.Ray.map e.symm

full_name: instMulActionRayVector
code: /-- Any invertible action preserves the non-zeroness of ray vectors. This is primarily of interest
when `G = Rˣ` -/
instance {R : Type*} : MulAction G (RayVector R M) 
goal: MulAction G (RayVector R M)

full_name: instMulActionRay
code: /-- Any invertible action preserves the non-zeroness of rays. This is primarily of interest when
`G = Rˣ` -/
instance : MulAction G (Module.Ray R M) 
goal: MulAction G (Module.Ray R M)

full_name: Module.Ray.linearEquiv_smul_eq_map
code: /-- The action via `LinearEquiv.apply_distribMulAction` corresponds to `Module.Ray.map`. -/
@[simp]
theorem Module.Ray.linearEquiv_smul_eq_map (e : M ≃ₗ[R] M) (v : Module.Ray R M) :
    e • v = Module.Ray.map e v 
goal: e • v = (Module.Ray.map e) v

full_name: smul_rayOfNeZero
code: @[simp]
theorem smul_rayOfNeZero (g : G) (v : M) (hv) :
    g • rayOfNeZero R v hv = rayOfNeZero R (g • v) ((smul_ne_zero_iff_ne _).2 hv) 
goal: g • rayOfNeZero R v hv = rayOfNeZero R (g • v) ⋯

full_name: Module.Ray.units_smul_of_pos
code: /-- Scaling by a positive unit is a no-op. -/
theorem units_smul_of_pos (u : Rˣ) (hu : 0 < (u.1 : R)) (v : Module.Ray R M) : u • v = v 
goal: u • v = v

full_name: Module.Ray.someRayVector
code: /-- An arbitrary `RayVector` giving a ray. -/
def someRayVector (x : Module.Ray R M) : RayVector R M 
goal: RayVector R M

full_name: Module.Ray.someRayVector_ray
code: /-- The ray of `someRayVector`. -/
@[simp]
theorem someRayVector_ray (x : Module.Ray R M) : (⟦x.someRayVector⟧ : Module.Ray R M) = x 
goal: ⟦x.someRayVector⟧ = x

full_name: Module.Ray.someVector
code: /-- An arbitrary nonzero vector giving a ray. -/
def someVector (x : Module.Ray R M) : M 
goal: M

full_name: Module.Ray.someVector_ne_zero
code: /-- `someVector` is nonzero. -/
@[simp]
theorem someVector_ne_zero (x : Module.Ray R M) : x.someVector ≠ 0 
goal: x.someVector ≠ 0

full_name: Module.Ray.someVector_ray
code: /-- The ray of `someVector`. -/
@[simp]
theorem someVector_ray (x : Module.Ray R M) : rayOfNeZero R _ x.someVector_ne_zero = x 
goal: rayOfNeZero R x.someVector ⋯ = x

full_name: sameRay_neg_iff
code: /-- `SameRay.neg` as an `iff`. -/
@[simp]
theorem sameRay_neg_iff : SameRay R (-x) (-y) ↔ SameRay R x y 
goal: SameRay R (-x) (-y) ↔ SameRay R x y

full_name: sameRay_neg_swap
code: theorem sameRay_neg_swap : SameRay R (-x) y ↔ SameRay R x (-y) 
goal: SameRay R (-x) y ↔ SameRay R x (-y)

full_name: eq_zero_of_sameRay_neg_smul_right
code: theorem eq_zero_of_sameRay_neg_smul_right [NoZeroSMulDivisors R M] {r : R} (hr : r < 0)
    (h : SameRay R x (r • x)) : x = 0 
goal: x = 0

full_name: eq_zero_of_sameRay_self_neg
code: /-- If a vector is in the same ray as its negation, that vector is zero. -/
theorem eq_zero_of_sameRay_self_neg [NoZeroSMulDivisors R M] (h : SameRay R x (-x)) : x = 0 
goal: x = 0

full_name: RayVector.instNeg
code: /-- Negating a nonzero vector. -/
instance {R : Type*} : Neg (RayVector R M) 
goal: Neg (RayVector R M)

full_name: RayVector.coe_neg
code: /-- Negating a nonzero vector commutes with coercion to the underlying module. -/
@[simp, norm_cast]
theorem coe_neg {R : Type*} (v : RayVector R M) : ↑(-v) = -(v : M) 
goal: ↑(-v) = -↑v

full_name: RayVector.instInvolutiveNeg
code: /-- Negating a nonzero vector twice produces the original vector. -/
instance {R : Type*} : InvolutiveNeg (RayVector R M) 
goal: InvolutiveNeg (RayVector R M)

full_name: RayVector.equiv_neg_iff
code: /-- If two nonzero vectors are equivalent, so are their negations. -/
@[simp]
theorem equiv_neg_iff {v₁ v₂ : RayVector R M} : -v₁ ≈ -v₂ ↔ v₁ ≈ v₂ 
goal: -v₁ ≈ -v₂ ↔ v₁ ≈ v₂

full_name: instNegRay
code: /-- Negating a ray. -/
instance : Neg (Module.Ray R M) 
goal: Neg (Module.Ray R M)

full_name: neg_rayOfNeZero
code: /-- The ray given by the negation of a nonzero vector. -/
@[simp]
theorem neg_rayOfNeZero (v : M) (h : v ≠ 0) :
    -rayOfNeZero R _ h = rayOfNeZero R (-v) (neg_ne_zero.2 h) 
goal: -rayOfNeZero R v h = rayOfNeZero R (-v) ⋯

full_name: Module.Ray.instInvolutiveNeg
code: /-- Negating a ray twice produces the original ray. -/
instance : InvolutiveNeg (Module.Ray R M) 
goal: InvolutiveNeg (Module.Ray R M)

full_name: Module.Ray.ne_neg_self
code: /-- A ray does not equal its own negation. -/
theorem ne_neg_self [NoZeroSMulDivisors R M] (x : Module.Ray R M) : x ≠ -x 
goal: x ≠ -x

full_name: Module.Ray.neg_units_smul
code: theorem neg_units_smul (u : Rˣ) (v : Module.Ray R M) : -u • v = -(u • v) 
goal: -u • v = -(u • v)

full_name: Module.Ray.units_smul_of_neg
code: /-- Scaling by a negative unit is negation. -/
theorem units_smul_of_neg (u : Rˣ) (hu : u.1 < 0) (v : Module.Ray R M) : u • v = -v 
goal: u • v = -v

full_name: Module.Ray.map_neg
code: @[simp]
protected theorem map_neg (f : M ≃ₗ[R] N) (v : Module.Ray R M) : map f (-v) = -map f v 
goal: (Module.Ray.map f) (-v) = -(Module.Ray.map f) v

full_name: sameRay_of_mem_orbit
code: /-- `SameRay` follows from membership of `MulAction.orbit` for the `Units.posSubgroup`. -/
theorem sameRay_of_mem_orbit {v₁ v₂ : M} (h : v₁ ∈ MulAction.orbit ↥(Units.posSubgroup R) v₂) :
    SameRay R v₁ v₂ 
goal: SameRay R v₁ v₂

full_name: units_inv_smul
code: /-- Scaling by an inverse unit is the same as scaling by itself. -/
@[simp]
theorem units_inv_smul (u : Rˣ) (v : Module.Ray R M) : u⁻¹ • v = u • v 
goal: u⁻¹ • v = u • v

full_name: sameRay_smul_right_iff
code: @[simp]
theorem sameRay_smul_right_iff {v : M} {r : R} : SameRay R v (r • v) ↔ 0 ≤ r ∨ v = 0 
goal: SameRay R v (r • v) ↔ 0 ≤ r ∨ v = 0

full_name: sameRay_smul_right_iff_of_ne
code: /-- A nonzero vector is in the same ray as a multiple of itself if and only if that multiple
is positive. -/
theorem sameRay_smul_right_iff_of_ne {v : M} (hv : v ≠ 0) {r : R} (hr : r ≠ 0) :
    SameRay R v (r • v) ↔ 0 < r 
goal: SameRay R v (r • v) ↔ 0 < r

full_name: sameRay_smul_left_iff
code: @[simp]
theorem sameRay_smul_left_iff {v : M} {r : R} : SameRay R (r • v) v ↔ 0 ≤ r ∨ v = 0 
goal: SameRay R (r • v) v ↔ 0 ≤ r ∨ v = 0

full_name: sameRay_smul_left_iff_of_ne
code: /-- A multiple of a nonzero vector is in the same ray as that vector if and only if that multiple
is positive. -/
theorem sameRay_smul_left_iff_of_ne {v : M} (hv : v ≠ 0) {r : R} (hr : r ≠ 0) :
    SameRay R (r • v) v ↔ 0 < r 
goal: SameRay R (r • v) v ↔ 0 < r

full_name: sameRay_neg_smul_right_iff
code: @[simp]
theorem sameRay_neg_smul_right_iff {v : M} {r : R} : SameRay R (-v) (r • v) ↔ r ≤ 0 ∨ v = 0 
goal: SameRay R (-v) (r • v) ↔ r ≤ 0 ∨ v = 0

full_name: sameRay_neg_smul_right_iff_of_ne
code: theorem sameRay_neg_smul_right_iff_of_ne {v : M} {r : R} (hv : v ≠ 0) (hr : r ≠ 0) :
    SameRay R (-v) (r • v) ↔ r < 0 
goal: SameRay R (-v) (r • v) ↔ r < 0

full_name: sameRay_neg_smul_left_iff
code: @[simp]
theorem sameRay_neg_smul_left_iff {v : M} {r : R} : SameRay R (r • v) (-v) ↔ r ≤ 0 ∨ v = 0 
goal: SameRay R (r • v) (-v) ↔ r ≤ 0 ∨ v = 0

full_name: sameRay_neg_smul_left_iff_of_ne
code: theorem sameRay_neg_smul_left_iff_of_ne {v : M} {r : R} (hv : v ≠ 0) (hr : r ≠ 0) :
    SameRay R (r • v) (-v) ↔ r < 0 
goal: SameRay R (r • v) (-v) ↔ r < 0

full_name: units_smul_eq_self_iff
code: @[simp]
theorem units_smul_eq_self_iff {u : Rˣ} {v : Module.Ray R M} : u • v = v ↔ 0 < u.1 
goal: u • v = v ↔ 0 < ↑u

full_name: units_smul_eq_neg_iff
code: @[simp]
theorem units_smul_eq_neg_iff {u : Rˣ} {v : Module.Ray R M} : u • v = -v ↔ u.1 < 0 
goal: u • v = -v ↔ ↑u < 0

full_name: sameRay_or_sameRay_neg_iff_not_linearIndependent
code: /-- Two vectors are in the same ray, or the first is in the same ray as the negation of the
second, if and only if they are not linearly independent. -/
theorem sameRay_or_sameRay_neg_iff_not_linearIndependent {x y : M} :
    SameRay R x y ∨ SameRay R x (-y) ↔ ¬LinearIndependent R ![x, y] 
goal: SameRay R x y ∨ SameRay R x (-y) ↔ ¬LinearIndependent R ![x, y]

full_name: sameRay_or_ne_zero_and_sameRay_neg_iff_not_linearIndependent
code: /-- Two vectors are in the same ray, or they are nonzero and the first is in the same ray as the
negation of the second, if and only if they are not linearly independent. -/
theorem sameRay_or_ne_zero_and_sameRay_neg_iff_not_linearIndependent {x y : M} :
    SameRay R x y ∨ x ≠ 0 ∧ y ≠ 0 ∧ SameRay R x (-y) ↔ ¬LinearIndependent R ![x, y] 
goal: SameRay R x y ∨ x ≠ 0 ∧ y ≠ 0 ∧ SameRay R x (-y) ↔ ¬LinearIndependent R ![x, y]

full_name: SameRay.exists_pos_left
code: theorem exists_pos_left (h : SameRay R x y) (hx : x ≠ 0) (hy : y ≠ 0) :
    ∃ r : R, 0 < r ∧ r • x = y 
goal: ∃ r, 0 < r ∧ r • x = y

full_name: SameRay.exists_pos_right
code: theorem exists_pos_right (h : SameRay R x y) (hx : x ≠ 0) (hy : y ≠ 0) :
    ∃ r : R, 0 < r ∧ x = r • y 
goal: ∃ r, 0 < r ∧ x = r • y

full_name: SameRay.exists_nonneg_left
code: /-- If a vector `v₂` is on the same ray as a nonzero vector `v₁`, then it is equal to `c • v₁` for
some nonnegative `c`. -/
theorem exists_nonneg_left (h : SameRay R x y) (hx : x ≠ 0) : ∃ r : R, 0 ≤ r ∧ r • x = y 
goal: ∃ r, 0 ≤ r ∧ r • x = y

full_name: SameRay.exists_nonneg_right
code: /-- If a vector `v₁` is on the same ray as a nonzero vector `v₂`, then it is equal to `c • v₂` for
some nonnegative `c`. -/
theorem exists_nonneg_right (h : SameRay R x y) (hy : y ≠ 0) : ∃ r : R, 0 ≤ r ∧ x = r • y 
goal: ∃ r, 0 ≤ r ∧ x = r • y

full_name: SameRay.exists_eq_smul_add
code: /-- If vectors `v₁` and `v₂` are on the same ray, then for some nonnegative `a b`, `a + b = 1`, we
have `v₁ = a • (v₁ + v₂)` and `v₂ = b • (v₁ + v₂)`. -/
theorem exists_eq_smul_add (h : SameRay R v₁ v₂) :
    ∃ a b : R, 0 ≤ a ∧ 0 ≤ b ∧ a + b = 1 ∧ v₁ = a • (v₁ + v₂) ∧ v₂ = b • (v₁ + v₂) 
goal: ∃ a b, 0 ≤ a ∧ 0 ≤ b ∧ a + b = 1 ∧ v₁ = a • (v₁ + v₂) ∧ v₂ = b • (v₁ + v₂)

full_name: SameRay.exists_eq_smul
code: /-- If vectors `v₁` and `v₂` are on the same ray, then they are nonnegative multiples of the same
vector. Actually, this vector can be assumed to be `v₁ + v₂`, see `SameRay.exists_eq_smul_add`. -/
theorem exists_eq_smul (h : SameRay R v₁ v₂) :
    ∃ (u : M) (a b : R), 0 ≤ a ∧ 0 ≤ b ∧ a + b = 1 ∧ v₁ = a • u ∧ v₂ = b • u 
goal: ∃ u a b, 0 ≤ a ∧ 0 ≤ b ∧ a + b = 1 ∧ v₁ = a • u ∧ v₂ = b • u

full_name: exists_pos_left_iff_sameRay
code: theorem exists_pos_left_iff_sameRay (hx : x ≠ 0) (hy : y ≠ 0) :
    (∃ r : R, 0 < r ∧ r • x = y) ↔ SameRay R x y 
goal: (∃ r, 0 < r ∧ r • x = y) ↔ SameRay R x y

full_name: exists_pos_left_iff_sameRay_and_ne_zero
code: theorem exists_pos_left_iff_sameRay_and_ne_zero (hx : x ≠ 0) :
    (∃ r : R, 0 < r ∧ r • x = y) ↔ SameRay R x y ∧ y ≠ 0 
goal: (∃ r, 0 < r ∧ r • x = y) ↔ SameRay R x y ∧ y ≠ 0

full_name: exists_nonneg_left_iff_sameRay
code: theorem exists_nonneg_left_iff_sameRay (hx : x ≠ 0) :
    (∃ r : R, 0 ≤ r ∧ r • x = y) ↔ SameRay R x y 
goal: (∃ r, 0 ≤ r ∧ r • x = y) ↔ SameRay R x y

full_name: exists_pos_right_iff_sameRay
code: theorem exists_pos_right_iff_sameRay (hx : x ≠ 0) (hy : y ≠ 0) :
    (∃ r : R, 0 < r ∧ x = r • y) ↔ SameRay R x y 
goal: (∃ r, 0 < r ∧ x = r • y) ↔ SameRay R x y

full_name: exists_pos_right_iff_sameRay_and_ne_zero
code: theorem exists_pos_right_iff_sameRay_and_ne_zero (hy : y ≠ 0) :
    (∃ r : R, 0 < r ∧ x = r • y) ↔ SameRay R x y ∧ x ≠ 0 
goal: (∃ r, 0 < r ∧ x = r • y) ↔ SameRay R x y ∧ x ≠ 0

full_name: exists_nonneg_right_iff_sameRay
code: theorem exists_nonneg_right_iff_sameRay (hy : y ≠ 0) :
    (∃ r : R, 0 ≤ r ∧ x = r • y) ↔ SameRay R x y 
goal: (∃ r, 0 ≤ r ∧ x = r • y) ↔ SameRay R x y