@[simp]
theorem listDecode_encode_list (l : List (Σn, L.BoundedFormula α n)) :
    (listDecode (l.bind fun φ => φ.2.listEncode)).1 = l.headI := by
  suffices h : ∀ (φ : Σn, L.BoundedFormula α n) (l),
      (listDecode (listEncode φ.2 ++ l)).1 = φ ∧ (listDecode (listEncode φ.2 ++ l)).2.1 = l
  · induction' l with φ l _
    · rw [List.nil_bind]
      simp [listDecode]
    · rw [cons_bind, (h φ _).1, headI_cons]
  · rintro ⟨n, φ⟩
    induction' φ with _ _ _ _ φ_n φ_l φ_R ts _ _ _ ih1 ih2 _ _ ih <;> intro l
    · rw [listEncode, singleton_append, listDecode]
      simp only [eq_self_iff_true, heq_iff_eq, and_self_iff]
    · rw [listEncode, cons_append, cons_append, listDecode, dif_pos]
      · simp only [eq_mp_eq_cast, cast_eq, eq_self_iff_true, heq_iff_eq, and_self_iff, nil_append]
      · simp only [eq_self_iff_true, heq_iff_eq, and_self_iff]
    · rw [listEncode, cons_append, cons_append, singleton_append, cons_append, listDecode]
      · have h : ∀ i : Fin φ_l, ((List.map Sum.getLeft? (List.map (fun i : Fin φ_l =>
          Sum.inl (⟨(⟨φ_n, rel φ_R ts⟩ : Σn, L.BoundedFormula α n).fst, ts i⟩ :
            Σn, L.Term (Sum α (Fin n)))) (finRange φ_l) ++ l)).get? ↑i).join = some ⟨_, ts i⟩ := by
          intro i
          simp only [Option.join, map_append, map_map, Option.bind_eq_some, id.def, exists_eq_right,
            get?_eq_some, length_append, length_map, length_finRange]
          refine' ⟨lt_of_lt_of_le i.2 le_self_add, _⟩
          rw [get_append, get_map]
          · simp only [Sum.getLeft?, get_finRange, Fin.eta, Function.comp_apply, eq_self_iff_true,
              heq_iff_eq, and_self_iff]
          · simp only [length_map, length_finRange, is_lt]
        rw [dif_pos]
        swap
        · exact fun i => Option.isSome_iff_exists.2 ⟨⟨_, ts i⟩, h i⟩
        rw [dif_pos]
        swap
        · intro i
          obtain ⟨h1, h2⟩ := Option.eq_some_iff_get_eq.1 (h i)
          rw [h2]
        

Proof state:
case h.mk.rel
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
l✝ : List ((n : ℕ) × BoundedFormula L α n)
n φ_n φ_l : ℕ
φ_R : Relations L φ_l
ts : Fin φ_l → Term L (α ⊕ Fin φ_n)
l : List ((k : ℕ) × Term L (α ⊕ Fin k) ⊕ (n : ℕ) × Relations L n ⊕ ℕ)
h :
  ∀ (i : Fin φ_l),
    Option.join
        (get?
          (List.map Sum.getLeft?
            (List.map (fun i => Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i }) (finRange φ_l) ++
              l))
          ↑i) =
      some { fst := φ_n, snd := ts i }
⊢ ({ fst := { fst := φ_n, snd := rel φ_R ts }.fst,
            snd :=
              rel φ_R fun i =>
                Eq.mp
                  (_ :
                    Term L
                        (α ⊕
                          Fin
                            (Option.get
                                (Option.join
                                  (get?
                                    (List.map Sum.getLeft?
                                      (List.map
                                          (fun i =>
                                            Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                                          (finRange φ_l) ++
                                        l))
                                    ↑i))
                                (_ :
                                  Option.isSome
                                      (Option.join
                                        (get?
                                          (List.map Sum.getLeft?
                                            (List.map
                                                (fun i =>
                                                  Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                                                (finRange φ_l) ++
                                              l))
                                          ↑i)) =
                                    true)).fst) =
                      Term L (α ⊕ Fin { fst := φ_n, snd := rel φ_R ts }.fst))
                  (Option.get
                      (Option.join
                        (get?
                          (List.map Sum.getLeft?
                            (List.map (fun i => Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                                (finRange φ_l) ++
                              l))
                          ↑i))
                      (_ :
                        Option.isSome
                            (Option.join
                              (get?
                                (List.map Sum.getLeft?
                                  (List.map
                                      (fun i => Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                                      (finRange φ_l) ++
                                    l))
                                ↑i)) =
                          true)).snd },
          {
            val :=
              drop φ_l
                (List.map (fun i => Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                    (finRange φ_l) ++
                  l),
            property :=
              (_ :
                sizeOf
                    (drop φ_l
                      (List.map (fun i => Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                          (finRange φ_l) ++
                        l)) ≤
                  max 1
                    (sizeOf
                      (Sum.inr (Sum.inl { fst := φ_l, snd := φ_R }) ::
                        Sum.inr (Sum.inr { fst := φ_n, snd := rel φ_R ts }.fst) ::
                          (List.map (fun i => Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                              (finRange φ_l) ++
                            l)))) }).1 =
      { fst := φ_n, snd := rel φ_R ts } ∧
    ↑({ fst := { fst := φ_n, snd := rel φ_R ts }.fst,
              snd :=
                rel φ_R fun i =>
                  Eq.mp
                    (_ :
                      Term L
                          (α ⊕
                            Fin
                              (Option.get
                                  (Option.join
                                    (get?
                                      (List.map Sum.getLeft?
                                        (List.map
                                            (fun i =>
                                              Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                                            (finRange φ_l) ++
                                          l))
                                      ↑i))
                                  (_ :
                                    Option.isSome
                                        (Option.join
                                          (get?
                                            (List.map Sum.getLeft?
                                              (List.map
                                                  (fun i =>
                                                    Sum.inl
                                                      { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                                                  (finRange φ_l) ++
                                                l))
                                            ↑i)) =
                                      true)).fst) =
                        Term L (α ⊕ Fin { fst := φ_n, snd := rel φ_R ts }.fst))
                    (Option.get
                        (Option.join
                          (get?
                            (List.map Sum.getLeft?
                              (List.map (fun i => Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                                  (finRange φ_l) ++
                                l))
                            ↑i))
                        (_ :
                          Option.isSome
                              (Option.join
                                (get?
                                  (List.map Sum.getLeft?
                                    (List.map
                                        (fun i => Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                                        (finRange φ_l) ++
                                      l))
                                  ↑i)) =
                            true)).snd },
            {
              val :=
                drop φ_l
                  (List.map (fun i => Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                      (finRange φ_l) ++
                    l),
              property :=
                (_ :
                  sizeOf
                      (drop φ_l
                        (List.map (fun i => Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                            (finRange φ_l) ++
                          l)) ≤
                    max 1
                      (sizeOf
                        (Sum.inr (Sum.inl { fst := φ_l, snd := φ_R }) ::
                          Sum.inr (Sum.inr { fst := φ_n, snd := rel φ_R ts }.fst) ::
                            (List.map (fun i => Sum.inl { fst := { fst := φ_n, snd := rel φ_R ts }.fst, snd := ts i })
                                (finRange φ_l) ++
                              l)))) }).2 =
      l

Next tactic:
simp only [Sigma.mk.inj_iff, heq_eq_eq, rel.injEq, true_and]