Theorem: FirstOrder.Language.Term.listDecode_encode_list
File: Mathlib/ModelTheory/Encoding.lean

tactic: intro t
state_before: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l : List (L.Term α)
⊢ ∀ (t : L.Term α) (l : List (α ⊕ (i : ℕ) × L.Functions i)), listDecode (t.listEncode ++ l) = some t :: listDecode l
state_after: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l : List (L.Term α)
t : L.Term α
⊢ ∀ (l : List (α ⊕ (i : ℕ) × L.Functions i)), listDecode (t.listEncode ++ l) = some t :: listDecode l

tactic: induction' t with a n f ts ih <;> intro l
state_before: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l : List (L.Term α)
t : L.Term α
⊢ ∀ (l : List (α ⊕ (i : ℕ) × L.Functions i)), listDecode (t.listEncode ++ l) = some t :: listDecode l
state_after: case var
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
a : α
l : List (α ⊕ (i : ℕ) × L.Functions i)
⊢ listDecode ((var a).listEncode ++ l) = some (var a) :: listDecode l

case func
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
⊢ listDecode ((func f ts).listEncode ++ l) = some (func f ts) :: listDecode l

tactic: induction' l with t l lih
state_before: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l : List (L.Term α)
h : ∀ (t : L.Term α) (l : List (α ⊕ (i : ℕ) × L.Functions i)), listDecode (t.listEncode ++ l) = some t :: listDecode l
⊢ listDecode (l.bind listEncode) = List.map some l
state_after: case nil
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
h : ∀ (t : L.Term α) (l : List (α ⊕ (i : ℕ) × L.Functions i)), listDecode (t.listEncode ++ l) = some t :: listDecode l
⊢ listDecode ([].bind listEncode) = List.map some []

case cons
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
h : ∀ (t : L.Term α) (l : List (α ⊕ (i : ℕ) × L.Functions i)), listDecode (t.listEncode ++ l) = some t :: listDecode l
t : L.Term α
l : List (L.Term α)
lih : listDecode (l.bind listEncode) = List.map some l
⊢ listDecode ((t :: l).bind listEncode) = List.map some (t :: l)

tactic: rfl
state_before: case nil
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
h : ∀ (t : L.Term α) (l : List (α ⊕ (i : ℕ) × L.Functions i)), listDecode (t.listEncode ++ l) = some t :: listDecode l
⊢ listDecode ([].bind listEncode) = List.map some []
state_after: no goals

tactic: rw [bind_cons, h t (l.bind listEncode), lih, List.map]
state_before: case cons
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
h : ∀ (t : L.Term α) (l : List (α ⊕ (i : ℕ) × L.Functions i)), listDecode (t.listEncode ++ l) = some t :: listDecode l
t : L.Term α
l : List (L.Term α)
lih : listDecode (l.bind listEncode) = List.map some l
⊢ listDecode ((t :: l).bind listEncode) = List.map some (t :: l)
state_after: no goals

tactic: rw [listEncode, singleton_append, listDecode]
state_before: case var
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
a : α
l : List (α ⊕ (i : ℕ) × L.Functions i)
⊢ listDecode ((var a).listEncode ++ l) = some (var a) :: listDecode l
state_after: no goals

tactic: rw [listEncode, cons_append, listDecode]
state_before: case func
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
⊢ listDecode ((func f ts).listEncode ++ l) = some (func f ts) :: listDecode l
state_after: case func
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
⊢ (if h :
        ∀ (i : Fin n),
          ((listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)).get? ↑i).join.isSome = true then
      some (func f fun i => ((listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)).get? ↑i).join.get ⋯) ::
        drop n (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))
    else [none]) =
    some (func f ts) :: listDecode l

tactic: refine (dif_pos fun i => Option.isSome_iff_exists.2 ⟨ts i, ?_⟩).trans ?_
state_before: case func
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
h' : ∀ (i : Fin n), (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))
⊢ (if h :
        ∀ (i : Fin n),
          ((listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)).get? ↑i).join.isSome = true then
      some (func f fun i => ((listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)).get? ↑i).join.get ⋯) ::
        drop n (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))
    else [none]) =
    some (func f ts) :: listDecode l
state_after: case func.refine_1
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
h' : ∀ (i : Fin n), (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))
i : Fin n
⊢ ((listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)).get? ↑i).join = some (ts i)

case func.refine_2
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
h' : ∀ (i : Fin n), (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))
⊢ some (func f fun i => ((listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)).get? ↑i).join.get ⋯) ::
      drop n (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)) =
    some (func f ts) :: listDecode l

tactic: refine congr (congr rfl (congr rfl (congr rfl (funext fun i => Option.get_of_mem _ ?_)))) ?_
state_before: case func.refine_2
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
h' : ∀ (i : Fin n), (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))
⊢ some (func f fun i => ((listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)).get? ↑i).join.get ⋯) ::
      drop n (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)) =
    some (func f ts) :: listDecode l
state_after: case func.refine_2.refine_1
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
h' : ∀ (i : Fin n), (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))
i : Fin n
⊢ ts i ∈ ((listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)).get? ↑i).join

case func.refine_2.refine_2
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
h' : ∀ (i : Fin n), (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))
⊢ drop n (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)) = listDecode l

tactic: induction' finRange n with i l' l'ih
state_before: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
⊢ listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
state_after: case nil
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
⊢ listDecode (([].bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) [] ++ listDecode l

case cons
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
i : Fin n
l' : List (Fin n)
l'ih : listDecode ((l'.bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) l' ++ listDecode l
⊢ listDecode (((i :: l').bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (i :: l') ++ listDecode l

tactic: rfl
state_before: case nil
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
⊢ listDecode (([].bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) [] ++ listDecode l
state_after: no goals

tactic: rw [bind_cons, List.append_assoc, ih, map_cons, l'ih, cons_append, Function.comp]
state_before: case cons
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
i : Fin n
l' : List (Fin n)
l'ih : listDecode ((l'.bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) l' ++ listDecode l
⊢ listDecode (((i :: l').bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (i :: l') ++ listDecode l
state_after: no goals

tactic: intro i
state_before: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
⊢ ∀ (i : Fin n), (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))
state_after: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
i : Fin n
⊢ (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))

tactic: rw [h, getElem?_append, getElem?_map]
state_before: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
i : Fin n
⊢ (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))
state_after: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
i : Fin n
⊢ Option.map (some ∘ ts) (finRange n)[↑i]? = some (some (ts i))

L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
i : Fin n
⊢ ↑i < (List.map (some ∘ ts) (finRange n)).length

tactic: simp only [Option.map_eq_some', Function.comp_apply, getElem?_eq_some]
state_before: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
i : Fin n
⊢ Option.map (some ∘ ts) (finRange n)[↑i]? = some (some (ts i))
state_after: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
i : Fin n
⊢ ∃ a, (∃ (h : ↑i < (finRange n).length), (finRange n)[↑i] = a) ∧ some (ts a) = some (ts i)

tactic: refine ⟨i, ⟨lt_of_lt_of_le i.2 (ge_of_eq (length_finRange _)), ?_⟩, rfl⟩
state_before: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
i : Fin n
⊢ ∃ a, (∃ (h : ↑i < (finRange n).length), (finRange n)[↑i] = a) ∧ some (ts a) = some (ts i)
state_after: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
i : Fin n
⊢ (finRange n)[↑i] = i

tactic: rw [getElem_finRange, Fin.eta]
state_before: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
i : Fin n
⊢ (finRange n)[↑i] = i
state_after: no goals

tactic: refine lt_of_lt_of_le i.2 ?_
state_before: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
i : Fin n
⊢ ↑i < (List.map (some ∘ ts) (finRange n)).length
state_after: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
i : Fin n
⊢ n ≤ (List.map (some ∘ ts) (finRange n)).length

tactic: simp
state_before: L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
i : Fin n
⊢ n ≤ (List.map (some ∘ ts) (finRange n)).length
state_after: no goals

tactic: rw [get?_eq_getElem?, Option.join_eq_some, h']
state_before: case func.refine_1
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
h' : ∀ (i : Fin n), (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))
i : Fin n
⊢ ((listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)).get? ↑i).join = some (ts i)
state_after: no goals

tactic: simp [h']
state_before: case func.refine_2.refine_1
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
h' : ∀ (i : Fin n), (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))
i : Fin n
⊢ ts i ∈ ((listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)).get? ↑i).join
state_after: no goals

tactic: rw [h, drop_left']
state_before: case func.refine_2.refine_2
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
h' : ∀ (i : Fin n), (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))
⊢ drop n (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l)) = listDecode l
state_after: case func.refine_2.refine_2
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
h' : ∀ (i : Fin n), (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))
⊢ (List.map (some ∘ ts) (finRange n)).length = n

tactic: rw [length_map, length_finRange]
state_before: case func.refine_2.refine_2
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : L.Structure M
inst✝¹ : L.Structure N
inst✝ : L.Structure P
α : Type u'
β : Type v'
l✝ : List (L.Term α)
n : ℕ
f : L.Functions n
ts : Fin n → L.Term α
ih :
  ∀ (a : Fin n) (l : List (α ⊕ (i : ℕ) × L.Functions i)),
    listDecode ((ts a).listEncode ++ l) = some (ts a) :: listDecode l
l : List (α ⊕ (i : ℕ) × L.Functions i)
h : listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l) = List.map (some ∘ ts) (finRange n) ++ listDecode l
h' : ∀ (i : Fin n), (listDecode (((finRange n).bind fun i => (ts i).listEncode) ++ l))[↑i]? = some (some (ts i))
⊢ (List.map (some ∘ ts) (finRange n)).length = n
state_after: no goals