l3lab/ntp-mathlib huggingface dataset:
/-- Composition as a bilinear map. -/
@[simps]
def comp (X Y Z : C) : (X ⟶ Y) →ₗ[S] (Y ⟶ Z) →ₗ[S] X ⟶ Z
    where
  toFun f := leftComp S Z f
  map_add' := by
    intros
    ext
    

Proof state:
case h
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
S : Type w
inst✝¹ : CommSemiring S
inst✝ : Linear S C
X Y Z : C
x✝¹ y✝ : X ⟶ Y
x✝ : Y ⟶ Z
⊢ ((fun f => leftComp S Z f) (x✝¹ + y✝)) x✝ = ((fun f => leftComp S Z f) x✝¹ + (fun f => leftComp S Z f) y✝) x✝

Next tactic:
simp
/-- Composition as a bilinear map. -/
@[simps]
def comp (X Y Z : C) : (X ⟶ Y) →ₗ[S] (Y ⟶ Z) →ₗ[S] X ⟶ Z
    where
  toFun f := leftComp S Z f
  map_add' := by
    intros
    ext
    simp
  map_smul' := by
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
S : Type w
inst✝¹ : CommSemiring S
inst✝ : Linear S C
X Y Z : C
⊢ ∀ (r : S) (x : X ⟶ Y),
    AddHom.toFun
        { toFun := fun f => leftComp S Z f,
          map_add' :=
            (_ :
              ∀ (x y : X ⟶ Y),
                (fun f => leftComp S Z f) (x + y) = (fun f => leftComp S Z f) x + (fun f => leftComp S Z f) y) }
        (r • x) =
      (RingHom.id S) r •
        AddHom.toFun
          { toFun := fun f => leftComp S Z f,
            map_add' :=
              (_ :
                ∀ (x y : X ⟶ Y),
                  (fun f => leftComp S Z f) (x + y) = (fun f => leftComp S Z f) x + (fun f => leftComp S Z f) y) }
          x

Next tactic:
intros
/-- Composition as a bilinear map. -/
@[simps]
def comp (X Y Z : C) : (X ⟶ Y) →ₗ[S] (Y ⟶ Z) →ₗ[S] X ⟶ Z
    where
  toFun f := leftComp S Z f
  map_add' := by
    intros
    ext
    simp
  map_smul' := by
    intros
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
S : Type w
inst✝¹ : CommSemiring S
inst✝ : Linear S C
X Y Z : C
r✝ : S
x✝ : X ⟶ Y
⊢ AddHom.toFun
      { toFun := fun f => leftComp S Z f,
        map_add' :=
          (_ :
            ∀ (x y : X ⟶ Y),
              (fun f => leftComp S Z f) (x + y) = (fun f => leftComp S Z f) x + (fun f => leftComp S Z f) y) }
      (r✝ • x✝) =
    (RingHom.id S) r✝ •
      AddHom.toFun
        { toFun := fun f => leftComp S Z f,
          map_add' :=
            (_ :
              ∀ (x y : X ⟶ Y),
                (fun f => leftComp S Z f) (x + y) = (fun f => leftComp S Z f) x + (fun f => leftComp S Z f) y) }
        x✝

Next tactic:
ext
/-- Composition as a bilinear map. -/
@[simps]
def comp (X Y Z : C) : (X ⟶ Y) →ₗ[S] (Y ⟶ Z) →ₗ[S] X ⟶ Z
    where
  toFun f := leftComp S Z f
  map_add' := by
    intros
    ext
    simp
  map_smul' := by
    intros
    ext
    

Proof state:
case h
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
S : Type w
inst✝¹ : CommSemiring S
inst✝ : Linear S C
X Y Z : C
r✝ : S
x✝¹ : X ⟶ Y
x✝ : Y ⟶ Z
⊢ (AddHom.toFun
        { toFun := fun f => leftComp S Z f,
          map_add' :=
            (_ :
              ∀ (x y : X ⟶ Y),
                (fun f => leftComp S Z f) (x + y) = (fun f => leftComp S Z f) x + (fun f => leftComp S Z f) y) }
        (r✝ • x✝¹))
      x✝ =
    ((RingHom.id S) r✝ •
        AddHom.toFun
          { toFun := fun f => leftComp S Z f,
            map_add' :=
              (_ :
                ∀ (x y : X ⟶ Y),
                  (fun f => leftComp S Z f) (x + y) = (fun f => leftComp S Z f) x + (fun f => leftComp S Z f) y) }
          x✝¹)
      x✝

Next tactic:
simp
lemma IsZeckendorfRep.sum_fib_lt : ∀ {n l}, IsZeckendorfRep l → (∀ a ∈ (l ++ [0]).head?, a < n) →
    (l.map fib).sum < fib n
  | n, [], _, hn => fib_pos.2 $ hn _ rfl
  | n, a :: l, hl, hn => by
    

Proof state:
n a : ℕ
l : List ℕ
hl : IsZeckendorfRep (a :: l)
hn : ∀ a_1 ∈ head? (a :: l ++ [0]), a_1 < n
⊢ sum (map fib (a :: l)) < fib n

Next tactic:
simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons] at hl
lemma IsZeckendorfRep.sum_fib_lt : ∀ {n l}, IsZeckendorfRep l → (∀ a ∈ (l ++ [0]).head?, a < n) →
    (l.map fib).sum < fib n
  | n, [], _, hn => fib_pos.2 $ hn _ rfl
  | n, a :: l, hl, hn => by
    simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons] at hl
    

Proof state:
n a : ℕ
l : List ℕ
hn : ∀ a_1 ∈ head? (a :: l ++ [0]), a_1 < n
hl : (∀ a' ∈ l ++ [0], a' + 2 ≤ a) ∧ Pairwise (fun a b => b + 2 ≤ a) (l ++ [0])
⊢ sum (map fib (a :: l)) < fib n

Next tactic:
have : ∀ b, b ∈ head? (l ++ [0]) → b < a - 1 :=
      fun b hb ↦ lt_tsub_iff_right.2 $ hl.1 _ $ mem_of_mem_head? hb
lemma IsZeckendorfRep.sum_fib_lt : ∀ {n l}, IsZeckendorfRep l → (∀ a ∈ (l ++ [0]).head?, a < n) →
    (l.map fib).sum < fib n
  | n, [], _, hn => fib_pos.2 $ hn _ rfl
  | n, a :: l, hl, hn => by
    simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons] at hl
    have : ∀ b, b ∈ head? (l ++ [0]) → b < a - 1 :=
      fun b hb ↦ lt_tsub_iff_right.2 $ hl.1 _ $ mem_of_mem_head? hb
    

Proof state:
n a : ℕ
l : List ℕ
hn : ∀ a_1 ∈ head? (a :: l ++ [0]), a_1 < n
hl : (∀ a' ∈ l ++ [0], a' + 2 ≤ a) ∧ Pairwise (fun a b => b + 2 ≤ a) (l ++ [0])
this : ∀ b ∈ head? (l ++ [0]), b < a - 1
⊢ sum (map fib (a :: l)) < fib n

Next tactic:
simp only [mem_append, mem_singleton, ← chain'_iff_pairwise, or_imp, forall_and, forall_eq,
      zero_add] at hl
lemma IsZeckendorfRep.sum_fib_lt : ∀ {n l}, IsZeckendorfRep l → (∀ a ∈ (l ++ [0]).head?, a < n) →
    (l.map fib).sum < fib n
  | n, [], _, hn => fib_pos.2 $ hn _ rfl
  | n, a :: l, hl, hn => by
    simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons] at hl
    have : ∀ b, b ∈ head? (l ++ [0]) → b < a - 1 :=
      fun b hb ↦ lt_tsub_iff_right.2 $ hl.1 _ $ mem_of_mem_head? hb
    simp only [mem_append, mem_singleton, ← chain'_iff_pairwise, or_imp, forall_and, forall_eq,
      zero_add] at hl
    

Proof state:
n a : ℕ
l : List ℕ
hn : ∀ a_1 ∈ head? (a :: l ++ [0]), a_1 < n
this : ∀ b ∈ head? (l ++ [0]), b < a - 1
hl : ((∀ x ∈ l, x + 2 ≤ a) ∧ 2 ≤ a) ∧ Chain' (fun a b => b + 2 ≤ a) (l ++ [0])
⊢ sum (map fib (a :: l)) < fib n

Next tactic:
simp only [map, List.sum_cons]
lemma IsZeckendorfRep.sum_fib_lt : ∀ {n l}, IsZeckendorfRep l → (∀ a ∈ (l ++ [0]).head?, a < n) →
    (l.map fib).sum < fib n
  | n, [], _, hn => fib_pos.2 $ hn _ rfl
  | n, a :: l, hl, hn => by
    simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons] at hl
    have : ∀ b, b ∈ head? (l ++ [0]) → b < a - 1 :=
      fun b hb ↦ lt_tsub_iff_right.2 $ hl.1 _ $ mem_of_mem_head? hb
    simp only [mem_append, mem_singleton, ← chain'_iff_pairwise, or_imp, forall_and, forall_eq,
      zero_add] at hl
    simp only [map, List.sum_cons]
    

Proof state:
n a : ℕ
l : List ℕ
hn : ∀ a_1 ∈ head? (a :: l ++ [0]), a_1 < n
this : ∀ b ∈ head? (l ++ [0]), b < a - 1
hl : ((∀ x ∈ l, x + 2 ≤ a) ∧ 2 ≤ a) ∧ Chain' (fun a b => b + 2 ≤ a) (l ++ [0])
⊢ fib a + sum (map fib l) < fib n

Next tactic:
refine (add_lt_add_left (sum_fib_lt hl.2 this) _).trans_le ?_
lemma IsZeckendorfRep.sum_fib_lt : ∀ {n l}, IsZeckendorfRep l → (∀ a ∈ (l ++ [0]).head?, a < n) →
    (l.map fib).sum < fib n
  | n, [], _, hn => fib_pos.2 $ hn _ rfl
  | n, a :: l, hl, hn => by
    simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons] at hl
    have : ∀ b, b ∈ head? (l ++ [0]) → b < a - 1 :=
      fun b hb ↦ lt_tsub_iff_right.2 $ hl.1 _ $ mem_of_mem_head? hb
    simp only [mem_append, mem_singleton, ← chain'_iff_pairwise, or_imp, forall_and, forall_eq,
      zero_add] at hl
    simp only [map, List.sum_cons]
    refine (add_lt_add_left (sum_fib_lt hl.2 this) _).trans_le ?_
    

Proof state:
n a : ℕ
l : List ℕ
hn : ∀ a_1 ∈ head? (a :: l ++ [0]), a_1 < n
this : ∀ b ∈ head? (l ++ [0]), b < a - 1
hl : ((∀ x ∈ l, x + 2 ≤ a) ∧ 2 ≤ a) ∧ Chain' (fun a b => b + 2 ≤ a) (l ++ [0])
⊢ fib a + fib (a - 1) ≤ fib n

Next tactic:
rw [add_comm, ← fib_add_one (hl.1.2.trans_lt' zero_lt_two).ne']
lemma IsZeckendorfRep.sum_fib_lt : ∀ {n l}, IsZeckendorfRep l → (∀ a ∈ (l ++ [0]).head?, a < n) →
    (l.map fib).sum < fib n
  | n, [], _, hn => fib_pos.2 $ hn _ rfl
  | n, a :: l, hl, hn => by
    simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons] at hl
    have : ∀ b, b ∈ head? (l ++ [0]) → b < a - 1 :=
      fun b hb ↦ lt_tsub_iff_right.2 $ hl.1 _ $ mem_of_mem_head? hb
    simp only [mem_append, mem_singleton, ← chain'_iff_pairwise, or_imp, forall_and, forall_eq,
      zero_add] at hl
    simp only [map, List.sum_cons]
    refine (add_lt_add_left (sum_fib_lt hl.2 this) _).trans_le ?_
    rw [add_comm, ← fib_add_one (hl.1.2.trans_lt' zero_lt_two).ne']
    

Proof state:
n a : ℕ
l : List ℕ
hn : ∀ a_1 ∈ head? (a :: l ++ [0]), a_1 < n
this : ∀ b ∈ head? (l ++ [0]), b < a - 1
hl : ((∀ x ∈ l, x + 2 ≤ a) ∧ 2 ≤ a) ∧ Chain' (fun a b => b + 2 ≤ a) (l ++ [0])
⊢ fib (a + 1) ≤ fib n

Next tactic:
exact fib_mono (hn _ rfl)
@[simp] lemma greatestFib_eq_zero : greatestFib n = 0 ↔ n = 0 :=
  ⟨fun h ↦ by 

Proof state:
l : List ℕ
a m n : ℕ
h : greatestFib n = 0
⊢ n = 0

Next tactic:
simpa using findGreatest_eq_zero_iff.1 h zero_lt_one le_add_self
@[simp] lemma greatestFib_eq_zero : greatestFib n = 0 ↔ n = 0 :=
  ⟨fun h ↦ by simpa using findGreatest_eq_zero_iff.1 h zero_lt_one le_add_self, by 

Proof state:
l : List ℕ
a m n : ℕ
⊢ n = 0 → greatestFib n = 0

Next tactic:
rintro rfl
@[simp] lemma greatestFib_eq_zero : greatestFib n = 0 ↔ n = 0 :=
  ⟨fun h ↦ by simpa using findGreatest_eq_zero_iff.1 h zero_lt_one le_add_self, by rintro rfl; 

Proof state:
l : List ℕ
a m : ℕ
⊢ greatestFib 0 = 0

Next tactic:
rfl
@[simp] lemma greatestFib_pos : 0 < greatestFib n ↔ 0 < n := by 

Proof state:
l : List ℕ
a m n : ℕ
⊢ 0 < greatestFib n ↔ 0 < n

Next tactic:
simp [pos_iff_ne_zero]
lemma greatestFib_sub_fib_greatestFib_le_greatestFib (hn : n ≠ 0) :
    greatestFib (n - fib (greatestFib n)) ≤ greatestFib n - 2 := by
  

Proof state:
l : List ℕ
a m n : ℕ
hn : n ≠ 0
⊢ greatestFib (n - fib (greatestFib n)) ≤ greatestFib n - 2

Next tactic:
rw [← lt_succ_iff, greatestFib_lt, tsub_lt_iff_right n.fib_greatestFib_le, Nat.sub_succ,
    succ_pred, ← fib_add_one]
lemma greatestFib_sub_fib_greatestFib_le_greatestFib (hn : n ≠ 0) :
    greatestFib (n - fib (greatestFib n)) ≤ greatestFib n - 2 := by
  rw [← lt_succ_iff, greatestFib_lt, tsub_lt_iff_right n.fib_greatestFib_le, Nat.sub_succ,
    succ_pred, ← fib_add_one]
  

Proof state:
l : List ℕ
a m n : ℕ
hn : n ≠ 0
⊢ n < fib (greatestFib n + 1)
l : List ℕ
a m n : ℕ
hn : n ≠ 0
⊢ greatestFib n ≠ 0
l : List ℕ a m n : ℕ hn : n ≠ 0 ⊢ greatestFib n - 1 ≠ 0

Next tactic:
exact n.lt_fib_greatestFib_add_one
lemma greatestFib_sub_fib_greatestFib_le_greatestFib (hn : n ≠ 0) :
    greatestFib (n - fib (greatestFib n)) ≤ greatestFib n - 2 := by
  rw [← lt_succ_iff, greatestFib_lt, tsub_lt_iff_right n.fib_greatestFib_le, Nat.sub_succ,
    succ_pred, ← fib_add_one]
  exact n.lt_fib_greatestFib_add_one
  · 

Proof state:
l : List ℕ
a m n : ℕ
hn : n ≠ 0
⊢ greatestFib n ≠ 0

Next tactic:
simpa
lemma greatestFib_sub_fib_greatestFib_le_greatestFib (hn : n ≠ 0) :
    greatestFib (n - fib (greatestFib n)) ≤ greatestFib n - 2 := by
  rw [← lt_succ_iff, greatestFib_lt, tsub_lt_iff_right n.fib_greatestFib_le, Nat.sub_succ,
    succ_pred, ← fib_add_one]
  exact n.lt_fib_greatestFib_add_one
  · simpa
  · 

Proof state:
l : List ℕ
a m n : ℕ
hn : n ≠ 0
⊢ greatestFib n - 1 ≠ 0

Next tactic:
simpa [← succ_le_iff] using hn.bot_lt
@[simp, nolint unusedHavesSuffices] lemma zeckendorf_succ (n : ℕ) :
    zeckendorf (n + 1) = greatestFib (n + 1) :: zeckendorf (n + 1 - fib (greatestFib (n + 1))) := by
  

Proof state:
l : List ℕ
a m n✝ n : ℕ
⊢ zeckendorf (n + 1) = greatestFib (n + 1) :: zeckendorf (n + 1 - fib (greatestFib (n + 1)))

Next tactic:
simp [zeckendorf]
lemma isZeckendorfRep_zeckendorf : ∀ n, (zeckendorf n).IsZeckendorfRep
  | 0 => Chain.nil
  | n + 1 => by
    

Proof state:
l : List ℕ
a m n✝ n : ℕ
⊢ IsZeckendorfRep (zeckendorf (n + 1))

Next tactic:
rw [zeckendorf_succ, IsZeckendorfRep, List.cons_append]
lemma isZeckendorfRep_zeckendorf : ∀ n, (zeckendorf n).IsZeckendorfRep
  | 0 => Chain.nil
  | n + 1 => by
    rw [zeckendorf_succ, IsZeckendorfRep, List.cons_append]
    

Proof state:
l : List ℕ
a m n✝ n : ℕ
⊢ Chain' (fun a b => b + 2 ≤ a) (greatestFib (n + 1) :: (zeckendorf (n + 1 - fib (greatestFib (n + 1))) ++ [0]))

Next tactic:
have := zeckendorf_aux n.succ_pos
lemma isZeckendorfRep_zeckendorf : ∀ n, (zeckendorf n).IsZeckendorfRep
  | 0 => Chain.nil
  | n + 1 => by
    rw [zeckendorf_succ, IsZeckendorfRep, List.cons_append]
    have := zeckendorf_aux n.succ_pos
    

Proof state:
l : List ℕ
a m n✝ n : ℕ
this : succ n - fib (greatestFib (succ n)) < succ n
⊢ Chain' (fun a b => b + 2 ≤ a) (greatestFib (n + 1) :: (zeckendorf (n + 1 - fib (greatestFib (n + 1))) ++ [0]))

Next tactic:
refine (isZeckendorfRep_zeckendorf _).cons' (fun a ha ↦ ?_)
lemma isZeckendorfRep_zeckendorf : ∀ n, (zeckendorf n).IsZeckendorfRep
  | 0 => Chain.nil
  | n + 1 => by
    rw [zeckendorf_succ, IsZeckendorfRep, List.cons_append]
    have := zeckendorf_aux n.succ_pos
    refine (isZeckendorfRep_zeckendorf _).cons' (fun a ha ↦ ?_)
    

Proof state:
l : List ℕ
a✝ m n✝ n : ℕ
this : succ n - fib (greatestFib (succ n)) < succ n
a : ℕ
ha : a ∈ head? (zeckendorf (n + 1 - fib (greatestFib (n + 1))) ++ [0])
⊢ a + 2 ≤ greatestFib (n + 1)

Next tactic:
obtain h | h := eq_zero_or_pos (n + 1 - fib (greatestFib (n + 1)))
lemma isZeckendorfRep_zeckendorf : ∀ n, (zeckendorf n).IsZeckendorfRep
  | 0 => Chain.nil
  | n + 1 => by
    rw [zeckendorf_succ, IsZeckendorfRep, List.cons_append]
    have := zeckendorf_aux n.succ_pos
    refine (isZeckendorfRep_zeckendorf _).cons' (fun a ha ↦ ?_)
    obtain h | h := eq_zero_or_pos (n + 1 - fib (greatestFib (n + 1)))
    · 

Proof state:
case inl
l : List ℕ
a✝ m n✝ n : ℕ
this : succ n - fib (greatestFib (succ n)) < succ n
a : ℕ
ha : a ∈ head? (zeckendorf (n + 1 - fib (greatestFib (n + 1))) ++ [0])
h : n + 1 - fib (greatestFib (n + 1)) = 0
⊢ a + 2 ≤ greatestFib (n + 1)

Next tactic:
simp only [h, zeckendorf_zero, nil_append, head?_cons, Option.mem_some_iff] at ha
lemma isZeckendorfRep_zeckendorf : ∀ n, (zeckendorf n).IsZeckendorfRep
  | 0 => Chain.nil
  | n + 1 => by
    rw [zeckendorf_succ, IsZeckendorfRep, List.cons_append]
    have := zeckendorf_aux n.succ_pos
    refine (isZeckendorfRep_zeckendorf _).cons' (fun a ha ↦ ?_)
    obtain h | h := eq_zero_or_pos (n + 1 - fib (greatestFib (n + 1)))
    · simp only [h, zeckendorf_zero, nil_append, head?_cons, Option.mem_some_iff] at ha
      

Proof state:
case inl
l : List ℕ
a✝ m n✝ n : ℕ
this : succ n - fib (greatestFib (succ n)) < succ n
a : ℕ
h : n + 1 - fib (greatestFib (n + 1)) = 0
ha : 0 = a
⊢ a + 2 ≤ greatestFib (n + 1)

Next tactic:
subst ha
lemma isZeckendorfRep_zeckendorf : ∀ n, (zeckendorf n).IsZeckendorfRep
  | 0 => Chain.nil
  | n + 1 => by
    rw [zeckendorf_succ, IsZeckendorfRep, List.cons_append]
    have := zeckendorf_aux n.succ_pos
    refine (isZeckendorfRep_zeckendorf _).cons' (fun a ha ↦ ?_)
    obtain h | h := eq_zero_or_pos (n + 1 - fib (greatestFib (n + 1)))
    · simp only [h, zeckendorf_zero, nil_append, head?_cons, Option.mem_some_iff] at ha
      subst ha
      

Proof state:
case inl
l : List ℕ
a m n✝ n : ℕ
this : succ n - fib (greatestFib (succ n)) < succ n
h : n + 1 - fib (greatestFib (n + 1)) = 0
⊢ 0 + 2 ≤ greatestFib (n + 1)

Next tactic:
exact le_greatestFib.2 le_add_self
lemma isZeckendorfRep_zeckendorf : ∀ n, (zeckendorf n).IsZeckendorfRep
  | 0 => Chain.nil
  | n + 1 => by
    rw [zeckendorf_succ, IsZeckendorfRep, List.cons_append]
    have := zeckendorf_aux n.succ_pos
    refine (isZeckendorfRep_zeckendorf _).cons' (fun a ha ↦ ?_)
    obtain h | h := eq_zero_or_pos (n + 1 - fib (greatestFib (n + 1)))
    · simp only [h, zeckendorf_zero, nil_append, head?_cons, Option.mem_some_iff] at ha
      subst ha
      exact le_greatestFib.2 le_add_self
    

Proof state:
case inr
l : List ℕ
a✝ m n✝ n : ℕ
this : succ n - fib (greatestFib (succ n)) < succ n
a : ℕ
ha : a ∈ head? (zeckendorf (n + 1 - fib (greatestFib (n + 1))) ++ [0])
h : n + 1 - fib (greatestFib (n + 1)) > 0
⊢ a + 2 ≤ greatestFib (n + 1)

Next tactic:
rw [zeckendorf_of_pos h, cons_append, head?_cons, Option.mem_some_iff] at ha
lemma isZeckendorfRep_zeckendorf : ∀ n, (zeckendorf n).IsZeckendorfRep
  | 0 => Chain.nil
  | n + 1 => by
    rw [zeckendorf_succ, IsZeckendorfRep, List.cons_append]
    have := zeckendorf_aux n.succ_pos
    refine (isZeckendorfRep_zeckendorf _).cons' (fun a ha ↦ ?_)
    obtain h | h := eq_zero_or_pos (n + 1 - fib (greatestFib (n + 1)))
    · simp only [h, zeckendorf_zero, nil_append, head?_cons, Option.mem_some_iff] at ha
      subst ha
      exact le_greatestFib.2 le_add_self
    rw [zeckendorf_of_pos h, cons_append, head?_cons, Option.mem_some_iff] at ha
    

Proof state:
case inr
l : List ℕ
a✝ m n✝ n : ℕ
this : succ n - fib (greatestFib (succ n)) < succ n
a : ℕ
ha : greatestFib (n + 1 - fib (greatestFib (n + 1))) = a
h : n + 1 - fib (greatestFib (n + 1)) > 0
⊢ a + 2 ≤ greatestFib (n + 1)

Next tactic:
subst a
lemma isZeckendorfRep_zeckendorf : ∀ n, (zeckendorf n).IsZeckendorfRep
  | 0 => Chain.nil
  | n + 1 => by
    rw [zeckendorf_succ, IsZeckendorfRep, List.cons_append]
    have := zeckendorf_aux n.succ_pos
    refine (isZeckendorfRep_zeckendorf _).cons' (fun a ha ↦ ?_)
    obtain h | h := eq_zero_or_pos (n + 1 - fib (greatestFib (n + 1)))
    · simp only [h, zeckendorf_zero, nil_append, head?_cons, Option.mem_some_iff] at ha
      subst ha
      exact le_greatestFib.2 le_add_self
    rw [zeckendorf_of_pos h, cons_append, head?_cons, Option.mem_some_iff] at ha
    subst a
    

Proof state:
case inr
l : List ℕ
a m n✝ n : ℕ
this : succ n - fib (greatestFib (succ n)) < succ n
h : n + 1 - fib (greatestFib (n + 1)) > 0
⊢ greatestFib (n + 1 - fib (greatestFib (n + 1))) + 2 ≤ greatestFib (n + 1)

Next tactic:
exact add_le_of_le_tsub_right_of_le (le_greatestFib.2 le_add_self)
      (greatestFib_sub_fib_greatestFib_le_greatestFib n.succ_ne_zero)
lemma zeckendorf_sum_fib : ∀ {l}, IsZeckendorfRep l → zeckendorf (l.map fib).sum = l
  | [], _ => rfl
  | a :: l, hl => by
    

Proof state:
l✝ : List ℕ
a✝ m n a : ℕ
l : List ℕ
hl : IsZeckendorfRep (a :: l)
⊢ zeckendorf (sum (map fib (a :: l))) = a :: l

Next tactic:
have hl' := hl
lemma zeckendorf_sum_fib : ∀ {l}, IsZeckendorfRep l → zeckendorf (l.map fib).sum = l
  | [], _ => rfl
  | a :: l, hl => by
    have hl' := hl
    

Proof state:
l✝ : List ℕ
a✝ m n a : ℕ
l : List ℕ
hl hl' : IsZeckendorfRep (a :: l)
⊢ zeckendorf (sum (map fib (a :: l))) = a :: l

Next tactic:
simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons, mem_append,
      mem_singleton, or_imp, forall_and, forall_eq, zero_add] at hl
lemma zeckendorf_sum_fib : ∀ {l}, IsZeckendorfRep l → zeckendorf (l.map fib).sum = l
  | [], _ => rfl
  | a :: l, hl => by
    have hl' := hl
    simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons, mem_append,
      mem_singleton, or_imp, forall_and, forall_eq, zero_add] at hl
    

Proof state:
l✝ : List ℕ
a✝ m n a : ℕ
l : List ℕ
hl' : IsZeckendorfRep (a :: l)
hl : ((∀ x ∈ l, x + 2 ≤ a) ∧ 2 ≤ a) ∧ List.Pairwise (fun a b => b + 2 ≤ a) (l ++ [0])
⊢ zeckendorf (sum (map fib (a :: l))) = a :: l

Next tactic:
rw [← chain'_iff_pairwise] at hl
lemma zeckendorf_sum_fib : ∀ {l}, IsZeckendorfRep l → zeckendorf (l.map fib).sum = l
  | [], _ => rfl
  | a :: l, hl => by
    have hl' := hl
    simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons, mem_append,
      mem_singleton, or_imp, forall_and, forall_eq, zero_add] at hl
    rw [← chain'_iff_pairwise] at hl
    

Proof state:
l✝ : List ℕ
a✝ m n a : ℕ
l : List ℕ
hl' : IsZeckendorfRep (a :: l)
hl : ((∀ x ∈ l, x + 2 ≤ a) ∧ 2 ≤ a) ∧ Chain' (fun a b => b + 2 ≤ a) (l ++ [0])
⊢ zeckendorf (sum (map fib (a :: l))) = a :: l

Next tactic:
have ha : 0 < a := hl.1.2.trans_lt' zero_lt_two
lemma zeckendorf_sum_fib : ∀ {l}, IsZeckendorfRep l → zeckendorf (l.map fib).sum = l
  | [], _ => rfl
  | a :: l, hl => by
    have hl' := hl
    simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons, mem_append,
      mem_singleton, or_imp, forall_and, forall_eq, zero_add] at hl
    rw [← chain'_iff_pairwise] at hl
    have ha : 0 < a := hl.1.2.trans_lt' zero_lt_two
    

Proof state:
l✝ : List ℕ
a✝ m n a : ℕ
l : List ℕ
hl' : IsZeckendorfRep (a :: l)
hl : ((∀ x ∈ l, x + 2 ≤ a) ∧ 2 ≤ a) ∧ Chain' (fun a b => b + 2 ≤ a) (l ++ [0])
ha : 0 < a
⊢ zeckendorf (sum (map fib (a :: l))) = a :: l

Next tactic:
suffices h : greatestFib (fib a + sum (map fib l)) = a
lemma zeckendorf_sum_fib : ∀ {l}, IsZeckendorfRep l → zeckendorf (l.map fib).sum = l
  | [], _ => rfl
  | a :: l, hl => by
    have hl' := hl
    simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons, mem_append,
      mem_singleton, or_imp, forall_and, forall_eq, zero_add] at hl
    rw [← chain'_iff_pairwise] at hl
    have ha : 0 < a := hl.1.2.trans_lt' zero_lt_two
    suffices h : greatestFib (fib a + sum (map fib l)) = a
    · 

Proof state:
l✝ : List ℕ
a✝ m n a : ℕ
l : List ℕ
hl' : IsZeckendorfRep (a :: l)
hl : ((∀ x ∈ l, x + 2 ≤ a) ∧ 2 ≤ a) ∧ Chain' (fun a b => b + 2 ≤ a) (l ++ [0])
ha : 0 < a
h : greatestFib (fib a + sum (map fib l)) = a
⊢ zeckendorf (sum (map fib (a :: l))) = a :: l

Next tactic:
simp only [map, List.sum_cons, add_pos_iff, fib_pos.2 ha, true_or, zeckendorf_of_pos, h,
      add_tsub_cancel_left, zeckendorf_sum_fib hl.2]
lemma zeckendorf_sum_fib : ∀ {l}, IsZeckendorfRep l → zeckendorf (l.map fib).sum = l
  | [], _ => rfl
  | a :: l, hl => by
    have hl' := hl
    simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons, mem_append,
      mem_singleton, or_imp, forall_and, forall_eq, zero_add] at hl
    rw [← chain'_iff_pairwise] at hl
    have ha : 0 < a := hl.1.2.trans_lt' zero_lt_two
    suffices h : greatestFib (fib a + sum (map fib l)) = a
    · simp only [map, List.sum_cons, add_pos_iff, fib_pos.2 ha, true_or, zeckendorf_of_pos, h,
      add_tsub_cancel_left, zeckendorf_sum_fib hl.2]
    

Proof state:
case h
l✝ : List ℕ
a✝ m n a : ℕ
l : List ℕ
hl' : IsZeckendorfRep (a :: l)
hl : ((∀ x ∈ l, x + 2 ≤ a) ∧ 2 ≤ a) ∧ Chain' (fun a b => b + 2 ≤ a) (l ++ [0])
ha : 0 < a
⊢ greatestFib (fib a + sum (map fib l)) = a

Next tactic:
simp only [add_comm, add_assoc, greatestFib, findGreatest_eq_iff, ne_eq, ha.ne',
      not_false_eq_true, le_add_iff_nonneg_left, _root_.zero_le, forall_true_left, not_le, true_and]
lemma zeckendorf_sum_fib : ∀ {l}, IsZeckendorfRep l → zeckendorf (l.map fib).sum = l
  | [], _ => rfl
  | a :: l, hl => by
    have hl' := hl
    simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons, mem_append,
      mem_singleton, or_imp, forall_and, forall_eq, zero_add] at hl
    rw [← chain'_iff_pairwise] at hl
    have ha : 0 < a := hl.1.2.trans_lt' zero_lt_two
    suffices h : greatestFib (fib a + sum (map fib l)) = a
    · simp only [map, List.sum_cons, add_pos_iff, fib_pos.2 ha, true_or, zeckendorf_of_pos, h,
      add_tsub_cancel_left, zeckendorf_sum_fib hl.2]
    simp only [add_comm, add_assoc, greatestFib, findGreatest_eq_iff, ne_eq, ha.ne',
      not_false_eq_true, le_add_iff_nonneg_left, _root_.zero_le, forall_true_left, not_le, true_and]
    

Proof state:
case h
l✝ : List ℕ
a✝ m n a : ℕ
l : List ℕ
hl' : IsZeckendorfRep (a :: l)
hl : ((∀ x ∈ l, x + 2 ≤ a) ∧ 2 ≤ a) ∧ Chain' (fun a b => b + 2 ≤ a) (l ++ [0])
ha : 0 < a
⊢ a ≤ sum (map fib l) + (fib a + 1) ∧
    ∀ ⦃n : ℕ⦄, a < n → n ≤ sum (map fib l) + (fib a + 1) → sum (map fib l) + fib a < fib n

Next tactic:
refine ⟨le_add_of_le_right $ le_fib_add_one _, fun n hn _ ↦ ?_⟩