l3lab/ntp-mathlib huggingface dataset:
@[simp] lemma _root_.LinearMap.surjective_domRestrict_iff
    {f : M →ₛₗ[τ₁₂] M₂} {S : Submodule R M} (hf : Surjective f) :
    Surjective (f.domRestrict S) ↔ S ⊔ LinearMap.ker f = ⊤ := by
  rw [← LinearMap.range_eq_top] at hf ⊢
  rw [← hf]
  

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S✝ : Type u_7
inst✝⁶ : Semiring R
inst✝⁵ : Semiring R₂
inst✝⁴ : AddCommGroup M
inst✝³ : Module R M
inst✝² : AddCommGroup M₂
inst✝¹ : Module R₂ M₂
τ₁₂ : R →+* R₂
inst✝ : RingHomSurjective τ₁₂
F : Type u_8
sc : SemilinearMapClass F τ₁₂ M M₂
f : M →ₛₗ[τ₁₂] M₂
S : Submodule R M
hf : LinearMap.range f = ⊤
⊢ LinearMap.range (LinearMap.domRestrict f S) = LinearMap.range f ↔ S ⊔ LinearMap.ker f = ⊤

Next tactic:
exact LinearMap.range_domRestrict_eq_range_iff
/-- There is no vector subspace between `p` and `(K ∙ x) ⊔ p`, `Wcovby` version. -/
theorem wcovby_span_singleton_sup (x : V) (p : Submodule K V) : Wcovby p ((K ∙ x) ⊔ p) := by
  

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : DivisionRing K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
x : V
p : Submodule K V
⊢ p ⩿ span K {x} ⊔ p

Next tactic:
refine ⟨le_sup_right, fun q hpq hqp ↦ hqp.not_le ?_⟩
/-- There is no vector subspace between `p` and `(K ∙ x) ⊔ p`, `Wcovby` version. -/
theorem wcovby_span_singleton_sup (x : V) (p : Submodule K V) : Wcovby p ((K ∙ x) ⊔ p) := by
  refine ⟨le_sup_right, fun q hpq hqp ↦ hqp.not_le ?_⟩
  

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : DivisionRing K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
x : V
p q : Submodule K V
hpq : p < q
hqp : q < span K {x} ⊔ p
⊢ span K {x} ⊔ p ≤ q

Next tactic:
rcases SetLike.exists_of_lt hpq with ⟨y, hyq, hyp⟩
/-- There is no vector subspace between `p` and `(K ∙ x) ⊔ p`, `Wcovby` version. -/
theorem wcovby_span_singleton_sup (x : V) (p : Submodule K V) : Wcovby p ((K ∙ x) ⊔ p) := by
  refine ⟨le_sup_right, fun q hpq hqp ↦ hqp.not_le ?_⟩
  rcases SetLike.exists_of_lt hpq with ⟨y, hyq, hyp⟩
  

Proof state:
case intro.intro
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : DivisionRing K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
x : V
p q : Submodule K V
hpq : p < q
hqp : q < span K {x} ⊔ p
y : V
hyq : y ∈ q
hyp : y ∉ p
⊢ span K {x} ⊔ p ≤ q

Next tactic:
obtain ⟨c, z, hz, rfl⟩ : ∃ c : K, ∃ z ∈ p, c • x + z = y := by
    simpa [mem_sup, mem_span_singleton] using hqp.le hyq
/-- There is no vector subspace between `p` and `(K ∙ x) ⊔ p`, `Wcovby` version. -/
theorem wcovby_span_singleton_sup (x : V) (p : Submodule K V) : Wcovby p ((K ∙ x) ⊔ p) := by
  refine ⟨le_sup_right, fun q hpq hqp ↦ hqp.not_le ?_⟩
  rcases SetLike.exists_of_lt hpq with ⟨y, hyq, hyp⟩
  obtain ⟨c, z, hz, rfl⟩ : ∃ c : K, ∃ z ∈ p, c • x + z = y := by
    

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : DivisionRing K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
x : V
p q : Submodule K V
hpq : p < q
hqp : q < span K {x} ⊔ p
y : V
hyq : y ∈ q
hyp : y ∉ p
⊢ ∃ c, ∃ z ∈ p, c • x + z = y

Next tactic:
simpa [mem_sup, mem_span_singleton] using hqp.le hyq
/-- There is no vector subspace between `p` and `(K ∙ x) ⊔ p`, `Wcovby` version. -/
theorem wcovby_span_singleton_sup (x : V) (p : Submodule K V) : Wcovby p ((K ∙ x) ⊔ p) := by
  refine ⟨le_sup_right, fun q hpq hqp ↦ hqp.not_le ?_⟩
  rcases SetLike.exists_of_lt hpq with ⟨y, hyq, hyp⟩
  obtain ⟨c, z, hz, rfl⟩ : ∃ c : K, ∃ z ∈ p, c • x + z = y := by
    simpa [mem_sup, mem_span_singleton] using hqp.le hyq
  

Proof state:
case intro.intro.intro.intro.intro
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : DivisionRing K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
x : V
p q : Submodule K V
hpq : p < q
hqp : q < span K {x} ⊔ p
c : K
z : V
hz : z ∈ p
hyq : c • x + z ∈ q
hyp : c • x + z ∉ p
⊢ span K {x} ⊔ p ≤ q

Next tactic:
rcases eq_or_ne c 0 with rfl | hc
/-- There is no vector subspace between `p` and `(K ∙ x) ⊔ p`, `Wcovby` version. -/
theorem wcovby_span_singleton_sup (x : V) (p : Submodule K V) : Wcovby p ((K ∙ x) ⊔ p) := by
  refine ⟨le_sup_right, fun q hpq hqp ↦ hqp.not_le ?_⟩
  rcases SetLike.exists_of_lt hpq with ⟨y, hyq, hyp⟩
  obtain ⟨c, z, hz, rfl⟩ : ∃ c : K, ∃ z ∈ p, c • x + z = y := by
    simpa [mem_sup, mem_span_singleton] using hqp.le hyq
  rcases eq_or_ne c 0 with rfl | hc
  · 

Proof state:
case intro.intro.intro.intro.intro.inl
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : DivisionRing K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
x : V
p q : Submodule K V
hpq : p < q
hqp : q < span K {x} ⊔ p
z : V
hz : z ∈ p
hyq : 0 • x + z ∈ q
hyp : 0 • x + z ∉ p
⊢ span K {x} ⊔ p ≤ q

Next tactic:
simp [hz] at hyp
/-- There is no vector subspace between `p` and `(K ∙ x) ⊔ p`, `Wcovby` version. -/
theorem wcovby_span_singleton_sup (x : V) (p : Submodule K V) : Wcovby p ((K ∙ x) ⊔ p) := by
  refine ⟨le_sup_right, fun q hpq hqp ↦ hqp.not_le ?_⟩
  rcases SetLike.exists_of_lt hpq with ⟨y, hyq, hyp⟩
  obtain ⟨c, z, hz, rfl⟩ : ∃ c : K, ∃ z ∈ p, c • x + z = y := by
    simpa [mem_sup, mem_span_singleton] using hqp.le hyq
  rcases eq_or_ne c 0 with rfl | hc
  · simp [hz] at hyp
  · 

Proof state:
case intro.intro.intro.intro.intro.inr
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : DivisionRing K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
x : V
p q : Submodule K V
hpq : p < q
hqp : q < span K {x} ⊔ p
c : K
z : V
hz : z ∈ p
hyq : c • x + z ∈ q
hyp : c • x + z ∉ p
hc : c ≠ 0
⊢ span K {x} ⊔ p ≤ q

Next tactic:
have : x ∈ q
/-- There is no vector subspace between `p` and `(K ∙ x) ⊔ p`, `Wcovby` version. -/
theorem wcovby_span_singleton_sup (x : V) (p : Submodule K V) : Wcovby p ((K ∙ x) ⊔ p) := by
  refine ⟨le_sup_right, fun q hpq hqp ↦ hqp.not_le ?_⟩
  rcases SetLike.exists_of_lt hpq with ⟨y, hyq, hyp⟩
  obtain ⟨c, z, hz, rfl⟩ : ∃ c : K, ∃ z ∈ p, c • x + z = y := by
    simpa [mem_sup, mem_span_singleton] using hqp.le hyq
  rcases eq_or_ne c 0 with rfl | hc
  · simp [hz] at hyp
  · have : x ∈ q
    · 

Proof state:
case this
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : DivisionRing K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
x : V
p q : Submodule K V
hpq : p < q
hqp : q < span K {x} ⊔ p
c : K
z : V
hz : z ∈ p
hyq : c • x + z ∈ q
hyp : c • x + z ∉ p
hc : c ≠ 0
⊢ x ∈ q

Next tactic:
rwa [q.add_mem_iff_left (hpq.le hz), q.smul_mem_iff hc] at hyq
/-- There is no vector subspace between `p` and `(K ∙ x) ⊔ p`, `Wcovby` version. -/
theorem wcovby_span_singleton_sup (x : V) (p : Submodule K V) : Wcovby p ((K ∙ x) ⊔ p) := by
  refine ⟨le_sup_right, fun q hpq hqp ↦ hqp.not_le ?_⟩
  rcases SetLike.exists_of_lt hpq with ⟨y, hyq, hyp⟩
  obtain ⟨c, z, hz, rfl⟩ : ∃ c : K, ∃ z ∈ p, c • x + z = y := by
    simpa [mem_sup, mem_span_singleton] using hqp.le hyq
  rcases eq_or_ne c 0 with rfl | hc
  · simp [hz] at hyp
  · have : x ∈ q
    · rwa [q.add_mem_iff_left (hpq.le hz), q.smul_mem_iff hc] at hyq
    

Proof state:
case intro.intro.intro.intro.intro.inr
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : DivisionRing K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
x : V
p q : Submodule K V
hpq : p < q
hqp : q < span K {x} ⊔ p
c : K
z : V
hz : z ∈ p
hyq : c • x + z ∈ q
hyp : c • x + z ∉ p
hc : c ≠ 0
this : x ∈ q
⊢ span K {x} ⊔ p ≤ q

Next tactic:
simp [hpq.le, this]
/-- There is no vector subspace between `p` and `(K ∙ x) ⊔ p`, `Covby` version. -/
theorem covby_span_singleton_sup {x : V} {p : Submodule K V} (h : x ∉ p) : Covby p ((K ∙ x) ⊔ p) :=
  ⟨by 

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : DivisionRing K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
x : V
p : Submodule K V
h : x ∉ p
⊢ p < span K {x} ⊔ p

Next tactic:
simpa
protected theorem map_le_map_iff (f : F) {p p'} : map f p ≤ map f p' ↔ p ≤ p' ⊔ ker f := by
  

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝⁶ : Semiring R
inst✝⁵ : Semiring R₂
inst✝⁴ : AddCommGroup M
inst✝³ : AddCommGroup M₂
inst✝² : Module R M
inst✝¹ : Module R₂ M₂
τ₁₂ : R →+* R₂
inst✝ : RingHomSurjective τ₁₂
F : Type u_8
sc : SemilinearMapClass F τ₁₂ M M₂
f : F
p p' : Submodule R M
⊢ map f p ≤ map f p' ↔ p ≤ p' ⊔ ker f

Next tactic:
rw [map_le_iff_le_comap, Submodule.comap_map_eq]
theorem map_le_map_iff' {f : F} (hf : ker f = ⊥) {p p'} : map f p ≤ map f p' ↔ p ≤ p' := by
  

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝⁶ : Semiring R
inst✝⁵ : Semiring R₂
inst✝⁴ : AddCommGroup M
inst✝³ : AddCommGroup M₂
inst✝² : Module R M
inst✝¹ : Module R₂ M₂
τ₁₂ : R →+* R₂
inst✝ : RingHomSurjective τ₁₂
F : Type u_8
sc : SemilinearMapClass F τ₁₂ M M₂
f : F
hf : ker f = ⊥
p p' : Submodule R M
⊢ map f p ≤ map f p' ↔ p ≤ p'

Next tactic:
rw [LinearMap.map_le_map_iff, hf, sup_bot_eq]
theorem map_eq_top_iff {f : F} (hf : range f = ⊤) {p : Submodule R M} :
    p.map f = ⊤ ↔ p ⊔ LinearMap.ker f = ⊤ := by
  

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝⁶ : Semiring R
inst✝⁵ : Semiring R₂
inst✝⁴ : AddCommGroup M
inst✝³ : AddCommGroup M₂
inst✝² : Module R M
inst✝¹ : Module R₂ M₂
τ₁₂ : R →+* R₂
inst✝ : RingHomSurjective τ₁₂
F : Type u_8
sc : SemilinearMapClass F τ₁₂ M M₂
f : F
hf : range f = ⊤
p : Submodule R M
⊢ map f p = ⊤ ↔ p ⊔ ker f = ⊤

Next tactic:
simp_rw [← top_le_iff, ← hf, range_eq_map, LinearMap.map_le_map_iff]
/-- The range of `toSpanSingleton x` is the span of `x`.-/
theorem span_singleton_eq_range (x : M) : (R ∙ x) = range (toSpanSingleton R M x) :=
  Submodule.ext fun y => by
    

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x y : M
⊢ y ∈ span R {x} ↔ y ∈ range (toSpanSingleton R M x)

Next tactic:
refine' Iff.trans _ LinearMap.mem_range.symm
/-- The range of `toSpanSingleton x` is the span of `x`.-/
theorem span_singleton_eq_range (x : M) : (R ∙ x) = range (toSpanSingleton R M x) :=
  Submodule.ext fun y => by
    refine' Iff.trans _ LinearMap.mem_range.symm
    

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x y : M
⊢ y ∈ span R {x} ↔ ∃ y_1, (toSpanSingleton R M x) y_1 = y

Next tactic:
exact mem_span_singleton
@[simp]
theorem toSpanSingleton_zero : toSpanSingleton R M 0 = 0 := by
  

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
⊢ toSpanSingleton R M 0 = 0

Next tactic:
ext
@[simp]
theorem toSpanSingleton_zero : toSpanSingleton R M 0 = 0 := by
  ext
  

Proof state:
case h
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
⊢ (toSpanSingleton R M 0) 1 = 0 1

Next tactic:
simp
/-- Two linear maps are equal on `Submodule.span s` iff they are equal on `s`. -/
theorem eqOn_span_iff {s : Set M} {f g : F} : Set.EqOn f g (span R s) ↔ Set.EqOn f g s := by
  

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : Semiring R₂
inst✝² : AddCommMonoid M₂
inst✝¹ : Module R₂ M₂
F : Type u_8
σ₁₂ : R →+* R₂
inst✝ : SemilinearMapClass F σ₁₂ M M₂
s : Set M
f g : F
⊢ Set.EqOn ⇑f ⇑g ↑(span R s) ↔ Set.EqOn (⇑f) (⇑g) s

Next tactic:
rw [← le_eqLocus, span_le]
/-- Two linear maps are equal on `Submodule.span s` iff they are equal on `s`. -/
theorem eqOn_span_iff {s : Set M} {f g : F} : Set.EqOn f g (span R s) ↔ Set.EqOn f g s := by
  rw [← le_eqLocus, span_le]; 

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : Semiring R₂
inst✝² : AddCommMonoid M₂
inst✝¹ : Module R₂ M₂
F : Type u_8
σ₁₂ : R →+* R₂
inst✝ : SemilinearMapClass F σ₁₂ M M₂
s : Set M
f g : F
⊢ s ⊆ ↑(eqLocus f g) ↔ Set.EqOn (⇑f) (⇑g) s

Next tactic:
rfl
theorem span_singleton_sup_ker_eq_top (f : V →ₗ[K] K) {x : V} (hx : f x ≠ 0) :
    (K ∙ x) ⊔ ker f = ⊤ :=
  top_unique fun y _ =>
    Submodule.mem_sup.2
      ⟨(f y * (f x)⁻¹) • x, Submodule.mem_span_singleton.2 ⟨f y * (f x)⁻¹, rfl⟩,
        ⟨y - (f y * (f x)⁻¹) • x, by 

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝² : Field K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
f : V →ₗ[K] K
x : V
hx : f x ≠ 0
y : V
x✝ : y ∈ ⊤
⊢ y - (f y * (f x)⁻¹) • x ∈ ker f ∧ (f y * (f x)⁻¹) • x + (y - (f y * (f x)⁻¹) • x) = y

Next tactic:
simp [hx]
theorem toSpanNonzeroSingleton_one :
    LinearEquiv.toSpanNonzeroSingleton R M x h 1 =
      (⟨x, Submodule.mem_span_singleton_self x⟩ : R ∙ x) := by
  

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : NoZeroSMulDivisors R M
x : M
h : x ≠ 0
⊢ (toSpanNonzeroSingleton R M x h) 1 = { val := x, property := (_ : x ∈ Submodule.span R {x}) }

Next tactic:
apply SetLike.coe_eq_coe.mp
theorem toSpanNonzeroSingleton_one :
    LinearEquiv.toSpanNonzeroSingleton R M x h 1 =
      (⟨x, Submodule.mem_span_singleton_self x⟩ : R ∙ x) := by
  apply SetLike.coe_eq_coe.mp
  

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : NoZeroSMulDivisors R M
x : M
h : x ≠ 0
⊢ ↑((toSpanNonzeroSingleton R M x h) 1) = ↑{ val := x, property := (_ : x ∈ Submodule.span R {x}) }

Next tactic:
have : ↑(toSpanNonzeroSingleton R M x h 1) = toSpanSingleton R M x 1 := rfl
theorem toSpanNonzeroSingleton_one :
    LinearEquiv.toSpanNonzeroSingleton R M x h 1 =
      (⟨x, Submodule.mem_span_singleton_self x⟩ : R ∙ x) := by
  apply SetLike.coe_eq_coe.mp
  have : ↑(toSpanNonzeroSingleton R M x h 1) = toSpanSingleton R M x 1 := rfl
  

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : NoZeroSMulDivisors R M
x : M
h : x ≠ 0
this : ↑((toSpanNonzeroSingleton R M x h) 1) = (toSpanSingleton R M x) 1
⊢ ↑((toSpanNonzeroSingleton R M x h) 1) = ↑{ val := x, property := (_ : x ∈ Submodule.span R {x}) }

Next tactic:
rw [this, toSpanSingleton_one, Submodule.coe_mk]
theorem coord_self : (coord R M x h) (⟨x, Submodule.mem_span_singleton_self x⟩ : R ∙ x) = 1 := by
  

Proof state:
R : Type u_1
R₂ : Type u_2
K : Type u_3
M : Type u_4
M₂ : Type u_5
V : Type u_6
S : Type u_7
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : NoZeroSMulDivisors R M
x : M
h : x ≠ 0
⊢ (coord R M x h) { val := x, property := (_ : x ∈ Submodule.span R {x}) } = 1

Next tactic:
rw [← toSpanNonzeroSingleton_one R M x h, LinearEquiv.symm_apply_apply]
instance instLinearOrderInt : LinearOrder ℤ where
  le := (·≤·)
  le_refl := Int.le_refl
  le_trans := @Int.le_trans
  le_antisymm := @Int.le_antisymm
  lt := (·<·)
  lt_iff_le_not_le := @Int.lt_iff_le_not_le
  le_total := Int.le_total
  decidableEq := by infer_instance
  decidableLE := by 

Proof state:
⊢ DecidableRel fun x x_1 => x ≤ x_1

Next tactic:
infer_instance
instance instLinearOrderInt : LinearOrder ℤ where
  le := (·≤·)
  le_refl := Int.le_refl
  le_trans := @Int.le_trans
  le_antisymm := @Int.le_antisymm
  lt := (·<·)
  lt_iff_le_not_le := @Int.lt_iff_le_not_le
  le_total := Int.le_total
  decidableEq := by 

Proof state:
⊢ DecidableEq ℤ

Next tactic:
infer_instance
instance instLinearOrderInt : LinearOrder ℤ where
  le := (·≤·)
  le_refl := Int.le_refl
  le_trans := @Int.le_trans
  le_antisymm := @Int.le_antisymm
  lt := (·<·)
  lt_iff_le_not_le := @Int.lt_iff_le_not_le
  le_total := Int.le_total
  decidableEq := by infer_instance
  decidableLE := by infer_instance
  decidableLT := by 

Proof state:
⊢ DecidableRel fun x x_1 => x < x_1

Next tactic:
infer_instance
protected theorem eq_zero_or_eq_zero_of_mul_eq_zero {a b : ℤ} (h : a * b = 0) : a = 0 ∨ b = 0 :=
  match lt_trichotomy 0 a with
  | Or.inl hlt₁ =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      

Proof state:
a b : ℤ
h : a * b = 0
hlt₁ : 0 < a
hlt₂ : 0 < b
⊢ a = 0 ∨ b = 0

Next tactic:
have : 0 < a * b := Int.mul_pos hlt₁ hlt₂
protected theorem eq_zero_or_eq_zero_of_mul_eq_zero {a b : ℤ} (h : a * b = 0) : a = 0 ∨ b = 0 :=
  match lt_trichotomy 0 a with
  | Or.inl hlt₁ =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 < a * b := Int.mul_pos hlt₁ hlt₂
      

Proof state:
a b : ℤ
h : a * b = 0
hlt₁ : 0 < a
hlt₂ : 0 < b
this : 0 < a * b
⊢ a = 0 ∨ b = 0

Next tactic:
rw [h] at this
protected theorem eq_zero_or_eq_zero_of_mul_eq_zero {a b : ℤ} (h : a * b = 0) : a = 0 ∨ b = 0 :=
  match lt_trichotomy 0 a with
  | Or.inl hlt₁ =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 < a * b := Int.mul_pos hlt₁ hlt₂
      rw [h] at this
      

Proof state:
a b : ℤ
h : a * b = 0
hlt₁ : 0 < a
hlt₂ : 0 < b
this : 0 < 0
⊢ a = 0 ∨ b = 0

Next tactic:
exact absurd this (lt_irrefl _)
protected theorem eq_zero_or_eq_zero_of_mul_eq_zero {a b : ℤ} (h : a * b = 0) : a = 0 ∨ b = 0 :=
  match lt_trichotomy 0 a with
  | Or.inl hlt₁ =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 < a * b := Int.mul_pos hlt₁ hlt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
    | Or.inr (Or.inl heq₂) => Or.inr heq₂.symm
    | Or.inr (Or.inr hgt₂) => by
      

Proof state:
a b : ℤ
h : a * b = 0
hlt₁ : 0 < a
hgt₂ : b < 0
⊢ a = 0 ∨ b = 0

Next tactic:
have : 0 > a * b := Int.mul_neg_of_pos_of_neg hlt₁ hgt₂
protected theorem eq_zero_or_eq_zero_of_mul_eq_zero {a b : ℤ} (h : a * b = 0) : a = 0 ∨ b = 0 :=
  match lt_trichotomy 0 a with
  | Or.inl hlt₁ =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 < a * b := Int.mul_pos hlt₁ hlt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
    | Or.inr (Or.inl heq₂) => Or.inr heq₂.symm
    | Or.inr (Or.inr hgt₂) => by
      have : 0 > a * b := Int.mul_neg_of_pos_of_neg hlt₁ hgt₂
      

Proof state:
a b : ℤ
h : a * b = 0
hlt₁ : 0 < a
hgt₂ : b < 0
this : 0 > a * b
⊢ a = 0 ∨ b = 0

Next tactic:
rw [h] at this
protected theorem eq_zero_or_eq_zero_of_mul_eq_zero {a b : ℤ} (h : a * b = 0) : a = 0 ∨ b = 0 :=
  match lt_trichotomy 0 a with
  | Or.inl hlt₁ =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 < a * b := Int.mul_pos hlt₁ hlt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
    | Or.inr (Or.inl heq₂) => Or.inr heq₂.symm
    | Or.inr (Or.inr hgt₂) => by
      have : 0 > a * b := Int.mul_neg_of_pos_of_neg hlt₁ hgt₂
      rw [h] at this
      

Proof state:
a b : ℤ
h : a * b = 0
hlt₁ : 0 < a
hgt₂ : b < 0
this : 0 > 0
⊢ a = 0 ∨ b = 0

Next tactic:
exact absurd this (lt_irrefl _)
protected theorem eq_zero_or_eq_zero_of_mul_eq_zero {a b : ℤ} (h : a * b = 0) : a = 0 ∨ b = 0 :=
  match lt_trichotomy 0 a with
  | Or.inl hlt₁ =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 < a * b := Int.mul_pos hlt₁ hlt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
    | Or.inr (Or.inl heq₂) => Or.inr heq₂.symm
    | Or.inr (Or.inr hgt₂) => by
      have : 0 > a * b := Int.mul_neg_of_pos_of_neg hlt₁ hgt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
  | Or.inr (Or.inl heq₁) => Or.inl heq₁.symm
  | Or.inr (Or.inr hgt₁) =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      

Proof state:
a b : ℤ
h : a * b = 0
hgt₁ : a < 0
hlt₂ : 0 < b
⊢ a = 0 ∨ b = 0

Next tactic:
have : 0 > a * b := Int.mul_neg_of_neg_of_pos hgt₁ hlt₂
protected theorem eq_zero_or_eq_zero_of_mul_eq_zero {a b : ℤ} (h : a * b = 0) : a = 0 ∨ b = 0 :=
  match lt_trichotomy 0 a with
  | Or.inl hlt₁ =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 < a * b := Int.mul_pos hlt₁ hlt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
    | Or.inr (Or.inl heq₂) => Or.inr heq₂.symm
    | Or.inr (Or.inr hgt₂) => by
      have : 0 > a * b := Int.mul_neg_of_pos_of_neg hlt₁ hgt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
  | Or.inr (Or.inl heq₁) => Or.inl heq₁.symm
  | Or.inr (Or.inr hgt₁) =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 > a * b := Int.mul_neg_of_neg_of_pos hgt₁ hlt₂
      

Proof state:
a b : ℤ
h : a * b = 0
hgt₁ : a < 0
hlt₂ : 0 < b
this : 0 > a * b
⊢ a = 0 ∨ b = 0

Next tactic:
rw [h] at this
protected theorem eq_zero_or_eq_zero_of_mul_eq_zero {a b : ℤ} (h : a * b = 0) : a = 0 ∨ b = 0 :=
  match lt_trichotomy 0 a with
  | Or.inl hlt₁ =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 < a * b := Int.mul_pos hlt₁ hlt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
    | Or.inr (Or.inl heq₂) => Or.inr heq₂.symm
    | Or.inr (Or.inr hgt₂) => by
      have : 0 > a * b := Int.mul_neg_of_pos_of_neg hlt₁ hgt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
  | Or.inr (Or.inl heq₁) => Or.inl heq₁.symm
  | Or.inr (Or.inr hgt₁) =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 > a * b := Int.mul_neg_of_neg_of_pos hgt₁ hlt₂
      rw [h] at this
      

Proof state:
a b : ℤ
h : a * b = 0
hgt₁ : a < 0
hlt₂ : 0 < b
this : 0 > 0
⊢ a = 0 ∨ b = 0

Next tactic:
exact absurd this (lt_irrefl _)
protected theorem eq_zero_or_eq_zero_of_mul_eq_zero {a b : ℤ} (h : a * b = 0) : a = 0 ∨ b = 0 :=
  match lt_trichotomy 0 a with
  | Or.inl hlt₁ =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 < a * b := Int.mul_pos hlt₁ hlt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
    | Or.inr (Or.inl heq₂) => Or.inr heq₂.symm
    | Or.inr (Or.inr hgt₂) => by
      have : 0 > a * b := Int.mul_neg_of_pos_of_neg hlt₁ hgt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
  | Or.inr (Or.inl heq₁) => Or.inl heq₁.symm
  | Or.inr (Or.inr hgt₁) =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 > a * b := Int.mul_neg_of_neg_of_pos hgt₁ hlt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
    | Or.inr (Or.inl heq₂) => Or.inr heq₂.symm
    | Or.inr (Or.inr hgt₂) => by
      

Proof state:
a b : ℤ
h : a * b = 0
hgt₁ : a < 0
hgt₂ : b < 0
⊢ a = 0 ∨ b = 0

Next tactic:
have : 0 < a * b := Int.mul_pos_of_neg_of_neg hgt₁ hgt₂
protected theorem eq_zero_or_eq_zero_of_mul_eq_zero {a b : ℤ} (h : a * b = 0) : a = 0 ∨ b = 0 :=
  match lt_trichotomy 0 a with
  | Or.inl hlt₁ =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 < a * b := Int.mul_pos hlt₁ hlt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
    | Or.inr (Or.inl heq₂) => Or.inr heq₂.symm
    | Or.inr (Or.inr hgt₂) => by
      have : 0 > a * b := Int.mul_neg_of_pos_of_neg hlt₁ hgt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
  | Or.inr (Or.inl heq₁) => Or.inl heq₁.symm
  | Or.inr (Or.inr hgt₁) =>
    match lt_trichotomy 0 b with
    | Or.inl hlt₂ => by
      have : 0 > a * b := Int.mul_neg_of_neg_of_pos hgt₁ hlt₂
      rw [h] at this
      exact absurd this (lt_irrefl _)
    | Or.inr (Or.inl heq₂) => Or.inr heq₂.symm
    | Or.inr (Or.inr hgt₂) => by
      have : 0 < a * b := Int.mul_pos_of_neg_of_neg hgt₁ hgt₂
      

Proof state:
a b : ℤ
h : a * b = 0
hgt₁ : a < 0
hgt₂ : b < 0
this : 0 < a * b
⊢ a = 0 ∨ b = 0

Next tactic:
rw [h] at this