l3lab/ntp-mathlib huggingface dataset:
theorem map_ceil (f : F) (hf : StrictMono f) (a : α) : ⌈f a⌉₊ = ⌈a⌉₊ :=
  ceil_congr fun n => by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : LinearOrderedSemiring α
inst✝³ : LinearOrderedSemiring β
inst✝² : FloorSemiring α
inst✝¹ : FloorSemiring β
inst✝ : RingHomClass F α β
a✝ : α
b : β
f : F
hf : StrictMono ⇑f
a : α
n : ℕ
⊢ f a ≤ ↑n ↔ a ≤ ↑n

Next tactic:
rw [← map_natCast f, hf.le_iff_le]
theorem map_floor (f : F) (hf : StrictMono f) (a : α) : ⌊f a⌋ = ⌊a⌋ :=
  floor_congr fun n => by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : LinearOrderedRing α
inst✝³ : LinearOrderedRing β
inst✝² : FloorRing α
inst✝¹ : FloorRing β
inst✝ : RingHomClass F α β
a✝ : α
b : β
f : F
hf : StrictMono ⇑f
a : α
n : ℤ
⊢ ↑n ≤ f a ↔ ↑n ≤ a

Next tactic:
rw [← map_intCast f, hf.le_iff_le]
theorem map_ceil (f : F) (hf : StrictMono f) (a : α) : ⌈f a⌉ = ⌈a⌉ :=
  ceil_congr fun n => by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : LinearOrderedRing α
inst✝³ : LinearOrderedRing β
inst✝² : FloorRing α
inst✝¹ : FloorRing β
inst✝ : RingHomClass F α β
a✝ : α
b : β
f : F
hf : StrictMono ⇑f
a : α
n : ℤ
⊢ f a ≤ ↑n ↔ a ≤ ↑n

Next tactic:
rw [← map_intCast f, hf.le_iff_le]
theorem map_fract (f : F) (hf : StrictMono f) (a : α) : fract (f a) = f (fract a) := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : LinearOrderedRing α
inst✝³ : LinearOrderedRing β
inst✝² : FloorRing α
inst✝¹ : FloorRing β
inst✝ : RingHomClass F α β
a✝ : α
b : β
f : F
hf : StrictMono ⇑f
a : α
⊢ fract (f a) = f (fract a)

Next tactic:
simp_rw [fract, map_sub, map_intCast, map_floor _ hf]
theorem map_round (f : F) (hf : StrictMono f) (a : α) : round (f a) = round a := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : LinearOrderedField α
inst✝³ : LinearOrderedField β
inst✝² : FloorRing α
inst✝¹ : FloorRing β
inst✝ : RingHomClass F α β
a✝ : α
b : β
f : F
hf : StrictMono ⇑f
a : α
⊢ round (f a) = round a

Next tactic:
have H : f 2 = 2 := map_natCast f 2
theorem map_round (f : F) (hf : StrictMono f) (a : α) : round (f a) = round a := by
  have H : f 2 = 2 := map_natCast f 2
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : LinearOrderedField α
inst✝³ : LinearOrderedField β
inst✝² : FloorRing α
inst✝¹ : FloorRing β
inst✝ : RingHomClass F α β
a✝ : α
b : β
f : F
hf : StrictMono ⇑f
a : α
H : f 2 = 2
⊢ round (f a) = round a

Next tactic:
simp_rw [round_eq, ← map_floor _ hf, map_add, one_div, map_inv₀, H]
instance (priority := 100) FloorRing.toFloorSemiring : FloorSemiring α where
  floor a := ⌊a⌋.toNat
  ceil a := ⌈a⌉.toNat
  floor_of_neg {a} ha := Int.toNat_of_nonpos (Int.floor_nonpos ha.le)
  gc_floor {a n} ha := by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrderedRing α
inst✝ : FloorRing α
a : α
n : ℕ
ha : 0 ≤ a
⊢ n ≤ (fun a => toNat ⌊a⌋) a ↔ ↑n ≤ a

Next tactic:
rw [Int.le_toNat (Int.floor_nonneg.2 ha), Int.le_floor, Int.cast_ofNat]
instance (priority := 100) FloorRing.toFloorSemiring : FloorSemiring α where
  floor a := ⌊a⌋.toNat
  ceil a := ⌈a⌉.toNat
  floor_of_neg {a} ha := Int.toNat_of_nonpos (Int.floor_nonpos ha.le)
  gc_floor {a n} ha := by rw [Int.le_toNat (Int.floor_nonneg.2 ha), Int.le_floor, Int.cast_ofNat]
  gc_ceil a n := by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrderedRing α
inst✝ : FloorRing α
a : α
n : ℕ
⊢ (fun a => toNat ⌈a⌉) a ≤ n ↔ a ≤ ↑n

Next tactic:
rw [Int.toNat_le, Int.ceil_le, Int.cast_ofNat]
theorem Nat.cast_floor_eq_int_floor (ha : 0 ≤ a) : (⌊a⌋₊ : ℤ) = ⌊a⌋ := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrderedRing α
inst✝ : FloorRing α
a : α
ha : 0 ≤ a
⊢ ↑⌊a⌋₊ = ⌊a⌋

Next tactic:
rw [← Int.floor_toNat, Int.toNat_of_nonneg (Int.floor_nonneg.2 ha)]
theorem Nat.cast_floor_eq_cast_int_floor (ha : 0 ≤ a) : (⌊a⌋₊ : α) = ⌊a⌋ := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrderedRing α
inst✝ : FloorRing α
a : α
ha : 0 ≤ a
⊢ ↑⌊a⌋₊ = ↑⌊a⌋

Next tactic:
rw [← Nat.cast_floor_eq_int_floor ha, Int.cast_ofNat]
theorem Nat.cast_ceil_eq_int_ceil (ha : 0 ≤ a) : (⌈a⌉₊ : ℤ) = ⌈a⌉ := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrderedRing α
inst✝ : FloorRing α
a : α
ha : 0 ≤ a
⊢ ↑⌈a⌉₊ = ⌈a⌉

Next tactic:
rw [← Int.ceil_toNat, Int.toNat_of_nonneg (Int.ceil_nonneg ha)]
theorem Nat.cast_ceil_eq_cast_int_ceil (ha : 0 ≤ a) : (⌈a⌉₊ : α) = ⌈a⌉ := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrderedRing α
inst✝ : FloorRing α
a : α
ha : 0 ≤ a
⊢ ↑⌈a⌉₊ = ↑⌈a⌉

Next tactic:
rw [← Nat.cast_ceil_eq_int_ceil ha, Int.cast_ofNat]
/-- There exists at most one `FloorRing` structure on a given linear ordered ring. -/
theorem subsingleton_floorRing {α} [LinearOrderedRing α] : Subsingleton (FloorRing α) := by
  

Proof state:
F : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
inst✝ : LinearOrderedRing α
⊢ Subsingleton (FloorRing α)

Next tactic:
refine' ⟨fun H₁ H₂ => _⟩
/-- There exists at most one `FloorRing` structure on a given linear ordered ring. -/
theorem subsingleton_floorRing {α} [LinearOrderedRing α] : Subsingleton (FloorRing α) := by
  refine' ⟨fun H₁ H₂ => _⟩
  

Proof state:
F : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
inst✝ : LinearOrderedRing α
H₁ H₂ : FloorRing α
⊢ H₁ = H₂

Next tactic:
have : H₁.floor = H₂.floor :=
    funext fun a => (H₁.gc_coe_floor.u_unique H₂.gc_coe_floor) fun _ => rfl
/-- There exists at most one `FloorRing` structure on a given linear ordered ring. -/
theorem subsingleton_floorRing {α} [LinearOrderedRing α] : Subsingleton (FloorRing α) := by
  refine' ⟨fun H₁ H₂ => _⟩
  have : H₁.floor = H₂.floor :=
    funext fun a => (H₁.gc_coe_floor.u_unique H₂.gc_coe_floor) fun _ => rfl
  

Proof state:
F : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
inst✝ : LinearOrderedRing α
H₁ H₂ : FloorRing α
this : FloorRing.floor = FloorRing.floor
⊢ H₁ = H₂

Next tactic:
have : H₁.ceil = H₂.ceil := funext fun a => (H₁.gc_ceil_coe.l_unique H₂.gc_ceil_coe) fun _ => rfl
/-- There exists at most one `FloorRing` structure on a given linear ordered ring. -/
theorem subsingleton_floorRing {α} [LinearOrderedRing α] : Subsingleton (FloorRing α) := by
  refine' ⟨fun H₁ H₂ => _⟩
  have : H₁.floor = H₂.floor :=
    funext fun a => (H₁.gc_coe_floor.u_unique H₂.gc_coe_floor) fun _ => rfl
  have : H₁.ceil = H₂.ceil := funext fun a => (H₁.gc_ceil_coe.l_unique H₂.gc_ceil_coe) fun _ => rfl
  

Proof state:
F : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
inst✝ : LinearOrderedRing α
H₁ H₂ : FloorRing α
this✝ : FloorRing.floor = FloorRing.floor
this : FloorRing.ceil = FloorRing.ceil
⊢ H₁ = H₂

Next tactic:
cases H₁
/-- There exists at most one `FloorRing` structure on a given linear ordered ring. -/
theorem subsingleton_floorRing {α} [LinearOrderedRing α] : Subsingleton (FloorRing α) := by
  refine' ⟨fun H₁ H₂ => _⟩
  have : H₁.floor = H₂.floor :=
    funext fun a => (H₁.gc_coe_floor.u_unique H₂.gc_coe_floor) fun _ => rfl
  have : H₁.ceil = H₂.ceil := funext fun a => (H₁.gc_ceil_coe.l_unique H₂.gc_ceil_coe) fun _ => rfl
  cases H₁; 

Proof state:
case mk
F : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
inst✝ : LinearOrderedRing α
H₂ : FloorRing α
floor✝ ceil✝ : α → ℤ
gc_coe_floor✝ : GaloisConnection Int.cast floor✝
gc_ceil_coe✝ : GaloisConnection ceil✝ Int.cast
this✝ : FloorRing.floor = FloorRing.floor
this : FloorRing.ceil = FloorRing.ceil
⊢ { floor := floor✝, ceil := ceil✝, gc_coe_floor := gc_coe_floor✝, gc_ceil_coe := gc_ceil_coe✝ } = H₂

Next tactic:
cases H₂
/-- There exists at most one `FloorRing` structure on a given linear ordered ring. -/
theorem subsingleton_floorRing {α} [LinearOrderedRing α] : Subsingleton (FloorRing α) := by
  refine' ⟨fun H₁ H₂ => _⟩
  have : H₁.floor = H₂.floor :=
    funext fun a => (H₁.gc_coe_floor.u_unique H₂.gc_coe_floor) fun _ => rfl
  have : H₁.ceil = H₂.ceil := funext fun a => (H₁.gc_ceil_coe.l_unique H₂.gc_ceil_coe) fun _ => rfl
  cases H₁; cases H₂; 

Proof state:
case mk.mk
F : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
inst✝ : LinearOrderedRing α
floor✝¹ ceil✝¹ : α → ℤ
gc_coe_floor✝¹ : GaloisConnection Int.cast floor✝¹
gc_ceil_coe✝¹ : GaloisConnection ceil✝¹ Int.cast
floor✝ ceil✝ : α → ℤ
gc_coe_floor✝ : GaloisConnection Int.cast floor✝
gc_ceil_coe✝ : GaloisConnection ceil✝ Int.cast
this✝ : FloorRing.floor = FloorRing.floor
this : FloorRing.ceil = FloorRing.ceil
⊢ { floor := floor✝¹, ceil := ceil✝¹, gc_coe_floor := gc_coe_floor✝¹, gc_ceil_coe := gc_ceil_coe✝¹ } =
    { floor := floor✝, ceil := ceil✝, gc_coe_floor := gc_coe_floor✝, gc_ceil_coe := gc_ceil_coe✝ }

Next tactic:
congr
@[simp]
theorem coeff_modMonomial_of_not_le {s' s : σ →₀ ℕ} (x : MvPolynomial σ R) (h : ¬s ≤ s') :
    coeff s' (x %ᵐᵒⁿᵒᵐⁱᵃˡ s) = coeff s' x :=
  x.modOf_apply_of_not_exists_add s s'
    (by
      

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
s' s : σ →₀ ℕ
x : MvPolynomial σ R
h : ¬s ≤ s'
⊢ ¬∃ d, s' = s + d

Next tactic:
rintro ⟨d, rfl⟩
@[simp]
theorem coeff_modMonomial_of_not_le {s' s : σ →₀ ℕ} (x : MvPolynomial σ R) (h : ¬s ≤ s') :
    coeff s' (x %ᵐᵒⁿᵒᵐⁱᵃˡ s) = coeff s' x :=
  x.modOf_apply_of_not_exists_add s s'
    (by
      rintro ⟨d, rfl⟩
      

Proof state:
case intro
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
s : σ →₀ ℕ
x : MvPolynomial σ R
d : σ →₀ ℕ
h : ¬s ≤ s + d
⊢ False

Next tactic:
exact h le_self_add
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
⊢ (monomial i) r ∣ (monomial j) s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s

Next tactic:
constructor
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · 

Proof state:
case mp
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
⊢ (monomial i) r ∣ (monomial j) s → (s = 0 ∨ i ≤ j) ∧ r ∣ s

Next tactic:
rintro ⟨x, hx⟩
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    

Proof state:
case mp.intro
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
x : MvPolynomial σ R
hx : (monomial j) s = (monomial i) r * x
⊢ (s = 0 ∨ i ≤ j) ∧ r ∣ s

Next tactic:
rw [MvPolynomial.ext_iff] at hx
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    

Proof state:
case mp.intro
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
x : MvPolynomial σ R
hx : ∀ (m : σ →₀ ℕ), coeff m ((monomial j) s) = coeff m ((monomial i) r * x)
⊢ (s = 0 ∨ i ≤ j) ∧ r ∣ s

Next tactic:
have hj := hx j
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    have hj := hx j
    

Proof state:
case mp.intro
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
x : MvPolynomial σ R
hx : ∀ (m : σ →₀ ℕ), coeff m ((monomial j) s) = coeff m ((monomial i) r * x)
hj : coeff j ((monomial j) s) = coeff j ((monomial i) r * x)
⊢ (s = 0 ∨ i ≤ j) ∧ r ∣ s

Next tactic:
have hi := hx i
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    have hj := hx j
    have hi := hx i
    

Proof state:
case mp.intro
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
x : MvPolynomial σ R
hx : ∀ (m : σ →₀ ℕ), coeff m ((monomial j) s) = coeff m ((monomial i) r * x)
hj : coeff j ((monomial j) s) = coeff j ((monomial i) r * x)
hi : coeff i ((monomial j) s) = coeff i ((monomial i) r * x)
⊢ (s = 0 ∨ i ≤ j) ∧ r ∣ s

Next tactic:
classical
      simp_rw [coeff_monomial, if_pos] at hj hi
      simp_rw [coeff_monomial_mul'] at hi hj
      split_ifs at hi hj with hi hi
      · exact ⟨Or.inr hi, _, hj⟩
      · exact ⟨Or.inl hj, hj.symm ▸ dvd_zero _⟩
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    have hj := hx j
    have hi := hx i
    classical
      

Proof state:
case mp.intro
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
x : MvPolynomial σ R
hx : ∀ (m : σ →₀ ℕ), coeff m ((monomial j) s) = coeff m ((monomial i) r * x)
hj : coeff j ((monomial j) s) = coeff j ((monomial i) r * x)
hi : coeff i ((monomial j) s) = coeff i ((monomial i) r * x)
⊢ (s = 0 ∨ i ≤ j) ∧ r ∣ s

Next tactic:
simp_rw [coeff_monomial, if_pos] at hj hi
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    have hj := hx j
    have hi := hx i
    classical
      simp_rw [coeff_monomial, if_pos] at hj hi
      

Proof state:
case mp.intro
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
x : MvPolynomial σ R
hx : ∀ (m : σ →₀ ℕ), coeff m ((monomial j) s) = coeff m ((monomial i) r * x)
hi : (if j = i then s else 0) = coeff i ((monomial i) r * x)
hj : s = coeff j ((monomial i) r * x)
⊢ (s = 0 ∨ i ≤ j) ∧ r ∣ s

Next tactic:
simp_rw [coeff_monomial_mul'] at hi hj
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    have hj := hx j
    have hi := hx i
    classical
      simp_rw [coeff_monomial, if_pos] at hj hi
      simp_rw [coeff_monomial_mul'] at hi hj
      

Proof state:
case mp.intro
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
x : MvPolynomial σ R
hx : ∀ (m : σ →₀ ℕ), coeff m ((monomial j) s) = coeff m ((monomial i) r * x)
hi : (if j = i then s else 0) = if i ≤ i then r * coeff (i - i) x else 0
hj : s = if i ≤ j then r * coeff (j - i) x else 0
⊢ (s = 0 ∨ i ≤ j) ∧ r ∣ s

Next tactic:
split_ifs at hi hj with hi hi
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    have hj := hx j
    have hi := hx i
    classical
      simp_rw [coeff_monomial, if_pos] at hj hi
      simp_rw [coeff_monomial_mul'] at hi hj
      split_ifs at hi hj with hi hi
      · 

Proof state:
case pos
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
x : MvPolynomial σ R
hx : ∀ (m : σ →₀ ℕ), coeff m ((monomial j) s) = coeff m ((monomial i) r * x)
hi✝¹ : (if j = i then s else 0) = if i ≤ i then r * coeff (i - i) x else 0
hi✝ : j = i
hi : i ≤ j
hj : s = r * coeff (j - i) x
⊢ (s = 0 ∨ i ≤ j) ∧ r ∣ s

Next tactic:
exact ⟨Or.inr hi, _, hj⟩
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    have hj := hx j
    have hi := hx i
    classical
      simp_rw [coeff_monomial, if_pos] at hj hi
      simp_rw [coeff_monomial_mul'] at hi hj
      split_ifs at hi hj with hi hi
      · exact ⟨Or.inr hi, _, hj⟩
      · 

Proof state:
case neg
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
x : MvPolynomial σ R
hx : ∀ (m : σ →₀ ℕ), coeff m ((monomial j) s) = coeff m ((monomial i) r * x)
hi✝¹ : (if j = i then s else 0) = if i ≤ i then r * coeff (i - i) x else 0
hi✝ : j = i
hi : ¬i ≤ j
hj : s = 0
⊢ (s = 0 ∨ i ≤ j) ∧ r ∣ s

Next tactic:
exact ⟨Or.inl hj, hj.symm ▸ dvd_zero _⟩
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    have hj := hx j
    have hi := hx i
    classical
      simp_rw [coeff_monomial, if_pos] at hj hi
      simp_rw [coeff_monomial_mul'] at hi hj
      split_ifs at hi hj with hi hi
      · exact ⟨Or.inr hi, _, hj⟩
      · exact ⟨Or.inl hj, hj.symm ▸ dvd_zero _⟩
    -- Porting note: two goals remain at this point in Lean 4
    · 

Proof state:
case pos
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
x : MvPolynomial σ R
hx : ∀ (m : σ →₀ ℕ), coeff m ((monomial j) s) = coeff m ((monomial i) r * x)
hi✝ : (if j = i then s else 0) = if i ≤ i then r * coeff (i - i) x else 0
hi : ¬j = i
h✝ : i ≤ j
hj : s = r * coeff (j - i) x
⊢ (s = 0 ∨ i ≤ j) ∧ r ∣ s

Next tactic:
simp_all only [or_true, dvd_mul_right, and_self]
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    have hj := hx j
    have hi := hx i
    classical
      simp_rw [coeff_monomial, if_pos] at hj hi
      simp_rw [coeff_monomial_mul'] at hi hj
      split_ifs at hi hj with hi hi
      · exact ⟨Or.inr hi, _, hj⟩
      · exact ⟨Or.inl hj, hj.symm ▸ dvd_zero _⟩
    -- Porting note: two goals remain at this point in Lean 4
    · simp_all only [or_true, dvd_mul_right, and_self]
    · 

Proof state:
case neg
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
x : MvPolynomial σ R
hx : ∀ (m : σ →₀ ℕ), coeff m ((monomial j) s) = coeff m ((monomial i) r * x)
hi✝ : (if j = i then s else 0) = if i ≤ i then r * coeff (i - i) x else 0
hi : ¬j = i
h✝ : ¬i ≤ j
hj : s = 0
⊢ (s = 0 ∨ i ≤ j) ∧ r ∣ s

Next tactic:
simp_all only [ite_self, le_refl, ite_true, dvd_mul_right, or_false, and_self]
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    have hj := hx j
    have hi := hx i
    classical
      simp_rw [coeff_monomial, if_pos] at hj hi
      simp_rw [coeff_monomial_mul'] at hi hj
      split_ifs at hi hj with hi hi
      · exact ⟨Or.inr hi, _, hj⟩
      · exact ⟨Or.inl hj, hj.symm ▸ dvd_zero _⟩
    -- Porting note: two goals remain at this point in Lean 4
    · simp_all only [or_true, dvd_mul_right, and_self]
    · simp_all only [ite_self, le_refl, ite_true, dvd_mul_right, or_false, and_self]
  · 

Proof state:
case mpr
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r s : R
i j : σ →₀ ℕ
⊢ (s = 0 ∨ i ≤ j) ∧ r ∣ s → (monomial i) r ∣ (monomial j) s

Next tactic:
rintro ⟨h | hij, d, rfl⟩
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    have hj := hx j
    have hi := hx i
    classical
      simp_rw [coeff_monomial, if_pos] at hj hi
      simp_rw [coeff_monomial_mul'] at hi hj
      split_ifs at hi hj with hi hi
      · exact ⟨Or.inr hi, _, hj⟩
      · exact ⟨Or.inl hj, hj.symm ▸ dvd_zero _⟩
    -- Porting note: two goals remain at this point in Lean 4
    · simp_all only [or_true, dvd_mul_right, and_self]
    · simp_all only [ite_self, le_refl, ite_true, dvd_mul_right, or_false, and_self]
  · rintro ⟨h | hij, d, rfl⟩
    · 

Proof state:
case mpr.intro.inl.intro
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r : R
i j : σ →₀ ℕ
d : R
h : r * d = 0
⊢ (monomial i) r ∣ (monomial j) (r * d)

Next tactic:
simp_rw [h, monomial_zero, dvd_zero]
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    have hj := hx j
    have hi := hx i
    classical
      simp_rw [coeff_monomial, if_pos] at hj hi
      simp_rw [coeff_monomial_mul'] at hi hj
      split_ifs at hi hj with hi hi
      · exact ⟨Or.inr hi, _, hj⟩
      · exact ⟨Or.inl hj, hj.symm ▸ dvd_zero _⟩
    -- Porting note: two goals remain at this point in Lean 4
    · simp_all only [or_true, dvd_mul_right, and_self]
    · simp_all only [ite_self, le_refl, ite_true, dvd_mul_right, or_false, and_self]
  · rintro ⟨h | hij, d, rfl⟩
    · simp_rw [h, monomial_zero, dvd_zero]
    · 

Proof state:
case mpr.intro.inr.intro
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r : R
i j : σ →₀ ℕ
hij : i ≤ j
d : R
⊢ (monomial i) r ∣ (monomial j) (r * d)

Next tactic:
refine' ⟨monomial (j - i) d, _⟩
theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} :
    monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by
  constructor
  · rintro ⟨x, hx⟩
    rw [MvPolynomial.ext_iff] at hx
    have hj := hx j
    have hi := hx i
    classical
      simp_rw [coeff_monomial, if_pos] at hj hi
      simp_rw [coeff_monomial_mul'] at hi hj
      split_ifs at hi hj with hi hi
      · exact ⟨Or.inr hi, _, hj⟩
      · exact ⟨Or.inl hj, hj.symm ▸ dvd_zero _⟩
    -- Porting note: two goals remain at this point in Lean 4
    · simp_all only [or_true, dvd_mul_right, and_self]
    · simp_all only [ite_self, le_refl, ite_true, dvd_mul_right, or_false, and_self]
  · rintro ⟨h | hij, d, rfl⟩
    · simp_rw [h, monomial_zero, dvd_zero]
    · refine' ⟨monomial (j - i) d, _⟩
      

Proof state:
case mpr.intro.inr.intro
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
r : R
i j : σ →₀ ℕ
hij : i ≤ j
d : R
⊢ (monomial j) (r * d) = (monomial i) r * (monomial (j - i)) d

Next tactic:
rw [monomial_mul, add_tsub_cancel_of_le hij]
@[simp]
theorem monomial_one_dvd_monomial_one [Nontrivial R] {i j : σ →₀ ℕ} :
    monomial i (1 : R) ∣ monomial j 1 ↔ i ≤ j := by
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Nontrivial R
i j : σ →₀ ℕ
⊢ (monomial i) 1 ∣ (monomial j) 1 ↔ i ≤ j

Next tactic:
rw [monomial_dvd_monomial]
@[simp]
theorem monomial_one_dvd_monomial_one [Nontrivial R] {i j : σ →₀ ℕ} :
    monomial i (1 : R) ∣ monomial j 1 ↔ i ≤ j := by
  rw [monomial_dvd_monomial]
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Nontrivial R
i j : σ →₀ ℕ
⊢ (1 = 0 ∨ i ≤ j) ∧ 1 ∣ 1 ↔ i ≤ j

Next tactic:
simp_rw [one_ne_zero, false_or_iff, dvd_rfl, and_true_iff]
@[simp]
theorem X_dvd_X [Nontrivial R] {i j : σ} :
    (X i : MvPolynomial σ R) ∣ (X j : MvPolynomial σ R) ↔ i = j := by
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Nontrivial R
i j : σ
⊢ X i ∣ X j ↔ i = j

Next tactic:
refine' monomial_one_dvd_monomial_one.trans _
@[simp]
theorem X_dvd_X [Nontrivial R] {i j : σ} :
    (X i : MvPolynomial σ R) ∣ (X j : MvPolynomial σ R) ↔ i = j := by
  refine' monomial_one_dvd_monomial_one.trans _
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Nontrivial R
i j : σ
⊢ ((fun₀ | i => 1) ≤ fun₀ | j => 1) ↔ i = j

Next tactic:
simp_rw [Finsupp.single_le_iff, Nat.one_le_iff_ne_zero, Finsupp.single_apply_ne_zero,
    ne_eq, not_false_eq_true, and_true]
@[simp]
theorem X_dvd_monomial {i : σ} {j : σ →₀ ℕ} {r : R} :
    (X i : MvPolynomial σ R) ∣ monomial j r ↔ r = 0 ∨ j i ≠ 0 := by
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
i : σ
j : σ →₀ ℕ
r : R
⊢ X i ∣ (monomial j) r ↔ r = 0 ∨ j i ≠ 0

Next tactic:
refine' monomial_dvd_monomial.trans _
@[simp]
theorem X_dvd_monomial {i : σ} {j : σ →₀ ℕ} {r : R} :
    (X i : MvPolynomial σ R) ∣ monomial j r ↔ r = 0 ∨ j i ≠ 0 := by
  refine' monomial_dvd_monomial.trans _
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
i : σ
j : σ →₀ ℕ
r : R
⊢ (r = 0 ∨ (fun₀ | i => 1) ≤ j) ∧ 1 ∣ r ↔ r = 0 ∨ j i ≠ 0

Next tactic:
simp_rw [one_dvd, and_true_iff, Finsupp.single_le_iff, Nat.one_le_iff_ne_zero]
/-- For a topology generated by a basis, it suffices to check the sheaf condition on the basis
presieves only.
-/
theorem isSheaf_pretopology [HasPullbacks C] (K : Pretopology C) :
    IsSheaf (K.toGrothendieck C) P ↔ ∀ {X : C} (R : Presieve X), R ∈ K X → IsSheafFor P R := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
P : Cᵒᵖ ⥤ Type w
X : C
J J₂ : GrothendieckTopology C
inst✝ : HasPullbacks C
K : Pretopology C
⊢ IsSheaf (Pretopology.toGrothendieck C K) P ↔ ∀ {X : C}, ∀ R ∈ Pretopology.coverings K X, IsSheafFor P R

Next tactic:
constructor