l3lab/ntp-mathlib huggingface dataset:
/-- Abelian group structure on `Fin n`. -/
instance addCommGroup (n : ℕ) [NeZero n] : AddCommGroup (Fin n) :=
  { Fin.addCommMonoid n, Fin.neg n with
    add_left_neg := fun ⟨a, ha⟩ =>
      Fin.ext <|
        _root_.trans (Nat.mod_add_mod _ _ _) <| by
          rw [Fin.val_zero', tsub_add_cancel_of_le, Nat.mod_self]
          exact le_of_lt ha
    sub_eq_add_neg := fun ⟨a, ha⟩ ⟨b, hb⟩ =>
      Fin.ext <| show (a + (n - b)) % n = (a + (n - b) % n) % n by 

Proof state:
n✝ m n : ℕ
inst✝ : NeZero n
src✝¹ : AddCommMonoid (Fin n) := addCommMonoid n
src✝ : Neg (Fin n) := neg n
x✝¹ x✝ : Fin n
a : ℕ
ha : a < n
b : ℕ
hb : b < n
⊢ (a + (n - b)) % n = (a + (n - b) % n) % n

Next tactic:
simp
/-- Abelian group structure on `Fin n`. -/
instance addCommGroup (n : ℕ) [NeZero n] : AddCommGroup (Fin n) :=
  { Fin.addCommMonoid n, Fin.neg n with
    add_left_neg := fun ⟨a, ha⟩ =>
      Fin.ext <|
        _root_.trans (Nat.mod_add_mod _ _ _) <| by
          

Proof state:
n✝ m n : ℕ
inst✝ : NeZero n
src✝¹ : AddCommMonoid (Fin n) := addCommMonoid n
src✝ : Neg (Fin n) := neg n
x✝ : Fin n
a : ℕ
ha : a < n
⊢ (n - ↑{ val := a, isLt := ha } + a) % n = ↑0

Next tactic:
rw [Fin.val_zero', tsub_add_cancel_of_le, Nat.mod_self]
/-- Abelian group structure on `Fin n`. -/
instance addCommGroup (n : ℕ) [NeZero n] : AddCommGroup (Fin n) :=
  { Fin.addCommMonoid n, Fin.neg n with
    add_left_neg := fun ⟨a, ha⟩ =>
      Fin.ext <|
        _root_.trans (Nat.mod_add_mod _ _ _) <| by
          rw [Fin.val_zero', tsub_add_cancel_of_le, Nat.mod_self]
          

Proof state:
n✝ m n : ℕ
inst✝ : NeZero n
src✝¹ : AddCommMonoid (Fin n) := addCommMonoid n
src✝ : Neg (Fin n) := neg n
x✝ : Fin n
a : ℕ
ha : a < n
⊢ ↑{ val := a, isLt := ha } ≤ n

Next tactic:
exact le_of_lt ha
protected theorem coe_sub (a b : Fin n) : ((a - b : Fin n) : ℕ) = (a + (n - b)) % n := by
  

Proof state:
n m : ℕ
a b : Fin n
⊢ ↑(a - b) = (↑a + (n - ↑b)) % n

Next tactic:
cases a
protected theorem coe_sub (a b : Fin n) : ((a - b : Fin n) : ℕ) = (a + (n - b)) % n := by
  cases a; 

Proof state:
case mk
n m : ℕ
b : Fin n
val✝ : ℕ
isLt✝ : val✝ < n
⊢ ↑({ val := val✝, isLt := isLt✝ } - b) = (↑{ val := val✝, isLt := isLt✝ } + (n - ↑b)) % n

Next tactic:
cases b
protected theorem coe_sub (a b : Fin n) : ((a - b : Fin n) : ℕ) = (a + (n - b)) % n := by
  cases a; cases b; 

Proof state:
case mk.mk
n m val✝¹ : ℕ
isLt✝¹ : val✝¹ < n
val✝ : ℕ
isLt✝ : val✝ < n
⊢ ↑({ val := val✝¹, isLt := isLt✝¹ } - { val := val✝, isLt := isLt✝ }) =
    (↑{ val := val✝¹, isLt := isLt✝¹ } + (n - ↑{ val := val✝, isLt := isLt✝ })) % n

Next tactic:
rfl
@[simp]
theorem coe_fin_one (a : Fin 1) : (a : ℕ) = 0 := by 

Proof state:
n m : ℕ
a : Fin 1
⊢ ↑a = 0

Next tactic:
simp [Subsingleton.elim a 0]
lemma eq_one_of_neq_zero (i : Fin 2) (hi : i ≠ 0) : i = 1 :=
  fin_two_eq_of_eq_zero_iff (by 

Proof state:
n m : ℕ
i : Fin 2
hi : i ≠ 0
⊢ i = 0 ↔ 1 = 0

Next tactic:
simpa only [one_eq_zero_iff, succ.injEq, iff_false] using hi
@[simp]
theorem coe_neg_one : ↑(-1 : Fin (n + 1)) = n := by
  

Proof state:
n m : ℕ
⊢ ↑(-1) = n

Next tactic:
cases n
@[simp]
theorem coe_neg_one : ↑(-1 : Fin (n + 1)) = n := by
  cases n
  · 

Proof state:
case zero
m : ℕ
⊢ ↑(-1) = zero

Next tactic:
simp
@[simp]
theorem coe_neg_one : ↑(-1 : Fin (n + 1)) = n := by
  cases n
  · simp
  

Proof state:
case succ
m n✝ : ℕ
⊢ ↑(-1) = Nat.succ n✝

Next tactic:
rw [Fin.coe_neg, Fin.val_one, Nat.add_one_sub_one, Nat.mod_eq_of_lt]
@[simp]
theorem coe_neg_one : ↑(-1 : Fin (n + 1)) = n := by
  cases n
  · simp
  rw [Fin.coe_neg, Fin.val_one, Nat.add_one_sub_one, Nat.mod_eq_of_lt]
  

Proof state:
case succ
m n✝ : ℕ
⊢ n✝ + 1 < Nat.succ n✝ + 1

Next tactic:
constructor
theorem coe_sub_one {n} (a : Fin (n + 1)) : ↑(a - 1) = if a = 0 then n else a - 1 := by
  

Proof state:
n✝ m n : ℕ
a : Fin (n + 1)
⊢ ↑(a - 1) = if a = 0 then n else ↑a - 1

Next tactic:
cases n
theorem coe_sub_one {n} (a : Fin (n + 1)) : ↑(a - 1) = if a = 0 then n else a - 1 := by
  cases n
  · 

Proof state:
case zero
n m : ℕ
a : Fin (zero + 1)
⊢ ↑(a - 1) = if a = 0 then zero else ↑a - 1

Next tactic:
simp
theorem coe_sub_one {n} (a : Fin (n + 1)) : ↑(a - 1) = if a = 0 then n else a - 1 := by
  cases n
  · simp
  

Proof state:
case succ
n m n✝ : ℕ
a : Fin (Nat.succ n✝ + 1)
⊢ ↑(a - 1) = if a = 0 then Nat.succ n✝ else ↑a - 1

Next tactic:
split_ifs with h
theorem coe_sub_one {n} (a : Fin (n + 1)) : ↑(a - 1) = if a = 0 then n else a - 1 := by
  cases n
  · simp
  split_ifs with h
  · 

Proof state:
case pos
n m n✝ : ℕ
a : Fin (Nat.succ n✝ + 1)
h : a = 0
⊢ ↑(a - 1) = Nat.succ n✝

Next tactic:
simp [h]
theorem coe_sub_one {n} (a : Fin (n + 1)) : ↑(a - 1) = if a = 0 then n else a - 1 := by
  cases n
  · simp
  split_ifs with h
  · simp [h]
  

Proof state:
case neg
n m n✝ : ℕ
a : Fin (Nat.succ n✝ + 1)
h : ¬a = 0
⊢ ↑(a - 1) = ↑a - 1

Next tactic:
rw [sub_eq_add_neg, val_add_eq_ite, coe_neg_one, if_pos, add_comm, add_tsub_add_eq_tsub_left]
theorem coe_sub_one {n} (a : Fin (n + 1)) : ↑(a - 1) = if a = 0 then n else a - 1 := by
  cases n
  · simp
  split_ifs with h
  · simp [h]
  rw [sub_eq_add_neg, val_add_eq_ite, coe_neg_one, if_pos, add_comm, add_tsub_add_eq_tsub_left]
  

Proof state:
case neg.hc
n m n✝ : ℕ
a : Fin (Nat.succ n✝ + 1)
h : ¬a = 0
⊢ Nat.succ n✝ + 1 ≤ ↑a + (n✝ + 1)

Next tactic:
conv_rhs => rw [add_comm]
theorem coe_sub_one {n} (a : Fin (n + 1)) : ↑(a - 1) = if a = 0 then n else a - 1 := by
  cases n
  · simp
  split_ifs with h
  · simp [h]
  rw [sub_eq_add_neg, val_add_eq_ite, coe_neg_one, if_pos, add_comm, add_tsub_add_eq_tsub_left]
  conv_rhs => 

Proof state:
n m n✝ : ℕ
a : Fin (Nat.succ n✝ + 1)
h : ¬a = 0
| ↑a + (n✝ + 1)

Next tactic:
rw [add_comm]
theorem coe_sub_one {n} (a : Fin (n + 1)) : ↑(a - 1) = if a = 0 then n else a - 1 := by
  cases n
  · simp
  split_ifs with h
  · simp [h]
  rw [sub_eq_add_neg, val_add_eq_ite, coe_neg_one, if_pos, add_comm, add_tsub_add_eq_tsub_left]
  conv_rhs => rw [add_comm]
  

Proof state:
case neg.hc
n m n✝ : ℕ
a : Fin (Nat.succ n✝ + 1)
h : ¬a = 0
⊢ Nat.succ n✝ + 1 ≤ n✝ + 1 + ↑a

Next tactic:
rw [add_le_add_iff_left, Nat.one_le_iff_ne_zero]
theorem coe_sub_one {n} (a : Fin (n + 1)) : ↑(a - 1) = if a = 0 then n else a - 1 := by
  cases n
  · simp
  split_ifs with h
  · simp [h]
  rw [sub_eq_add_neg, val_add_eq_ite, coe_neg_one, if_pos, add_comm, add_tsub_add_eq_tsub_left]
  conv_rhs => rw [add_comm]
  rw [add_le_add_iff_left, Nat.one_le_iff_ne_zero]
  

Proof state:
case neg.hc
n m n✝ : ℕ
a : Fin (Nat.succ n✝ + 1)
h : ¬a = 0
⊢ ↑a ≠ 0

Next tactic:
rwa [Fin.ext_iff] at h
theorem coe_sub_iff_le {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = a - b ↔ b ≤ a := by
  

Proof state:
n✝ m n : ℕ
a b : Fin n
⊢ ↑(a - b) = ↑a - ↑b ↔ b ≤ a

Next tactic:
cases n
theorem coe_sub_iff_le {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = a - b ↔ b ≤ a := by
  cases n; · 

Proof state:
case zero
n m : ℕ
a b : Fin zero
⊢ ↑(a - b) = ↑a - ↑b ↔ b ≤ a

Next tactic:
exact @finZeroElim (fun _ => _) a
theorem coe_sub_iff_le {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = a - b ↔ b ≤ a := by
  cases n; · exact @finZeroElim (fun _ => _) a
  

Proof state:
case succ
n m n✝ : ℕ
a b : Fin (Nat.succ n✝)
⊢ ↑(a - b) = ↑a - ↑b ↔ b ≤ a

Next tactic:
rw [le_iff_val_le_val, Fin.coe_sub, ← add_tsub_assoc_of_le b.is_lt.le a]
theorem coe_sub_iff_le {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = a - b ↔ b ≤ a := by
  cases n; · exact @finZeroElim (fun _ => _) a
  rw [le_iff_val_le_val, Fin.coe_sub, ← add_tsub_assoc_of_le b.is_lt.le a]
  

Proof state:
case succ
n m n✝ : ℕ
a b : Fin (Nat.succ n✝)
⊢ (↑a + Nat.succ n✝ - ↑b) % Nat.succ n✝ = ↑a - ↑b ↔ ↑b ≤ ↑a

Next tactic:
rcases le_or_lt (b : ℕ) a with h | h
theorem coe_sub_iff_le {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = a - b ↔ b ≤ a := by
  cases n; · exact @finZeroElim (fun _ => _) a
  rw [le_iff_val_le_val, Fin.coe_sub, ← add_tsub_assoc_of_le b.is_lt.le a]
  rcases le_or_lt (b : ℕ) a with h | h
  · 

Proof state:
case succ.inl
n m n✝ : ℕ
a b : Fin (Nat.succ n✝)
h : ↑b ≤ ↑a
⊢ (↑a + Nat.succ n✝ - ↑b) % Nat.succ n✝ = ↑a - ↑b ↔ ↑b ≤ ↑a

Next tactic:
simp [← tsub_add_eq_add_tsub h, val_fin_le.mp h,
      Nat.mod_eq_of_lt ((Nat.sub_le _ _).trans_lt a.is_lt)]
theorem coe_sub_iff_le {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = a - b ↔ b ≤ a := by
  cases n; · exact @finZeroElim (fun _ => _) a
  rw [le_iff_val_le_val, Fin.coe_sub, ← add_tsub_assoc_of_le b.is_lt.le a]
  rcases le_or_lt (b : ℕ) a with h | h
  · simp [← tsub_add_eq_add_tsub h, val_fin_le.mp h,
      Nat.mod_eq_of_lt ((Nat.sub_le _ _).trans_lt a.is_lt)]
  · 

Proof state:
case succ.inr
n m n✝ : ℕ
a b : Fin (Nat.succ n✝)
h : ↑a < ↑b
⊢ (↑a + Nat.succ n✝ - ↑b) % Nat.succ n✝ = ↑a - ↑b ↔ ↑b ≤ ↑a

Next tactic:
rw [Nat.mod_eq_of_lt, tsub_eq_zero_of_le h.le, tsub_eq_zero_iff_le, ← not_iff_not]
theorem coe_sub_iff_le {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = a - b ↔ b ≤ a := by
  cases n; · exact @finZeroElim (fun _ => _) a
  rw [le_iff_val_le_val, Fin.coe_sub, ← add_tsub_assoc_of_le b.is_lt.le a]
  rcases le_or_lt (b : ℕ) a with h | h
  · simp [← tsub_add_eq_add_tsub h, val_fin_le.mp h,
      Nat.mod_eq_of_lt ((Nat.sub_le _ _).trans_lt a.is_lt)]
  · rw [Nat.mod_eq_of_lt, tsub_eq_zero_of_le h.le, tsub_eq_zero_iff_le, ← not_iff_not]
    · 

Proof state:
case succ.inr
n m n✝ : ℕ
a b : Fin (Nat.succ n✝)
h : ↑a < ↑b
⊢ ¬↑a + Nat.succ n✝ ≤ ↑b ↔ ¬↑b ≤ ↑a

Next tactic:
simpa [b.is_lt.trans_le le_add_self] using h
theorem coe_sub_iff_le {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = a - b ↔ b ≤ a := by
  cases n; · exact @finZeroElim (fun _ => _) a
  rw [le_iff_val_le_val, Fin.coe_sub, ← add_tsub_assoc_of_le b.is_lt.le a]
  rcases le_or_lt (b : ℕ) a with h | h
  · simp [← tsub_add_eq_add_tsub h, val_fin_le.mp h,
      Nat.mod_eq_of_lt ((Nat.sub_le _ _).trans_lt a.is_lt)]
  · rw [Nat.mod_eq_of_lt, tsub_eq_zero_of_le h.le, tsub_eq_zero_iff_le, ← not_iff_not]
    · simpa [b.is_lt.trans_le le_add_self] using h
    · 

Proof state:
case succ.inr
n m n✝ : ℕ
a b : Fin (Nat.succ n✝)
h : ↑a < ↑b
⊢ ↑a + Nat.succ n✝ - ↑b < Nat.succ n✝

Next tactic:
rwa [tsub_lt_iff_left (b.is_lt.le.trans le_add_self), add_lt_add_iff_right]
theorem coe_sub_iff_lt {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = n + a - b ↔ a < b := by
  

Proof state:
n✝ m n : ℕ
a b : Fin n
⊢ ↑(a - b) = n + ↑a - ↑b ↔ a < b

Next tactic:
cases' n with n
theorem coe_sub_iff_lt {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = n + a - b ↔ a < b := by
  cases' n with n
  · 

Proof state:
case zero
n m : ℕ
a b : Fin zero
⊢ ↑(a - b) = zero + ↑a - ↑b ↔ a < b

Next tactic:
exact @finZeroElim (fun _ => _) a
theorem coe_sub_iff_lt {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = n + a - b ↔ a < b := by
  cases' n with n
  · exact @finZeroElim (fun _ => _) a
  

Proof state:
case succ
n✝ m n : ℕ
a b : Fin (Nat.succ n)
⊢ ↑(a - b) = Nat.succ n + ↑a - ↑b ↔ a < b

Next tactic:
rw [lt_iff_val_lt_val, Fin.coe_sub, add_comm]
theorem coe_sub_iff_lt {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = n + a - b ↔ a < b := by
  cases' n with n
  · exact @finZeroElim (fun _ => _) a
  rw [lt_iff_val_lt_val, Fin.coe_sub, add_comm]
  

Proof state:
case succ
n✝ m n : ℕ
a b : Fin (Nat.succ n)
⊢ (Nat.succ n - ↑b + ↑a) % Nat.succ n = Nat.succ n + ↑a - ↑b ↔ ↑a < ↑b

Next tactic:
rcases le_or_lt (b : ℕ) a with h | h
theorem coe_sub_iff_lt {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = n + a - b ↔ a < b := by
  cases' n with n
  · exact @finZeroElim (fun _ => _) a
  rw [lt_iff_val_lt_val, Fin.coe_sub, add_comm]
  rcases le_or_lt (b : ℕ) a with h | h
  · 

Proof state:
case succ.inl
n✝ m n : ℕ
a b : Fin (Nat.succ n)
h : ↑b ≤ ↑a
⊢ (Nat.succ n - ↑b + ↑a) % Nat.succ n = Nat.succ n + ↑a - ↑b ↔ ↑a < ↑b

Next tactic:
refine iff_of_false ?_ (not_lt_of_le h)
theorem coe_sub_iff_lt {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = n + a - b ↔ a < b := by
  cases' n with n
  · exact @finZeroElim (fun _ => _) a
  rw [lt_iff_val_lt_val, Fin.coe_sub, add_comm]
  rcases le_or_lt (b : ℕ) a with h | h
  · refine iff_of_false ?_ (not_lt_of_le h)
    

Proof state:
case succ.inl
n✝ m n : ℕ
a b : Fin (Nat.succ n)
h : ↑b ≤ ↑a
⊢ ¬(Nat.succ n - ↑b + ↑a) % Nat.succ n = Nat.succ n + ↑a - ↑b

Next tactic:
simpa [add_tsub_assoc_of_le h] using
      ((Nat.mod_lt _ (Nat.succ_pos _)).trans_le le_self_add).ne
theorem coe_sub_iff_lt {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = n + a - b ↔ a < b := by
  cases' n with n
  · exact @finZeroElim (fun _ => _) a
  rw [lt_iff_val_lt_val, Fin.coe_sub, add_comm]
  rcases le_or_lt (b : ℕ) a with h | h
  · refine iff_of_false ?_ (not_lt_of_le h)
    simpa [add_tsub_assoc_of_le h] using
      ((Nat.mod_lt _ (Nat.succ_pos _)).trans_le le_self_add).ne
  · 

Proof state:
case succ.inr
n✝ m n : ℕ
a b : Fin (Nat.succ n)
h : ↑a < ↑b
⊢ (Nat.succ n - ↑b + ↑a) % Nat.succ n = Nat.succ n + ↑a - ↑b ↔ ↑a < ↑b

Next tactic:
simp [← tsub_tsub_assoc b.is_lt.le h.le, ← tsub_add_eq_add_tsub b.is_lt.le,
      Nat.mod_eq_of_lt (tsub_lt_self (Nat.succ_pos _) (tsub_pos_of_lt h)), val_fin_le.mp _]
theorem coe_sub_iff_lt {n : ℕ} {a b : Fin n} : (↑(a - b) : ℕ) = n + a - b ↔ a < b := by
  cases' n with n
  · exact @finZeroElim (fun _ => _) a
  rw [lt_iff_val_lt_val, Fin.coe_sub, add_comm]
  rcases le_or_lt (b : ℕ) a with h | h
  · refine iff_of_false ?_ (not_lt_of_le h)
    simpa [add_tsub_assoc_of_le h] using
      ((Nat.mod_lt _ (Nat.succ_pos _)).trans_le le_self_add).ne
  · simp [← tsub_tsub_assoc b.is_lt.le h.le, ← tsub_add_eq_add_tsub b.is_lt.le,
      Nat.mod_eq_of_lt (tsub_lt_self (Nat.succ_pos _) (tsub_pos_of_lt h)), val_fin_le.mp _]
    

Proof state:
case succ.inr
n✝ m n : ℕ
a b : Fin (Nat.succ n)
h : ↑a < ↑b
⊢ a < b

Next tactic:
exact h
@[simp]
theorem lt_sub_one_iff {n : ℕ} {k : Fin (n + 2)} : k < k - 1 ↔ k = 0 := by
  

Proof state:
n✝ m n : ℕ
k : Fin (n + 2)
⊢ k < k - 1 ↔ k = 0

Next tactic:
rcases k with ⟨_ | k, hk⟩
@[simp]
theorem lt_sub_one_iff {n : ℕ} {k : Fin (n + 2)} : k < k - 1 ↔ k = 0 := by
  rcases k with ⟨_ | k, hk⟩
  

Proof state:
case mk.zero
n✝ m n : ℕ
hk : zero < n + 2
⊢ { val := zero, isLt := hk } < { val := zero, isLt := hk } - 1 ↔ { val := zero, isLt := hk } = 0
case mk.succ
n✝ m n k : ℕ
hk : Nat.succ k < n + 2
⊢ { val := Nat.succ k, isLt := hk } < { val := Nat.succ k, isLt := hk } - 1 ↔ { val := Nat.succ k, isLt := hk } = 0

Next tactic:
simp only [zero_eq, zero_eta, zero_sub, lt_iff_val_lt_val, val_zero, coe_neg_one, add_pos_iff,
    _root_.zero_lt_one, or_true]
@[simp]
theorem lt_sub_one_iff {n : ℕ} {k : Fin (n + 2)} : k < k - 1 ↔ k = 0 := by
  rcases k with ⟨_ | k, hk⟩
  simp only [zero_eq, zero_eta, zero_sub, lt_iff_val_lt_val, val_zero, coe_neg_one, add_pos_iff,
    _root_.zero_lt_one, or_true]
  

Proof state:
case mk.succ
n✝ m n k : ℕ
hk : Nat.succ k < n + 2
⊢ { val := Nat.succ k, isLt := hk } < { val := Nat.succ k, isLt := hk } - 1 ↔ { val := Nat.succ k, isLt := hk } = 0

Next tactic:
have : (k + 1 + (n + 1)) % (n + 2) = k % (n + 2) := by
    rw [add_right_comm, add_assoc, add_mod_right]
@[simp]
theorem lt_sub_one_iff {n : ℕ} {k : Fin (n + 2)} : k < k - 1 ↔ k = 0 := by
  rcases k with ⟨_ | k, hk⟩
  simp only [zero_eq, zero_eta, zero_sub, lt_iff_val_lt_val, val_zero, coe_neg_one, add_pos_iff,
    _root_.zero_lt_one, or_true]
  have : (k + 1 + (n + 1)) % (n + 2) = k % (n + 2) := by
    

Proof state:
n✝ m n k : ℕ
hk : Nat.succ k < n + 2
⊢ (k + 1 + (n + 1)) % (n + 2) = k % (n + 2)

Next tactic:
rw [add_right_comm, add_assoc, add_mod_right]
@[simp]
theorem lt_sub_one_iff {n : ℕ} {k : Fin (n + 2)} : k < k - 1 ↔ k = 0 := by
  rcases k with ⟨_ | k, hk⟩
  simp only [zero_eq, zero_eta, zero_sub, lt_iff_val_lt_val, val_zero, coe_neg_one, add_pos_iff,
    _root_.zero_lt_one, or_true]
  have : (k + 1 + (n + 1)) % (n + 2) = k % (n + 2) := by
    rw [add_right_comm, add_assoc, add_mod_right]
  

Proof state:
case mk.succ
n✝ m n k : ℕ
hk : Nat.succ k < n + 2
this : (k + 1 + (n + 1)) % (n + 2) = k % (n + 2)
⊢ { val := Nat.succ k, isLt := hk } < { val := Nat.succ k, isLt := hk } - 1 ↔ { val := Nat.succ k, isLt := hk } = 0

Next tactic:
simp [lt_iff_val_lt_val, ext_iff, Fin.coe_sub, succ_eq_add_one, this,
    mod_eq_of_lt ((lt_succ_self _).trans hk)]
@[simp]
theorem le_sub_one_iff {n : ℕ} {k : Fin (n + 1)} : k ≤ k - 1 ↔ k = 0 := by
  

Proof state:
n✝ m n : ℕ
k : Fin (n + 1)
⊢ k ≤ k - 1 ↔ k = 0

Next tactic:
cases n
@[simp]
theorem le_sub_one_iff {n : ℕ} {k : Fin (n + 1)} : k ≤ k - 1 ↔ k = 0 := by
  cases n
  · 

Proof state:
case zero
n m : ℕ
k : Fin (zero + 1)
⊢ k ≤ k - 1 ↔ k = 0

Next tactic:
simp [fin_one_eq_zero k]
@[simp]
theorem le_sub_one_iff {n : ℕ} {k : Fin (n + 1)} : k ≤ k - 1 ↔ k = 0 := by
  cases n
  · simp [fin_one_eq_zero k]
  

Proof state:
case succ
n m n✝ : ℕ
k : Fin (Nat.succ n✝ + 1)
⊢ k ≤ k - 1 ↔ k = 0

Next tactic:
rw [← lt_sub_one_iff, le_iff_lt_or_eq, lt_sub_one_iff, or_iff_left_iff_imp, eq_comm,
    sub_eq_iff_eq_add]
@[simp]
theorem le_sub_one_iff {n : ℕ} {k : Fin (n + 1)} : k ≤ k - 1 ↔ k = 0 := by
  cases n
  · simp [fin_one_eq_zero k]
  rw [← lt_sub_one_iff, le_iff_lt_or_eq, lt_sub_one_iff, or_iff_left_iff_imp, eq_comm,
    sub_eq_iff_eq_add]
  

Proof state:
case succ
n m n✝ : ℕ
k : Fin (Nat.succ n✝ + 1)
⊢ k = k + 1 → k = 0

Next tactic:
simp
@[simp]
theorem sub_one_lt_iff {n : ℕ} {k : Fin (n + 1)} : k - 1 < k ↔ 0 < k :=
  not_iff_not.1 <| by 

Proof state:
n✝ m n : ℕ
k : Fin (n + 1)
⊢ ¬k - 1 < k ↔ ¬0 < k

Next tactic:
simp only [not_lt, le_sub_one_iff, le_zero_iff]
theorem last_sub (i : Fin (n + 1)) : last n - i = Fin.rev i :=
  ext <| by 

Proof state:
n m : ℕ
i : Fin (n + 1)
⊢ ↑(last n - i) = ↑(rev i)

Next tactic:
rw [coe_sub_iff_le.2 i.le_last, val_last, val_rev, Nat.succ_sub_succ_eq_sub]
@[simp]
theorem succAbove_ne_zero_zero [NeZero n] {a : Fin (n + 1)} (ha : a ≠ 0) : a.succAbove 0 = 0 := by
  

Proof state:
n m : ℕ
inst✝ : NeZero n
a : Fin (n + 1)
ha : a ≠ 0
⊢ succAbove a 0 = 0

Next tactic:
rw [Fin.succAbove_below]
@[simp]
theorem succAbove_ne_zero_zero [NeZero n] {a : Fin (n + 1)} (ha : a ≠ 0) : a.succAbove 0 = 0 := by
  rw [Fin.succAbove_below]
  · 

Proof state:
n m : ℕ
inst✝ : NeZero n
a : Fin (n + 1)
ha : a ≠ 0
⊢ castSucc 0 = 0

Next tactic:
simp
@[simp]
theorem succAbove_ne_zero_zero [NeZero n] {a : Fin (n + 1)} (ha : a ≠ 0) : a.succAbove 0 = 0 := by
  rw [Fin.succAbove_below]
  · simp
  · 

Proof state:
case h
n m : ℕ
inst✝ : NeZero n
a : Fin (n + 1)
ha : a ≠ 0
⊢ castSucc 0 < a

Next tactic:
exact bot_lt_iff_ne_bot.mpr ha
theorem succAbove_eq_zero_iff [NeZero n] {a : Fin (n + 1)} {b : Fin n} (ha : a ≠ 0) :
    a.succAbove b = 0 ↔ b = 0 := by
  

Proof state:
n m : ℕ
inst✝ : NeZero n
a : Fin (n + 1)
b : Fin n
ha : a ≠ 0
⊢ succAbove a b = 0 ↔ b = 0

Next tactic:
simp only [← succAbove_ne_zero_zero ha, ← succAboveEmb_apply, OrderEmbedding.eq_iff_eq, iff_self]
/-- Embedding `Fin n` into `Fin (n + 1)` with a hole around `last n` embeds by `castSucc`. -/
@[simp]
theorem succAbove_last : succAbove (Fin.last n) = castSucc := by
  

Proof state:
n m : ℕ
⊢ succAbove (last n) = castSucc

Next tactic:
ext
/-- Embedding `Fin n` into `Fin (n + 1)` with a hole around `last n` embeds by `castSucc`. -/
@[simp]
theorem succAbove_last : succAbove (Fin.last n) = castSucc := by
  ext
  

Proof state:
case h.h
n m : ℕ
x✝ : Fin n
⊢ ↑(succAbove (last n) x✝) = ↑(castSucc x✝)

Next tactic:
simp only [succAbove_below, castSucc_lt_last]
theorem succAbove_last_apply (i : Fin n) : succAbove (Fin.last n) i = castSucc i := by
  

Proof state:
n m : ℕ
i : Fin n
⊢ succAbove (last n) i = castSucc i

Next tactic:
rw [succAbove_last]
/-- Embedding `i : Fin n` into `Fin (n + 1)` with a hole around `p : Fin (n + 1)`
embeds `i` by `succ` when the resulting `p < i.succ`. -/
theorem succAbove_above (p : Fin (n + 1)) (i : Fin n) (h : p ≤ castSucc i) :
    p.succAbove i = i.succ := by 

Proof state:
n m : ℕ
p : Fin (n + 1)
i : Fin n
h : p ≤ castSucc i
⊢ succAbove p i = succ i

Next tactic:
simp [le_iff_val_le_val] at h
/-- Embedding `i : Fin n` into `Fin (n + 1)` with a hole around `p : Fin (n + 1)`
embeds `i` by `succ` when the resulting `p < i.succ`. -/
theorem succAbove_above (p : Fin (n + 1)) (i : Fin n) (h : p ≤ castSucc i) :
    p.succAbove i = i.succ := by simp [le_iff_val_le_val] at h; 

Proof state:
n m : ℕ
p : Fin (n + 1)
i : Fin n
h : ↑p ≤ ↑i
⊢ succAbove p i = succ i

Next tactic:
simp [succAbove, h.not_lt]
/-- Embedding `i : Fin n` into `Fin (n + 1)` using a pivot `p` that is greater
results in a value that is less than `p`. -/
@[simp]
theorem succAbove_lt_iff (p : Fin (n + 1)) (i : Fin n) : p.succAbove i < p ↔ castSucc i < p := by
  

Proof state:
n m : ℕ
p : Fin (n + 1)
i : Fin n
⊢ succAbove p i < p ↔ castSucc i < p

Next tactic:
refine' Iff.intro _ _
/-- Embedding `i : Fin n` into `Fin (n + 1)` using a pivot `p` that is greater
results in a value that is less than `p`. -/
@[simp]
theorem succAbove_lt_iff (p : Fin (n + 1)) (i : Fin n) : p.succAbove i < p ↔ castSucc i < p := by
  refine' Iff.intro _ _
  · 

Proof state:
case refine'_1
n m : ℕ
p : Fin (n + 1)
i : Fin n
⊢ succAbove p i < p → castSucc i < p

Next tactic:
intro h
/-- Embedding `i : Fin n` into `Fin (n + 1)` using a pivot `p` that is greater
results in a value that is less than `p`. -/
@[simp]
theorem succAbove_lt_iff (p : Fin (n + 1)) (i : Fin n) : p.succAbove i < p ↔ castSucc i < p := by
  refine' Iff.intro _ _
  · intro h
    

Proof state:
case refine'_1
n m : ℕ
p : Fin (n + 1)
i : Fin n
h : succAbove p i < p
⊢ castSucc i < p

Next tactic:
cases' succAbove_lt_ge p i with H H
/-- Embedding `i : Fin n` into `Fin (n + 1)` using a pivot `p` that is greater
results in a value that is less than `p`. -/
@[simp]
theorem succAbove_lt_iff (p : Fin (n + 1)) (i : Fin n) : p.succAbove i < p ↔ castSucc i < p := by
  refine' Iff.intro _ _
  · intro h
    cases' succAbove_lt_ge p i with H H
    · 

Proof state:
case refine'_1.inl
n m : ℕ
p : Fin (n + 1)
i : Fin n
h : succAbove p i < p
H : castSucc i < p
⊢ castSucc i < p

Next tactic:
exact H
/-- Embedding `i : Fin n` into `Fin (n + 1)` using a pivot `p` that is greater
results in a value that is less than `p`. -/
@[simp]
theorem succAbove_lt_iff (p : Fin (n + 1)) (i : Fin n) : p.succAbove i < p ↔ castSucc i < p := by
  refine' Iff.intro _ _
  · intro h
    cases' succAbove_lt_ge p i with H H
    · exact H
    · 

Proof state:
case refine'_1.inr
n m : ℕ
p : Fin (n + 1)
i : Fin n
h : succAbove p i < p
H : p ≤ castSucc i
⊢ castSucc i < p

Next tactic:
rw [succAbove_above _ _ H] at h
/-- Embedding `i : Fin n` into `Fin (n + 1)` using a pivot `p` that is greater
results in a value that is less than `p`. -/
@[simp]
theorem succAbove_lt_iff (p : Fin (n + 1)) (i : Fin n) : p.succAbove i < p ↔ castSucc i < p := by
  refine' Iff.intro _ _
  · intro h
    cases' succAbove_lt_ge p i with H H
    · exact H
    · rw [succAbove_above _ _ H] at h
      

Proof state:
case refine'_1.inr
n m : ℕ
p : Fin (n + 1)
i : Fin n
h : succ i < p
H : p ≤ castSucc i
⊢ castSucc i < p

Next tactic:
exact lt_trans (castSucc_lt_succ i) h
/-- Embedding `i : Fin n` into `Fin (n + 1)` using a pivot `p` that is greater
results in a value that is less than `p`. -/
@[simp]
theorem succAbove_lt_iff (p : Fin (n + 1)) (i : Fin n) : p.succAbove i < p ↔ castSucc i < p := by
  refine' Iff.intro _ _
  · intro h
    cases' succAbove_lt_ge p i with H H
    · exact H
    · rw [succAbove_above _ _ H] at h
      exact lt_trans (castSucc_lt_succ i) h
  · 

Proof state:
case refine'_2
n m : ℕ
p : Fin (n + 1)
i : Fin n
⊢ castSucc i < p → succAbove p i < p

Next tactic:
intro h
/-- Embedding `i : Fin n` into `Fin (n + 1)` using a pivot `p` that is greater
results in a value that is less than `p`. -/
@[simp]
theorem succAbove_lt_iff (p : Fin (n + 1)) (i : Fin n) : p.succAbove i < p ↔ castSucc i < p := by
  refine' Iff.intro _ _
  · intro h
    cases' succAbove_lt_ge p i with H H
    · exact H
    · rw [succAbove_above _ _ H] at h
      exact lt_trans (castSucc_lt_succ i) h
  · intro h
    

Proof state:
case refine'_2
n m : ℕ
p : Fin (n + 1)
i : Fin n
h : castSucc i < p
⊢ succAbove p i < p

Next tactic:
rw [succAbove_below _ _ h]
/-- Embedding `i : Fin n` into `Fin (n + 1)` using a pivot `p` that is greater
results in a value that is less than `p`. -/
@[simp]
theorem succAbove_lt_iff (p : Fin (n + 1)) (i : Fin n) : p.succAbove i < p ↔ castSucc i < p := by
  refine' Iff.intro _ _
  · intro h
    cases' succAbove_lt_ge p i with H H
    · exact H
    · rw [succAbove_above _ _ H] at h
      exact lt_trans (castSucc_lt_succ i) h
  · intro h
    rw [succAbove_below _ _ h]
    

Proof state:
case refine'_2
n m : ℕ
p : Fin (n + 1)
i : Fin n
h : castSucc i < p
⊢ castSucc i < p

Next tactic:
exact h