l3lab/ntp-mathlib huggingface dataset:
/-- Bijection between compositions of `n` and subsets of `{0, ..., n-2}`, defined by
considering the restriction of the subset to `{1, ..., n-1}` and shifting to the left by one. -/
def compositionAsSetEquiv (n : ℕ) : CompositionAsSet n ≃ Finset (Fin (n - 1))
    where
  toFun c :=
    { i : Fin (n - 1) |
        (⟨1 + (i : ℕ), by
              apply (add_lt_add_left i.is_lt 1).trans_le
              rw [Nat.succ_eq_add_one, add_comm]
              exact add_le_add (Nat.sub_le n 1) (le_refl 1)⟩ :
            Fin n.succ) ∈
          c.boundaries }.toFinset
  invFun s :=
    { boundaries :=
        { i : Fin n.succ |
            i = 0 ∨ i = Fin.last n ∨ ∃ (j : Fin (n - 1)) (_hj : j ∈ s), (i : ℕ) = j + 1 }.toFinset
      zero_mem := by simp
      getLast_mem := by simp }
  left_inv := by
    intro c
    ext i
    simp only [add_comm, Set.toFinset_setOf, Finset.mem_univ,
     forall_true_left, Finset.mem_filter, true_and, exists_prop]
    constructor
    · rintro (rfl | rfl | ⟨j, hj1, hj2⟩)
      · exact c.zero_mem
      · exact c.getLast_mem
      · convert hj1
    · simp only [or_iff_not_imp_left]
      intro i_mem i_ne_zero i_ne_last
      simp? [Fin.ext_iff] at i_ne_zero i_ne_last says
        simp only [Fin.ext_iff, Fin.val_zero, Fin.val_last] at i_ne_zero i_ne_last
      have A : (1 + (i - 1) : ℕ) = (i : ℕ) := by
        rw [add_comm]
        exact Nat.succ_pred_eq_of_pos (pos_iff_ne_zero.mpr i_ne_zero)
      refine' ⟨⟨i - 1, _⟩, _, _⟩
      · have : (i : ℕ) < n + 1 := i.2
        simp? [Nat.lt_succ_iff_lt_or_eq, i_ne_last] at this says
          simp only [Nat.lt_succ_iff_lt_or_eq, i_ne_last, or_false] at this
        exact Nat.pred_lt_pred i_ne_zero this
      · convert i_mem
        simp only [ge_iff_le]
        rwa [add_comm]
      · simp only [ge_iff_le]
        symm
        rwa [add_comm]
  right_inv := by
    intro s
    ext i
    have : 1 + (i : ℕ) ≠ n := by
      apply ne_of_lt
      convert add_lt_add_left i.is_lt 1
      rw [add_comm]
      apply (Nat.succ_pred_eq_of_pos _).symm
      exact (zero_le i.val).trans_lt (i.2.trans_le (Nat.sub_le n 1))
    simp only [add_comm, Fin.ext_iff, Fin.val_zero, Fin.val_last, exists_prop, Set.toFinset_setOf,
      Finset.mem_univ, forall_true_left, Finset.mem_filter, add_eq_zero_iff, and_false,
      add_left_inj, false_or, true_and]
    erw [Set.mem_setOf_eq]
    simp [this, false_or_iff, add_right_inj, add_eq_zero_iff, one_ne_zero, false_and_iff,
      Fin.val_mk]
    constructor
    · intro h
      cases' h with n h
      · rw [add_comm] at this
        contradiction
      · cases' h with w h; cases' h with h₁ h₂
        rw [← Fin.ext_iff] at h₂
        

Proof state:
case a.mp.inr.intro.intro
n✝ n : ℕ
s : Finset (Fin (n - 1))
i : Fin (n - 1)
this : 1 + ↑i ≠ n
w : Fin (n - 1)
h₁ : w ∈ s
h₂ : i = w
⊢ i ∈ s

Next tactic:
rwa [h₂]
/-- Bijection between compositions of `n` and subsets of `{0, ..., n-2}`, defined by
considering the restriction of the subset to `{1, ..., n-1}` and shifting to the left by one. -/
def compositionAsSetEquiv (n : ℕ) : CompositionAsSet n ≃ Finset (Fin (n - 1))
    where
  toFun c :=
    { i : Fin (n - 1) |
        (⟨1 + (i : ℕ), by
              apply (add_lt_add_left i.is_lt 1).trans_le
              rw [Nat.succ_eq_add_one, add_comm]
              exact add_le_add (Nat.sub_le n 1) (le_refl 1)⟩ :
            Fin n.succ) ∈
          c.boundaries }.toFinset
  invFun s :=
    { boundaries :=
        { i : Fin n.succ |
            i = 0 ∨ i = Fin.last n ∨ ∃ (j : Fin (n - 1)) (_hj : j ∈ s), (i : ℕ) = j + 1 }.toFinset
      zero_mem := by simp
      getLast_mem := by simp }
  left_inv := by
    intro c
    ext i
    simp only [add_comm, Set.toFinset_setOf, Finset.mem_univ,
     forall_true_left, Finset.mem_filter, true_and, exists_prop]
    constructor
    · rintro (rfl | rfl | ⟨j, hj1, hj2⟩)
      · exact c.zero_mem
      · exact c.getLast_mem
      · convert hj1
    · simp only [or_iff_not_imp_left]
      intro i_mem i_ne_zero i_ne_last
      simp? [Fin.ext_iff] at i_ne_zero i_ne_last says
        simp only [Fin.ext_iff, Fin.val_zero, Fin.val_last] at i_ne_zero i_ne_last
      have A : (1 + (i - 1) : ℕ) = (i : ℕ) := by
        rw [add_comm]
        exact Nat.succ_pred_eq_of_pos (pos_iff_ne_zero.mpr i_ne_zero)
      refine' ⟨⟨i - 1, _⟩, _, _⟩
      · have : (i : ℕ) < n + 1 := i.2
        simp? [Nat.lt_succ_iff_lt_or_eq, i_ne_last] at this says
          simp only [Nat.lt_succ_iff_lt_or_eq, i_ne_last, or_false] at this
        exact Nat.pred_lt_pred i_ne_zero this
      · convert i_mem
        simp only [ge_iff_le]
        rwa [add_comm]
      · simp only [ge_iff_le]
        symm
        rwa [add_comm]
  right_inv := by
    intro s
    ext i
    have : 1 + (i : ℕ) ≠ n := by
      apply ne_of_lt
      convert add_lt_add_left i.is_lt 1
      rw [add_comm]
      apply (Nat.succ_pred_eq_of_pos _).symm
      exact (zero_le i.val).trans_lt (i.2.trans_le (Nat.sub_le n 1))
    simp only [add_comm, Fin.ext_iff, Fin.val_zero, Fin.val_last, exists_prop, Set.toFinset_setOf,
      Finset.mem_univ, forall_true_left, Finset.mem_filter, add_eq_zero_iff, and_false,
      add_left_inj, false_or, true_and]
    erw [Set.mem_setOf_eq]
    simp [this, false_or_iff, add_right_inj, add_eq_zero_iff, one_ne_zero, false_and_iff,
      Fin.val_mk]
    constructor
    · intro h
      cases' h with n h
      · rw [add_comm] at this
        contradiction
      · cases' h with w h; cases' h with h₁ h₂
        rw [← Fin.ext_iff] at h₂
        rwa [h₂]
    · 

Proof state:
case a.mpr
n✝ n : ℕ
s : Finset (Fin (n - 1))
i : Fin (n - 1)
this : 1 + ↑i ≠ n
⊢ i ∈ s → ↑i + 1 = n ∨ ∃ j ∈ s, ↑i = ↑j

Next tactic:
intro h
/-- Bijection between compositions of `n` and subsets of `{0, ..., n-2}`, defined by
considering the restriction of the subset to `{1, ..., n-1}` and shifting to the left by one. -/
def compositionAsSetEquiv (n : ℕ) : CompositionAsSet n ≃ Finset (Fin (n - 1))
    where
  toFun c :=
    { i : Fin (n - 1) |
        (⟨1 + (i : ℕ), by
              apply (add_lt_add_left i.is_lt 1).trans_le
              rw [Nat.succ_eq_add_one, add_comm]
              exact add_le_add (Nat.sub_le n 1) (le_refl 1)⟩ :
            Fin n.succ) ∈
          c.boundaries }.toFinset
  invFun s :=
    { boundaries :=
        { i : Fin n.succ |
            i = 0 ∨ i = Fin.last n ∨ ∃ (j : Fin (n - 1)) (_hj : j ∈ s), (i : ℕ) = j + 1 }.toFinset
      zero_mem := by simp
      getLast_mem := by simp }
  left_inv := by
    intro c
    ext i
    simp only [add_comm, Set.toFinset_setOf, Finset.mem_univ,
     forall_true_left, Finset.mem_filter, true_and, exists_prop]
    constructor
    · rintro (rfl | rfl | ⟨j, hj1, hj2⟩)
      · exact c.zero_mem
      · exact c.getLast_mem
      · convert hj1
    · simp only [or_iff_not_imp_left]
      intro i_mem i_ne_zero i_ne_last
      simp? [Fin.ext_iff] at i_ne_zero i_ne_last says
        simp only [Fin.ext_iff, Fin.val_zero, Fin.val_last] at i_ne_zero i_ne_last
      have A : (1 + (i - 1) : ℕ) = (i : ℕ) := by
        rw [add_comm]
        exact Nat.succ_pred_eq_of_pos (pos_iff_ne_zero.mpr i_ne_zero)
      refine' ⟨⟨i - 1, _⟩, _, _⟩
      · have : (i : ℕ) < n + 1 := i.2
        simp? [Nat.lt_succ_iff_lt_or_eq, i_ne_last] at this says
          simp only [Nat.lt_succ_iff_lt_or_eq, i_ne_last, or_false] at this
        exact Nat.pred_lt_pred i_ne_zero this
      · convert i_mem
        simp only [ge_iff_le]
        rwa [add_comm]
      · simp only [ge_iff_le]
        symm
        rwa [add_comm]
  right_inv := by
    intro s
    ext i
    have : 1 + (i : ℕ) ≠ n := by
      apply ne_of_lt
      convert add_lt_add_left i.is_lt 1
      rw [add_comm]
      apply (Nat.succ_pred_eq_of_pos _).symm
      exact (zero_le i.val).trans_lt (i.2.trans_le (Nat.sub_le n 1))
    simp only [add_comm, Fin.ext_iff, Fin.val_zero, Fin.val_last, exists_prop, Set.toFinset_setOf,
      Finset.mem_univ, forall_true_left, Finset.mem_filter, add_eq_zero_iff, and_false,
      add_left_inj, false_or, true_and]
    erw [Set.mem_setOf_eq]
    simp [this, false_or_iff, add_right_inj, add_eq_zero_iff, one_ne_zero, false_and_iff,
      Fin.val_mk]
    constructor
    · intro h
      cases' h with n h
      · rw [add_comm] at this
        contradiction
      · cases' h with w h; cases' h with h₁ h₂
        rw [← Fin.ext_iff] at h₂
        rwa [h₂]
    · intro h
      

Proof state:
case a.mpr
n✝ n : ℕ
s : Finset (Fin (n - 1))
i : Fin (n - 1)
this : 1 + ↑i ≠ n
h : i ∈ s
⊢ ↑i + 1 = n ∨ ∃ j ∈ s, ↑i = ↑j

Next tactic:
apply Or.inr
/-- Bijection between compositions of `n` and subsets of `{0, ..., n-2}`, defined by
considering the restriction of the subset to `{1, ..., n-1}` and shifting to the left by one. -/
def compositionAsSetEquiv (n : ℕ) : CompositionAsSet n ≃ Finset (Fin (n - 1))
    where
  toFun c :=
    { i : Fin (n - 1) |
        (⟨1 + (i : ℕ), by
              apply (add_lt_add_left i.is_lt 1).trans_le
              rw [Nat.succ_eq_add_one, add_comm]
              exact add_le_add (Nat.sub_le n 1) (le_refl 1)⟩ :
            Fin n.succ) ∈
          c.boundaries }.toFinset
  invFun s :=
    { boundaries :=
        { i : Fin n.succ |
            i = 0 ∨ i = Fin.last n ∨ ∃ (j : Fin (n - 1)) (_hj : j ∈ s), (i : ℕ) = j + 1 }.toFinset
      zero_mem := by simp
      getLast_mem := by simp }
  left_inv := by
    intro c
    ext i
    simp only [add_comm, Set.toFinset_setOf, Finset.mem_univ,
     forall_true_left, Finset.mem_filter, true_and, exists_prop]
    constructor
    · rintro (rfl | rfl | ⟨j, hj1, hj2⟩)
      · exact c.zero_mem
      · exact c.getLast_mem
      · convert hj1
    · simp only [or_iff_not_imp_left]
      intro i_mem i_ne_zero i_ne_last
      simp? [Fin.ext_iff] at i_ne_zero i_ne_last says
        simp only [Fin.ext_iff, Fin.val_zero, Fin.val_last] at i_ne_zero i_ne_last
      have A : (1 + (i - 1) : ℕ) = (i : ℕ) := by
        rw [add_comm]
        exact Nat.succ_pred_eq_of_pos (pos_iff_ne_zero.mpr i_ne_zero)
      refine' ⟨⟨i - 1, _⟩, _, _⟩
      · have : (i : ℕ) < n + 1 := i.2
        simp? [Nat.lt_succ_iff_lt_or_eq, i_ne_last] at this says
          simp only [Nat.lt_succ_iff_lt_or_eq, i_ne_last, or_false] at this
        exact Nat.pred_lt_pred i_ne_zero this
      · convert i_mem
        simp only [ge_iff_le]
        rwa [add_comm]
      · simp only [ge_iff_le]
        symm
        rwa [add_comm]
  right_inv := by
    intro s
    ext i
    have : 1 + (i : ℕ) ≠ n := by
      apply ne_of_lt
      convert add_lt_add_left i.is_lt 1
      rw [add_comm]
      apply (Nat.succ_pred_eq_of_pos _).symm
      exact (zero_le i.val).trans_lt (i.2.trans_le (Nat.sub_le n 1))
    simp only [add_comm, Fin.ext_iff, Fin.val_zero, Fin.val_last, exists_prop, Set.toFinset_setOf,
      Finset.mem_univ, forall_true_left, Finset.mem_filter, add_eq_zero_iff, and_false,
      add_left_inj, false_or, true_and]
    erw [Set.mem_setOf_eq]
    simp [this, false_or_iff, add_right_inj, add_eq_zero_iff, one_ne_zero, false_and_iff,
      Fin.val_mk]
    constructor
    · intro h
      cases' h with n h
      · rw [add_comm] at this
        contradiction
      · cases' h with w h; cases' h with h₁ h₂
        rw [← Fin.ext_iff] at h₂
        rwa [h₂]
    · intro h
      apply Or.inr
      

Proof state:
case a.mpr.h
n✝ n : ℕ
s : Finset (Fin (n - 1))
i : Fin (n - 1)
this : 1 + ↑i ≠ n
h : i ∈ s
⊢ ∃ j ∈ s, ↑i = ↑j

Next tactic:
use i, h
theorem compositionAsSet_card (n : ℕ) : Fintype.card (CompositionAsSet n) = 2 ^ (n - 1) := by
  

Proof state:
n✝ n : ℕ
⊢ Fintype.card (CompositionAsSet n) = 2 ^ (n - 1)

Next tactic:
have : Fintype.card (Finset (Fin (n - 1))) = 2 ^ (n - 1) := by simp
theorem compositionAsSet_card (n : ℕ) : Fintype.card (CompositionAsSet n) = 2 ^ (n - 1) := by
  have : Fintype.card (Finset (Fin (n - 1))) = 2 ^ (n - 1) := by 

Proof state:
n✝ n : ℕ
⊢ Fintype.card (Finset (Fin (n - 1))) = 2 ^ (n - 1)

Next tactic:
simp
theorem compositionAsSet_card (n : ℕ) : Fintype.card (CompositionAsSet n) = 2 ^ (n - 1) := by
  have : Fintype.card (Finset (Fin (n - 1))) = 2 ^ (n - 1) := by simp
  

Proof state:
n✝ n : ℕ
this : Fintype.card (Finset (Fin (n - 1))) = 2 ^ (n - 1)
⊢ Fintype.card (CompositionAsSet n) = 2 ^ (n - 1)

Next tactic:
rw [← this]
theorem compositionAsSet_card (n : ℕ) : Fintype.card (CompositionAsSet n) = 2 ^ (n - 1) := by
  have : Fintype.card (Finset (Fin (n - 1))) = 2 ^ (n - 1) := by simp
  rw [← this]
  

Proof state:
n✝ n : ℕ
this : Fintype.card (Finset (Fin (n - 1))) = 2 ^ (n - 1)
⊢ Fintype.card (CompositionAsSet n) = Fintype.card (Finset (Fin (n - 1)))

Next tactic:
exact Fintype.card_congr (compositionAsSetEquiv n)
theorem length_lt_card_boundaries : c.length < c.boundaries.card := by
  

Proof state:
n : ℕ
c : CompositionAsSet n
⊢ length c < Finset.card c.boundaries

Next tactic:
rw [c.card_boundaries_eq_succ_length]
theorem length_lt_card_boundaries : c.length < c.boundaries.card := by
  rw [c.card_boundaries_eq_succ_length]
  

Proof state:
n : ℕ
c : CompositionAsSet n
⊢ length c < length c + 1

Next tactic:
exact lt_add_one _
@[simp]
theorem boundary_zero : (c.boundary ⟨0, c.card_boundaries_pos⟩ : Fin (n + 1)) = 0 := by
  

Proof state:
n : ℕ
c : CompositionAsSet n
⊢ (boundary c) { val := 0, isLt := (_ : 0 < Finset.card c.boundaries) } = 0

Next tactic:
rw [boundary, Finset.orderEmbOfFin_zero rfl c.card_boundaries_pos]
@[simp]
theorem boundary_zero : (c.boundary ⟨0, c.card_boundaries_pos⟩ : Fin (n + 1)) = 0 := by
  rw [boundary, Finset.orderEmbOfFin_zero rfl c.card_boundaries_pos]
  

Proof state:
n : ℕ
c : CompositionAsSet n
⊢ Finset.min' c.boundaries (_ : Finset.Nonempty c.boundaries) = 0

Next tactic:
exact le_antisymm (Finset.min'_le _ _ c.zero_mem) (Fin.zero_le _)
@[simp]
theorem boundary_length : c.boundary ⟨c.length, c.length_lt_card_boundaries⟩ = Fin.last n := by
  

Proof state:
n : ℕ
c : CompositionAsSet n
⊢ (boundary c) { val := length c, isLt := (_ : length c < Finset.card c.boundaries) } = Fin.last n

Next tactic:
convert Finset.orderEmbOfFin_last rfl c.card_boundaries_pos
@[simp]
theorem boundary_length : c.boundary ⟨c.length, c.length_lt_card_boundaries⟩ = Fin.last n := by
  convert Finset.orderEmbOfFin_last rfl c.card_boundaries_pos
  

Proof state:
case h.e'_3
n : ℕ
c : CompositionAsSet n
⊢ Fin.last n = Finset.max' c.boundaries (_ : Finset.Nonempty c.boundaries)

Next tactic:
exact le_antisymm (Finset.le_max' _ _ c.getLast_mem) (Fin.le_last _)
theorem blocks_partial_sum {i : ℕ} (h : i < c.boundaries.card) :
    (c.blocks.take i).sum = c.boundary ⟨i, h⟩ := by
  

Proof state:
n : ℕ
c : CompositionAsSet n
i : ℕ
h : i < Finset.card c.boundaries
⊢ sum (take i (blocks c)) = ↑((boundary c) { val := i, isLt := h })

Next tactic:
induction' i with i IH
theorem blocks_partial_sum {i : ℕ} (h : i < c.boundaries.card) :
    (c.blocks.take i).sum = c.boundary ⟨i, h⟩ := by
  induction' i with i IH
  · 

Proof state:
case zero
n : ℕ
c : CompositionAsSet n
h : Nat.zero < Finset.card c.boundaries
⊢ sum (take Nat.zero (blocks c)) = ↑((boundary c) { val := Nat.zero, isLt := h })

Next tactic:
simp
theorem blocks_partial_sum {i : ℕ} (h : i < c.boundaries.card) :
    (c.blocks.take i).sum = c.boundary ⟨i, h⟩ := by
  induction' i with i IH
  · simp
  

Proof state:
case succ
n : ℕ
c : CompositionAsSet n
i : ℕ
IH : ∀ (h : i < Finset.card c.boundaries), sum (take i (blocks c)) = ↑((boundary c) { val := i, isLt := h })
h : Nat.succ i < Finset.card c.boundaries
⊢ sum (take (Nat.succ i) (blocks c)) = ↑((boundary c) { val := Nat.succ i, isLt := h })

Next tactic:
have A : i < c.blocks.length := by
    rw [c.card_boundaries_eq_succ_length] at h
    simp [blocks, Nat.lt_of_succ_lt_succ h]
theorem blocks_partial_sum {i : ℕ} (h : i < c.boundaries.card) :
    (c.blocks.take i).sum = c.boundary ⟨i, h⟩ := by
  induction' i with i IH
  · simp
  have A : i < c.blocks.length := by
    

Proof state:
n : ℕ
c : CompositionAsSet n
i : ℕ
IH : ∀ (h : i < Finset.card c.boundaries), sum (take i (blocks c)) = ↑((boundary c) { val := i, isLt := h })
h : Nat.succ i < Finset.card c.boundaries
⊢ i < List.length (blocks c)

Next tactic:
rw [c.card_boundaries_eq_succ_length] at h
theorem blocks_partial_sum {i : ℕ} (h : i < c.boundaries.card) :
    (c.blocks.take i).sum = c.boundary ⟨i, h⟩ := by
  induction' i with i IH
  · simp
  have A : i < c.blocks.length := by
    rw [c.card_boundaries_eq_succ_length] at h
    

Proof state:
n : ℕ
c : CompositionAsSet n
i : ℕ
IH : ∀ (h : i < Finset.card c.boundaries), sum (take i (blocks c)) = ↑((boundary c) { val := i, isLt := h })
h : Nat.succ i < length c + 1
⊢ i < List.length (blocks c)

Next tactic:
simp [blocks, Nat.lt_of_succ_lt_succ h]
theorem blocks_partial_sum {i : ℕ} (h : i < c.boundaries.card) :
    (c.blocks.take i).sum = c.boundary ⟨i, h⟩ := by
  induction' i with i IH
  · simp
  have A : i < c.blocks.length := by
    rw [c.card_boundaries_eq_succ_length] at h
    simp [blocks, Nat.lt_of_succ_lt_succ h]
  

Proof state:
case succ
n : ℕ
c : CompositionAsSet n
i : ℕ
IH : ∀ (h : i < Finset.card c.boundaries), sum (take i (blocks c)) = ↑((boundary c) { val := i, isLt := h })
h : Nat.succ i < Finset.card c.boundaries
A : i < List.length (blocks c)
⊢ sum (take (Nat.succ i) (blocks c)) = ↑((boundary c) { val := Nat.succ i, isLt := h })

Next tactic:
have B : i < c.boundaries.card := lt_of_lt_of_le A (by simp [blocks, length, Nat.sub_le])
theorem blocks_partial_sum {i : ℕ} (h : i < c.boundaries.card) :
    (c.blocks.take i).sum = c.boundary ⟨i, h⟩ := by
  induction' i with i IH
  · simp
  have A : i < c.blocks.length := by
    rw [c.card_boundaries_eq_succ_length] at h
    simp [blocks, Nat.lt_of_succ_lt_succ h]
  have B : i < c.boundaries.card := lt_of_lt_of_le A (by 

Proof state:
n : ℕ
c : CompositionAsSet n
i : ℕ
IH : ∀ (h : i < Finset.card c.boundaries), sum (take i (blocks c)) = ↑((boundary c) { val := i, isLt := h })
h : Nat.succ i < Finset.card c.boundaries
A : i < List.length (blocks c)
⊢ List.length (blocks c) ≤ Finset.card c.boundaries

Next tactic:
simp [blocks, length, Nat.sub_le]
theorem blocks_partial_sum {i : ℕ} (h : i < c.boundaries.card) :
    (c.blocks.take i).sum = c.boundary ⟨i, h⟩ := by
  induction' i with i IH
  · simp
  have A : i < c.blocks.length := by
    rw [c.card_boundaries_eq_succ_length] at h
    simp [blocks, Nat.lt_of_succ_lt_succ h]
  have B : i < c.boundaries.card := lt_of_lt_of_le A (by simp [blocks, length, Nat.sub_le])
  

Proof state:
case succ
n : ℕ
c : CompositionAsSet n
i : ℕ
IH : ∀ (h : i < Finset.card c.boundaries), sum (take i (blocks c)) = ↑((boundary c) { val := i, isLt := h })
h : Nat.succ i < Finset.card c.boundaries
A : i < List.length (blocks c)
B : i < Finset.card c.boundaries
⊢ sum (take (Nat.succ i) (blocks c)) = ↑((boundary c) { val := Nat.succ i, isLt := h })

Next tactic:
rw [sum_take_succ _ _ A, IH B]
theorem blocks_partial_sum {i : ℕ} (h : i < c.boundaries.card) :
    (c.blocks.take i).sum = c.boundary ⟨i, h⟩ := by
  induction' i with i IH
  · simp
  have A : i < c.blocks.length := by
    rw [c.card_boundaries_eq_succ_length] at h
    simp [blocks, Nat.lt_of_succ_lt_succ h]
  have B : i < c.boundaries.card := lt_of_lt_of_le A (by simp [blocks, length, Nat.sub_le])
  rw [sum_take_succ _ _ A, IH B]
  

Proof state:
case succ
n : ℕ
c : CompositionAsSet n
i : ℕ
IH : ∀ (h : i < Finset.card c.boundaries), sum (take i (blocks c)) = ↑((boundary c) { val := i, isLt := h })
h : Nat.succ i < Finset.card c.boundaries
A : i < List.length (blocks c)
B : i < Finset.card c.boundaries
⊢ ↑((boundary c) { val := i, isLt := B }) + List.get (blocks c) { val := i, isLt := A } =
    ↑((boundary c) { val := Nat.succ i, isLt := h })

Next tactic:
simp [blocks, blocksFun, get_ofFn]
theorem mem_boundaries_iff_exists_blocks_sum_take_eq {j : Fin (n + 1)} :
    j ∈ c.boundaries ↔ ∃ i < c.boundaries.card, (c.blocks.take i).sum = j := by
  

Proof state:
n : ℕ
c : CompositionAsSet n
j : Fin (n + 1)
⊢ j ∈ c.boundaries ↔ ∃ i < Finset.card c.boundaries, sum (take i (blocks c)) = ↑j

Next tactic:
constructor
theorem mem_boundaries_iff_exists_blocks_sum_take_eq {j : Fin (n + 1)} :
    j ∈ c.boundaries ↔ ∃ i < c.boundaries.card, (c.blocks.take i).sum = j := by
  constructor
  · 

Proof state:
case mp
n : ℕ
c : CompositionAsSet n
j : Fin (n + 1)
⊢ j ∈ c.boundaries → ∃ i < Finset.card c.boundaries, sum (take i (blocks c)) = ↑j

Next tactic:
intro hj
theorem mem_boundaries_iff_exists_blocks_sum_take_eq {j : Fin (n + 1)} :
    j ∈ c.boundaries ↔ ∃ i < c.boundaries.card, (c.blocks.take i).sum = j := by
  constructor
  · intro hj
    

Proof state:
case mp
n : ℕ
c : CompositionAsSet n
j : Fin (n + 1)
hj : j ∈ c.boundaries
⊢ ∃ i < Finset.card c.boundaries, sum (take i (blocks c)) = ↑j

Next tactic:
rcases (c.boundaries.orderIsoOfFin rfl).surjective ⟨j, hj⟩ with ⟨i, hi⟩
theorem mem_boundaries_iff_exists_blocks_sum_take_eq {j : Fin (n + 1)} :
    j ∈ c.boundaries ↔ ∃ i < c.boundaries.card, (c.blocks.take i).sum = j := by
  constructor
  · intro hj
    rcases (c.boundaries.orderIsoOfFin rfl).surjective ⟨j, hj⟩ with ⟨i, hi⟩
    

Proof state:
case mp.intro
n : ℕ
c : CompositionAsSet n
j : Fin (n + 1)
hj : j ∈ c.boundaries
i : Fin (Finset.card c.boundaries)
hi :
  (Finset.orderIsoOfFin c.boundaries (_ : Finset.card c.boundaries = Finset.card c.boundaries)) i =
    { val := j, property := hj }
⊢ ∃ i < Finset.card c.boundaries, sum (take i (blocks c)) = ↑j

Next tactic:
rw [Subtype.ext_iff, Subtype.coe_mk] at hi
theorem mem_boundaries_iff_exists_blocks_sum_take_eq {j : Fin (n + 1)} :
    j ∈ c.boundaries ↔ ∃ i < c.boundaries.card, (c.blocks.take i).sum = j := by
  constructor
  · intro hj
    rcases (c.boundaries.orderIsoOfFin rfl).surjective ⟨j, hj⟩ with ⟨i, hi⟩
    rw [Subtype.ext_iff, Subtype.coe_mk] at hi
    

Proof state:
case mp.intro
n : ℕ
c : CompositionAsSet n
j : Fin (n + 1)
hj : j ∈ c.boundaries
i : Fin (Finset.card c.boundaries)
hi :
  ↑((Finset.orderIsoOfFin c.boundaries (_ : Finset.card c.boundaries = Finset.card c.boundaries)) i) =
    ↑{ val := j, property := hj }
⊢ ∃ i < Finset.card c.boundaries, sum (take i (blocks c)) = ↑j

Next tactic:
refine' ⟨i.1, i.2, _⟩
theorem mem_boundaries_iff_exists_blocks_sum_take_eq {j : Fin (n + 1)} :
    j ∈ c.boundaries ↔ ∃ i < c.boundaries.card, (c.blocks.take i).sum = j := by
  constructor
  · intro hj
    rcases (c.boundaries.orderIsoOfFin rfl).surjective ⟨j, hj⟩ with ⟨i, hi⟩
    rw [Subtype.ext_iff, Subtype.coe_mk] at hi
    refine' ⟨i.1, i.2, _⟩
    

Proof state:
case mp.intro
n : ℕ
c : CompositionAsSet n
j : Fin (n + 1)
hj : j ∈ c.boundaries
i : Fin (Finset.card c.boundaries)
hi :
  ↑((Finset.orderIsoOfFin c.boundaries (_ : Finset.card c.boundaries = Finset.card c.boundaries)) i) =
    ↑{ val := j, property := hj }
⊢ sum (take (↑i) (blocks c)) = ↑j

Next tactic:
dsimp at hi
theorem mem_boundaries_iff_exists_blocks_sum_take_eq {j : Fin (n + 1)} :
    j ∈ c.boundaries ↔ ∃ i < c.boundaries.card, (c.blocks.take i).sum = j := by
  constructor
  · intro hj
    rcases (c.boundaries.orderIsoOfFin rfl).surjective ⟨j, hj⟩ with ⟨i, hi⟩
    rw [Subtype.ext_iff, Subtype.coe_mk] at hi
    refine' ⟨i.1, i.2, _⟩
    dsimp at hi
    

Proof state:
case mp.intro
n : ℕ
c : CompositionAsSet n
j : Fin (n + 1)
hj : j ∈ c.boundaries
i : Fin (Finset.card c.boundaries)
hi : (Finset.orderEmbOfFin c.boundaries (_ : Finset.card c.boundaries = Finset.card c.boundaries)) i = j
⊢ sum (take (↑i) (blocks c)) = ↑j

Next tactic:
rw [← hi, c.blocks_partial_sum i.2]
theorem mem_boundaries_iff_exists_blocks_sum_take_eq {j : Fin (n + 1)} :
    j ∈ c.boundaries ↔ ∃ i < c.boundaries.card, (c.blocks.take i).sum = j := by
  constructor
  · intro hj
    rcases (c.boundaries.orderIsoOfFin rfl).surjective ⟨j, hj⟩ with ⟨i, hi⟩
    rw [Subtype.ext_iff, Subtype.coe_mk] at hi
    refine' ⟨i.1, i.2, _⟩
    dsimp at hi
    rw [← hi, c.blocks_partial_sum i.2]
    

Proof state:
case mp.intro
n : ℕ
c : CompositionAsSet n
j : Fin (n + 1)
hj : j ∈ c.boundaries
i : Fin (Finset.card c.boundaries)
hi : (Finset.orderEmbOfFin c.boundaries (_ : Finset.card c.boundaries = Finset.card c.boundaries)) i = j
⊢ ↑((boundary c) { val := ↑i, isLt := (_ : ↑i < Finset.card c.boundaries) }) =
    ↑((Finset.orderEmbOfFin c.boundaries (_ : Finset.card c.boundaries = Finset.card c.boundaries)) i)

Next tactic:
rfl