l3lab/ntp-mathlib huggingface dataset:
theorem mod_add_div (m k : ℕ+) : (mod m k + k * div m k : ℕ) = m := by
  let h₀ := Nat.mod_add_div (m : ℕ) (k : ℕ)
  have : ¬((m : ℕ) % (k : ℕ) = 0 ∧ (m : ℕ) / (k : ℕ) = 0) := by
    

Proof state:
m k : ℕ+
h₀ : ↑m % ↑k + ↑k * (↑m / ↑k) = ↑m := Nat.mod_add_div ↑m ↑k
⊢ ¬(↑m % ↑k = 0 ∧ ↑m / ↑k = 0)

Next tactic:
rintro ⟨hr, hq⟩
theorem mod_add_div (m k : ℕ+) : (mod m k + k * div m k : ℕ) = m := by
  let h₀ := Nat.mod_add_div (m : ℕ) (k : ℕ)
  have : ¬((m : ℕ) % (k : ℕ) = 0 ∧ (m : ℕ) / (k : ℕ) = 0) := by
    rintro ⟨hr, hq⟩
    

Proof state:
case intro
m k : ℕ+
h₀ : ↑m % ↑k + ↑k * (↑m / ↑k) = ↑m := Nat.mod_add_div ↑m ↑k
hr : ↑m % ↑k = 0
hq : ↑m / ↑k = 0
⊢ False

Next tactic:
rw [hr, hq, mul_zero, zero_add] at h₀
theorem mod_add_div (m k : ℕ+) : (mod m k + k * div m k : ℕ) = m := by
  let h₀ := Nat.mod_add_div (m : ℕ) (k : ℕ)
  have : ¬((m : ℕ) % (k : ℕ) = 0 ∧ (m : ℕ) / (k : ℕ) = 0) := by
    rintro ⟨hr, hq⟩
    rw [hr, hq, mul_zero, zero_add] at h₀
    

Proof state:
case intro
m k : ℕ+
h₀ : 0 = ↑m
hr : ↑m % ↑k = 0
hq : ↑m / ↑k = 0
⊢ False

Next tactic:
exact (m.ne_zero h₀.symm).elim
theorem mod_add_div (m k : ℕ+) : (mod m k + k * div m k : ℕ) = m := by
  let h₀ := Nat.mod_add_div (m : ℕ) (k : ℕ)
  have : ¬((m : ℕ) % (k : ℕ) = 0 ∧ (m : ℕ) / (k : ℕ) = 0) := by
    rintro ⟨hr, hq⟩
    rw [hr, hq, mul_zero, zero_add] at h₀
    exact (m.ne_zero h₀.symm).elim
  

Proof state:
m k : ℕ+
h₀ : ↑m % ↑k + ↑k * (↑m / ↑k) = ↑m := Nat.mod_add_div ↑m ↑k
this : ¬(↑m % ↑k = 0 ∧ ↑m / ↑k = 0)
⊢ ↑(mod m k) + ↑k * div m k = ↑m

Next tactic:
have := modDivAux_spec k ((m : ℕ) % (k : ℕ)) ((m : ℕ) / (k : ℕ)) this
theorem mod_add_div (m k : ℕ+) : (mod m k + k * div m k : ℕ) = m := by
  let h₀ := Nat.mod_add_div (m : ℕ) (k : ℕ)
  have : ¬((m : ℕ) % (k : ℕ) = 0 ∧ (m : ℕ) / (k : ℕ) = 0) := by
    rintro ⟨hr, hq⟩
    rw [hr, hq, mul_zero, zero_add] at h₀
    exact (m.ne_zero h₀.symm).elim
  have := modDivAux_spec k ((m : ℕ) % (k : ℕ)) ((m : ℕ) / (k : ℕ)) this
  

Proof state:
m k : ℕ+
h₀ : ↑m % ↑k + ↑k * (↑m / ↑k) = ↑m := Nat.mod_add_div ↑m ↑k
this✝ : ¬(↑m % ↑k = 0 ∧ ↑m / ↑k = 0)
this : ↑(modDivAux k (↑m % ↑k) (↑m / ↑k)).1 + ↑k * (modDivAux k (↑m % ↑k) (↑m / ↑k)).2 = ↑m % ↑k + ↑k * (↑m / ↑k)
⊢ ↑(mod m k) + ↑k * div m k = ↑m

Next tactic:
exact this.trans h₀
theorem mod_add_div' (m k : ℕ+) : (mod m k + div m k * k : ℕ) = m := by
  

Proof state:
m k : ℕ+
⊢ ↑(mod m k) + div m k * ↑k = ↑m

Next tactic:
rw [mul_comm]
theorem mod_add_div' (m k : ℕ+) : (mod m k + div m k * k : ℕ) = m := by
  rw [mul_comm]
  

Proof state:
m k : ℕ+
⊢ ↑(mod m k) + ↑k * div m k = ↑m

Next tactic:
exact mod_add_div _ _
theorem div_add_mod' (m k : ℕ+) : (div m k * k + mod m k : ℕ) = m := by
  

Proof state:
m k : ℕ+
⊢ div m k * ↑k + ↑(mod m k) = ↑m

Next tactic:
rw [mul_comm]
theorem div_add_mod' (m k : ℕ+) : (div m k * k + mod m k : ℕ) = m := by
  rw [mul_comm]
  

Proof state:
m k : ℕ+
⊢ ↑k * div m k + ↑(mod m k) = ↑m

Next tactic:
exact div_add_mod _ _
theorem mod_le (m k : ℕ+) : mod m k ≤ m ∧ mod m k ≤ k := by
  

Proof state:
m k : ℕ+
⊢ mod m k ≤ m ∧ mod m k ≤ k

Next tactic:
change (mod m k : ℕ) ≤ (m : ℕ) ∧ (mod m k : ℕ) ≤ (k : ℕ)
theorem mod_le (m k : ℕ+) : mod m k ≤ m ∧ mod m k ≤ k := by
  change (mod m k : ℕ) ≤ (m : ℕ) ∧ (mod m k : ℕ) ≤ (k : ℕ)
  

Proof state:
m k : ℕ+
⊢ ↑(mod m k) ≤ ↑m ∧ ↑(mod m k) ≤ ↑k

Next tactic:
rw [mod_coe]
theorem mod_le (m k : ℕ+) : mod m k ≤ m ∧ mod m k ≤ k := by
  change (mod m k : ℕ) ≤ (m : ℕ) ∧ (mod m k : ℕ) ≤ (k : ℕ)
  rw [mod_coe]
  

Proof state:
m k : ℕ+
⊢ (if ↑m % ↑k = 0 then ↑k else ↑m % ↑k) ≤ ↑m ∧ (if ↑m % ↑k = 0 then ↑k else ↑m % ↑k) ≤ ↑k

Next tactic:
split_ifs with h
theorem mod_le (m k : ℕ+) : mod m k ≤ m ∧ mod m k ≤ k := by
  change (mod m k : ℕ) ≤ (m : ℕ) ∧ (mod m k : ℕ) ≤ (k : ℕ)
  rw [mod_coe]
  split_ifs with h
  · 

Proof state:
case pos
m k : ℕ+
h : ↑m % ↑k = 0
⊢ ↑k ≤ ↑m ∧ ↑k ≤ ↑k

Next tactic:
have hm : (m : ℕ) > 0 := m.pos
theorem mod_le (m k : ℕ+) : mod m k ≤ m ∧ mod m k ≤ k := by
  change (mod m k : ℕ) ≤ (m : ℕ) ∧ (mod m k : ℕ) ≤ (k : ℕ)
  rw [mod_coe]
  split_ifs with h
  · have hm : (m : ℕ) > 0 := m.pos
    

Proof state:
case pos
m k : ℕ+
h : ↑m % ↑k = 0
hm : ↑m > 0
⊢ ↑k ≤ ↑m ∧ ↑k ≤ ↑k

Next tactic:
rw [← Nat.mod_add_div (m : ℕ) (k : ℕ), h, zero_add] at hm ⊢
theorem mod_le (m k : ℕ+) : mod m k ≤ m ∧ mod m k ≤ k := by
  change (mod m k : ℕ) ≤ (m : ℕ) ∧ (mod m k : ℕ) ≤ (k : ℕ)
  rw [mod_coe]
  split_ifs with h
  · have hm : (m : ℕ) > 0 := m.pos
    rw [← Nat.mod_add_div (m : ℕ) (k : ℕ), h, zero_add] at hm ⊢
    

Proof state:
case pos
m k : ℕ+
h : ↑m % ↑k = 0
hm : ↑k * (↑m / ↑k) > 0
⊢ ↑k ≤ ↑k * (↑m / ↑k) ∧ ↑k ≤ ↑k

Next tactic:
by_cases h₁ : (m : ℕ) / (k : ℕ) = 0
theorem mod_le (m k : ℕ+) : mod m k ≤ m ∧ mod m k ≤ k := by
  change (mod m k : ℕ) ≤ (m : ℕ) ∧ (mod m k : ℕ) ≤ (k : ℕ)
  rw [mod_coe]
  split_ifs with h
  · have hm : (m : ℕ) > 0 := m.pos
    rw [← Nat.mod_add_div (m : ℕ) (k : ℕ), h, zero_add] at hm ⊢
    by_cases h₁ : (m : ℕ) / (k : ℕ) = 0
    · 

Proof state:
case pos
m k : ℕ+
h : ↑m % ↑k = 0
hm : ↑k * (↑m / ↑k) > 0
h₁ : ↑m / ↑k = 0
⊢ ↑k ≤ ↑k * (↑m / ↑k) ∧ ↑k ≤ ↑k

Next tactic:
rw [h₁, mul_zero] at hm
theorem mod_le (m k : ℕ+) : mod m k ≤ m ∧ mod m k ≤ k := by
  change (mod m k : ℕ) ≤ (m : ℕ) ∧ (mod m k : ℕ) ≤ (k : ℕ)
  rw [mod_coe]
  split_ifs with h
  · have hm : (m : ℕ) > 0 := m.pos
    rw [← Nat.mod_add_div (m : ℕ) (k : ℕ), h, zero_add] at hm ⊢
    by_cases h₁ : (m : ℕ) / (k : ℕ) = 0
    · rw [h₁, mul_zero] at hm
      

Proof state:
case pos
m k : ℕ+
h : ↑m % ↑k = 0
hm : 0 > 0
h₁ : ↑m / ↑k = 0
⊢ ↑k ≤ ↑k * (↑m / ↑k) ∧ ↑k ≤ ↑k

Next tactic:
exact (lt_irrefl _ hm).elim
theorem mod_le (m k : ℕ+) : mod m k ≤ m ∧ mod m k ≤ k := by
  change (mod m k : ℕ) ≤ (m : ℕ) ∧ (mod m k : ℕ) ≤ (k : ℕ)
  rw [mod_coe]
  split_ifs with h
  · have hm : (m : ℕ) > 0 := m.pos
    rw [← Nat.mod_add_div (m : ℕ) (k : ℕ), h, zero_add] at hm ⊢
    by_cases h₁ : (m : ℕ) / (k : ℕ) = 0
    · rw [h₁, mul_zero] at hm
      exact (lt_irrefl _ hm).elim
    · 

Proof state:
case neg
m k : ℕ+
h : ↑m % ↑k = 0
hm : ↑k * (↑m / ↑k) > 0
h₁ : ¬↑m / ↑k = 0
⊢ ↑k ≤ ↑k * (↑m / ↑k) ∧ ↑k ≤ ↑k

Next tactic:
let h₂ : (k : ℕ) * 1 ≤ k * (m / k) :=
        -- Porting note : Specified type of `h₂` explicitly because `rw` could not unify
        -- `succ 0` with `1`.
        Nat.mul_le_mul_left (k : ℕ) (Nat.succ_le_of_lt (Nat.pos_of_ne_zero h₁))
theorem mod_le (m k : ℕ+) : mod m k ≤ m ∧ mod m k ≤ k := by
  change (mod m k : ℕ) ≤ (m : ℕ) ∧ (mod m k : ℕ) ≤ (k : ℕ)
  rw [mod_coe]
  split_ifs with h
  · have hm : (m : ℕ) > 0 := m.pos
    rw [← Nat.mod_add_div (m : ℕ) (k : ℕ), h, zero_add] at hm ⊢
    by_cases h₁ : (m : ℕ) / (k : ℕ) = 0
    · rw [h₁, mul_zero] at hm
      exact (lt_irrefl _ hm).elim
    · let h₂ : (k : ℕ) * 1 ≤ k * (m / k) :=
        -- Porting note : Specified type of `h₂` explicitly because `rw` could not unify
        -- `succ 0` with `1`.
        Nat.mul_le_mul_left (k : ℕ) (Nat.succ_le_of_lt (Nat.pos_of_ne_zero h₁))
      

Proof state:
case neg
m k : ℕ+
h : ↑m % ↑k = 0
hm : ↑k * (↑m / ↑k) > 0
h₁ : ¬↑m / ↑k = 0
h₂ : ↑k * 1 ≤ ↑k * (↑m / ↑k) := Nat.mul_le_mul_left (↑k) (succ_le_of_lt (Nat.pos_of_ne_zero h₁))
⊢ ↑k ≤ ↑k * (↑m / ↑k) ∧ ↑k ≤ ↑k

Next tactic:
rw [mul_one] at h₂
theorem mod_le (m k : ℕ+) : mod m k ≤ m ∧ mod m k ≤ k := by
  change (mod m k : ℕ) ≤ (m : ℕ) ∧ (mod m k : ℕ) ≤ (k : ℕ)
  rw [mod_coe]
  split_ifs with h
  · have hm : (m : ℕ) > 0 := m.pos
    rw [← Nat.mod_add_div (m : ℕ) (k : ℕ), h, zero_add] at hm ⊢
    by_cases h₁ : (m : ℕ) / (k : ℕ) = 0
    · rw [h₁, mul_zero] at hm
      exact (lt_irrefl _ hm).elim
    · let h₂ : (k : ℕ) * 1 ≤ k * (m / k) :=
        -- Porting note : Specified type of `h₂` explicitly because `rw` could not unify
        -- `succ 0` with `1`.
        Nat.mul_le_mul_left (k : ℕ) (Nat.succ_le_of_lt (Nat.pos_of_ne_zero h₁))
      rw [mul_one] at h₂
      

Proof state:
case neg
m k : ℕ+
h : ↑m % ↑k = 0
hm : ↑k * (↑m / ↑k) > 0
h₁ : ¬↑m / ↑k = 0
h₂ : ↑k ≤ ↑k * (↑m / ↑k)
⊢ ↑k ≤ ↑k * (↑m / ↑k) ∧ ↑k ≤ ↑k

Next tactic:
exact ⟨h₂, le_refl (k : ℕ)⟩
theorem mod_le (m k : ℕ+) : mod m k ≤ m ∧ mod m k ≤ k := by
  change (mod m k : ℕ) ≤ (m : ℕ) ∧ (mod m k : ℕ) ≤ (k : ℕ)
  rw [mod_coe]
  split_ifs with h
  · have hm : (m : ℕ) > 0 := m.pos
    rw [← Nat.mod_add_div (m : ℕ) (k : ℕ), h, zero_add] at hm ⊢
    by_cases h₁ : (m : ℕ) / (k : ℕ) = 0
    · rw [h₁, mul_zero] at hm
      exact (lt_irrefl _ hm).elim
    · let h₂ : (k : ℕ) * 1 ≤ k * (m / k) :=
        -- Porting note : Specified type of `h₂` explicitly because `rw` could not unify
        -- `succ 0` with `1`.
        Nat.mul_le_mul_left (k : ℕ) (Nat.succ_le_of_lt (Nat.pos_of_ne_zero h₁))
      rw [mul_one] at h₂
      exact ⟨h₂, le_refl (k : ℕ)⟩
  · 

Proof state:
case neg
m k : ℕ+
h : ¬↑m % ↑k = 0
⊢ ↑m % ↑k ≤ ↑m ∧ ↑m % ↑k ≤ ↑k

Next tactic:
exact ⟨Nat.mod_le (m : ℕ) (k : ℕ), (Nat.mod_lt (m : ℕ) k.pos).le⟩
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by
  

Proof state:
k m : ℕ+
⊢ k ∣ m ↔ ↑k ∣ ↑m

Next tactic:
constructor
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by
  constructor <;> 

Proof state:
case mp
k m : ℕ+
⊢ k ∣ m → ↑k ∣ ↑m

Next tactic:
intro h
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by
  constructor <;> 

Proof state:
case mpr
k m : ℕ+
⊢ ↑k ∣ ↑m → k ∣ m

Next tactic:
intro h
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by
  constructor <;> intro h
  · 

Proof state:
case mp
k m : ℕ+
h : k ∣ m
⊢ ↑k ∣ ↑m

Next tactic:
rcases h with ⟨_, rfl⟩
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by
  constructor <;> intro h
  · rcases h with ⟨_, rfl⟩
    

Proof state:
case mp.intro
k w✝ : ℕ+
⊢ ↑k ∣ ↑(k * w✝)

Next tactic:
apply dvd_mul_right
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by
  constructor <;> intro h
  · rcases h with ⟨_, rfl⟩
    apply dvd_mul_right
  · 

Proof state:
case mpr
k m : ℕ+
h : ↑k ∣ ↑m
⊢ k ∣ m

Next tactic:
rcases h with ⟨a, h⟩
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by
  constructor <;> intro h
  · rcases h with ⟨_, rfl⟩
    apply dvd_mul_right
  · rcases h with ⟨a, h⟩
    

Proof state:
case mpr.intro
k m : ℕ+
a : ℕ
h : ↑m = ↑k * a
⊢ k ∣ m

Next tactic:
cases a with
    | zero =>
      contrapose h
      apply ne_zero
    | succ n =>
      use ⟨n.succ, n.succ_pos⟩
      rw [← coe_inj, h, mul_coe, mk_coe]
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by
  constructor <;> intro h
  · rcases h with ⟨_, rfl⟩
    apply dvd_mul_right
  · rcases h with ⟨a, h⟩
    cases a with
    

Proof state:
case mpr.intro.zero
k m : ℕ+
h : ↑m = ↑k * zero
⊢ k ∣ m

Next tactic:
| zero =>
      contrapose h
      apply ne_zero
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by
  constructor <;> intro h
  · rcases h with ⟨_, rfl⟩
    apply dvd_mul_right
  · rcases h with ⟨a, h⟩
    cases a with
    | zero =>
      

Proof state:
case mpr.intro.zero
k m : ℕ+
h : ↑m = ↑k * zero
⊢ k ∣ m

Next tactic:
contrapose h
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by
  constructor <;> intro h
  · rcases h with ⟨_, rfl⟩
    apply dvd_mul_right
  · rcases h with ⟨a, h⟩
    cases a with
    | zero =>
      contrapose h
      

Proof state:
case mpr.intro.zero
k m : ℕ+
h : ¬k ∣ m
⊢ ¬↑m = ↑k * zero

Next tactic:
apply ne_zero
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by
  constructor <;> intro h
  · rcases h with ⟨_, rfl⟩
    apply dvd_mul_right
  · rcases h with ⟨a, h⟩
    cases a with
    | zero =>
      contrapose h
      apply ne_zero
    

Proof state:
case mpr.intro.succ
k m : ℕ+
n : ℕ
h : ↑m = ↑k * succ n
⊢ k ∣ m

Next tactic:
| succ n =>
      use ⟨n.succ, n.succ_pos⟩
      rw [← coe_inj, h, mul_coe, mk_coe]
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by
  constructor <;> intro h
  · rcases h with ⟨_, rfl⟩
    apply dvd_mul_right
  · rcases h with ⟨a, h⟩
    cases a with
    | zero =>
      contrapose h
      apply ne_zero
    | succ n =>
      

Proof state:
case mpr.intro.succ
k m : ℕ+
n : ℕ
h : ↑m = ↑k * succ n
⊢ k ∣ m

Next tactic:
use ⟨n.succ, n.succ_pos⟩
theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by
  constructor <;> intro h
  · rcases h with ⟨_, rfl⟩
    apply dvd_mul_right
  · rcases h with ⟨a, h⟩
    cases a with
    | zero =>
      contrapose h
      apply ne_zero
    | succ n =>
      use ⟨n.succ, n.succ_pos⟩
      

Proof state:
case h
k m : ℕ+
n : ℕ
h : ↑m = ↑k * succ n
⊢ m = k * { val := succ n, property := (_ : 0 < succ n) }

Next tactic:
rw [← coe_inj, h, mul_coe, mk_coe]
theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by
  

Proof state:
k m : ℕ+
⊢ k ∣ m ↔ mod m k = k

Next tactic:
rw [dvd_iff]
theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by
  rw [dvd_iff]
  

Proof state:
k m : ℕ+
⊢ ↑k ∣ ↑m ↔ mod m k = k

Next tactic:
rw [Nat.dvd_iff_mod_eq_zero]
theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by
  rw [dvd_iff]
  rw [Nat.dvd_iff_mod_eq_zero]; 

Proof state:
k m : ℕ+
⊢ ↑m % ↑k = 0 ↔ mod m k = k

Next tactic:
constructor
theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by
  rw [dvd_iff]
  rw [Nat.dvd_iff_mod_eq_zero]; constructor
  · 

Proof state:
case mp
k m : ℕ+
⊢ ↑m % ↑k = 0 → mod m k = k

Next tactic:
intro h
theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by
  rw [dvd_iff]
  rw [Nat.dvd_iff_mod_eq_zero]; constructor
  · intro h
    

Proof state:
case mp
k m : ℕ+
h : ↑m % ↑k = 0
⊢ mod m k = k

Next tactic:
apply PNat.eq
theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by
  rw [dvd_iff]
  rw [Nat.dvd_iff_mod_eq_zero]; constructor
  · intro h
    apply PNat.eq
    

Proof state:
case mp.a
k m : ℕ+
h : ↑m % ↑k = 0
⊢ ↑(mod m k) = ↑k

Next tactic:
rw [mod_coe, if_pos h]
theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by
  rw [dvd_iff]
  rw [Nat.dvd_iff_mod_eq_zero]; constructor
  · intro h
    apply PNat.eq
    rw [mod_coe, if_pos h]
  · 

Proof state:
case mpr
k m : ℕ+
⊢ mod m k = k → ↑m % ↑k = 0

Next tactic:
intro h
theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by
  rw [dvd_iff]
  rw [Nat.dvd_iff_mod_eq_zero]; constructor
  · intro h
    apply PNat.eq
    rw [mod_coe, if_pos h]
  · intro h
    

Proof state:
case mpr
k m : ℕ+
h : mod m k = k
⊢ ↑m % ↑k = 0

Next tactic:
by_cases h' : (m : ℕ) % (k : ℕ) = 0
theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by
  rw [dvd_iff]
  rw [Nat.dvd_iff_mod_eq_zero]; constructor
  · intro h
    apply PNat.eq
    rw [mod_coe, if_pos h]
  · intro h
    by_cases h' : (m : ℕ) % (k : ℕ) = 0
    · 

Proof state:
case pos
k m : ℕ+
h : mod m k = k
h' : ↑m % ↑k = 0
⊢ ↑m % ↑k = 0

Next tactic:
exact h'
theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by
  rw [dvd_iff]
  rw [Nat.dvd_iff_mod_eq_zero]; constructor
  · intro h
    apply PNat.eq
    rw [mod_coe, if_pos h]
  · intro h
    by_cases h' : (m : ℕ) % (k : ℕ) = 0
    · exact h'
    · 

Proof state:
case neg
k m : ℕ+
h : mod m k = k
h' : ¬↑m % ↑k = 0
⊢ ↑m % ↑k = 0

Next tactic:
replace h : (mod m k : ℕ) = (k : ℕ) := congr_arg _ h
theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by
  rw [dvd_iff]
  rw [Nat.dvd_iff_mod_eq_zero]; constructor
  · intro h
    apply PNat.eq
    rw [mod_coe, if_pos h]
  · intro h
    by_cases h' : (m : ℕ) % (k : ℕ) = 0
    · exact h'
    · replace h : (mod m k : ℕ) = (k : ℕ) := congr_arg _ h
      

Proof state:
case neg
k m : ℕ+
h' : ¬↑m % ↑k = 0
h : ↑(mod m k) = ↑k
⊢ ↑m % ↑k = 0

Next tactic:
rw [mod_coe, if_neg h'] at h
theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by
  rw [dvd_iff]
  rw [Nat.dvd_iff_mod_eq_zero]; constructor
  · intro h
    apply PNat.eq
    rw [mod_coe, if_pos h]
  · intro h
    by_cases h' : (m : ℕ) % (k : ℕ) = 0
    · exact h'
    · replace h : (mod m k : ℕ) = (k : ℕ) := congr_arg _ h
      rw [mod_coe, if_neg h'] at h
      

Proof state:
case neg
k m : ℕ+
h' : ¬↑m % ↑k = 0
h : ↑m % ↑k = ↑k
⊢ ↑m % ↑k = 0

Next tactic:
exact ((Nat.mod_lt (m : ℕ) k.pos).ne h).elim
theorem le_of_dvd {m n : ℕ+} : m ∣ n → m ≤ n := by
  

Proof state:
m n : ℕ+
⊢ m ∣ n → m ≤ n

Next tactic:
rw [dvd_iff']
theorem le_of_dvd {m n : ℕ+} : m ∣ n → m ≤ n := by
  rw [dvd_iff']
  

Proof state:
m n : ℕ+
⊢ mod n m = m → m ≤ n

Next tactic:
intro h
theorem le_of_dvd {m n : ℕ+} : m ∣ n → m ≤ n := by
  rw [dvd_iff']
  intro h
  

Proof state:
m n : ℕ+
h : mod n m = m
⊢ m ≤ n

Next tactic:
rw [← h]
theorem le_of_dvd {m n : ℕ+} : m ∣ n → m ≤ n := by
  rw [dvd_iff']
  intro h
  rw [← h]
  

Proof state:
m n : ℕ+
h : mod n m = m
⊢ mod n m ≤ n

Next tactic:
apply (mod_le n m).left
theorem mul_div_exact {m k : ℕ+} (h : k ∣ m) : k * divExact m k = m := by
  

Proof state:
m k : ℕ+
h : k ∣ m
⊢ k * divExact m k = m

Next tactic:
apply PNat.eq
theorem mul_div_exact {m k : ℕ+} (h : k ∣ m) : k * divExact m k = m := by
  apply PNat.eq; 

Proof state:
case a
m k : ℕ+
h : k ∣ m
⊢ ↑(k * divExact m k) = ↑m

Next tactic:
rw [mul_coe]
theorem mul_div_exact {m k : ℕ+} (h : k ∣ m) : k * divExact m k = m := by
  apply PNat.eq; rw [mul_coe]
  

Proof state:
case a
m k : ℕ+
h : k ∣ m
⊢ ↑k * ↑(divExact m k) = ↑m

Next tactic:
change (k : ℕ) * (div m k).succ = m
theorem mul_div_exact {m k : ℕ+} (h : k ∣ m) : k * divExact m k = m := by
  apply PNat.eq; rw [mul_coe]
  change (k : ℕ) * (div m k).succ = m
  

Proof state:
case a
m k : ℕ+
h : k ∣ m
⊢ ↑k * succ (div m k) = ↑m

Next tactic:
rw [← div_add_mod m k, dvd_iff'.mp h, Nat.mul_succ]
theorem pos_of_div_pos {n : ℕ+} {a : ℕ} (h : a ∣ n) : 0 < a := by
  

Proof state:
n : ℕ+
a : ℕ
h : a ∣ ↑n
⊢ 0 < a

Next tactic:
apply pos_iff_ne_zero.2
theorem pos_of_div_pos {n : ℕ+} {a : ℕ} (h : a ∣ n) : 0 < a := by
  apply pos_iff_ne_zero.2
  

Proof state:
n : ℕ+
a : ℕ
h : a ∣ ↑n
⊢ a ≠ 0

Next tactic:
intro hzero
theorem pos_of_div_pos {n : ℕ+} {a : ℕ} (h : a ∣ n) : 0 < a := by
  apply pos_iff_ne_zero.2
  intro hzero
  

Proof state:
n : ℕ+
a : ℕ
h : a ∣ ↑n
hzero : a = 0
⊢ False

Next tactic:
rw [hzero] at h
theorem pos_of_div_pos {n : ℕ+} {a : ℕ} (h : a ∣ n) : 0 < a := by
  apply pos_iff_ne_zero.2
  intro hzero
  rw [hzero] at h
  

Proof state:
n : ℕ+
a : ℕ
h : 0 ∣ ↑n
hzero : a = 0
⊢ False

Next tactic:
exact PNat.ne_zero n (eq_zero_of_zero_dvd h)
@[simp]
theorem Bool.symmDiff_eq_xor : ∀ p q : Bool, p ∆ q = xor p q := by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
⊢ ∀ (p q : Bool), p ∆ q = xor p q

Next tactic:
decide
theorem symmDiff_comm : a ∆ b = b ∆ a := by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ a ∆ b = b ∆ a

Next tactic:
simp only [symmDiff, sup_comm]
@[simp]
theorem symmDiff_self : a ∆ a = ⊥ := by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ a ∆ a = ⊥

Next tactic:
rw [symmDiff, sup_idem, sdiff_self]
@[simp]
theorem symmDiff_bot : a ∆ ⊥ = a := by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ a ∆ ⊥ = a

Next tactic:
rw [symmDiff, sdiff_bot, bot_sdiff, sup_bot_eq]
@[simp]
theorem bot_symmDiff : ⊥ ∆ a = a := by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ ⊥ ∆ a = a

Next tactic:
rw [symmDiff_comm, symmDiff_bot]
@[simp]
theorem symmDiff_eq_bot {a b : α} : a ∆ b = ⊥ ↔ a = b := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a✝ b✝ c d a b : α
⊢ a ∆ b = ⊥ ↔ a = b

Next tactic:
simp_rw [symmDiff, sup_eq_bot_iff, sdiff_eq_bot_iff, le_antisymm_iff]
theorem symmDiff_of_le {a b : α} (h : a ≤ b) : a ∆ b = b \ a := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a✝ b✝ c d a b : α
h : a ≤ b
⊢ a ∆ b = b \ a

Next tactic:
rw [symmDiff, sdiff_eq_bot_iff.2 h, bot_sup_eq]
theorem symmDiff_of_ge {a b : α} (h : b ≤ a) : a ∆ b = a \ b := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a✝ b✝ c d a b : α
h : b ≤ a
⊢ a ∆ b = a \ b

Next tactic:
rw [symmDiff, sdiff_eq_bot_iff.2 h, sup_bot_eq]
theorem symmDiff_le_iff {a b c : α} : a ∆ b ≤ c ↔ a ≤ b ⊔ c ∧ b ≤ a ⊔ c := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a✝ b✝ c✝ d a b c : α
⊢ a ∆ b ≤ c ↔ a ≤ b ⊔ c ∧ b ≤ a ⊔ c

Next tactic:
simp_rw [symmDiff, sup_le_iff, sdiff_le_iff]
theorem symmDiff_eq_sup_sdiff_inf : a ∆ b = (a ⊔ b) \ (a ⊓ b) := by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ a ∆ b = (a ⊔ b) \ (a ⊓ b)

Next tactic:
simp [sup_sdiff, symmDiff]
theorem Disjoint.symmDiff_eq_sup {a b : α} (h : Disjoint a b) : a ∆ b = a ⊔ b := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a✝ b✝ c d a b : α
h : Disjoint a b
⊢ a ∆ b = a ⊔ b

Next tactic:
rw [symmDiff, h.sdiff_eq_left, h.sdiff_eq_right]
theorem symmDiff_sdiff : a ∆ b \ c = a \ (b ⊔ c) ⊔ b \ (a ⊔ c) := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ a ∆ b \ c = a \ (b ⊔ c) ⊔ b \ (a ⊔ c)

Next tactic:
rw [symmDiff, sup_sdiff_distrib, sdiff_sdiff_left, sdiff_sdiff_left]
@[simp]
theorem symmDiff_sdiff_inf : a ∆ b \ (a ⊓ b) = a ∆ b := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ a ∆ b \ (a ⊓ b) = a ∆ b

Next tactic:
rw [symmDiff_sdiff]
@[simp]
theorem symmDiff_sdiff_inf : a ∆ b \ (a ⊓ b) = a ∆ b := by
  rw [symmDiff_sdiff]
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ a \ (b ⊔ a ⊓ b) ⊔ b \ (a ⊔ a ⊓ b) = a ∆ b

Next tactic:
simp [symmDiff]
@[simp]
theorem symmDiff_sdiff_eq_sup : a ∆ (b \ a) = a ⊔ b := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ a ∆ (b \ a) = a ⊔ b

Next tactic:
rw [symmDiff, sdiff_idem]
@[simp]
theorem symmDiff_sdiff_eq_sup : a ∆ (b \ a) = a ⊔ b := by
  rw [symmDiff, sdiff_idem]
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ a \ (b \ a) ⊔ b \ a = a ⊔ b

Next tactic:
exact
    le_antisymm (sup_le_sup sdiff_le sdiff_le)
      (sup_le le_sdiff_sup <| le_sdiff_sup.trans <| sup_le le_sup_right le_sdiff_sup)
@[simp]
theorem sdiff_symmDiff_eq_sup : (a \ b) ∆ b = a ⊔ b := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ (a \ b) ∆ b = a ⊔ b

Next tactic:
rw [symmDiff_comm, symmDiff_sdiff_eq_sup, sup_comm]
@[simp]
theorem symmDiff_sup_inf : a ∆ b ⊔ a ⊓ b = a ⊔ b := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ a ∆ b ⊔ a ⊓ b = a ⊔ b

Next tactic:
refine' le_antisymm (sup_le symmDiff_le_sup inf_le_sup) _
@[simp]
theorem symmDiff_sup_inf : a ∆ b ⊔ a ⊓ b = a ⊔ b := by
  refine' le_antisymm (sup_le symmDiff_le_sup inf_le_sup) _
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ a ⊔ b ≤ a ∆ b ⊔ a ⊓ b

Next tactic:
rw [sup_inf_left, symmDiff]
@[simp]
theorem symmDiff_sup_inf : a ∆ b ⊔ a ⊓ b = a ⊔ b := by
  refine' le_antisymm (sup_le symmDiff_le_sup inf_le_sup) _
  rw [sup_inf_left, symmDiff]
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ a ⊔ b ≤ (a \ b ⊔ b \ a ⊔ a) ⊓ (a \ b ⊔ b \ a ⊔ b)

Next tactic:
refine' sup_le (le_inf le_sup_right _) (le_inf _ le_sup_right)
@[simp]
theorem symmDiff_sup_inf : a ∆ b ⊔ a ⊓ b = a ⊔ b := by
  refine' le_antisymm (sup_le symmDiff_le_sup inf_le_sup) _
  rw [sup_inf_left, symmDiff]
  refine' sup_le (le_inf le_sup_right _) (le_inf _ le_sup_right)
  · 

Proof state:
case refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
π : ι → Type u_4
inst✝ : GeneralizedCoheytingAlgebra α
a b c d : α
⊢ a ≤ a \ b ⊔ b \ a ⊔ b

Next tactic:
rw [sup_right_comm]