l3lab/ntp-mathlib huggingface dataset:
theorem cons_injective_of_injective {α} {x₀ : α} {x : Fin n → α} (hx₀ : x₀ ∉ Set.range x)
    (hx : Function.Injective x) : Function.Injective (cons x₀ x : Fin n.succ → α) := by
  refine' Fin.cases _ _
  · refine' Fin.cases _ _
    · intro
      rfl
    · intro j h
      rw [cons_zero, cons_succ] at h
      exact hx₀.elim ⟨_, h.symm⟩
  · intro i
    refine' Fin.cases _ _
    · 

Proof state:
case refine'_2.refine'_1
m n : ℕ
α✝ : Fin (n + 1) → Type u
x✝ : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i✝ : Fin n
y : α✝ (succ i✝)
z : α✝ 0
α : Type u_1
x₀ : α
x : Fin n → α
hx₀ : x₀ ∉ Set.range x
hx : Injective x
i : Fin n
⊢ cons x₀ x (succ i) = cons x₀ x 0 → succ i = 0

Next tactic:
intro h
theorem cons_injective_of_injective {α} {x₀ : α} {x : Fin n → α} (hx₀ : x₀ ∉ Set.range x)
    (hx : Function.Injective x) : Function.Injective (cons x₀ x : Fin n.succ → α) := by
  refine' Fin.cases _ _
  · refine' Fin.cases _ _
    · intro
      rfl
    · intro j h
      rw [cons_zero, cons_succ] at h
      exact hx₀.elim ⟨_, h.symm⟩
  · intro i
    refine' Fin.cases _ _
    · intro h
      

Proof state:
case refine'_2.refine'_1
m n : ℕ
α✝ : Fin (n + 1) → Type u
x✝ : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i✝ : Fin n
y : α✝ (succ i✝)
z : α✝ 0
α : Type u_1
x₀ : α
x : Fin n → α
hx₀ : x₀ ∉ Set.range x
hx : Injective x
i : Fin n
h : cons x₀ x (succ i) = cons x₀ x 0
⊢ succ i = 0

Next tactic:
rw [cons_zero, cons_succ] at h
theorem cons_injective_of_injective {α} {x₀ : α} {x : Fin n → α} (hx₀ : x₀ ∉ Set.range x)
    (hx : Function.Injective x) : Function.Injective (cons x₀ x : Fin n.succ → α) := by
  refine' Fin.cases _ _
  · refine' Fin.cases _ _
    · intro
      rfl
    · intro j h
      rw [cons_zero, cons_succ] at h
      exact hx₀.elim ⟨_, h.symm⟩
  · intro i
    refine' Fin.cases _ _
    · intro h
      rw [cons_zero, cons_succ] at h
      

Proof state:
case refine'_2.refine'_1
m n : ℕ
α✝ : Fin (n + 1) → Type u
x✝ : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i✝ : Fin n
y : α✝ (succ i✝)
z : α✝ 0
α : Type u_1
x₀ : α
x : Fin n → α
hx₀ : x₀ ∉ Set.range x
hx : Injective x
i : Fin n
h : x i = x₀
⊢ succ i = 0

Next tactic:
exact hx₀.elim ⟨_, h⟩
theorem cons_injective_of_injective {α} {x₀ : α} {x : Fin n → α} (hx₀ : x₀ ∉ Set.range x)
    (hx : Function.Injective x) : Function.Injective (cons x₀ x : Fin n.succ → α) := by
  refine' Fin.cases _ _
  · refine' Fin.cases _ _
    · intro
      rfl
    · intro j h
      rw [cons_zero, cons_succ] at h
      exact hx₀.elim ⟨_, h.symm⟩
  · intro i
    refine' Fin.cases _ _
    · intro h
      rw [cons_zero, cons_succ] at h
      exact hx₀.elim ⟨_, h⟩
    · 

Proof state:
case refine'_2.refine'_2
m n : ℕ
α✝ : Fin (n + 1) → Type u
x✝ : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i✝ : Fin n
y : α✝ (succ i✝)
z : α✝ 0
α : Type u_1
x₀ : α
x : Fin n → α
hx₀ : x₀ ∉ Set.range x
hx : Injective x
i : Fin n
⊢ ∀ (i_1 : Fin n), cons x₀ x (succ i) = cons x₀ x (succ i_1) → succ i = succ i_1

Next tactic:
intro j h
theorem cons_injective_of_injective {α} {x₀ : α} {x : Fin n → α} (hx₀ : x₀ ∉ Set.range x)
    (hx : Function.Injective x) : Function.Injective (cons x₀ x : Fin n.succ → α) := by
  refine' Fin.cases _ _
  · refine' Fin.cases _ _
    · intro
      rfl
    · intro j h
      rw [cons_zero, cons_succ] at h
      exact hx₀.elim ⟨_, h.symm⟩
  · intro i
    refine' Fin.cases _ _
    · intro h
      rw [cons_zero, cons_succ] at h
      exact hx₀.elim ⟨_, h⟩
    · intro j h
      

Proof state:
case refine'_2.refine'_2
m n : ℕ
α✝ : Fin (n + 1) → Type u
x✝ : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i✝ : Fin n
y : α✝ (succ i✝)
z : α✝ 0
α : Type u_1
x₀ : α
x : Fin n → α
hx₀ : x₀ ∉ Set.range x
hx : Injective x
i j : Fin n
h : cons x₀ x (succ i) = cons x₀ x (succ j)
⊢ succ i = succ j

Next tactic:
rw [cons_succ, cons_succ] at h
theorem cons_injective_of_injective {α} {x₀ : α} {x : Fin n → α} (hx₀ : x₀ ∉ Set.range x)
    (hx : Function.Injective x) : Function.Injective (cons x₀ x : Fin n.succ → α) := by
  refine' Fin.cases _ _
  · refine' Fin.cases _ _
    · intro
      rfl
    · intro j h
      rw [cons_zero, cons_succ] at h
      exact hx₀.elim ⟨_, h.symm⟩
  · intro i
    refine' Fin.cases _ _
    · intro h
      rw [cons_zero, cons_succ] at h
      exact hx₀.elim ⟨_, h⟩
    · intro j h
      rw [cons_succ, cons_succ] at h
      

Proof state:
case refine'_2.refine'_2
m n : ℕ
α✝ : Fin (n + 1) → Type u
x✝ : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i✝ : Fin n
y : α✝ (succ i✝)
z : α✝ 0
α : Type u_1
x₀ : α
x : Fin n → α
hx₀ : x₀ ∉ Set.range x
hx : Injective x
i j : Fin n
h : x i = x j
⊢ succ i = succ j

Next tactic:
exact congr_arg _ (hx h)
theorem cons_injective_iff {α} {x₀ : α} {x : Fin n → α} :
    Function.Injective (cons x₀ x : Fin n.succ → α) ↔ x₀ ∉ Set.range x ∧ Function.Injective x := by
  

Proof state:
m n : ℕ
α✝ : Fin (n + 1) → Type u
x✝ : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
x₀ : α
x : Fin n → α
⊢ Injective (cons x₀ x) ↔ x₀ ∉ Set.range x ∧ Injective x

Next tactic:
refine' ⟨fun h ↦ ⟨_, _⟩, fun h ↦ cons_injective_of_injective h.1 h.2⟩
theorem cons_injective_iff {α} {x₀ : α} {x : Fin n → α} :
    Function.Injective (cons x₀ x : Fin n.succ → α) ↔ x₀ ∉ Set.range x ∧ Function.Injective x := by
  refine' ⟨fun h ↦ ⟨_, _⟩, fun h ↦ cons_injective_of_injective h.1 h.2⟩
  · 

Proof state:
case refine'_1
m n : ℕ
α✝ : Fin (n + 1) → Type u
x✝ : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
x₀ : α
x : Fin n → α
h : Injective (cons x₀ x)
⊢ x₀ ∉ Set.range x

Next tactic:
rintro ⟨i, hi⟩
theorem cons_injective_iff {α} {x₀ : α} {x : Fin n → α} :
    Function.Injective (cons x₀ x : Fin n.succ → α) ↔ x₀ ∉ Set.range x ∧ Function.Injective x := by
  refine' ⟨fun h ↦ ⟨_, _⟩, fun h ↦ cons_injective_of_injective h.1 h.2⟩
  · rintro ⟨i, hi⟩
    

Proof state:
case refine'_1.intro
m n : ℕ
α✝ : Fin (n + 1) → Type u
x✝ : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i✝ : Fin n
y : α✝ (succ i✝)
z : α✝ 0
α : Type u_1
x₀ : α
x : Fin n → α
h : Injective (cons x₀ x)
i : Fin n
hi : x i = x₀
⊢ False

Next tactic:
replace h := @h i.succ 0
theorem cons_injective_iff {α} {x₀ : α} {x : Fin n → α} :
    Function.Injective (cons x₀ x : Fin n.succ → α) ↔ x₀ ∉ Set.range x ∧ Function.Injective x := by
  refine' ⟨fun h ↦ ⟨_, _⟩, fun h ↦ cons_injective_of_injective h.1 h.2⟩
  · rintro ⟨i, hi⟩
    replace h := @h i.succ 0
    

Proof state:
case refine'_1.intro
m n : ℕ
α✝ : Fin (n + 1) → Type u
x✝ : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i✝ : Fin n
y : α✝ (succ i✝)
z : α✝ 0
α : Type u_1
x₀ : α
x : Fin n → α
i : Fin n
hi : x i = x₀
h : cons x₀ x (succ i) = cons x₀ x 0 → succ i = 0
⊢ False

Next tactic:
simp [hi, succ_ne_zero] at h
theorem cons_injective_iff {α} {x₀ : α} {x : Fin n → α} :
    Function.Injective (cons x₀ x : Fin n.succ → α) ↔ x₀ ∉ Set.range x ∧ Function.Injective x := by
  refine' ⟨fun h ↦ ⟨_, _⟩, fun h ↦ cons_injective_of_injective h.1 h.2⟩
  · rintro ⟨i, hi⟩
    replace h := @h i.succ 0
    simp [hi, succ_ne_zero] at h
  · 

Proof state:
case refine'_2
m n : ℕ
α✝ : Fin (n + 1) → Type u
x✝ : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
x₀ : α
x : Fin n → α
h : Injective (cons x₀ x)
⊢ Injective x

Next tactic:
simpa [Function.comp] using h.comp (Fin.succ_injective _)
/-- Updating the first element of a tuple does not change the tail. -/
@[simp]
theorem tail_update_zero : tail (update q 0 z) = tail q := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x : α 0
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (succ i)
i : Fin n
y : α (succ i)
z : α 0
⊢ tail (update q 0 z) = tail q

Next tactic:
ext j
/-- Updating the first element of a tuple does not change the tail. -/
@[simp]
theorem tail_update_zero : tail (update q 0 z) = tail q := by
  ext j
  

Proof state:
case h
m n : ℕ
α : Fin (n + 1) → Type u
x : α 0
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (succ i)
i : Fin n
y : α (succ i)
z : α 0
j : Fin n
⊢ tail (update q 0 z) j = tail q j

Next tactic:
simp [tail, Fin.succ_ne_zero]
/-- Updating a nonzero element and taking the tail commute. -/
@[simp]
theorem tail_update_succ : tail (update q i.succ y) = update (tail q) i y := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x : α 0
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (succ i)
i : Fin n
y : α (succ i)
z : α 0
⊢ tail (update q (succ i) y) = update (tail q) i y

Next tactic:
ext j
/-- Updating a nonzero element and taking the tail commute. -/
@[simp]
theorem tail_update_succ : tail (update q i.succ y) = update (tail q) i y := by
  ext j
  

Proof state:
case h
m n : ℕ
α : Fin (n + 1) → Type u
x : α 0
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (succ i)
i : Fin n
y : α (succ i)
z : α 0
j : Fin n
⊢ tail (update q (succ i) y) j = update (tail q) i y j

Next tactic:
by_cases h : j = i
/-- Updating a nonzero element and taking the tail commute. -/
@[simp]
theorem tail_update_succ : tail (update q i.succ y) = update (tail q) i y := by
  ext j
  by_cases h : j = i
  · 

Proof state:
case pos
m n : ℕ
α : Fin (n + 1) → Type u
x : α 0
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (succ i)
i : Fin n
y : α (succ i)
z : α 0
j : Fin n
h : j = i
⊢ tail (update q (succ i) y) j = update (tail q) i y j

Next tactic:
rw [h]
/-- Updating a nonzero element and taking the tail commute. -/
@[simp]
theorem tail_update_succ : tail (update q i.succ y) = update (tail q) i y := by
  ext j
  by_cases h : j = i
  · rw [h]
    

Proof state:
case pos
m n : ℕ
α : Fin (n + 1) → Type u
x : α 0
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (succ i)
i : Fin n
y : α (succ i)
z : α 0
j : Fin n
h : j = i
⊢ tail (update q (succ i) y) i = update (tail q) i y i

Next tactic:
simp [tail]
/-- Updating a nonzero element and taking the tail commute. -/
@[simp]
theorem tail_update_succ : tail (update q i.succ y) = update (tail q) i y := by
  ext j
  by_cases h : j = i
  · rw [h]
    simp [tail]
  · 

Proof state:
case neg
m n : ℕ
α : Fin (n + 1) → Type u
x : α 0
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (succ i)
i : Fin n
y : α (succ i)
z : α 0
j : Fin n
h : ¬j = i
⊢ tail (update q (succ i) y) j = update (tail q) i y j

Next tactic:
simp [tail, (Fin.succ_injective n).ne h, h]
theorem comp_cons {α : Type*} {β : Type*} (g : α → β) (y : α) (q : Fin n → α) :
    g ∘ cons y q = cons (g y) (g ∘ q) := by
  

Proof state:
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q✝ : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y✝ : α✝ (succ i)
z : α✝ 0
α : Type u_1
β : Type u_2
g : α → β
y : α
q : Fin n → α
⊢ g ∘ cons y q = cons (g y) (g ∘ q)

Next tactic:
ext j
theorem comp_cons {α : Type*} {β : Type*} (g : α → β) (y : α) (q : Fin n → α) :
    g ∘ cons y q = cons (g y) (g ∘ q) := by
  ext j
  

Proof state:
case h
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q✝ : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y✝ : α✝ (succ i)
z : α✝ 0
α : Type u_1
β : Type u_2
g : α → β
y : α
q : Fin n → α
j : Fin (n + 1)
⊢ (g ∘ cons y q) j = cons (g y) (g ∘ q) j

Next tactic:
by_cases h : j = 0
theorem comp_cons {α : Type*} {β : Type*} (g : α → β) (y : α) (q : Fin n → α) :
    g ∘ cons y q = cons (g y) (g ∘ q) := by
  ext j
  by_cases h : j = 0
  · 

Proof state:
case pos
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q✝ : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y✝ : α✝ (succ i)
z : α✝ 0
α : Type u_1
β : Type u_2
g : α → β
y : α
q : Fin n → α
j : Fin (n + 1)
h : j = 0
⊢ (g ∘ cons y q) j = cons (g y) (g ∘ q) j

Next tactic:
rw [h]
theorem comp_cons {α : Type*} {β : Type*} (g : α → β) (y : α) (q : Fin n → α) :
    g ∘ cons y q = cons (g y) (g ∘ q) := by
  ext j
  by_cases h : j = 0
  · rw [h]
    

Proof state:
case pos
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q✝ : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y✝ : α✝ (succ i)
z : α✝ 0
α : Type u_1
β : Type u_2
g : α → β
y : α
q : Fin n → α
j : Fin (n + 1)
h : j = 0
⊢ (g ∘ cons y q) 0 = cons (g y) (g ∘ q) 0

Next tactic:
rfl
theorem comp_cons {α : Type*} {β : Type*} (g : α → β) (y : α) (q : Fin n → α) :
    g ∘ cons y q = cons (g y) (g ∘ q) := by
  ext j
  by_cases h : j = 0
  · rw [h]
    rfl
  · 

Proof state:
case neg
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q✝ : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y✝ : α✝ (succ i)
z : α✝ 0
α : Type u_1
β : Type u_2
g : α → β
y : α
q : Fin n → α
j : Fin (n + 1)
h : ¬j = 0
⊢ (g ∘ cons y q) j = cons (g y) (g ∘ q) j

Next tactic:
let j' := pred j h
theorem comp_cons {α : Type*} {β : Type*} (g : α → β) (y : α) (q : Fin n → α) :
    g ∘ cons y q = cons (g y) (g ∘ q) := by
  ext j
  by_cases h : j = 0
  · rw [h]
    rfl
  · let j' := pred j h
    

Proof state:
case neg
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q✝ : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y✝ : α✝ (succ i)
z : α✝ 0
α : Type u_1
β : Type u_2
g : α → β
y : α
q : Fin n → α
j : Fin (n + 1)
h : ¬j = 0
j' : Fin n := pred j h
⊢ (g ∘ cons y q) j = cons (g y) (g ∘ q) j

Next tactic:
have : j'.succ = j := succ_pred j h
theorem comp_cons {α : Type*} {β : Type*} (g : α → β) (y : α) (q : Fin n → α) :
    g ∘ cons y q = cons (g y) (g ∘ q) := by
  ext j
  by_cases h : j = 0
  · rw [h]
    rfl
  · let j' := pred j h
    have : j'.succ = j := succ_pred j h
    

Proof state:
case neg
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q✝ : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y✝ : α✝ (succ i)
z : α✝ 0
α : Type u_1
β : Type u_2
g : α → β
y : α
q : Fin n → α
j : Fin (n + 1)
h : ¬j = 0
j' : Fin n := pred j h
this : succ j' = j
⊢ (g ∘ cons y q) j = cons (g y) (g ∘ q) j

Next tactic:
rw [← this, cons_succ, comp_apply, comp_apply, cons_succ]
theorem comp_tail {α : Type*} {β : Type*} (g : α → β) (q : Fin n.succ → α) :
    g ∘ tail q = tail (g ∘ q) := by
  

Proof state:
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q✝ : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
β : Type u_2
g : α → β
q : Fin (Nat.succ n) → α
⊢ g ∘ tail q = tail (g ∘ q)

Next tactic:
ext j
theorem comp_tail {α : Type*} {β : Type*} (g : α → β) (q : Fin n.succ → α) :
    g ∘ tail q = tail (g ∘ q) := by
  ext j
  

Proof state:
case h
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q✝ : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
β : Type u_2
g : α → β
q : Fin (Nat.succ n) → α
j : Fin n
⊢ (g ∘ tail q) j = tail (g ∘ q) j

Next tactic:
simp [tail]
theorem le_cons [∀ i, Preorder (α i)] {x : α 0} {q : ∀ i, α i} {p : ∀ i : Fin n, α i.succ} :
    q ≤ cons x p ↔ q 0 ≤ x ∧ tail q ≤ p :=
  forall_fin_succ.trans <| and_congr Iff.rfl <| forall_congr' fun j ↦ by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x✝ : α 0
q✝ : (i : Fin (n + 1)) → α i
p✝ : (i : Fin n) → α (succ i)
i : Fin n
y : α (succ i)
z : α 0
inst✝ : (i : Fin (n + 1)) → Preorder (α i)
x : α 0
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (succ i)
j : Fin n
⊢ q (succ j) ≤ cons x p (succ j) ↔ tail q j ≤ p j

Next tactic:
simp [tail]
theorem cons_le_cons [∀ i, Preorder (α i)] {x₀ y₀ : α 0} {x y : ∀ i : Fin n, α i.succ} :
    cons x₀ x ≤ cons y₀ y ↔ x₀ ≤ y₀ ∧ x ≤ y :=
  forall_fin_succ.trans <| and_congr_right' <| by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x✝ : α 0
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (succ i)
i : Fin n
y✝ : α (succ i)
z : α 0
inst✝ : (i : Fin (n + 1)) → Preorder (α i)
x₀ y₀ : α 0
x y : (i : Fin n) → α (succ i)
⊢ (∀ (i : Fin n), cons x₀ x (succ i) ≤ cons y₀ y (succ i)) ↔ x ≤ y

Next tactic:
simp only [cons_succ, Pi.le_def]
theorem pi_lex_lt_cons_cons {x₀ y₀ : α 0} {x y : ∀ i : Fin n, α i.succ}
    (s : ∀ {i : Fin n.succ}, α i → α i → Prop) :
    Pi.Lex (· < ·) (@s) (Fin.cons x₀ x) (Fin.cons y₀ y) ↔
      s x₀ y₀ ∨ x₀ = y₀ ∧ Pi.Lex (· < ·) (@fun i : Fin n ↦ @s i.succ) x y := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x✝ : α 0
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (succ i)
i : Fin n
y✝ : α (succ i)
z x₀ y₀ : α 0
x y : (i : Fin n) → α (succ i)
s : {i : Fin (Nat.succ n)} → α i → α i → Prop
⊢ Pi.Lex (fun x x_1 => x < x_1) s (cons x₀ x) (cons y₀ y) ↔
    s x₀ y₀ ∨ x₀ = y₀ ∧ Pi.Lex (fun x x_1 => x < x_1) (fun i => s) x y

Next tactic:
simp_rw [Pi.Lex, Fin.exists_fin_succ, Fin.cons_succ, Fin.cons_zero, Fin.forall_fin_succ]
theorem pi_lex_lt_cons_cons {x₀ y₀ : α 0} {x y : ∀ i : Fin n, α i.succ}
    (s : ∀ {i : Fin n.succ}, α i → α i → Prop) :
    Pi.Lex (· < ·) (@s) (Fin.cons x₀ x) (Fin.cons y₀ y) ↔
      s x₀ y₀ ∨ x₀ = y₀ ∧ Pi.Lex (· < ·) (@fun i : Fin n ↦ @s i.succ) x y := by
  simp_rw [Pi.Lex, Fin.exists_fin_succ, Fin.cons_succ, Fin.cons_zero, Fin.forall_fin_succ]
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x✝ : α 0
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (succ i)
i : Fin n
y✝ : α (succ i)
z x₀ y₀ : α 0
x y : (i : Fin n) → α (succ i)
s : {i : Fin (Nat.succ n)} → α i → α i → Prop
⊢ (((0 < 0 → cons x₀ x 0 = cons y₀ y 0) ∧ ∀ (i : Fin n), succ i < 0 → cons x₀ x (succ i) = cons y₀ y (succ i)) ∧
        s x₀ y₀ ∨
      ∃ i,
        ((0 < succ i → cons x₀ x 0 = cons y₀ y 0) ∧
            ∀ (i_1 : Fin n), succ i_1 < succ i → cons x₀ x (succ i_1) = cons y₀ y (succ i_1)) ∧
          s (x i) (y i)) ↔
    s x₀ y₀ ∨ x₀ = y₀ ∧ ∃ i, (∀ j < i, x j = y j) ∧ s (x i) (y i)

Next tactic:
simp [and_assoc, exists_and_left]
@[simp]
theorem range_cons {α : Type*} {n : ℕ} (x : α) (b : Fin n → α) :
    Set.range (Fin.cons x b : Fin n.succ → α) = insert x (Set.range b) := by
  

Proof state:
m n✝ : ℕ
α✝ : Fin (n✝ + 1) → Type u
x✝ : α✝ 0
q : (i : Fin (n✝ + 1)) → α✝ i
p : (i : Fin n✝) → α✝ (succ i)
i : Fin n✝
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
n : ℕ
x : α
b : Fin n → α
⊢ Set.range (cons x b) = insert x (Set.range b)

Next tactic:
rw [range_fin_succ, cons_zero, tail_cons]
theorem append_right_nil {α : Type*} (u : Fin m → α) (v : Fin n → α) (hv : n = 0) :
    append u v = u ∘ Fin.cast (by 

Proof state:
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
u : Fin m → α
v : Fin n → α
hv : n = 0
⊢ m + n = m

Next tactic:
rw [hv, add_zero]
theorem append_right_nil {α : Type*} (u : Fin m → α) (v : Fin n → α) (hv : n = 0) :
    append u v = u ∘ Fin.cast (by rw [hv, add_zero]) := by
  

Proof state:
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
u : Fin m → α
v : Fin n → α
hv : n = 0
⊢ append u v = u ∘ cast (_ : m + n = m)

Next tactic:
refine' funext (Fin.addCases (fun l => _) fun r => _)
theorem append_right_nil {α : Type*} (u : Fin m → α) (v : Fin n → α) (hv : n = 0) :
    append u v = u ∘ Fin.cast (by rw [hv, add_zero]) := by
  refine' funext (Fin.addCases (fun l => _) fun r => _)
  · 

Proof state:
case refine'_1
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
u : Fin m → α
v : Fin n → α
hv : n = 0
l : Fin m
⊢ append u v (castAdd n l) = (u ∘ cast (_ : m + n = m)) (castAdd n l)

Next tactic:
rw [append_left, Function.comp_apply]
theorem append_right_nil {α : Type*} (u : Fin m → α) (v : Fin n → α) (hv : n = 0) :
    append u v = u ∘ Fin.cast (by rw [hv, add_zero]) := by
  refine' funext (Fin.addCases (fun l => _) fun r => _)
  · rw [append_left, Function.comp_apply]
    

Proof state:
case refine'_1
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
u : Fin m → α
v : Fin n → α
hv : n = 0
l : Fin m
⊢ u l = u (cast (_ : m + n = m) (castAdd n l))

Next tactic:
refine' congr_arg u (Fin.ext _)
theorem append_right_nil {α : Type*} (u : Fin m → α) (v : Fin n → α) (hv : n = 0) :
    append u v = u ∘ Fin.cast (by rw [hv, add_zero]) := by
  refine' funext (Fin.addCases (fun l => _) fun r => _)
  · rw [append_left, Function.comp_apply]
    refine' congr_arg u (Fin.ext _)
    

Proof state:
case refine'_1
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
u : Fin m → α
v : Fin n → α
hv : n = 0
l : Fin m
⊢ ↑l = ↑(cast (_ : m + n = m) (castAdd n l))

Next tactic:
simp
theorem append_right_nil {α : Type*} (u : Fin m → α) (v : Fin n → α) (hv : n = 0) :
    append u v = u ∘ Fin.cast (by rw [hv, add_zero]) := by
  refine' funext (Fin.addCases (fun l => _) fun r => _)
  · rw [append_left, Function.comp_apply]
    refine' congr_arg u (Fin.ext _)
    simp
  · 

Proof state:
case refine'_2
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
u : Fin m → α
v : Fin n → α
hv : n = 0
r : Fin n
⊢ append u v (natAdd m r) = (u ∘ cast (_ : m + n = m)) (natAdd m r)

Next tactic:
exact (Fin.cast hv r).elim0'
theorem append_left_nil {α : Type*} (u : Fin m → α) (v : Fin n → α) (hu : m = 0) :
    append u v = v ∘ Fin.cast (by 

Proof state:
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
u : Fin m → α
v : Fin n → α
hu : m = 0
⊢ m + n = n

Next tactic:
rw [hu, zero_add]
theorem append_left_nil {α : Type*} (u : Fin m → α) (v : Fin n → α) (hu : m = 0) :
    append u v = v ∘ Fin.cast (by rw [hu, zero_add]) := by
  

Proof state:
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
u : Fin m → α
v : Fin n → α
hu : m = 0
⊢ append u v = v ∘ cast (_ : m + n = n)

Next tactic:
refine' funext (Fin.addCases (fun l => _) fun r => _)
theorem append_left_nil {α : Type*} (u : Fin m → α) (v : Fin n → α) (hu : m = 0) :
    append u v = v ∘ Fin.cast (by rw [hu, zero_add]) := by
  refine' funext (Fin.addCases (fun l => _) fun r => _)
  · 

Proof state:
case refine'_1
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
u : Fin m → α
v : Fin n → α
hu : m = 0
l : Fin m
⊢ append u v (castAdd n l) = (v ∘ cast (_ : m + n = n)) (castAdd n l)

Next tactic:
exact (Fin.cast hu l).elim0'
theorem append_left_nil {α : Type*} (u : Fin m → α) (v : Fin n → α) (hu : m = 0) :
    append u v = v ∘ Fin.cast (by rw [hu, zero_add]) := by
  refine' funext (Fin.addCases (fun l => _) fun r => _)
  · exact (Fin.cast hu l).elim0'
  · 

Proof state:
case refine'_2
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
u : Fin m → α
v : Fin n → α
hu : m = 0
r : Fin n
⊢ append u v (natAdd m r) = (v ∘ cast (_ : m + n = n)) (natAdd m r)

Next tactic:
rw [append_right, Function.comp_apply]
theorem append_left_nil {α : Type*} (u : Fin m → α) (v : Fin n → α) (hu : m = 0) :
    append u v = v ∘ Fin.cast (by rw [hu, zero_add]) := by
  refine' funext (Fin.addCases (fun l => _) fun r => _)
  · exact (Fin.cast hu l).elim0'
  · rw [append_right, Function.comp_apply]
    

Proof state:
case refine'_2
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
u : Fin m → α
v : Fin n → α
hu : m = 0
r : Fin n
⊢ v r = v (cast (_ : m + n = n) (natAdd m r))

Next tactic:
refine' congr_arg v (Fin.ext _)
theorem append_left_nil {α : Type*} (u : Fin m → α) (v : Fin n → α) (hu : m = 0) :
    append u v = v ∘ Fin.cast (by rw [hu, zero_add]) := by
  refine' funext (Fin.addCases (fun l => _) fun r => _)
  · exact (Fin.cast hu l).elim0'
  · rw [append_right, Function.comp_apply]
    refine' congr_arg v (Fin.ext _)
    

Proof state:
case refine'_2
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
u : Fin m → α
v : Fin n → α
hu : m = 0
r : Fin n
⊢ ↑r = ↑(cast (_ : m + n = n) (natAdd m r))

Next tactic:
simp [hu]