[GOAL]
⊢ eval zero' = fun v => pure (0 :: v)
[PROOFSTEP]
simp [eval]
[GOAL]
⊢ eval succ = fun v => pure [Nat.succ (List.headI v)]
[PROOFSTEP]
simp [eval]
[GOAL]
⊢ eval tail = fun v => pure (List.tail v)
[PROOFSTEP]
simp [eval]
[GOAL]
f fs : Code
⊢ eval (cons f fs) = fun v => do
    let n ← eval f v
    let ns ← eval fs v
    pure (List.headI n :: ns)
[PROOFSTEP]
simp [eval]
[GOAL]
f g : Code
⊢ eval (comp f g) = fun v => eval g v >>= eval f
[PROOFSTEP]
simp [eval]
[GOAL]
f g : Code
⊢ eval (case f g) = fun v => Nat.rec (eval f (List.tail v)) (fun y x => eval g (y :: List.tail v)) (List.headI v)
[PROOFSTEP]
simp [eval]
[GOAL]
f : Code
⊢ eval (fix f) =
    PFun.fix fun v =>
      Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (eval f v)
[PROOFSTEP]
simp [eval]
[GOAL]
v : List ℕ
⊢ eval nil v = pure []
[PROOFSTEP]
simp [nil]
[GOAL]
v : List ℕ
⊢ eval id v = pure v
[PROOFSTEP]
simp [id]
[GOAL]
v : List ℕ
⊢ eval head v = pure [List.headI v]
[PROOFSTEP]
simp [head]
[GOAL]
v : List ℕ
⊢ eval zero v = pure [0]
[PROOFSTEP]
simp [zero]
[GOAL]
v : List ℕ
⊢ eval pred v = pure [Nat.pred (List.headI v)]
[PROOFSTEP]
simp [pred]
[GOAL]
v : List ℕ
⊢ Nat.rec (Part.some [0]) (fun y x => Part.some [y]) (List.headI v) = Part.some [Nat.pred (List.headI v)]
[PROOFSTEP]
cases v.headI
[GOAL]
case zero
v : List ℕ
⊢ Nat.rec (Part.some [0]) (fun y x => Part.some [y]) Nat.zero = Part.some [Nat.pred Nat.zero]
[PROOFSTEP]
simp
[GOAL]
case succ
v : List ℕ
n✝ : ℕ
⊢ Nat.rec (Part.some [0]) (fun y x => Part.some [y]) (Nat.succ n✝) = Part.some [Nat.pred (Nat.succ n✝)]
[PROOFSTEP]
simp
[GOAL]
m n : ℕ
f : Vector ℕ n →. ℕ
g : Fin n → Vector ℕ m →. ℕ
hf : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> f v
hg : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> ((Vector.mOfFn fun i => g i v) >>= f)
[PROOFSTEP]
rsuffices ⟨cg, hg⟩ : ∃ c : Code, ∀ v : Vector ℕ m, c.eval v.1 = Subtype.val <$> Vector.mOfFn fun i => g i v
[GOAL]
case intro
m n : ℕ
f : Vector ℕ n →. ℕ
g : Fin n → Vector ℕ m →. ℕ
hf : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> f v
hg✝ : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
cg : Code
hg : ∀ (v : Vector ℕ m), eval cg ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> ((Vector.mOfFn fun i => g i v) >>= f)
[PROOFSTEP]
obtain ⟨cf, hf⟩ := hf
[GOAL]
case intro.intro
m n : ℕ
f : Vector ℕ n →. ℕ
g : Fin n → Vector ℕ m →. ℕ
hg✝ : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
cg : Code
hg : ∀ (v : Vector ℕ m), eval cg ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
cf : Code
hf : ∀ (v : Vector ℕ n), eval cf ↑v = pure <$> f v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> ((Vector.mOfFn fun i => g i v) >>= f)
[PROOFSTEP]
exact
  ⟨cf.comp cg, fun v => by
    simp [hg, hf, map_bind, seq_bind_eq, Function.comp]
    rfl⟩
[GOAL]
m n : ℕ
f : Vector ℕ n →. ℕ
g : Fin n → Vector ℕ m →. ℕ
hg✝ : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
cg : Code
hg : ∀ (v : Vector ℕ m), eval cg ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
cf : Code
hf : ∀ (v : Vector ℕ n), eval cf ↑v = pure <$> f v
v : Vector ℕ m
⊢ eval (Code.comp cf cg) ↑v = pure <$> ((Vector.mOfFn fun i => g i v) >>= f)
[PROOFSTEP]
simp [hg, hf, map_bind, seq_bind_eq, Function.comp]
[GOAL]
m n : ℕ
f : Vector ℕ n →. ℕ
g : Fin n → Vector ℕ m →. ℕ
hg✝ : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
cg : Code
hg : ∀ (v : Vector ℕ m), eval cg ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
cf : Code
hf : ∀ (v : Vector ℕ n), eval cf ↑v = pure <$> f v
v : Vector ℕ m
⊢ (do
      let x ← Vector.mOfFn fun i => g i v
      pure <$> f x) =
    do
    let a ← Vector.mOfFn fun i => g i v
    pure <$> f a
[PROOFSTEP]
rfl
[GOAL]
m n : ℕ
f : Vector ℕ n →. ℕ
g : Fin n → Vector ℕ m →. ℕ
hf : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> f v
hg : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
[PROOFSTEP]
clear hf f
[GOAL]
m n : ℕ
g : Fin n → Vector ℕ m →. ℕ
hg : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
[PROOFSTEP]
induction' n with n IH
[GOAL]
case zero
m n : ℕ
g✝ : Fin n → Vector ℕ m →. ℕ
hg✝ : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g✝ i v
g : Fin Nat.zero → Vector ℕ m →. ℕ
hg : ∀ (i : Fin Nat.zero), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
[PROOFSTEP]
exact ⟨nil, fun v => by simp [Vector.mOfFn, Bind.bind]; rfl⟩
[GOAL]
m n : ℕ
g✝ : Fin n → Vector ℕ m →. ℕ
hg✝ : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g✝ i v
g : Fin Nat.zero → Vector ℕ m →. ℕ
hg : ∀ (i : Fin Nat.zero), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
v : Vector ℕ m
⊢ eval nil ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
[PROOFSTEP]
simp [Vector.mOfFn, Bind.bind]
[GOAL]
m n : ℕ
g✝ : Fin n → Vector ℕ m →. ℕ
hg✝ : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g✝ i v
g : Fin Nat.zero → Vector ℕ m →. ℕ
hg : ∀ (i : Fin Nat.zero), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
v : Vector ℕ m
⊢ Part.some [] = Subtype.val <$> Part.some Vector.nil
[PROOFSTEP]
rfl
[GOAL]
case succ
m n✝ : ℕ
g✝ : Fin n✝ → Vector ℕ m →. ℕ
hg✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g✝ i v
n : ℕ
IH :
  ∀ {g : Fin n → Vector ℕ m →. ℕ},
    (∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v) →
      ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
g : Fin (Nat.succ n) → Vector ℕ m →. ℕ
hg : ∀ (i : Fin (Nat.succ n)), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
[PROOFSTEP]
obtain ⟨cg, hg₁⟩ := hg 0
[GOAL]
case succ.intro
m n✝ : ℕ
g✝ : Fin n✝ → Vector ℕ m →. ℕ
hg✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g✝ i v
n : ℕ
IH :
  ∀ {g : Fin n → Vector ℕ m →. ℕ},
    (∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v) →
      ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
g : Fin (Nat.succ n) → Vector ℕ m →. ℕ
hg : ∀ (i : Fin (Nat.succ n)), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
cg : Code
hg₁ : ∀ (v : Vector ℕ m), eval cg ↑v = pure <$> g 0 v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
[PROOFSTEP]
obtain ⟨cl, hl⟩ := IH fun i => hg i.succ
[GOAL]
case succ.intro.intro
m n✝ : ℕ
g✝ : Fin n✝ → Vector ℕ m →. ℕ
hg✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g✝ i v
n : ℕ
IH :
  ∀ {g : Fin n → Vector ℕ m →. ℕ},
    (∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v) →
      ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
g : Fin (Nat.succ n) → Vector ℕ m →. ℕ
hg : ∀ (i : Fin (Nat.succ n)), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
cg : Code
hg₁ : ∀ (v : Vector ℕ m), eval cg ↑v = pure <$> g 0 v
cl : Code
hl : ∀ (v : Vector ℕ m), eval cl ↑v = Subtype.val <$> Vector.mOfFn fun i => g (Fin.succ i) v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
[PROOFSTEP]
exact
  ⟨cons cg cl, fun v => by
    simp [Vector.mOfFn, hg₁, map_bind, seq_bind_eq, bind_assoc, (· ∘ ·), hl]
    rfl⟩
[GOAL]
m n✝ : ℕ
g✝ : Fin n✝ → Vector ℕ m →. ℕ
hg✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g✝ i v
n : ℕ
IH :
  ∀ {g : Fin n → Vector ℕ m →. ℕ},
    (∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v) →
      ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
g : Fin (Nat.succ n) → Vector ℕ m →. ℕ
hg : ∀ (i : Fin (Nat.succ n)), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
cg : Code
hg₁ : ∀ (v : Vector ℕ m), eval cg ↑v = pure <$> g 0 v
cl : Code
hl : ∀ (v : Vector ℕ m), eval cl ↑v = Subtype.val <$> Vector.mOfFn fun i => g (Fin.succ i) v
v : Vector ℕ m
⊢ eval (cons cg cl) ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
[PROOFSTEP]
simp [Vector.mOfFn, hg₁, map_bind, seq_bind_eq, bind_assoc, (· ∘ ·), hl]
[GOAL]
m n✝ : ℕ
g✝ : Fin n✝ → Vector ℕ m →. ℕ
hg✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g✝ i v
n : ℕ
IH :
  ∀ {g : Fin n → Vector ℕ m →. ℕ},
    (∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v) →
      ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = Subtype.val <$> Vector.mOfFn fun i => g i v
g : Fin (Nat.succ n) → Vector ℕ m →. ℕ
hg : ∀ (i : Fin (Nat.succ n)), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
cg : Code
hg₁ : ∀ (v : Vector ℕ m), eval cg ↑v = pure <$> g 0 v
cl : Code
hl : ∀ (v : Vector ℕ m), eval cl ↑v = Subtype.val <$> Vector.mOfFn fun i => g (Fin.succ i) v
v : Vector ℕ m
⊢ (do
      let x ← g 0 v
      let x_1 ← Vector.mOfFn fun i => g (Fin.succ i) v
      Part.some (List.headI (pure x) :: ↑x_1)) =
    do
    let a ← g 0 v
    let a_1 ← Vector.mOfFn fun i => g (Fin.succ i) v
    Subtype.val <$> Part.some (a ::ᵥ a_1)
[PROOFSTEP]
rfl
[GOAL]
n : ℕ
f : Vector ℕ n →. ℕ
hf : Nat.Partrec' f
⊢ ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> f v
[PROOFSTEP]
induction' hf with n f hf
[GOAL]
case prim
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
hf : Nat.Primrec' f
⊢ ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> ↑f v
case comp
n : ℕ
f : Vector ℕ n →. ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
g✝ : Fin n✝ → Vector ℕ m✝ →. ℕ
a✝¹ : Nat.Partrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Partrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> g✝ i v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g✝ i v) >>= f✝) v
case rfind
n : ℕ
f : Vector ℕ n →. ℕ
n✝ : ℕ
f✝ : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f✝
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 1)), eval c ↑v = pure <$> ↑f✝ v
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (fun v => Nat.rfind fun n => Part.some (decide (f✝ (n ::ᵥ v) = 0))) v
[PROOFSTEP]
induction hf
[GOAL]
case prim.zero
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 0), eval c ↑v = pure <$> (↑fun x => 0) v
case prim.succ
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 1), eval c ↑v = pure <$> (↑fun v => Nat.succ (Vector.head v)) v
case prim.get
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
n✝ : ℕ
i✝ : Fin n✝
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (↑fun v => Vector.get v i✝) v
case prim.comp
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Fin n✝ → Vector ℕ m✝ → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Primrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> ↑(g✝ i) v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (↑fun a => f✝ (Vector.ofFn fun i => g✝ i a)) v
case prim.prec
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : Nat.Primrec' g✝
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 2)), eval c ↑v = pure <$> ↑g✝ v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n✝ + 1)),
      eval c ↑v =
        pure <$>
          (↑fun v => Nat.rec (f✝ (Vector.tail v)) (fun y IH => g✝ (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v
case comp
n : ℕ
f : Vector ℕ n →. ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
g✝ : Fin n✝ → Vector ℕ m✝ →. ℕ
a✝¹ : Nat.Partrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Partrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> g✝ i v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g✝ i v) >>= f✝) v
case rfind
n : ℕ
f : Vector ℕ n →. ℕ
n✝ : ℕ
f✝ : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f✝
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 1)), eval c ↑v = pure <$> ↑f✝ v
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (fun v => Nat.rfind fun n => Part.some (decide (f✝ (n ::ᵥ v) = 0))) v
[PROOFSTEP]
case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
[GOAL]
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 0), eval c ↑v = pure <$> (↑fun x => 0) v
[PROOFSTEP]
case prim.zero => exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
[GOAL]
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 0), eval c ↑v = pure <$> (↑fun x => 0) v
[PROOFSTEP]
exact ⟨zero', fun ⟨[], _⟩ => rfl⟩
[GOAL]
case prim.succ
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 1), eval c ↑v = pure <$> (↑fun v => Nat.succ (Vector.head v)) v
case prim.get
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
n✝ : ℕ
i✝ : Fin n✝
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (↑fun v => Vector.get v i✝) v
case prim.comp
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Fin n✝ → Vector ℕ m✝ → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Primrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> ↑(g✝ i) v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (↑fun a => f✝ (Vector.ofFn fun i => g✝ i a)) v
case prim.prec
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : Nat.Primrec' g✝
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 2)), eval c ↑v = pure <$> ↑g✝ v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n✝ + 1)),
      eval c ↑v =
        pure <$>
          (↑fun v => Nat.rec (f✝ (Vector.tail v)) (fun y IH => g✝ (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v
case comp
n : ℕ
f : Vector ℕ n →. ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
g✝ : Fin n✝ → Vector ℕ m✝ →. ℕ
a✝¹ : Nat.Partrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Partrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> g✝ i v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g✝ i v) >>= f✝) v
case rfind
n : ℕ
f : Vector ℕ n →. ℕ
n✝ : ℕ
f✝ : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f✝
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 1)), eval c ↑v = pure <$> ↑f✝ v
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (fun v => Nat.rfind fun n => Part.some (decide (f✝ (n ::ᵥ v) = 0))) v
[PROOFSTEP]
case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
[GOAL]
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 1), eval c ↑v = pure <$> (↑fun v => Nat.succ (Vector.head v)) v
[PROOFSTEP]
case prim.succ => exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
[GOAL]
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
⊢ ∃ c, ∀ (v : Vector ℕ 1), eval c ↑v = pure <$> (↑fun v => Nat.succ (Vector.head v)) v
[PROOFSTEP]
exact ⟨succ, fun ⟨[v], _⟩ => rfl⟩
[GOAL]
case prim.get
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
n✝ : ℕ
i✝ : Fin n✝
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (↑fun v => Vector.get v i✝) v
case prim.comp
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Fin n✝ → Vector ℕ m✝ → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Primrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> ↑(g✝ i) v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (↑fun a => f✝ (Vector.ofFn fun i => g✝ i a)) v
case prim.prec
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : Nat.Primrec' g✝
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 2)), eval c ↑v = pure <$> ↑g✝ v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n✝ + 1)),
      eval c ↑v =
        pure <$>
          (↑fun v => Nat.rec (f✝ (Vector.tail v)) (fun y IH => g✝ (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v
case comp
n : ℕ
f : Vector ℕ n →. ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
g✝ : Fin n✝ → Vector ℕ m✝ →. ℕ
a✝¹ : Nat.Partrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Partrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> g✝ i v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g✝ i v) >>= f✝) v
case rfind
n : ℕ
f : Vector ℕ n →. ℕ
n✝ : ℕ
f✝ : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f✝
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 1)), eval c ↑v = pure <$> ↑f✝ v
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (fun v => Nat.rfind fun n => Part.some (decide (f✝ (n ::ᵥ v) = 0))) v
[PROOFSTEP]
case prim.get n i =>
  refine' Fin.succRec (fun n => _) (fun n i IH => _) i
  · exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; rfl⟩
  · obtain ⟨c, h⟩ := IH
    exact ⟨c.comp tail, fun v => by simpa [← Vector.get_tail, Bind.bind] using h v.tail⟩
[GOAL]
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
n : ℕ
i : Fin n
⊢ ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (↑fun v => Vector.get v i) v
[PROOFSTEP]
case prim.get n i =>
  refine' Fin.succRec (fun n => _) (fun n i IH => _) i
  · exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; rfl⟩
  · obtain ⟨c, h⟩ := IH
    exact ⟨c.comp tail, fun v => by simpa [← Vector.get_tail, Bind.bind] using h v.tail⟩
[GOAL]
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
n : ℕ
i : Fin n
⊢ ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (↑fun v => Vector.get v i) v
[PROOFSTEP]
refine' Fin.succRec (fun n => _) (fun n i IH => _) i
[GOAL]
case refine'_1
n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
i : Fin n✝
n : ℕ
⊢ ∃ c, ∀ (v : Vector ℕ (Nat.succ n)), eval c ↑v = pure <$> (↑fun v => Vector.get v 0) v
[PROOFSTEP]
exact ⟨head, fun ⟨List.cons a as, _⟩ => by simp [Bind.bind]; rfl⟩
[GOAL]
n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
i : Fin n✝
n : ℕ
x✝ : Vector ℕ (Nat.succ n)
a : ℕ
as : List ℕ
property✝ : List.length (a :: as) = Nat.succ n
⊢ eval head ↑{ val := a :: as, property := property✝ } =
    pure <$> (↑fun v => Vector.get v 0) { val := a :: as, property := property✝ }
[PROOFSTEP]
simp [Bind.bind]
[GOAL]
n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
i : Fin n✝
n : ℕ
x✝ : Vector ℕ (Nat.succ n)
a : ℕ
as : List ℕ
property✝ : List.length (a :: as) = Nat.succ n
⊢ Part.some [a] = pure <$> Part.some (Vector.head { val := a :: as, property := property✝ })
[PROOFSTEP]
rfl
[GOAL]
case refine'_2
n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
i✝ : Fin n✝
n : ℕ
i : Fin n
IH : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (↑fun v => Vector.get v i) v
⊢ ∃ c, ∀ (v : Vector ℕ (Nat.succ n)), eval c ↑v = pure <$> (↑fun v => Vector.get v (Fin.succ i)) v
[PROOFSTEP]
obtain ⟨c, h⟩ := IH
[GOAL]
case refine'_2.intro
n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
i✝ : Fin n✝
n : ℕ
i : Fin n
c : Code
h : ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (↑fun v => Vector.get v i) v
⊢ ∃ c, ∀ (v : Vector ℕ (Nat.succ n)), eval c ↑v = pure <$> (↑fun v => Vector.get v (Fin.succ i)) v
[PROOFSTEP]
exact ⟨c.comp tail, fun v => by simpa [← Vector.get_tail, Bind.bind] using h v.tail⟩
[GOAL]
n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
i✝ : Fin n✝
n : ℕ
i : Fin n
c : Code
h : ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (↑fun v => Vector.get v i) v
v : Vector ℕ (Nat.succ n)
⊢ eval (comp c tail) ↑v = pure <$> (↑fun v => Vector.get v (Fin.succ i)) v
[PROOFSTEP]
simpa [← Vector.get_tail, Bind.bind] using h v.tail
[GOAL]
case prim.comp
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Fin n✝ → Vector ℕ m✝ → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Primrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> ↑(g✝ i) v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (↑fun a => f✝ (Vector.ofFn fun i => g✝ i a)) v
case prim.prec
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : Nat.Primrec' g✝
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 2)), eval c ↑v = pure <$> ↑g✝ v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n✝ + 1)),
      eval c ↑v =
        pure <$>
          (↑fun v => Nat.rec (f✝ (Vector.tail v)) (fun y IH => g✝ (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v
case comp
n : ℕ
f : Vector ℕ n →. ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
g✝ : Fin n✝ → Vector ℕ m✝ →. ℕ
a✝¹ : Nat.Partrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Partrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> g✝ i v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g✝ i v) >>= f✝) v
case rfind
n : ℕ
f : Vector ℕ n →. ℕ
n✝ : ℕ
f✝ : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f✝
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 1)), eval c ↑v = pure <$> ↑f✝ v
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (fun v => Nat.rfind fun n => Part.some (decide (f✝ (n ::ᵥ v) = 0))) v
[PROOFSTEP]
case prim.comp m n f g hf hg IHf IHg => simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
[GOAL]
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
m n : ℕ
f : Vector ℕ n → ℕ
g : Fin n → Vector ℕ m → ℕ
hf : Nat.Primrec' f
hg : ∀ (i : Fin n), Nat.Primrec' (g i)
IHf : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> ↑f v
IHg : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> ↑(g i) v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> (↑fun a => f (Vector.ofFn fun i => g i a)) v
[PROOFSTEP]
case prim.comp m n f g hf hg IHf IHg => simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
[GOAL]
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
m n : ℕ
f : Vector ℕ n → ℕ
g : Fin n → Vector ℕ m → ℕ
hf : Nat.Primrec' f
hg : ∀ (i : Fin n), Nat.Primrec' (g i)
IHf : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> ↑f v
IHg : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> ↑(g i) v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> (↑fun a => f (Vector.ofFn fun i => g i a)) v
[PROOFSTEP]
simpa [Part.bind_eq_bind] using exists_code.comp IHf IHg
[GOAL]
case prim.prec
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n : ℕ
f : Vector ℕ n → ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
g✝ : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f✝
a✝ : Nat.Primrec' g✝
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> ↑f✝ v
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 2)), eval c ↑v = pure <$> ↑g✝ v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n✝ + 1)),
      eval c ↑v =
        pure <$>
          (↑fun v => Nat.rec (f✝ (Vector.tail v)) (fun y IH => g✝ (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v
case comp
n : ℕ
f : Vector ℕ n →. ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
g✝ : Fin n✝ → Vector ℕ m✝ →. ℕ
a✝¹ : Nat.Partrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Partrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> g✝ i v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g✝ i v) >>= f✝) v
case rfind
n : ℕ
f : Vector ℕ n →. ℕ
n✝ : ℕ
f✝ : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f✝
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 1)), eval c ↑v = pure <$> ↑f✝ v
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (fun v => Nat.rfind fun n => Part.some (decide (f✝ (n ::ᵥ v) = 0))) v
[PROOFSTEP]
case prim.prec n f g _ _ IHf IHg =>
  obtain ⟨cf, hf⟩ := IHf
  obtain ⟨cg, hg⟩ := IHg
  simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
  refine' ⟨prec cf cg, fun v => _⟩
  rw [← v.cons_head_tail]
  specialize hf v.tail
  replace hg := fun a b => hg (a ::ᵥ b ::ᵥ v.tail)
  simp only [Vector.cons_val, Vector.tail_val] at hf hg
  simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, Vector.tail_cons, Vector.head_cons, PFun.coe_val,
    Vector.tail_val]
  simp only [← Part.pure_eq_some] at hf hg ⊢
  induction' v.head with n _ <;>
    simp [prec, hf, Part.bind_assoc, ← Part.bind_some_eq_map, Part.bind_some, show ∀ x, pure x = [x] from fun _ => rfl,
      Bind.bind, Functor.map]
  suffices
    ∀ a b,
      a + b = n →
        (n.succ :: 0 :: g (n ::ᵥ Nat.rec (f v.tail) (fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)) n ::ᵥ v.tail) :: v.val.tail :
            List ℕ) ∈
          PFun.fix
            (fun v : List ℕ =>
              Part.bind (cg.eval (v.headI :: v.tail.tail))
                (fun x =>
                  Part.some
                    (if v.tail.headI = 0 then
                      Sum.inl (v.headI.succ :: v.tail.headI.pred :: x.headI :: v.tail.tail.tail : List ℕ)
                    else Sum.inr (v.headI.succ :: v.tail.headI.pred :: x.headI :: v.tail.tail.tail))))
            (a :: b :: Nat.rec (f v.tail) (fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)) a :: v.val.tail)
    by
    erw [Part.eq_some_iff.2 (this 0 n (zero_add n))]
    simp only [List.headI, Part.bind_some, List.tail_cons]
  intro a b e
  induction' b with b IH generalizing a
  · refine' PFun.mem_fix_iff.2 (Or.inl <| Part.eq_some_iff.1 _)
    simp only [hg, ← e, Part.bind_some, List.tail_cons, pure]
    rfl
  · refine' PFun.mem_fix_iff.2 (Or.inr ⟨_, _, IH (a + 1) (by rwa [add_right_comm])⟩)
    simp only [hg, eval, Part.bind_some, Nat.rec_add_one, List.tail_nil, List.tail_cons, pure]
    exact Part.mem_some_iff.2 rfl
[GOAL]
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
IHf : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> ↑f v
IHg : ∃ c, ∀ (v : Vector ℕ (n + 2)), eval c ↑v = pure <$> ↑g v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n + 1)),
      eval c ↑v =
        pure <$> (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v
[PROOFSTEP]
case prim.prec n f g _ _ IHf IHg =>
  obtain ⟨cf, hf⟩ := IHf
  obtain ⟨cg, hg⟩ := IHg
  simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
  refine' ⟨prec cf cg, fun v => _⟩
  rw [← v.cons_head_tail]
  specialize hf v.tail
  replace hg := fun a b => hg (a ::ᵥ b ::ᵥ v.tail)
  simp only [Vector.cons_val, Vector.tail_val] at hf hg
  simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, Vector.tail_cons, Vector.head_cons, PFun.coe_val,
    Vector.tail_val]
  simp only [← Part.pure_eq_some] at hf hg ⊢
  induction' v.head with n _ <;>
    simp [prec, hf, Part.bind_assoc, ← Part.bind_some_eq_map, Part.bind_some, show ∀ x, pure x = [x] from fun _ => rfl,
      Bind.bind, Functor.map]
  suffices
    ∀ a b,
      a + b = n →
        (n.succ :: 0 :: g (n ::ᵥ Nat.rec (f v.tail) (fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)) n ::ᵥ v.tail) :: v.val.tail :
            List ℕ) ∈
          PFun.fix
            (fun v : List ℕ =>
              Part.bind (cg.eval (v.headI :: v.tail.tail))
                (fun x =>
                  Part.some
                    (if v.tail.headI = 0 then
                      Sum.inl (v.headI.succ :: v.tail.headI.pred :: x.headI :: v.tail.tail.tail : List ℕ)
                    else Sum.inr (v.headI.succ :: v.tail.headI.pred :: x.headI :: v.tail.tail.tail))))
            (a :: b :: Nat.rec (f v.tail) (fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)) a :: v.val.tail)
    by
    erw [Part.eq_some_iff.2 (this 0 n (zero_add n))]
    simp only [List.headI, Part.bind_some, List.tail_cons]
  intro a b e
  induction' b with b IH generalizing a
  · refine' PFun.mem_fix_iff.2 (Or.inl <| Part.eq_some_iff.1 _)
    simp only [hg, ← e, Part.bind_some, List.tail_cons, pure]
    rfl
  · refine' PFun.mem_fix_iff.2 (Or.inr ⟨_, _, IH (a + 1) (by rwa [add_right_comm])⟩)
    simp only [hg, eval, Part.bind_some, Nat.rec_add_one, List.tail_nil, List.tail_cons, pure]
    exact Part.mem_some_iff.2 rfl
[GOAL]
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
IHf : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> ↑f v
IHg : ∃ c, ∀ (v : Vector ℕ (n + 2)), eval c ↑v = pure <$> ↑g v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n + 1)),
      eval c ↑v =
        pure <$> (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v
[PROOFSTEP]
obtain ⟨cf, hf⟩ := IHf
[GOAL]
case intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
IHg : ∃ c, ∀ (v : Vector ℕ (n + 2)), eval c ↑v = pure <$> ↑g v
cf : Code
hf : ∀ (v : Vector ℕ n), eval cf ↑v = pure <$> ↑f v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n + 1)),
      eval c ↑v =
        pure <$> (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v
[PROOFSTEP]
obtain ⟨cg, hg⟩ := IHg
[GOAL]
case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf : Code
hf : ∀ (v : Vector ℕ n), eval cf ↑v = pure <$> ↑f v
cg : Code
hg : ∀ (v : Vector ℕ (n + 2)), eval cg ↑v = pure <$> ↑g v
⊢ ∃ c,
    ∀ (v : Vector ℕ (n + 1)),
      eval c ↑v =
        pure <$> (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v
[PROOFSTEP]
simp only [Part.map_eq_map, Part.map_some, PFun.coe_val] at hf hg
[GOAL]
case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
hf : ∀ (v : Vector ℕ n), eval cf ↑v = Part.some (pure (f v))
hg : ∀ (v : Vector ℕ (n + 2)), eval cg ↑v = Part.some (pure (g v))
⊢ ∃ c,
    ∀ (v : Vector ℕ (n + 1)),
      eval c ↑v =
        pure <$> (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v
[PROOFSTEP]
refine' ⟨prec cf cg, fun v => _⟩
[GOAL]
case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
hf : ∀ (v : Vector ℕ n), eval cf ↑v = Part.some (pure (f v))
hg : ∀ (v : Vector ℕ (n + 2)), eval cg ↑v = Part.some (pure (g v))
v : Vector ℕ (n + 1)
⊢ eval (prec cf cg) ↑v =
    pure <$> (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)) v
[PROOFSTEP]
rw [← v.cons_head_tail]
[GOAL]
case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
hf : ∀ (v : Vector ℕ n), eval cf ↑v = Part.some (pure (f v))
hg : ∀ (v : Vector ℕ (n + 2)), eval cg ↑v = Part.some (pure (g v))
v : Vector ℕ (n + 1)
⊢ eval (prec cf cg) ↑(Vector.head v ::ᵥ Vector.tail v) =
    pure <$>
      (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v))
        (Vector.head v ::ᵥ Vector.tail v)
[PROOFSTEP]
specialize hf v.tail
[GOAL]
case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
hg : ∀ (v : Vector ℕ (n + 2)), eval cg ↑v = Part.some (pure (g v))
v : Vector ℕ (n + 1)
hf : eval cf ↑(Vector.tail v) = Part.some (pure (f (Vector.tail v)))
⊢ eval (prec cf cg) ↑(Vector.head v ::ᵥ Vector.tail v) =
    pure <$>
      (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v))
        (Vector.head v ::ᵥ Vector.tail v)
[PROOFSTEP]
replace hg := fun a b => hg (a ::ᵥ b ::ᵥ v.tail)
[GOAL]
case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n + 1)
hf : eval cf ↑(Vector.tail v) = Part.some (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg ↑(a ::ᵥ b ::ᵥ Vector.tail v) = Part.some (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
⊢ eval (prec cf cg) ↑(Vector.head v ::ᵥ Vector.tail v) =
    pure <$>
      (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v))
        (Vector.head v ::ᵥ Vector.tail v)
[PROOFSTEP]
simp only [Vector.cons_val, Vector.tail_val] at hf hg
[GOAL]
case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n + 1)
hf : eval cf (List.tail ↑v) = Part.some (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = Part.some (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
⊢ eval (prec cf cg) ↑(Vector.head v ::ᵥ Vector.tail v) =
    pure <$>
      (↑fun v => Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v))
        (Vector.head v ::ᵥ Vector.tail v)
[PROOFSTEP]
simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, Vector.tail_cons, Vector.head_cons, PFun.coe_val,
  Vector.tail_val]
[GOAL]
case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n + 1)
hf : eval cf (List.tail ↑v) = Part.some (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = Part.some (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
⊢ eval (prec cf cg) (Vector.head v :: List.tail ↑v) =
    Part.some (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)))
[PROOFSTEP]
simp only [← Part.pure_eq_some] at hf hg ⊢
[GOAL]
case intro.intro
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
⊢ eval (prec cf cg) (Vector.head v :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Vector.head v)))
[PROOFSTEP]
induction' v.head with n _
[GOAL]
case intro.intro.zero
n✝¹ : ℕ
f✝¹ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f✝ : Vector ℕ n✝ → ℕ
n : ℕ
f : Vector ℕ n → ℕ
g : Vector ℕ (n + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
⊢ eval (prec cf cg) (Nat.zero :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) Nat.zero))
[PROOFSTEP]
simp [prec, hf, Part.bind_assoc, ← Part.bind_some_eq_map, Part.bind_some, show ∀ x, pure x = [x] from fun _ => rfl,
  Bind.bind, Functor.map]
[GOAL]
case intro.intro.succ
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
⊢ eval (prec cf cg) (Nat.succ n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (Nat.succ n)))
[PROOFSTEP]
simp [prec, hf, Part.bind_assoc, ← Part.bind_some_eq_map, Part.bind_some, show ∀ x, pure x = [x] from fun _ => rfl,
  Bind.bind, Functor.map]
[GOAL]
case intro.intro.succ
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
⊢ (Part.bind
      (PFun.fix
        (fun v =>
          Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
            Part.some
              (if List.headI (List.tail v) = 0 then
                Sum.inl
                  (Nat.succ (List.headI v) ::
                    Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
              else
                Sum.inr
                  (Nat.succ (List.headI v) ::
                    Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
        (0 :: n :: f (Vector.tail v) :: List.tail ↑v))
      fun x => Part.some [List.headI (List.tail (List.tail x))]) =
    Part.some [g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v)]
[PROOFSTEP]
suffices
  ∀ a b,
    a + b = n →
      (n.succ :: 0 :: g (n ::ᵥ Nat.rec (f v.tail) (fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)) n ::ᵥ v.tail) :: v.val.tail :
          List ℕ) ∈
        PFun.fix
          (fun v : List ℕ =>
            Part.bind (cg.eval (v.headI :: v.tail.tail))
              (fun x =>
                Part.some
                  (if v.tail.headI = 0 then
                    Sum.inl (v.headI.succ :: v.tail.headI.pred :: x.headI :: v.tail.tail.tail : List ℕ)
                  else Sum.inr (v.headI.succ :: v.tail.headI.pred :: x.headI :: v.tail.tail.tail))))
          (a :: b :: Nat.rec (f v.tail) (fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)) a :: v.val.tail)
  by
  erw [Part.eq_some_iff.2 (this 0 n (zero_add n))]
  simp only [List.headI, Part.bind_some, List.tail_cons]
[GOAL]
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
this :
  ∀ (a b : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
⊢ (Part.bind
      (PFun.fix
        (fun v =>
          Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
            Part.some
              (if List.headI (List.tail v) = 0 then
                Sum.inl
                  (Nat.succ (List.headI v) ::
                    Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
              else
                Sum.inr
                  (Nat.succ (List.headI v) ::
                    Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
        (0 :: n :: f (Vector.tail v) :: List.tail ↑v))
      fun x => Part.some [List.headI (List.tail (List.tail x))]) =
    Part.some [g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v)]
[PROOFSTEP]
erw [Part.eq_some_iff.2 (this 0 n (zero_add n))]
[GOAL]
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
this :
  ∀ (a b : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
⊢ (Part.bind
      (Part.some
        (Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v))
      fun x => Part.some [List.headI (List.tail (List.tail x))]) =
    Part.some [g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v)]
[PROOFSTEP]
simp only [List.headI, Part.bind_some, List.tail_cons]
[GOAL]
case intro.intro.succ
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
⊢ ∀ (a b : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
[PROOFSTEP]
intro a b e
[GOAL]
case intro.intro.succ
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝¹ : Nat.Primrec' f
a✝ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a b : ℕ
e : a + b = n
⊢ Nat.succ n ::
      0 ::
        g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
          List.tail ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
          Part.some
            (if List.headI (List.tail v) = 0 then
              Sum.inl
                (Nat.succ (List.headI v) ::
                  Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
            else
              Sum.inr
                (Nat.succ (List.headI v) ::
                  Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
      (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
[PROOFSTEP]
induction' b with b IH generalizing a
[GOAL]
case intro.intro.succ.zero
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b : ℕ
e✝ : a✝ + b = n
a : ℕ
e : a + Nat.zero = n
⊢ Nat.succ n ::
      0 ::
        g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
          List.tail ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
          Part.some
            (if List.headI (List.tail v) = 0 then
              Sum.inl
                (Nat.succ (List.headI v) ::
                  Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
            else
              Sum.inr
                (Nat.succ (List.headI v) ::
                  Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
      (a :: Nat.zero :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
[PROOFSTEP]
refine' PFun.mem_fix_iff.2 (Or.inl <| Part.eq_some_iff.1 _)
[GOAL]
case intro.intro.succ.zero
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b : ℕ
e✝ : a✝ + b = n
a : ℕ
e : a + Nat.zero = n
⊢ (Part.bind
      (eval cg
        (List.headI
            (a ::
              Nat.zero :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v) ::
          List.tail
            (List.tail
              (a ::
                Nat.zero ::
                  Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v))))
      fun x =>
      Part.some
        (if
            List.headI
                (List.tail
                  (a ::
                    Nat.zero ::
                      Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) =
              0 then
          Sum.inl
            (Nat.succ
                (List.headI
                  (a ::
                    Nat.zero ::
                      Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              Nat.pred
                  (List.headI
                    (List.tail
                      (a ::
                        Nat.zero ::
                          Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                            List.tail ↑v))) ::
                List.headI x ::
                  List.tail
                    (List.tail
                      (List.tail
                        (a ::
                          Nat.zero ::
                            Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                              List.tail ↑v))))
        else
          Sum.inr
            (Nat.succ
                (List.headI
                  (a ::
                    Nat.zero ::
                      Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              Nat.pred
                  (List.headI
                    (List.tail
                      (a ::
                        Nat.zero ::
                          Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                            List.tail ↑v))) ::
                List.headI x ::
                  List.tail
                    (List.tail
                      (List.tail
                        (a ::
                          Nat.zero ::
                            Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                              List.tail ↑v)))))) =
    Part.some
      (Sum.inl
        (Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v))
[PROOFSTEP]
simp only [hg, ← e, Part.bind_some, List.tail_cons, pure]
[GOAL]
case intro.intro.succ.zero
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b : ℕ
e✝ : a✝ + b = n
a : ℕ
e : a + Nat.zero = n
⊢ Part.some
      (if
          List.headI
              (Nat.zero :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v) =
            0 then
        Sum.inl
          (Nat.succ
              (List.headI
                (a ::
                  Nat.zero ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
            Nat.pred
                (List.headI
                  (Nat.zero ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              List.headI
                  (List.ret
                    (g
                      (List.headI
                          (a ::
                            Nat.zero ::
                              Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                                List.tail ↑v) ::ᵥ
                        Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::ᵥ
                          Vector.tail v))) ::
                List.tail ↑v)
      else
        Sum.inr
          (Nat.succ
              (List.headI
                (a ::
                  Nat.zero ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
            Nat.pred
                (List.headI
                  (Nat.zero ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              List.headI
                  (List.ret
                    (g
                      (List.headI
                          (a ::
                            Nat.zero ::
                              Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                                List.tail ↑v) ::ᵥ
                        Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::ᵥ
                          Vector.tail v))) ::
                List.tail ↑v)) =
    Part.some
      (Sum.inl
        (Nat.succ (a + Nat.zero) ::
          0 ::
            g
                ((a + Nat.zero) ::ᵥ
                  Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (a + Nat.zero) ::ᵥ
                    Vector.tail v) ::
              List.tail ↑v))
[PROOFSTEP]
rfl
[GOAL]
case intro.intro.succ.succ
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b✝ : ℕ
e✝ : a✝ + b✝ = n
b : ℕ
IH :
  ∀ (a : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
a : ℕ
e : a + Nat.succ b = n
⊢ Nat.succ n ::
      0 ::
        g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
          List.tail ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
          Part.some
            (if List.headI (List.tail v) = 0 then
              Sum.inl
                (Nat.succ (List.headI v) ::
                  Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
            else
              Sum.inr
                (Nat.succ (List.headI v) ::
                  Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
      (a :: Nat.succ b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
[PROOFSTEP]
refine' PFun.mem_fix_iff.2 (Or.inr ⟨_, _, IH (a + 1) (by rwa [add_right_comm])⟩)
[GOAL]
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b✝ : ℕ
e✝ : a✝ + b✝ = n
b : ℕ
IH :
  ∀ (a : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
a : ℕ
e : a + Nat.succ b = n
⊢ a + 1 + b = n
[PROOFSTEP]
rwa [add_right_comm]
[GOAL]
case intro.intro.succ.succ
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b✝ : ℕ
e✝ : a✝ + b✝ = n
b : ℕ
IH :
  ∀ (a : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
a : ℕ
e : a + Nat.succ b = n
⊢ Sum.inr
      ((a + 1) ::
        b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) (a + 1) :: List.tail ↑v) ∈
    Part.bind
      (eval cg
        (List.headI
            (a ::
              Nat.succ b ::
                Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v) ::
          List.tail
            (List.tail
              (a ::
                Nat.succ b ::
                  Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v))))
      fun x =>
      Part.some
        (if
            List.headI
                (List.tail
                  (a ::
                    Nat.succ b ::
                      Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) =
              0 then
          Sum.inl
            (Nat.succ
                (List.headI
                  (a ::
                    Nat.succ b ::
                      Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              Nat.pred
                  (List.headI
                    (List.tail
                      (a ::
                        Nat.succ b ::
                          Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                            List.tail ↑v))) ::
                List.headI x ::
                  List.tail
                    (List.tail
                      (List.tail
                        (a ::
                          Nat.succ b ::
                            Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                              List.tail ↑v))))
        else
          Sum.inr
            (Nat.succ
                (List.headI
                  (a ::
                    Nat.succ b ::
                      Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              Nat.pred
                  (List.headI
                    (List.tail
                      (a ::
                        Nat.succ b ::
                          Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                            List.tail ↑v))) ::
                List.headI x ::
                  List.tail
                    (List.tail
                      (List.tail
                        (a ::
                          Nat.succ b ::
                            Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                              List.tail ↑v)))))
[PROOFSTEP]
simp only [hg, eval, Part.bind_some, Nat.rec_add_one, List.tail_nil, List.tail_cons, pure]
[GOAL]
case intro.intro.succ.succ
n✝² : ℕ
f✝¹ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ → ℕ
n✝ : ℕ
f : Vector ℕ n✝ → ℕ
g : Vector ℕ (n✝ + 2) → ℕ
a✝² : Nat.Primrec' f
a✝¹ : Nat.Primrec' g
cf cg : Code
v : Vector ℕ (n✝ + 1)
hf : eval cf (List.tail ↑v) = pure (pure (f (Vector.tail v)))
hg : ∀ (a b : ℕ), eval cg (a :: b :: List.tail ↑v) = pure (pure (g (a ::ᵥ b ::ᵥ Vector.tail v)))
n : ℕ
n_ih✝ :
  eval (prec cf cg) (n :: List.tail ↑v) =
    pure (pure (Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n))
a✝ b✝ : ℕ
e✝ : a✝ + b✝ = n
b : ℕ
IH :
  ∀ (a : ℕ),
    a + b = n →
      Nat.succ n ::
          0 ::
            g (n ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) n ::ᵥ Vector.tail v) ::
              List.tail ↑v ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cg (List.headI v :: List.tail (List.tail v))) fun x =>
              Part.some
                (if List.headI (List.tail v) = 0 then
                  Sum.inl
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))
                else
                  Sum.inr
                    (Nat.succ (List.headI v) ::
                      Nat.pred (List.headI (List.tail v)) :: List.headI x :: List.tail (List.tail (List.tail v)))))
          (a :: b :: Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)
a : ℕ
e : a + Nat.succ b = n
⊢ Sum.inr
      ((a + 1) ::
        b ::
          g (a ::ᵥ Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::ᵥ Vector.tail v) ::
            List.tail ↑v) ∈
    Part.some
      (if
          List.headI
              (Nat.succ b ::
                Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v) =
            0 then
        Sum.inl
          (Nat.succ
              (List.headI
                (a ::
                  Nat.succ b ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
            Nat.pred
                (List.headI
                  (Nat.succ b ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              List.headI
                  (List.ret
                    (g
                      (List.headI
                          (a ::
                            Nat.succ b ::
                              Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                                List.tail ↑v) ::ᵥ
                        Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::ᵥ
                          Vector.tail v))) ::
                List.tail ↑v)
      else
        Sum.inr
          (Nat.succ
              (List.headI
                (a ::
                  Nat.succ b ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
            Nat.pred
                (List.headI
                  (Nat.succ b ::
                    Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a :: List.tail ↑v)) ::
              List.headI
                  (List.ret
                    (g
                      (List.headI
                          (a ::
                            Nat.succ b ::
                              Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::
                                List.tail ↑v) ::ᵥ
                        Nat.rec (f (Vector.tail v)) (fun y IH => g (y ::ᵥ IH ::ᵥ Vector.tail v)) a ::ᵥ
                          Vector.tail v))) ::
                List.tail ↑v))
[PROOFSTEP]
exact Part.mem_some_iff.2 rfl
[GOAL]
case comp
n : ℕ
f : Vector ℕ n →. ℕ
m✝ n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
g✝ : Fin n✝ → Vector ℕ m✝ →. ℕ
a✝¹ : Nat.Partrec' f✝
a✝ : ∀ (i : Fin n✝), Nat.Partrec' (g✝ i)
a_ih✝¹ : ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> f✝ v
a_ih✝ : ∀ (i : Fin n✝), ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> g✝ i v
⊢ ∃ c, ∀ (v : Vector ℕ m✝), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g✝ i v) >>= f✝) v
case rfind
n : ℕ
f : Vector ℕ n →. ℕ
n✝ : ℕ
f✝ : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f✝
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 1)), eval c ↑v = pure <$> ↑f✝ v
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (fun v => Nat.rfind fun n => Part.some (decide (f✝ (n ::ᵥ v) = 0))) v
[PROOFSTEP]
case comp m n f g _ _ IHf IHg => exact exists_code.comp IHf IHg
[GOAL]
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
m n : ℕ
f : Vector ℕ n →. ℕ
g : Fin n → Vector ℕ m →. ℕ
a✝¹ : Nat.Partrec' f
a✝ : ∀ (i : Fin n), Nat.Partrec' (g i)
IHf : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> f v
IHg : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g i v) >>= f) v
[PROOFSTEP]
case comp m n f g _ _ IHf IHg => exact exists_code.comp IHf IHg
[GOAL]
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
m n : ℕ
f : Vector ℕ n →. ℕ
g : Fin n → Vector ℕ m →. ℕ
a✝¹ : Nat.Partrec' f
a✝ : ∀ (i : Fin n), Nat.Partrec' (g i)
IHf : ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> f v
IHg : ∀ (i : Fin n), ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> g i v
⊢ ∃ c, ∀ (v : Vector ℕ m), eval c ↑v = pure <$> (fun v => (Vector.mOfFn fun i => g i v) >>= f) v
[PROOFSTEP]
exact exists_code.comp IHf IHg
[GOAL]
case rfind
n : ℕ
f : Vector ℕ n →. ℕ
n✝ : ℕ
f✝ : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f✝
a_ih✝ : ∃ c, ∀ (v : Vector ℕ (n✝ + 1)), eval c ↑v = pure <$> ↑f✝ v
⊢ ∃ c, ∀ (v : Vector ℕ n✝), eval c ↑v = pure <$> (fun v => Nat.rfind fun n => Part.some (decide (f✝ (n ::ᵥ v) = 0))) v
[PROOFSTEP]
case rfind n f _ IHf =>
  obtain ⟨cf, hf⟩ := IHf; refine' ⟨rfind cf, fun v => _⟩
  replace hf := fun a => hf (a ::ᵥ v)
  simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, PFun.coe_val, show ∀ x, pure x = [x] from fun _ => rfl] at
    hf ⊢
  refine' Part.ext fun x => _
  simp only [rfind, Part.bind_eq_bind, Part.pure_eq_some, Part.map_eq_map, Part.bind_some, exists_prop, cons_eval,
    comp_eval, fix_eval, tail_eval, succ_eval, zero'_eval, List.headI_nil, List.headI_cons, pred_eval, Part.map_some,
    Bool.false_eq_decide_iff, Part.mem_bind_iff, List.length, Part.mem_map_iff, Nat.mem_rfind, List.tail_nil,
    List.tail_cons, Bool.true_eq_decide_iff, Part.mem_some_iff, Part.map_bind]
  constructor
  · rintro ⟨v', h1, rfl⟩
    suffices
      ∀ v₁ : List ℕ,
        v' ∈
            PFun.fix
              (fun v =>
                (cf.eval v).bind fun y =>
                  Part.some <|
                    if y.headI = 0 then Sum.inl (v.headI.succ :: v.tail) else Sum.inr (v.headI.succ :: v.tail))
              v₁ →
          ∀ n,
            (v₁ = n :: v.val) →
              (∀ m < n, ¬f (m ::ᵥ v) = 0) →
                ∃ a : ℕ, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [v'.headI.pred]
      by exact this _ h1 0 rfl (by rintro _ ⟨⟩)
    clear h1
    intro v₀ h1
    refine' PFun.fixInduction h1 fun v₁ h2 IH => _
    clear h1
    rintro n rfl hm
    have := PFun.mem_fix_iff.1 h2
    simp only [hf, Part.bind_some] at this
    split_ifs at this  with h
    · simp only [List.headI_nil, List.headI_cons, exists_false, or_false_iff, Part.mem_some_iff, List.tail_cons,
        false_and_iff, Sum.inl.injEq] at this
      subst this
      exact ⟨_, ⟨h, @(hm)⟩, rfl⟩
    · refine' IH (n.succ :: v.val) (by simp_all) _ rfl fun m h' => _
      obtain h | rfl := Nat.lt_succ_iff_lt_or_eq.1 h'
      exacts [hm _ h, h]
  · rintro ⟨n, ⟨hn, hm⟩, rfl⟩
    refine' ⟨n.succ :: v.1, _, rfl⟩
    have :
      (n.succ :: v.1 : List ℕ) ∈
        PFun.fix
          (fun v =>
            (cf.eval v).bind fun y =>
              Part.some <| if y.headI = 0 then Sum.inl (v.headI.succ :: v.tail) else Sum.inr (v.headI.succ :: v.tail))
          (n :: v.val) :=
      PFun.mem_fix_iff.2 (Or.inl (by simp [hf, hn]))
    generalize (n.succ :: v.1 : List ℕ) = w at this ⊢
    clear hn
    induction' n with n IH
    · exact this
    refine' IH (fun {m} h' => hm (Nat.lt_succ_of_lt h')) (PFun.mem_fix_iff.2 (Or.inr ⟨_, _, this⟩))
    simp only [hf, hm n.lt_succ_self, Part.bind_some, List.headI, eq_self_iff_true, if_false, Part.mem_some_iff,
      and_self_iff, List.tail_cons]
[GOAL]
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
IHf : ∃ c, ∀ (v : Vector ℕ (n + 1)), eval c ↑v = pure <$> ↑f v
⊢ ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (fun v => Nat.rfind fun n_1 => Part.some (decide (f (n_1 ::ᵥ v) = 0))) v
[PROOFSTEP]
case rfind n f _ IHf =>
  obtain ⟨cf, hf⟩ := IHf; refine' ⟨rfind cf, fun v => _⟩
  replace hf := fun a => hf (a ::ᵥ v)
  simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, PFun.coe_val, show ∀ x, pure x = [x] from fun _ => rfl] at
    hf ⊢
  refine' Part.ext fun x => _
  simp only [rfind, Part.bind_eq_bind, Part.pure_eq_some, Part.map_eq_map, Part.bind_some, exists_prop, cons_eval,
    comp_eval, fix_eval, tail_eval, succ_eval, zero'_eval, List.headI_nil, List.headI_cons, pred_eval, Part.map_some,
    Bool.false_eq_decide_iff, Part.mem_bind_iff, List.length, Part.mem_map_iff, Nat.mem_rfind, List.tail_nil,
    List.tail_cons, Bool.true_eq_decide_iff, Part.mem_some_iff, Part.map_bind]
  constructor
  · rintro ⟨v', h1, rfl⟩
    suffices
      ∀ v₁ : List ℕ,
        v' ∈
            PFun.fix
              (fun v =>
                (cf.eval v).bind fun y =>
                  Part.some <|
                    if y.headI = 0 then Sum.inl (v.headI.succ :: v.tail) else Sum.inr (v.headI.succ :: v.tail))
              v₁ →
          ∀ n,
            (v₁ = n :: v.val) →
              (∀ m < n, ¬f (m ::ᵥ v) = 0) →
                ∃ a : ℕ, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [v'.headI.pred]
      by exact this _ h1 0 rfl (by rintro _ ⟨⟩)
    clear h1
    intro v₀ h1
    refine' PFun.fixInduction h1 fun v₁ h2 IH => _
    clear h1
    rintro n rfl hm
    have := PFun.mem_fix_iff.1 h2
    simp only [hf, Part.bind_some] at this
    split_ifs at this  with h
    · simp only [List.headI_nil, List.headI_cons, exists_false, or_false_iff, Part.mem_some_iff, List.tail_cons,
        false_and_iff, Sum.inl.injEq] at this
      subst this
      exact ⟨_, ⟨h, @(hm)⟩, rfl⟩
    · refine' IH (n.succ :: v.val) (by simp_all) _ rfl fun m h' => _
      obtain h | rfl := Nat.lt_succ_iff_lt_or_eq.1 h'
      exacts [hm _ h, h]
  · rintro ⟨n, ⟨hn, hm⟩, rfl⟩
    refine' ⟨n.succ :: v.1, _, rfl⟩
    have :
      (n.succ :: v.1 : List ℕ) ∈
        PFun.fix
          (fun v =>
            (cf.eval v).bind fun y =>
              Part.some <| if y.headI = 0 then Sum.inl (v.headI.succ :: v.tail) else Sum.inr (v.headI.succ :: v.tail))
          (n :: v.val) :=
      PFun.mem_fix_iff.2 (Or.inl (by simp [hf, hn]))
    generalize (n.succ :: v.1 : List ℕ) = w at this ⊢
    clear hn
    induction' n with n IH
    · exact this
    refine' IH (fun {m} h' => hm (Nat.lt_succ_of_lt h')) (PFun.mem_fix_iff.2 (Or.inr ⟨_, _, this⟩))
    simp only [hf, hm n.lt_succ_self, Part.bind_some, List.headI, eq_self_iff_true, if_false, Part.mem_some_iff,
      and_self_iff, List.tail_cons]
[GOAL]
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
IHf : ∃ c, ∀ (v : Vector ℕ (n + 1)), eval c ↑v = pure <$> ↑f v
⊢ ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (fun v => Nat.rfind fun n_1 => Part.some (decide (f (n_1 ::ᵥ v) = 0))) v
[PROOFSTEP]
obtain ⟨cf, hf⟩ := IHf
[GOAL]
case intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
hf : ∀ (v : Vector ℕ (n + 1)), eval cf ↑v = pure <$> ↑f v
⊢ ∃ c, ∀ (v : Vector ℕ n), eval c ↑v = pure <$> (fun v => Nat.rfind fun n_1 => Part.some (decide (f (n_1 ::ᵥ v) = 0))) v
[PROOFSTEP]
refine' ⟨rfind cf, fun v => _⟩
[GOAL]
case intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
hf : ∀ (v : Vector ℕ (n + 1)), eval cf ↑v = pure <$> ↑f v
v : Vector ℕ n
⊢ eval (rfind cf) ↑v = pure <$> (fun v => Nat.rfind fun n_1 => Part.some (decide (f (n_1 ::ᵥ v) = 0))) v
[PROOFSTEP]
replace hf := fun a => hf (a ::ᵥ v)
[GOAL]
case intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf ↑(a ::ᵥ v) = pure <$> ↑f (a ::ᵥ v)
⊢ eval (rfind cf) ↑v = pure <$> (fun v => Nat.rfind fun n_1 => Part.some (decide (f (n_1 ::ᵥ v) = 0))) v
[PROOFSTEP]
simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, PFun.coe_val, show ∀ x, pure x = [x] from fun _ => rfl] at
  hf ⊢
[GOAL]
case intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
⊢ eval (rfind cf) ↑v = Part.map pure (Nat.rfind fun n_1 => Part.some (decide (f (n_1 ::ᵥ v) = 0)))
[PROOFSTEP]
refine' Part.ext fun x => _
[GOAL]
case intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
x : List ℕ
⊢ x ∈ eval (rfind cf) ↑v ↔ x ∈ Part.map pure (Nat.rfind fun n_1 => Part.some (decide (f (n_1 ::ᵥ v) = 0)))
[PROOFSTEP]
simp only [rfind, Part.bind_eq_bind, Part.pure_eq_some, Part.map_eq_map, Part.bind_some, exists_prop, cons_eval,
  comp_eval, fix_eval, tail_eval, succ_eval, zero'_eval, List.headI_nil, List.headI_cons, pred_eval, Part.map_some,
  Bool.false_eq_decide_iff, Part.mem_bind_iff, List.length, Part.mem_map_iff, Nat.mem_rfind, List.tail_nil,
  List.tail_cons, Bool.true_eq_decide_iff, Part.mem_some_iff, Part.map_bind]
[GOAL]
case intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
x : List ℕ
⊢ (∃ a,
      a ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            (0 :: ↑v) ∧
        x = [Nat.pred (List.headI a)]) ↔
    ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ pure a = x
[PROOFSTEP]
constructor
[GOAL]
case intro.mp
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
x : List ℕ
⊢ (∃ a,
      a ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            (0 :: ↑v) ∧
        x = [Nat.pred (List.headI a)]) →
    ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ pure a = x
[PROOFSTEP]
rintro ⟨v', h1, rfl⟩
[GOAL]
case intro.mp.intro.intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' : List ℕ
h1 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ pure a = [Nat.pred (List.headI v')]
[PROOFSTEP]
suffices
  ∀ v₁ : List ℕ,
    v' ∈
        PFun.fix
          (fun v =>
            (cf.eval v).bind fun y =>
              Part.some <| if y.headI = 0 then Sum.inl (v.headI.succ :: v.tail) else Sum.inr (v.headI.succ :: v.tail))
          v₁ →
      ∀ n,
        (v₁ = n :: v.val) →
          (∀ m < n, ¬f (m ::ᵥ v) = 0) →
            ∃ a : ℕ, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [v'.headI.pred]
  by exact this _ h1 0 rfl (by rintro _ ⟨⟩)
[GOAL]
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' : List ℕ
h1 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
this :
  ∀ (v₁ : List ℕ),
    v' ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          v₁ →
      ∀ (n_1 : ℕ),
        v₁ = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ pure a = [Nat.pred (List.headI v')]
[PROOFSTEP]
exact this _ h1 0 rfl (by rintro _ ⟨⟩)
[GOAL]
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' : List ℕ
h1 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
this :
  ∀ (v₁ : List ℕ),
    v' ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          v₁ →
      ∀ (n_1 : ℕ),
        v₁ = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
⊢ ∀ (m : ℕ), m < 0 → ¬f (m ::ᵥ v) = 0
[PROOFSTEP]
rintro _ ⟨⟩
[GOAL]
case intro.mp.intro.intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' : List ℕ
h1 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
⊢ ∀ (v₁ : List ℕ),
    v' ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          v₁ →
      ∀ (n_1 : ℕ),
        v₁ = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
[PROOFSTEP]
clear h1
[GOAL]
case intro.mp.intro.intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' : List ℕ
⊢ ∀ (v₁ : List ℕ),
    v' ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          v₁ →
      ∀ (n_1 : ℕ),
        v₁ = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
[PROOFSTEP]
intro v₀ h1
[GOAL]
case intro.mp.intro.intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
h1 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      v₀
⊢ ∀ (n_1 : ℕ),
    v₀ = n_1 :: ↑v →
      (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
        ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
[PROOFSTEP]
refine' PFun.fixInduction h1 fun v₁ h2 IH => _
[GOAL]
case intro.mp.intro.intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
h1 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      v₀
v₁ : List ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      v₁
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf v₁) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v₁) :: List.tail v₁)
            else Sum.inr (Nat.succ (List.headI v₁) :: List.tail v₁))) →
      ∀ (n_1 : ℕ),
        a'' = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
⊢ ∀ (n_1 : ℕ),
    v₁ = n_1 :: ↑v →
      (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
        ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
[PROOFSTEP]
clear h1
[GOAL]
case intro.mp.intro.intro
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ v₁ : List ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      v₁
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf v₁) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v₁) :: List.tail v₁)
            else Sum.inr (Nat.succ (List.headI v₁) :: List.tail v₁))) →
      ∀ (n_1 : ℕ),
        a'' = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
⊢ ∀ (n_1 : ℕ),
    v₁ = n_1 :: ↑v →
      (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
        ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
[PROOFSTEP]
rintro n rfl hm
[GOAL]
case intro.mp.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
[PROOFSTEP]
have := PFun.mem_fix_iff.1 h2
[GOAL]
case intro.mp.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
this :
  (Sum.inl v' ∈
      Part.bind (eval cf (n :: ↑v)) fun y =>
        Part.some
          (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
          else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) ∨
    ∃ a',
      (Sum.inr a' ∈
          Part.bind (eval cf (n :: ↑v)) fun y =>
            Part.some
              (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
              else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
[PROOFSTEP]
simp only [hf, Part.bind_some] at this
[GOAL]
case intro.mp.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
this :
  Sum.inl v' ∈
      Part.some
        (if List.headI [f (n ::ᵥ v)] = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
        else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈
          Part.some
            (if List.headI [f (n ::ᵥ v)] = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
[PROOFSTEP]
split_ifs at this  with h
[GOAL]
case pos
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h : List.headI [f (n ::ᵥ v)] = 0
this :
  Sum.inl v' ∈ Part.some (Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
[PROOFSTEP]
simp only [List.headI_nil, List.headI_cons, exists_false, or_false_iff, Part.mem_some_iff, List.tail_cons,
  false_and_iff, Sum.inl.injEq] at this
[GOAL]
case pos
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h : List.headI [f (n ::ᵥ v)] = 0
this : v' = Nat.succ n :: ↑v
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
[PROOFSTEP]
subst this
[GOAL]
case pos
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v₀ : List ℕ
n : ℕ
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h : List.headI [f (n ::ᵥ v)] = 0
h2 :
  Nat.succ n :: ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n_1 : ℕ),
        a'' = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a,
              (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI (Nat.succ n :: ↑v))]
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI (Nat.succ n :: ↑v))]
[PROOFSTEP]
exact ⟨_, ⟨h, @(hm)⟩, rfl⟩
[GOAL]
case neg
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h : ¬List.headI [f (n ::ᵥ v)] = 0
this :
  Sum.inl v' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
⊢ ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
[PROOFSTEP]
refine' IH (n.succ :: v.val) (by simp_all) _ rfl fun m h' => _
[GOAL]
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h : ¬List.headI [f (n ::ᵥ v)] = 0
this :
  Sum.inl v' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
⊢ Sum.inr (Nat.succ n :: ↑v) ∈
    Part.bind (eval cf (n :: ↑v)) fun y =>
      Part.some
        (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
        else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))
[PROOFSTEP]
simp_all
[GOAL]
case neg
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h : ¬List.headI [f (n ::ᵥ v)] = 0
this :
  Sum.inl v' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
m : ℕ
h' : m < Nat.succ n
⊢ ¬f (m ::ᵥ v) = 0
[PROOFSTEP]
obtain h | rfl := Nat.lt_succ_iff_lt_or_eq.1 h'
[GOAL]
case neg.inl
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
n : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (n :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
            else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))) →
      ∀ (n : ℕ),
        a'' = n :: ↑v →
          (∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m : ℕ), m < n → ¬f (m ::ᵥ v) = 0
h✝ : ¬List.headI [f (n ::ᵥ v)] = 0
this :
  Sum.inl v' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
m : ℕ
h' : m < Nat.succ n
h : m < n
⊢ ¬f (m ::ᵥ v) = 0
case neg.inr
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
v' v₀ : List ℕ
m : ℕ
h2 :
  v' ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (m :: ↑v)
IH :
  ∀ (a'' : List ℕ),
    (Sum.inr a'' ∈
        Part.bind (eval cf (m :: ↑v)) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (m :: ↑v)) :: List.tail (m :: ↑v))
            else Sum.inr (Nat.succ (List.headI (m :: ↑v)) :: List.tail (m :: ↑v)))) →
      ∀ (n_1 : ℕ),
        a'' = n_1 :: ↑v →
          (∀ (m : ℕ), m < n_1 → ¬f (m ::ᵥ v) = 0) →
            ∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ [a] = [Nat.pred (List.headI v')]
hm : ∀ (m_1 : ℕ), m_1 < m → ¬f (m_1 ::ᵥ v) = 0
h : ¬List.headI [f (m ::ᵥ v)] = 0
this :
  Sum.inl v' ∈ Part.some (Sum.inr (Nat.succ (List.headI (m :: ↑v)) :: List.tail (m :: ↑v))) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inr (Nat.succ (List.headI (m :: ↑v)) :: List.tail (m :: ↑v))) ∧
        v' ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            a'
h' : m < Nat.succ m
⊢ ¬f (m ::ᵥ v) = 0
[PROOFSTEP]
exacts [hm _ h, h]
[GOAL]
case intro.mpr
n✝ : ℕ
f✝ : Vector ℕ n✝ →. ℕ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
x : List ℕ
⊢ (∃ a, (f (a ::ᵥ v) = 0 ∧ ∀ {m : ℕ}, m < a → ¬f (m ::ᵥ v) = 0) ∧ pure a = x) →
    ∃ a,
      a ∈
          PFun.fix
            (fun v =>
              Part.bind (eval cf v) fun y =>
                Part.some
                  (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                  else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
            (0 :: ↑v) ∧
        x = [Nat.pred (List.headI a)]
[PROOFSTEP]
rintro ⟨n, ⟨hn, hm⟩, rfl⟩
[GOAL]
case intro.mpr.intro.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hn : f (n ::ᵥ v) = 0
hm : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
⊢ ∃ a,
    a ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          (0 :: ↑v) ∧
      pure n = [Nat.pred (List.headI a)]
[PROOFSTEP]
refine' ⟨n.succ :: v.1, _, rfl⟩
[GOAL]
case intro.mpr.intro.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hn : f (n ::ᵥ v) = 0
hm : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
⊢ Nat.succ n :: ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
[PROOFSTEP]
have :
  (n.succ :: v.1 : List ℕ) ∈
    PFun.fix
      (fun v =>
        (cf.eval v).bind fun y =>
          Part.some <| if y.headI = 0 then Sum.inl (v.headI.succ :: v.tail) else Sum.inr (v.headI.succ :: v.tail))
      (n :: v.val) :=
  PFun.mem_fix_iff.2 (Or.inl (by simp [hf, hn]))
[GOAL]
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hn : f (n ::ᵥ v) = 0
hm : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
⊢ Sum.inl (Nat.succ n :: ↑v) ∈
    Part.bind (eval cf (n :: ↑v)) fun y =>
      Part.some
        (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
        else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))
[PROOFSTEP]
simp [hf, hn]
[GOAL]
case intro.mpr.intro.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hn : f (n ::ᵥ v) = 0
hm : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
this :
  Nat.succ n :: ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
⊢ Nat.succ n :: ↑v ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
[PROOFSTEP]
generalize (n.succ :: v.1 : List ℕ) = w at this ⊢
[GOAL]
case intro.mpr.intro.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hn : f (n ::ᵥ v) = 0
hm : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
w : List ℕ
this :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
⊢ w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
[PROOFSTEP]
clear hn
[GOAL]
case intro.mpr.intro.intro.intro
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hm : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
w : List ℕ
this :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
⊢ w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
[PROOFSTEP]
induction' n with n IH
[GOAL]
case intro.mpr.intro.intro.intro.zero
n✝¹ : ℕ
f✝ : Vector ℕ n✝¹ →. ℕ
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n : ℕ
hm✝ : ∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0
w : List ℕ
this✝ :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n :: ↑v)
hm : ∀ {m : ℕ}, m < Nat.zero → ¬f (m ::ᵥ v) = 0
this :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (Nat.zero :: ↑v)
⊢ w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
[PROOFSTEP]
exact this
[GOAL]
case intro.mpr.intro.intro.intro.succ
n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ (n✝¹ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝¹
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n✝ : ℕ
hm✝ : ∀ {m : ℕ}, m < n✝ → ¬f (m ::ᵥ v) = 0
w : List ℕ
this✝ :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n✝ :: ↑v)
n : ℕ
IH :
  (∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0) →
    w ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          (n :: ↑v) →
      w ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          (0 :: ↑v)
hm : ∀ {m : ℕ}, m < Nat.succ n → ¬f (m ::ᵥ v) = 0
this :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (Nat.succ n :: ↑v)
⊢ w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (0 :: ↑v)
[PROOFSTEP]
refine' IH (fun {m} h' => hm (Nat.lt_succ_of_lt h')) (PFun.mem_fix_iff.2 (Or.inr ⟨_, _, this⟩))
[GOAL]
case intro.mpr.intro.intro.intro.succ
n✝² : ℕ
f✝ : Vector ℕ n✝² →. ℕ
n✝¹ : ℕ
f : Vector ℕ (n✝¹ + 1) → ℕ
a✝ : Nat.Partrec' ↑f
cf : Code
v : Vector ℕ n✝¹
hf : ∀ (a : ℕ), eval cf (a :: ↑v) = Part.some [f (a ::ᵥ v)]
n✝ : ℕ
hm✝ : ∀ {m : ℕ}, m < n✝ → ¬f (m ::ᵥ v) = 0
w : List ℕ
this✝ :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (n✝ :: ↑v)
n : ℕ
IH :
  (∀ {m : ℕ}, m < n → ¬f (m ::ᵥ v) = 0) →
    w ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          (n :: ↑v) →
      w ∈
        PFun.fix
          (fun v =>
            Part.bind (eval cf v) fun y =>
              Part.some
                (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
                else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
          (0 :: ↑v)
hm : ∀ {m : ℕ}, m < Nat.succ n → ¬f (m ::ᵥ v) = 0
this :
  w ∈
    PFun.fix
      (fun v =>
        Part.bind (eval cf v) fun y =>
          Part.some
            (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI v) :: List.tail v)
            else Sum.inr (Nat.succ (List.headI v) :: List.tail v)))
      (Nat.succ n :: ↑v)
⊢ Sum.inr (Nat.succ n :: ↑v) ∈
    Part.bind (eval cf (n :: ↑v)) fun y =>
      Part.some
        (if List.headI y = 0 then Sum.inl (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v))
        else Sum.inr (Nat.succ (List.headI (n :: ↑v)) :: List.tail (n :: ↑v)))
[PROOFSTEP]
simp only [hf, hm n.lt_succ_self, Part.bind_some, List.headI, eq_self_iff_true, if_false, Part.mem_some_iff,
  and_self_iff, List.tail_cons]
[GOAL]
k k' : Cont
v : List ℕ
⊢ eval (then k k') v = eval k v >>= eval k'
[PROOFSTEP]
induction' k with _ _ _ _ _ _ _ _ _ k_ih _ _ k_ih generalizing v
[GOAL]
case halt
k' : Cont
v✝ v : List ℕ
⊢ eval (then halt k') v = eval halt v >>= eval k'
[PROOFSTEP]
simp only [Cont.eval, Cont.then, bind_assoc, pure_bind, *]
[GOAL]
case cons₁
k' : Cont
v✝ : List ℕ
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval (then a✝ k') v = eval a✝ v >>= eval k'
v : List ℕ
⊢ eval (then (cons₁ a✝² a✝¹ a✝) k') v = eval (cons₁ a✝² a✝¹ a✝) v >>= eval k'
[PROOFSTEP]
simp only [Cont.eval, Cont.then, bind_assoc, pure_bind, *]
[GOAL]
case cons₂
k' : Cont
v✝ a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval (then a✝ k') v = eval a✝ v >>= eval k'
v : List ℕ
⊢ eval (then (cons₂ a✝¹ a✝) k') v = eval (cons₂ a✝¹ a✝) v >>= eval k'
[PROOFSTEP]
simp only [Cont.eval, Cont.then, bind_assoc, pure_bind, *]
[GOAL]
case comp
k' : Cont
v✝ : List ℕ
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, eval (then a✝ k') v = eval a✝ v >>= eval k'
v : List ℕ
⊢ eval (then (comp a✝¹ a✝) k') v = eval (comp a✝¹ a✝) v >>= eval k'
[PROOFSTEP]
simp only [Cont.eval, Cont.then, bind_assoc, pure_bind, *]
[GOAL]
case fix
k' : Cont
v✝ : List ℕ
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, eval (then a✝ k') v = eval a✝ v >>= eval k'
v : List ℕ
⊢ eval (then (fix a✝¹ a✝) k') v = eval (fix a✝¹ a✝) v >>= eval k'
[PROOFSTEP]
simp only [Cont.eval, Cont.then, bind_assoc, pure_bind, *]
[GOAL]
case comp
k' : Cont
v✝ : List ℕ
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, eval (then a✝ k') v = eval a✝ v >>= eval k'
v : List ℕ
⊢ Code.eval a✝¹ v >>= eval (then a✝ k') = Code.eval a✝¹ v >>= fun x => eval a✝ x >>= eval k'
[PROOFSTEP]
simp only [← k_ih]
[GOAL]
case fix
k' : Cont
v✝ : List ℕ
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, eval (then a✝ k') v = eval a✝ v >>= eval k'
v : List ℕ
⊢ (if List.headI v = 0 then eval a✝ (List.tail v) >>= eval k'
    else Code.eval (Code.fix a✝¹) (List.tail v) >>= eval (then a✝ k')) =
    (if List.headI v = 0 then eval a✝ (List.tail v) else Code.eval (Code.fix a✝¹) (List.tail v) >>= eval a✝) >>= eval k'
[PROOFSTEP]
split_ifs <;> [rfl; simp only [← k_ih, bind_assoc]]
[GOAL]
case fix
k' : Cont
v✝ : List ℕ
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, eval (then a✝ k') v = eval a✝ v >>= eval k'
v : List ℕ
⊢ (if List.headI v = 0 then eval a✝ (List.tail v) >>= eval k'
    else Code.eval (Code.fix a✝¹) (List.tail v) >>= eval (then a✝ k')) =
    (if List.headI v = 0 then eval a✝ (List.tail v) else Code.eval (Code.fix a✝¹) (List.tail v) >>= eval a✝) >>= eval k'
[PROOFSTEP]
split_ifs
[GOAL]
case pos
k' : Cont
v✝ : List ℕ
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, eval (then a✝ k') v = eval a✝ v >>= eval k'
v : List ℕ
h✝ : List.headI v = 0
⊢ eval a✝ (List.tail v) >>= eval k' = eval a✝ (List.tail v) >>= eval k'
[PROOFSTEP]
rfl
[GOAL]
case neg
k' : Cont
v✝ : List ℕ
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, eval (then a✝ k') v = eval a✝ v >>= eval k'
v : List ℕ
h✝ : ¬List.headI v = 0
⊢ Code.eval (Code.fix a✝¹) (List.tail v) >>= eval (then a✝ k') =
    Code.eval (Code.fix a✝¹) (List.tail v) >>= eval a✝ >>= eval k'
[PROOFSTEP]
simp only [← k_ih, bind_assoc]
[GOAL]
c : Code
k k' : Cont
v : List ℕ
⊢ stepNormal c (Cont.then k k') v = Cfg.then (stepNormal c k v) k'
[PROOFSTEP]
induction c generalizing k v
[GOAL]
case zero'
k' k : Cont
v : List ℕ
⊢ stepNormal Code.zero' (Cont.then k k') v = Cfg.then (stepNormal Code.zero' k v) k'
[PROOFSTEP]
simp only [Cont.then, stepNormal, *]
[GOAL]
case succ
k' k : Cont
v : List ℕ
⊢ stepNormal Code.succ (Cont.then k k') v = Cfg.then (stepNormal Code.succ k v) k'
[PROOFSTEP]
simp only [Cont.then, stepNormal, *]
[GOAL]
case tail
k' k : Cont
v : List ℕ
⊢ stepNormal Code.tail (Cont.then k k') v = Cfg.then (stepNormal Code.tail k v) k'
[PROOFSTEP]
simp only [Cont.then, stepNormal, *]
[GOAL]
case cons
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal (Code.cons a✝¹ a✝) (Cont.then k k') v = Cfg.then (stepNormal (Code.cons a✝¹ a✝) k v) k'
[PROOFSTEP]
simp only [Cont.then, stepNormal, *]
[GOAL]
case comp
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal (Code.comp a✝¹ a✝) (Cont.then k k') v = Cfg.then (stepNormal (Code.comp a✝¹ a✝) k v) k'
[PROOFSTEP]
simp only [Cont.then, stepNormal, *]
[GOAL]
case case
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal (Code.case a✝¹ a✝) (Cont.then k k') v = Cfg.then (stepNormal (Code.case a✝¹ a✝) k v) k'
[PROOFSTEP]
simp only [Cont.then, stepNormal, *]
[GOAL]
case fix
k' : Cont
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal (Code.fix a✝) (Cont.then k k') v = Cfg.then (stepNormal (Code.fix a✝) k v) k'
[PROOFSTEP]
simp only [Cont.then, stepNormal, *]
[GOAL]
case zero'
k' k : Cont
v : List ℕ
⊢ Cfg.ret (Cont.then k k') (0 :: v) = Cfg.then (Cfg.ret k (0 :: v)) k'
[PROOFSTEP]
try {simp only [Cfg.then]; done
}
[GOAL]
case zero'
k' k : Cont
v : List ℕ
⊢ Cfg.ret (Cont.then k k') (0 :: v) = Cfg.then (Cfg.ret k (0 :: v)) k'
[PROOFSTEP]
{simp only [Cfg.then]; done
}
[GOAL]
case zero'
k' k : Cont
v : List ℕ
⊢ Cfg.ret (Cont.then k k') (0 :: v) = Cfg.then (Cfg.ret k (0 :: v)) k'
[PROOFSTEP]
simp only [Cfg.then]
[GOAL]

[PROOFSTEP]
done
[GOAL]
case succ
k' k : Cont
v : List ℕ
⊢ Cfg.ret (Cont.then k k') [Nat.succ (List.headI v)] = Cfg.then (Cfg.ret k [Nat.succ (List.headI v)]) k'
[PROOFSTEP]
try {simp only [Cfg.then]; done
}
[GOAL]
case succ
k' k : Cont
v : List ℕ
⊢ Cfg.ret (Cont.then k k') [Nat.succ (List.headI v)] = Cfg.then (Cfg.ret k [Nat.succ (List.headI v)]) k'
[PROOFSTEP]
{simp only [Cfg.then]; done
}
[GOAL]
case succ
k' k : Cont
v : List ℕ
⊢ Cfg.ret (Cont.then k k') [Nat.succ (List.headI v)] = Cfg.then (Cfg.ret k [Nat.succ (List.headI v)]) k'
[PROOFSTEP]
simp only [Cfg.then]
[GOAL]

[PROOFSTEP]
done
[GOAL]
case tail
k' k : Cont
v : List ℕ
⊢ Cfg.ret (Cont.then k k') (List.tail v) = Cfg.then (Cfg.ret k (List.tail v)) k'
[PROOFSTEP]
try {simp only [Cfg.then]; done
}
[GOAL]
case tail
k' k : Cont
v : List ℕ
⊢ Cfg.ret (Cont.then k k') (List.tail v) = Cfg.then (Cfg.ret k (List.tail v)) k'
[PROOFSTEP]
{simp only [Cfg.then]; done
}
[GOAL]
case tail
k' k : Cont
v : List ℕ
⊢ Cfg.ret (Cont.then k k') (List.tail v) = Cfg.then (Cfg.ret k (List.tail v)) k'
[PROOFSTEP]
simp only [Cfg.then]
[GOAL]

[PROOFSTEP]
done
[GOAL]
case cons
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝¹ (Cont.cons₁ a✝ v (Cont.then k k')) v = Cfg.then (stepNormal a✝¹ (Cont.cons₁ a✝ v k) v) k'
[PROOFSTEP]
try {simp only [Cfg.then]; done
}
[GOAL]
case cons
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝¹ (Cont.cons₁ a✝ v (Cont.then k k')) v = Cfg.then (stepNormal a✝¹ (Cont.cons₁ a✝ v k) v) k'
[PROOFSTEP]
{simp only [Cfg.then]; done
}
[GOAL]
case cons
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝¹ (Cont.cons₁ a✝ v (Cont.then k k')) v = Cfg.then (stepNormal a✝¹ (Cont.cons₁ a✝ v k) v) k'
[PROOFSTEP]
simp only [Cfg.then]
[GOAL]
case cons
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝¹ (Cont.cons₁ a✝ v (Cont.then k k')) v =
    (match (motive := Cfg → Cont → Cfg) stepNormal a✝¹ (Cont.cons₁ a✝ v k) v with
      | Cfg.halt v => fun k' => stepRet k' v
      | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
      k'
[PROOFSTEP]
done
[GOAL]
case comp
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝ (Cont.comp a✝¹ (Cont.then k k')) v = Cfg.then (stepNormal a✝ (Cont.comp a✝¹ k) v) k'
[PROOFSTEP]
try {simp only [Cfg.then]; done
}
[GOAL]
case comp
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝ (Cont.comp a✝¹ (Cont.then k k')) v = Cfg.then (stepNormal a✝ (Cont.comp a✝¹ k) v) k'
[PROOFSTEP]
{simp only [Cfg.then]; done
}
[GOAL]
case comp
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝ (Cont.comp a✝¹ (Cont.then k k')) v = Cfg.then (stepNormal a✝ (Cont.comp a✝¹ k) v) k'
[PROOFSTEP]
simp only [Cfg.then]
[GOAL]
case comp
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝ (Cont.comp a✝¹ (Cont.then k k')) v =
    (match (motive := Cfg → Cont → Cfg) stepNormal a✝ (Cont.comp a✝¹ k) v with
      | Cfg.halt v => fun k' => stepRet k' v
      | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
      k'
[PROOFSTEP]
done
[GOAL]
case case
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ Nat.rec (Cfg.then (stepNormal a✝¹ k (List.tail v)) k') (fun y x => Cfg.then (stepNormal a✝ k (y :: List.tail v)) k')
      (List.headI v) =
    Cfg.then (Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v))
      k'
[PROOFSTEP]
try {simp only [Cfg.then]; done
}
[GOAL]
case case
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ Nat.rec (Cfg.then (stepNormal a✝¹ k (List.tail v)) k') (fun y x => Cfg.then (stepNormal a✝ k (y :: List.tail v)) k')
      (List.headI v) =
    Cfg.then (Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v))
      k'
[PROOFSTEP]
{simp only [Cfg.then]; done
}
[GOAL]
case case
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ Nat.rec (Cfg.then (stepNormal a✝¹ k (List.tail v)) k') (fun y x => Cfg.then (stepNormal a✝ k (y :: List.tail v)) k')
      (List.headI v) =
    Cfg.then (Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v))
      k'
[PROOFSTEP]
simp only [Cfg.then]
[GOAL]
case case
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ Nat.rec
      ((match (motive := Cfg → Cont → Cfg) stepNormal a✝¹ k (List.tail v) with
        | Cfg.halt v => fun k' => stepRet k' v
        | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
        k')
      (fun y x =>
        (match (motive := Cfg → Cont → Cfg) stepNormal a✝ k (y :: List.tail v) with
          | Cfg.halt v => fun k' => stepRet k' v
          | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
          k')
      (List.headI v) =
    (match (motive := Cfg → Cont → Cfg)
        Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v) with
      | Cfg.halt v => fun k' => stepRet k' v
      | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
      k'
[PROOFSTEP]
done
[GOAL]
case fix
k' : Cont
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝ (Cont.fix a✝ (Cont.then k k')) v = Cfg.then (stepNormal a✝ (Cont.fix a✝ k) v) k'
[PROOFSTEP]
try {simp only [Cfg.then]; done
}
[GOAL]
case fix
k' : Cont
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝ (Cont.fix a✝ (Cont.then k k')) v = Cfg.then (stepNormal a✝ (Cont.fix a✝ k) v) k'
[PROOFSTEP]
{simp only [Cfg.then]; done
}
[GOAL]
case fix
k' : Cont
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝ (Cont.fix a✝ (Cont.then k k')) v = Cfg.then (stepNormal a✝ (Cont.fix a✝ k) v) k'
[PROOFSTEP]
simp only [Cfg.then]
[GOAL]
case fix
k' : Cont
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝ (Cont.fix a✝ (Cont.then k k')) v =
    (match (motive := Cfg → Cont → Cfg) stepNormal a✝ (Cont.fix a✝ k) v with
      | Cfg.halt v => fun k' => stepRet k' v
      | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
      k'
[PROOFSTEP]
done
[GOAL]
case cons
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝¹ (Cont.cons₁ a✝ v (Cont.then k k')) v = Cfg.then (stepNormal a✝¹ (Cont.cons₁ a✝ v k) v) k'
case comp
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝ (Cont.comp a✝¹ (Cont.then k k')) v = Cfg.then (stepNormal a✝ (Cont.comp a✝¹ k) v) k'
case case
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ Nat.rec (Cfg.then (stepNormal a✝¹ k (List.tail v)) k') (fun y x => Cfg.then (stepNormal a✝ k (y :: List.tail v)) k')
      (List.headI v) =
    Cfg.then (Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v))
      k'
case fix
k' : Cont
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝ (Cont.fix a✝ (Cont.then k k')) v = Cfg.then (stepNormal a✝ (Cont.fix a✝ k) v) k'
[PROOFSTEP]
case cons c c' ih _ => rw [← ih, Cont.then]
[GOAL]
k' : Cont
c c' : Code
ih : ∀ (k : Cont) (v : List ℕ), stepNormal c (Cont.then k k') v = Cfg.then (stepNormal c k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal c' (Cont.then k k') v = Cfg.then (stepNormal c' k v) k'
k : Cont
v : List ℕ
⊢ stepNormal c (Cont.cons₁ c' v (Cont.then k k')) v = Cfg.then (stepNormal c (Cont.cons₁ c' v k) v) k'
[PROOFSTEP]
case cons c c' ih _ => rw [← ih, Cont.then]
[GOAL]
k' : Cont
c c' : Code
ih : ∀ (k : Cont) (v : List ℕ), stepNormal c (Cont.then k k') v = Cfg.then (stepNormal c k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal c' (Cont.then k k') v = Cfg.then (stepNormal c' k v) k'
k : Cont
v : List ℕ
⊢ stepNormal c (Cont.cons₁ c' v (Cont.then k k')) v = Cfg.then (stepNormal c (Cont.cons₁ c' v k) v) k'
[PROOFSTEP]
rw [← ih, Cont.then]
[GOAL]
case comp
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝ (Cont.comp a✝¹ (Cont.then k k')) v = Cfg.then (stepNormal a✝ (Cont.comp a✝¹ k) v) k'
case case
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ Nat.rec (Cfg.then (stepNormal a✝¹ k (List.tail v)) k') (fun y x => Cfg.then (stepNormal a✝ k (y :: List.tail v)) k')
      (List.headI v) =
    Cfg.then (Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v))
      k'
case fix
k' : Cont
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝ (Cont.fix a✝ (Cont.then k k')) v = Cfg.then (stepNormal a✝ (Cont.fix a✝ k) v) k'
[PROOFSTEP]
case comp c c' _ ih' => rw [← ih', Cont.then]
[GOAL]
k' : Cont
c c' : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal c (Cont.then k k') v = Cfg.then (stepNormal c k v) k'
ih' : ∀ (k : Cont) (v : List ℕ), stepNormal c' (Cont.then k k') v = Cfg.then (stepNormal c' k v) k'
k : Cont
v : List ℕ
⊢ stepNormal c' (Cont.comp c (Cont.then k k')) v = Cfg.then (stepNormal c' (Cont.comp c k) v) k'
[PROOFSTEP]
case comp c c' _ ih' => rw [← ih', Cont.then]
[GOAL]
k' : Cont
c c' : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal c (Cont.then k k') v = Cfg.then (stepNormal c k v) k'
ih' : ∀ (k : Cont) (v : List ℕ), stepNormal c' (Cont.then k k') v = Cfg.then (stepNormal c' k v) k'
k : Cont
v : List ℕ
⊢ stepNormal c' (Cont.comp c (Cont.then k k')) v = Cfg.then (stepNormal c' (Cont.comp c k) v) k'
[PROOFSTEP]
rw [← ih', Cont.then]
[GOAL]
case case
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ Nat.rec (Cfg.then (stepNormal a✝¹ k (List.tail v)) k') (fun y x => Cfg.then (stepNormal a✝ k (y :: List.tail v)) k')
      (List.headI v) =
    Cfg.then (Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v))
      k'
[PROOFSTEP]
cases v.headI
[GOAL]
case case.zero
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ Nat.rec (Cfg.then (stepNormal a✝¹ k (List.tail v)) k') (fun y x => Cfg.then (stepNormal a✝ k (y :: List.tail v)) k')
      Nat.zero =
    Cfg.then (Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) Nat.zero) k'
[PROOFSTEP]
simp only [Nat.rec]
[GOAL]
case case.succ
k' : Cont
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝¹ (Cont.then k k') v = Cfg.then (stepNormal a✝¹ k v) k'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
n✝ : ℕ
⊢ Nat.rec (Cfg.then (stepNormal a✝¹ k (List.tail v)) k') (fun y x => Cfg.then (stepNormal a✝ k (y :: List.tail v)) k')
      (Nat.succ n✝) =
    Cfg.then (Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (Nat.succ n✝)) k'
[PROOFSTEP]
simp only [Nat.rec]
[GOAL]
case fix
k' : Cont
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), stepNormal a✝ (Cont.then k k') v = Cfg.then (stepNormal a✝ k v) k'
k : Cont
v : List ℕ
⊢ stepNormal a✝ (Cont.fix a✝ (Cont.then k k')) v = Cfg.then (stepNormal a✝ (Cont.fix a✝ k) v) k'
[PROOFSTEP]
case fix c ih => rw [← ih, Cont.then]
[GOAL]
k' : Cont
c : Code
ih : ∀ (k : Cont) (v : List ℕ), stepNormal c (Cont.then k k') v = Cfg.then (stepNormal c k v) k'
k : Cont
v : List ℕ
⊢ stepNormal c (Cont.fix c (Cont.then k k')) v = Cfg.then (stepNormal c (Cont.fix c k) v) k'
[PROOFSTEP]
case fix c ih => rw [← ih, Cont.then]
[GOAL]
k' : Cont
c : Code
ih : ∀ (k : Cont) (v : List ℕ), stepNormal c (Cont.then k k') v = Cfg.then (stepNormal c k v) k'
k : Cont
v : List ℕ
⊢ stepNormal c (Cont.fix c (Cont.then k k')) v = Cfg.then (stepNormal c (Cont.fix c k) v) k'
[PROOFSTEP]
rw [← ih, Cont.then]
[GOAL]
k k' : Cont
v : List ℕ
⊢ stepRet (Cont.then k k') v = Cfg.then (stepRet k v) k'
[PROOFSTEP]
induction k generalizing v
[GOAL]
case halt
k' : Cont
v : List ℕ
⊢ stepRet (Cont.then Cont.halt k') v = Cfg.then (stepRet Cont.halt v) k'
[PROOFSTEP]
simp only [Cont.then, stepRet, *]
[GOAL]
case cons₁
k' : Cont
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepRet (Cont.then (Cont.cons₁ a✝² a✝¹ a✝) k') v = Cfg.then (stepRet (Cont.cons₁ a✝² a✝¹ a✝) v) k'
[PROOFSTEP]
simp only [Cont.then, stepRet, *]
[GOAL]
case cons₂
k' : Cont
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepRet (Cont.then (Cont.cons₂ a✝¹ a✝) k') v = Cfg.then (stepRet (Cont.cons₂ a✝¹ a✝) v) k'
[PROOFSTEP]
simp only [Cont.then, stepRet, *]
[GOAL]
case comp
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepRet (Cont.then (Cont.comp a✝¹ a✝) k') v = Cfg.then (stepRet (Cont.comp a✝¹ a✝) v) k'
[PROOFSTEP]
simp only [Cont.then, stepRet, *]
[GOAL]
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepRet (Cont.then (Cont.fix a✝¹ a✝) k') v = Cfg.then (stepRet (Cont.fix a✝¹ a✝) v) k'
[PROOFSTEP]
simp only [Cont.then, stepRet, *]
[GOAL]
case halt
k' : Cont
v : List ℕ
⊢ stepRet k' v = Cfg.then (Cfg.halt v) k'
[PROOFSTEP]
try {simp only [Cfg.then]; done
}
[GOAL]
case halt
k' : Cont
v : List ℕ
⊢ stepRet k' v = Cfg.then (Cfg.halt v) k'
[PROOFSTEP]
{simp only [Cfg.then]; done
}
[GOAL]
case halt
k' : Cont
v : List ℕ
⊢ stepRet k' v = Cfg.then (Cfg.halt v) k'
[PROOFSTEP]
simp only [Cfg.then]
[GOAL]

[PROOFSTEP]
done
[GOAL]
case cons₁
k' : Cont
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝² (Cont.cons₂ v (Cont.then a✝ k')) a✝¹ = Cfg.then (stepNormal a✝² (Cont.cons₂ v a✝) a✝¹) k'
[PROOFSTEP]
try {simp only [Cfg.then]; done
}
[GOAL]
case cons₁
k' : Cont
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝² (Cont.cons₂ v (Cont.then a✝ k')) a✝¹ = Cfg.then (stepNormal a✝² (Cont.cons₂ v a✝) a✝¹) k'
[PROOFSTEP]
{simp only [Cfg.then]; done
}
[GOAL]
case cons₁
k' : Cont
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝² (Cont.cons₂ v (Cont.then a✝ k')) a✝¹ = Cfg.then (stepNormal a✝² (Cont.cons₂ v a✝) a✝¹) k'
[PROOFSTEP]
simp only [Cfg.then]
[GOAL]
case cons₁
k' : Cont
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝² (Cont.cons₂ v (Cont.then a✝ k')) a✝¹ =
    (match (motive := Cfg → Cont → Cfg) stepNormal a✝² (Cont.cons₂ v a✝) a✝¹ with
      | Cfg.halt v => fun k' => stepRet k' v
      | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
      k'
[PROOFSTEP]
done
[GOAL]
case comp
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝¹ (Cont.then a✝ k') v = Cfg.then (stepNormal a✝¹ a✝ v) k'
[PROOFSTEP]
try {simp only [Cfg.then]; done
}
[GOAL]
case comp
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝¹ (Cont.then a✝ k') v = Cfg.then (stepNormal a✝¹ a✝ v) k'
[PROOFSTEP]
{simp only [Cfg.then]; done
}
[GOAL]
case comp
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝¹ (Cont.then a✝ k') v = Cfg.then (stepNormal a✝¹ a✝ v) k'
[PROOFSTEP]
simp only [Cfg.then]
[GOAL]
case comp
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝¹ (Cont.then a✝ k') v =
    (match (motive := Cfg → Cont → Cfg) stepNormal a✝¹ a✝ v with
      | Cfg.halt v => fun k' => stepRet k' v
      | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
      k'
[PROOFSTEP]
done
[GOAL]
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'
[PROOFSTEP]
try {simp only [Cfg.then]; done
}
[GOAL]
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'
[PROOFSTEP]
{simp only [Cfg.then]; done
}
[GOAL]
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'
[PROOFSTEP]
simp only [Cfg.then]
[GOAL]
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then
      (match (motive := Cfg → Cont → Cfg) stepRet a✝ (List.tail v) with
        | Cfg.halt v => fun k' => stepRet k' v
        | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
        k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    (match (motive := Cfg → Cont → Cfg)
        if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v) with
      | Cfg.halt v => fun k' => stepRet k' v
      | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
      k'
[PROOFSTEP]
done
[GOAL]
case cons₁
k' : Cont
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝² (Cont.cons₂ v (Cont.then a✝ k')) a✝¹ = Cfg.then (stepNormal a✝² (Cont.cons₂ v a✝) a✝¹) k'
case comp
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝¹ (Cont.then a✝ k') v = Cfg.then (stepNormal a✝¹ a✝ v) k'
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'
[PROOFSTEP]
case cons₁ =>
  rw [← stepNormal_then]
  rfl
[GOAL]
k' : Cont
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝² (Cont.cons₂ v (Cont.then a✝ k')) a✝¹ = Cfg.then (stepNormal a✝² (Cont.cons₂ v a✝) a✝¹) k'
[PROOFSTEP]
case cons₁ =>
  rw [← stepNormal_then]
  rfl
[GOAL]
k' : Cont
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝² (Cont.cons₂ v (Cont.then a✝ k')) a✝¹ = Cfg.then (stepNormal a✝² (Cont.cons₂ v a✝) a✝¹) k'
[PROOFSTEP]
rw [← stepNormal_then]
[GOAL]
k' : Cont
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝² (Cont.cons₂ v (Cont.then a✝ k')) a✝¹ = stepNormal a✝² (Cont.then (Cont.cons₂ v a✝) k') a✝¹
[PROOFSTEP]
rfl
[GOAL]
case comp
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝¹ (Cont.then a✝ k') v = Cfg.then (stepNormal a✝¹ a✝ v) k'
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'
[PROOFSTEP]
case comp => rw [← stepNormal_then]
[GOAL]
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝¹ (Cont.then a✝ k') v = Cfg.then (stepNormal a✝¹ a✝ v) k'
[PROOFSTEP]
case comp => rw [← stepNormal_then]
[GOAL]
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ stepNormal a✝¹ (Cont.then a✝ k') v = Cfg.then (stepNormal a✝¹ a✝ v) k'
[PROOFSTEP]
rw [← stepNormal_then]
[GOAL]
case fix
k' : Cont
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'
[PROOFSTEP]
case fix _ k_ih =>
  split_ifs
  · rw [← k_ih]
  · rw [← stepNormal_then]
    rfl
[GOAL]
k' : Cont
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'
[PROOFSTEP]
case fix _ k_ih =>
  split_ifs
  · rw [← k_ih]
  · rw [← stepNormal_then]
    rfl
[GOAL]
k' : Cont
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
⊢ (if List.headI v = 0 then Cfg.then (stepRet a✝ (List.tail v)) k'
    else stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v)) =
    Cfg.then (if List.headI v = 0 then stepRet a✝ (List.tail v) else stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'
[PROOFSTEP]
split_ifs
[GOAL]
case pos
k' : Cont
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
h✝ : List.headI v = 0
⊢ Cfg.then (stepRet a✝ (List.tail v)) k' = Cfg.then (stepRet a✝ (List.tail v)) k'
[PROOFSTEP]
rw [← k_ih]
[GOAL]
case neg
k' : Cont
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
h✝ : ¬List.headI v = 0
⊢ stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v) =
    Cfg.then (stepNormal a✝¹ (Cont.fix a✝¹ a✝) (List.tail v)) k'
[PROOFSTEP]
rw [← stepNormal_then]
[GOAL]
case neg
k' : Cont
a✝¹ : Code
a✝ : Cont
k_ih : ∀ {v : List ℕ}, stepRet (Cont.then a✝ k') v = Cfg.then (stepRet a✝ v) k'
v : List ℕ
h✝ : ¬List.headI v = 0
⊢ stepNormal a✝¹ (Cont.fix a✝¹ (Cont.then a✝ k')) (List.tail v) =
    stepNormal a✝¹ (Cont.then (Cont.fix a✝¹ a✝) k') (List.tail v)
[PROOFSTEP]
rfl
[GOAL]
c : Code
h : Ok c
v : List ℕ
⊢ Turing.eval step (stepNormal c Cont.halt v) = Cfg.halt <$> eval c v
[PROOFSTEP]
rw [h, ← bind_pure_comp]
[GOAL]
c : Code
h : Ok c
v : List ℕ
⊢ (do
      let v ← eval c v
      Turing.eval step (Cfg.ret Cont.halt v)) =
    do
    let a ← eval c v
    pure (Cfg.halt a)
[PROOFSTEP]
congr
[GOAL]
case e_a
c : Code
h : Ok c
v : List ℕ
⊢ (fun v => Turing.eval step (Cfg.ret Cont.halt v)) = fun a => pure (Cfg.halt a)
[PROOFSTEP]
funext v
[GOAL]
case e_a.h
c : Code
h : Ok c
v✝ v : List ℕ
⊢ Turing.eval step (Cfg.ret Cont.halt v) = pure (Cfg.halt v)
[PROOFSTEP]
exact Part.eq_some_iff.2 (mem_eval.2 ⟨ReflTransGen.single rfl, rfl⟩)
[GOAL]
c : Code
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal c k v = Cfg.ret k' v'
[PROOFSTEP]
induction c generalizing k v
[GOAL]
case zero'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.zero' k v = Cfg.ret k' v'
case succ
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.succ k v = Cfg.ret k' v'
case tail
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.tail k v = Cfg.ret k' v'
case cons
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons a✝¹ a✝) k v = Cfg.ret k' v'
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp a✝¹ a✝) k v = Cfg.ret k' v'
case case
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case a✝¹ a✝) k v = Cfg.ret k' v'
case fix
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix a✝) k v = Cfg.ret k' v'
[PROOFSTEP]
iterate 3 exact ⟨_, _, rfl⟩
[GOAL]
case zero'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.zero' k v = Cfg.ret k' v'
case succ
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.succ k v = Cfg.ret k' v'
case tail
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.tail k v = Cfg.ret k' v'
case cons
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons a✝¹ a✝) k v = Cfg.ret k' v'
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp a✝¹ a✝) k v = Cfg.ret k' v'
case case
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case a✝¹ a✝) k v = Cfg.ret k' v'
case fix
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix a✝) k v = Cfg.ret k' v'
[PROOFSTEP]
exact ⟨_, _, rfl⟩
[GOAL]
case succ
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.succ k v = Cfg.ret k' v'
case tail
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.tail k v = Cfg.ret k' v'
case cons
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons a✝¹ a✝) k v = Cfg.ret k' v'
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp a✝¹ a✝) k v = Cfg.ret k' v'
case case
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case a✝¹ a✝) k v = Cfg.ret k' v'
case fix
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix a✝) k v = Cfg.ret k' v'
[PROOFSTEP]
exact ⟨_, _, rfl⟩
[GOAL]
case tail
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal Code.tail k v = Cfg.ret k' v'
case cons
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons a✝¹ a✝) k v = Cfg.ret k' v'
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp a✝¹ a✝) k v = Cfg.ret k' v'
case case
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case a✝¹ a✝) k v = Cfg.ret k' v'
case fix
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix a✝) k v = Cfg.ret k' v'
[PROOFSTEP]
exact ⟨_, _, rfl⟩
[GOAL]
case cons
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons a✝¹ a✝) k v = Cfg.ret k' v'
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp a✝¹ a✝) k v = Cfg.ret k' v'
case case
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case a✝¹ a✝) k v = Cfg.ret k' v'
case fix
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix a✝) k v = Cfg.ret k' v'
[PROOFSTEP]
case cons _f fs IHf _IHfs => apply IHf
[GOAL]
_f fs : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal _f k v = Cfg.ret k' v'
_IHfs : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal fs k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons _f fs) k v = Cfg.ret k' v'
[PROOFSTEP]
case cons _f fs IHf _IHfs => apply IHf
[GOAL]
_f fs : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal _f k v = Cfg.ret k' v'
_IHfs : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal fs k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.cons _f fs) k v = Cfg.ret k' v'
[PROOFSTEP]
apply IHf
[GOAL]
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp a✝¹ a✝) k v = Cfg.ret k' v'
case case
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case a✝¹ a✝) k v = Cfg.ret k' v'
case fix
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix a✝) k v = Cfg.ret k' v'
[PROOFSTEP]
case comp f _g _IHf IHg => apply IHg
[GOAL]
f _g : Code
_IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal _g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp f _g) k v = Cfg.ret k' v'
[PROOFSTEP]
case comp f _g _IHf IHg => apply IHg
[GOAL]
f _g : Code
_IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal _g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.comp f _g) k v = Cfg.ret k' v'
[PROOFSTEP]
apply IHg
[GOAL]
case case
a✝¹ a✝ : Code
a_ih✝¹ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝¹ k v = Cfg.ret k' v'
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case a✝¹ a✝) k v = Cfg.ret k' v'
case fix
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix a✝) k v = Cfg.ret k' v'
[PROOFSTEP]
case case f g IHf IHg =>
  rw [stepNormal]
  simp only []
  cases v.headI <;> simp only [] <;> [apply IHf; apply IHg]
[GOAL]
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case f g) k v = Cfg.ret k' v'
[PROOFSTEP]
case case f g IHf IHg =>
  rw [stepNormal]
  simp only []
  cases v.headI <;> simp only [] <;> [apply IHf; apply IHg]
[GOAL]
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.case f g) k v = Cfg.ret k' v'
[PROOFSTEP]
rw [stepNormal]
[GOAL]
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v',
    (fun k v => Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v)) k
        v =
      Cfg.ret k' v'
[PROOFSTEP]
simp only []
[GOAL]
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v',
    Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v) = Cfg.ret k' v'
[PROOFSTEP]
cases v.headI <;> simp only [] <;> [apply IHf; apply IHg]
[GOAL]
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v',
    Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v) = Cfg.ret k' v'
[PROOFSTEP]
cases v.headI
[GOAL]
case zero
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v',
    Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) Nat.zero = Cfg.ret k' v'
[PROOFSTEP]
simp only []
[GOAL]
case succ
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
n✝ : ℕ
⊢ ∃ k' v',
    Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (Nat.succ n✝) = Cfg.ret k' v'
[PROOFSTEP]
simp only []
[GOAL]
case zero
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal f k (List.tail v) = Cfg.ret k' v'
[PROOFSTEP]
apply IHf
[GOAL]
case succ
f g : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
IHg : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal g k v = Cfg.ret k' v'
k : Cont
v : List ℕ
n✝ : ℕ
⊢ ∃ k' v', stepNormal g k (n✝ :: List.tail v) = Cfg.ret k' v'
[PROOFSTEP]
apply IHg
[GOAL]
case fix
a✝ : Code
a_ih✝ : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal a✝ k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix a✝) k v = Cfg.ret k' v'
[PROOFSTEP]
case fix f IHf => apply IHf
[GOAL]
f : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix f) k v = Cfg.ret k' v'
[PROOFSTEP]
case fix f IHf => apply IHf
[GOAL]
f : Code
IHf : ∀ (k : Cont) (v : List ℕ), ∃ k' v', stepNormal f k v = Cfg.ret k' v'
k : Cont
v : List ℕ
⊢ ∃ k' v', stepNormal (Code.fix f) k v = Cfg.ret k' v'
[PROOFSTEP]
apply IHf
[GOAL]
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
⊢ eval step (stepNormal f (Cont.fix f k) v) = do
    let v ← Code.eval (Code.fix f) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
refine' Part.ext fun x => _
[GOAL]
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v) ↔
    x ∈ do
      let v ← Code.eval (Code.fix f) v
      eval step (Cfg.ret k v)
[PROOFSTEP]
simp only [Part.bind_eq_bind, Part.mem_bind_iff]
[GOAL]
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v) ↔ ∃ a, a ∈ Code.eval (Code.fix f) v ∧ x ∈ eval step (Cfg.ret k a)
[PROOFSTEP]
constructor
[GOAL]
case mp
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v) → ∃ a, a ∈ Code.eval (Code.fix f) v ∧ x ∈ eval step (Cfg.ret k a)
[PROOFSTEP]
suffices
  ∀ c,
    x ∈ eval step c →
      ∀ v c',
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁ ∈ f.eval v,
              ∃ v₂ ∈ if List.headI v₁ = 0 then pure v₁.tail else f.fix.eval v₁.tail, x ∈ eval step (Cfg.ret k v₂)
  by
  intro h
  obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ := this _ h _ _ (stepNormal_then _ Cont.halt _ _) ReflTransGen.refl
  refine' ⟨v₂, PFun.mem_fix_iff.2 _, h₃⟩
  simp only [Part.eq_some_iff.2 hv₁, Part.map_some]
  split_ifs at hv₂ ⊢
  · rw [Part.mem_some_iff.1 hv₂]
    exact Or.inl (Part.mem_some _)
  · exact Or.inr ⟨_, Part.mem_some _, hv₂⟩
[GOAL]
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v) → ∃ a, a ∈ Code.eval (Code.fix f) v ∧ x ∈ eval step (Cfg.ret k a)
[PROOFSTEP]
intro h
[GOAL]
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
h : x ∈ eval step (stepNormal f (Cont.fix f k) v)
⊢ ∃ a, a ∈ Code.eval (Code.fix f) v ∧ x ∈ eval step (Cfg.ret k a)
[PROOFSTEP]
obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ := this _ h _ _ (stepNormal_then _ Cont.halt _ _) ReflTransGen.refl
[GOAL]
case intro.intro.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
h : x ∈ eval step (stepNormal f (Cont.fix f k) v)
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f v
v₂ : List ℕ
hv₂ : v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)
h₃ : x ∈ eval step (Cfg.ret k v₂)
⊢ ∃ a, a ∈ Code.eval (Code.fix f) v ∧ x ∈ eval step (Cfg.ret k a)
[PROOFSTEP]
refine' ⟨v₂, PFun.mem_fix_iff.2 _, h₃⟩
[GOAL]
case intro.intro.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
h : x ∈ eval step (stepNormal f (Cont.fix f k) v)
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f v
v₂ : List ℕ
hv₂ : v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)
h₃ : x ∈ eval step (Cfg.ret k v₂)
⊢ Sum.inl v₂ ∈
      Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) ∨
    ∃ a',
      Sum.inr a' ∈
          Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
            (Code.eval f v) ∧
        v₂ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'
[PROOFSTEP]
simp only [Part.eq_some_iff.2 hv₁, Part.map_some]
[GOAL]
case intro.intro.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
h : x ∈ eval step (stepNormal f (Cont.fix f k) v)
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f v
v₂ : List ℕ
hv₂ : v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)
h₃ : x ∈ eval step (Cfg.ret k v₂)
⊢ Sum.inl v₂ ∈ Part.some (if List.headI v₁ = 0 then Sum.inl (List.tail v₁) else Sum.inr (List.tail v₁)) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (if List.headI v₁ = 0 then Sum.inl (List.tail v₁) else Sum.inr (List.tail v₁)) ∧
        v₂ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'
[PROOFSTEP]
split_ifs at hv₂ ⊢
[GOAL]
case pos
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
h : x ∈ eval step (stepNormal f (Cont.fix f k) v)
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f v
v₂ : List ℕ
h₃ : x ∈ eval step (Cfg.ret k v₂)
h✝ : List.headI v₁ = 0
hv₂ : v₂ ∈ pure (List.tail v₁)
⊢ Sum.inl v₂ ∈ Part.some (Sum.inl (List.tail v₁)) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inl (List.tail v₁)) ∧
        v₂ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'
[PROOFSTEP]
rw [Part.mem_some_iff.1 hv₂]
[GOAL]
case pos
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
h : x ∈ eval step (stepNormal f (Cont.fix f k) v)
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f v
v₂ : List ℕ
h₃ : x ∈ eval step (Cfg.ret k v₂)
h✝ : List.headI v₁ = 0
hv₂ : v₂ ∈ pure (List.tail v₁)
⊢ Sum.inl (List.tail v₁) ∈ Part.some (Sum.inl (List.tail v₁)) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inl (List.tail v₁)) ∧
        List.tail v₁ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'
[PROOFSTEP]
exact Or.inl (Part.mem_some _)
[GOAL]
case neg
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
this :
  ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
h : x ∈ eval step (stepNormal f (Cont.fix f k) v)
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f v
v₂ : List ℕ
h₃ : x ∈ eval step (Cfg.ret k v₂)
h✝ : ¬List.headI v₁ = 0
hv₂ : v₂ ∈ Code.eval (Code.fix f) (List.tail v₁)
⊢ Sum.inl v₂ ∈ Part.some (Sum.inr (List.tail v₁)) ∨
    ∃ a',
      Sum.inr a' ∈ Part.some (Sum.inr (List.tail v₁)) ∧
        v₂ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'
[PROOFSTEP]
exact Or.inr ⟨_, Part.mem_some _, hv₂⟩
[GOAL]
case mp
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
⊢ ∀ (c : Cfg),
    x ∈ eval step c →
      ∀ (v : List ℕ) (c' : Cfg),
        c = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
refine' fun c he => evalInduction he fun y h IH => _
[GOAL]
case mp
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
y : Cfg
h : x ∈ eval step y
IH :
  ∀ (a' : Cfg),
    step y = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
⊢ ∀ (v : List ℕ) (c' : Cfg),
    y = Cfg.then c' (Cont.fix f k) →
      Reaches step (stepNormal f Cont.halt v) c' →
        ∃ v₁,
          v₁ ∈ Code.eval f v ∧
            ∃ v₂,
              (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
rintro v (⟨v'⟩ | ⟨k', v'⟩) rfl hr
[GOAL]
case mp.halt
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (Cfg.then (Cfg.halt v') (Cont.fix f k))
IH :
  ∀ (a' : Cfg),
    step (Cfg.then (Cfg.halt v') (Cont.fix f k)) = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ v₂,
        (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
          x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
rw [Cfg.then] at h IH
[GOAL]
case mp.ret
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v : List ℕ
k' : Cont
v' : List ℕ
h : x ∈ eval step (Cfg.then (Cfg.ret k' v') (Cont.fix f k))
IH :
  ∀ (a' : Cfg),
    step (Cfg.then (Cfg.ret k' v') (Cont.fix f k)) = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.ret k' v')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ v₂,
        (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
          x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
rw [Cfg.then] at h IH
[GOAL]
case mp.halt
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h :
  x ∈
    eval step
      ((match (motive := Cfg → Cont → Cfg) Cfg.halt v' with
        | Cfg.halt v => fun k' => stepRet k' v
        | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
        (Cont.fix f k))
IH :
  ∀ (a' : Cfg),
    step
          ((match (motive := Cfg → Cont → Cfg) Cfg.halt v' with
            | Cfg.halt v => fun k' => stepRet k' v
            | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
            (Cont.fix f k)) =
        some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ v₂,
        (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
          x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
simp only [] at h IH
[GOAL]
case mp.ret
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v : List ℕ
k' : Cont
v' : List ℕ
h :
  x ∈
    eval step
      ((match (motive := Cfg → Cont → Cfg) Cfg.ret k' v' with
        | Cfg.halt v => fun k' => stepRet k' v
        | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
        (Cont.fix f k))
IH :
  ∀ (a' : Cfg),
    step
          ((match (motive := Cfg → Cont → Cfg) Cfg.ret k' v' with
            | Cfg.halt v => fun k' => stepRet k' v
            | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
            (Cont.fix f k)) =
        some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.ret k' v')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ v₂,
        (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
          x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
simp only [] at h IH
[GOAL]
case mp.halt
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ v₂,
        (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
          x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
have := mem_eval.2 ⟨hr, rfl⟩
[GOAL]
case mp.halt
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
this : Cfg.halt v' ∈ eval step (stepNormal f Cont.halt v)
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ v₂,
        (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
          x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
rw [fok, Part.bind_eq_bind, Part.mem_bind_iff] at this
[GOAL]
case mp.halt
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
this : ∃ a, a ∈ Code.eval f v ∧ Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt a)
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ v₂,
        (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
          x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
obtain ⟨v'', h₁, h₂⟩ := this
[GOAL]
case mp.halt.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ v₂,
        (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
          x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
rw [reaches_eval] at h₂
[GOAL]
case mp.halt.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
h₂ : Cfg.halt v' ∈ eval step ?m.194513
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ v₂,
        (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
          x ∈ eval step (Cfg.ret k v₂)
case mp.halt.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
⊢ Reaches step (Cfg.ret Cont.halt v'') ?m.194513
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
⊢ Cfg
[PROOFSTEP]
swap
[GOAL]
case mp.halt.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
⊢ Reaches step (Cfg.ret Cont.halt v'') ?m.194513
case mp.halt.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
h₂ : Cfg.halt v' ∈ eval step ?m.194513
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ v₂,
        (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
          x ∈ eval step (Cfg.ret k v₂)
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
⊢ Cfg
[PROOFSTEP]
exact ReflTransGen.single rfl
[GOAL]
case mp.halt.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
v'' : List ℕ
h₁ : v'' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v'')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v'')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ v₂,
        (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
          x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
cases Part.mem_unique h₂ (mem_eval.2 ⟨ReflTransGen.refl, rfl⟩)
[GOAL]
case mp.halt.intro.intro.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ v₂,
        (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
          x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
refine' ⟨v', h₁, _⟩
[GOAL]
case mp.halt.intro.intro.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (stepRet (Cont.fix f k) v')
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
⊢ ∃ v₂,
    (v₂ ∈ if List.headI v' = 0 then pure (List.tail v') else Code.eval (Code.fix f) (List.tail v')) ∧
      x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
rw [stepRet] at h
[GOAL]
case mp.halt.intro.intro.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
h : x ∈ eval step (if List.headI v' = 0 then stepRet k (List.tail v') else stepNormal f (Cont.fix f k) (List.tail v'))
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
⊢ ∃ v₂,
    (v₂ ∈ if List.headI v' = 0 then pure (List.tail v') else Code.eval (Code.fix f) (List.tail v')) ∧
      x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
revert h
[GOAL]
case mp.halt.intro.intro.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
⊢ x ∈ eval step (if List.headI v' = 0 then stepRet k (List.tail v') else stepNormal f (Cont.fix f k) (List.tail v')) →
    ∃ v₂,
      (v₂ ∈ if List.headI v' = 0 then pure (List.tail v') else Code.eval (Code.fix f) (List.tail v')) ∧
        x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
by_cases he : v'.headI = 0
[GOAL]
case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
⊢ x ∈ eval step (if List.headI v' = 0 then stepRet k (List.tail v') else stepNormal f (Cont.fix f k) (List.tail v')) →
    ∃ v₂,
      (v₂ ∈ if List.headI v' = 0 then pure (List.tail v') else Code.eval (Code.fix f) (List.tail v')) ∧
        x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
simp only [exists_prop, if_pos, if_false, he]
[GOAL]
case neg
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
⊢ x ∈ eval step (if List.headI v' = 0 then stepRet k (List.tail v') else stepNormal f (Cont.fix f k) (List.tail v')) →
    ∃ v₂,
      (v₂ ∈ if List.headI v' = 0 then pure (List.tail v') else Code.eval (Code.fix f) (List.tail v')) ∧
        x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
simp only [exists_prop, if_pos, if_false, he]
[GOAL]
case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
⊢ x ∈ eval step (stepRet k (List.tail v')) → ∃ v₂, v₂ ∈ pure (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
intro h
[GOAL]
case neg
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v')) →
    ∃ v₂, v₂ ∈ Code.eval (Code.fix f) (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
intro h
[GOAL]
case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
h : x ∈ eval step (stepRet k (List.tail v'))
⊢ ∃ v₂, v₂ ∈ pure (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
refine' ⟨_, Part.mem_some _, _⟩
[GOAL]
case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
h : x ∈ eval step (stepRet k (List.tail v'))
⊢ x ∈ eval step (Cfg.ret k (List.tail v'))
[PROOFSTEP]
rw [reaches_eval]
[GOAL]
case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
h : x ∈ eval step (stepRet k (List.tail v'))
⊢ x ∈ eval step ?m.195505
case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
h : x ∈ eval step (stepRet k (List.tail v'))
⊢ Reaches step (Cfg.ret k (List.tail v')) ?m.195505
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
h : x ∈ eval step (stepRet k (List.tail v'))
⊢ Cfg
[PROOFSTEP]
exact h
[GOAL]
case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : List.headI v' = 0
h : x ∈ eval step (stepRet k (List.tail v'))
⊢ Reaches step (Cfg.ret k (List.tail v')) (stepRet k (List.tail v'))
[PROOFSTEP]
exact ReflTransGen.single rfl
[GOAL]
case neg
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
⊢ ∃ v₂, v₂ ∈ Code.eval (Code.fix f) (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
obtain ⟨k₀, v₀, e₀⟩ := stepNormal.is_ret f Cont.halt v'.tail
[GOAL]
case neg.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
⊢ ∃ v₂, v₂ ∈ Code.eval (Code.fix f) (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
have e₁ := stepNormal_then f Cont.halt (Cont.fix f k) v'.tail
[GOAL]
case neg.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ :
  stepNormal f (Cont.then Cont.halt (Cont.fix f k)) (List.tail v') =
    Cfg.then (stepNormal f Cont.halt (List.tail v')) (Cont.fix f k)
⊢ ∃ v₂, v₂ ∈ Code.eval (Code.fix f) (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
rw [e₀, Cont.then, Cfg.then] at e₁
[GOAL]
case neg.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ :
  stepNormal f ((fun k' => k') (Cont.fix f k)) (List.tail v') =
    (match (motive := Cfg → Cont → Cfg) Cfg.ret k₀ v₀ with
      | Cfg.halt v => fun k' => stepRet k' v
      | Cfg.ret k v => fun k' => Cfg.ret (Cont.then k k') v)
      (Cont.fix f k)
⊢ ∃ v₂, v₂ ∈ Code.eval (Code.fix f) (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
simp only [] at e₁
[GOAL]
case neg.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
⊢ ∃ v₂, v₂ ∈ Code.eval (Code.fix f) (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ :=
  IH (stepRet (k₀.then (Cont.fix f k)) v₀) (by rw [stepRet, if_neg he, e₁]; rfl) v'.tail _ stepRet_then
    (by apply ReflTransGen.single; rw [e₀]; rfl)
[GOAL]
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
⊢ step (stepRet (Cont.fix f k) v') = some (stepRet (Cont.then k₀ (Cont.fix f k)) v₀)
[PROOFSTEP]
rw [stepRet, if_neg he, e₁]
[GOAL]
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
⊢ step (Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀) = some (stepRet (Cont.then k₀ (Cont.fix f k)) v₀)
[PROOFSTEP]
rfl
[GOAL]
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
⊢ Reaches step (stepNormal f Cont.halt (List.tail v')) (stepRet k₀ v₀)
[PROOFSTEP]
apply ReflTransGen.single
[GOAL]
case hab
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
⊢ stepRet k₀ v₀ ∈ step (stepNormal f Cont.halt (List.tail v'))
[PROOFSTEP]
rw [e₀]
[GOAL]
case hab
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
⊢ stepRet k₀ v₀ ∈ step (Cfg.ret k₀ v₀)
[PROOFSTEP]
rfl
[GOAL]
case neg.intro.intro.intro.intro.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f (List.tail v')
v₂ : List ℕ
hv₂ : v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)
h₃ : x ∈ eval step (Cfg.ret k v₂)
⊢ ∃ v₂, v₂ ∈ Code.eval (Code.fix f) (List.tail v') ∧ x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
refine' ⟨_, PFun.mem_fix_iff.2 _, h₃⟩
[GOAL]
case neg.intro.intro.intro.intro.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f (List.tail v')
v₂ : List ℕ
hv₂ : v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)
h₃ : x ∈ eval step (Cfg.ret k v₂)
⊢ Sum.inl v₂ ∈
      Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
        (Code.eval f (List.tail v')) ∨
    ∃ a',
      Sum.inr a' ∈
          Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
            (Code.eval f (List.tail v')) ∧
        v₂ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'
[PROOFSTEP]
simp only [Part.eq_some_iff.2 hv₁, Part.map_some, Part.mem_some_iff]
[GOAL]
case neg.intro.intro.intro.intro.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f (List.tail v')
v₂ : List ℕ
hv₂ : v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)
h₃ : x ∈ eval step (Cfg.ret k v₂)
⊢ (Sum.inl v₂ = if List.headI v₁ = 0 then Sum.inl (List.tail v₁) else Sum.inr (List.tail v₁)) ∨
    ∃ a',
      (Sum.inr a' = if List.headI v₁ = 0 then Sum.inl (List.tail v₁) else Sum.inr (List.tail v₁)) ∧
        v₂ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'
[PROOFSTEP]
split_ifs at hv₂ ⊢ <;> [exact Or.inl (congr_arg Sum.inl (Part.mem_some_iff.1 hv₂)); exact Or.inr ⟨_, rfl, hv₂⟩]
[GOAL]
case neg.intro.intro.intro.intro.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f (List.tail v')
v₂ : List ℕ
hv₂ : v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)
h₃ : x ∈ eval step (Cfg.ret k v₂)
⊢ (Sum.inl v₂ = if List.headI v₁ = 0 then Sum.inl (List.tail v₁) else Sum.inr (List.tail v₁)) ∨
    ∃ a',
      (Sum.inr a' = if List.headI v₁ = 0 then Sum.inl (List.tail v₁) else Sum.inr (List.tail v₁)) ∧
        v₂ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'
[PROOFSTEP]
split_ifs at hv₂ ⊢
[GOAL]
case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f (List.tail v')
v₂ : List ℕ
h₃ : x ∈ eval step (Cfg.ret k v₂)
h✝ : List.headI v₁ = 0
hv₂ : v₂ ∈ pure (List.tail v₁)
⊢ Sum.inl v₂ = Sum.inl (List.tail v₁) ∨
    ∃ a',
      False ∧
        v₂ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'
[PROOFSTEP]
exact Or.inl (congr_arg Sum.inl (Part.mem_some_iff.1 hv₂))
[GOAL]
case neg
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he✝ : x ∈ eval step c
v v' : List ℕ
IH :
  ∀ (a' : Cfg),
    step (stepRet (Cont.fix f k) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.halt v')
h₁ : v' ∈ Code.eval f v
h₂✝ : Cfg.halt v' ∈ eval step (Cfg.ret Cont.halt v')
h₂ : Cfg.halt v' ∈ eval step (stepRet Cont.halt v')
he : ¬List.headI v' = 0
h : x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v'))
k₀ : Cont
v₀ : List ℕ
e₀ : stepNormal f Cont.halt (List.tail v') = Cfg.ret k₀ v₀
e₁ : stepNormal f (Cont.fix f k) (List.tail v') = Cfg.ret (Cont.then k₀ (Cont.fix f k)) v₀
v₁ : List ℕ
hv₁ : v₁ ∈ Code.eval f (List.tail v')
v₂ : List ℕ
h₃ : x ∈ eval step (Cfg.ret k v₂)
h✝ : ¬List.headI v₁ = 0
hv₂ : v₂ ∈ Code.eval (Code.fix f) (List.tail v₁)
⊢ False ∨
    ∃ a',
      Sum.inr a' = Sum.inr (List.tail v₁) ∧
        v₂ ∈
          PFun.fix
            (fun v =>
              Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v))
                (Code.eval f v))
            a'
[PROOFSTEP]
exact Or.inr ⟨_, rfl, hv₂⟩
[GOAL]
case mp.ret
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x c : Cfg
he : x ∈ eval step c
v : List ℕ
k' : Cont
v' : List ℕ
h : x ∈ eval step (Cfg.ret (Cont.then k' (Cont.fix f k)) v')
IH :
  ∀ (a' : Cfg),
    step (Cfg.ret (Cont.then k' (Cont.fix f k)) v') = some a' →
      ∀ (v : List ℕ) (c' : Cfg),
        a' = Cfg.then c' (Cont.fix f k) →
          Reaches step (stepNormal f Cont.halt v) c' →
            ∃ v₁,
              v₁ ∈ Code.eval f v ∧
                ∃ v₂,
                  (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
                    x ∈ eval step (Cfg.ret k v₂)
hr : Reaches step (stepNormal f Cont.halt v) (Cfg.ret k' v')
⊢ ∃ v₁,
    v₁ ∈ Code.eval f v ∧
      ∃ v₂,
        (v₂ ∈ if List.headI v₁ = 0 then pure (List.tail v₁) else Code.eval (Code.fix f) (List.tail v₁)) ∧
          x ∈ eval step (Cfg.ret k v₂)
[PROOFSTEP]
exact IH _ rfl _ _ stepRet_then (ReflTransGen.tail hr rfl)
[GOAL]
case mpr
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
⊢ (∃ a, a ∈ Code.eval (Code.fix f) v ∧ x ∈ eval step (Cfg.ret k a)) → x ∈ eval step (stepNormal f (Cont.fix f k) v)
[PROOFSTEP]
rintro ⟨v', he, hr⟩
[GOAL]
case mpr.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr : x ∈ eval step (Cfg.ret k v')
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v)
[PROOFSTEP]
rw [reaches_eval] at hr
[GOAL]
case mpr.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step ?m.197483
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v)
case mpr.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr : x ∈ eval step (Cfg.ret k v')
⊢ Reaches step (Cfg.ret k v') ?m.197483
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr : x ∈ eval step (Cfg.ret k v')
⊢ Cfg
[PROOFSTEP]
swap
[GOAL]
case mpr.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr : x ∈ eval step (Cfg.ret k v')
⊢ Reaches step (Cfg.ret k v') ?m.197483
case mpr.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step ?m.197483
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v)
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr : x ∈ eval step (Cfg.ret k v')
⊢ Cfg
[PROOFSTEP]
exact ReflTransGen.single rfl
[GOAL]
case mpr.intro.intro
f : Code
k : Cont
v : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v)
[PROOFSTEP]
refine' PFun.fixInduction he fun v (he : v' ∈ f.fix.eval v) IH => _
[GOAL]
case mpr.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) v)
[PROOFSTEP]
rw [fok, Part.bind_eq_bind, Part.mem_bind_iff]
[GOAL]
case mpr.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)
[PROOFSTEP]
obtain he | ⟨v'', he₁', _⟩ := PFun.mem_fix_iff.1 he
[GOAL]
case mpr.intro.intro.inl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝¹ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
he :
  Sum.inl v' ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)
[PROOFSTEP]
obtain ⟨v', he₁, he₂⟩ := (Part.mem_map_iff _).1 he
[GOAL]
case mpr.intro.intro.inl.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v'✝ : List ℕ
he✝¹ : v'✝ ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v'✝)
hr : x ∈ eval step (stepRet k v'✝)
v : List ℕ
he✝ : v'✝ ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
he :
  Sum.inl v'✝ ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
v' : List ℕ
he₁ : v' ∈ Code.eval f v
he₂ : (if List.headI v' = 0 then Sum.inl (List.tail v') else Sum.inr (List.tail v')) = Sum.inl v'✝
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)
[PROOFSTEP]
split_ifs at he₂  with h
[GOAL]
case pos
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v'✝ : List ℕ
he✝¹ : v'✝ ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v'✝)
hr : x ∈ eval step (stepRet k v'✝)
v : List ℕ
he✝ : v'✝ ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
he :
  Sum.inl v'✝ ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he₂ : Sum.inl (List.tail v') = Sum.inl v'✝
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)
[PROOFSTEP]
cases he₂
[GOAL]
case pos.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail v') ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)
[PROOFSTEP]
refine' ⟨_, he₁, _⟩
[GOAL]
case pos.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail v') ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
⊢ x ∈ eval step (Cfg.ret (Cont.fix f k) v')
[PROOFSTEP]
rw [reaches_eval]
[GOAL]
case pos.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail v') ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
⊢ x ∈ eval step ?m.198384
case pos.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail v') ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
⊢ Reaches step (Cfg.ret (Cont.fix f k) v') ?m.198384
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail v') ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
⊢ Cfg
[PROOFSTEP]
swap
[GOAL]
case pos.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail v') ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
⊢ Reaches step (Cfg.ret (Cont.fix f k) v') ?m.198384
case pos.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail v') ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
⊢ x ∈ eval step ?m.198384
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail v') ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
⊢ Cfg
[PROOFSTEP]
exact ReflTransGen.single rfl
[GOAL]
case pos.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v : List ℕ
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v' : List ℕ
he₁ : v' ∈ Code.eval f v
h : List.headI v' = 0
he✝¹ : List.tail v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k (List.tail v'))
hr : x ∈ eval step (stepRet k (List.tail v'))
he✝ : List.tail v' ∈ Code.eval (Code.fix f) v
he :
  Sum.inl (List.tail v') ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
⊢ x ∈ eval step (stepRet (Cont.fix f k) v')
[PROOFSTEP]
rwa [stepRet, if_pos h]
[GOAL]
case mpr.intro.intro.inr.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v'' : List ℕ
he₁' :
  Sum.inr v'' ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      v''
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)
[PROOFSTEP]
obtain ⟨v₁, he₁, he₂⟩ := (Part.mem_map_iff _).1 he₁'
[GOAL]
case mpr.intro.intro.inr.intro.intro.intro.intro
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v'' : List ℕ
he₁' :
  Sum.inr v'' ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      v''
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
he₂ : (if List.headI v₁ = 0 then Sum.inl (List.tail v₁) else Sum.inr (List.tail v₁)) = Sum.inr v''
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)
[PROOFSTEP]
split_ifs at he₂  with h
[GOAL]
case neg
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v'' : List ℕ
he₁' :
  Sum.inr v'' ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      v''
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
he₂ : Sum.inr (List.tail v₁) = Sum.inr v''
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)
[PROOFSTEP]
cases he₂
[GOAL]
case neg.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
he₁' :
  Sum.inr (List.tail v₁) ∈
    Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v)
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      (List.tail v₁)
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)
[PROOFSTEP]
clear he₁'
[GOAL]
case neg.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      (List.tail v₁)
⊢ ∃ a, a ∈ Code.eval f v ∧ x ∈ eval step (Cfg.ret (Cont.fix f k) a)
[PROOFSTEP]
refine' ⟨_, he₁, _⟩
[GOAL]
case neg.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      (List.tail v₁)
⊢ x ∈ eval step (Cfg.ret (Cont.fix f k) v₁)
[PROOFSTEP]
rw [reaches_eval]
[GOAL]
case neg.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      (List.tail v₁)
⊢ x ∈ eval step ?m.199070
case neg.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      (List.tail v₁)
⊢ Reaches step (Cfg.ret (Cont.fix f k) v₁) ?m.199070
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      (List.tail v₁)
⊢ Cfg
[PROOFSTEP]
swap
[GOAL]
case neg.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      (List.tail v₁)
⊢ Reaches step (Cfg.ret (Cont.fix f k) v₁) ?m.199070
case neg.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      (List.tail v₁)
⊢ x ∈ eval step ?m.199070
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      (List.tail v₁)
⊢ Cfg
[PROOFSTEP]
exact ReflTransGen.single rfl
[GOAL]
case neg.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      (List.tail v₁)
⊢ x ∈ eval step (stepRet (Cont.fix f k) v₁)
[PROOFSTEP]
rw [stepRet, if_neg h]
[GOAL]
case neg.refl
f : Code
k : Cont
v✝ : List ℕ
fok : Code.Ok f
x : Cfg
v' : List ℕ
he✝ : v' ∈ Code.eval (Code.fix f) v✝
hr✝ : x ∈ eval step (Cfg.ret k v')
hr : x ∈ eval step (stepRet k v')
v : List ℕ
he : v' ∈ Code.eval (Code.fix f) v
IH :
  ∀ (a'' : List ℕ),
    Sum.inr a'' ∈
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v) →
      x ∈ eval step (stepNormal f (Cont.fix f k) a'')
v₁ : List ℕ
he₁ : v₁ ∈ Code.eval f v
h : ¬List.headI v₁ = 0
right✝ :
  v' ∈
    PFun.fix
      (fun v =>
        Part.map (fun v => if List.headI v = 0 then Sum.inl (List.tail v) else Sum.inr (List.tail v)) (Code.eval f v))
      (List.tail v₁)
⊢ x ∈ eval step (stepNormal f (Cont.fix f k) (List.tail v₁))
[PROOFSTEP]
exact IH v₁.tail ((Part.mem_map_iff _).2 ⟨_, he₁, if_neg h⟩)
[GOAL]
c : Code
⊢ Code.Ok c
[PROOFSTEP]
induction c
[GOAL]
case zero'
⊢ Code.Ok Code.zero'
[PROOFSTEP]
intro k v
[GOAL]
case succ
⊢ Code.Ok Code.succ
[PROOFSTEP]
intro k v
[GOAL]
case tail
⊢ Code.Ok Code.tail
[PROOFSTEP]
intro k v
[GOAL]
case cons
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
⊢ Code.Ok (Code.cons a✝¹ a✝)
[PROOFSTEP]
intro k v
[GOAL]
case comp
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
⊢ Code.Ok (Code.comp a✝¹ a✝)
[PROOFSTEP]
intro k v
[GOAL]
case case
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
⊢ Code.Ok (Code.case a✝¹ a✝)
[PROOFSTEP]
intro k v
[GOAL]
case fix
a✝ : Code
a_ih✝ : Code.Ok a✝
⊢ Code.Ok (Code.fix a✝)
[PROOFSTEP]
intro k v
[GOAL]
case zero'
k : Cont
v : List ℕ
⊢ eval step (stepNormal Code.zero' k v) = do
    let v ← Code.eval Code.zero' v
    eval step (Cfg.ret k v)
[PROOFSTEP]
rw [stepNormal]
[GOAL]
case succ
k : Cont
v : List ℕ
⊢ eval step (stepNormal Code.succ k v) = do
    let v ← Code.eval Code.succ v
    eval step (Cfg.ret k v)
[PROOFSTEP]
rw [stepNormal]
[GOAL]
case tail
k : Cont
v : List ℕ
⊢ eval step (stepNormal Code.tail k v) = do
    let v ← Code.eval Code.tail v
    eval step (Cfg.ret k v)
[PROOFSTEP]
rw [stepNormal]
[GOAL]
case cons
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step (stepNormal (Code.cons a✝¹ a✝) k v) = do
    let v ← Code.eval (Code.cons a✝¹ a✝) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
rw [stepNormal]
[GOAL]
case comp
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step (stepNormal (Code.comp a✝¹ a✝) k v) = do
    let v ← Code.eval (Code.comp a✝¹ a✝) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
rw [stepNormal]
[GOAL]
case case
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step (stepNormal (Code.case a✝¹ a✝) k v) = do
    let v ← Code.eval (Code.case a✝¹ a✝) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
rw [stepNormal]
[GOAL]
case fix
a✝ : Code
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step (stepNormal (Code.fix a✝) k v) = do
    let v ← Code.eval (Code.fix a✝) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
rw [stepNormal]
[GOAL]
case zero'
k : Cont
v : List ℕ
⊢ eval step ((fun k v => Cfg.ret k (0 :: v)) k v) = do
    let v ← Code.eval Code.zero' v
    eval step (Cfg.ret k v)
case succ
k : Cont
v : List ℕ
⊢ eval step ((fun k v => Cfg.ret k [Nat.succ (List.headI v)]) k v) = do
    let v ← Code.eval Code.succ v
    eval step (Cfg.ret k v)
case tail
k : Cont
v : List ℕ
⊢ eval step ((fun k v => Cfg.ret k (List.tail v)) k v) = do
    let v ← Code.eval Code.tail v
    eval step (Cfg.ret k v)
case cons
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝¹ (Cont.cons₁ a✝ v k) v) k v) = do
    let v ← Code.eval (Code.cons a✝¹ a✝) v
    eval step (Cfg.ret k v)
case comp
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.comp a✝¹ k) v) k v) = do
    let v ← Code.eval (Code.comp a✝¹ a✝) v
    eval step (Cfg.ret k v)
case case
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step
      ((fun k v =>
          Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v))
        k v) =
    do
    let v ← Code.eval (Code.case a✝¹ a✝) v
    eval step (Cfg.ret k v)
case fix
a✝ : Code
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.fix a✝ k) v) k v) = do
    let v ← Code.eval (Code.fix a✝) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
iterate 3 simp only [Code.eval, pure_bind]
[GOAL]
case zero'
k : Cont
v : List ℕ
⊢ eval step ((fun k v => Cfg.ret k (0 :: v)) k v) = do
    let v ← Code.eval Code.zero' v
    eval step (Cfg.ret k v)
case succ
k : Cont
v : List ℕ
⊢ eval step ((fun k v => Cfg.ret k [Nat.succ (List.headI v)]) k v) = do
    let v ← Code.eval Code.succ v
    eval step (Cfg.ret k v)
case tail
k : Cont
v : List ℕ
⊢ eval step ((fun k v => Cfg.ret k (List.tail v)) k v) = do
    let v ← Code.eval Code.tail v
    eval step (Cfg.ret k v)
case cons
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝¹ (Cont.cons₁ a✝ v k) v) k v) = do
    let v ← Code.eval (Code.cons a✝¹ a✝) v
    eval step (Cfg.ret k v)
case comp
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.comp a✝¹ k) v) k v) = do
    let v ← Code.eval (Code.comp a✝¹ a✝) v
    eval step (Cfg.ret k v)
case case
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step
      ((fun k v =>
          Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v))
        k v) =
    do
    let v ← Code.eval (Code.case a✝¹ a✝) v
    eval step (Cfg.ret k v)
case fix
a✝ : Code
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.fix a✝ k) v) k v) = do
    let v ← Code.eval (Code.fix a✝) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
simp only [Code.eval, pure_bind]
[GOAL]
case succ
k : Cont
v : List ℕ
⊢ eval step ((fun k v => Cfg.ret k [Nat.succ (List.headI v)]) k v) = do
    let v ← Code.eval Code.succ v
    eval step (Cfg.ret k v)
case tail
k : Cont
v : List ℕ
⊢ eval step ((fun k v => Cfg.ret k (List.tail v)) k v) = do
    let v ← Code.eval Code.tail v
    eval step (Cfg.ret k v)
case cons
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝¹ (Cont.cons₁ a✝ v k) v) k v) = do
    let v ← Code.eval (Code.cons a✝¹ a✝) v
    eval step (Cfg.ret k v)
case comp
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.comp a✝¹ k) v) k v) = do
    let v ← Code.eval (Code.comp a✝¹ a✝) v
    eval step (Cfg.ret k v)
case case
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step
      ((fun k v =>
          Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v))
        k v) =
    do
    let v ← Code.eval (Code.case a✝¹ a✝) v
    eval step (Cfg.ret k v)
case fix
a✝ : Code
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.fix a✝ k) v) k v) = do
    let v ← Code.eval (Code.fix a✝) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
simp only [Code.eval, pure_bind]
[GOAL]
case tail
k : Cont
v : List ℕ
⊢ eval step ((fun k v => Cfg.ret k (List.tail v)) k v) = do
    let v ← Code.eval Code.tail v
    eval step (Cfg.ret k v)
case cons
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝¹ (Cont.cons₁ a✝ v k) v) k v) = do
    let v ← Code.eval (Code.cons a✝¹ a✝) v
    eval step (Cfg.ret k v)
case comp
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.comp a✝¹ k) v) k v) = do
    let v ← Code.eval (Code.comp a✝¹ a✝) v
    eval step (Cfg.ret k v)
case case
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step
      ((fun k v =>
          Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v))
        k v) =
    do
    let v ← Code.eval (Code.case a✝¹ a✝) v
    eval step (Cfg.ret k v)
case fix
a✝ : Code
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.fix a✝ k) v) k v) = do
    let v ← Code.eval (Code.fix a✝) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
simp only [Code.eval, pure_bind]
[GOAL]
case cons
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝¹ (Cont.cons₁ a✝ v k) v) k v) = do
    let v ← Code.eval (Code.cons a✝¹ a✝) v
    eval step (Cfg.ret k v)
case comp
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.comp a✝¹ k) v) k v) = do
    let v ← Code.eval (Code.comp a✝¹ a✝) v
    eval step (Cfg.ret k v)
case case
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step
      ((fun k v =>
          Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v))
        k v) =
    do
    let v ← Code.eval (Code.case a✝¹ a✝) v
    eval step (Cfg.ret k v)
case fix
a✝ : Code
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.fix a✝ k) v) k v) = do
    let v ← Code.eval (Code.fix a✝) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
case cons f fs IHf IHfs =>
  rw [Code.eval, IHf]
  simp only [bind_assoc, Cont.eval, pure_bind]; congr; funext v
  rw [reaches_eval]; swap; exact ReflTransGen.single rfl
  rw [stepRet, IHfs]; congr; funext v'
  refine' Eq.trans _ (Eq.symm _) <;> try exact reaches_eval (ReflTransGen.single rfl)
[GOAL]
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal f (Cont.cons₁ fs v k) v) k v) = do
    let v ← Code.eval (Code.cons f fs) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
case cons f fs IHf IHfs =>
  rw [Code.eval, IHf]
  simp only [bind_assoc, Cont.eval, pure_bind]; congr; funext v
  rw [reaches_eval]; swap; exact ReflTransGen.single rfl
  rw [stepRet, IHfs]; congr; funext v'
  refine' Eq.trans _ (Eq.symm _) <;> try exact reaches_eval (ReflTransGen.single rfl)
[GOAL]
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal f (Cont.cons₁ fs v k) v) k v) = do
    let v ← Code.eval (Code.cons f fs) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
rw [Code.eval, IHf]
[GOAL]
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v : List ℕ
⊢ (do
      let v_1 ← Code.eval f v
      eval step (Cfg.ret (Cont.cons₁ fs v k) v_1)) =
    do
    let v ←
      (fun v => do
            let n ← Code.eval f v
            let ns ← Code.eval fs v
            pure (List.headI n :: ns))
          v
    eval step (Cfg.ret k v)
[PROOFSTEP]
simp only [bind_assoc, Cont.eval, pure_bind]
[GOAL]
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v : List ℕ
⊢ (do
      let v_1 ← Code.eval f v
      eval step (Cfg.ret (Cont.cons₁ fs v k) v_1)) =
    do
    let x ← Code.eval f v
    let x_1 ← Code.eval fs v
    eval step (Cfg.ret k (List.headI x :: x_1))
[PROOFSTEP]
congr
[GOAL]
case e_a
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v : List ℕ
⊢ (fun v_1 => eval step (Cfg.ret (Cont.cons₁ fs v k) v_1)) = fun x => do
    let x_1 ← Code.eval fs v
    eval step (Cfg.ret k (List.headI x :: x_1))
[PROOFSTEP]
funext v
[GOAL]
case e_a.h
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v✝ v : List ℕ
⊢ eval step (Cfg.ret (Cont.cons₁ fs v✝ k) v) = do
    let x ← Code.eval fs v✝
    eval step (Cfg.ret k (List.headI v :: x))
[PROOFSTEP]
rw [reaches_eval]
[GOAL]
case e_a.h
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v✝ v : List ℕ
⊢ eval step ?m.200491 = do
    let x ← Code.eval fs v✝
    eval step (Cfg.ret k (List.headI v :: x))
case e_a.h
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v✝ v : List ℕ
⊢ Reaches step (Cfg.ret (Cont.cons₁ fs v✝ k) v) ?m.200491
f fs : Code IHf : Code.Ok f IHfs : Code.Ok fs k : Cont v✝ v : List ℕ ⊢ Cfg
[PROOFSTEP]
swap
[GOAL]
case e_a.h
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v✝ v : List ℕ
⊢ Reaches step (Cfg.ret (Cont.cons₁ fs v✝ k) v) ?m.200491
case e_a.h
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v✝ v : List ℕ
⊢ eval step ?m.200491 = do
    let x ← Code.eval fs v✝
    eval step (Cfg.ret k (List.headI v :: x))
f fs : Code IHf : Code.Ok f IHfs : Code.Ok fs k : Cont v✝ v : List ℕ ⊢ Cfg
[PROOFSTEP]
exact ReflTransGen.single rfl
[GOAL]
case e_a.h
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v✝ v : List ℕ
⊢ eval step (stepRet (Cont.cons₁ fs v✝ k) v) = do
    let x ← Code.eval fs v✝
    eval step (Cfg.ret k (List.headI v :: x))
[PROOFSTEP]
rw [stepRet, IHfs]
[GOAL]
case e_a.h
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v✝ v : List ℕ
⊢ (do
      let v_1 ← Code.eval fs v✝
      eval step (Cfg.ret (Cont.cons₂ v k) v_1)) =
    do
    let x ← Code.eval fs v✝
    eval step (Cfg.ret k (List.headI v :: x))
[PROOFSTEP]
congr
[GOAL]
case e_a.h.e_a
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v✝ v : List ℕ
⊢ (fun v_1 => eval step (Cfg.ret (Cont.cons₂ v k) v_1)) = fun x => eval step (Cfg.ret k (List.headI v :: x))
[PROOFSTEP]
funext v'
[GOAL]
case e_a.h.e_a.h
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v✝ v v' : List ℕ
⊢ eval step (Cfg.ret (Cont.cons₂ v k) v') = eval step (Cfg.ret k (List.headI v :: v'))
[PROOFSTEP]
refine' Eq.trans _ (Eq.symm _)
[GOAL]
case e_a.h.e_a.h.refine'_1
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v✝ v v' : List ℕ
⊢ eval step (Cfg.ret (Cont.cons₂ v k) v') = ?e_a.h.e_a.h.refine'_2✝
[PROOFSTEP]
try exact reaches_eval (ReflTransGen.single rfl)
[GOAL]
case e_a.h.e_a.h.refine'_1
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v✝ v v' : List ℕ
⊢ eval step (Cfg.ret (Cont.cons₂ v k) v') = ?e_a.h.e_a.h.refine'_2✝
[PROOFSTEP]
exact reaches_eval (ReflTransGen.single rfl)
[GOAL]
case e_a.h.e_a.h.refine'_3
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v✝ v v' : List ℕ
⊢ eval step (Cfg.ret k (List.headI v :: v')) = eval step (stepRet (Cont.cons₂ v k) v')
[PROOFSTEP]
try exact reaches_eval (ReflTransGen.single rfl)
[GOAL]
case e_a.h.e_a.h.refine'_3
f fs : Code
IHf : Code.Ok f
IHfs : Code.Ok fs
k : Cont
v✝ v v' : List ℕ
⊢ eval step (Cfg.ret k (List.headI v :: v')) = eval step (stepRet (Cont.cons₂ v k) v')
[PROOFSTEP]
exact reaches_eval (ReflTransGen.single rfl)
[GOAL]
case comp
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.comp a✝¹ k) v) k v) = do
    let v ← Code.eval (Code.comp a✝¹ a✝) v
    eval step (Cfg.ret k v)
case case
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step
      ((fun k v =>
          Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v))
        k v) =
    do
    let v ← Code.eval (Code.case a✝¹ a✝) v
    eval step (Cfg.ret k v)
case fix
a✝ : Code
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.fix a✝ k) v) k v) = do
    let v ← Code.eval (Code.fix a✝) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
case comp f g IHf IHg =>
  rw [Code.eval, IHg]
  simp only [bind_assoc, Cont.eval, pure_bind]; congr; funext v
  rw [reaches_eval]; swap; exact ReflTransGen.single rfl
  rw [stepRet, IHf]
[GOAL]
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal g (Cont.comp f k) v) k v) = do
    let v ← Code.eval (Code.comp f g) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
case comp f g IHf IHg =>
  rw [Code.eval, IHg]
  simp only [bind_assoc, Cont.eval, pure_bind]; congr; funext v
  rw [reaches_eval]; swap; exact ReflTransGen.single rfl
  rw [stepRet, IHf]
[GOAL]
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal g (Cont.comp f k) v) k v) = do
    let v ← Code.eval (Code.comp f g) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
rw [Code.eval, IHg]
[GOAL]
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v : List ℕ
⊢ (do
      let v ← Code.eval g v
      eval step (Cfg.ret (Cont.comp f k) v)) =
    do
    let v ← (fun v => Code.eval g v >>= Code.eval f) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
simp only [bind_assoc, Cont.eval, pure_bind]
[GOAL]
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v : List ℕ
⊢ (do
      let v ← Code.eval g v
      eval step (Cfg.ret (Cont.comp f k) v)) =
    do
    let x ← Code.eval g v
    let v ← Code.eval f x
    eval step (Cfg.ret k v)
[PROOFSTEP]
congr
[GOAL]
case e_a
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v : List ℕ
⊢ (fun v => eval step (Cfg.ret (Cont.comp f k) v)) = fun x => do
    let v ← Code.eval f x
    eval step (Cfg.ret k v)
[PROOFSTEP]
funext v
[GOAL]
case e_a.h
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v✝ v : List ℕ
⊢ eval step (Cfg.ret (Cont.comp f k) v) = do
    let v ← Code.eval f v
    eval step (Cfg.ret k v)
[PROOFSTEP]
rw [reaches_eval]
[GOAL]
case e_a.h
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v✝ v : List ℕ
⊢ eval step ?m.201265 = do
    let v ← Code.eval f v
    eval step (Cfg.ret k v)
case e_a.h
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v✝ v : List ℕ
⊢ Reaches step (Cfg.ret (Cont.comp f k) v) ?m.201265
f g : Code IHf : Code.Ok f IHg : Code.Ok g k : Cont v✝ v : List ℕ ⊢ Cfg
[PROOFSTEP]
swap
[GOAL]
case e_a.h
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v✝ v : List ℕ
⊢ Reaches step (Cfg.ret (Cont.comp f k) v) ?m.201265
case e_a.h
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v✝ v : List ℕ
⊢ eval step ?m.201265 = do
    let v ← Code.eval f v
    eval step (Cfg.ret k v)
f g : Code IHf : Code.Ok f IHg : Code.Ok g k : Cont v✝ v : List ℕ ⊢ Cfg
[PROOFSTEP]
exact ReflTransGen.single rfl
[GOAL]
case e_a.h
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v✝ v : List ℕ
⊢ eval step (stepRet (Cont.comp f k) v) = do
    let v ← Code.eval f v
    eval step (Cfg.ret k v)
[PROOFSTEP]
rw [stepRet, IHf]
[GOAL]
case case
a✝¹ a✝ : Code
a_ih✝¹ : Code.Ok a✝¹
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step
      ((fun k v =>
          Nat.rec (stepNormal a✝¹ k (List.tail v)) (fun y x => stepNormal a✝ k (y :: List.tail v)) (List.headI v))
        k v) =
    do
    let v ← Code.eval (Code.case a✝¹ a✝) v
    eval step (Cfg.ret k v)
case fix
a✝ : Code
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.fix a✝ k) v) k v) = do
    let v ← Code.eval (Code.fix a✝) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
case case f g IHf IHg =>
  simp only [Code.eval]
  cases v.headI <;> simp only [Code.eval] <;> [apply IHf; apply IHg]
[GOAL]
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v : List ℕ
⊢ eval step
      ((fun k v => Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v))
        k v) =
    do
    let v ← Code.eval (Code.case f g) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
case case f g IHf IHg =>
  simp only [Code.eval]
  cases v.headI <;> simp only [Code.eval] <;> [apply IHf; apply IHg]
[GOAL]
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v : List ℕ
⊢ eval step
      ((fun k v => Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v))
        k v) =
    do
    let v ← Code.eval (Code.case f g) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
simp only [Code.eval]
[GOAL]
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v : List ℕ
⊢ eval step (Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v)) = do
    let v ← Nat.rec (Code.eval f (List.tail v)) (fun y x => Code.eval g (y :: List.tail v)) (List.headI v)
    eval step (Cfg.ret k v)
[PROOFSTEP]
cases v.headI <;> simp only [Code.eval] <;> [apply IHf; apply IHg]
[GOAL]
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v : List ℕ
⊢ eval step (Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v)) = do
    let v ← Nat.rec (Code.eval f (List.tail v)) (fun y x => Code.eval g (y :: List.tail v)) (List.headI v)
    eval step (Cfg.ret k v)
[PROOFSTEP]
cases v.headI
[GOAL]
case zero
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v : List ℕ
⊢ eval step (Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) Nat.zero) = do
    let v ← Nat.rec (Code.eval f (List.tail v)) (fun y x => Code.eval g (y :: List.tail v)) Nat.zero
    eval step (Cfg.ret k v)
[PROOFSTEP]
simp only [Code.eval]
[GOAL]
case succ
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v : List ℕ
n✝ : ℕ
⊢ eval step (Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (Nat.succ n✝)) = do
    let v ← Nat.rec (Code.eval f (List.tail v)) (fun y x => Code.eval g (y :: List.tail v)) (Nat.succ n✝)
    eval step (Cfg.ret k v)
[PROOFSTEP]
simp only [Code.eval]
[GOAL]
case zero
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v : List ℕ
⊢ eval step (stepNormal f k (List.tail v)) = do
    let v ← Code.eval f (List.tail v)
    eval step (Cfg.ret k v)
[PROOFSTEP]
apply IHf
[GOAL]
case succ
f g : Code
IHf : Code.Ok f
IHg : Code.Ok g
k : Cont
v : List ℕ
n✝ : ℕ
⊢ eval step (stepNormal g k (n✝ :: List.tail v)) = do
    let v ← Code.eval g (n✝ :: List.tail v)
    eval step (Cfg.ret k v)
[PROOFSTEP]
apply IHg
[GOAL]
case fix
a✝ : Code
a_ih✝ : Code.Ok a✝
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal a✝ (Cont.fix a✝ k) v) k v) = do
    let v ← Code.eval (Code.fix a✝) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
case fix f IHf => rw [cont_eval_fix IHf]
[GOAL]
f : Code
IHf : Code.Ok f
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal f (Cont.fix f k) v) k v) = do
    let v ← Code.eval (Code.fix f) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
case fix f IHf => rw [cont_eval_fix IHf]
[GOAL]
f : Code
IHf : Code.Ok f
k : Cont
v : List ℕ
⊢ eval step ((fun k v => stepNormal f (Cont.fix f k) v) k v) = do
    let v ← Code.eval (Code.fix f) v
    eval step (Cfg.ret k v)
[PROOFSTEP]
rw [cont_eval_fix IHf]
[GOAL]
k : Cont
v : List ℕ
⊢ eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
[PROOFSTEP]
induction k generalizing v
[GOAL]
case halt
v : List ℕ
⊢ eval step (stepRet Cont.halt v) = Cfg.halt <$> Cont.eval Cont.halt v
case cons₁
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.cons₁ a✝² a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.cons₁ a✝² a✝¹ a✝) v
case cons₂
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.cons₂ a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.cons₂ a✝¹ a✝) v
case comp
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.comp a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.comp a✝¹ a✝) v
case fix
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.fix a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.fix a✝¹ a✝) v
[PROOFSTEP]
case halt =>
  simp only [mem_eval, Cont.eval, map_pure]
  exact Part.eq_some_iff.2 (mem_eval.2 ⟨ReflTransGen.refl, rfl⟩)
[GOAL]
v : List ℕ
⊢ eval step (stepRet Cont.halt v) = Cfg.halt <$> Cont.eval Cont.halt v
[PROOFSTEP]
case halt =>
  simp only [mem_eval, Cont.eval, map_pure]
  exact Part.eq_some_iff.2 (mem_eval.2 ⟨ReflTransGen.refl, rfl⟩)
[GOAL]
v : List ℕ
⊢ eval step (stepRet Cont.halt v) = Cfg.halt <$> Cont.eval Cont.halt v
[PROOFSTEP]
simp only [mem_eval, Cont.eval, map_pure]
[GOAL]
v : List ℕ
⊢ eval step (stepRet Cont.halt v) = pure (Cfg.halt v)
[PROOFSTEP]
exact Part.eq_some_iff.2 (mem_eval.2 ⟨ReflTransGen.refl, rfl⟩)
[GOAL]
case cons₁
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.cons₁ a✝² a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.cons₁ a✝² a✝¹ a✝) v
case cons₂
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.cons₂ a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.cons₂ a✝¹ a✝) v
case comp
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.comp a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.comp a✝¹ a✝) v
case fix
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.fix a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.fix a✝¹ a✝) v
[PROOFSTEP]
case cons₁ fs as k IH =>
  rw [Cont.eval, stepRet, code_is_ok]
  simp only [← bind_pure_comp, bind_assoc]; congr; funext v'
  rw [reaches_eval]; swap; exact ReflTransGen.single rfl
  rw [stepRet, IH, bind_pure_comp]
[GOAL]
fs : Code
as : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ eval step (stepRet (Cont.cons₁ fs as k) v) = Cfg.halt <$> Cont.eval (Cont.cons₁ fs as k) v
[PROOFSTEP]
case cons₁ fs as k IH =>
  rw [Cont.eval, stepRet, code_is_ok]
  simp only [← bind_pure_comp, bind_assoc]; congr; funext v'
  rw [reaches_eval]; swap; exact ReflTransGen.single rfl
  rw [stepRet, IH, bind_pure_comp]
[GOAL]
fs : Code
as : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ eval step (stepRet (Cont.cons₁ fs as k) v) = Cfg.halt <$> Cont.eval (Cont.cons₁ fs as k) v
[PROOFSTEP]
rw [Cont.eval, stepRet, code_is_ok]
[GOAL]
fs : Code
as : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ (do
      let v_1 ← Code.eval fs as
      eval step (Cfg.ret (Cont.cons₂ v k) v_1)) =
    Cfg.halt <$>
      (fun v => do
          let ns ← Code.eval fs as
          Cont.eval k (List.headI v :: ns))
        v
[PROOFSTEP]
simp only [← bind_pure_comp, bind_assoc]
[GOAL]
fs : Code
as : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ (do
      let v_1 ← Code.eval fs as
      eval step (Cfg.ret (Cont.cons₂ v k) v_1)) =
    do
    let x ← Code.eval fs as
    let a ← Cont.eval k (List.headI v :: x)
    pure (Cfg.halt a)
[PROOFSTEP]
congr
[GOAL]
case e_a
fs : Code
as : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ (fun v_1 => eval step (Cfg.ret (Cont.cons₂ v k) v_1)) = fun x => do
    let a ← Cont.eval k (List.headI v :: x)
    pure (Cfg.halt a)
[PROOFSTEP]
funext v'
[GOAL]
case e_a.h
fs : Code
as : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ eval step (Cfg.ret (Cont.cons₂ v k) v') = do
    let a ← Cont.eval k (List.headI v :: v')
    pure (Cfg.halt a)
[PROOFSTEP]
rw [reaches_eval]
[GOAL]
case e_a.h
fs : Code
as : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ eval step ?m.203004 = do
    let a ← Cont.eval k (List.headI v :: v')
    pure (Cfg.halt a)
case e_a.h
fs : Code
as : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ Reaches step (Cfg.ret (Cont.cons₂ v k) v') ?m.203004
fs : Code
as : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ Cfg
[PROOFSTEP]
swap
[GOAL]
case e_a.h
fs : Code
as : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ Reaches step (Cfg.ret (Cont.cons₂ v k) v') ?m.203004
case e_a.h
fs : Code
as : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ eval step ?m.203004 = do
    let a ← Cont.eval k (List.headI v :: v')
    pure (Cfg.halt a)
fs : Code
as : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ Cfg
[PROOFSTEP]
exact ReflTransGen.single rfl
[GOAL]
case e_a.h
fs : Code
as : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ eval step (stepRet (Cont.cons₂ v k) v') = do
    let a ← Cont.eval k (List.headI v :: v')
    pure (Cfg.halt a)
[PROOFSTEP]
rw [stepRet, IH, bind_pure_comp]
[GOAL]
case cons₂
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.cons₂ a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.cons₂ a✝¹ a✝) v
case comp
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.comp a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.comp a✝¹ a✝) v
case fix
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.fix a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.fix a✝¹ a✝) v
[PROOFSTEP]
case cons₂ ns k IH => rw [Cont.eval, stepRet]; exact IH
[GOAL]
ns : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ eval step (stepRet (Cont.cons₂ ns k) v) = Cfg.halt <$> Cont.eval (Cont.cons₂ ns k) v
[PROOFSTEP]
case cons₂ ns k IH => rw [Cont.eval, stepRet]; exact IH
[GOAL]
ns : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ eval step (stepRet (Cont.cons₂ ns k) v) = Cfg.halt <$> Cont.eval (Cont.cons₂ ns k) v
[PROOFSTEP]
rw [Cont.eval, stepRet]
[GOAL]
ns : List ℕ
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ eval step (stepRet k (List.headI ns :: v)) = Cfg.halt <$> (fun v => Cont.eval k (List.headI ns :: v)) v
[PROOFSTEP]
exact IH
[GOAL]
case comp
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.comp a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.comp a✝¹ a✝) v
case fix
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.fix a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.fix a✝¹ a✝) v
[PROOFSTEP]
case comp f k IH =>
  rw [Cont.eval, stepRet, code_is_ok]
  simp only [← bind_pure_comp, bind_assoc]; congr; funext v'
  rw [reaches_eval]; swap; exact ReflTransGen.single rfl
  rw [IH, bind_pure_comp]
[GOAL]
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ eval step (stepRet (Cont.comp f k) v) = Cfg.halt <$> Cont.eval (Cont.comp f k) v
[PROOFSTEP]
case comp f k IH =>
  rw [Cont.eval, stepRet, code_is_ok]
  simp only [← bind_pure_comp, bind_assoc]; congr; funext v'
  rw [reaches_eval]; swap; exact ReflTransGen.single rfl
  rw [IH, bind_pure_comp]
[GOAL]
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ eval step (stepRet (Cont.comp f k) v) = Cfg.halt <$> Cont.eval (Cont.comp f k) v
[PROOFSTEP]
rw [Cont.eval, stepRet, code_is_ok]
[GOAL]
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ (do
      let v ← Code.eval f v
      eval step (Cfg.ret k v)) =
    Cfg.halt <$> (fun v => Code.eval f v >>= Cont.eval k) v
[PROOFSTEP]
simp only [← bind_pure_comp, bind_assoc]
[GOAL]
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ (do
      let v ← Code.eval f v
      eval step (Cfg.ret k v)) =
    do
    let x ← Code.eval f v
    let a ← Cont.eval k x
    pure (Cfg.halt a)
[PROOFSTEP]
congr
[GOAL]
case e_a
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ (fun v => eval step (Cfg.ret k v)) = fun x => do
    let a ← Cont.eval k x
    pure (Cfg.halt a)
[PROOFSTEP]
funext v'
[GOAL]
case e_a.h
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ eval step (Cfg.ret k v') = do
    let a ← Cont.eval k v'
    pure (Cfg.halt a)
[PROOFSTEP]
rw [reaches_eval]
[GOAL]
case e_a.h
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ eval step ?m.203696 = do
    let a ← Cont.eval k v'
    pure (Cfg.halt a)
case e_a.h
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ Reaches step (Cfg.ret k v') ?m.203696
f : Code k : Cont IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v v v' : List ℕ ⊢ Cfg
[PROOFSTEP]
swap
[GOAL]
case e_a.h
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ Reaches step (Cfg.ret k v') ?m.203696
case e_a.h
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ eval step ?m.203696 = do
    let a ← Cont.eval k v'
    pure (Cfg.halt a)
f : Code k : Cont IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v v v' : List ℕ ⊢ Cfg
[PROOFSTEP]
exact ReflTransGen.single rfl
[GOAL]
case e_a.h
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v v' : List ℕ
⊢ eval step (stepRet k v') = do
    let a ← Cont.eval k v'
    pure (Cfg.halt a)
[PROOFSTEP]
rw [IH, bind_pure_comp]
[GOAL]
case fix
a✝¹ : Code
a✝ : Cont
a_ih✝ : ∀ {v : List ℕ}, eval step (stepRet a✝ v) = Cfg.halt <$> Cont.eval a✝ v
v : List ℕ
⊢ eval step (stepRet (Cont.fix a✝¹ a✝) v) = Cfg.halt <$> Cont.eval (Cont.fix a✝¹ a✝) v
[PROOFSTEP]
case fix f k IH =>
  rw [Cont.eval, stepRet]; simp only [bind_pure_comp]
  split_ifs; · exact IH
  simp only [← bind_pure_comp, bind_assoc, cont_eval_fix (code_is_ok _)]
  congr; funext; rw [bind_pure_comp, ← IH]
  exact reaches_eval (ReflTransGen.single rfl)
[GOAL]
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ eval step (stepRet (Cont.fix f k) v) = Cfg.halt <$> Cont.eval (Cont.fix f k) v
[PROOFSTEP]
case fix f k IH =>
  rw [Cont.eval, stepRet]; simp only [bind_pure_comp]
  split_ifs; · exact IH
  simp only [← bind_pure_comp, bind_assoc, cont_eval_fix (code_is_ok _)]
  congr; funext; rw [bind_pure_comp, ← IH]
  exact reaches_eval (ReflTransGen.single rfl)
[GOAL]
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ eval step (stepRet (Cont.fix f k) v) = Cfg.halt <$> Cont.eval (Cont.fix f k) v
[PROOFSTEP]
rw [Cont.eval, stepRet]
[GOAL]
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ eval step (if List.headI v = 0 then stepRet k (List.tail v) else stepNormal f (Cont.fix f k) (List.tail v)) =
    Cfg.halt <$>
      (fun v =>
          if List.headI v = 0 then Cont.eval k (List.tail v) else Code.eval (Code.fix f) (List.tail v) >>= Cont.eval k)
        v
[PROOFSTEP]
simp only [bind_pure_comp]
[GOAL]
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
⊢ eval step (if List.headI v = 0 then stepRet k (List.tail v) else stepNormal f (Cont.fix f k) (List.tail v)) =
    Cfg.halt <$>
      if List.headI v = 0 then Cont.eval k (List.tail v) else Code.eval (Code.fix f) (List.tail v) >>= Cont.eval k
[PROOFSTEP]
split_ifs
[GOAL]
case pos
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
h✝ : List.headI v = 0
⊢ eval step (stepRet k (List.tail v)) = Cfg.halt <$> Cont.eval k (List.tail v)
[PROOFSTEP]
exact IH
[GOAL]
case neg
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
h✝ : ¬List.headI v = 0
⊢ eval step (stepNormal f (Cont.fix f k) (List.tail v)) =
    Cfg.halt <$> (Code.eval (Code.fix f) (List.tail v) >>= Cont.eval k)
[PROOFSTEP]
simp only [← bind_pure_comp, bind_assoc, cont_eval_fix (code_is_ok _)]
[GOAL]
case neg
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
h✝ : ¬List.headI v = 0
⊢ (do
      let v ← Code.eval (Code.fix f) (List.tail v)
      eval step (Cfg.ret k v)) =
    do
    let x ← Code.eval (Code.fix f) (List.tail v)
    let a ← Cont.eval k x
    pure (Cfg.halt a)
[PROOFSTEP]
congr
[GOAL]
case neg.e_a
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
h✝ : ¬List.headI v = 0
⊢ (fun v => eval step (Cfg.ret k v)) = fun x => do
    let a ← Cont.eval k x
    pure (Cfg.halt a)
[PROOFSTEP]
funext
[GOAL]
case neg.e_a.h
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
h✝ : ¬List.headI v = 0
x✝ : List ℕ
⊢ eval step (Cfg.ret k x✝) = do
    let a ← Cont.eval k x✝
    pure (Cfg.halt a)
[PROOFSTEP]
rw [bind_pure_comp, ← IH]
[GOAL]
case neg.e_a.h
f : Code
k : Cont
IH : ∀ {v : List ℕ}, eval step (stepRet k v) = Cfg.halt <$> Cont.eval k v
v : List ℕ
h✝ : ¬List.headI v = 0
x✝ : List ℕ
⊢ eval step (Cfg.ret k x✝) = eval step (stepRet k x✝)
[PROOFSTEP]
exact reaches_eval (ReflTransGen.single rfl)
[GOAL]
a b : Λ'
⊢ Decidable (a = b)
[PROOFSTEP]
induction a generalizing b
[GOAL]
case move
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
b : Λ'
⊢ Decidable (move p✝ k₁✝ k₂✝ q✝ = b)
[PROOFSTEP]
cases b
[GOAL]
case clear
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
b : Λ'
⊢ Decidable (clear p✝ k✝ q✝ = b)
[PROOFSTEP]
cases b
[GOAL]
case copy
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
b : Λ'
⊢ Decidable (copy q✝ = b)
[PROOFSTEP]
cases b
[GOAL]
case push
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
b : Λ'
⊢ Decidable (push k✝ s✝ q✝ = b)
[PROOFSTEP]
cases b
[GOAL]
case read
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
b : Λ'
⊢ Decidable (read f✝ = b)
[PROOFSTEP]
cases b
[GOAL]
case succ
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
b : Λ'
⊢ Decidable (succ q✝ = b)
[PROOFSTEP]
cases b
[GOAL]
case pred
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
b : Λ'
⊢ Decidable (pred q₁✝ q₂✝ = b)
[PROOFSTEP]
cases b
[GOAL]
case ret
k✝ : Cont'
b : Λ'
⊢ Decidable (ret k✝ = b)
[PROOFSTEP]
cases b
[GOAL]
case move.move
p✝¹ : Γ' → Bool
k₁✝¹ k₂✝¹ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (move p✝¹ k₁✝¹ k₂✝¹ q✝¹ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case move.move
p✝¹ : Γ' → Bool
k₁✝¹ k₂✝¹ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (move p✝¹ k₁✝¹ k₂✝¹ q✝¹ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case move.move.h
p✝¹ : Γ' → Bool
k₁✝¹ k₂✝¹ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ ¬move p✝¹ k₁✝¹ k₂✝¹ q✝¹ = move p✝ k₁✝ k₂✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]
case move.move.h.refl
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
⊢ False
[PROOFSTEP]
done
[GOAL]
case move.clear
p✝¹ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (move p✝¹ k₁✝ k₂✝ q✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case move.clear
p✝¹ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (move p✝¹ k₁✝ k₂✝ q✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case move.clear.h
p✝¹ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ ¬move p✝¹ k₁✝ k₂✝ q✝¹ = clear p✝ k✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case move.copy
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (move p✝ k₁✝ k₂✝ q✝¹ = copy q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case move.copy
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (move p✝ k₁✝ k₂✝ q✝¹ = copy q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case move.copy.h
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ ¬move p✝ k₁✝ k₂✝ q✝¹ = copy q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case move.push
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (move p✝ k₁✝ k₂✝ q✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case move.push
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (move p✝ k₁✝ k₂✝ q✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case move.push.h
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ ¬move p✝ k₁✝ k₂✝ q✝¹ = push k✝ s✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case move.read
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (move p✝ k₁✝ k₂✝ q✝ = read f✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case move.read
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (move p✝ k₁✝ k₂✝ q✝ = read f✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case move.read.h
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ ¬move p✝ k₁✝ k₂✝ q✝ = read f✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case move.succ
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (move p✝ k₁✝ k₂✝ q✝¹ = succ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case move.succ
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (move p✝ k₁✝ k₂✝ q✝¹ = succ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case move.succ.h
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ ¬move p✝ k₁✝ k₂✝ q✝¹ = succ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case move.pred
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (move p✝ k₁✝ k₂✝ q✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case move.pred
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (move p✝ k₁✝ k₂✝ q✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case move.pred.h
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ ¬move p✝ k₁✝ k₂✝ q✝ = pred q₁✝ q₂✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case move.ret
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ Decidable (move p✝ k₁✝ k₂✝ q✝ = ret k✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case move.ret
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ Decidable (move p✝ k₁✝ k₂✝ q✝ = ret k✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case move.ret.h
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ ¬move p✝ k₁✝ k₂✝ q✝ = ret k✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case clear.move
p✝¹ : Γ' → Bool
k✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (clear p✝¹ k✝ q✝¹ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case clear.move
p✝¹ : Γ' → Bool
k✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (clear p✝¹ k✝ q✝¹ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case clear.move.h
p✝¹ : Γ' → Bool
k✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ ¬clear p✝¹ k✝ q✝¹ = move p✝ k₁✝ k₂✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case clear.clear
p✝¹ : Γ' → Bool
k✝¹ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (clear p✝¹ k✝¹ q✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case clear.clear
p✝¹ : Γ' → Bool
k✝¹ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (clear p✝¹ k✝¹ q✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case clear.clear.h
p✝¹ : Γ' → Bool
k✝¹ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ ¬clear p✝¹ k✝¹ q✝¹ = clear p✝ k✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]
case clear.clear.h.refl
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
⊢ False
[PROOFSTEP]
done
[GOAL]
case clear.copy
p✝ : Γ' → Bool
k✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (clear p✝ k✝ q✝¹ = copy q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case clear.copy
p✝ : Γ' → Bool
k✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (clear p✝ k✝ q✝¹ = copy q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case clear.copy.h
p✝ : Γ' → Bool
k✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ ¬clear p✝ k✝ q✝¹ = copy q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case clear.push
p✝ : Γ' → Bool
k✝¹ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (clear p✝ k✝¹ q✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case clear.push
p✝ : Γ' → Bool
k✝¹ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (clear p✝ k✝¹ q✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case clear.push.h
p✝ : Γ' → Bool
k✝¹ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ ¬clear p✝ k✝¹ q✝¹ = push k✝ s✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case clear.read
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (clear p✝ k✝ q✝ = read f✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case clear.read
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (clear p✝ k✝ q✝ = read f✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case clear.read.h
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ ¬clear p✝ k✝ q✝ = read f✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case clear.succ
p✝ : Γ' → Bool
k✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (clear p✝ k✝ q✝¹ = succ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case clear.succ
p✝ : Γ' → Bool
k✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (clear p✝ k✝ q✝¹ = succ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case clear.succ.h
p✝ : Γ' → Bool
k✝ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ ¬clear p✝ k✝ q✝¹ = succ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case clear.pred
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (clear p✝ k✝ q✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case clear.pred
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (clear p✝ k✝ q✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case clear.pred.h
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ ¬clear p✝ k✝ q✝ = pred q₁✝ q₂✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case clear.ret
p✝ : Γ' → Bool
k✝¹ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ Decidable (clear p✝ k✝¹ q✝ = ret k✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case clear.ret
p✝ : Γ' → Bool
k✝¹ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ Decidable (clear p✝ k✝¹ q✝ = ret k✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case clear.ret.h
p✝ : Γ' → Bool
k✝¹ : K'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ ¬clear p✝ k✝¹ q✝ = ret k✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case copy.move
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (copy q✝¹ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case copy.move
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (copy q✝¹ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case copy.move.h
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ ¬copy q✝¹ = move p✝ k₁✝ k₂✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case copy.clear
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (copy q✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case copy.clear
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (copy q✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case copy.clear.h
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ ¬copy q✝¹ = clear p✝ k✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case copy.copy
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (copy q✝¹ = copy q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case copy.copy
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (copy q✝¹ = copy q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case copy.copy.h
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ ¬copy q✝¹ = copy q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]
case copy.copy.h.refl
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
⊢ False
[PROOFSTEP]
done
[GOAL]
case copy.push
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (copy q✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case copy.push
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (copy q✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case copy.push.h
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ ¬copy q✝¹ = push k✝ s✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case copy.read
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (copy q✝ = read f✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case copy.read
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (copy q✝ = read f✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case copy.read.h
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ ¬copy q✝ = read f✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case copy.succ
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (copy q✝¹ = succ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case copy.succ
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (copy q✝¹ = succ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case copy.succ.h
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ ¬copy q✝¹ = succ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case copy.pred
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (copy q✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case copy.pred
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (copy q✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case copy.pred.h
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ ¬copy q✝ = pred q₁✝ q₂✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case copy.ret
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ Decidable (copy q✝ = ret k✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case copy.ret
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ Decidable (copy q✝ = ret k✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case copy.ret.h
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ ¬copy q✝ = ret k✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case push.move
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (push k✝ s✝ q✝¹ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case push.move
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (push k✝ s✝ q✝¹ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case push.move.h
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ ¬push k✝ s✝ q✝¹ = move p✝ k₁✝ k₂✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case push.clear
k✝¹ : K'
s✝ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (push k✝¹ s✝ q✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case push.clear
k✝¹ : K'
s✝ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (push k✝¹ s✝ q✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case push.clear.h
k✝¹ : K'
s✝ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ ¬push k✝¹ s✝ q✝¹ = clear p✝ k✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case push.copy
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (push k✝ s✝ q✝¹ = copy q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case push.copy
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (push k✝ s✝ q✝¹ = copy q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case push.copy.h
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ ¬push k✝ s✝ q✝¹ = copy q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case push.push
k✝¹ : K'
s✝¹ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (push k✝¹ s✝¹ q✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case push.push
k✝¹ : K'
s✝¹ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (push k✝¹ s✝¹ q✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case push.push.h
k✝¹ : K'
s✝¹ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ ¬push k✝¹ s✝¹ q✝¹ = push k✝ s✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]
case push.push.h.refl
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
⊢ False
[PROOFSTEP]
done
[GOAL]
case push.read
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (push k✝ s✝ q✝ = read f✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case push.read
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (push k✝ s✝ q✝ = read f✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case push.read.h
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ ¬push k✝ s✝ q✝ = read f✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case push.succ
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (push k✝ s✝ q✝¹ = succ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case push.succ
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (push k✝ s✝ q✝¹ = succ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case push.succ.h
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ ¬push k✝ s✝ q✝¹ = succ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case push.pred
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (push k✝ s✝ q✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case push.pred
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (push k✝ s✝ q✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case push.pred.h
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ ¬push k✝ s✝ q✝ = pred q₁✝ q₂✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case push.ret
k✝¹ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ Decidable (push k✝¹ s✝ q✝ = ret k✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case push.ret
k✝¹ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ Decidable (push k✝¹ s✝ q✝ = ret k✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case push.ret.h
k✝¹ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ ¬push k✝¹ s✝ q✝ = ret k✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case read.move
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (read f✝ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case read.move
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (read f✝ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case read.move.h
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ ¬read f✝ = move p✝ k₁✝ k₂✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case read.clear
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (read f✝ = clear p✝ k✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case read.clear
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (read f✝ = clear p✝ k✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case read.clear.h
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ ¬read f✝ = clear p✝ k✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case read.copy
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
q✝ : Λ'
⊢ Decidable (read f✝ = copy q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case read.copy
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
q✝ : Λ'
⊢ Decidable (read f✝ = copy q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case read.copy.h
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
q✝ : Λ'
⊢ ¬read f✝ = copy q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case read.push
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (read f✝ = push k✝ s✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case read.push
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (read f✝ = push k✝ s✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case read.push.h
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ ¬read f✝ = push k✝ s✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case read.read
f✝¹ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (read f✝¹ = read f✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case read.read
f✝¹ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (read f✝¹ = read f✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case read.read.h
f✝¹ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b)
f✝ : Option Γ' → Λ'
⊢ ¬read f✝¹ = read f✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]
case read.read.h.refl
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
⊢ False
[PROOFSTEP]
done
[GOAL]
case read.succ
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
q✝ : Λ'
⊢ Decidable (read f✝ = succ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case read.succ
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
q✝ : Λ'
⊢ Decidable (read f✝ = succ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case read.succ.h
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
q✝ : Λ'
⊢ ¬read f✝ = succ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case read.pred
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (read f✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case read.pred
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (read f✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case read.pred.h
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
q₁✝ q₂✝ : Λ'
⊢ ¬read f✝ = pred q₁✝ q₂✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case read.ret
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
k✝ : Cont'
⊢ Decidable (read f✝ = ret k✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case read.ret
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
k✝ : Cont'
⊢ Decidable (read f✝ = ret k✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case read.ret.h
f✝ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝ a = b)
k✝ : Cont'
⊢ ¬read f✝ = ret k✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case succ.move
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (succ q✝¹ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case succ.move
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (succ q✝¹ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case succ.move.h
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ ¬succ q✝¹ = move p✝ k₁✝ k₂✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case succ.clear
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (succ q✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case succ.clear
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (succ q✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case succ.clear.h
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ ¬succ q✝¹ = clear p✝ k✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case succ.copy
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (succ q✝¹ = copy q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case succ.copy
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (succ q✝¹ = copy q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case succ.copy.h
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ ¬succ q✝¹ = copy q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case succ.push
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (succ q✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case succ.push
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (succ q✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case succ.push.h
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ ¬succ q✝¹ = push k✝ s✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case succ.read
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (succ q✝ = read f✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case succ.read
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (succ q✝ = read f✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case succ.read.h
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
f✝ : Option Γ' → Λ'
⊢ ¬succ q✝ = read f✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case succ.succ
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (succ q✝¹ = succ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case succ.succ
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (succ q✝¹ = succ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case succ.succ.h
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ ¬succ q✝¹ = succ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]
case succ.succ.h.refl
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
⊢ False
[PROOFSTEP]
done
[GOAL]
case succ.pred
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (succ q✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case succ.pred
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (succ q✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case succ.pred.h
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
q₁✝ q₂✝ : Λ'
⊢ ¬succ q✝ = pred q₁✝ q₂✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case succ.ret
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ Decidable (succ q✝ = ret k✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case succ.ret
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ Decidable (succ q✝ = ret k✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case succ.ret.h
q✝ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝ = b)
k✝ : Cont'
⊢ ¬succ q✝ = ret k✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case pred.move
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (pred q₁✝ q₂✝ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case pred.move
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (pred q₁✝ q₂✝ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case pred.move.h
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ ¬pred q₁✝ q₂✝ = move p✝ k₁✝ k₂✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case pred.clear
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (pred q₁✝ q₂✝ = clear p✝ k✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case pred.clear
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (pred q₁✝ q₂✝ = clear p✝ k✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case pred.clear.h
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ ¬pred q₁✝ q₂✝ = clear p✝ k✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case pred.copy
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
q✝ : Λ'
⊢ Decidable (pred q₁✝ q₂✝ = copy q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case pred.copy
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
q✝ : Λ'
⊢ Decidable (pred q₁✝ q₂✝ = copy q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case pred.copy.h
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
q✝ : Λ'
⊢ ¬pred q₁✝ q₂✝ = copy q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case pred.push
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (pred q₁✝ q₂✝ = push k✝ s✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case pred.push
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (pred q₁✝ q₂✝ = push k✝ s✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case pred.push.h
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ ¬pred q₁✝ q₂✝ = push k✝ s✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case pred.read
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (pred q₁✝ q₂✝ = read f✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case pred.read
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (pred q₁✝ q₂✝ = read f✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case pred.read.h
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
f✝ : Option Γ' → Λ'
⊢ ¬pred q₁✝ q₂✝ = read f✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case pred.succ
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
q✝ : Λ'
⊢ Decidable (pred q₁✝ q₂✝ = succ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case pred.succ
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
q✝ : Λ'
⊢ Decidable (pred q₁✝ q₂✝ = succ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case pred.succ.h
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
q✝ : Λ'
⊢ ¬pred q₁✝ q₂✝ = succ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case pred.pred
q₁✝¹ q₂✝¹ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝¹ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case pred.pred
q₁✝¹ q₂✝¹ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝¹ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case pred.pred.h
q₁✝¹ q₂✝¹ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝¹ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
⊢ ¬pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]
case pred.pred.h.refl
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
⊢ False
[PROOFSTEP]
done
[GOAL]
case pred.ret
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
k✝ : Cont'
⊢ Decidable (pred q₁✝ q₂✝ = ret k✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case pred.ret
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
k✝ : Cont'
⊢ Decidable (pred q₁✝ q₂✝ = ret k✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case pred.ret.h
q₁✝ q₂✝ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝ = b)
k✝ : Cont'
⊢ ¬pred q₁✝ q₂✝ = ret k✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case ret.move
k✝ : Cont'
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (ret k✝ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case ret.move
k✝ : Cont'
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (ret k✝ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case ret.move.h
k✝ : Cont'
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ ¬ret k✝ = move p✝ k₁✝ k₂✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case ret.clear
k✝¹ : Cont'
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (ret k✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case ret.clear
k✝¹ : Cont'
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (ret k✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case ret.clear.h
k✝¹ : Cont'
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ ¬ret k✝¹ = clear p✝ k✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case ret.copy
k✝ : Cont'
q✝ : Λ'
⊢ Decidable (ret k✝ = copy q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case ret.copy
k✝ : Cont'
q✝ : Λ'
⊢ Decidable (ret k✝ = copy q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case ret.copy.h
k✝ : Cont'
q✝ : Λ'
⊢ ¬ret k✝ = copy q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case ret.push
k✝¹ : Cont'
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (ret k✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case ret.push
k✝¹ : Cont'
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (ret k✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case ret.push.h
k✝¹ : Cont'
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ ¬ret k✝¹ = push k✝ s✝ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case ret.read
k✝ : Cont'
f✝ : Option Γ' → Λ'
⊢ Decidable (ret k✝ = read f✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case ret.read
k✝ : Cont'
f✝ : Option Γ' → Λ'
⊢ Decidable (ret k✝ = read f✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case ret.read.h
k✝ : Cont'
f✝ : Option Γ' → Λ'
⊢ ¬ret k✝ = read f✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case ret.succ
k✝ : Cont'
q✝ : Λ'
⊢ Decidable (ret k✝ = succ q✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case ret.succ
k✝ : Cont'
q✝ : Λ'
⊢ Decidable (ret k✝ = succ q✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case ret.succ.h
k✝ : Cont'
q✝ : Λ'
⊢ ¬ret k✝ = succ q✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case ret.pred
k✝ : Cont'
q₁✝ q₂✝ : Λ'
⊢ Decidable (ret k✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case ret.pred
k✝ : Cont'
q₁✝ q₂✝ : Λ'
⊢ Decidable (ret k✝ = pred q₁✝ q₂✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case ret.pred.h
k✝ : Cont'
q₁✝ q₂✝ : Λ'
⊢ ¬ret k✝ = pred q₁✝ q₂✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]

[PROOFSTEP]
done
[GOAL]
case ret.ret
k✝¹ k✝ : Cont'
⊢ Decidable (ret k✝¹ = ret k✝)
[PROOFSTEP]
try apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done
[GOAL]
case ret.ret
k✝¹ k✝ : Cont'
⊢ Decidable (ret k✝¹ = ret k✝)
[PROOFSTEP]
apply Decidable.isFalse
[GOAL]
case ret.ret.h
k✝¹ k✝ : Cont'
⊢ ¬ret k✝¹ = ret k✝
[PROOFSTEP]
rintro ⟨⟨⟩⟩
[GOAL]
case ret.ret.h.refl
k✝ : Cont'
⊢ False
[PROOFSTEP]
done
[GOAL]
case move.move
p✝¹ : Γ' → Bool
k₁✝¹ k₂✝¹ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (move p✝¹ k₁✝¹ k₂✝¹ q✝¹ = move p✝ k₁✝ k₂✝ q✝)
case clear.clear
p✝¹ : Γ' → Bool
k✝¹ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (clear p✝¹ k✝¹ q✝¹ = clear p✝ k✝ q✝)
case copy.copy
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (copy q✝¹ = copy q✝)
case push.push
k✝¹ : K'
s✝¹ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (push k✝¹ s✝¹ q✝¹ = push k✝ s✝ q✝)
case read.read
f✝¹ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (read f✝¹ = read f✝)
case succ.succ
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (succ q✝¹ = succ q✝)
case pred.pred
q₁✝¹ q₂✝¹ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝¹ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝)
case ret.ret k✝¹ k✝ : Cont' ⊢ Decidable (ret k✝¹ = ret k✝)
[PROOFSTEP]
case move.move _ _ _ _ I _ _ _ _ =>
  letI := I
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
p✝¹ : Γ' → Bool
k₁✝¹ k₂✝¹ : K'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (move p✝¹ k₁✝¹ k₂✝¹ q✝¹ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
case move.move _ _ _ _ I _ _ _ _ =>
  letI := I
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
p✝¹ : Γ' → Bool
k₁✝¹ k₂✝¹ : K'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
⊢ Decidable (move p✝¹ k₁✝¹ k₂✝¹ q✝¹ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
letI := I
[GOAL]
p✝¹ : Γ' → Bool
k₁✝¹ k₂✝¹ : K'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ Decidable (move p✝¹ k₁✝¹ k₂✝¹ q✝¹ = move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
p✝¹ : Γ' → Bool
k₁✝¹ k₂✝¹ : K'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ move p✝¹ k₁✝¹ k₂✝¹ q✝¹ = move p✝ k₁✝ k₂✝ q✝ ↔ ?m.224030
[PROOFSTEP]
simp [Function.funext_iff]
[GOAL]
p✝¹ : Γ' → Bool
k₁✝¹ k₂✝¹ : K'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ (∀ (a : Γ'), p✝¹ a = p✝ a) ∧ k₁✝¹ = k₁✝ ∧ k₂✝¹ = k₂✝ ∧ q✝¹ = q✝ ↔ ?m.224030
[PROOFSTEP]
rfl
[GOAL]
case clear.clear
p✝¹ : Γ' → Bool
k✝¹ : K'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (clear p✝¹ k✝¹ q✝¹ = clear p✝ k✝ q✝)
case copy.copy
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (copy q✝¹ = copy q✝)
case push.push
k✝¹ : K'
s✝¹ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (push k✝¹ s✝¹ q✝¹ = push k✝ s✝ q✝)
case read.read
f✝¹ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (read f✝¹ = read f✝)
case succ.succ
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (succ q✝¹ = succ q✝)
case pred.pred
q₁✝¹ q₂✝¹ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝¹ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝)
case ret.ret k✝¹ k✝ : Cont' ⊢ Decidable (ret k✝¹ = ret k✝)
[PROOFSTEP]
case clear.clear _ _ _ I _ _ _ =>
  letI := I
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
p✝¹ : Γ' → Bool
k✝¹ : K'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (clear p✝¹ k✝¹ q✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
case clear.clear _ _ _ I _ _ _ =>
  letI := I
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
p✝¹ : Γ' → Bool
k✝¹ : K'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
⊢ Decidable (clear p✝¹ k✝¹ q✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
letI := I
[GOAL]
p✝¹ : Γ' → Bool
k✝¹ : K'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ Decidable (clear p✝¹ k✝¹ q✝¹ = clear p✝ k✝ q✝)
[PROOFSTEP]
exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
p✝¹ : Γ' → Bool
k✝¹ : K'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ clear p✝¹ k✝¹ q✝¹ = clear p✝ k✝ q✝ ↔ ?m.227323
[PROOFSTEP]
simp [Function.funext_iff]
[GOAL]
p✝¹ : Γ' → Bool
k✝¹ : K'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ (∀ (a : Γ'), p✝¹ a = p✝ a) ∧ k✝¹ = k✝ ∧ q✝¹ = q✝ ↔ ?m.227323
[PROOFSTEP]
rfl
[GOAL]
case copy.copy
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (copy q✝¹ = copy q✝)
case push.push
k✝¹ : K'
s✝¹ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (push k✝¹ s✝¹ q✝¹ = push k✝ s✝ q✝)
case read.read
f✝¹ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (read f✝¹ = read f✝)
case succ.succ
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (succ q✝¹ = succ q✝)
case pred.pred
q₁✝¹ q₂✝¹ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝¹ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝)
case ret.ret k✝¹ k✝ : Cont' ⊢ Decidable (ret k✝¹ = ret k✝)
[PROOFSTEP]
case copy.copy _ I _ =>
  letI := I
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (copy q✝¹ = copy q✝)
[PROOFSTEP]
case copy.copy _ I _ =>
  letI := I
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (copy q✝¹ = copy q✝)
[PROOFSTEP]
letI := I
[GOAL]
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ Decidable (copy q✝¹ = copy q✝)
[PROOFSTEP]
exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ copy q✝¹ = copy q✝ ↔ ?m.230273
[PROOFSTEP]
simp [Function.funext_iff]
[GOAL]
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ q✝¹ = q✝ ↔ ?m.230273
[PROOFSTEP]
rfl
[GOAL]
case push.push
k✝¹ : K'
s✝¹ : Option Γ' → Option Γ'
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (push k✝¹ s✝¹ q✝¹ = push k✝ s✝ q✝)
case read.read
f✝¹ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (read f✝¹ = read f✝)
case succ.succ
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (succ q✝¹ = succ q✝)
case pred.pred
q₁✝¹ q₂✝¹ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝¹ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝)
case ret.ret k✝¹ k✝ : Cont' ⊢ Decidable (ret k✝¹ = ret k✝)
[PROOFSTEP]
case push.push _ _ _ I _ _ _ =>
  letI := I
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
k✝¹ : K'
s✝¹ : Option Γ' → Option Γ'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (push k✝¹ s✝¹ q✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
case push.push _ _ _ I _ _ _ =>
  letI := I
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
k✝¹ : K'
s✝¹ : Option Γ' → Option Γ'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
⊢ Decidable (push k✝¹ s✝¹ q✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
letI := I
[GOAL]
k✝¹ : K'
s✝¹ : Option Γ' → Option Γ'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ Decidable (push k✝¹ s✝¹ q✝¹ = push k✝ s✝ q✝)
[PROOFSTEP]
exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
k✝¹ : K'
s✝¹ : Option Γ' → Option Γ'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ push k✝¹ s✝¹ q✝¹ = push k✝ s✝ q✝ ↔ ?m.231623
[PROOFSTEP]
simp [Function.funext_iff]
[GOAL]
k✝¹ : K'
s✝¹ : Option Γ' → Option Γ'
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ k✝¹ = k✝ ∧ (∀ (a : Option Γ'), s✝¹ a = s✝ a) ∧ q✝¹ = q✝ ↔ ?m.231623
[PROOFSTEP]
rfl
[GOAL]
case read.read
f✝¹ : Option Γ' → Λ'
f_ih✝ : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (read f✝¹ = read f✝)
case succ.succ
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (succ q✝¹ = succ q✝)
case pred.pred
q₁✝¹ q₂✝¹ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝¹ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝)
case ret.ret k✝¹ k✝ : Cont' ⊢ Decidable (ret k✝¹ = ret k✝)
[PROOFSTEP]
case read.read _ I _ =>
  letI := I
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
f✝¹ : Option Γ' → Λ'
I : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (read f✝¹ = read f✝)
[PROOFSTEP]
case read.read _ I _ =>
  letI := I
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
f✝¹ : Option Γ' → Λ'
I : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b)
f✝ : Option Γ' → Λ'
⊢ Decidable (read f✝¹ = read f✝)
[PROOFSTEP]
letI := I
[GOAL]
f✝¹ : Option Γ' → Λ'
I : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b)
f✝ : Option Γ' → Λ'
this : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b) := I
⊢ Decidable (read f✝¹ = read f✝)
[PROOFSTEP]
exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
f✝¹ : Option Γ' → Λ'
I : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b)
f✝ : Option Γ' → Λ'
this : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b) := I
⊢ read f✝¹ = read f✝ ↔ ?m.235705
[PROOFSTEP]
simp [Function.funext_iff]
[GOAL]
f✝¹ : Option Γ' → Λ'
I : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b)
f✝ : Option Γ' → Λ'
this : (a : Option Γ') → (b : Λ') → Decidable (f✝¹ a = b) := I
⊢ (∀ (a : Option Γ'), f✝¹ a = f✝ a) ↔ ?m.235705
[PROOFSTEP]
rfl
[GOAL]
case succ.succ
q✝¹ : Λ'
q_ih✝ : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (succ q✝¹ = succ q✝)
case pred.pred
q₁✝¹ q₂✝¹ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝¹ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝)
case ret.ret k✝¹ k✝ : Cont' ⊢ Decidable (ret k✝¹ = ret k✝)
[PROOFSTEP]
case succ.succ _ I _ =>
  letI := I
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (succ q✝¹ = succ q✝)
[PROOFSTEP]
case succ.succ _ I _ =>
  letI := I
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
⊢ Decidable (succ q✝¹ = succ q✝)
[PROOFSTEP]
letI := I
[GOAL]
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ Decidable (succ q✝¹ = succ q✝)
[PROOFSTEP]
exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ succ q✝¹ = succ q✝ ↔ ?m.239621
[PROOFSTEP]
simp [Function.funext_iff]
[GOAL]
q✝¹ : Λ'
I : (b : Λ') → Decidable (q✝¹ = b)
q✝ : Λ'
this : (b : Λ') → Decidable (q✝¹ = b) := I
⊢ q✝¹ = q✝ ↔ ?m.239621
[PROOFSTEP]
rfl
[GOAL]
case pred.pred
q₁✝¹ q₂✝¹ : Λ'
q₁_ih✝ : (b : Λ') → Decidable (q₁✝¹ = b)
q₂_ih✝ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝)
case ret.ret k✝¹ k✝ : Cont' ⊢ Decidable (ret k✝¹ = ret k✝)
[PROOFSTEP]
case pred.pred _ _ I₁ I₂ _ _ =>
  letI := I₁
  letI := I₂
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
q₁✝¹ q₂✝¹ : Λ'
I₁ : (b : Λ') → Decidable (q₁✝¹ = b)
I₂ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝)
[PROOFSTEP]
case pred.pred _ _ I₁ I₂ _ _ =>
  letI := I₁
  letI := I₂
  exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
q₁✝¹ q₂✝¹ : Λ'
I₁ : (b : Λ') → Decidable (q₁✝¹ = b)
I₂ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
⊢ Decidable (pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝)
[PROOFSTEP]
letI := I₁
[GOAL]
q₁✝¹ q₂✝¹ : Λ'
I₁ : (b : Λ') → Decidable (q₁✝¹ = b)
I₂ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
this : (b : Λ') → Decidable (q₁✝¹ = b) := I₁
⊢ Decidable (pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝)
[PROOFSTEP]
letI := I₂
[GOAL]
q₁✝¹ q₂✝¹ : Λ'
I₁ : (b : Λ') → Decidable (q₁✝¹ = b)
I₂ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
this✝ : (b : Λ') → Decidable (q₁✝¹ = b) := I₁
this : (b : Λ') → Decidable (q₂✝¹ = b) := I₂
⊢ Decidable (pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝)
[PROOFSTEP]
exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
q₁✝¹ q₂✝¹ : Λ'
I₁ : (b : Λ') → Decidable (q₁✝¹ = b)
I₂ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
this✝ : (b : Λ') → Decidable (q₁✝¹ = b) := I₁
this : (b : Λ') → Decidable (q₂✝¹ = b) := I₂
⊢ pred q₁✝¹ q₂✝¹ = pred q₁✝ q₂✝ ↔ ?m.240977
[PROOFSTEP]
simp [Function.funext_iff]
[GOAL]
q₁✝¹ q₂✝¹ : Λ'
I₁ : (b : Λ') → Decidable (q₁✝¹ = b)
I₂ : (b : Λ') → Decidable (q₂✝¹ = b)
q₁✝ q₂✝ : Λ'
this✝ : (b : Λ') → Decidable (q₁✝¹ = b) := I₁
this : (b : Λ') → Decidable (q₂✝¹ = b) := I₂
⊢ q₁✝¹ = q₁✝ ∧ q₂✝¹ = q₂✝ ↔ ?m.240977
[PROOFSTEP]
rfl
[GOAL]
case ret.ret
k✝¹ k✝ : Cont'
⊢ Decidable (ret k✝¹ = ret k✝)
[PROOFSTEP]
case ret.ret _ _ => exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
k✝¹ k✝ : Cont'
⊢ Decidable (ret k✝¹ = ret k✝)
[PROOFSTEP]
case ret.ret _ _ => exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
k✝¹ k✝ : Cont'
⊢ Decidable (ret k✝¹ = ret k✝)
[PROOFSTEP]
exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl)
[GOAL]
k✝¹ k✝ : Cont'
⊢ ret k✝¹ = ret k✝ ↔ ?m.242367
[PROOFSTEP]
simp [Function.funext_iff]
[GOAL]
k✝¹ k✝ : Cont'
⊢ k✝¹ = k✝ ↔ ?m.242367
[PROOFSTEP]
rfl
[GOAL]
⊢ trNat 0 = []
[PROOFSTEP]
rw [trNat, Nat.cast_zero]
[GOAL]
⊢ trNum 0 = []
[PROOFSTEP]
rfl
[GOAL]
a b c d a' : List Γ'
⊢ update (elim a b c d) main a' = elim a' b c d
[PROOFSTEP]
funext x
[GOAL]
case h
a b c d a' : List Γ'
x : K'
⊢ update (elim a b c d) main a' x = elim a' b c d x
[PROOFSTEP]
cases x
[GOAL]
case h.main
a b c d a' : List Γ'
⊢ update (elim a b c d) main a' main = elim a' b c d main
[PROOFSTEP]
rfl
[GOAL]
case h.rev
a b c d a' : List Γ'
⊢ update (elim a b c d) main a' rev = elim a' b c d rev
[PROOFSTEP]
rfl
[GOAL]
case h.aux
a b c d a' : List Γ'
⊢ update (elim a b c d) main a' aux = elim a' b c d aux
[PROOFSTEP]
rfl
[GOAL]
case h.stack
a b c d a' : List Γ'
⊢ update (elim a b c d) main a' stack = elim a' b c d stack
[PROOFSTEP]
rfl
[GOAL]
a b c d b' : List Γ'
⊢ update (elim a b c d) rev b' = elim a b' c d
[PROOFSTEP]
funext x
[GOAL]
case h
a b c d b' : List Γ'
x : K'
⊢ update (elim a b c d) rev b' x = elim a b' c d x
[PROOFSTEP]
cases x
[GOAL]
case h.main
a b c d b' : List Γ'
⊢ update (elim a b c d) rev b' main = elim a b' c d main
[PROOFSTEP]
rfl
[GOAL]
case h.rev
a b c d b' : List Γ'
⊢ update (elim a b c d) rev b' rev = elim a b' c d rev
[PROOFSTEP]
rfl
[GOAL]
case h.aux
a b c d b' : List Γ'
⊢ update (elim a b c d) rev b' aux = elim a b' c d aux
[PROOFSTEP]
rfl
[GOAL]
case h.stack
a b c d b' : List Γ'
⊢ update (elim a b c d) rev b' stack = elim a b' c d stack
[PROOFSTEP]
rfl
[GOAL]
a b c d c' : List Γ'
⊢ update (elim a b c d) aux c' = elim a b c' d
[PROOFSTEP]
funext x
[GOAL]
case h
a b c d c' : List Γ'
x : K'
⊢ update (elim a b c d) aux c' x = elim a b c' d x
[PROOFSTEP]
cases x
[GOAL]
case h.main
a b c d c' : List Γ'
⊢ update (elim a b c d) aux c' main = elim a b c' d main
[PROOFSTEP]
rfl
[GOAL]
case h.rev
a b c d c' : List Γ'
⊢ update (elim a b c d) aux c' rev = elim a b c' d rev
[PROOFSTEP]
rfl
[GOAL]
case h.aux
a b c d c' : List Γ'
⊢ update (elim a b c d) aux c' aux = elim a b c' d aux
[PROOFSTEP]
rfl
[GOAL]
case h.stack
a b c d c' : List Γ'
⊢ update (elim a b c d) aux c' stack = elim a b c' d stack
[PROOFSTEP]
rfl
[GOAL]
a b c d d' : List Γ'
⊢ update (elim a b c d) stack d' = elim a b c d'
[PROOFSTEP]
funext x
[GOAL]
case h
a b c d d' : List Γ'
x : K'
⊢ update (elim a b c d) stack d' x = elim a b c d' x
[PROOFSTEP]
cases x
[GOAL]
case h.main
a b c d d' : List Γ'
⊢ update (elim a b c d) stack d' main = elim a b c d' main
[PROOFSTEP]
rfl
[GOAL]
case h.rev
a b c d d' : List Γ'
⊢ update (elim a b c d) stack d' rev = elim a b c d' rev
[PROOFSTEP]
rfl
[GOAL]
case h.aux
a b c d d' : List Γ'
⊢ update (elim a b c d) stack d' aux = elim a b c d' aux
[PROOFSTEP]
rfl
[GOAL]
case h.stack
a b c d d' : List Γ'
⊢ update (elim a b c d) stack d' stack = elim a b c d' stack
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
p : α → Bool
l₁ : List α
o : α
l₂ : List α
x✝ : ∀ (x : α), x ∈ l₁ → p x = false
left✝ : p o = true
h₃ : [] = l₁ ++ o :: l₂
⊢ splitAtPred p [] = (l₁, some o, l₂)
[PROOFSTEP]
simp at h₃
[GOAL]
α : Type u_1
p : α → Bool
a : α
L l₁ : List α
o : Option α
l₂ : List α
h₁ : ∀ (x : α), x ∈ l₁ → p x = false
h₂ : Option.elim' (a :: L = l₁ ∧ l₂ = []) (fun a_1 => p a_1 = true ∧ a :: L = l₁ ++ a_1 :: l₂) o
⊢ splitAtPred p (a :: L) = (l₁, o, l₂)
[PROOFSTEP]
rw [splitAtPred]
[GOAL]
α : Type u_1
p : α → Bool
a : α
L l₁ : List α
o : Option α
l₂ : List α
h₁ : ∀ (x : α), x ∈ l₁ → p x = false
h₂ : Option.elim' (a :: L = l₁ ∧ l₂ = []) (fun a_1 => p a_1 = true ∧ a :: L = l₁ ++ a_1 :: l₂) o
⊢ (bif p a then ([], some a, L)
    else
      match splitAtPred p L with
      | (l₁, o, l₂) => (a :: l₁, o, l₂)) =
    (l₁, o, l₂)
[PROOFSTEP]
have IH := splitAtPred_eq p L
[GOAL]
α : Type u_1
p : α → Bool
a : α
L l₁ : List α
o : Option α
l₂ : List α
h₁ : ∀ (x : α), x ∈ l₁ → p x = false
h₂ : Option.elim' (a :: L = l₁ ∧ l₂ = []) (fun a_1 => p a_1 = true ∧ a :: L = l₁ ++ a_1 :: l₂) o
IH :
  ∀ (l₁ : List α) (o : Option α) (l₂ : List α),
    (∀ (x : α), x ∈ l₁ → p x = false) →
      Option.elim' (L = l₁ ∧ l₂ = []) (fun a => p a = true ∧ L = l₁ ++ a :: l₂) o → splitAtPred p L = (l₁, o, l₂)
⊢ (bif p a then ([], some a, L)
    else
      match splitAtPred p L with
      | (l₁, o, l₂) => (a :: l₁, o, l₂)) =
    (l₁, o, l₂)
[PROOFSTEP]
cases' o with o
[GOAL]
case none
α : Type u_1
p : α → Bool
a : α
L l₁ l₂ : List α
h₁ : ∀ (x : α), x ∈ l₁ → p x = false
IH :
  ∀ (l₁ : List α) (o : Option α) (l₂ : List α),
    (∀ (x : α), x ∈ l₁ → p x = false) →
      Option.elim' (L = l₁ ∧ l₂ = []) (fun a => p a = true ∧ L = l₁ ++ a :: l₂) o → splitAtPred p L = (l₁, o, l₂)
h₂ : Option.elim' (a :: L = l₁ ∧ l₂ = []) (fun a_1 => p a_1 = true ∧ a :: L = l₁ ++ a_1 :: l₂) none
⊢ (bif p a then ([], some a, L)
    else
      match splitAtPred p L with
      | (l₁, o, l₂) => (a :: l₁, o, l₂)) =
    (l₁, none, l₂)
[PROOFSTEP]
cases' l₁ with a' l₁
[GOAL]
case none.nil
α : Type u_1
p : α → Bool
a : α
L l₂ : List α
IH :
  ∀ (l₁ : List α) (o : Option α) (l₂ : List α),
    (∀ (x : α), x ∈ l₁ → p x = false) →
      Option.elim' (L = l₁ ∧ l₂ = []) (fun a => p a = true ∧ L = l₁ ++ a :: l₂) o → splitAtPred p L = (l₁, o, l₂)
h₁ : ∀ (x : α), x ∈ [] → p x = false
h₂ : Option.elim' (a :: L = [] ∧ l₂ = []) (fun a_1 => p a_1 = true ∧ a :: L = [] ++ a_1 :: l₂) none
⊢ (bif p a then ([], some a, L)
    else
      match splitAtPred p L with
      | (l₁, o, l₂) => (a :: l₁, o, l₂)) =
    ([], none, l₂)
[PROOFSTEP]
rcases h₂ with ⟨⟨⟩, rfl⟩
[GOAL]
case none.cons
α : Type u_1
p : α → Bool
a : α
L l₂ : List α
IH :
  ∀ (l₁ : List α) (o : Option α) (l₂ : List α),
    (∀ (x : α), x ∈ l₁ → p x = false) →
      Option.elim' (L = l₁ ∧ l₂ = []) (fun a => p a = true ∧ L = l₁ ++ a :: l₂) o → splitAtPred p L = (l₁, o, l₂)
a' : α
l₁ : List α
h₁ : ∀ (x : α), x ∈ a' :: l₁ → p x = false
h₂ : Option.elim' (a :: L = a' :: l₁ ∧ l₂ = []) (fun a_1 => p a_1 = true ∧ a :: L = a' :: l₁ ++ a_1 :: l₂) none
⊢ (bif p a then ([], some a, L)
    else
      match splitAtPred p L with
      | (l₁, o, l₂) => (a :: l₁, o, l₂)) =
    (a' :: l₁, none, l₂)
[PROOFSTEP]
rcases h₂ with ⟨⟨⟩, rfl⟩
[GOAL]
case none.cons.intro.refl
α : Type u_1
p : α → Bool
a : α
L : List α
IH :
  ∀ (l₁ : List α) (o : Option α) (l₂ : List α),
    (∀ (x : α), x ∈ l₁ → p x = false) →
      Option.elim' (L = l₁ ∧ l₂ = []) (fun a => p a = true ∧ L = l₁ ++ a :: l₂) o → splitAtPred p L = (l₁, o, l₂)
h₁ : ∀ (x : α), x ∈ a :: L → p x = false
⊢ (bif p a then ([], some a, L)
    else
      match splitAtPred p L with
      | (l₁, o, l₂) => (a :: l₁, o, l₂)) =
    (a :: L, none, [])
[PROOFSTEP]
rw [h₁ a (List.Mem.head _), cond, IH L none [] _ ⟨rfl, rfl⟩]
[GOAL]
α : Type u_1
p : α → Bool
a : α
L : List α
IH :
  ∀ (l₁ : List α) (o : Option α) (l₂ : List α),
    (∀ (x : α), x ∈ l₁ → p x = false) →
      Option.elim' (L = l₁ ∧ l₂ = []) (fun a => p a = true ∧ L = l₁ ++ a :: l₂) o → splitAtPred p L = (l₁, o, l₂)
h₁ : ∀ (x : α), x ∈ a :: L → p x = false
⊢ ∀ (x : α), x ∈ L → p x = false
[PROOFSTEP]
exact fun x h => h₁ x (List.Mem.tail _ h)
[GOAL]
case some
α : Type u_1
p : α → Bool
a : α
L l₁ l₂ : List α
h₁ : ∀ (x : α), x ∈ l₁ → p x = false
IH :
  ∀ (l₁ : List α) (o : Option α) (l₂ : List α),
    (∀ (x : α), x ∈ l₁ → p x = false) →
      Option.elim' (L = l₁ ∧ l₂ = []) (fun a => p a = true ∧ L = l₁ ++ a :: l₂) o → splitAtPred p L = (l₁, o, l₂)
o : α
h₂ : Option.elim' (a :: L = l₁ ∧ l₂ = []) (fun a_1 => p a_1 = true ∧ a :: L = l₁ ++ a_1 :: l₂) (some o)
⊢ (bif p a then ([], some a, L)
    else
      match splitAtPred p L with
      | (l₁, o, l₂) => (a :: l₁, o, l₂)) =
    (l₁, some o, l₂)
[PROOFSTEP]
cases' l₁ with a' l₁
[GOAL]
case some.nil
α : Type u_1
p : α → Bool
a : α
L l₂ : List α
IH :
  ∀ (l₁ : List α) (o : Option α) (l₂ : List α),
    (∀ (x : α), x ∈ l₁ → p x = false) →
      Option.elim' (L = l₁ ∧ l₂ = []) (fun a => p a = true ∧ L = l₁ ++ a :: l₂) o → splitAtPred p L = (l₁, o, l₂)
o : α
h₁ : ∀ (x : α), x ∈ [] → p x = false
h₂ : Option.elim' (a :: L = [] ∧ l₂ = []) (fun a_1 => p a_1 = true ∧ a :: L = [] ++ a_1 :: l₂) (some o)
⊢ (bif p a then ([], some a, L)
    else
      match splitAtPred p L with
      | (l₁, o, l₂) => (a :: l₁, o, l₂)) =
    ([], some o, l₂)
[PROOFSTEP]
rcases h₂ with ⟨h₂, ⟨⟩⟩
[GOAL]
case some.cons
α : Type u_1
p : α → Bool
a : α
L l₂ : List α
IH :
  ∀ (l₁ : List α) (o : Option α) (l₂ : List α),
    (∀ (x : α), x ∈ l₁ → p x = false) →
      Option.elim' (L = l₁ ∧ l₂ = []) (fun a => p a = true ∧ L = l₁ ++ a :: l₂) o → splitAtPred p L = (l₁, o, l₂)
o a' : α
l₁ : List α
h₁ : ∀ (x : α), x ∈ a' :: l₁ → p x = false
h₂ : Option.elim' (a :: L = a' :: l₁ ∧ l₂ = []) (fun a_1 => p a_1 = true ∧ a :: L = a' :: l₁ ++ a_1 :: l₂) (some o)
⊢ (bif p a then ([], some a, L)
    else
      match splitAtPred p L with
      | (l₁, o, l₂) => (a :: l₁, o, l₂)) =
    (a' :: l₁, some o, l₂)
[PROOFSTEP]
rcases h₂ with ⟨h₂, ⟨⟩⟩
[GOAL]
case some.nil.intro.refl
α : Type u_1
p : α → Bool
a : α
L : List α
IH :
  ∀ (l₁ : List α) (o : Option α) (l₂ : List α),
    (∀ (x : α), x ∈ l₁ → p x = false) →
      Option.elim' (L = l₁ ∧ l₂ = []) (fun a => p a = true ∧ L = l₁ ++ a :: l₂) o → splitAtPred p L = (l₁, o, l₂)
h₁ : ∀ (x : α), x ∈ [] → p x = false
h₂ : p a = true
⊢ (bif p a then ([], some a, L)
    else
      match splitAtPred p L with
      | (l₁, o, l₂) => (a :: l₁, o, l₂)) =
    ([], some a, L)
[PROOFSTEP]
rw [h₂, cond]
[GOAL]
case some.cons.intro.refl
α : Type u_1
p : α → Bool
a : α
l₂ : List α
o : α
l₁ : List α
h₂ : p o = true
h₁ : ∀ (x : α), x ∈ a :: l₁ → p x = false
IH :
  ∀ (l₁_1 : List α) (o_1 : Option α) (l₂_1 : List α),
    (∀ (x : α), x ∈ l₁_1 → p x = false) →
      Option.elim' (List.append l₁ (o :: l₂) = l₁_1 ∧ l₂_1 = [])
          (fun a => p a = true ∧ List.append l₁ (o :: l₂) = l₁_1 ++ a :: l₂_1) o_1 →
        splitAtPred p (List.append l₁ (o :: l₂)) = (l₁_1, o_1, l₂_1)
⊢ (bif p a then ([], some a, List.append l₁ (o :: l₂))
    else
      match splitAtPred p (List.append l₁ (o :: l₂)) with
      | (l₁, o, l₂) => (a :: l₁, o, l₂)) =
    (a :: l₁, some o, l₂)
[PROOFSTEP]
rw [h₁ a (List.Mem.head _), cond, IH l₁ (some o) l₂ _ ⟨h₂, _⟩]
[GOAL]
α : Type u_1
p : α → Bool
a : α
l₂ : List α
o : α
l₁ : List α
h₂ : p o = true
h₁ : ∀ (x : α), x ∈ a :: l₁ → p x = false
IH :
  ∀ (l₁_1 : List α) (o_1 : Option α) (l₂_1 : List α),
    (∀ (x : α), x ∈ l₁_1 → p x = false) →
      Option.elim' (List.append l₁ (o :: l₂) = l₁_1 ∧ l₂_1 = [])
          (fun a => p a = true ∧ List.append l₁ (o :: l₂) = l₁_1 ++ a :: l₂_1) o_1 →
        splitAtPred p (List.append l₁ (o :: l₂)) = (l₁_1, o_1, l₂_1)
⊢ ∀ (x : α), x ∈ l₁ → p x = false
[PROOFSTEP]
try rfl
[GOAL]
α : Type u_1
p : α → Bool
a : α
l₂ : List α
o : α
l₁ : List α
h₂ : p o = true
h₁ : ∀ (x : α), x ∈ a :: l₁ → p x = false
IH :
  ∀ (l₁_1 : List α) (o_1 : Option α) (l₂_1 : List α),
    (∀ (x : α), x ∈ l₁_1 → p x = false) →
      Option.elim' (List.append l₁ (o :: l₂) = l₁_1 ∧ l₂_1 = [])
          (fun a => p a = true ∧ List.append l₁ (o :: l₂) = l₁_1 ++ a :: l₂_1) o_1 →
        splitAtPred p (List.append l₁ (o :: l₂)) = (l₁_1, o_1, l₂_1)
⊢ ∀ (x : α), x ∈ l₁ → p x = false
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
p : α → Bool
a : α
l₂ : List α
o : α
l₁ : List α
h₂ : p o = true
h₁ : ∀ (x : α), x ∈ a :: l₁ → p x = false
IH :
  ∀ (l₁_1 : List α) (o_1 : Option α) (l₂_1 : List α),
    (∀ (x : α), x ∈ l₁_1 → p x = false) →
      Option.elim' (List.append l₁ (o :: l₂) = l₁_1 ∧ l₂_1 = [])
          (fun a => p a = true ∧ List.append l₁ (o :: l₂) = l₁_1 ++ a :: l₂_1) o_1 →
        splitAtPred p (List.append l₁ (o :: l₂)) = (l₁_1, o_1, l₂_1)
⊢ List.append l₁ (o :: l₂) = l₁ ++ o :: l₂
[PROOFSTEP]
try rfl
[GOAL]
α : Type u_1
p : α → Bool
a : α
l₂ : List α
o : α
l₁ : List α
h₂ : p o = true
h₁ : ∀ (x : α), x ∈ a :: l₁ → p x = false
IH :
  ∀ (l₁_1 : List α) (o_1 : Option α) (l₂_1 : List α),
    (∀ (x : α), x ∈ l₁_1 → p x = false) →
      Option.elim' (List.append l₁ (o :: l₂) = l₁_1 ∧ l₂_1 = [])
          (fun a => p a = true ∧ List.append l₁ (o :: l₂) = l₁_1 ++ a :: l₂_1) o_1 →
        splitAtPred p (List.append l₁ (o :: l₂)) = (l₁_1, o_1, l₂_1)
⊢ List.append l₁ (o :: l₂) = l₁ ++ o :: l₂
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
p : α → Bool
a : α
l₂ : List α
o : α
l₁ : List α
h₂ : p o = true
h₁ : ∀ (x : α), x ∈ a :: l₁ → p x = false
IH :
  ∀ (l₁_1 : List α) (o_1 : Option α) (l₂_1 : List α),
    (∀ (x : α), x ∈ l₁_1 → p x = false) →
      Option.elim' (List.append l₁ (o :: l₂) = l₁_1 ∧ l₂_1 = [])
          (fun a => p a = true ∧ List.append l₁ (o :: l₂) = l₁_1 ++ a :: l₂_1) o_1 →
        splitAtPred p (List.append l₁ (o :: l₂)) = (l₁_1, o_1, l₂_1)
⊢ ∀ (x : α), x ∈ l₁ → p x = false
[PROOFSTEP]
exact fun x h => h₁ x (List.Mem.tail _ h)
[GOAL]
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ k₂
e : splitAtPred p (S k₁) = (L₁, o, L₂)
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
[PROOFSTEP]
induction' L₁ with a L₁ IH generalizing S s
[GOAL]
case nil
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k₁) = ([], o, L₂)
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux [] (S k₂)) }
[PROOFSTEP]
rw [(_ : [].reverseAux _ = _), Function.update_eq_self]
[GOAL]
case nil
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k₁) = ([], o, L₂)
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
    { l := some q, var := o, stk := update S k₁ L₂ }
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k₁) = ([], o, L₂)
⊢ List.reverseAux [] (S k₂) = update S k₁ L₂ k₂
[PROOFSTEP]
swap
[GOAL]
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k₁) = ([], o, L₂)
⊢ List.reverseAux [] (S k₂) = update S k₁ L₂ k₂
[PROOFSTEP]
rw [Function.update_noteq h₁.symm]
[GOAL]
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k₁) = ([], o, L₂)
⊢ List.reverseAux [] (S k₂) = S k₂
[PROOFSTEP]
rfl
[GOAL]
case nil
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k₁) = ([], o, L₂)
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
    { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
refine' TransGen.head' rfl _
[GOAL]
case nil
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k₁) = ([], o, L₂)
⊢ ReflTransGen (fun a b => b ∈ TM2.step tr a) (TM2.stepAux (tr (Λ'.move p k₁ k₂ q)) s S)
    { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
simp
[GOAL]
case nil
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k₁) = ([], o, L₂)
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (S k₁), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (S k₁), stk := update S k₁ (List.tail (S k₁)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (S k₁),
        stk :=
          update (update S k₁ (List.tail (S k₁))) k₂
            (Option.iget (List.head? (S k₁)) :: update S k₁ (List.tail (S k₁)) k₂) })
    { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
revert e
[GOAL]
case nil
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
⊢ splitAtPred p (S k₁) = ([], o, L₂) →
    ReflTransGen
      (fun a b =>
        (match a with
          | { l := none, var := var, stk := stk } => none
          | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
          some b)
      (bif
          match List.head? (S k₁), true, p with
          | some x, x_1, f => f x
          | none, y, x => y then
        { l := some q, var := List.head? (S k₁), stk := update S k₁ (List.tail (S k₁)) }
      else
        { l := some (Λ'.move p k₁ k₂ q), var := List.head? (S k₁),
          stk :=
            update (update S k₁ (List.tail (S k₁))) k₂
              (Option.iget (List.head? (S k₁)) :: update S k₁ (List.tail (S k₁)) k₂) })
      { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
cases' S k₁ with a Sk
[GOAL]
case nil.nil
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
⊢ splitAtPred p [] = ([], o, L₂) →
    ReflTransGen
      (fun a b =>
        (match a with
          | { l := none, var := var, stk := stk } => none
          | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
          some b)
      (bif
          match List.head? [], true, p with
          | some x, x_1, f => f x
          | none, y, x => y then
        { l := some q, var := List.head? [], stk := update S k₁ (List.tail []) }
      else
        { l := some (Λ'.move p k₁ k₂ q), var := List.head? [],
          stk :=
            update (update S k₁ (List.tail [])) k₂ (Option.iget (List.head? []) :: update S k₁ (List.tail []) k₂) })
      { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
intro e
[GOAL]
case nil.cons
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
⊢ splitAtPred p (a :: Sk) = ([], o, L₂) →
    ReflTransGen
      (fun a b =>
        (match a with
          | { l := none, var := var, stk := stk } => none
          | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
          some b)
      (bif
          match List.head? (a :: Sk), true, p with
          | some x, x_1, f => f x
          | none, y, x => y then
        { l := some q, var := List.head? (a :: Sk), stk := update S k₁ (List.tail (a :: Sk)) }
      else
        { l := some (Λ'.move p k₁ k₂ q), var := List.head? (a :: Sk),
          stk :=
            update (update S k₁ (List.tail (a :: Sk))) k₂
              (Option.iget (List.head? (a :: Sk)) :: update S k₁ (List.tail (a :: Sk)) k₂) })
      { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
intro e
[GOAL]
case nil.nil
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p [] = ([], o, L₂)
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? [], true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? [], stk := update S k₁ (List.tail []) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? [],
        stk := update (update S k₁ (List.tail [])) k₂ (Option.iget (List.head? []) :: update S k₁ (List.tail []) k₂) })
    { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
cases e
[GOAL]
case nil.nil.refl
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S✝ k₁) = (L₁, none, [])
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? [], true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? [], stk := update S k₁ (List.tail []) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? [],
        stk := update (update S k₁ (List.tail [])) k₂ (Option.iget (List.head? []) :: update S k₁ (List.tail []) k₂) })
    { l := some q, var := none, stk := update S k₁ [] }
[PROOFSTEP]
rfl
[GOAL]
case nil.cons
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
e : splitAtPred p (a :: Sk) = ([], o, L₂)
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a :: Sk), stk := update S k₁ (List.tail (a :: Sk)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (a :: Sk),
        stk :=
          update (update S k₁ (List.tail (a :: Sk))) k₂
            (Option.iget (List.head? (a :: Sk)) :: update S k₁ (List.tail (a :: Sk)) k₂) })
    { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
simp only [splitAtPred, Option.elim, List.head?, List.tail_cons, Option.iget_some] at e ⊢
[GOAL]
case nil.cons
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
e :
  (bif p a then ([], some a, Sk)
    else (a :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd)) =
    ([], o, L₂)
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif p a then { l := some q, var := some a, stk := update S k₁ Sk }
    else { l := some (Λ'.move p k₁ k₂ q), var := some a, stk := update (update S k₁ Sk) k₂ (a :: update S k₁ Sk k₂) })
    { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
revert e
[GOAL]
case nil.cons
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
⊢ (bif p a then ([], some a, Sk)
      else (a :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd)) =
      ([], o, L₂) →
    ReflTransGen
      (fun a b =>
        (match a with
          | { l := none, var := var, stk := stk } => none
          | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
          some b)
      (bif p a then { l := some q, var := some a, stk := update S k₁ Sk }
      else { l := some (Λ'.move p k₁ k₂ q), var := some a, stk := update (update S k₁ Sk) k₂ (a :: update S k₁ Sk k₂) })
      { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
cases p a
[GOAL]
case nil.cons.false
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
⊢ (bif false then ([], some a, Sk)
      else (a :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd)) =
      ([], o, L₂) →
    ReflTransGen
      (fun a b =>
        (match a with
          | { l := none, var := var, stk := stk } => none
          | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
          some b)
      (bif false then { l := some q, var := some a, stk := update S k₁ Sk }
      else { l := some (Λ'.move p k₁ k₂ q), var := some a, stk := update (update S k₁ Sk) k₂ (a :: update S k₁ Sk k₂) })
      { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
intro e
[GOAL]
case nil.cons.true
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
⊢ (bif true then ([], some a, Sk)
      else (a :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd)) =
      ([], o, L₂) →
    ReflTransGen
      (fun a b =>
        (match a with
          | { l := none, var := var, stk := stk } => none
          | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
          some b)
      (bif true then { l := some q, var := some a, stk := update S k₁ Sk }
      else { l := some (Λ'.move p k₁ k₂ q), var := some a, stk := update (update S k₁ Sk) k₂ (a :: update S k₁ Sk k₂) })
      { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
intro e
[GOAL]
case nil.cons.false
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
e :
  (bif false then ([], some a, Sk)
    else (a :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd)) =
    ([], o, L₂)
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif false then { l := some q, var := some a, stk := update S k₁ Sk }
    else { l := some (Λ'.move p k₁ k₂ q), var := some a, stk := update (update S k₁ Sk) k₂ (a :: update S k₁ Sk k₂) })
    { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
simp only [cond_false, cond_true, Prod.mk.injEq, true_and, false_and] at e ⊢
[GOAL]
case nil.cons.true
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
e :
  (bif true then ([], some a, Sk)
    else (a :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd)) =
    ([], o, L₂)
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif true then { l := some q, var := some a, stk := update S k₁ Sk }
    else { l := some (Λ'.move p k₁ k₂ q), var := some a, stk := update (update S k₁ Sk) k₂ (a :: update S k₁ Sk k₂) })
    { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
simp only [cond_false, cond_true, Prod.mk.injEq, true_and, false_and] at e ⊢
[GOAL]
case nil.cons.true
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
e : some a = o ∧ Sk = L₂
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some q, var := some a, stk := update S k₁ Sk } { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
simp only [e]
[GOAL]
case nil.cons.true
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
e : some a = o ∧ Sk = L₂
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some q, var := o, stk := update S k₁ L₂ } { l := some q, var := o, stk := update S k₁ L₂ }
[PROOFSTEP]
rfl
[GOAL]
case cons
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k₁) = (a :: L₁, o, L₂)
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux (a :: L₁) (S k₂)) }
[PROOFSTEP]
refine' TransGen.head rfl _
[GOAL]
case cons
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k₁) = (a :: L₁, o, L₂)
⊢ TransGen (fun a b => b ∈ TM2.step tr a) (TM2.stepAux (tr (Λ'.move p k₁ k₂ q)) s S)
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux (a :: L₁) (S k₂)) }
[PROOFSTEP]
simp
[GOAL]
case cons
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k₁) = (a :: L₁, o, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (S k₁), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (S k₁), stk := update S k₁ (List.tail (S k₁)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (S k₁),
        stk :=
          update (update S k₁ (List.tail (S k₁))) k₂
            (Option.iget (List.head? (S k₁)) :: update S k₁ (List.tail (S k₁)) k₂) })
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (a :: S k₂)) }
[PROOFSTEP]
cases' e₁ : S k₁ with a' Sk
[GOAL]
case cons.nil
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k₁) = (a :: L₁, o, L₂)
e₁ : S k₁ = []
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? [], true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? [], stk := update S k₁ (List.tail []) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? [],
        stk := update (update S k₁ (List.tail [])) k₂ (Option.iget (List.head? []) :: update S k₁ (List.tail []) k₂) })
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (a :: S k₂)) }
[PROOFSTEP]
rw [e₁, splitAtPred] at e
[GOAL]
case cons.cons
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k₁) = (a :: L₁, o, L₂)
a' : Γ'
Sk : List Γ'
e₁ : S k₁ = a' :: Sk
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k₁ (List.tail (a' :: Sk)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (a' :: Sk),
        stk :=
          update (update S k₁ (List.tail (a' :: Sk))) k₂
            (Option.iget (List.head? (a' :: Sk)) :: update S k₁ (List.tail (a' :: Sk)) k₂) })
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (a :: S k₂)) }
[PROOFSTEP]
rw [e₁, splitAtPred] at e
[GOAL]
case cons.nil
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
e : ([], none, []) = (a :: L₁, o, L₂)
e₁ : S k₁ = []
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? [], true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? [], stk := update S k₁ (List.tail []) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? [],
        stk := update (update S k₁ (List.tail [])) k₂ (Option.iget (List.head? []) :: update S k₁ (List.tail []) k₂) })
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (a :: S k₂)) }
[PROOFSTEP]
cases e
[GOAL]
case cons.cons
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e :
  (bif p a' then ([], some a', Sk)
    else
      match splitAtPred p Sk with
      | (l₁, o, l₂) => (a' :: l₁, o, l₂)) =
    (a :: L₁, o, L₂)
e₁ : S k₁ = a' :: Sk
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k₁ (List.tail (a' :: Sk)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (a' :: Sk),
        stk :=
          update (update S k₁ (List.tail (a' :: Sk))) k₂
            (Option.iget (List.head? (a' :: Sk)) :: update S k₁ (List.tail (a' :: Sk)) k₂) })
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (a :: S k₂)) }
[PROOFSTEP]
cases e₂ : p a'
[GOAL]
case cons.cons.false
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e :
  (bif p a' then ([], some a', Sk)
    else
      match splitAtPred p Sk with
      | (l₁, o, l₂) => (a' :: l₁, o, l₂)) =
    (a :: L₁, o, L₂)
e₁ : S k₁ = a' :: Sk
e₂ : p a' = false
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k₁ (List.tail (a' :: Sk)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (a' :: Sk),
        stk :=
          update (update S k₁ (List.tail (a' :: Sk))) k₂
            (Option.iget (List.head? (a' :: Sk)) :: update S k₁ (List.tail (a' :: Sk)) k₂) })
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (a :: S k₂)) }
[PROOFSTEP]
simp only [e₂, cond] at e
[GOAL]
case cons.cons.true
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e :
  (bif p a' then ([], some a', Sk)
    else
      match splitAtPred p Sk with
      | (l₁, o, l₂) => (a' :: l₁, o, l₂)) =
    (a :: L₁, o, L₂)
e₁ : S k₁ = a' :: Sk
e₂ : p a' = true
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k₁ (List.tail (a' :: Sk)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (a' :: Sk),
        stk :=
          update (update S k₁ (List.tail (a' :: Sk))) k₂
            (Option.iget (List.head? (a' :: Sk)) :: update S k₁ (List.tail (a' :: Sk)) k₂) })
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (a :: S k₂)) }
[PROOFSTEP]
simp only [e₂, cond] at e
[GOAL]
case cons.cons.false
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e₁ : S k₁ = a' :: Sk
e₂ : p a' = false
e : (a' :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd) = (a :: L₁, o, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k₁ (List.tail (a' :: Sk)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (a' :: Sk),
        stk :=
          update (update S k₁ (List.tail (a' :: Sk))) k₂
            (Option.iget (List.head? (a' :: Sk)) :: update S k₁ (List.tail (a' :: Sk)) k₂) })
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (a :: S k₂)) }
case cons.cons.true
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e₁ : S k₁ = a' :: Sk
e₂ : p a' = true
e : ([], some a', Sk) = (a :: L₁, o, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k₁ (List.tail (a' :: Sk)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (a' :: Sk),
        stk :=
          update (update S k₁ (List.tail (a' :: Sk))) k₂
            (Option.iget (List.head? (a' :: Sk)) :: update S k₁ (List.tail (a' :: Sk)) k₂) })
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (a :: S k₂)) }
[PROOFSTEP]
swap
[GOAL]
case cons.cons.true
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e₁ : S k₁ = a' :: Sk
e₂ : p a' = true
e : ([], some a', Sk) = (a :: L₁, o, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k₁ (List.tail (a' :: Sk)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (a' :: Sk),
        stk :=
          update (update S k₁ (List.tail (a' :: Sk))) k₂
            (Option.iget (List.head? (a' :: Sk)) :: update S k₁ (List.tail (a' :: Sk)) k₂) })
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (a :: S k₂)) }
[PROOFSTEP]
cases e
[GOAL]
case cons.cons.false
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e₁ : S k₁ = a' :: Sk
e₂ : p a' = false
e : (a' :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd) = (a :: L₁, o, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k₁ (List.tail (a' :: Sk)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (a' :: Sk),
        stk :=
          update (update S k₁ (List.tail (a' :: Sk))) k₂
            (Option.iget (List.head? (a' :: Sk)) :: update S k₁ (List.tail (a' :: Sk)) k₂) })
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (a :: S k₂)) }
[PROOFSTEP]
rcases e₃ : splitAtPred p Sk with ⟨_, _, _⟩
[GOAL]
case cons.cons.false.mk.mk
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e₁ : S k₁ = a' :: Sk
e₂ : p a' = false
e : (a' :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd) = (a :: L₁, o, L₂)
fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k₁ (List.tail (a' :: Sk)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (a' :: Sk),
        stk :=
          update (update S k₁ (List.tail (a' :: Sk))) k₂
            (Option.iget (List.head? (a' :: Sk)) :: update S k₁ (List.tail (a' :: Sk)) k₂) })
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (a :: S k₂)) }
[PROOFSTEP]
rw [e₃] at e
[GOAL]
case cons.cons.false.mk.mk
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
e✝ : splitAtPred p (S✝ k₁) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (S k₂)) }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e₁ : S k₁ = a' :: Sk
e₂ : p a' = false
fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e : (a' :: (fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd) = (a :: L₁, o, L₂)
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k₁ (List.tail (a' :: Sk)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (a' :: Sk),
        stk :=
          update (update S k₁ (List.tail (a' :: Sk))) k₂
            (Option.iget (List.head? (a' :: Sk)) :: update S k₁ (List.tail (a' :: Sk)) k₂) })
    { l := some q, var := o, stk := update (update S k₁ L₂) k₂ (List.reverseAux L₁ (a :: S k₂)) }
[PROOFSTEP]
cases e
[GOAL]
case cons.cons.false.mk.mk.refl
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
a : Γ'
s : Option Γ'
S : K' → List Γ'
Sk fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
e₁ : S k₁ = a :: Sk
e₂ : p a = false
e : splitAtPred p (S✝ k₁) = (L₁, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd)
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = ((fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := (fst✝¹, fst✝, snd✝).2.fst,
          stk := update (update S k₁ (fst✝¹, fst✝, snd✝).2.snd) k₂ (List.reverseAux (fst✝¹, fst✝, snd✝).fst (S k₂)) }
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a :: Sk), stk := update S k₁ (List.tail (a :: Sk)) }
    else
      { l := some (Λ'.move p k₁ k₂ q), var := List.head? (a :: Sk),
        stk :=
          update (update S k₁ (List.tail (a :: Sk))) k₂
            (Option.iget (List.head? (a :: Sk)) :: update S k₁ (List.tail (a :: Sk)) k₂) })
    { l := some q, var := (fst✝¹, fst✝, snd✝).2.fst,
      stk := update (update S k₁ (fst✝¹, fst✝, snd✝).2.snd) k₂ (List.reverseAux (fst✝¹, fst✝, snd✝).fst (a :: S k₂)) }
[PROOFSTEP]
simp [e₂]
[GOAL]
case cons.cons.false.mk.mk.refl
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
a : Γ'
s : Option Γ'
S : K' → List Γ'
Sk fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
e₁ : S k₁ = a :: Sk
e₂ : p a = false
e : splitAtPred p (S✝ k₁) = (L₁, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd)
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = ((fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := (fst✝¹, fst✝, snd✝).2.fst,
          stk := update (update S k₁ (fst✝¹, fst✝, snd✝).2.snd) k₂ (List.reverseAux (fst✝¹, fst✝, snd✝).fst (S k₂)) }
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (Λ'.move p k₁ k₂ q), var := some a,
      stk := update (update S k₁ Sk) k₂ (Option.iget (some a) :: update S k₁ Sk k₂) }
    { l := some q, var := fst✝, stk := update (update S k₁ snd✝) k₂ (List.reverseAux fst✝¹ (a :: S k₂)) }
[PROOFSTEP]
convert @IH _ (update (update S k₁ Sk) k₂ (a :: S k₂)) _ using 2
[GOAL]
case h.e'_1.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
a : Γ'
s : Option Γ'
S : K' → List Γ'
Sk fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
e₁ : S k₁ = a :: Sk
e₂ : p a = false
e : splitAtPred p (S✝ k₁) = (L₁, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd)
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = ((fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := (fst✝¹, fst✝, snd✝).2.fst,
          stk := update (update S k₁ (fst✝¹, fst✝, snd✝).2.snd) k₂ (List.reverseAux (fst✝¹, fst✝, snd✝).fst (S k₂)) }
⊢ update (update S k₁ Sk) k₂ (Option.iget (some a) :: update S k₁ Sk k₂) = update (update S k₁ Sk) k₂ (a :: S k₂)
[PROOFSTEP]
simp [Function.update_noteq, h₁, h₁.symm, e₃, List.reverseAux]
[GOAL]
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
a : Γ'
s : Option Γ'
S : K' → List Γ'
Sk fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
e₁ : S k₁ = a :: Sk
e₂ : p a = false
e : splitAtPred p (S✝ k₁) = (L₁, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd)
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = ((fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := (fst✝¹, fst✝, snd✝).2.fst,
          stk := update (update S k₁ (fst✝¹, fst✝, snd✝).2.snd) k₂ (List.reverseAux (fst✝¹, fst✝, snd✝).fst (S k₂)) }
⊢ update (update S k₁ snd✝) k₂ (List.reverseAux fst✝¹ (a :: S k₂)) =
    update (update (update (update S k₁ Sk) k₂ (a :: S k₂)) k₁ (fst✝¹, fst✝, snd✝).2.snd) k₂
      (List.reverseAux (fst✝¹, fst✝, snd✝).fst (update (update S k₁ Sk) k₂ (a :: S k₂) k₂))
[PROOFSTEP]
simp [Function.update_noteq, h₁, h₁.symm, e₃, List.reverseAux]
[GOAL]
case cons.cons.false.mk.mk.refl.convert_2
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
a : Γ'
s : Option Γ'
S : K' → List Γ'
Sk fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
e₁ : S k₁ = a :: Sk
e₂ : p a = false
e : splitAtPred p (S✝ k₁) = (L₁, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd)
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = ((fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := (fst✝¹, fst✝, snd✝).2.fst,
          stk := update (update S k₁ (fst✝¹, fst✝, snd✝).2.snd) k₂ (List.reverseAux (fst✝¹, fst✝, snd✝).fst (S k₂)) }
⊢ splitAtPred p (update (update S k₁ Sk) k₂ (a :: S k₂) k₁) =
    ((fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd)
[PROOFSTEP]
simp [Function.update_noteq, h₁, h₁.symm, e₃, List.reverseAux]
[GOAL]
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
S✝ : K' → List Γ'
h₁ : k₁ ≠ k₂
a : Γ'
s : Option Γ'
S : K' → List Γ'
Sk fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
e₁ : S k₁ = a :: Sk
e₂ : p a = false
e : splitAtPred p (S✝ k₁) = (L₁, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd)
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k₁) = ((fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.move p k₁ k₂ q), var := s, stk := S }
        { l := some q, var := (fst✝¹, fst✝, snd✝).2.fst,
          stk := update (update S k₁ (fst✝¹, fst✝, snd✝).2.snd) k₂ (List.reverseAux (fst✝¹, fst✝, snd✝).fst (S k₂)) }
⊢ update (update S k₁ snd✝) k₂ (List.reverseAux fst✝¹ (a :: S k₂)) =
    update (update (update (update S k₁ Sk) k₂ (a :: S k₂)) k₁ snd✝) k₂ (List.reverseAux fst✝¹ (a :: S k₂))
[PROOFSTEP]
simp [Function.update_comm h₁.symm]
[GOAL]
q : Λ'
s : Option Γ'
S : K' → List Γ'
⊢ rev ≠ main
[PROOFSTEP]
decide
[GOAL]
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, o, L₂)
⊢ Reaches₁ (TM2.step tr) { l := some (move₂ p k₁ k₂ q), var := s, stk := S }
    { l := some q, var := none, stk := update (update S k₁ (Option.elim o id List.cons L₂)) k₂ (L₁ ++ S k₂) }
[PROOFSTEP]
refine' (move_ok h₁.1 e).trans (TransGen.head rfl _)
[GOAL]
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, o, L₂)
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    (TM2.stepAux (tr (Λ'.push k₁ id (Λ'.move (fun x => false) rev k₂ q))) o
      (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))))
    { l := some q, var := none, stk := update (update S k₁ (Option.elim o id List.cons L₂)) k₂ (L₁ ++ S k₂) }
[PROOFSTEP]
simp
[GOAL]
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, o, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif Option.isSome o then
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := o,
        stk :=
          update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
            (Option.iget o :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    else
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := o,
        stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) })
    { l := some q, var := none,
      stk :=
        update
          (update S k₁
            ((match (motive := Option Γ' → (List Γ' → List Γ') → (Γ' → List Γ' → List Γ') → List Γ' → List Γ') o, id,
                List.cons with
              | some x, x_1, f => f x
              | none, y, x => y)
              L₂))
          k₂ (L₁ ++ S k₂) }
[PROOFSTEP]
cases o
[GOAL]
case none
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif Option.isSome none then
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := none,
        stk :=
          update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
            (Option.iget none :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    else
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := none,
        stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) })
    { l := some q, var := none,
      stk :=
        update
          (update S k₁
            ((match (motive := Option Γ' → (List Γ' → List Γ') → (Γ' → List Γ' → List Γ') → List Γ' → List Γ') none, id,
                List.cons with
              | some x, x_1, f => f x
              | none, y, x => y)
              L₂))
          k₂ (L₁ ++ S k₂) }
[PROOFSTEP]
simp only [Option.elim, id.def]
[GOAL]
case some
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif Option.isSome (some val✝) then
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := some val✝,
        stk :=
          update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
            (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    else
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := some val✝,
        stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) })
    { l := some q, var := none,
      stk :=
        update
          (update S k₁
            ((match (motive := Option Γ' → (List Γ' → List Γ') → (Γ' → List Γ' → List Γ') → List Γ' → List Γ')
                some val✝, id, List.cons with
              | some x, x_1, f => f x
              | none, y, x => y)
              L₂))
          k₂ (L₁ ++ S k₂) }
[PROOFSTEP]
simp only [Option.elim, id.def]
[GOAL]
case none
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif Option.isSome none then
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := none,
        stk :=
          update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
            (Option.iget none :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    else
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := none,
        stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) })
    { l := some q, var := none, stk := update (update S k₁ L₂) k₂ (L₁ ++ S k₂) }
[PROOFSTEP]
simp only [TM2.stepAux, Option.isSome, cond_false]
[GOAL]
case none
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (Λ'.move (fun x => false) rev k₂ q), var := none,
      stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) }
    { l := some q, var := none, stk := update (update S k₁ L₂) k₂ (L₁ ++ S k₂) }
[PROOFSTEP]
convert move_ok h₁.2.1.symm (splitAtPred_false _) using 2
[GOAL]
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ update (update S k₁ L₂) k₂ (L₁ ++ S k₂) =
    update (update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) rev []) k₂
      (List.reverseAux (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) rev)
        (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₂))
[PROOFSTEP]
simp only [Function.update_comm h₁.1, Function.update_idem]
[GOAL]
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ update (update S k₁ L₂) k₂ (L₁ ++ S k₂) =
    update (update (update S rev []) k₁ L₂) k₂
      (List.reverseAux (update (update S rev (List.reverseAux L₁ (S rev))) k₁ L₂ rev)
        (update (update S rev (List.reverseAux L₁ (S rev))) k₁ L₂ k₂))
[PROOFSTEP]
rw [show update S rev [] = S by rw [← h₂, Function.update_eq_self]]
[GOAL]
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ update S rev [] = S
[PROOFSTEP]
rw [← h₂, Function.update_eq_self]
[GOAL]
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
e : splitAtPred p (S k₁) = (L₁, none, L₂)
⊢ update (update S k₁ L₂) k₂ (L₁ ++ S k₂) =
    update (update S k₁ L₂) k₂
      (List.reverseAux (update (update S rev (List.reverseAux L₁ (S rev))) k₁ L₂ rev)
        (update (update S rev (List.reverseAux L₁ (S rev))) k₁ L₂ k₂))
[PROOFSTEP]
simp only [Function.update_noteq h₁.2.2.symm, Function.update_noteq h₁.2.1, Function.update_noteq h₁.1.symm,
  List.reverseAux_eq, h₂, Function.update_same, List.append_nil, List.reverse_reverse]
[GOAL]
case some
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif Option.isSome (some val✝) then
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := some val✝,
        stk :=
          update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
            (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    else
      { l := some (Λ'.move (fun x => false) rev k₂ q), var := some val✝,
        stk := update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) })
    { l := some q, var := none, stk := update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) }
[PROOFSTEP]
simp only [TM2.stepAux, Option.isSome, cond_true]
[GOAL]
case some
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (Λ'.move (fun x => false) rev k₂ q), var := some val✝,
      stk :=
        update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
          (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) }
    { l := some q, var := none, stk := update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) }
[PROOFSTEP]
convert move_ok h₁.2.1.symm (splitAtPred_false _) using 2
[GOAL]
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) =
    update
      (update
        (update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
          (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁))
        rev [])
      k₂
      (List.reverseAux
        (update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
          (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) rev)
        (update (update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev))) k₁
          (Option.iget (some val✝) :: update (update S k₁ L₂) rev (List.reverseAux L₁ (S rev)) k₁) k₂))
[PROOFSTEP]
simp only [h₂, Function.update_comm h₁.1, List.reverseAux_eq, Function.update_same, List.append_nil,
  Function.update_idem]
[GOAL]
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) =
    update (update (update S rev []) k₁ (Option.iget (some val✝) :: L₂)) k₂
      (List.reverse (update (update S rev (List.reverse L₁)) k₁ (Option.iget (some val✝) :: L₂) rev) ++
        update (update S rev (List.reverse L₁)) k₁ (Option.iget (some val✝) :: L₂) k₂)
[PROOFSTEP]
rw [show update S rev [] = S by rw [← h₂, Function.update_eq_self]]
[GOAL]
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ update S rev [] = S
[PROOFSTEP]
rw [← h₂, Function.update_eq_self]
[GOAL]
case h.e'_2.h.e'_7
p : Γ' → Bool
k₁ k₂ : K'
q : Λ'
s : Option Γ'
L₁ L₂ : List Γ'
S : K' → List Γ'
h₁ : k₁ ≠ rev ∧ k₂ ≠ rev ∧ k₁ ≠ k₂
h₂ : S rev = []
val✝ : Γ'
e : splitAtPred p (S k₁) = (L₁, some val✝, L₂)
⊢ update (update S k₁ (val✝ :: L₂)) k₂ (L₁ ++ S k₂) =
    update (update S k₁ (Option.iget (some val✝) :: L₂)) k₂
      (List.reverse (update (update S rev (List.reverse L₁)) k₁ (Option.iget (some val✝) :: L₂) rev) ++
        update (update S rev (List.reverse L₁)) k₁ (Option.iget (some val✝) :: L₂) k₂)
[PROOFSTEP]
simp only [Function.update_noteq h₁.1.symm, Function.update_noteq h₁.2.2.symm, Function.update_noteq h₁.2.1,
  Function.update_same, List.reverse_reverse]
[GOAL]
p : Γ' → Bool
k : K'
q : Λ'
s : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S : K' → List Γ'
e : splitAtPred p (S k) = (L₁, o, L₂)
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
induction' L₁ with a L₁ IH generalizing S s
[GOAL]
case nil
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k) = ([], o, L₂)
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
refine' TransGen.head' rfl _
[GOAL]
case nil
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k) = ([], o, L₂)
⊢ ReflTransGen (fun a b => b ∈ TM2.step tr a) (TM2.stepAux (tr (Λ'.clear p k q)) s S)
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
simp
[GOAL]
case nil
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k) = ([], o, L₂)
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (S k), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (S k), stk := update S k (List.tail (S k)) }
    else { l := some (Λ'.clear p k q), var := List.head? (S k), stk := update S k (List.tail (S k)) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
revert e
[GOAL]
case nil
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
⊢ splitAtPred p (S k) = ([], o, L₂) →
    ReflTransGen
      (fun a b =>
        (match a with
          | { l := none, var := var, stk := stk } => none
          | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
          some b)
      (bif
          match List.head? (S k), true, p with
          | some x, x_1, f => f x
          | none, y, x => y then
        { l := some q, var := List.head? (S k), stk := update S k (List.tail (S k)) }
      else { l := some (Λ'.clear p k q), var := List.head? (S k), stk := update S k (List.tail (S k)) })
      { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
cases' S k with a Sk
[GOAL]
case nil.nil
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
⊢ splitAtPred p [] = ([], o, L₂) →
    ReflTransGen
      (fun a b =>
        (match a with
          | { l := none, var := var, stk := stk } => none
          | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
          some b)
      (bif
          match List.head? [], true, p with
          | some x, x_1, f => f x
          | none, y, x => y then
        { l := some q, var := List.head? [], stk := update S k (List.tail []) }
      else { l := some (Λ'.clear p k q), var := List.head? [], stk := update S k (List.tail []) })
      { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
intro e
[GOAL]
case nil.cons
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
⊢ splitAtPred p (a :: Sk) = ([], o, L₂) →
    ReflTransGen
      (fun a b =>
        (match a with
          | { l := none, var := var, stk := stk } => none
          | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
          some b)
      (bif
          match List.head? (a :: Sk), true, p with
          | some x, x_1, f => f x
          | none, y, x => y then
        { l := some q, var := List.head? (a :: Sk), stk := update S k (List.tail (a :: Sk)) }
      else { l := some (Λ'.clear p k q), var := List.head? (a :: Sk), stk := update S k (List.tail (a :: Sk)) })
      { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
intro e
[GOAL]
case nil.nil
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p [] = ([], o, L₂)
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? [], true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? [], stk := update S k (List.tail []) }
    else { l := some (Λ'.clear p k q), var := List.head? [], stk := update S k (List.tail []) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
cases e
[GOAL]
case nil.nil.refl
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
S✝ : K' → List Γ'
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S✝ k) = (L₁, none, [])
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? [], true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? [], stk := update S k (List.tail []) }
    else { l := some (Λ'.clear p k q), var := List.head? [], stk := update S k (List.tail []) })
    { l := some q, var := none, stk := update S k [] }
[PROOFSTEP]
rfl
[GOAL]
case nil.cons
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
e : splitAtPred p (a :: Sk) = ([], o, L₂)
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a :: Sk), stk := update S k (List.tail (a :: Sk)) }
    else { l := some (Λ'.clear p k q), var := List.head? (a :: Sk), stk := update S k (List.tail (a :: Sk)) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
simp only [splitAtPred, Option.elim, List.head?, List.tail_cons] at e ⊢
[GOAL]
case nil.cons
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
e :
  (bif p a then ([], some a, Sk)
    else (a :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd)) =
    ([], o, L₂)
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif p a then { l := some q, var := some a, stk := update S k Sk }
    else { l := some (Λ'.clear p k q), var := some a, stk := update S k Sk })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
revert e
[GOAL]
case nil.cons
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
⊢ (bif p a then ([], some a, Sk)
      else (a :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd)) =
      ([], o, L₂) →
    ReflTransGen
      (fun a b =>
        (match a with
          | { l := none, var := var, stk := stk } => none
          | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
          some b)
      (bif p a then { l := some q, var := some a, stk := update S k Sk }
      else { l := some (Λ'.clear p k q), var := some a, stk := update S k Sk })
      { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
cases p a
[GOAL]
case nil.cons.false
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
⊢ (bif false then ([], some a, Sk)
      else (a :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd)) =
      ([], o, L₂) →
    ReflTransGen
      (fun a b =>
        (match a with
          | { l := none, var := var, stk := stk } => none
          | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
          some b)
      (bif false then { l := some q, var := some a, stk := update S k Sk }
      else { l := some (Λ'.clear p k q), var := some a, stk := update S k Sk })
      { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
intro e
[GOAL]
case nil.cons.true
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
⊢ (bif true then ([], some a, Sk)
      else (a :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd)) =
      ([], o, L₂) →
    ReflTransGen
      (fun a b =>
        (match a with
          | { l := none, var := var, stk := stk } => none
          | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
          some b)
      (bif true then { l := some q, var := some a, stk := update S k Sk }
      else { l := some (Λ'.clear p k q), var := some a, stk := update S k Sk })
      { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
intro e
[GOAL]
case nil.cons.false
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
e :
  (bif false then ([], some a, Sk)
    else (a :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd)) =
    ([], o, L₂)
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif false then { l := some q, var := some a, stk := update S k Sk }
    else { l := some (Λ'.clear p k q), var := some a, stk := update S k Sk })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
simp only [cond_false, cond_true, Prod.mk.injEq, true_and, false_and] at e ⊢
[GOAL]
case nil.cons.true
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
e :
  (bif true then ([], some a, Sk)
    else (a :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd)) =
    ([], o, L₂)
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif true then { l := some q, var := some a, stk := update S k Sk }
    else { l := some (Λ'.clear p k q), var := some a, stk := update S k Sk })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
simp only [cond_false, cond_true, Prod.mk.injEq, true_and, false_and] at e ⊢
[GOAL]
case nil.cons.true
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
e : some a = o ∧ Sk = L₂
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some q, var := some a, stk := update S k Sk } { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
rcases e with ⟨e₁, e₂⟩
[GOAL]
case nil.cons.true.intro
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e : splitAtPred p (S✝ k) = (L₁, o, L₂)
s : Option Γ'
S : K' → List Γ'
a : Γ'
Sk : List Γ'
e₁ : some a = o
e₂ : Sk = L₂
⊢ ReflTransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some q, var := some a, stk := update S k Sk } { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
rw [e₁, e₂]
[GOAL]
case cons
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k) = (a :: L₁, o, L₂)
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
refine' TransGen.head rfl _
[GOAL]
case cons
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k) = (a :: L₁, o, L₂)
⊢ TransGen (fun a b => b ∈ TM2.step tr a) (TM2.stepAux (tr (Λ'.clear p k q)) s S)
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
simp
[GOAL]
case cons
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k) = (a :: L₁, o, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (S k), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (S k), stk := update S k (List.tail (S k)) }
    else { l := some (Λ'.clear p k q), var := List.head? (S k), stk := update S k (List.tail (S k)) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
cases' e₁ : S k with a' Sk
[GOAL]
case cons.nil
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k) = (a :: L₁, o, L₂)
e₁ : S k = []
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? [], true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? [], stk := update S k (List.tail []) }
    else { l := some (Λ'.clear p k q), var := List.head? [], stk := update S k (List.tail []) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
rw [e₁, splitAtPred] at e
[GOAL]
case cons.cons
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
e : splitAtPred p (S k) = (a :: L₁, o, L₂)
a' : Γ'
Sk : List Γ'
e₁ : S k = a' :: Sk
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) }
    else { l := some (Λ'.clear p k q), var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
rw [e₁, splitAtPred] at e
[GOAL]
case cons.nil
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
e : ([], none, []) = (a :: L₁, o, L₂)
e₁ : S k = []
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? [], true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? [], stk := update S k (List.tail []) }
    else { l := some (Λ'.clear p k q), var := List.head? [], stk := update S k (List.tail []) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
cases e
[GOAL]
case cons.cons
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e :
  (bif p a' then ([], some a', Sk)
    else
      match splitAtPred p Sk with
      | (l₁, o, l₂) => (a' :: l₁, o, l₂)) =
    (a :: L₁, o, L₂)
e₁ : S k = a' :: Sk
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) }
    else { l := some (Λ'.clear p k q), var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
cases e₂ : p a'
[GOAL]
case cons.cons.false
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e :
  (bif p a' then ([], some a', Sk)
    else
      match splitAtPred p Sk with
      | (l₁, o, l₂) => (a' :: l₁, o, l₂)) =
    (a :: L₁, o, L₂)
e₁ : S k = a' :: Sk
e₂ : p a' = false
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) }
    else { l := some (Λ'.clear p k q), var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
simp only [e₂, cond] at e
[GOAL]
case cons.cons.true
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e :
  (bif p a' then ([], some a', Sk)
    else
      match splitAtPred p Sk with
      | (l₁, o, l₂) => (a' :: l₁, o, l₂)) =
    (a :: L₁, o, L₂)
e₁ : S k = a' :: Sk
e₂ : p a' = true
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) }
    else { l := some (Λ'.clear p k q), var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
simp only [e₂, cond] at e
[GOAL]
case cons.cons.false
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e₁ : S k = a' :: Sk
e₂ : p a' = false
e : (a' :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd) = (a :: L₁, o, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) }
    else { l := some (Λ'.clear p k q), var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) })
    { l := some q, var := o, stk := update S k L₂ }
case cons.cons.true
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e₁ : S k = a' :: Sk
e₂ : p a' = true
e : ([], some a', Sk) = (a :: L₁, o, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) }
    else { l := some (Λ'.clear p k q), var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
swap
[GOAL]
case cons.cons.true
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e₁ : S k = a' :: Sk
e₂ : p a' = true
e : ([], some a', Sk) = (a :: L₁, o, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) }
    else { l := some (Λ'.clear p k q), var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
cases e
[GOAL]
case cons.cons.false
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e₁ : S k = a' :: Sk
e₂ : p a' = false
e : (a' :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd) = (a :: L₁, o, L₂)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) }
    else { l := some (Λ'.clear p k q), var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
rcases e₃ : splitAtPred p Sk with ⟨_, _, _⟩
[GOAL]
case cons.cons.false.mk.mk
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e₁ : S k = a' :: Sk
e₂ : p a' = false
e : (a' :: (splitAtPred p Sk).fst, (splitAtPred p Sk).2.fst, (splitAtPred p Sk).2.snd) = (a :: L₁, o, L₂)
fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) }
    else { l := some (Λ'.clear p k q), var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
rw [e₃] at e
[GOAL]
case cons.cons.false.mk.mk
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁✝ : List Γ'
o : Option Γ'
L₂ : List Γ'
S✝ : K' → List Γ'
e✝ : splitAtPred p (S✝ k) = (L₁✝, o, L₂)
a : Γ'
L₁ : List Γ'
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = (L₁, o, L₂) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := o, stk := update S k L₂ }
s : Option Γ'
S : K' → List Γ'
a' : Γ'
Sk : List Γ'
e₁ : S k = a' :: Sk
e₂ : p a' = false
fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e : (a' :: (fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd) = (a :: L₁, o, L₂)
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a' :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) }
    else { l := some (Λ'.clear p k q), var := List.head? (a' :: Sk), stk := update S k (List.tail (a' :: Sk)) })
    { l := some q, var := o, stk := update S k L₂ }
[PROOFSTEP]
cases e
[GOAL]
case cons.cons.false.mk.mk.refl
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
S✝ : K' → List Γ'
a : Γ'
s : Option Γ'
S : K' → List Γ'
Sk fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
e₁ : S k = a :: Sk
e₂ : p a = false
e : splitAtPred p (S✝ k) = (L₁, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd)
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = ((fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := (fst✝¹, fst✝, snd✝).2.fst, stk := update S k (fst✝¹, fst✝, snd✝).2.snd }
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    (bif
        match List.head? (a :: Sk), true, p with
        | some x, x_1, f => f x
        | none, y, x => y then
      { l := some q, var := List.head? (a :: Sk), stk := update S k (List.tail (a :: Sk)) }
    else { l := some (Λ'.clear p k q), var := List.head? (a :: Sk), stk := update S k (List.tail (a :: Sk)) })
    { l := some q, var := (fst✝¹, fst✝, snd✝).2.fst, stk := update S k (fst✝¹, fst✝, snd✝).2.snd }
[PROOFSTEP]
simp [e₂]
[GOAL]
case cons.cons.false.mk.mk.refl
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
S✝ : K' → List Γ'
a : Γ'
s : Option Γ'
S : K' → List Γ'
Sk fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
e₁ : S k = a :: Sk
e₂ : p a = false
e : splitAtPred p (S✝ k) = (L₁, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd)
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = ((fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := (fst✝¹, fst✝, snd✝).2.fst, stk := update S k (fst✝¹, fst✝, snd✝).2.snd }
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (Λ'.clear p k q), var := some a, stk := update S k Sk }
    { l := some q, var := fst✝, stk := update S k snd✝ }
[PROOFSTEP]
convert @IH _ (update S k Sk) _ using 2
[GOAL]
case h.e'_2.h.e'_7
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
S✝ : K' → List Γ'
a : Γ'
s : Option Γ'
S : K' → List Γ'
Sk fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
e₁ : S k = a :: Sk
e₂ : p a = false
e : splitAtPred p (S✝ k) = (L₁, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd)
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = ((fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := (fst✝¹, fst✝, snd✝).2.fst, stk := update S k (fst✝¹, fst✝, snd✝).2.snd }
⊢ update S k snd✝ = update (update S k Sk) k (fst✝¹, fst✝, snd✝).2.snd
[PROOFSTEP]
simp [e₃]
[GOAL]
case cons.cons.false.mk.mk.refl.convert_2
p : Γ' → Bool
k : K'
q : Λ'
s✝ : Option Γ'
L₁ : List Γ'
S✝ : K' → List Γ'
a : Γ'
s : Option Γ'
S : K' → List Γ'
Sk fst✝¹ : List Γ'
fst✝ : Option Γ'
snd✝ : List Γ'
e₃ : splitAtPred p Sk = (fst✝¹, fst✝, snd✝)
e₁ : S k = a :: Sk
e₂ : p a = false
e : splitAtPred p (S✝ k) = (L₁, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd)
IH :
  ∀ {s : Option Γ'} {S : K' → List Γ'},
    splitAtPred p (S k) = ((fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd) →
      Reaches₁ (TM2.step tr) { l := some (Λ'.clear p k q), var := s, stk := S }
        { l := some q, var := (fst✝¹, fst✝, snd✝).2.fst, stk := update S k (fst✝¹, fst✝, snd✝).2.snd }
⊢ splitAtPred p (update S k Sk k) = ((fst✝¹, fst✝, snd✝).fst, (fst✝¹, fst✝, snd✝).2.fst, (fst✝¹, fst✝, snd✝).2.snd)
[PROOFSTEP]
simp [e₃]
[GOAL]
q : Λ'
s : Option Γ'
a b c d : List Γ'
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.copy q), var := s, stk := elim a b c d }
    { l := some q, var := none, stk := elim (List.reverseAux b a) [] c (List.reverseAux b d) }
[PROOFSTEP]
induction' b with x b IH generalizing a d s
[GOAL]
case nil
q : Λ'
s✝ : Option Γ'
a✝ c d✝ : List Γ'
s : Option Γ'
a d : List Γ'
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.copy q), var := s, stk := elim a [] c d }
    { l := some q, var := none, stk := elim (List.reverseAux [] a) [] c (List.reverseAux [] d) }
[PROOFSTEP]
refine' TransGen.single _
[GOAL]
case nil
q : Λ'
s✝ : Option Γ'
a✝ c d✝ : List Γ'
s : Option Γ'
a d : List Γ'
⊢ { l := some q, var := none, stk := elim (List.reverseAux [] a) [] c (List.reverseAux [] d) } ∈
    TM2.step tr { l := some (Λ'.copy q), var := s, stk := elim a [] c d }
[PROOFSTEP]
simp
[GOAL]
case cons
q : Λ'
s✝ : Option Γ'
a✝ c d✝ : List Γ'
x : Γ'
b : List Γ'
IH :
  ∀ (s : Option Γ') (a d : List Γ'),
    Reaches₁ (TM2.step tr) { l := some (Λ'.copy q), var := s, stk := elim a b c d }
      { l := some q, var := none, stk := elim (List.reverseAux b a) [] c (List.reverseAux b d) }
s : Option Γ'
a d : List Γ'
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.copy q), var := s, stk := elim a (x :: b) c d }
    { l := some q, var := none, stk := elim (List.reverseAux (x :: b) a) [] c (List.reverseAux (x :: b) d) }
[PROOFSTEP]
refine' TransGen.head rfl _
[GOAL]
case cons
q : Λ'
s✝ : Option Γ'
a✝ c d✝ : List Γ'
x : Γ'
b : List Γ'
IH :
  ∀ (s : Option Γ') (a d : List Γ'),
    Reaches₁ (TM2.step tr) { l := some (Λ'.copy q), var := s, stk := elim a b c d }
      { l := some q, var := none, stk := elim (List.reverseAux b a) [] c (List.reverseAux b d) }
s : Option Γ'
a d : List Γ'
⊢ TransGen (fun a b => b ∈ TM2.step tr a) (TM2.stepAux (tr (Λ'.copy q)) s (elim a (x :: b) c d))
    { l := some q, var := none, stk := elim (List.reverseAux (x :: b) a) [] c (List.reverseAux (x :: b) d) }
[PROOFSTEP]
simp
[GOAL]
case cons
q : Λ'
s✝ : Option Γ'
a✝ c d✝ : List Γ'
x : Γ'
b : List Γ'
IH :
  ∀ (s : Option Γ') (a d : List Γ'),
    Reaches₁ (TM2.step tr) { l := some (Λ'.copy q), var := s, stk := elim a b c d }
      { l := some q, var := none, stk := elim (List.reverseAux b a) [] c (List.reverseAux b d) }
s : Option Γ'
a d : List Γ'
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (Λ'.copy q), var := some x, stk := elim (Option.iget (some x) :: a) b c (Option.iget (some x) :: d) }
    { l := some q, var := none, stk := elim (List.reverseAux b (x :: a)) [] c (List.reverseAux b (x :: d)) }
[PROOFSTEP]
exact IH _ _ _
[GOAL]
a : ℕ
l : List ℕ
x : Γ'
h : x ∈ trList (a :: l)
⊢ x ≠ Γ'.consₗ
[PROOFSTEP]
simp [trList] at h
[GOAL]
a : ℕ
l : List ℕ
x : Γ'
h : x ∈ trNat a ∨ x = Γ'.cons ∨ x ∈ trList l
⊢ x ≠ Γ'.consₗ
[PROOFSTEP]
obtain h | rfl | h := h
[GOAL]
case inl
a : ℕ
l : List ℕ
x : Γ'
h : x ∈ trNat a
⊢ x ≠ Γ'.consₗ
[PROOFSTEP]
rintro rfl
[GOAL]
case inl
a : ℕ
l : List ℕ
h : Γ'.consₗ ∈ trNat a
⊢ False
[PROOFSTEP]
cases trNat_natEnd _ _ h
[GOAL]
case inr.inl
a : ℕ
l : List ℕ
⊢ Γ'.cons ≠ Γ'.consₗ
[PROOFSTEP]
rintro ⟨⟩
[GOAL]
case inr.inr
a : ℕ
l : List ℕ
x : Γ'
h : x ∈ trList l
⊢ x ≠ Γ'.consₗ
[PROOFSTEP]
exact trList_ne_consₗ l _ h
[GOAL]
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
⊢ Reaches₁ (TM2.step tr) { l := some (head main q), var := s, stk := elim (trList L) [] c d }
    { l := some q, var := none, stk := elim (trList [List.headI L]) [] c d }
[PROOFSTEP]
let o : Option Γ' := List.casesOn L none fun _ _ => some Γ'.cons
[GOAL]
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ Reaches₁ (TM2.step tr) { l := some (head main q), var := s, stk := elim (trList L) [] c d }
    { l := some q, var := none, stk := elim (trList [List.headI L]) [] c d }
[PROOFSTEP]
refine'
  (move_ok (by decide) (splitAtPred_eq _ _ (trNat L.headI) o (trList L.tail) (trNat_natEnd _) _)).trans
    (TransGen.head rfl (TransGen.head rfl _))
[GOAL]
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ main ≠ rev
[PROOFSTEP]
decide
[GOAL]
case refine'_1
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ Option.elim' (elim (trList L) [] c d main = trNat (List.headI L) ∧ trList (List.tail L) = [])
    (fun a => natEnd a = true ∧ elim (trList L) [] c d main = trNat (List.headI L) ++ a :: trList (List.tail L)) o
[PROOFSTEP]
cases L
[GOAL]
case refine'_1.nil
q : Λ'
s : Option Γ'
c d : List Γ'
o : Option Γ' := List.casesOn [] none fun x x => some Γ'.cons
⊢ Option.elim' (elim (trList []) [] c d main = trNat (List.headI []) ∧ trList (List.tail []) = [])
    (fun a => natEnd a = true ∧ elim (trList []) [] c d main = trNat (List.headI []) ++ a :: trList (List.tail [])) o
[PROOFSTEP]
simp
[GOAL]
case refine'_1.cons
q : Λ'
s : Option Γ'
c d : List Γ'
head✝ : ℕ
tail✝ : List ℕ
o : Option Γ' := List.casesOn (head✝ :: tail✝) none fun x x => some Γ'.cons
⊢ Option.elim'
    (elim (trList (head✝ :: tail✝)) [] c d main = trNat (List.headI (head✝ :: tail✝)) ∧
      trList (List.tail (head✝ :: tail✝)) = [])
    (fun a =>
      natEnd a = true ∧
        elim (trList (head✝ :: tail✝)) [] c d main =
          trNat (List.headI (head✝ :: tail✝)) ++ a :: trList (List.tail (head✝ :: tail✝)))
    o
[PROOFSTEP]
simp
[GOAL]
case refine'_2
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    (TM2.stepAux
      (tr
        ((fun x =>
            Λ'.read fun s => ite (s = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev q))
          o))
      o
      (update
        (update (update (elim (trList L) [] c d) main (trList (List.tail L))) rev
          (List.reverseAux (trNat (List.headI L)) (elim (trList L) [] c d rev)))
        rev
        ((fun s => Option.iget ((fun x => some Γ'.cons) s)) o ::
          update (update (elim (trList L) [] c d) main (trList (List.tail L))) rev
            (List.reverseAux (trNat (List.headI L)) (elim (trList L) [] c d rev)) rev)))
    { l := some q, var := none, stk := elim (trList [List.headI L]) [] c d }
[PROOFSTEP]
simp
[GOAL]
case refine'_2
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    {
      l :=
        some
          (ite (List.rec none (fun head tail tail_ih => some Γ'.cons) L = some Γ'.consₗ) id
            (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev q)),
      var := List.rec none (fun head tail tail_ih => some Γ'.cons) L,
      stk := elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d }
    { l := some q, var := none, stk := elim (trNat (List.headI L) ++ [Γ'.cons]) [] c d }
[PROOFSTEP]
rw [if_neg (show o ≠ some Γ'.consₗ by cases L <;> simp)]
[GOAL]
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ o ≠ some Γ'.consₗ
[PROOFSTEP]
cases L
[GOAL]
case nil
q : Λ'
s : Option Γ'
c d : List Γ'
o : Option Γ' := List.casesOn [] none fun x x => some Γ'.cons
⊢ o ≠ some Γ'.consₗ
[PROOFSTEP]
simp
[GOAL]
case cons
q : Λ'
s : Option Γ'
c d : List Γ'
head✝ : ℕ
tail✝ : List ℕ
o : Option Γ' := List.casesOn (head✝ :: tail✝) none fun x x => some Γ'.cons
⊢ o ≠ some Γ'.consₗ
[PROOFSTEP]
simp
[GOAL]
case refine'_2
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main (unrev q)),
      var := List.rec none (fun head tail tail_ih => some Γ'.cons) L,
      stk := elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d }
    { l := some q, var := none, stk := elim (trNat (List.headI L) ++ [Γ'.cons]) [] c d }
[PROOFSTEP]
refine' (clear_ok (splitAtPred_eq _ _ _ none [] _ ⟨rfl, rfl⟩)).trans _
[GOAL]
case refine'_2.refine'_1
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ ∀ (x : Γ'),
    x ∈ elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d main →
      decide (x = Γ'.consₗ) = false
[PROOFSTEP]
exact fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)
[GOAL]
case refine'_2.refine'_2
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    { l := some (unrev q), var := none,
      stk :=
        update
          (elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d)
          main [] }
    { l := some q, var := none, stk := elim (trNat (List.headI L) ++ [Γ'.cons]) [] c d }
[PROOFSTEP]
convert unrev_ok using 2
[GOAL]
case h.e'_2.h.e'_7
q : Λ'
s : Option Γ'
L : List ℕ
c d : List Γ'
o : Option Γ' := List.casesOn L none fun x x => some Γ'.cons
⊢ elim (trNat (List.headI L) ++ [Γ'.cons]) [] c d =
    update
      (update
        (update
          (elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d)
          main [])
        rev [])
      main
      (List.reverseAux
        (update
          (elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d)
          main [] rev)
        (update
          (elim (trList (List.tail L)) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat (List.headI L)) []) c d)
          main [] main))
[PROOFSTEP]
simp [List.reverseAux_eq]
[GOAL]
q : Λ'
s : Option Γ'
L₁ L₂ : List ℕ
L₃ : List Γ'
⊢ Reaches₁ (TM2.step tr)
    { l := some (head stack q), var := s, stk := elim (trList L₁) [] [] (trList L₂ ++ Γ'.consₗ :: L₃) }
    { l := some q, var := none, stk := elim (trList (List.headI L₂ :: L₁)) [] [] L₃ }
[PROOFSTEP]
cases' L₂ with a L₂
[GOAL]
case nil
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
⊢ Reaches₁ (TM2.step tr)
    { l := some (head stack q), var := s, stk := elim (trList L₁) [] [] (trList [] ++ Γ'.consₗ :: L₃) }
    { l := some q, var := none, stk := elim (trList (List.headI [] :: L₁)) [] [] L₃ }
[PROOFSTEP]
refine'
  TransGen.trans (move_ok (by decide) (splitAtPred_eq _ _ [] (some Γ'.consₗ) L₃ (by rintro _ ⟨⟩) ⟨rfl, rfl⟩))
    (TransGen.head rfl (TransGen.head rfl _))
[GOAL]
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
⊢ stack ≠ rev
[PROOFSTEP]
decide
[GOAL]
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
⊢ ∀ (x : Γ'), x ∈ [] → natEnd x = false
[PROOFSTEP]
rintro _ ⟨⟩
[GOAL]
case nil
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    (TM2.stepAux
      (tr
        ((fun x =>
            Λ'.read fun s => ite (s = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) stack) (unrev q))
          (some Γ'.consₗ)))
      (some Γ'.consₗ)
      (update
        (update (update (elim (trList L₁) [] [] (trList [] ++ Γ'.consₗ :: L₃)) stack L₃) rev
          (List.reverseAux [] (elim (trList L₁) [] [] (trList [] ++ Γ'.consₗ :: L₃) rev)))
        rev
        ((fun s => Option.iget ((fun x => some Γ'.cons) s)) (some Γ'.consₗ) ::
          update (update (elim (trList L₁) [] [] (trList [] ++ Γ'.consₗ :: L₃)) stack L₃) rev
            (List.reverseAux [] (elim (trList L₁) [] [] (trList [] ++ Γ'.consₗ :: L₃) rev)) rev)))
    { l := some q, var := none, stk := elim (trList (List.headI [] :: L₁)) [] [] L₃ }
[PROOFSTEP]
simp
[GOAL]
case nil
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (unrev q), var := some Γ'.consₗ, stk := elim (trList L₁) [Option.iget (some Γ'.cons)] [] L₃ }
    { l := some q, var := none, stk := elim (Γ'.cons :: trList L₁) [] [] L₃ }
[PROOFSTEP]
convert unrev_ok using 2
[GOAL]
case h.e'_2.h.e'_7
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
⊢ elim (Γ'.cons :: trList L₁) [] [] L₃ =
    update (update (elim (trList L₁) [Option.iget (some Γ'.cons)] [] L₃) rev []) main
      (List.reverseAux (elim (trList L₁) [Option.iget (some Γ'.cons)] [] L₃ rev)
        (elim (trList L₁) [Option.iget (some Γ'.cons)] [] L₃ main))
[PROOFSTEP]
simp
[GOAL]
case cons
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ Reaches₁ (TM2.step tr)
    { l := some (head stack q), var := s, stk := elim (trList L₁) [] [] (trList (a :: L₂) ++ Γ'.consₗ :: L₃) }
    { l := some q, var := none, stk := elim (trList (List.headI (a :: L₂) :: L₁)) [] [] L₃ }
[PROOFSTEP]
refine'
  TransGen.trans
    (move_ok (by decide)
      (splitAtPred_eq _ _ (trNat a) (some Γ'.cons) (trList L₂ ++ Γ'.consₗ :: L₃) (trNat_natEnd _) ⟨rfl, by simp⟩))
    (TransGen.head rfl (TransGen.head rfl _))
[GOAL]
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ stack ≠ rev
[PROOFSTEP]
decide
[GOAL]
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ elim (trList L₁) [] [] (trList (a :: L₂) ++ Γ'.consₗ :: L₃) stack =
    trNat a ++ Γ'.cons :: (trList L₂ ++ Γ'.consₗ :: L₃)
[PROOFSTEP]
simp
[GOAL]
case cons
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    (TM2.stepAux
      (tr
        ((fun x =>
            Λ'.read fun s => ite (s = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) stack) (unrev q))
          (some Γ'.cons)))
      (some Γ'.cons)
      (update
        (update
          (update (elim (trList L₁) [] [] (trList (a :: L₂) ++ Γ'.consₗ :: L₃)) stack (trList L₂ ++ Γ'.consₗ :: L₃)) rev
          (List.reverseAux (trNat a) (elim (trList L₁) [] [] (trList (a :: L₂) ++ Γ'.consₗ :: L₃) rev)))
        rev
        ((fun s => Option.iget ((fun x => some Γ'.cons) s)) (some Γ'.cons) ::
          update
            (update (elim (trList L₁) [] [] (trList (a :: L₂) ++ Γ'.consₗ :: L₃)) stack (trList L₂ ++ Γ'.consₗ :: L₃))
            rev (List.reverseAux (trNat a) (elim (trList L₁) [] [] (trList (a :: L₂) ++ Γ'.consₗ :: L₃) rev)) rev)))
    { l := some q, var := none, stk := elim (trList (List.headI (a :: L₂) :: L₁)) [] [] L₃ }
[PROOFSTEP]
simp
[GOAL]
case cons
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (Λ'.clear (fun x => decide (x = Γ'.consₗ)) stack (unrev q)), var := some Γ'.cons,
      stk :=
        elim (trList L₁) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat a) []) [] (trList L₂ ++ Γ'.consₗ :: L₃) }
    { l := some q, var := none, stk := elim (trNat a ++ Γ'.cons :: trList L₁) [] [] L₃ }
[PROOFSTEP]
refine'
  TransGen.trans
    (clear_ok
      (splitAtPred_eq _ _ (trList L₂) (some Γ'.consₗ) L₃ (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h))
        ⟨rfl, by simp⟩))
    _
[GOAL]
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ elim (trList L₁) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat a) []) [] (trList L₂ ++ Γ'.consₗ :: L₃) stack =
    trList L₂ ++ Γ'.consₗ :: L₃
[PROOFSTEP]
simp
[GOAL]
case cons
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (unrev q), var := some Γ'.consₗ,
      stk :=
        update
          (elim (trList L₁) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat a) []) []
            (trList L₂ ++ Γ'.consₗ :: L₃))
          stack L₃ }
    { l := some q, var := none, stk := elim (trNat a ++ Γ'.cons :: trList L₁) [] [] L₃ }
[PROOFSTEP]
convert unrev_ok using 2
[GOAL]
case h.e'_2.h.e'_7
q : Λ'
s : Option Γ'
L₁ : List ℕ
L₃ : List Γ'
a : ℕ
L₂ : List ℕ
⊢ elim (trNat a ++ Γ'.cons :: trList L₁) [] [] L₃ =
    update
      (update
        (update
          (elim (trList L₁) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat a) []) []
            (trList L₂ ++ Γ'.consₗ :: L₃))
          stack L₃)
        rev [])
      main
      (List.reverseAux
        (update
          (elim (trList L₁) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat a) []) []
            (trList L₂ ++ Γ'.consₗ :: L₃))
          stack L₃ rev)
        (update
          (elim (trList L₁) (Option.iget (some Γ'.cons) :: List.reverseAux (trNat a) []) []
            (trList L₂ ++ Γ'.consₗ :: L₃))
          stack L₃ main))
[PROOFSTEP]
simp [List.reverseAux_eq]
[GOAL]
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trList [n]) [] c d }
    { l := some q, var := none, stk := elim (trList [Nat.succ n]) [] c d }
[PROOFSTEP]
simp [trNat, Num.add_one]
[GOAL]
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.succ q), var := s, stk := elim (trNum ↑n ++ [Γ'.cons]) [] c d }
    { l := some q, var := none, stk := elim (trNum (Num.succ ↑n) ++ [Γ'.cons]) [] c d }
[PROOFSTEP]
cases' (n : Num) with a
[GOAL]
case zero
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.succ q), var := s, stk := elim (trNum Num.zero ++ [Γ'.cons]) [] c d }
    { l := some q, var := none, stk := elim (trNum (Num.succ Num.zero) ++ [Γ'.cons]) [] c d }
[PROOFSTEP]
refine' TransGen.head rfl _
[GOAL]
case zero
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ TransGen
    (fun a b =>
      b ∈
        (fun x =>
            match x with
            | { l := none, var := var, stk := stk } => none
            | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
          a)
    (TM2.stepAux (tr (Λ'.succ q)) s (elim (trNum Num.zero ++ [Γ'.cons]) [] c d))
    { l := some q, var := none, stk := elim (trNum (Num.succ Num.zero) ++ [Γ'.cons]) [] c d }
[PROOFSTEP]
simp
[GOAL]
case zero
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (unrev q), var := List.head? (trNum Num.zero ++ [Γ'.cons]),
      stk := elim (Γ'.bit1 :: Γ'.cons :: List.tail (trNum Num.zero ++ [Γ'.cons])) [] c d }
    { l := some q, var := none, stk := elim (trNum (Num.succ Num.zero) ++ [Γ'.cons]) [] c d }
[PROOFSTEP]
convert unrev_ok using 2
[GOAL]
case h.e'_2.h.e'_7
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ elim (trNum (Num.succ Num.zero) ++ [Γ'.cons]) [] c d =
    update (update (elim (Γ'.bit1 :: Γ'.cons :: List.tail (trNum Num.zero ++ [Γ'.cons])) [] c d) rev []) main
      (List.reverseAux (elim (Γ'.bit1 :: Γ'.cons :: List.tail (trNum Num.zero ++ [Γ'.cons])) [] c d rev)
        (elim (Γ'.bit1 :: Γ'.cons :: List.tail (trNum Num.zero ++ [Γ'.cons])) [] c d main))
[PROOFSTEP]
simp
[GOAL]
case h.e'_2.h.e'_7
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
⊢ elim (trNum (Num.succ Num.zero) ++ [Γ'.cons]) [] c d =
    elim (Γ'.bit1 :: Γ'.cons :: List.tail (trNum Num.zero ++ [Γ'.cons])) [] c d
[PROOFSTEP]
rfl
[GOAL]
case pos
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
a : PosNum
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.succ q), var := s, stk := elim (trNum (Num.pos a) ++ [Γ'.cons]) [] c d }
    { l := some q, var := none, stk := elim (trNum (Num.succ (Num.pos a)) ++ [Γ'.cons]) [] c d }
[PROOFSTEP]
simp [Num.succ, trNum, Num.succ']
[GOAL]
case pos
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
a : PosNum
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) [] c d }
    { l := some q, var := none, stk := elim (trPosNum (PosNum.succ a) ++ [Γ'.cons]) [] c d }
[PROOFSTEP]
suffices
  ∀ l₁,
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a.succ) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) ⟨some q.succ, s, K'.elim (trPosNum a ++ [Γ'.cons]) l₁ c d⟩
          ⟨some (unrev q), s', K'.elim (l₂' ++ [Γ'.cons]) l₁' c d⟩
  by
  obtain ⟨l₁', l₂', s', e, h⟩ := this []
  simp [List.reverseAux] at e
  refine' h.trans _
  convert unrev_ok using 2
  simp [e, List.reverseAux_eq]
[GOAL]
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ a)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) [] c d }
    { l := some q, var := none, stk := elim (trPosNum (PosNum.succ a) ++ [Γ'.cons]) [] c d }
[PROOFSTEP]
obtain ⟨l₁', l₂', s', e, h⟩ := this []
[GOAL]
case intro.intro.intro.intro
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ a)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
l₁' l₂' : List Γ'
s' : Option Γ'
e : List.reverseAux [] (trPosNum (PosNum.succ a)) = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) [] c d }
    { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) [] c d }
    { l := some q, var := none, stk := elim (trPosNum (PosNum.succ a) ++ [Γ'.cons]) [] c d }
[PROOFSTEP]
simp [List.reverseAux] at e
[GOAL]
case intro.intro.intro.intro
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ a)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
l₁' l₂' : List Γ'
s' : Option Γ'
e : trPosNum (PosNum.succ a) = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) [] c d }
    { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) [] c d }
    { l := some q, var := none, stk := elim (trPosNum (PosNum.succ a) ++ [Γ'.cons]) [] c d }
[PROOFSTEP]
refine' h.trans _
[GOAL]
case intro.intro.intro.intro
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ a)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
l₁' l₂' : List Γ'
s' : Option Γ'
e : trPosNum (PosNum.succ a) = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) [] c d }
    { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
⊢ TransGen (fun a b => b ∈ TM2.step tr a) { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
    { l := some q, var := none, stk := elim (trPosNum (PosNum.succ a) ++ [Γ'.cons]) [] c d }
[PROOFSTEP]
convert unrev_ok using 2
[GOAL]
case h.e'_2.h.e'_7
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ a)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
l₁' l₂' : List Γ'
s' : Option Γ'
e : trPosNum (PosNum.succ a) = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) [] c d }
    { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
⊢ elim (trPosNum (PosNum.succ a) ++ [Γ'.cons]) [] c d =
    update (update (elim (l₂' ++ [Γ'.cons]) l₁' c d) rev []) main
      (List.reverseAux (elim (l₂' ++ [Γ'.cons]) l₁' c d rev) (elim (l₂' ++ [Γ'.cons]) l₁' c d main))
[PROOFSTEP]
simp [e, List.reverseAux_eq]
[GOAL]
case pos
q : Λ'
s : Option Γ'
n : ℕ
c d : List Γ'
a : PosNum
⊢ ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ a)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum a ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
[PROOFSTEP]
induction' a with m IH m _ generalizing s
[GOAL]
case pos.one
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
s : Option Γ'
⊢ ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ PosNum.one)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.succ q), var := s, stk := elim (trPosNum PosNum.one ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
[PROOFSTEP]
intro l₁
[GOAL]
case pos.bit1
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
m : PosNum
IH :
  ∀ {s : Option Γ'} (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum m ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
s : Option Γ'
⊢ ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ (PosNum.bit1 m))) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.succ q), var := s, stk := elim (trPosNum (PosNum.bit1 m) ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
[PROOFSTEP]
intro l₁
[GOAL]
case pos.bit0
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
m : PosNum
a_ih✝ :
  ∀ {s : Option Γ'} (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum m ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
s : Option Γ'
⊢ ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ (PosNum.bit0 m))) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.succ q), var := s, stk := elim (trPosNum (PosNum.bit0 m) ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
[PROOFSTEP]
intro l₁
[GOAL]
case pos.one
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
s : Option Γ'
l₁ : List Γ'
⊢ ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum (PosNum.succ PosNum.one)) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum PosNum.one ++ [Γ'.cons]) l₁ c d }
        { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
[PROOFSTEP]
refine' ⟨Γ'.bit0 :: l₁, [Γ'.bit1], some Γ'.cons, rfl, TransGen.head rfl (TransGen.single _)⟩
[GOAL]
case pos.one
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
s : Option Γ'
l₁ : List Γ'
⊢ { l := some (unrev q), var := some Γ'.cons, stk := elim ([Γ'.bit1] ++ [Γ'.cons]) (Γ'.bit0 :: l₁) c d } ∈
    TM2.step tr (TM2.stepAux (tr (Λ'.succ q)) s (elim (trPosNum PosNum.one ++ [Γ'.cons]) l₁ c d))
[PROOFSTEP]
simp [trPosNum]
[GOAL]
case pos.bit1
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
m : PosNum
IH :
  ∀ {s : Option Γ'} (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum m ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
s : Option Γ'
l₁ : List Γ'
⊢ ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum (PosNum.succ (PosNum.bit1 m))) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.succ q), var := s, stk := elim (trPosNum (PosNum.bit1 m) ++ [Γ'.cons]) l₁ c d }
        { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
[PROOFSTEP]
obtain ⟨l₁', l₂', s', e, h⟩ := IH (Γ'.bit0 :: l₁)
[GOAL]
case pos.bit1.intro.intro.intro.intro
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
m : PosNum
IH :
  ∀ {s : Option Γ'} (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum m ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
s : Option Γ'
l₁ l₁' l₂' : List Γ'
s' : Option Γ'
e : List.reverseAux (Γ'.bit0 :: l₁) (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.succ q), var := ?m.523453, stk := elim (trPosNum m ++ [Γ'.cons]) (Γ'.bit0 :: l₁) c d }
    { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
⊢ ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum (PosNum.succ (PosNum.bit1 m))) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.succ q), var := s, stk := elim (trPosNum (PosNum.bit1 m) ++ [Γ'.cons]) l₁ c d }
        { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
[PROOFSTEP]
refine' ⟨l₁', l₂', s', e, TransGen.head _ h⟩
[GOAL]
case pos.bit1.intro.intro.intro.intro.refine'_1
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
m : PosNum
IH :
  ∀ {s : Option Γ'} (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum m ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
s : Option Γ'
l₁ : List Γ'
⊢ Option Γ'
case pos.bit1.intro.intro.intro.intro.refine'_2
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
m : PosNum
IH :
  ∀ {s : Option Γ'} (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum m ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
s : Option Γ'
l₁ l₁' l₂' : List Γ'
s' : Option Γ'
e : List.reverseAux (Γ'.bit0 :: l₁) (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.succ q), var := ?pos.bit1.intro.intro.intro.intro.refine'_1,
      stk := elim (trPosNum m ++ [Γ'.cons]) (Γ'.bit0 :: l₁) c d }
    { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
⊢ { l := some (Λ'.succ q), var := ?pos.bit1.intro.intro.intro.intro.refine'_1,
      stk := elim (trPosNum m ++ [Γ'.cons]) (Γ'.bit0 :: l₁) c d } ∈
    TM2.step tr { l := some (Λ'.succ q), var := s, stk := elim (trPosNum (PosNum.bit1 m) ++ [Γ'.cons]) l₁ c d }
[PROOFSTEP]
swap
[GOAL]
case pos.bit1.intro.intro.intro.intro.refine'_2
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
m : PosNum
IH :
  ∀ {s : Option Γ'} (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum m ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
s : Option Γ'
l₁ l₁' l₂' : List Γ'
s' : Option Γ'
e : List.reverseAux (Γ'.bit0 :: l₁) (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.succ q), var := ?pos.bit1.intro.intro.intro.intro.refine'_1,
      stk := elim (trPosNum m ++ [Γ'.cons]) (Γ'.bit0 :: l₁) c d }
    { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
⊢ { l := some (Λ'.succ q), var := ?pos.bit1.intro.intro.intro.intro.refine'_1,
      stk := elim (trPosNum m ++ [Γ'.cons]) (Γ'.bit0 :: l₁) c d } ∈
    TM2.step tr { l := some (Λ'.succ q), var := s, stk := elim (trPosNum (PosNum.bit1 m) ++ [Γ'.cons]) l₁ c d }
case pos.bit1.intro.intro.intro.intro.refine'_1
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
m : PosNum
IH :
  ∀ {s : Option Γ'} (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum m ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
s : Option Γ'
l₁ : List Γ'
⊢ Option Γ'
[PROOFSTEP]
simp [PosNum.succ, trPosNum]
[GOAL]
case pos.bit1.intro.intro.intro.intro.refine'_2
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
m : PosNum
IH :
  ∀ {s : Option Γ'} (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum m ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
s : Option Γ'
l₁ l₁' l₂' : List Γ'
s' : Option Γ'
e : List.reverseAux (Γ'.bit0 :: l₁) (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.succ q), var := ?pos.bit1.intro.intro.intro.intro.refine'_1,
      stk := elim (trPosNum m ++ [Γ'.cons]) (Γ'.bit0 :: l₁) c d }
    { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
⊢ some Γ'.bit1 = ?pos.bit1.intro.intro.intro.intro.refine'_1
case pos.bit1.intro.intro.intro.intro.refine'_1
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
m : PosNum
IH :
  ∀ {s : Option Γ'} (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum m ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
s : Option Γ'
l₁ : List Γ'
⊢ Option Γ'
[PROOFSTEP]
rfl
[GOAL]
case pos.bit0
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
m : PosNum
a_ih✝ :
  ∀ {s : Option Γ'} (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum m ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
s : Option Γ'
l₁ : List Γ'
⊢ ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum (PosNum.succ (PosNum.bit0 m))) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.succ q), var := s, stk := elim (trPosNum (PosNum.bit0 m) ++ [Γ'.cons]) l₁ c d }
        { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
[PROOFSTEP]
refine' ⟨l₁, _, some Γ'.bit0, rfl, TransGen.single _⟩
[GOAL]
case pos.bit0
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
m : PosNum
a_ih✝ :
  ∀ {s : Option Γ'} (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum m ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
s : Option Γ'
l₁ : List Γ'
⊢ { l := some (unrev q), var := some Γ'.bit0,
      stk := elim (trPosNum (PosNum.succ (PosNum.bit0 m)) ++ [Γ'.cons]) l₁ c d } ∈
    TM2.step tr { l := some (Λ'.succ q), var := s, stk := elim (trPosNum (PosNum.bit0 m) ++ [Γ'.cons]) l₁ c d }
[PROOFSTEP]
simp
[GOAL]
case pos.bit0
q : Λ'
s✝ : Option Γ'
n : ℕ
c d : List Γ'
m : PosNum
a_ih✝ :
  ∀ {s : Option Γ'} (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.succ m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.succ q), var := s, stk := elim (trPosNum m ++ [Γ'.cons]) l₁ c d }
          { l := some (unrev q), var := s', stk := elim (l₂' ++ [Γ'.cons]) l₁' c d }
s : Option Γ'
l₁ : List Γ'
⊢ (bif decide (List.head? (trPosNum (PosNum.bit0 m) ++ [Γ'.cons]) = some Γ'.bit1) then
      { l := some (Λ'.succ q), var := List.head? (trPosNum (PosNum.bit0 m) ++ [Γ'.cons]),
        stk := elim (List.tail (trPosNum (PosNum.bit0 m) ++ [Γ'.cons])) (Γ'.bit0 :: l₁) c d }
    else
      bif decide (List.head? (trPosNum (PosNum.bit0 m) ++ [Γ'.cons]) = some Γ'.cons) then
        { l := some (unrev q), var := List.head? (trPosNum (PosNum.bit0 m) ++ [Γ'.cons]),
          stk := elim (Γ'.bit1 :: Γ'.cons :: List.tail (trPosNum (PosNum.bit0 m) ++ [Γ'.cons])) l₁ c d }
      else
        { l := some (unrev q), var := List.head? (trPosNum (PosNum.bit0 m) ++ [Γ'.cons]),
          stk := elim (Γ'.bit1 :: List.tail (trPosNum (PosNum.bit0 m) ++ [Γ'.cons])) l₁ c d }) =
    { l := some (unrev q), var := some Γ'.bit0,
      stk := elim (trPosNum (PosNum.succ (PosNum.bit0 m)) ++ [Γ'.cons]) l₁ c d }
[PROOFSTEP]
rfl
[GOAL]
q₁ q₂ : Λ'
s : Option Γ'
v : List ℕ
c d : List Γ'
⊢ ∃ s',
    Reaches₁ (TM2.step tr) { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trList v) [] c d }
      (Nat.rec { l := some q₁, var := s', stk := elim (trList (List.tail v)) [] c d }
        (fun n x => { l := some q₂, var := s', stk := elim (trList (n :: List.tail v)) [] c d }) (List.headI v))
[PROOFSTEP]
rcases v with (_ | ⟨_ | n, v⟩)
[GOAL]
case nil
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
⊢ ∃ s',
    Reaches₁ (TM2.step tr) { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trList []) [] c d }
      (Nat.rec { l := some q₁, var := s', stk := elim (trList (List.tail [])) [] c d }
        (fun n x => { l := some q₂, var := s', stk := elim (trList (n :: List.tail [])) [] c d }) (List.headI []))
[PROOFSTEP]
refine' ⟨none, TransGen.single _⟩
[GOAL]
case nil
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
⊢ Nat.rec { l := some q₁, var := none, stk := elim (trList (List.tail [])) [] c d }
      (fun n x => { l := some q₂, var := none, stk := elim (trList (n :: List.tail [])) [] c d }) (List.headI []) ∈
    TM2.step tr { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trList []) [] c d }
[PROOFSTEP]
simp
[GOAL]
case nil
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
⊢ { l := some q₁, var := none, stk := elim [] [] c d } =
    Nat.rec { l := some q₁, var := none, stk := elim [] [] c d }
      (fun n x => { l := some q₂, var := none, stk := elim (trNat n ++ [Γ'.cons]) [] c d }) default
[PROOFSTEP]
rfl
[GOAL]
case cons.zero
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
⊢ ∃ s',
    Reaches₁ (TM2.step tr) { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trList (Nat.zero :: v)) [] c d }
      (Nat.rec { l := some q₁, var := s', stk := elim (trList (List.tail (Nat.zero :: v))) [] c d }
        (fun n x => { l := some q₂, var := s', stk := elim (trList (n :: List.tail (Nat.zero :: v))) [] c d })
        (List.headI (Nat.zero :: v)))
[PROOFSTEP]
refine' ⟨some Γ'.cons, TransGen.single _⟩
[GOAL]
case cons.zero
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
⊢ Nat.rec { l := some q₁, var := some Γ'.cons, stk := elim (trList (List.tail (Nat.zero :: v))) [] c d }
      (fun n x => { l := some q₂, var := some Γ'.cons, stk := elim (trList (n :: List.tail (Nat.zero :: v))) [] c d })
      (List.headI (Nat.zero :: v)) ∈
    TM2.step tr { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trList (Nat.zero :: v)) [] c d }
[PROOFSTEP]
simp
[GOAL]
case cons.succ
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
⊢ ∃ s',
    Reaches₁ (TM2.step tr) { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trList (Nat.succ n :: v)) [] c d }
      (Nat.rec { l := some q₁, var := s', stk := elim (trList (List.tail (Nat.succ n :: v))) [] c d }
        (fun n_1 x => { l := some q₂, var := s', stk := elim (trList (n_1 :: List.tail (Nat.succ n :: v))) [] c d })
        (List.headI (Nat.succ n :: v)))
[PROOFSTEP]
refine' ⟨none, _⟩
[GOAL]
case cons.succ
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
⊢ Reaches₁ (TM2.step tr) { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trList (Nat.succ n :: v)) [] c d }
    (Nat.rec { l := some q₁, var := none, stk := elim (trList (List.tail (Nat.succ n :: v))) [] c d }
      (fun n_1 x => { l := some q₂, var := none, stk := elim (trList (n_1 :: List.tail (Nat.succ n :: v))) [] c d })
      (List.headI (Nat.succ n :: v)))
[PROOFSTEP]
simp [trNat, Num.add_one, Num.succ, trNum]
[GOAL]
case cons.succ
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (Num.succ' ↑n) ++ Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none,
      stk :=
        elim
          ((match ↑n with
            | Num.zero => []
            | Num.pos n => trPosNum n) ++
            Γ'.cons :: trList v)
          [] c d }
[PROOFSTEP]
cases' (n : Num) with a
[GOAL]
case cons.succ.zero
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (Num.succ' Num.zero) ++ Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none,
      stk :=
        elim
          ((match Num.zero with
            | Num.zero => []
            | Num.pos n => trPosNum n) ++
            Γ'.cons :: trList v)
          [] c d }
[PROOFSTEP]
simp [trPosNum, trNum, show Num.zero.succ' = PosNum.one from rfl]
[GOAL]
case cons.succ.zero
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (Γ'.bit1 :: Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none, stk := elim (Γ'.cons :: trList v) [] c d }
[PROOFSTEP]
refine' TransGen.head rfl _
[GOAL]
case cons.succ.zero
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
⊢ TransGen
    (fun a b =>
      b ∈
        (fun x =>
            match x with
            | { l := none, var := var, stk := stk } => none
            | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
          a)
    (TM2.stepAux (tr (Λ'.pred q₁ q₂)) s (elim (Γ'.bit1 :: Γ'.cons :: trList v) [] c d))
    { l := some q₂, var := none, stk := elim (Γ'.cons :: trList v) [] c d }
[PROOFSTEP]
simp
[GOAL]
case cons.succ.zero
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (unrev q₂), var := some Γ'.cons, stk := elim (Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none, stk := elim (Γ'.cons :: trList v) [] c d }
[PROOFSTEP]
convert unrev_ok using 2
[GOAL]
case h.e'_2.h.e'_7
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
⊢ elim (Γ'.cons :: trList v) [] c d =
    update (update (elim (Γ'.cons :: trList v) [] c d) rev []) main
      (List.reverseAux (elim (Γ'.cons :: trList v) [] c d rev) (elim (Γ'.cons :: trList v) [] c d main))
[PROOFSTEP]
simp
[GOAL]
case cons.succ.pos
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.pred q₁ q₂), var := s,
      stk := elim (trPosNum (Num.succ' (Num.pos a)) ++ Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none,
      stk :=
        elim
          ((match Num.pos a with
            | Num.zero => []
            | Num.pos n => trPosNum n) ++
            Γ'.cons :: trList v)
          [] c d }
[PROOFSTEP]
simp [trNum, Num.succ']
[GOAL]
case cons.succ.pos
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none, stk := elim (trPosNum a ++ Γ'.cons :: trList v) [] c d }
[PROOFSTEP]
suffices
  ∀ l₁,
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr) ⟨some (q₁.pred q₂), s, K'.elim (trPosNum a.succ ++ Γ'.cons :: trList v) l₁ c d⟩
          ⟨some (unrev q₂), s', K'.elim (l₂' ++ Γ'.cons :: trList v) l₁' c d⟩
  by
  obtain ⟨l₁', l₂', s', e, h⟩ := this []
  simp [List.reverseAux] at e
  refine' h.trans _
  convert unrev_ok using 2
  simp [e, List.reverseAux_eq]
[GOAL]
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none, stk := elim (trPosNum a ++ Γ'.cons :: trList v) [] c d }
[PROOFSTEP]
obtain ⟨l₁', l₂', s', e, h⟩ := this []
[GOAL]
case intro.intro.intro.intro
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
l₁' l₂' : List Γ'
s' : Option Γ'
e : List.reverseAux [] (trPosNum a) = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none, stk := elim (trPosNum a ++ Γ'.cons :: trList v) [] c d }
[PROOFSTEP]
simp [List.reverseAux] at e
[GOAL]
case intro.intro.intro.intro
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
l₁' l₂' : List Γ'
s' : Option Γ'
e : trPosNum a = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ Reaches₁
    (fun x =>
      match x with
      | { l := none, var := var, stk := stk } => none
      | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S))
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some q₂, var := none, stk := elim (trPosNum a ++ Γ'.cons :: trList v) [] c d }
[PROOFSTEP]
refine' h.trans _
[GOAL]
case intro.intro.intro.intro
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
l₁' l₂' : List Γ'
s' : Option Γ'
e : trPosNum a = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
    { l := some q₂, var := none, stk := elim (trPosNum a ++ Γ'.cons :: trList v) [] c d }
[PROOFSTEP]
convert unrev_ok using 2
[GOAL]
case h.e'_2.h.e'_7
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
this :
  ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
l₁' l₂' : List Γ'
s' : Option Γ'
e : trPosNum a = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) [] c d }
    { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ elim (trPosNum a ++ Γ'.cons :: trList v) [] c d =
    update (update (elim (l₂' ++ Γ'.cons :: trList v) l₁' c d) rev []) main
      (List.reverseAux (elim (l₂' ++ Γ'.cons :: trList v) l₁' c d rev) (elim (l₂' ++ Γ'.cons :: trList v) l₁' c d main))
[PROOFSTEP]
simp [e, List.reverseAux_eq]
[GOAL]
case cons.succ.pos
q₁ q₂ : Λ'
s : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
a : PosNum
⊢ ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum a) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ a) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
[PROOFSTEP]
induction' a with m IH m IH generalizing s
[GOAL]
case cons.succ.pos.one
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
s : Option Γ'
⊢ ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum PosNum.one) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s,
            stk := elim (trPosNum (PosNum.succ PosNum.one) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
[PROOFSTEP]
intro l₁
[GOAL]
case cons.succ.pos.bit1
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
⊢ ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.bit1 m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s,
            stk := elim (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
[PROOFSTEP]
intro l₁
[GOAL]
case cons.succ.pos.bit0
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
⊢ ∀ (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.bit0 m)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s,
            stk := elim (trPosNum (PosNum.succ (PosNum.bit0 m)) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
[PROOFSTEP]
intro l₁
[GOAL]
case cons.succ.pos.one
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
s : Option Γ'
l₁ : List Γ'
⊢ ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum PosNum.one) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.pred q₁ q₂), var := s,
          stk := elim (trPosNum (PosNum.succ PosNum.one) ++ Γ'.cons :: trList v) l₁ c d }
        { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
[PROOFSTEP]
refine' ⟨Γ'.bit1 :: l₁, [], some Γ'.cons, rfl, TransGen.head rfl (TransGen.single _)⟩
[GOAL]
case cons.succ.pos.one
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
s : Option Γ'
l₁ : List Γ'
⊢ { l := some (unrev q₂), var := some Γ'.cons, stk := elim ([] ++ Γ'.cons :: trList v) (Γ'.bit1 :: l₁) c d } ∈
    TM2.step tr
      (TM2.stepAux (tr (Λ'.pred q₁ q₂)) s (elim (trPosNum (PosNum.succ PosNum.one) ++ Γ'.cons :: trList v) l₁ c d))
[PROOFSTEP]
simp [trPosNum, show PosNum.one.succ = PosNum.one.bit0 from rfl]
[GOAL]
case cons.succ.pos.bit1
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
l₁ : List Γ'
⊢ ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum (PosNum.bit1 m)) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.pred q₁ q₂), var := s,
          stk := elim (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v) l₁ c d }
        { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
[PROOFSTEP]
obtain ⟨l₁', l₂', s', e, h⟩ := IH (some Γ'.bit0) (Γ'.bit1 :: l₁)
[GOAL]
case cons.succ.pos.bit1.intro.intro.intro.intro
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
l₁ l₁' l₂' : List Γ'
s' : Option Γ'
e : List.reverseAux (Γ'.bit1 :: l₁) (trPosNum m) = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := some Γ'.bit0,
      stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) (Γ'.bit1 :: l₁) c d }
    { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum (PosNum.bit1 m)) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.pred q₁ q₂), var := s,
          stk := elim (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v) l₁ c d }
        { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
[PROOFSTEP]
refine' ⟨l₁', l₂', s', e, TransGen.head _ h⟩
[GOAL]
case cons.succ.pos.bit1.intro.intro.intro.intro
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
l₁ l₁' l₂' : List Γ'
s' : Option Γ'
e : List.reverseAux (Γ'.bit1 :: l₁) (trPosNum m) = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := some Γ'.bit0,
      stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) (Γ'.bit1 :: l₁) c d }
    { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ { l := some (Λ'.pred q₁ q₂), var := some Γ'.bit0,
      stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) (Γ'.bit1 :: l₁) c d } ∈
    TM2.step tr
      { l := some (Λ'.pred q₁ q₂), var := s,
        stk := elim (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v) l₁ c d }
[PROOFSTEP]
simp
[GOAL]
case cons.succ.pos.bit1.intro.intro.intro.intro
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
l₁ l₁' l₂' : List Γ'
s' : Option Γ'
e : List.reverseAux (Γ'.bit1 :: l₁) (trPosNum m) = List.reverseAux l₁' l₂'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred q₁ q₂), var := some Γ'.bit0,
      stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) (Γ'.bit1 :: l₁) c d }
    { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ (bif decide (List.head? (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v) = some Γ'.bit0) then
      { l := some (Λ'.pred q₁ q₂), var := List.head? (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v),
        stk := elim (List.tail (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v)) (Γ'.bit1 :: l₁) c d }
    else
      bif
          match Option.iget (List.head? (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v)) with
          | Γ'.consₗ => true
          | Γ'.cons => true
          | x => false then
        { l := some q₁, var := List.head? (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v),
          stk := elim (List.tail (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v)) l₁ c d }
      else
        bif
            match
              Option.iget (List.head? (List.tail (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v))) with
            | Γ'.consₗ => true
            | Γ'.cons => true
            | x => false then
          { l := some (unrev q₂),
            var := List.head? (List.tail (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v)),
            stk := elim (List.tail (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v)) l₁ c d }
        else
          { l := some (unrev q₂),
            var := List.head? (List.tail (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v)),
            stk :=
              elim (List.tail (trPosNum (PosNum.succ (PosNum.bit1 m)) ++ Γ'.cons :: trList v)) (Γ'.bit0 :: l₁) c d }) =
    { l := some (Λ'.pred q₁ q₂), var := some Γ'.bit0,
      stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) (Γ'.bit1 :: l₁) c d }
[PROOFSTEP]
rfl
[GOAL]
case cons.succ.pos.bit0
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
l₁ : List Γ'
⊢ ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum (PosNum.bit0 m)) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.pred q₁ q₂), var := s,
          stk := elim (trPosNum (PosNum.succ (PosNum.bit0 m)) ++ Γ'.cons :: trList v) l₁ c d }
        { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
[PROOFSTEP]
obtain ⟨a, l, e, h⟩ : ∃ a l, (trPosNum m = a :: l) ∧ natEnd a = false := by cases m <;> refine' ⟨_, _, rfl, rfl⟩
[GOAL]
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
l₁ : List Γ'
⊢ ∃ a l, trPosNum m = a :: l ∧ natEnd a = false
[PROOFSTEP]
cases m
[GOAL]
case one
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
s : Option Γ'
l₁ : List Γ'
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum PosNum.one) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s,
            stk := elim (trPosNum (PosNum.succ PosNum.one) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ ∃ a l, trPosNum PosNum.one = a :: l ∧ natEnd a = false
[PROOFSTEP]
refine' ⟨_, _, rfl, rfl⟩
[GOAL]
case bit1
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
s : Option Γ'
l₁ : List Γ'
a✝ : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.bit1 a✝)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s,
            stk := elim (trPosNum (PosNum.succ (PosNum.bit1 a✝)) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ ∃ a l, trPosNum (PosNum.bit1 a✝) = a :: l ∧ natEnd a = false
[PROOFSTEP]
refine' ⟨_, _, rfl, rfl⟩
[GOAL]
case bit0
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
s : Option Γ'
l₁ : List Γ'
a✝ : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum (PosNum.bit0 a✝)) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s,
            stk := elim (trPosNum (PosNum.succ (PosNum.bit0 a✝)) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
⊢ ∃ a l, trPosNum (PosNum.bit0 a✝) = a :: l ∧ natEnd a = false
[PROOFSTEP]
refine' ⟨_, _, rfl, rfl⟩
[GOAL]
case cons.succ.pos.bit0.intro.intro.intro
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
l₁ : List Γ'
a : Γ'
l : List Γ'
e : trPosNum m = a :: l
h : natEnd a = false
⊢ ∃ l₁' l₂' s',
    List.reverseAux l₁ (trPosNum (PosNum.bit0 m)) = List.reverseAux l₁' l₂' ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.pred q₁ q₂), var := s,
          stk := elim (trPosNum (PosNum.succ (PosNum.bit0 m)) ++ Γ'.cons :: trList v) l₁ c d }
        { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
[PROOFSTEP]
refine' ⟨Γ'.bit0 :: l₁, _, some a, rfl, TransGen.single _⟩
[GOAL]
case cons.succ.pos.bit0.intro.intro.intro
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
l₁ : List Γ'
a : Γ'
l : List Γ'
e : trPosNum m = a :: l
h : natEnd a = false
⊢ { l := some (unrev q₂), var := some a, stk := elim (trPosNum m ++ Γ'.cons :: trList v) (Γ'.bit0 :: l₁) c d } ∈
    TM2.step tr
      { l := some (Λ'.pred q₁ q₂), var := s,
        stk := elim (trPosNum (PosNum.succ (PosNum.bit0 m)) ++ Γ'.cons :: trList v) l₁ c d }
[PROOFSTEP]
simp [trPosNum, PosNum.succ, e, h, show some Γ'.bit1 ≠ some Γ'.bit0 by decide, Option.iget, -natEnd]
[GOAL]
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
l₁ : List Γ'
a : Γ'
l : List Γ'
e : trPosNum m = a :: l
h : natEnd a = false
⊢ some Γ'.bit1 ≠ some Γ'.bit0
[PROOFSTEP]
decide
[GOAL]
case cons.succ.pos.bit0.intro.intro.intro
q₁ q₂ : Λ'
s✝ : Option Γ'
c d : List Γ'
v : List ℕ
n : ℕ
m : PosNum
IH :
  ∀ (s : Option Γ') (l₁ : List Γ'),
    ∃ l₁' l₂' s',
      List.reverseAux l₁ (trPosNum m) = List.reverseAux l₁' l₂' ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.pred q₁ q₂), var := s, stk := elim (trPosNum (PosNum.succ m) ++ Γ'.cons :: trList v) l₁ c d }
          { l := some (unrev q₂), var := s', stk := elim (l₂' ++ Γ'.cons :: trList v) l₁' c d }
s : Option Γ'
l₁ : List Γ'
a : Γ'
l : List Γ'
e : trPosNum m = a :: l
h : natEnd a = false
⊢ (bif natEnd Γ'.bit1 then { l := some q₁, var := some Γ'.bit1, stk := elim (a :: (l ++ Γ'.cons :: trList v)) l₁ c d }
    else { l := some (unrev q₂), var := some a, stk := elim (a :: (l ++ Γ'.cons :: trList v)) (Γ'.bit0 :: l₁) c d }) =
    { l := some (unrev q₂), var := some a, stk := elim (a :: (l ++ Γ'.cons :: trList v)) (Γ'.bit0 :: l₁) c d }
[PROOFSTEP]
rfl
[GOAL]
c : Code
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal c k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal c (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
induction c generalizing k v s
[GOAL]
case zero'
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.zero' k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.zero' (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
case succ
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.succ k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.succ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
case tail
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.tail k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.tail (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
case cons
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.cons a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.cons a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case comp
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.comp a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.comp a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case case
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.case a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case fix
a✝ : Code
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.fix a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.fix a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case zero' => refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩; simp
[GOAL]
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.zero' k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.zero' (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case zero' => refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩; simp
[GOAL]
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.zero' k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.zero' (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
refine' ⟨_, ⟨s, rfl⟩, TransGen.single _⟩
[GOAL]
k : Cont
v : List ℕ
s : Option Γ'
⊢ { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList (0 :: v)) [] [] (trContStack k) } ∈
    TM2.step tr { l := some (trNormal Code.zero' (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
[PROOFSTEP]
simp
[GOAL]
case succ
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.succ k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.succ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
case tail
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.tail k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.tail (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
case cons
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.cons a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.cons a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case comp
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.comp a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.comp a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case case
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.case a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case fix
a✝ : Code
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.fix a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.fix a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case succ => refine' ⟨_, ⟨none, rfl⟩, head_main_ok.trans succ_ok⟩
[GOAL]
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.succ k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.succ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case succ => refine' ⟨_, ⟨none, rfl⟩, head_main_ok.trans succ_ok⟩
[GOAL]
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.succ k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.succ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
refine' ⟨_, ⟨none, rfl⟩, head_main_ok.trans succ_ok⟩
[GOAL]
case tail
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.tail k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.tail (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
case cons
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.cons a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.cons a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case comp
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.comp a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.comp a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case case
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.case a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case fix
a✝ : Code
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.fix a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.fix a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case tail =>
  let o : Option Γ' := List.casesOn v none fun _ _ => some Γ'.cons
  refine' ⟨_, ⟨o, rfl⟩, _⟩; convert clear_ok _ using 2; simp; rfl; swap
  refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
  cases v <;> simp
[GOAL]
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.tail k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.tail (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case tail =>
  let o : Option Γ' := List.casesOn v none fun _ _ => some Γ'.cons
  refine' ⟨_, ⟨o, rfl⟩, _⟩; convert clear_ok _ using 2; simp; rfl; swap
  refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
  cases v <;> simp
[GOAL]
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal Code.tail k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.tail (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
let o : Option Γ' := List.casesOn v none fun _ _ => some Γ'.cons
[GOAL]
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ ∃ b₂,
    TrCfg (stepNormal Code.tail k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal Code.tail (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
refine' ⟨_, ⟨o, rfl⟩, _⟩
[GOAL]
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ Reaches₁ (TM2.step tr)
    { l := some (trNormal Code.tail (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
    { l := some (Λ'.ret (trCont k)), var := o, stk := elim (trList (List.tail v)) [] [] (trContStack k) }
[PROOFSTEP]
convert clear_ok _ using 2
[GOAL]
case h.e'_4.h.e'_7
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ elim (trList (List.tail v)) [] [] (trContStack k) = update (elim (trList v) [] [] (trContStack k)) main ?convert_7
case convert_5
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ List Γ'
case convert_7
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ List Γ'
case convert_9
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ splitAtPred natEnd (elim (trList v) [] [] (trContStack k) main) = (?convert_5, o, ?convert_7)
[PROOFSTEP]
simp
[GOAL]
case h.e'_4.h.e'_7
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ elim (trList (List.tail v)) [] [] (trContStack k) = elim ?convert_7 [] [] (trContStack k)
case convert_5
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ List Γ'
case convert_7
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ List Γ'
case convert_9
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ splitAtPred natEnd (elim (trList v) [] [] (trContStack k) main) = (?convert_5, o, ?convert_7)
[PROOFSTEP]
rfl
[GOAL]
case convert_5
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ List Γ'
case convert_9
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ splitAtPred natEnd (elim (trList v) [] [] (trContStack k) main) = (?convert_5, o, trList (List.tail v))
[PROOFSTEP]
swap
[GOAL]
case convert_9
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ splitAtPred natEnd (elim (trList v) [] [] (trContStack k) main) = (?convert_5, o, trList (List.tail v))
case convert_5 k : Cont v : List ℕ s : Option Γ' o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons ⊢ List Γ'
[PROOFSTEP]
refine' splitAtPred_eq _ _ (trNat v.headI) _ _ (trNat_natEnd _) _
[GOAL]
case convert_9
k : Cont
v : List ℕ
s : Option Γ'
o : Option Γ' := List.casesOn v none fun x x => some Γ'.cons
⊢ Option.elim' (elim (trList v) [] [] (trContStack k) main = trNat (List.headI v) ∧ trList (List.tail v) = [])
    (fun a =>
      natEnd a = true ∧ elim (trList v) [] [] (trContStack k) main = trNat (List.headI v) ++ a :: trList (List.tail v))
    o
[PROOFSTEP]
cases v
[GOAL]
case convert_9.nil
k : Cont
s : Option Γ'
o : Option Γ' := List.casesOn [] none fun x x => some Γ'.cons
⊢ Option.elim' (elim (trList []) [] [] (trContStack k) main = trNat (List.headI []) ∧ trList (List.tail []) = [])
    (fun a =>
      natEnd a = true ∧
        elim (trList []) [] [] (trContStack k) main = trNat (List.headI []) ++ a :: trList (List.tail []))
    o
[PROOFSTEP]
simp
[GOAL]
case convert_9.cons
k : Cont
s : Option Γ'
head✝ : ℕ
tail✝ : List ℕ
o : Option Γ' := List.casesOn (head✝ :: tail✝) none fun x x => some Γ'.cons
⊢ Option.elim'
    (elim (trList (head✝ :: tail✝)) [] [] (trContStack k) main = trNat (List.headI (head✝ :: tail✝)) ∧
      trList (List.tail (head✝ :: tail✝)) = [])
    (fun a =>
      natEnd a = true ∧
        elim (trList (head✝ :: tail✝)) [] [] (trContStack k) main =
          trNat (List.headI (head✝ :: tail✝)) ++ a :: trList (List.tail (head✝ :: tail✝)))
    o
[PROOFSTEP]
simp
[GOAL]
case cons
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.cons a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.cons a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case comp
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.comp a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.comp a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case case
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.case a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case fix
a✝ : Code
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.fix a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.fix a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case cons f fs IHf _ =>
  obtain ⟨c, h₁, h₂⟩ := IHf (Cont.cons₁ fs v k) v none
  refine' ⟨c, h₁, TransGen.head rfl <| (move_ok (by decide) (splitAtPred_false _)).trans _⟩
  simp [stepNormal]
  refine' (copy_ok _ none [] (trList v).reverse _ _).trans _
  convert h₂ using 2
  simp [List.reverseAux_eq, trContStack]
[GOAL]
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.cons f fs) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.cons f fs) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case cons f fs IHf _ =>
  obtain ⟨c, h₁, h₂⟩ := IHf (Cont.cons₁ fs v k) v none
  refine' ⟨c, h₁, TransGen.head rfl <| (move_ok (by decide) (splitAtPred_false _)).trans _⟩
  simp [stepNormal]
  refine' (copy_ok _ none [] (trList v).reverse _ _).trans _
  convert h₂ using 2
  simp [List.reverseAux_eq, trContStack]
[GOAL]
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.cons f fs) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.cons f fs) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
obtain ⟨c, h₁, h₂⟩ := IHf (Cont.cons₁ fs v k) v none
[GOAL]
case intro.intro
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
c : Cfg'
h₁ : TrCfg (stepNormal f (Cont.cons₁ fs v k) v) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.cons₁ fs v k))), var := none,
      stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k)) }
    c
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.cons f fs) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.cons f fs) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
refine' ⟨c, h₁, TransGen.head rfl <| (move_ok (by decide) (splitAtPred_false _)).trans _⟩
[GOAL]
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
c : Cfg'
h₁ : TrCfg (stepNormal f (Cont.cons₁ fs v k) v) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.cons₁ fs v k))), var := none,
      stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k)) }
    c
⊢ main ≠ rev
[PROOFSTEP]
decide
[GOAL]
case intro.intro
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
c : Cfg'
h₁ : TrCfg (stepNormal f (Cont.cons₁ fs v k) v) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.cons₁ fs v k))), var := none,
      stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k)) }
    c
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    { l := some (Λ'.copy (trNormal f (Cont'.cons₁ fs (trCont k)))), var := none,
      stk :=
        update
          (update
            (update (elim (trList v) [] [] (trContStack k)) stack
              ((fun s => Option.iget ((fun x => some Γ'.consₗ) s)) s :: elim (trList v) [] [] (trContStack k) stack))
            main [])
          rev
          (List.reverseAux
            (update (elim (trList v) [] [] (trContStack k)) stack
              ((fun s => Option.iget ((fun x => some Γ'.consₗ) s)) s :: elim (trList v) [] [] (trContStack k) stack)
              main)
            (update (elim (trList v) [] [] (trContStack k)) stack
              ((fun s => Option.iget ((fun x => some Γ'.consₗ) s)) s :: elim (trList v) [] [] (trContStack k) stack)
              rev)) }
    c
[PROOFSTEP]
simp [stepNormal]
[GOAL]
case intro.intro
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
c : Cfg'
h₁ : TrCfg (stepNormal f (Cont.cons₁ fs v k) v) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.cons₁ fs v k))), var := none,
      stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k)) }
    c
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (Λ'.copy (trNormal f (Cont'.cons₁ fs (trCont k)))), var := none,
      stk := elim [] (List.reverseAux (trList v) []) [] (Option.iget (some Γ'.consₗ) :: trContStack k) }
    c
[PROOFSTEP]
refine' (copy_ok _ none [] (trList v).reverse _ _).trans _
[GOAL]
case intro.intro
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
c : Cfg'
h₁ : TrCfg (stepNormal f (Cont.cons₁ fs v k) v) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.cons₁ fs v k))), var := none,
      stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k)) }
    c
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    { l := some (trNormal f (Cont'.cons₁ fs (trCont k))), var := none,
      stk :=
        elim (List.reverseAux (List.reverse (trList v)) []) [] []
          (List.reverseAux (List.reverse (trList v)) (Option.iget (some Γ'.consₗ) :: trContStack k)) }
    c
[PROOFSTEP]
convert h₂ using 2
[GOAL]
case h.e'_1.h.e'_7
f fs : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal fs k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal fs (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
c : Cfg'
h₁ : TrCfg (stepNormal f (Cont.cons₁ fs v k) v) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.cons₁ fs v k))), var := none,
      stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k)) }
    c
⊢ elim (List.reverseAux (List.reverse (trList v)) []) [] []
      (List.reverseAux (List.reverse (trList v)) (Option.iget (some Γ'.consₗ) :: trContStack k)) =
    elim (trList v) [] [] (trContStack (Cont.cons₁ fs v k))
[PROOFSTEP]
simp [List.reverseAux_eq, trContStack]
[GOAL]
case comp
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.comp a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.comp a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case case
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.case a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case fix
a✝ : Code
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.fix a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.fix a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case comp f _ _ IHg => exact IHg (Cont.comp f k) v s
[GOAL]
f a✝ : Code
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.comp f a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.comp f a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case comp f _ _ IHg => exact IHg (Cont.comp f k) v s
[GOAL]
f a✝ : Code
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.comp f a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.comp f a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
exact IHg (Cont.comp f k) v s
[GOAL]
case case
a✝¹ a✝ : Code
a_ih✝¹ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝¹ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝¹ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.case a✝¹ a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case a✝¹ a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
case fix
a✝ : Code
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.fix a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.fix a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case case f g IHf IHg =>
  rw [stepNormal]
  simp only
  obtain ⟨s', h⟩ := pred_ok _ _ s v _ _
  revert h; cases' v.headI with n <;> intro h
  · obtain ⟨c, h₁, h₂⟩ := IHf k _ s'
    exact ⟨_, h₁, h.trans h₂⟩
  · obtain ⟨c, h₁, h₂⟩ := IHg k _ s'
    exact ⟨_, h₁, h.trans h₂⟩
[GOAL]
f g : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.case f g) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case f g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case case f g IHf IHg =>
  rw [stepNormal]
  simp only
  obtain ⟨s', h⟩ := pred_ok _ _ s v _ _
  revert h; cases' v.headI with n <;> intro h
  · obtain ⟨c, h₁, h₂⟩ := IHf k _ s'
    exact ⟨_, h₁, h.trans h₂⟩
  · obtain ⟨c, h₁, h₂⟩ := IHg k _ s'
    exact ⟨_, h₁, h.trans h₂⟩
[GOAL]
f g : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.case f g) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case f g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
rw [stepNormal]
[GOAL]
f g : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg
        ((fun k v =>
            Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v))
          k v)
        b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case f g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
simp only
[GOAL]
f g : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case f g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
obtain ⟨s', h⟩ := pred_ok _ _ s v _ _
[GOAL]
case intro
f g : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s s' : Option Γ'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred ?m.585609 ?m.585610), var := s, stk := elim (trList v) [] ?m.585611 ?m.585612 }
    (Nat.rec { l := some ?m.585609, var := s', stk := elim (trList (List.tail v)) [] ?m.585611 ?m.585612 }
      (fun n x => { l := some ?m.585610, var := s', stk := elim (trList (n :: List.tail v)) [] ?m.585611 ?m.585612 })
      (List.headI v))
⊢ ∃ b₂,
    TrCfg (Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case f g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
revert h
[GOAL]
case intro
f g : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s s' : Option Γ'
⊢ Reaches₁ (TM2.step tr)
      { l := some (Λ'.pred ?m.585609 ?m.585610), var := s, stk := elim (trList v) [] ?m.585611 ?m.585612 }
      (Nat.rec { l := some ?m.585609, var := s', stk := elim (trList (List.tail v)) [] ?m.585611 ?m.585612 }
        (fun n x => { l := some ?m.585610, var := s', stk := elim (trList (n :: List.tail v)) [] ?m.585611 ?m.585612 })
        (List.headI v)) →
    ∃ b₂,
      TrCfg (Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (List.headI v)) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal (Code.case f g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
cases' v.headI with n
[GOAL]
case intro.zero
f g : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s s' : Option Γ'
⊢ Reaches₁ (TM2.step tr)
      { l := some (Λ'.pred ?m.585609 ?m.585610), var := s, stk := elim (trList v) [] ?m.585611 ?m.585612 }
      (Nat.rec { l := some ?m.585609, var := s', stk := elim (trList (List.tail v)) [] ?m.585611 ?m.585612 }
        (fun n x => { l := some ?m.585610, var := s', stk := elim (trList (n :: List.tail v)) [] ?m.585611 ?m.585612 })
        Nat.zero) →
    ∃ b₂,
      TrCfg (Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) Nat.zero) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal (Code.case f g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
intro h
[GOAL]
case intro.succ
f g : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s s' : Option Γ'
n : ℕ
⊢ Reaches₁ (TM2.step tr)
      { l := some (Λ'.pred ?m.585609 ?m.585610), var := s, stk := elim (trList v) [] ?m.585611 ?m.585612 }
      (Nat.rec { l := some ?m.585609, var := s', stk := elim (trList (List.tail v)) [] ?m.585611 ?m.585612 }
        (fun n x => { l := some ?m.585610, var := s', stk := elim (trList (n :: List.tail v)) [] ?m.585611 ?m.585612 })
        (Nat.succ n)) →
    ∃ b₂,
      TrCfg (Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (Nat.succ n)) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal (Code.case f g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
intro h
[GOAL]
case intro.zero
f g : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s s' : Option Γ'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred ?m.585609 ?m.585610), var := s, stk := elim (trList v) [] ?m.585611 ?m.585612 }
    (Nat.rec { l := some ?m.585609, var := s', stk := elim (trList (List.tail v)) [] ?m.585611 ?m.585612 }
      (fun n x => { l := some ?m.585610, var := s', stk := elim (trList (n :: List.tail v)) [] ?m.585611 ?m.585612 })
      Nat.zero)
⊢ ∃ b₂,
    TrCfg (Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) Nat.zero) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case f g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
obtain ⟨c, h₁, h₂⟩ := IHf k _ s'
[GOAL]
case intro.zero.intro.intro
f g : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s s' : Option Γ'
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred ?m.585609 ?m.585610), var := s, stk := elim (trList v) [] ?m.585611 ?m.585612 }
    (Nat.rec { l := some ?m.585609, var := s', stk := elim (trList (List.tail v)) [] ?m.585611 ?m.585612 }
      (fun n x => { l := some ?m.585610, var := s', stk := elim (trList (n :: List.tail v)) [] ?m.585611 ?m.585612 })
      Nat.zero)
c : Cfg'
h₁ : TrCfg (stepNormal f k ?m.585742) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont k)), var := s', stk := elim (trList ?m.585742) [] [] (trContStack k) } c
⊢ ∃ b₂,
    TrCfg (Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) Nat.zero) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case f g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
exact ⟨_, h₁, h.trans h₂⟩
[GOAL]
case intro.succ
f g : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s s' : Option Γ'
n : ℕ
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred (trNormal f (trCont k)) (trNormal g (trCont k))), var := s,
      stk := elim (trList v) [] [] (trContStack k) }
    (Nat.rec { l := some (trNormal f (trCont k)), var := s', stk := elim (trList (List.tail v)) [] [] (trContStack k) }
      (fun n x =>
        { l := some (trNormal g (trCont k)), var := s', stk := elim (trList (n :: List.tail v)) [] [] (trContStack k) })
      (Nat.succ n))
⊢ ∃ b₂,
    TrCfg (Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (Nat.succ n)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case f g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
obtain ⟨c, h₁, h₂⟩ := IHg k _ s'
[GOAL]
case intro.succ.intro.intro
f g : Code
IHf :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
IHg :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal g k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal g (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s s' : Option Γ'
n : ℕ
h :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.pred (trNormal f (trCont k)) (trNormal g (trCont k))), var := s,
      stk := elim (trList v) [] [] (trContStack k) }
    (Nat.rec { l := some (trNormal f (trCont k)), var := s', stk := elim (trList (List.tail v)) [] [] (trContStack k) }
      (fun n x =>
        { l := some (trNormal g (trCont k)), var := s', stk := elim (trList (n :: List.tail v)) [] [] (trContStack k) })
      (Nat.succ n))
c : Cfg'
h₁ : TrCfg (stepNormal g k ?m.585866) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal g (trCont k)), var := s', stk := elim (trList ?m.585866) [] [] (trContStack k) } c
⊢ ∃ b₂,
    TrCfg (Nat.rec (stepNormal f k (List.tail v)) (fun y x => stepNormal g k (y :: List.tail v)) (Nat.succ n)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.case f g) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
exact ⟨_, h₁, h.trans h₂⟩
[GOAL]
case fix
a✝ : Code
a_ih✝ :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal a✝ k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal a✝ (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.fix a✝) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.fix a✝) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case fix f IH => apply IH
[GOAL]
f : Code
IH :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.fix f) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.fix f) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
case fix f IH => apply IH
[GOAL]
f : Code
IH :
  ∀ (k : Cont) (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepNormal f k v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepNormal (Code.fix f) k v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (trNormal (Code.fix f) (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) } b₂
[PROOFSTEP]
apply IH
[GOAL]
k : Cont
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet k v) b₂ ∧
      Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
        b₂
[PROOFSTEP]
induction k generalizing v s
[GOAL]
case halt
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet Cont.halt v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont Cont.halt)), var := s, stk := elim (trList v) [] [] (trContStack Cont.halt) } b₂
case cons₁
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.cons₁ a✝² a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.cons₁ a✝² a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.cons₁ a✝² a✝¹ a✝)) }
        b₂
case cons₂
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.cons₂ a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.cons₂ a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.cons₂ a✝¹ a✝)) }
        b₂
case comp
a✝¹ : Code
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.comp a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.comp a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.comp a✝¹ a✝)) }
        b₂
case fix
a✝¹ : Code
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.fix a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix a✝¹ a✝)) }
        b₂
[PROOFSTEP]
case halt => exact ⟨_, rfl, TransGen.single rfl⟩
[GOAL]
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet Cont.halt v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont Cont.halt)), var := s, stk := elim (trList v) [] [] (trContStack Cont.halt) } b₂
[PROOFSTEP]
case halt => exact ⟨_, rfl, TransGen.single rfl⟩
[GOAL]
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet Cont.halt v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont Cont.halt)), var := s, stk := elim (trList v) [] [] (trContStack Cont.halt) } b₂
[PROOFSTEP]
exact ⟨_, rfl, TransGen.single rfl⟩
[GOAL]
case cons₁
a✝² : Code
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.cons₁ a✝² a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.cons₁ a✝² a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.cons₁ a✝² a✝¹ a✝)) }
        b₂
case cons₂
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.cons₂ a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.cons₂ a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.cons₂ a✝¹ a✝)) }
        b₂
case comp
a✝¹ : Code
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.comp a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.comp a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.comp a✝¹ a✝)) }
        b₂
case fix
a✝¹ : Code
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.fix a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix a✝¹ a✝)) }
        b₂
[PROOFSTEP]
case cons₁ fs as k _ =>
  obtain ⟨s', h₁, h₂⟩ := trNormal_respects fs (Cont.cons₂ v k) as none
  refine' ⟨s', h₁, TransGen.head rfl _⟩; simp
  refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
  simp
  refine' (move₂_ok (by decide) _ _).trans _; pick_goal 4; · rfl
  pick_goal 4;
  · exact splitAtPred_eq _ _ _ (some Γ'.consₗ) _ (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, rfl⟩
  refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
  simp
  exact h₂
[GOAL]
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.cons₁ fs as k) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.cons₁ fs as k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs as k)) }
        b₂
[PROOFSTEP]
case cons₁ fs as k _ =>
  obtain ⟨s', h₁, h₂⟩ := trNormal_respects fs (Cont.cons₂ v k) as none
  refine' ⟨s', h₁, TransGen.head rfl _⟩; simp
  refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
  simp
  refine' (move₂_ok (by decide) _ _).trans _; pick_goal 4; · rfl
  pick_goal 4;
  · exact splitAtPred_eq _ _ _ (some Γ'.consₗ) _ (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, rfl⟩
  refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _; · rfl
  simp
  exact h₂
[GOAL]
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.cons₁ fs as k) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.cons₁ fs as k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs as k)) }
        b₂
[PROOFSTEP]
obtain ⟨s', h₁, h₂⟩ := trNormal_respects fs (Cont.cons₂ v k) as none
[GOAL]
case intro.intro
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.cons₁ fs as k) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.cons₁ fs as k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs as k)) }
        b₂
[PROOFSTEP]
refine' ⟨s', h₁, TransGen.head rfl _⟩
[GOAL]
case intro.intro
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    (TM2.stepAux (tr (Λ'.ret (trCont (Cont.cons₁ fs as k)))) s
      (elim (trList v) [] [] (trContStack (Cont.cons₁ fs as k))))
    s'
[PROOFSTEP]
simp
[GOAL]
case intro.intro
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    {
      l :=
        some
          (move₂ (fun x => false) main aux
            (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
              (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ (trCont k)))))),
      var := s, stk := elim (trList v) [] [] (trContStack (Cont.cons₁ fs as k)) }
    s'
[PROOFSTEP]
refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _
[GOAL]
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ main ≠ rev ∧ aux ≠ rev ∧ main ≠ aux
[PROOFSTEP]
decide
[GOAL]
case intro.intro.refine'_1
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ elim (trList v) [] [] (trContStack (Cont.cons₁ fs as k)) rev = []
[PROOFSTEP]
rfl
[GOAL]
case intro.intro.refine'_2
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    {
      l :=
        some
          (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
            (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ (trCont k))))),
      var := none,
      stk :=
        update
          (update (elim (trList v) [] [] (trContStack (Cont.cons₁ fs as k))) main (Option.elim none id List.cons []))
          aux
          (elim (trList v) [] [] (trContStack (Cont.cons₁ fs as k)) main ++
            elim (trList v) [] [] (trContStack (Cont.cons₁ fs as k)) aux) }
    s'
[PROOFSTEP]
simp
[GOAL]
case intro.intro.refine'_2
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    {
      l :=
        some
          (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
            (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ (trCont k))))),
      var := none, stk := elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k)) }
    s'
[PROOFSTEP]
refine' (move₂_ok (by decide) _ _).trans _
[GOAL]
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ stack ≠ rev ∧ main ≠ rev ∧ stack ≠ main
[PROOFSTEP]
decide
[GOAL]
case intro.intro.refine'_2.refine'_1
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ List Γ'
case intro.intro.refine'_2.refine'_2
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ Option Γ'
case intro.intro.refine'_2.refine'_3
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ List Γ'
case intro.intro.refine'_2.refine'_4
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k)) rev = []
case intro.intro.refine'_2.refine'_5
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ splitAtPred (fun s => decide (s = Γ'.consₗ)) (elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k)) stack) =
    (?intro.intro.refine'_2.refine'_1, ?intro.intro.refine'_2.refine'_2, ?intro.intro.refine'_2.refine'_3)
case intro.intro.refine'_2.refine'_6
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    { l := some (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ (trCont k)))), var := none,
      stk :=
        update
          (update (elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k))) stack
            (Option.elim ?intro.intro.refine'_2.refine'_2 id List.cons ?intro.intro.refine'_2.refine'_3))
          main (?intro.intro.refine'_2.refine'_1 ++ elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k)) main) }
    s'
[PROOFSTEP]
pick_goal 4
[GOAL]
case intro.intro.refine'_2.refine'_4
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k)) rev = []
[PROOFSTEP]
rfl
[GOAL]
case intro.intro.refine'_2.refine'_1
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ List Γ'
case intro.intro.refine'_2.refine'_2
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ Option Γ'
case intro.intro.refine'_2.refine'_3
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ List Γ'
case intro.intro.refine'_2.refine'_5
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ splitAtPred (fun s => decide (s = Γ'.consₗ)) (elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k)) stack) =
    (?intro.intro.refine'_2.refine'_1, ?intro.intro.refine'_2.refine'_2, ?intro.intro.refine'_2.refine'_3)
case intro.intro.refine'_2.refine'_6
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    { l := some (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ (trCont k)))), var := none,
      stk :=
        update
          (update (elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k))) stack
            (Option.elim ?intro.intro.refine'_2.refine'_2 id List.cons ?intro.intro.refine'_2.refine'_3))
          main (?intro.intro.refine'_2.refine'_1 ++ elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k)) main) }
    s'
[PROOFSTEP]
pick_goal 4
[GOAL]
case intro.intro.refine'_2.refine'_5
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ splitAtPred (fun s => decide (s = Γ'.consₗ)) (elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k)) stack) =
    (?intro.intro.refine'_2.refine'_1, ?intro.intro.refine'_2.refine'_2, ?intro.intro.refine'_2.refine'_3)
[PROOFSTEP]
exact splitAtPred_eq _ _ _ (some Γ'.consₗ) _ (fun x h => Bool.decide_false (trList_ne_consₗ _ _ h)) ⟨rfl, rfl⟩
[GOAL]
case intro.intro.refine'_2.refine'_6
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    { l := some (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ (trCont k)))), var := none,
      stk :=
        update
          (update (elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k))) stack
            (Option.elim (some Γ'.consₗ) id List.cons (trLList (contStack k))))
          main (trList as ++ elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k)) main) }
    s'
[PROOFSTEP]
refine' (move₂_ok (by decide) _ (splitAtPred_false _)).trans _
[GOAL]
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ aux ≠ rev ∧ stack ≠ rev ∧ aux ≠ stack
[PROOFSTEP]
decide
[GOAL]
case intro.intro.refine'_2.refine'_6.refine'_1
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ update
      (update (elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k))) stack
        (Option.elim (some Γ'.consₗ) id List.cons (trLList (contStack k))))
      main (trList as ++ elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k)) main) rev =
    []
[PROOFSTEP]
rfl
[GOAL]
case intro.intro.refine'_2.refine'_6.refine'_2
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    { l := some (trNormal fs (Cont'.cons₂ (trCont k))), var := none,
      stk :=
        update
          (update
            (update
              (update (elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k))) stack
                (Option.elim (some Γ'.consₗ) id List.cons (trLList (contStack k))))
              main (trList as ++ elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k)) main))
            aux (Option.elim none id List.cons []))
          stack
          (update
              (update (elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k))) stack
                (Option.elim (some Γ'.consₗ) id List.cons (trLList (contStack k))))
              main (trList as ++ elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k)) main) aux ++
            update
              (update (elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k))) stack
                (Option.elim (some Γ'.consₗ) id List.cons (trLList (contStack k))))
              main (trList as ++ elim [] [] (trList v) (trContStack (Cont.cons₁ fs as k)) main) stack) }
    s'
[PROOFSTEP]
simp
[GOAL]
case intro.intro.refine'_2.refine'_6.refine'_2
fs : Code
as : List ℕ
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal fs (Cont.cons₂ v k) as) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal fs (trCont (Cont.cons₂ v k))), var := none,
      stk := elim (trList as) [] [] (trContStack (Cont.cons₂ v k)) }
    s'
⊢ TransGen
    (fun a b =>
      (match a with
        | { l := none, var := var, stk := stk } => none
        | { l := some l, var := v, stk := S } => some (TM2.stepAux (tr l) v S)) =
        some b)
    { l := some (trNormal fs (Cont'.cons₂ (trCont k))), var := none,
      stk := elim (trList as) [] [] (trList v ++ Γ'.consₗ :: trLList (contStack k)) }
    s'
[PROOFSTEP]
exact h₂
[GOAL]
case cons₂
a✝¹ : List ℕ
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.cons₂ a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.cons₂ a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.cons₂ a✝¹ a✝)) }
        b₂
case comp
a✝¹ : Code
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.comp a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.comp a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.comp a✝¹ a✝)) }
        b₂
case fix
a✝¹ : Code
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.fix a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix a✝¹ a✝)) }
        b₂
[PROOFSTEP]
case cons₂ ns k IH =>
  obtain ⟨c, h₁, h₂⟩ := IH (ns.headI :: v) none
  exact ⟨c, h₁, TransGen.head rfl <| head_stack_ok.trans h₂⟩
[GOAL]
ns : List ℕ
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.cons₂ ns k) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.cons₂ ns k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.cons₂ ns k)) }
        b₂
[PROOFSTEP]
case cons₂ ns k IH =>
  obtain ⟨c, h₁, h₂⟩ := IH (ns.headI :: v) none
  exact ⟨c, h₁, TransGen.head rfl <| head_stack_ok.trans h₂⟩
[GOAL]
ns : List ℕ
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.cons₂ ns k) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.cons₂ ns k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.cons₂ ns k)) }
        b₂
[PROOFSTEP]
obtain ⟨c, h₁, h₂⟩ := IH (ns.headI :: v) none
[GOAL]
case intro.intro
ns : List ℕ
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
c : Cfg'
h₁ : TrCfg (stepRet k (List.headI ns :: v)) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.ret (trCont k)), var := none, stk := elim (trList (List.headI ns :: v)) [] [] (trContStack k) } c
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.cons₂ ns k) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.cons₂ ns k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.cons₂ ns k)) }
        b₂
[PROOFSTEP]
exact ⟨c, h₁, TransGen.head rfl <| head_stack_ok.trans h₂⟩
[GOAL]
case comp
a✝¹ : Code
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.comp a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.comp a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.comp a✝¹ a✝)) }
        b₂
case fix
a✝¹ : Code
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.fix a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix a✝¹ a✝)) }
        b₂
[PROOFSTEP]
case comp f k _ =>
  obtain ⟨s', h₁, h₂⟩ := trNormal_respects f k v s
  exact ⟨_, h₁, TransGen.head rfl h₂⟩
[GOAL]
f : Code
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.comp f k) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.comp f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.comp f k)) }
        b₂
[PROOFSTEP]
case comp f k _ =>
  obtain ⟨s', h₁, h₂⟩ := trNormal_respects f k v s
  exact ⟨_, h₁, TransGen.head rfl h₂⟩
[GOAL]
f : Code
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.comp f k) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.comp f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.comp f k)) }
        b₂
[PROOFSTEP]
obtain ⟨s', h₁, h₂⟩ := trNormal_respects f k v s
[GOAL]
case intro.intro
f : Code
k : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
s' : Cfg'
h₁ : TrCfg (stepNormal f k v) s'
h₂ :
  Reaches₁ (TM2.step tr) { l := some (trNormal f (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
    s'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.comp f k) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.comp f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.comp f k)) }
        b₂
[PROOFSTEP]
exact ⟨_, h₁, TransGen.head rfl h₂⟩
[GOAL]
case fix
a✝¹ : Code
a✝ : Cont
a_ih✝ :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet a✝ v) b₂ ∧
        Reaches₁ (TM2.step tr)
          { l := some (Λ'.ret (trCont a✝)), var := s, stk := elim (trList v) [] [] (trContStack a✝) } b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.fix a✝¹ a✝) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix a✝¹ a✝))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix a✝¹ a✝)) }
        b₂
[PROOFSTEP]
case fix f k IH =>
  rw [stepRet]
  have :
    if v.headI = 0 then natEnd (trList v).head?.iget = true ∧ (trList v).tail = trList v.tail
    else natEnd (trList v).head?.iget = false ∧ (trList v).tail = (trNat v.headI).tail ++ Γ'.cons :: trList v.tail :=
    by
    cases' v with n
    · exact ⟨rfl, rfl⟩
    cases' n with n
    · simp
    rw [trList, List.headI, trNat, Nat.cast_succ, Num.add_one, Num.succ, List.tail]
    cases (n : Num).succ' <;> exact ⟨rfl, rfl⟩
  by_cases v.headI = 0 <;> simp only [h, ite_true, ite_false] at this ⊢
  · obtain ⟨c, h₁, h₂⟩ := IH v.tail (trList v).head?
    refine' ⟨c, h₁, TransGen.head rfl _⟩
    simp [trCont, trContStack, this, -TM2.step, -natEnd]
    exact h₂
  · obtain ⟨s', h₁, h₂⟩ := trNormal_respects f (Cont.fix f k) v.tail (some Γ'.cons)
    refine' ⟨_, h₁, TransGen.head rfl <| TransGen.trans _ h₂⟩
    simp [trCont, this.1, -TM2.step, -natEnd]
    convert clear_ok (splitAtPred_eq _ _ (trNat v.headI).tail (some Γ'.cons) _ _ _) using 2
    · simp
      convert rfl
    · exact fun x h => trNat_natEnd _ _ (List.tail_subset _ h)
    · exact ⟨rfl, this.2⟩
[GOAL]
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.fix f k) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂
[PROOFSTEP]
case fix f k IH =>
  rw [stepRet]
  have :
    if v.headI = 0 then natEnd (trList v).head?.iget = true ∧ (trList v).tail = trList v.tail
    else natEnd (trList v).head?.iget = false ∧ (trList v).tail = (trNat v.headI).tail ++ Γ'.cons :: trList v.tail :=
    by
    cases' v with n
    · exact ⟨rfl, rfl⟩
    cases' n with n
    · simp
    rw [trList, List.headI, trNat, Nat.cast_succ, Num.add_one, Num.succ, List.tail]
    cases (n : Num).succ' <;> exact ⟨rfl, rfl⟩
  by_cases v.headI = 0 <;> simp only [h, ite_true, ite_false] at this ⊢
  · obtain ⟨c, h₁, h₂⟩ := IH v.tail (trList v).head?
    refine' ⟨c, h₁, TransGen.head rfl _⟩
    simp [trCont, trContStack, this, -TM2.step, -natEnd]
    exact h₂
  · obtain ⟨s', h₁, h₂⟩ := trNormal_respects f (Cont.fix f k) v.tail (some Γ'.cons)
    refine' ⟨_, h₁, TransGen.head rfl <| TransGen.trans _ h₂⟩
    simp [trCont, this.1, -TM2.step, -natEnd]
    convert clear_ok (splitAtPred_eq _ _ (trNat v.headI).tail (some Γ'.cons) _ _ _) using 2
    · simp
      convert rfl
    · exact fun x h => trNat_natEnd _ _ (List.tail_subset _ h)
    · exact ⟨rfl, this.2⟩
[GOAL]
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (stepRet (Cont.fix f k) v) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂
[PROOFSTEP]
rw [stepRet]
[GOAL]
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
⊢ ∃ b₂,
    TrCfg (if List.headI v = 0 then stepRet k (List.tail v) else stepNormal f (Cont.fix f k) (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂
[PROOFSTEP]
have :
  if v.headI = 0 then natEnd (trList v).head?.iget = true ∧ (trList v).tail = trList v.tail
  else natEnd (trList v).head?.iget = false ∧ (trList v).tail = (trNat v.headI).tail ++ Γ'.cons :: trList v.tail :=
  by
  cases' v with n
  · exact ⟨rfl, rfl⟩
  cases' n with n
  · simp
  rw [trList, List.headI, trNat, Nat.cast_succ, Num.add_one, Num.succ, List.tail]
  cases (n : Num).succ' <;> exact ⟨rfl, rfl⟩
[GOAL]
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
⊢ if List.headI v = 0 then
    natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
  else
    natEnd (Option.iget (List.head? (trList v))) = false ∧
      List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
[PROOFSTEP]
cases' v with n
[GOAL]
case nil
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
s : Option Γ'
⊢ if List.headI [] = 0 then
    natEnd (Option.iget (List.head? (trList []))) = true ∧ List.tail (trList []) = trList (List.tail [])
  else
    natEnd (Option.iget (List.head? (trList []))) = false ∧
      List.tail (trList []) = List.tail (trNat (List.headI [])) ++ Γ'.cons :: trList (List.tail [])
[PROOFSTEP]
exact ⟨rfl, rfl⟩
[GOAL]
case cons
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
s : Option Γ'
n : ℕ
tail✝ : List ℕ
⊢ if List.headI (n :: tail✝) = 0 then
    natEnd (Option.iget (List.head? (trList (n :: tail✝)))) = true ∧
      List.tail (trList (n :: tail✝)) = trList (List.tail (n :: tail✝))
  else
    natEnd (Option.iget (List.head? (trList (n :: tail✝)))) = false ∧
      List.tail (trList (n :: tail✝)) =
        List.tail (trNat (List.headI (n :: tail✝))) ++ Γ'.cons :: trList (List.tail (n :: tail✝))
[PROOFSTEP]
cases' n with n
[GOAL]
case cons.zero
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
s : Option Γ'
tail✝ : List ℕ
⊢ if List.headI (Nat.zero :: tail✝) = 0 then
    natEnd (Option.iget (List.head? (trList (Nat.zero :: tail✝)))) = true ∧
      List.tail (trList (Nat.zero :: tail✝)) = trList (List.tail (Nat.zero :: tail✝))
  else
    natEnd (Option.iget (List.head? (trList (Nat.zero :: tail✝)))) = false ∧
      List.tail (trList (Nat.zero :: tail✝)) =
        List.tail (trNat (List.headI (Nat.zero :: tail✝))) ++ Γ'.cons :: trList (List.tail (Nat.zero :: tail✝))
[PROOFSTEP]
simp
[GOAL]
case cons.succ
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
s : Option Γ'
tail✝ : List ℕ
n : ℕ
⊢ if List.headI (Nat.succ n :: tail✝) = 0 then
    natEnd (Option.iget (List.head? (trList (Nat.succ n :: tail✝)))) = true ∧
      List.tail (trList (Nat.succ n :: tail✝)) = trList (List.tail (Nat.succ n :: tail✝))
  else
    natEnd (Option.iget (List.head? (trList (Nat.succ n :: tail✝)))) = false ∧
      List.tail (trList (Nat.succ n :: tail✝)) =
        List.tail (trNat (List.headI (Nat.succ n :: tail✝))) ++ Γ'.cons :: trList (List.tail (Nat.succ n :: tail✝))
[PROOFSTEP]
rw [trList, List.headI, trNat, Nat.cast_succ, Num.add_one, Num.succ, List.tail]
[GOAL]
case cons.succ
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
s : Option Γ'
tail✝ : List ℕ
n : ℕ
⊢ if
      (match Nat.succ n :: tail✝ with
        | [] => default
        | a :: tail => a) =
        0 then
    natEnd (Option.iget (List.head? (trNum (Num.pos (Num.succ' ↑n)) ++ Γ'.cons :: trList tail✝))) = true ∧
      (match trNum (Num.pos (Num.succ' ↑n)) ++ Γ'.cons :: trList tail✝ with
        | [] => []
        | head :: as => as) =
        trList (List.tail (Nat.succ n :: tail✝))
  else
    natEnd (Option.iget (List.head? (trNum (Num.pos (Num.succ' ↑n)) ++ Γ'.cons :: trList tail✝))) = false ∧
      (match trNum (Num.pos (Num.succ' ↑n)) ++ Γ'.cons :: trList tail✝ with
        | [] => []
        | head :: as => as) =
        List.tail (trNum (Num.pos (Num.succ' ↑n))) ++ Γ'.cons :: trList (List.tail (Nat.succ n :: tail✝))
[PROOFSTEP]
cases (n : Num).succ'
[GOAL]
case cons.succ.one
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
s : Option Γ'
tail✝ : List ℕ
n : ℕ
⊢ if
      (match Nat.succ n :: tail✝ with
        | [] => default
        | a :: tail => a) =
        0 then
    natEnd (Option.iget (List.head? (trNum (Num.pos PosNum.one) ++ Γ'.cons :: trList tail✝))) = true ∧
      (match trNum (Num.pos PosNum.one) ++ Γ'.cons :: trList tail✝ with
        | [] => []
        | head :: as => as) =
        trList (List.tail (Nat.succ n :: tail✝))
  else
    natEnd (Option.iget (List.head? (trNum (Num.pos PosNum.one) ++ Γ'.cons :: trList tail✝))) = false ∧
      (match trNum (Num.pos PosNum.one) ++ Γ'.cons :: trList tail✝ with
        | [] => []
        | head :: as => as) =
        List.tail (trNum (Num.pos PosNum.one)) ++ Γ'.cons :: trList (List.tail (Nat.succ n :: tail✝))
[PROOFSTEP]
exact ⟨rfl, rfl⟩
[GOAL]
case cons.succ.bit1
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
s : Option Γ'
tail✝ : List ℕ
n : ℕ
a✝ : PosNum
⊢ if
      (match Nat.succ n :: tail✝ with
        | [] => default
        | a :: tail => a) =
        0 then
    natEnd (Option.iget (List.head? (trNum (Num.pos (PosNum.bit1 a✝)) ++ Γ'.cons :: trList tail✝))) = true ∧
      (match trNum (Num.pos (PosNum.bit1 a✝)) ++ Γ'.cons :: trList tail✝ with
        | [] => []
        | head :: as => as) =
        trList (List.tail (Nat.succ n :: tail✝))
  else
    natEnd (Option.iget (List.head? (trNum (Num.pos (PosNum.bit1 a✝)) ++ Γ'.cons :: trList tail✝))) = false ∧
      (match trNum (Num.pos (PosNum.bit1 a✝)) ++ Γ'.cons :: trList tail✝ with
        | [] => []
        | head :: as => as) =
        List.tail (trNum (Num.pos (PosNum.bit1 a✝))) ++ Γ'.cons :: trList (List.tail (Nat.succ n :: tail✝))
[PROOFSTEP]
exact ⟨rfl, rfl⟩
[GOAL]
case cons.succ.bit0
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
s : Option Γ'
tail✝ : List ℕ
n : ℕ
a✝ : PosNum
⊢ if
      (match Nat.succ n :: tail✝ with
        | [] => default
        | a :: tail => a) =
        0 then
    natEnd (Option.iget (List.head? (trNum (Num.pos (PosNum.bit0 a✝)) ++ Γ'.cons :: trList tail✝))) = true ∧
      (match trNum (Num.pos (PosNum.bit0 a✝)) ++ Γ'.cons :: trList tail✝ with
        | [] => []
        | head :: as => as) =
        trList (List.tail (Nat.succ n :: tail✝))
  else
    natEnd (Option.iget (List.head? (trNum (Num.pos (PosNum.bit0 a✝)) ++ Γ'.cons :: trList tail✝))) = false ∧
      (match trNum (Num.pos (PosNum.bit0 a✝)) ++ Γ'.cons :: trList tail✝ with
        | [] => []
        | head :: as => as) =
        List.tail (trNum (Num.pos (PosNum.bit0 a✝))) ++ Γ'.cons :: trList (List.tail (Nat.succ n :: tail✝))
[PROOFSTEP]
exact ⟨rfl, rfl⟩
[GOAL]
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
this :
  if List.headI v = 0 then
    natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
  else
    natEnd (Option.iget (List.head? (trList v))) = false ∧
      List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
⊢ ∃ b₂,
    TrCfg (if List.headI v = 0 then stepRet k (List.tail v) else stepNormal f (Cont.fix f k) (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂
[PROOFSTEP]
by_cases v.headI = 0
[GOAL]
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
this :
  if List.headI v = 0 then
    natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
  else
    natEnd (Option.iget (List.head? (trList v))) = false ∧
      List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
⊢ ∃ b₂,
    TrCfg (if List.headI v = 0 then stepRet k (List.tail v) else stepNormal f (Cont.fix f k) (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂
[PROOFSTEP]
by_cases v.headI = 0
[GOAL]
case pos
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
this :
  if List.headI v = 0 then
    natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
  else
    natEnd (Option.iget (List.head? (trList v))) = false ∧
      List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
h : List.headI v = 0
⊢ ∃ b₂,
    TrCfg (if List.headI v = 0 then stepRet k (List.tail v) else stepNormal f (Cont.fix f k) (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂
[PROOFSTEP]
simp only [h, ite_true, ite_false] at this ⊢
[GOAL]
case neg
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
this :
  if List.headI v = 0 then
    natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
  else
    natEnd (Option.iget (List.head? (trList v))) = false ∧
      List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
h : ¬List.headI v = 0
⊢ ∃ b₂,
    TrCfg (if List.headI v = 0 then stepRet k (List.tail v) else stepNormal f (Cont.fix f k) (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂
[PROOFSTEP]
simp only [h, ite_true, ite_false] at this ⊢
[GOAL]
case pos
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : List.headI v = 0
this : natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
⊢ ∃ b₂,
    TrCfg (stepRet k (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂
[PROOFSTEP]
obtain ⟨c, h₁, h₂⟩ := IH v.tail (trList v).head?
[GOAL]
case pos.intro.intro
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : List.headI v = 0
this : natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
c : Cfg'
h₁ : TrCfg (stepRet k (List.tail v)) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.ret (trCont k)), var := List.head? (trList v),
      stk := elim (trList (List.tail v)) [] [] (trContStack k) }
    c
⊢ ∃ b₂,
    TrCfg (stepRet k (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂
[PROOFSTEP]
refine' ⟨c, h₁, TransGen.head rfl _⟩
[GOAL]
case pos.intro.intro
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : List.headI v = 0
this : natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
c : Cfg'
h₁ : TrCfg (stepRet k (List.tail v)) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.ret (trCont k)), var := List.head? (trList v),
      stk := elim (trList (List.tail v)) [] [] (trContStack k) }
    c
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    (TM2.stepAux (tr (Λ'.ret (trCont (Cont.fix f k)))) s (elim (trList v) [] [] (trContStack (Cont.fix f k)))) c
[PROOFSTEP]
simp [trCont, trContStack, this, -TM2.step, -natEnd]
[GOAL]
case pos.intro.intro
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : List.headI v = 0
this : natEnd (Option.iget (List.head? (trList v))) = true ∧ List.tail (trList v) = trList (List.tail v)
c : Cfg'
h₁ : TrCfg (stepRet k (List.tail v)) c
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (Λ'.ret (trCont k)), var := List.head? (trList v),
      stk := elim (trList (List.tail v)) [] [] (trContStack k) }
    c
⊢ TransGen (fun a b => TM2.step tr a = some b)
    { l := some (Λ'.ret (trCont k)), var := List.head? (trList v),
      stk := elim (trList (List.tail v)) [] [] (trLList (contStack k)) }
    c
[PROOFSTEP]
exact h₂
[GOAL]
case neg
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : ¬List.headI v = 0
this :
  natEnd (Option.iget (List.head? (trList v))) = false ∧
    List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
⊢ ∃ b₂,
    TrCfg (stepNormal f (Cont.fix f k) (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂
[PROOFSTEP]
obtain ⟨s', h₁, h₂⟩ := trNormal_respects f (Cont.fix f k) v.tail (some Γ'.cons)
[GOAL]
case neg.intro.intro
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : ¬List.headI v = 0
this :
  natEnd (Option.iget (List.head? (trList v))) = false ∧
    List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
s' : Cfg'
h₁ : TrCfg (stepNormal f (Cont.fix f k) (List.tail v)) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.fix f k))), var := some Γ'.cons,
      stk := elim (trList (List.tail v)) [] [] (trContStack (Cont.fix f k)) }
    s'
⊢ ∃ b₂,
    TrCfg (stepNormal f (Cont.fix f k) (List.tail v)) b₂ ∧
      Reaches₁ (TM2.step tr)
        { l := some (Λ'.ret (trCont (Cont.fix f k))), var := s,
          stk := elim (trList v) [] [] (trContStack (Cont.fix f k)) }
        b₂
[PROOFSTEP]
refine' ⟨_, h₁, TransGen.head rfl <| TransGen.trans _ h₂⟩
[GOAL]
case neg.intro.intro
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : ¬List.headI v = 0
this :
  natEnd (Option.iget (List.head? (trList v))) = false ∧
    List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
s' : Cfg'
h₁ : TrCfg (stepNormal f (Cont.fix f k) (List.tail v)) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.fix f k))), var := some Γ'.cons,
      stk := elim (trList (List.tail v)) [] [] (trContStack (Cont.fix f k)) }
    s'
⊢ TransGen (fun a b => b ∈ TM2.step tr a)
    (TM2.stepAux (tr (Λ'.ret (trCont (Cont.fix f k)))) s (elim (trList v) [] [] (trContStack (Cont.fix f k))))
    { l := some (trNormal f (trCont (Cont.fix f k))), var := some Γ'.cons,
      stk := elim (trList (List.tail v)) [] [] (trContStack (Cont.fix f k)) }
[PROOFSTEP]
simp [trCont, this.1, -TM2.step, -natEnd]
[GOAL]
case neg.intro.intro
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : ¬List.headI v = 0
this :
  natEnd (Option.iget (List.head? (trList v))) = false ∧
    List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
s' : Cfg'
h₁ : TrCfg (stepNormal f (Cont.fix f k) (List.tail v)) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.fix f k))), var := some Γ'.cons,
      stk := elim (trList (List.tail v)) [] [] (trContStack (Cont.fix f k)) }
    s'
⊢ TransGen (fun a b => TM2.step tr a = some b)
    { l := some (Λ'.clear natEnd main (trNormal f (Cont'.fix f (trCont k)))), var := List.head? (trList v),
      stk := elim (List.tail (trList v)) [] [] (trContStack (Cont.fix f k)) }
    { l := some (trNormal f (Cont'.fix f (trCont k))), var := some Γ'.cons,
      stk := elim (trList (List.tail v)) [] [] (trContStack (Cont.fix f k)) }
[PROOFSTEP]
convert clear_ok (splitAtPred_eq _ _ (trNat v.headI).tail (some Γ'.cons) _ _ _) using 2
[GOAL]
case h.e'_2.h.e'_7
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : ¬List.headI v = 0
this :
  natEnd (Option.iget (List.head? (trList v))) = false ∧
    List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
s' : Cfg'
h₁ : TrCfg (stepNormal f (Cont.fix f k) (List.tail v)) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.fix f k))), var := some Γ'.cons,
      stk := elim (trList (List.tail v)) [] [] (trContStack (Cont.fix f k)) }
    s'
⊢ elim (trList (List.tail v)) [] [] (trContStack (Cont.fix f k)) =
    update (elim (List.tail (trList v)) [] [] (trContStack (Cont.fix f k))) main ?neg.intro.intro.convert_6✝
[PROOFSTEP]
simp
[GOAL]
case h.e'_2.h.e'_7
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : ¬List.headI v = 0
this :
  natEnd (Option.iget (List.head? (trList v))) = false ∧
    List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
s' : Cfg'
h₁ : TrCfg (stepNormal f (Cont.fix f k) (List.tail v)) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.fix f k))), var := some Γ'.cons,
      stk := elim (trList (List.tail v)) [] [] (trContStack (Cont.fix f k)) }
    s'
⊢ elim (trList (List.tail v)) [] [] (trContStack (Cont.fix f k)) =
    elim ?neg.intro.intro.convert_6✝ [] [] (trContStack (Cont.fix f k))
[PROOFSTEP]
convert rfl
[GOAL]
case neg.intro.intro.convert_7
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : ¬List.headI v = 0
this :
  natEnd (Option.iget (List.head? (trList v))) = false ∧
    List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
s' : Cfg'
h₁ : TrCfg (stepNormal f (Cont.fix f k) (List.tail v)) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.fix f k))), var := some Γ'.cons,
      stk := elim (trList (List.tail v)) [] [] (trContStack (Cont.fix f k)) }
    s'
⊢ ∀ (x : Γ'), x ∈ List.tail (trNat (List.headI v)) → natEnd x = false
[PROOFSTEP]
exact fun x h => trNat_natEnd _ _ (List.tail_subset _ h)
[GOAL]
case neg.intro.intro.convert_8
f : Code
k : Cont
IH :
  ∀ (v : List ℕ) (s : Option Γ'),
    ∃ b₂,
      TrCfg (stepRet k v) b₂ ∧
        Reaches₁ (TM2.step tr) { l := some (Λ'.ret (trCont k)), var := s, stk := elim (trList v) [] [] (trContStack k) }
          b₂
v : List ℕ
s : Option Γ'
h : ¬List.headI v = 0
this :
  natEnd (Option.iget (List.head? (trList v))) = false ∧
    List.tail (trList v) = List.tail (trNat (List.headI v)) ++ Γ'.cons :: trList (List.tail v)
s' : Cfg'
h₁ : TrCfg (stepNormal f (Cont.fix f k) (List.tail v)) s'
h₂ :
  Reaches₁ (TM2.step tr)
    { l := some (trNormal f (trCont (Cont.fix f k))), var := some Γ'.cons,
      stk := elim (trList (List.tail v)) [] [] (trContStack (Cont.fix f k)) }
    s'
⊢ Option.elim'
    (elim (List.tail (trList v)) [] [] (trContStack (Cont.fix f k)) main = List.tail (trNat (List.headI v)) ∧
      trList (List.tail v) = [])
    (fun a =>
      natEnd a = true ∧
        elim (List.tail (trList v)) [] [] (trContStack (Cont.fix f k)) main =
          List.tail (trNat (List.headI v)) ++ a :: trList (List.tail v))
    (some Γ'.cons)
[PROOFSTEP]
exact ⟨rfl, this.2⟩
[GOAL]
c : Code
v : List ℕ
⊢ eval (TM2.step tr) (init c v) = halt <$> Code.eval c v
[PROOFSTEP]
obtain ⟨i, h₁, h₂⟩ := tr_init c v
[GOAL]
case intro.intro
c : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c v) i
⊢ eval (TM2.step tr) (init c v) = halt <$> Code.eval c v
[PROOFSTEP]
refine' Part.ext fun x => _
[GOAL]
case intro.intro
c : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c v) i
x : TM2.Cfg (fun x => Γ') Λ' (Option Γ')
⊢ x ∈ eval (TM2.step tr) (init c v) ↔ x ∈ halt <$> Code.eval c v
[PROOFSTEP]
rw [reaches_eval h₂.to_reflTransGen]
[GOAL]
case intro.intro
c : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c v) i
x : TM2.Cfg (fun x => Γ') Λ' (Option Γ')
⊢ x ∈ eval (fun a => TM2.step tr a) i ↔ x ∈ halt <$> Code.eval c v
[PROOFSTEP]
simp [-TM2.step]
[GOAL]
case intro.intro
c : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c v) i
x : TM2.Cfg (fun x => Γ') Λ' (Option Γ')
⊢ x ∈ eval (fun a => TM2.step tr a) i ↔ ∃ a, a ∈ Code.eval c v ∧ halt a = x
[PROOFSTEP]
refine' ⟨fun h => _, _⟩
[GOAL]
case intro.intro.refine'_1
c : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c v) i
x : TM2.Cfg (fun x => Γ') Λ' (Option Γ')
h : x ∈ eval (fun a => TM2.step tr a) i
⊢ ∃ a, a ∈ Code.eval c v ∧ halt a = x
[PROOFSTEP]
obtain ⟨c, hc₁, hc₂⟩ := tr_eval_rev tr_respects h₁ h
[GOAL]
case intro.intro.refine'_1.intro.intro
c✝ : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c✝ Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c✝ v) i
x : TM2.Cfg (fun x => Γ') Λ' (Option Γ')
h : x ∈ eval (fun a => TM2.step tr a) i
c : Cfg
hc₁ : TrCfg c x
hc₂ : c ∈ eval step (stepNormal c✝ Cont.halt v)
⊢ ∃ a, a ∈ Code.eval c✝ v ∧ halt a = x
[PROOFSTEP]
simp [stepNormal_eval] at hc₂
[GOAL]
case intro.intro.refine'_1.intro.intro
c✝ : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c✝ Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c✝ v) i
x : TM2.Cfg (fun x => Γ') Λ' (Option Γ')
h : x ∈ eval (fun a => TM2.step tr a) i
c : Cfg
hc₁ : TrCfg c x
hc₂ : ∃ a, a ∈ Code.eval c✝ v ∧ Cfg.halt a = c
⊢ ∃ a, a ∈ Code.eval c✝ v ∧ halt a = x
[PROOFSTEP]
obtain ⟨v', hv, rfl⟩ := hc₂
[GOAL]
case intro.intro.refine'_1.intro.intro.intro.intro
c : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c v) i
x : TM2.Cfg (fun x => Γ') Λ' (Option Γ')
h : x ∈ eval (fun a => TM2.step tr a) i
v' : List ℕ
hv : v' ∈ Code.eval c v
hc₁ : TrCfg (Cfg.halt v') x
⊢ ∃ a, a ∈ Code.eval c v ∧ halt a = x
[PROOFSTEP]
exact ⟨_, hv, hc₁.symm⟩
[GOAL]
case intro.intro.refine'_2
c : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c v) i
x : TM2.Cfg (fun x => Γ') Λ' (Option Γ')
⊢ (∃ a, a ∈ Code.eval c v ∧ halt a = x) → x ∈ eval (fun a => TM2.step tr a) i
[PROOFSTEP]
rintro ⟨v', hv, rfl⟩
[GOAL]
case intro.intro.refine'_2.intro.intro
c : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c v) i
v' : List ℕ
hv : v' ∈ Code.eval c v
⊢ halt v' ∈ eval (fun a => TM2.step tr a) i
[PROOFSTEP]
have := Turing.tr_eval (b₁ := Cfg.halt v') tr_respects h₁
[GOAL]
case intro.intro.refine'_2.intro.intro
c : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c v) i
v' : List ℕ
hv : v' ∈ Code.eval c v
this : Cfg.halt v' ∈ eval step (stepNormal c Cont.halt v) → ∃ b₂, TrCfg (Cfg.halt v') b₂ ∧ b₂ ∈ eval (TM2.step tr) i
⊢ halt v' ∈ eval (fun a => TM2.step tr a) i
[PROOFSTEP]
simp [stepNormal_eval, -TM2.step] at this
[GOAL]
case intro.intro.refine'_2.intro.intro
c : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c v) i
v' : List ℕ
hv : v' ∈ Code.eval c v
this : v' ∈ Code.eval c v → ∃ b₂, TrCfg (Cfg.halt v') b₂ ∧ b₂ ∈ eval (TM2.step tr) i
⊢ halt v' ∈ eval (fun a => TM2.step tr a) i
[PROOFSTEP]
obtain ⟨_, ⟨⟩, h⟩ := this hv
[GOAL]
case intro.intro.refine'_2.intro.intro.intro.intro.refl
c : Code
v : List ℕ
i : Cfg'
h₁ : TrCfg (stepNormal c Cont.halt v) i
h₂ : Reaches₁ (TM2.step tr) (init c v) i
v' : List ℕ
hv : v' ∈ Code.eval c v
this : v' ∈ Code.eval c v → ∃ b₂, TrCfg (Cfg.halt v') b₂ ∧ b₂ ∈ eval (TM2.step tr) i
h : halt v' ∈ eval (TM2.step tr) i
⊢ halt v' ∈ eval (fun a => TM2.step tr a) i
[PROOFSTEP]
exact h
[GOAL]
q q' : Λ'
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
[PROOFSTEP]
induction' q with _ _ _ q q_ih _ _ q q_ih q q_ih _ _ q q_ih q q_ih q q_ih q₁ q₂ q₁_ih q₂_ih _
[GOAL]
case move
q' : Λ'
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ (Λ'.move p✝ k₁✝ k₂✝ q) → trStmts₁ q' ⊆ trStmts₁ (Λ'.move p✝ k₁✝ k₂✝ q)
[PROOFSTEP]
simp (config := { contextual := true }) only [trStmts₁, Finset.mem_insert, Finset.mem_union, or_imp,
  Finset.mem_singleton, Finset.Subset.refl, imp_true_iff, true_and_iff]
[GOAL]
case clear
q' : Λ'
p✝ : Γ' → Bool
k✝ : K'
q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ (Λ'.clear p✝ k✝ q) → trStmts₁ q' ⊆ trStmts₁ (Λ'.clear p✝ k✝ q)
[PROOFSTEP]
simp (config := { contextual := true }) only [trStmts₁, Finset.mem_insert, Finset.mem_union, or_imp,
  Finset.mem_singleton, Finset.Subset.refl, imp_true_iff, true_and_iff]
[GOAL]
case copy
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ (Λ'.copy q) → trStmts₁ q' ⊆ trStmts₁ (Λ'.copy q)
[PROOFSTEP]
simp (config := { contextual := true }) only [trStmts₁, Finset.mem_insert, Finset.mem_union, or_imp,
  Finset.mem_singleton, Finset.Subset.refl, imp_true_iff, true_and_iff]
[GOAL]
case push
q' : Λ'
k✝ : K'
s✝ : Option Γ' → Option Γ'
q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ (Λ'.push k✝ s✝ q) → trStmts₁ q' ⊆ trStmts₁ (Λ'.push k✝ s✝ q)
[PROOFSTEP]
simp (config := { contextual := true }) only [trStmts₁, Finset.mem_insert, Finset.mem_union, or_imp,
  Finset.mem_singleton, Finset.Subset.refl, imp_true_iff, true_and_iff]
[GOAL]
case read
q' : Λ'
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), q' ∈ trStmts₁ (q a) → trStmts₁ q' ⊆ trStmts₁ (q a)
⊢ q' ∈ trStmts₁ (Λ'.read q) → trStmts₁ q' ⊆ trStmts₁ (Λ'.read q)
[PROOFSTEP]
simp (config := { contextual := true }) only [trStmts₁, Finset.mem_insert, Finset.mem_union, or_imp,
  Finset.mem_singleton, Finset.Subset.refl, imp_true_iff, true_and_iff]
[GOAL]
case succ
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ (Λ'.succ q) → trStmts₁ q' ⊆ trStmts₁ (Λ'.succ q)
[PROOFSTEP]
simp (config := { contextual := true }) only [trStmts₁, Finset.mem_insert, Finset.mem_union, or_imp,
  Finset.mem_singleton, Finset.Subset.refl, imp_true_iff, true_and_iff]
[GOAL]
case pred
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
⊢ q' ∈ trStmts₁ (Λ'.pred q₁ q₂) → trStmts₁ q' ⊆ trStmts₁ (Λ'.pred q₁ q₂)
[PROOFSTEP]
simp (config := { contextual := true }) only [trStmts₁, Finset.mem_insert, Finset.mem_union, or_imp,
  Finset.mem_singleton, Finset.Subset.refl, imp_true_iff, true_and_iff]
[GOAL]
case ret
q' : Λ'
k✝ : Cont'
⊢ q' ∈ trStmts₁ (Λ'.ret k✝) → trStmts₁ q' ⊆ trStmts₁ (Λ'.ret k✝)
[PROOFSTEP]
simp (config := { contextual := true }) only [trStmts₁, Finset.mem_insert, Finset.mem_union, or_imp,
  Finset.mem_singleton, Finset.Subset.refl, imp_true_iff, true_and_iff]
[GOAL]
case move
q' : Λ'
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.move p✝ k₁✝ k₂✝ q) (trStmts₁ q)
case clear
q' : Λ'
p✝ : Γ' → Bool
k✝ : K'
q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.clear p✝ k✝ q) (trStmts₁ q)
case copy
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.copy q) (trStmts₁ q)
case push
q' : Λ'
k✝ : K'
s✝ : Option Γ' → Option Γ'
q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.push k✝ s✝ q) (trStmts₁ q)
case read
q' : Λ'
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), q' ∈ trStmts₁ (q a) → trStmts₁ q' ⊆ trStmts₁ (q a)
⊢ (q' ∈ Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) →
    trStmts₁ q' ⊆ insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))
case succ
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ (q' = unrev q →
      insert (Λ'.move (fun x => false) rev main q) (trStmts₁ q) ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))) ∧
    (q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)))
case pred
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
⊢ (q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))) ∧
    (q' = unrev q₂ →
        insert (Λ'.move (fun x => false) rev main q₂) (trStmts₁ q₂) ⊆
          insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))) ∧
      (q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂)))
[PROOFSTEP]
iterate 4 exact fun h => Finset.Subset.trans (q_ih h) (Finset.subset_insert _ _)
[GOAL]
case move
q' : Λ'
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.move p✝ k₁✝ k₂✝ q) (trStmts₁ q)
case clear
q' : Λ'
p✝ : Γ' → Bool
k✝ : K'
q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.clear p✝ k✝ q) (trStmts₁ q)
case copy
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.copy q) (trStmts₁ q)
case push
q' : Λ'
k✝ : K'
s✝ : Option Γ' → Option Γ'
q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.push k✝ s✝ q) (trStmts₁ q)
case read
q' : Λ'
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), q' ∈ trStmts₁ (q a) → trStmts₁ q' ⊆ trStmts₁ (q a)
⊢ (q' ∈ Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) →
    trStmts₁ q' ⊆ insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))
case succ
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ (q' = unrev q →
      insert (Λ'.move (fun x => false) rev main q) (trStmts₁ q) ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))) ∧
    (q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)))
case pred
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
⊢ (q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))) ∧
    (q' = unrev q₂ →
        insert (Λ'.move (fun x => false) rev main q₂) (trStmts₁ q₂) ⊆
          insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))) ∧
      (q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂)))
[PROOFSTEP]
exact fun h => Finset.Subset.trans (q_ih h) (Finset.subset_insert _ _)
[GOAL]
case clear
q' : Λ'
p✝ : Γ' → Bool
k✝ : K'
q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.clear p✝ k✝ q) (trStmts₁ q)
case copy
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.copy q) (trStmts₁ q)
case push
q' : Λ'
k✝ : K'
s✝ : Option Γ' → Option Γ'
q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.push k✝ s✝ q) (trStmts₁ q)
case read
q' : Λ'
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), q' ∈ trStmts₁ (q a) → trStmts₁ q' ⊆ trStmts₁ (q a)
⊢ (q' ∈ Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) →
    trStmts₁ q' ⊆ insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))
case succ
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ (q' = unrev q →
      insert (Λ'.move (fun x => false) rev main q) (trStmts₁ q) ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))) ∧
    (q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)))
case pred
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
⊢ (q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))) ∧
    (q' = unrev q₂ →
        insert (Λ'.move (fun x => false) rev main q₂) (trStmts₁ q₂) ⊆
          insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))) ∧
      (q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂)))
[PROOFSTEP]
exact fun h => Finset.Subset.trans (q_ih h) (Finset.subset_insert _ _)
[GOAL]
case copy
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.copy q) (trStmts₁ q)
case push
q' : Λ'
k✝ : K'
s✝ : Option Γ' → Option Γ'
q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.push k✝ s✝ q) (trStmts₁ q)
case read
q' : Λ'
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), q' ∈ trStmts₁ (q a) → trStmts₁ q' ⊆ trStmts₁ (q a)
⊢ (q' ∈ Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) →
    trStmts₁ q' ⊆ insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))
case succ
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ (q' = unrev q →
      insert (Λ'.move (fun x => false) rev main q) (trStmts₁ q) ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))) ∧
    (q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)))
case pred
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
⊢ (q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))) ∧
    (q' = unrev q₂ →
        insert (Λ'.move (fun x => false) rev main q₂) (trStmts₁ q₂) ⊆
          insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))) ∧
      (q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂)))
[PROOFSTEP]
exact fun h => Finset.Subset.trans (q_ih h) (Finset.subset_insert _ _)
[GOAL]
case push
q' : Λ'
k✝ : K'
s✝ : Option Γ' → Option Γ'
q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.push k✝ s✝ q) (trStmts₁ q)
case read
q' : Λ'
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), q' ∈ trStmts₁ (q a) → trStmts₁ q' ⊆ trStmts₁ (q a)
⊢ (q' ∈ Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) →
    trStmts₁ q' ⊆ insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))
case succ
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ (q' = unrev q →
      insert (Λ'.move (fun x => false) rev main q) (trStmts₁ q) ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))) ∧
    (q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)))
case pred
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
⊢ (q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))) ∧
    (q' = unrev q₂ →
        insert (Λ'.move (fun x => false) rev main q₂) (trStmts₁ q₂) ⊆
          insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))) ∧
      (q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂)))
[PROOFSTEP]
exact fun h => Finset.Subset.trans (q_ih h) (Finset.subset_insert _ _)
[GOAL]
case read
q' : Λ'
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), q' ∈ trStmts₁ (q a) → trStmts₁ q' ⊆ trStmts₁ (q a)
⊢ (q' ∈ Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) →
    trStmts₁ q' ⊆ insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))
[PROOFSTEP]
simp
[GOAL]
case read
q' : Λ'
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), q' ∈ trStmts₁ (q a) → trStmts₁ q' ⊆ trStmts₁ (q a)
⊢ ∀ (x : Option Γ'),
    q' ∈ trStmts₁ (q x) → trStmts₁ q' ⊆ insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))
[PROOFSTEP]
intro s h x h'
[GOAL]
case read
q' : Λ'
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), q' ∈ trStmts₁ (q a) → trStmts₁ q' ⊆ trStmts₁ (q a)
s : Option Γ'
h : q' ∈ trStmts₁ (q s)
x : Λ'
h' : x ∈ trStmts₁ q'
⊢ x ∈ insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))
[PROOFSTEP]
simp
[GOAL]
case read
q' : Λ'
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), q' ∈ trStmts₁ (q a) → trStmts₁ q' ⊆ trStmts₁ (q a)
s : Option Γ'
h : q' ∈ trStmts₁ (q s)
x : Λ'
h' : x ∈ trStmts₁ q'
⊢ x = Λ'.read q ∨ ∃ a, x ∈ trStmts₁ (q a)
[PROOFSTEP]
exact Or.inr ⟨_, q_ih s h h'⟩
[GOAL]
case succ
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ (q' = unrev q →
      insert (Λ'.move (fun x => false) rev main q) (trStmts₁ q) ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))) ∧
    (q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)))
[PROOFSTEP]
constructor
[GOAL]
case succ.left
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' = unrev q →
    insert (Λ'.move (fun x => false) rev main q) (trStmts₁ q) ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))
[PROOFSTEP]
rintro rfl
[GOAL]
case succ.left
q : Λ'
q_ih : unrev q ∈ trStmts₁ q → trStmts₁ (unrev q) ⊆ trStmts₁ q
⊢ insert (Λ'.move (fun x => false) rev main q) (trStmts₁ q) ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))
[PROOFSTEP]
apply Finset.subset_insert
[GOAL]
case succ.right
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
⊢ q' ∈ trStmts₁ q → trStmts₁ q' ⊆ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))
[PROOFSTEP]
intro h x h'
[GOAL]
case succ.right
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
h : q' ∈ trStmts₁ q
x : Λ'
h' : x ∈ trStmts₁ q'
⊢ x ∈ insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))
[PROOFSTEP]
simp
[GOAL]
case succ.right
q' q : Λ'
q_ih : q' ∈ trStmts₁ q → trStmts₁ q' ⊆ trStmts₁ q
h : q' ∈ trStmts₁ q
x : Λ'
h' : x ∈ trStmts₁ q'
⊢ x = Λ'.succ q ∨ x = unrev q ∨ x ∈ trStmts₁ q
[PROOFSTEP]
exact Or.inr (Or.inr <| q_ih h h')
[GOAL]
case pred
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
⊢ (q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))) ∧
    (q' = unrev q₂ →
        insert (Λ'.move (fun x => false) rev main q₂) (trStmts₁ q₂) ⊆
          insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))) ∧
      (q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂)))
[PROOFSTEP]
refine' ⟨fun h x h' => _, fun _ x h' => _, fun h x h' => _⟩
[GOAL]
case pred.refine'_1
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
h : q' ∈ trStmts₁ q₁
x : Λ'
h' : x ∈ trStmts₁ q'
⊢ x ∈ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))
[PROOFSTEP]
simp
[GOAL]
case pred.refine'_2
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
x✝ : q' = unrev q₂
x : Λ'
h' : x ∈ insert (Λ'.move (fun x => false) rev main q₂) (trStmts₁ q₂)
⊢ x ∈ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))
[PROOFSTEP]
simp
[GOAL]
case pred.refine'_3
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
h : q' ∈ trStmts₁ q₂
x : Λ'
h' : x ∈ trStmts₁ q'
⊢ x ∈ insert (Λ'.pred q₁ q₂) (trStmts₁ q₁ ∪ insert (unrev q₂) (trStmts₁ q₂))
[PROOFSTEP]
simp
[GOAL]
case pred.refine'_1
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
h : q' ∈ trStmts₁ q₁
x : Λ'
h' : x ∈ trStmts₁ q'
⊢ x = Λ'.pred q₁ q₂ ∨ x = unrev q₂ ∨ x ∈ trStmts₁ q₁ ∨ x ∈ trStmts₁ q₂
[PROOFSTEP]
exact Or.inr (Or.inr <| Or.inl <| q₁_ih h h')
[GOAL]
case pred.refine'_2
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
x✝ : q' = unrev q₂
x : Λ'
h' : x ∈ insert (Λ'.move (fun x => false) rev main q₂) (trStmts₁ q₂)
⊢ x = Λ'.pred q₁ q₂ ∨ x = unrev q₂ ∨ x ∈ trStmts₁ q₁ ∨ x ∈ trStmts₁ q₂
[PROOFSTEP]
cases' Finset.mem_insert.1 h' with h' h'
[GOAL]
case pred.refine'_2.inl
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
x✝ : q' = unrev q₂
x : Λ'
h'✝ : x ∈ insert (Λ'.move (fun x => false) rev main q₂) (trStmts₁ q₂)
h' : x = Λ'.move (fun x => false) rev main q₂
⊢ x = Λ'.pred q₁ q₂ ∨ x = unrev q₂ ∨ x ∈ trStmts₁ q₁ ∨ x ∈ trStmts₁ q₂
[PROOFSTEP]
simp [h', unrev]
[GOAL]
case pred.refine'_2.inr
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
x✝ : q' = unrev q₂
x : Λ'
h'✝ : x ∈ insert (Λ'.move (fun x => false) rev main q₂) (trStmts₁ q₂)
h' : x ∈ trStmts₁ q₂
⊢ x = Λ'.pred q₁ q₂ ∨ x = unrev q₂ ∨ x ∈ trStmts₁ q₁ ∨ x ∈ trStmts₁ q₂
[PROOFSTEP]
simp [h', unrev]
[GOAL]
case pred.refine'_3
q' q₁ q₂ : Λ'
q₁_ih : q' ∈ trStmts₁ q₁ → trStmts₁ q' ⊆ trStmts₁ q₁
q₂_ih : q' ∈ trStmts₁ q₂ → trStmts₁ q' ⊆ trStmts₁ q₂
h : q' ∈ trStmts₁ q₂
x : Λ'
h' : x ∈ trStmts₁ q'
⊢ x = Λ'.pred q₁ q₂ ∨ x = unrev q₂ ∨ x ∈ trStmts₁ q₁ ∨ x ∈ trStmts₁ q₂
[PROOFSTEP]
exact Or.inr (Or.inr <| Or.inr <| q₂_ih h h')
[GOAL]
q : Λ'
⊢ q ∈ trStmts₁ q
[PROOFSTEP]
induction q
[GOAL]
case move
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.move p✝ k₁✝ k₂✝ q✝ ∈ trStmts₁ (Λ'.move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
first
| apply Finset.mem_singleton_self
| apply Finset.mem_insert_self
[GOAL]
case move
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.move p✝ k₁✝ k₂✝ q✝ ∈ trStmts₁ (Λ'.move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
apply Finset.mem_singleton_self
[GOAL]
case move
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.move p✝ k₁✝ k₂✝ q✝ ∈ trStmts₁ (Λ'.move p✝ k₁✝ k₂✝ q✝)
[PROOFSTEP]
apply Finset.mem_insert_self
[GOAL]
case clear
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.clear p✝ k✝ q✝ ∈ trStmts₁ (Λ'.clear p✝ k✝ q✝)
[PROOFSTEP]
first
| apply Finset.mem_singleton_self
| apply Finset.mem_insert_self
[GOAL]
case clear
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.clear p✝ k✝ q✝ ∈ trStmts₁ (Λ'.clear p✝ k✝ q✝)
[PROOFSTEP]
apply Finset.mem_singleton_self
[GOAL]
case clear
p✝ : Γ' → Bool
k✝ : K'
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.clear p✝ k✝ q✝ ∈ trStmts₁ (Λ'.clear p✝ k✝ q✝)
[PROOFSTEP]
apply Finset.mem_insert_self
[GOAL]
case copy
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.copy q✝ ∈ trStmts₁ (Λ'.copy q✝)
[PROOFSTEP]
first
| apply Finset.mem_singleton_self
| apply Finset.mem_insert_self
[GOAL]
case copy
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.copy q✝ ∈ trStmts₁ (Λ'.copy q✝)
[PROOFSTEP]
apply Finset.mem_singleton_self
[GOAL]
case copy
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.copy q✝ ∈ trStmts₁ (Λ'.copy q✝)
[PROOFSTEP]
apply Finset.mem_insert_self
[GOAL]
case push
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.push k✝ s✝ q✝ ∈ trStmts₁ (Λ'.push k✝ s✝ q✝)
[PROOFSTEP]
first
| apply Finset.mem_singleton_self
| apply Finset.mem_insert_self
[GOAL]
case push
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.push k✝ s✝ q✝ ∈ trStmts₁ (Λ'.push k✝ s✝ q✝)
[PROOFSTEP]
apply Finset.mem_singleton_self
[GOAL]
case push
k✝ : K'
s✝ : Option Γ' → Option Γ'
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.push k✝ s✝ q✝ ∈ trStmts₁ (Λ'.push k✝ s✝ q✝)
[PROOFSTEP]
apply Finset.mem_insert_self
[GOAL]
case read
f✝ : Option Γ' → Λ'
f_ih✝ : ∀ (a : Option Γ'), f✝ a ∈ trStmts₁ (f✝ a)
⊢ Λ'.read f✝ ∈ trStmts₁ (Λ'.read f✝)
[PROOFSTEP]
first
| apply Finset.mem_singleton_self
| apply Finset.mem_insert_self
[GOAL]
case read
f✝ : Option Γ' → Λ'
f_ih✝ : ∀ (a : Option Γ'), f✝ a ∈ trStmts₁ (f✝ a)
⊢ Λ'.read f✝ ∈ trStmts₁ (Λ'.read f✝)
[PROOFSTEP]
apply Finset.mem_singleton_self
[GOAL]
case read
f✝ : Option Γ' → Λ'
f_ih✝ : ∀ (a : Option Γ'), f✝ a ∈ trStmts₁ (f✝ a)
⊢ Λ'.read f✝ ∈ trStmts₁ (Λ'.read f✝)
[PROOFSTEP]
apply Finset.mem_insert_self
[GOAL]
case succ
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.succ q✝ ∈ trStmts₁ (Λ'.succ q✝)
[PROOFSTEP]
first
| apply Finset.mem_singleton_self
| apply Finset.mem_insert_self
[GOAL]
case succ
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.succ q✝ ∈ trStmts₁ (Λ'.succ q✝)
[PROOFSTEP]
apply Finset.mem_singleton_self
[GOAL]
case succ
q✝ : Λ'
q_ih✝ : q✝ ∈ trStmts₁ q✝
⊢ Λ'.succ q✝ ∈ trStmts₁ (Λ'.succ q✝)
[PROOFSTEP]
apply Finset.mem_insert_self
[GOAL]
case pred
q₁✝ q₂✝ : Λ'
q₁_ih✝ : q₁✝ ∈ trStmts₁ q₁✝
q₂_ih✝ : q₂✝ ∈ trStmts₁ q₂✝
⊢ Λ'.pred q₁✝ q₂✝ ∈ trStmts₁ (Λ'.pred q₁✝ q₂✝)
[PROOFSTEP]
first
| apply Finset.mem_singleton_self
| apply Finset.mem_insert_self
[GOAL]
case pred
q₁✝ q₂✝ : Λ'
q₁_ih✝ : q₁✝ ∈ trStmts₁ q₁✝
q₂_ih✝ : q₂✝ ∈ trStmts₁ q₂✝
⊢ Λ'.pred q₁✝ q₂✝ ∈ trStmts₁ (Λ'.pred q₁✝ q₂✝)
[PROOFSTEP]
apply Finset.mem_singleton_self
[GOAL]
case pred
q₁✝ q₂✝ : Λ'
q₁_ih✝ : q₁✝ ∈ trStmts₁ q₁✝
q₂_ih✝ : q₂✝ ∈ trStmts₁ q₂✝
⊢ Λ'.pred q₁✝ q₂✝ ∈ trStmts₁ (Λ'.pred q₁✝ q₂✝)
[PROOFSTEP]
apply Finset.mem_insert_self
[GOAL]
case ret
k✝ : Cont'
⊢ Λ'.ret k✝ ∈ trStmts₁ (Λ'.ret k✝)
[PROOFSTEP]
first
| apply Finset.mem_singleton_self
| apply Finset.mem_insert_self
[GOAL]
case ret
k✝ : Cont'
⊢ Λ'.ret k✝ ∈ trStmts₁ (Λ'.ret k✝)
[PROOFSTEP]
apply Finset.mem_singleton_self
[GOAL]
c : Code
k : Cont'
⊢ trStmts₁ (trNormal c k) ⊆ codeSupp' c k
[PROOFSTEP]
cases c
[GOAL]
case zero'
k : Cont'
⊢ trStmts₁ (trNormal Code.zero' k) ⊆ codeSupp' Code.zero' k
[PROOFSTEP]
first
| rfl
| exact Finset.subset_union_left _ _
[GOAL]
case zero'
k : Cont'
⊢ trStmts₁ (trNormal Code.zero' k) ⊆ codeSupp' Code.zero' k
[PROOFSTEP]
rfl
[GOAL]
case succ
k : Cont'
⊢ trStmts₁ (trNormal Code.succ k) ⊆ codeSupp' Code.succ k
[PROOFSTEP]
first
| rfl
| exact Finset.subset_union_left _ _
[GOAL]
case succ
k : Cont'
⊢ trStmts₁ (trNormal Code.succ k) ⊆ codeSupp' Code.succ k
[PROOFSTEP]
rfl
[GOAL]
case tail
k : Cont'
⊢ trStmts₁ (trNormal Code.tail k) ⊆ codeSupp' Code.tail k
[PROOFSTEP]
first
| rfl
| exact Finset.subset_union_left _ _
[GOAL]
case tail
k : Cont'
⊢ trStmts₁ (trNormal Code.tail k) ⊆ codeSupp' Code.tail k
[PROOFSTEP]
rfl
[GOAL]
case cons
k : Cont'
a✝¹ a✝ : Code
⊢ trStmts₁ (trNormal (Code.cons a✝¹ a✝) k) ⊆ codeSupp' (Code.cons a✝¹ a✝) k
[PROOFSTEP]
first
| rfl
| exact Finset.subset_union_left _ _
[GOAL]
case cons
k : Cont'
a✝¹ a✝ : Code
⊢ trStmts₁ (trNormal (Code.cons a✝¹ a✝) k) ⊆ codeSupp' (Code.cons a✝¹ a✝) k
[PROOFSTEP]
rfl
[GOAL]
case cons
k : Cont'
a✝¹ a✝ : Code
⊢ trStmts₁ (trNormal (Code.cons a✝¹ a✝) k) ⊆ codeSupp' (Code.cons a✝¹ a✝) k
[PROOFSTEP]
exact Finset.subset_union_left _ _
[GOAL]
case comp
k : Cont'
a✝¹ a✝ : Code
⊢ trStmts₁ (trNormal (Code.comp a✝¹ a✝) k) ⊆ codeSupp' (Code.comp a✝¹ a✝) k
[PROOFSTEP]
first
| rfl
| exact Finset.subset_union_left _ _
[GOAL]
case comp
k : Cont'
a✝¹ a✝ : Code
⊢ trStmts₁ (trNormal (Code.comp a✝¹ a✝) k) ⊆ codeSupp' (Code.comp a✝¹ a✝) k
[PROOFSTEP]
rfl
[GOAL]
case comp
k : Cont'
a✝¹ a✝ : Code
⊢ trStmts₁ (trNormal (Code.comp a✝¹ a✝) k) ⊆ codeSupp' (Code.comp a✝¹ a✝) k
[PROOFSTEP]
exact Finset.subset_union_left _ _
[GOAL]
case case
k : Cont'
a✝¹ a✝ : Code
⊢ trStmts₁ (trNormal (Code.case a✝¹ a✝) k) ⊆ codeSupp' (Code.case a✝¹ a✝) k
[PROOFSTEP]
first
| rfl
| exact Finset.subset_union_left _ _
[GOAL]
case case
k : Cont'
a✝¹ a✝ : Code
⊢ trStmts₁ (trNormal (Code.case a✝¹ a✝) k) ⊆ codeSupp' (Code.case a✝¹ a✝) k
[PROOFSTEP]
rfl
[GOAL]
case case
k : Cont'
a✝¹ a✝ : Code
⊢ trStmts₁ (trNormal (Code.case a✝¹ a✝) k) ⊆ codeSupp' (Code.case a✝¹ a✝) k
[PROOFSTEP]
exact Finset.subset_union_left _ _
[GOAL]
case fix
k : Cont'
a✝ : Code
⊢ trStmts₁ (trNormal (Code.fix a✝) k) ⊆ codeSupp' (Code.fix a✝) k
[PROOFSTEP]
first
| rfl
| exact Finset.subset_union_left _ _
[GOAL]
case fix
k : Cont'
a✝ : Code
⊢ trStmts₁ (trNormal (Code.fix a✝) k) ⊆ codeSupp' (Code.fix a✝) k
[PROOFSTEP]
rfl
[GOAL]
case fix
k : Cont'
a✝ : Code
⊢ trStmts₁ (trNormal (Code.fix a✝) k) ⊆ codeSupp' (Code.fix a✝) k
[PROOFSTEP]
exact Finset.subset_union_left _ _
[GOAL]
f fs : Code
k : Cont'
⊢ codeSupp (Code.cons f fs) k = trStmts₁ (trNormal (Code.cons f fs) k) ∪ codeSupp f (Cont'.cons₁ fs k)
[PROOFSTEP]
simp [codeSupp, codeSupp', contSupp, Finset.union_assoc]
[GOAL]
f g : Code
k : Cont'
⊢ codeSupp (Code.comp f g) k = trStmts₁ (trNormal (Code.comp f g) k) ∪ codeSupp g (Cont'.comp f k)
[PROOFSTEP]
simp [codeSupp, codeSupp', contSupp, Finset.union_assoc]
[GOAL]
f g : Code
k : Cont'
⊢ trStmts₁ (trNormal g (Cont'.comp f k)) ∪
      (codeSupp' g (Cont'.comp f k) ∪ (trStmts₁ (trNormal f k) ∪ (codeSupp' f k ∪ contSupp k))) =
    trStmts₁ (trNormal g (Cont'.comp f k)) ∪ (codeSupp' g (Cont'.comp f k) ∪ (codeSupp' f k ∪ contSupp k))
[PROOFSTEP]
rw [← Finset.union_assoc _ _ (contSupp k), Finset.union_eq_right_iff_subset.2 (codeSupp'_self _ _)]
[GOAL]
f g : Code
k : Cont'
⊢ codeSupp (Code.case f g) k = trStmts₁ (trNormal (Code.case f g) k) ∪ (codeSupp f k ∪ codeSupp g k)
[PROOFSTEP]
simp [codeSupp, codeSupp', contSupp, Finset.union_assoc, Finset.union_left_comm]
[GOAL]
f : Code
k : Cont'
⊢ codeSupp (Code.fix f) k = trStmts₁ (trNormal (Code.fix f) k) ∪ codeSupp f (Cont'.fix f k)
[PROOFSTEP]
simp [codeSupp, codeSupp', contSupp, Finset.union_assoc, Finset.union_left_comm, Finset.union_left_idem]
[GOAL]
fs : Code
k : Cont'
⊢ contSupp (Cont'.cons₁ fs k) =
    trStmts₁
        (move₂ (fun x => false) main aux
          (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
            (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ k))))) ∪
      codeSupp fs (Cont'.cons₂ k)
[PROOFSTEP]
simp [codeSupp, codeSupp', contSupp, Finset.union_assoc]
[GOAL]
f : Code
k : Cont'
⊢ contSupp (Cont'.fix f k) = codeSupp f (Cont'.fix f k)
[PROOFSTEP]
simp (config := { contextual := true }) [codeSupp, codeSupp', contSupp, Finset.union_assoc, Finset.subset_iff]
[GOAL]
K S : Finset Λ'
q : Λ'
⊢ Supports (insert q K) S ↔ TM2.SupportsStmt S (tr q) ∧ Supports K S
[PROOFSTEP]
simp [Supports]
[GOAL]
S : Finset Λ'
q : Λ'
⊢ Supports {q} S ↔ TM2.SupportsStmt S (tr q)
[PROOFSTEP]
simp [Supports]
[GOAL]
K₁ K₂ S : Finset Λ'
⊢ Supports (K₁ ∪ K₂) S ↔ Supports K₁ S ∧ Supports K₂ S
[PROOFSTEP]
simp [Supports, or_imp, forall_and]
[GOAL]
K : Option Γ' → Finset Λ'
S : Finset Λ'
⊢ Supports (Finset.biUnion Finset.univ K) S ↔ ∀ (a : Option Γ'), Supports (K a) S
[PROOFSTEP]
simp [Supports]
[GOAL]
K : Option Γ' → Finset Λ'
S : Finset Λ'
⊢ (∀ (q : Λ') (x : Option Γ'), q ∈ K x → TM2.SupportsStmt S (tr q)) ↔
    ∀ (a : Option Γ') (q : Λ'), q ∈ K a → TM2.SupportsStmt S (tr q)
[PROOFSTEP]
apply forall_swap
[GOAL]
S : Finset Λ'
k : K'
q : Λ'
H : Λ'.Supports S q
x✝ : Option Γ'
⊢ Λ'.Supports S ((fun s => ite (s = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) k) (unrev q)) x✝)
[PROOFSTEP]
dsimp only
[GOAL]
S : Finset Λ'
k : K'
q : Λ'
H : Λ'.Supports S q
x✝ : Option Γ'
⊢ Λ'.Supports S (ite (x✝ = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) k) (unrev q))
[PROOFSTEP]
split_ifs
[GOAL]
case pos
S : Finset Λ'
k : K'
q : Λ'
H : Λ'.Supports S q
x✝ : Option Γ'
h✝ : x✝ = some Γ'.consₗ
⊢ Λ'.Supports S (id (unrev q))
[PROOFSTEP]
exact H
[GOAL]
case neg
S : Finset Λ'
k : K'
q : Λ'
H : Λ'.Supports S q
x✝ : Option Γ'
h✝ : ¬x✝ = some Γ'.consₗ
⊢ Λ'.Supports S (Λ'.clear (fun x => decide (x = Γ'.consₗ)) k (unrev q))
[PROOFSTEP]
exact H
[GOAL]
S : Finset Λ'
k : Cont'
H₁ : contSupp k ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret k))
[PROOFSTEP]
have W := fun {q} => trStmts₁_self q
[GOAL]
S : Finset Λ'
k : Cont'
H₁ : contSupp k ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
⊢ TM2.SupportsStmt S (tr (Λ'.ret k))
[PROOFSTEP]
cases k
[GOAL]
case halt
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
H₁ : contSupp Cont'.halt ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret Cont'.halt))
case cons₁
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.cons₁ a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.cons₁ a✝¹ a✝)))
case cons₂
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝ : Cont'
H₁ : contSupp (Cont'.cons₂ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.cons₂ a✝)))
case comp
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.comp a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.comp a✝¹ a✝)))
case fix
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.fix a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.fix a✝¹ a✝)))
[PROOFSTEP]
case halt => trivial
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
H₁ : contSupp Cont'.halt ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret Cont'.halt))
[PROOFSTEP]
case halt => trivial
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
H₁ : contSupp Cont'.halt ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret Cont'.halt))
[PROOFSTEP]
trivial
[GOAL]
case cons₁
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.cons₁ a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.cons₁ a✝¹ a✝)))
case cons₂
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝ : Cont'
H₁ : contSupp (Cont'.cons₂ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.cons₂ a✝)))
case comp
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.comp a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.comp a✝¹ a✝)))
case fix
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.fix a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.fix a✝¹ a✝)))
[PROOFSTEP]
case cons₁ => rw [contSupp_cons₁, Finset.union_subset_iff] at H₁ ; exact fun _ => H₁.1 W
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.cons₁ a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.cons₁ a✝¹ a✝)))
[PROOFSTEP]
case cons₁ => rw [contSupp_cons₁, Finset.union_subset_iff] at H₁ ; exact fun _ => H₁.1 W
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.cons₁ a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.cons₁ a✝¹ a✝)))
[PROOFSTEP]
rw [contSupp_cons₁, Finset.union_subset_iff] at H₁
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ :
  trStmts₁
        (move₂ (fun x => false) main aux
          (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
            (move₂ (fun x => false) aux stack (trNormal a✝¹ (Cont'.cons₂ a✝))))) ⊆
      S ∧
    codeSupp a✝¹ (Cont'.cons₂ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.cons₁ a✝¹ a✝)))
[PROOFSTEP]
exact fun _ => H₁.1 W
[GOAL]
case cons₂
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝ : Cont'
H₁ : contSupp (Cont'.cons₂ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.cons₂ a✝)))
case comp
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.comp a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.comp a✝¹ a✝)))
case fix
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.fix a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.fix a✝¹ a✝)))
[PROOFSTEP]
case cons₂ => rw [contSupp_cons₂, Finset.union_subset_iff] at H₁ ; exact fun _ => H₁.1 W
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝ : Cont'
H₁ : contSupp (Cont'.cons₂ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.cons₂ a✝)))
[PROOFSTEP]
case cons₂ => rw [contSupp_cons₂, Finset.union_subset_iff] at H₁ ; exact fun _ => H₁.1 W
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝ : Cont'
H₁ : contSupp (Cont'.cons₂ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.cons₂ a✝)))
[PROOFSTEP]
rw [contSupp_cons₂, Finset.union_subset_iff] at H₁
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝ : Cont'
H₁ : trStmts₁ (head stack (Λ'.ret a✝)) ⊆ S ∧ contSupp a✝ ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.cons₂ a✝)))
[PROOFSTEP]
exact fun _ => H₁.1 W
[GOAL]
case comp
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.comp a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.comp a✝¹ a✝)))
case fix
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.fix a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.fix a✝¹ a✝)))
[PROOFSTEP]
case comp => rw [contSupp_comp] at H₁ ; exact fun _ => H₁ (codeSupp_self _ _ W)
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.comp a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.comp a✝¹ a✝)))
[PROOFSTEP]
case comp => rw [contSupp_comp] at H₁ ; exact fun _ => H₁ (codeSupp_self _ _ W)
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.comp a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.comp a✝¹ a✝)))
[PROOFSTEP]
rw [contSupp_comp] at H₁
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : codeSupp a✝¹ a✝ ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.comp a✝¹ a✝)))
[PROOFSTEP]
exact fun _ => H₁ (codeSupp_self _ _ W)
[GOAL]
case fix
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.fix a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.fix a✝¹ a✝)))
[PROOFSTEP]
case fix =>
  rw [contSupp_fix] at H₁
  have L := @Finset.mem_union_left; have R := @Finset.mem_union_right
  intro s; dsimp only; cases natEnd s.iget
  · refine' H₁ (R _ <| L _ <| R _ <| R _ <| L _ W)
  · exact H₁ (R _ <| L _ <| R _ <| R _ <| R _ <| Finset.mem_singleton_self _)
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.fix a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.fix a✝¹ a✝)))
[PROOFSTEP]
case fix =>
  rw [contSupp_fix] at H₁
  have L := @Finset.mem_union_left; have R := @Finset.mem_union_right
  intro s; dsimp only; cases natEnd s.iget
  · refine' H₁ (R _ <| L _ <| R _ <| R _ <| L _ W)
  · exact H₁ (R _ <| L _ <| R _ <| R _ <| R _ <| Finset.mem_singleton_self _)
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : contSupp (Cont'.fix a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.fix a✝¹ a✝)))
[PROOFSTEP]
rw [contSupp_fix] at H₁
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : codeSupp a✝¹ (Cont'.fix a✝¹ a✝) ⊆ S
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.fix a✝¹ a✝)))
[PROOFSTEP]
have L := @Finset.mem_union_left
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : codeSupp a✝¹ (Cont'.fix a✝¹ a✝) ⊆ S
L : ∀ {α : Type ?u.680338} [inst : DecidableEq α] {s : Finset α} {a : α} (t : Finset α), a ∈ s → a ∈ s ∪ t
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.fix a✝¹ a✝)))
[PROOFSTEP]
have R := @Finset.mem_union_right
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : codeSupp a✝¹ (Cont'.fix a✝¹ a✝) ⊆ S
L : ∀ {α : Type ?u.680338} [inst : DecidableEq α] {s : Finset α} {a : α} (t : Finset α), a ∈ s → a ∈ s ∪ t
R : ∀ {α : Type ?u.680369} [inst : DecidableEq α] {t : Finset α} {a : α} (s : Finset α), a ∈ t → a ∈ s ∪ t
⊢ TM2.SupportsStmt S (tr (Λ'.ret (Cont'.fix a✝¹ a✝)))
[PROOFSTEP]
intro s
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : codeSupp a✝¹ (Cont'.fix a✝¹ a✝) ⊆ S
L : ∀ {α : Type ?u.680338} [inst : DecidableEq α] {s : Finset α} {a : α} (t : Finset α), a ∈ s → a ∈ s ∪ t
R : ∀ {α : Type ?u.680369} [inst : DecidableEq α] {t : Finset α} {a : α} (s : Finset α), a ∈ t → a ∈ s ∪ t
s : Option Γ'
⊢ (fun s => bif natEnd (Option.iget s) then Λ'.ret a✝ else Λ'.clear natEnd main (trNormal a✝¹ (Cont'.fix a✝¹ a✝))) s ∈ S
[PROOFSTEP]
dsimp only
[GOAL]
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : codeSupp a✝¹ (Cont'.fix a✝¹ a✝) ⊆ S
L : ∀ {α : Type ?u.680338} [inst : DecidableEq α] {s : Finset α} {a : α} (t : Finset α), a ∈ s → a ∈ s ∪ t
R : ∀ {α : Type ?u.680369} [inst : DecidableEq α] {t : Finset α} {a : α} (s : Finset α), a ∈ t → a ∈ s ∪ t
s : Option Γ'
⊢ (bif natEnd (Option.iget s) then Λ'.ret a✝ else Λ'.clear natEnd main (trNormal a✝¹ (Cont'.fix a✝¹ a✝))) ∈ S
[PROOFSTEP]
cases natEnd s.iget
[GOAL]
case false
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : codeSupp a✝¹ (Cont'.fix a✝¹ a✝) ⊆ S
L : ∀ {α : Type ?u.680338} [inst : DecidableEq α] {s : Finset α} {a : α} (t : Finset α), a ∈ s → a ∈ s ∪ t
R : ∀ {α : Type ?u.680369} [inst : DecidableEq α] {t : Finset α} {a : α} (s : Finset α), a ∈ t → a ∈ s ∪ t
s : Option Γ'
⊢ (bif false then Λ'.ret a✝ else Λ'.clear natEnd main (trNormal a✝¹ (Cont'.fix a✝¹ a✝))) ∈ S
[PROOFSTEP]
refine' H₁ (R _ <| L _ <| R _ <| R _ <| L _ W)
[GOAL]
case true
S : Finset Λ'
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
a✝¹ : Code
a✝ : Cont'
H₁ : codeSupp a✝¹ (Cont'.fix a✝¹ a✝) ⊆ S
L : ∀ {α : Type} [inst : DecidableEq α] {s : Finset α} {a : α} (t : Finset α), a ∈ s → a ∈ s ∪ t
R : ∀ {α : Type} [inst : DecidableEq α] {t : Finset α} {a : α} (s : Finset α), a ∈ t → a ∈ s ∪ t
s : Option Γ'
⊢ (bif true then Λ'.ret a✝ else Λ'.clear natEnd main (trNormal a✝¹ (Cont'.fix a✝¹ a✝))) ∈ S
[PROOFSTEP]
exact H₁ (R _ <| L _ <| R _ <| R _ <| R _ <| Finset.mem_singleton_self _)
[GOAL]
S : Finset Λ'
q : Λ'
H₁ : Λ'.Supports S q
HS₁ : trStmts₁ q ⊆ S
⊢ Supports (trStmts₁ q) S
[PROOFSTEP]
have W := fun {q} => trStmts₁_self q
[GOAL]
S : Finset Λ'
q : Λ'
H₁ : Λ'.Supports S q
HS₁ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
⊢ Supports (trStmts₁ q) S
[PROOFSTEP]
induction' q with _ _ _ q q_ih _ _ q q_ih q q_ih _ _ q q_ih q q_ih q q_ih q₁ q₂ q₁_ih q₂_ih _
[GOAL]
case move
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.move p✝ k₁✝ k₂✝ q)
HS₁ : trStmts₁ (Λ'.move p✝ k₁✝ k₂✝ q) ⊆ S
⊢ Supports (trStmts₁ (Λ'.move p✝ k₁✝ k₂✝ q)) S
[PROOFSTEP]
simp [trStmts₁, -Finset.singleton_subset_iff] at HS₁ ⊢
[GOAL]
case clear
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
p✝ : Γ' → Bool
k✝ : K'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.clear p✝ k✝ q)
HS₁ : trStmts₁ (Λ'.clear p✝ k✝ q) ⊆ S
⊢ Supports (trStmts₁ (Λ'.clear p✝ k✝ q)) S
[PROOFSTEP]
simp [trStmts₁, -Finset.singleton_subset_iff] at HS₁ ⊢
[GOAL]
case copy
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.copy q)
HS₁ : trStmts₁ (Λ'.copy q) ⊆ S
⊢ Supports (trStmts₁ (Λ'.copy q)) S
[PROOFSTEP]
simp [trStmts₁, -Finset.singleton_subset_iff] at HS₁ ⊢
[GOAL]
case push
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
k✝ : K'
s✝ : Option Γ' → Option Γ'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.push k✝ s✝ q)
HS₁ : trStmts₁ (Λ'.push k✝ s✝ q) ⊆ S
⊢ Supports (trStmts₁ (Λ'.push k✝ s✝ q)) S
[PROOFSTEP]
simp [trStmts₁, -Finset.singleton_subset_iff] at HS₁ ⊢
[GOAL]
case read
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), Λ'.Supports S (q a) → trStmts₁ (q a) ⊆ S → Supports (trStmts₁ (q a)) S
H₁ : Λ'.Supports S (Λ'.read q)
HS₁ : trStmts₁ (Λ'.read q) ⊆ S
⊢ Supports (trStmts₁ (Λ'.read q)) S
[PROOFSTEP]
simp [trStmts₁, -Finset.singleton_subset_iff] at HS₁ ⊢
[GOAL]
case succ
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.succ q)
HS₁ : trStmts₁ (Λ'.succ q) ⊆ S
⊢ Supports (trStmts₁ (Λ'.succ q)) S
[PROOFSTEP]
simp [trStmts₁, -Finset.singleton_subset_iff] at HS₁ ⊢
[GOAL]
case pred
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q₁ q₂ : Λ'
q₁_ih : Λ'.Supports S q₁ → trStmts₁ q₁ ⊆ S → Supports (trStmts₁ q₁) S
q₂_ih : Λ'.Supports S q₂ → trStmts₁ q₂ ⊆ S → Supports (trStmts₁ q₂) S
H₁ : Λ'.Supports S (Λ'.pred q₁ q₂)
HS₁ : trStmts₁ (Λ'.pred q₁ q₂) ⊆ S
⊢ Supports (trStmts₁ (Λ'.pred q₁ q₂)) S
[PROOFSTEP]
simp [trStmts₁, -Finset.singleton_subset_iff] at HS₁ ⊢
[GOAL]
case ret
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
k✝ : Cont'
H₁ : Λ'.Supports S (Λ'.ret k✝)
HS₁ : trStmts₁ (Λ'.ret k✝) ⊆ S
⊢ Supports (trStmts₁ (Λ'.ret k✝)) S
[PROOFSTEP]
simp [trStmts₁, -Finset.singleton_subset_iff] at HS₁ ⊢
[GOAL]
case move
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.move p✝ k₁✝ k₂✝ q)
HS₁ : insert (Λ'.move p✝ k₁✝ k₂✝ q) (trStmts₁ q) ⊆ S
⊢ Supports (insert (Λ'.move p✝ k₁✝ k₂✝ q) (trStmts₁ q)) S
case clear
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
p✝ : Γ' → Bool
k✝ : K'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.clear p✝ k✝ q)
HS₁ : insert (Λ'.clear p✝ k✝ q) (trStmts₁ q) ⊆ S
⊢ Supports (insert (Λ'.clear p✝ k✝ q) (trStmts₁ q)) S
case copy
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.copy q)
HS₁ : insert (Λ'.copy q) (trStmts₁ q) ⊆ S
⊢ Supports (insert (Λ'.copy q) (trStmts₁ q)) S
case push
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
k✝ : K'
s✝ : Option Γ' → Option Γ'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.push k✝ s✝ q)
HS₁ : insert (Λ'.push k✝ s✝ q) (trStmts₁ q) ⊆ S
⊢ Supports (insert (Λ'.push k✝ s✝ q) (trStmts₁ q)) S
case read
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), Λ'.Supports S (q a) → trStmts₁ (q a) ⊆ S → Supports (trStmts₁ (q a)) S
H₁ : Λ'.Supports S (Λ'.read q)
HS₁ : insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) ⊆ S
⊢ Supports (insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))) S
case succ
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.succ q)
HS₁ : insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)) ⊆ S
⊢ Supports (insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))) S
case pred
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q₁ q₂ : Λ'
q₁_ih : Λ'.Supports S q₁ → trStmts₁ q₁ ⊆ S → Supports (trStmts₁ q₁) S
q₂_ih : Λ'.Supports S q₂ → trStmts₁ q₂ ⊆ S → Supports (trStmts₁ q₂) S
H₁ : Λ'.Supports S (Λ'.pred q₁ q₂)
HS₁ : insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂)) ⊆ S
⊢ Supports (insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂))) S
case ret
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
k✝ : Cont'
H₁ : Λ'.Supports S (Λ'.ret k✝)
HS₁ : {Λ'.ret k✝} ⊆ S
⊢ Supports {Λ'.ret k✝} S
[PROOFSTEP]
any_goals
  cases' Finset.insert_subset_iff.1 HS₁ with h₁ h₂
  first
  | have h₃ := h₂ W
  | try simp [Finset.subset_iff] at h₂
[GOAL]
case move
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.move p✝ k₁✝ k₂✝ q)
HS₁ : insert (Λ'.move p✝ k₁✝ k₂✝ q) (trStmts₁ q) ⊆ S
⊢ Supports (insert (Λ'.move p✝ k₁✝ k₂✝ q) (trStmts₁ q)) S
[PROOFSTEP]
cases' Finset.insert_subset_iff.1 HS₁ with h₁ h₂
[GOAL]
case move.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.move p✝ k₁✝ k₂✝ q)
HS₁ : insert (Λ'.move p✝ k₁✝ k₂✝ q) (trStmts₁ q) ⊆ S
h₁ : Λ'.move p✝ k₁✝ k₂✝ q ∈ S
h₂ : trStmts₁ q ⊆ S
⊢ Supports (insert (Λ'.move p✝ k₁✝ k₂✝ q) (trStmts₁ q)) S
[PROOFSTEP]
first
| have h₃ := h₂ W
| try simp [Finset.subset_iff] at h₂
[GOAL]
case move.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.move p✝ k₁✝ k₂✝ q)
HS₁ : insert (Λ'.move p✝ k₁✝ k₂✝ q) (trStmts₁ q) ⊆ S
h₁ : Λ'.move p✝ k₁✝ k₂✝ q ∈ S
h₂ : trStmts₁ q ⊆ S
⊢ Supports (insert (Λ'.move p✝ k₁✝ k₂✝ q) (trStmts₁ q)) S
[PROOFSTEP]
have h₃ := h₂ W
[GOAL]
case clear
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
p✝ : Γ' → Bool
k✝ : K'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.clear p✝ k✝ q)
HS₁ : insert (Λ'.clear p✝ k✝ q) (trStmts₁ q) ⊆ S
⊢ Supports (insert (Λ'.clear p✝ k✝ q) (trStmts₁ q)) S
[PROOFSTEP]
cases' Finset.insert_subset_iff.1 HS₁ with h₁ h₂
[GOAL]
case clear.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
p✝ : Γ' → Bool
k✝ : K'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.clear p✝ k✝ q)
HS₁ : insert (Λ'.clear p✝ k✝ q) (trStmts₁ q) ⊆ S
h₁ : Λ'.clear p✝ k✝ q ∈ S
h₂ : trStmts₁ q ⊆ S
⊢ Supports (insert (Λ'.clear p✝ k✝ q) (trStmts₁ q)) S
[PROOFSTEP]
first
| have h₃ := h₂ W
| try simp [Finset.subset_iff] at h₂
[GOAL]
case clear.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
p✝ : Γ' → Bool
k✝ : K'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.clear p✝ k✝ q)
HS₁ : insert (Λ'.clear p✝ k✝ q) (trStmts₁ q) ⊆ S
h₁ : Λ'.clear p✝ k✝ q ∈ S
h₂ : trStmts₁ q ⊆ S
⊢ Supports (insert (Λ'.clear p✝ k✝ q) (trStmts₁ q)) S
[PROOFSTEP]
have h₃ := h₂ W
[GOAL]
case copy
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.copy q)
HS₁ : insert (Λ'.copy q) (trStmts₁ q) ⊆ S
⊢ Supports (insert (Λ'.copy q) (trStmts₁ q)) S
[PROOFSTEP]
cases' Finset.insert_subset_iff.1 HS₁ with h₁ h₂
[GOAL]
case copy.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.copy q)
HS₁ : insert (Λ'.copy q) (trStmts₁ q) ⊆ S
h₁ : Λ'.copy q ∈ S
h₂ : trStmts₁ q ⊆ S
⊢ Supports (insert (Λ'.copy q) (trStmts₁ q)) S
[PROOFSTEP]
first
| have h₃ := h₂ W
| try simp [Finset.subset_iff] at h₂
[GOAL]
case copy.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.copy q)
HS₁ : insert (Λ'.copy q) (trStmts₁ q) ⊆ S
h₁ : Λ'.copy q ∈ S
h₂ : trStmts₁ q ⊆ S
⊢ Supports (insert (Λ'.copy q) (trStmts₁ q)) S
[PROOFSTEP]
have h₃ := h₂ W
[GOAL]
case push
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
k✝ : K'
s✝ : Option Γ' → Option Γ'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.push k✝ s✝ q)
HS₁ : insert (Λ'.push k✝ s✝ q) (trStmts₁ q) ⊆ S
⊢ Supports (insert (Λ'.push k✝ s✝ q) (trStmts₁ q)) S
[PROOFSTEP]
cases' Finset.insert_subset_iff.1 HS₁ with h₁ h₂
[GOAL]
case push.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
k✝ : K'
s✝ : Option Γ' → Option Γ'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.push k✝ s✝ q)
HS₁ : insert (Λ'.push k✝ s✝ q) (trStmts₁ q) ⊆ S
h₁ : Λ'.push k✝ s✝ q ∈ S
h₂ : trStmts₁ q ⊆ S
⊢ Supports (insert (Λ'.push k✝ s✝ q) (trStmts₁ q)) S
[PROOFSTEP]
first
| have h₃ := h₂ W
| try simp [Finset.subset_iff] at h₂
[GOAL]
case push.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
k✝ : K'
s✝ : Option Γ' → Option Γ'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.push k✝ s✝ q)
HS₁ : insert (Λ'.push k✝ s✝ q) (trStmts₁ q) ⊆ S
h₁ : Λ'.push k✝ s✝ q ∈ S
h₂ : trStmts₁ q ⊆ S
⊢ Supports (insert (Λ'.push k✝ s✝ q) (trStmts₁ q)) S
[PROOFSTEP]
have h₃ := h₂ W
[GOAL]
case read
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), Λ'.Supports S (q a) → trStmts₁ (q a) ⊆ S → Supports (trStmts₁ (q a)) S
H₁ : Λ'.Supports S (Λ'.read q)
HS₁ : insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) ⊆ S
⊢ Supports (insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))) S
[PROOFSTEP]
cases' Finset.insert_subset_iff.1 HS₁ with h₁ h₂
[GOAL]
case read.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), Λ'.Supports S (q a) → trStmts₁ (q a) ⊆ S → Supports (trStmts₁ (q a)) S
H₁ : Λ'.Supports S (Λ'.read q)
HS₁ : insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) ⊆ S
h₁ : Λ'.read q ∈ S
h₂ : (Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) ⊆ S
⊢ Supports (insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))) S
[PROOFSTEP]
first
| have h₃ := h₂ W
| try simp [Finset.subset_iff] at h₂
[GOAL]
case read.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), Λ'.Supports S (q a) → trStmts₁ (q a) ⊆ S → Supports (trStmts₁ (q a)) S
H₁ : Λ'.Supports S (Λ'.read q)
HS₁ : insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) ⊆ S
h₁ : Λ'.read q ∈ S
h₂ : (Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) ⊆ S
⊢ Supports (insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))) S
[PROOFSTEP]
have h₃ := h₂ W
[GOAL]
case read.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), Λ'.Supports S (q a) → trStmts₁ (q a) ⊆ S → Supports (trStmts₁ (q a)) S
H₁ : Λ'.Supports S (Λ'.read q)
HS₁ : insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) ⊆ S
h₁ : Λ'.read q ∈ S
h₂ : (Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) ⊆ S
⊢ Supports (insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))) S
[PROOFSTEP]
try simp [Finset.subset_iff] at h₂
[GOAL]
case read.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), Λ'.Supports S (q a) → trStmts₁ (q a) ⊆ S → Supports (trStmts₁ (q a)) S
H₁ : Λ'.Supports S (Λ'.read q)
HS₁ : insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) ⊆ S
h₁ : Λ'.read q ∈ S
h₂ : (Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) ⊆ S
⊢ Supports (insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))) S
[PROOFSTEP]
simp [Finset.subset_iff] at h₂
[GOAL]
case succ
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.succ q)
HS₁ : insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)) ⊆ S
⊢ Supports (insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))) S
[PROOFSTEP]
cases' Finset.insert_subset_iff.1 HS₁ with h₁ h₂
[GOAL]
case succ.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.succ q)
HS₁ : insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)) ⊆ S
h₁ : Λ'.succ q ∈ S
h₂ : insert (unrev q) (trStmts₁ q) ⊆ S
⊢ Supports (insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))) S
[PROOFSTEP]
first
| have h₃ := h₂ W
| try simp [Finset.subset_iff] at h₂
[GOAL]
case succ.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.succ q)
HS₁ : insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)) ⊆ S
h₁ : Λ'.succ q ∈ S
h₂ : insert (unrev q) (trStmts₁ q) ⊆ S
⊢ Supports (insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))) S
[PROOFSTEP]
have h₃ := h₂ W
[GOAL]
case succ.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.succ q)
HS₁ : insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)) ⊆ S
h₁ : Λ'.succ q ∈ S
h₂ : insert (unrev q) (trStmts₁ q) ⊆ S
⊢ Supports (insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))) S
[PROOFSTEP]
try simp [Finset.subset_iff] at h₂
[GOAL]
case succ.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.succ q)
HS₁ : insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)) ⊆ S
h₁ : Λ'.succ q ∈ S
h₂ : insert (unrev q) (trStmts₁ q) ⊆ S
⊢ Supports (insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))) S
[PROOFSTEP]
simp [Finset.subset_iff] at h₂
[GOAL]
case pred
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q₁ q₂ : Λ'
q₁_ih : Λ'.Supports S q₁ → trStmts₁ q₁ ⊆ S → Supports (trStmts₁ q₁) S
q₂_ih : Λ'.Supports S q₂ → trStmts₁ q₂ ⊆ S → Supports (trStmts₁ q₂) S
H₁ : Λ'.Supports S (Λ'.pred q₁ q₂)
HS₁ : insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂)) ⊆ S
⊢ Supports (insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂))) S
[PROOFSTEP]
cases' Finset.insert_subset_iff.1 HS₁ with h₁ h₂
[GOAL]
case pred.intro
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q₁ q₂ : Λ'
q₁_ih : Λ'.Supports S q₁ → trStmts₁ q₁ ⊆ S → Supports (trStmts₁ q₁) S
q₂_ih : Λ'.Supports S q₂ → trStmts₁ q₂ ⊆ S → Supports (trStmts₁ q₂) S
H₁ : Λ'.Supports S (Λ'.pred q₁ q₂)
HS₁ : insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂)) ⊆ S
h₁ : Λ'.pred q₁ q₂ ∈ S
h₂ : insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂) ⊆ S
⊢ Supports (insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂))) S
[PROOFSTEP]
first
| have h₃ := h₂ W
| try simp [Finset.subset_iff] at h₂
[GOAL]
case pred.intro
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q₁ q₂ : Λ'
q₁_ih : Λ'.Supports S q₁ → trStmts₁ q₁ ⊆ S → Supports (trStmts₁ q₁) S
q₂_ih : Λ'.Supports S q₂ → trStmts₁ q₂ ⊆ S → Supports (trStmts₁ q₂) S
H₁ : Λ'.Supports S (Λ'.pred q₁ q₂)
HS₁ : insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂)) ⊆ S
h₁ : Λ'.pred q₁ q₂ ∈ S
h₂ : insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂) ⊆ S
⊢ Supports (insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂))) S
[PROOFSTEP]
have h₃ := h₂ W
[GOAL]
case pred.intro
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q₁ q₂ : Λ'
q₁_ih : Λ'.Supports S q₁ → trStmts₁ q₁ ⊆ S → Supports (trStmts₁ q₁) S
q₂_ih : Λ'.Supports S q₂ → trStmts₁ q₂ ⊆ S → Supports (trStmts₁ q₂) S
H₁ : Λ'.Supports S (Λ'.pred q₁ q₂)
HS₁ : insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂)) ⊆ S
h₁ : Λ'.pred q₁ q₂ ∈ S
h₂ : insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂) ⊆ S
⊢ Supports (insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂))) S
[PROOFSTEP]
try simp [Finset.subset_iff] at h₂
[GOAL]
case pred.intro
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q₁ q₂ : Λ'
q₁_ih : Λ'.Supports S q₁ → trStmts₁ q₁ ⊆ S → Supports (trStmts₁ q₁) S
q₂_ih : Λ'.Supports S q₂ → trStmts₁ q₂ ⊆ S → Supports (trStmts₁ q₂) S
H₁ : Λ'.Supports S (Λ'.pred q₁ q₂)
HS₁ : insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂)) ⊆ S
h₁ : Λ'.pred q₁ q₂ ∈ S
h₂ : insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂) ⊆ S
⊢ Supports (insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂))) S
[PROOFSTEP]
simp [Finset.subset_iff] at h₂
[GOAL]
case ret
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
k✝ : Cont'
H₁ : Λ'.Supports S (Λ'.ret k✝)
HS₁ : {Λ'.ret k✝} ⊆ S
⊢ Supports {Λ'.ret k✝} S
[PROOFSTEP]
cases' Finset.insert_subset_iff.1 HS₁ with h₁ h₂
[GOAL]
case move.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
p✝ : Γ' → Bool
k₁✝ k₂✝ : K'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.move p✝ k₁✝ k₂✝ q)
HS₁ : insert (Λ'.move p✝ k₁✝ k₂✝ q) (trStmts₁ q) ⊆ S
h₁ : Λ'.move p✝ k₁✝ k₂✝ q ∈ S
h₂ : trStmts₁ q ⊆ S
h₃ : q ∈ S
⊢ Supports (insert (Λ'.move p✝ k₁✝ k₂✝ q) (trStmts₁ q)) S
[PROOFSTEP]
exact
  supports_insert.2
    ⟨⟨fun _ => h₃, fun _ => h₁⟩, q_ih H₁ h₂⟩
      -- move
[GOAL]
case clear.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
p✝ : Γ' → Bool
k✝ : K'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.clear p✝ k✝ q)
HS₁ : insert (Λ'.clear p✝ k✝ q) (trStmts₁ q) ⊆ S
h₁ : Λ'.clear p✝ k✝ q ∈ S
h₂ : trStmts₁ q ⊆ S
h₃ : q ∈ S
⊢ Supports (insert (Λ'.clear p✝ k✝ q) (trStmts₁ q)) S
[PROOFSTEP]
exact
  supports_insert.2
    ⟨⟨fun _ => h₃, fun _ => h₁⟩, q_ih H₁ h₂⟩
      -- clear
[GOAL]
case copy.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.copy q)
HS₁ : insert (Λ'.copy q) (trStmts₁ q) ⊆ S
h₁ : Λ'.copy q ∈ S
h₂ : trStmts₁ q ⊆ S
h₃ : q ∈ S
⊢ Supports (insert (Λ'.copy q) (trStmts₁ q)) S
[PROOFSTEP]
exact
  supports_insert.2
    ⟨⟨fun _ => h₁, fun _ => h₃⟩, q_ih H₁ h₂⟩
      -- copy
[GOAL]
case push.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
k✝ : K'
s✝ : Option Γ' → Option Γ'
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.push k✝ s✝ q)
HS₁ : insert (Λ'.push k✝ s✝ q) (trStmts₁ q) ⊆ S
h₁ : Λ'.push k✝ s✝ q ∈ S
h₂ : trStmts₁ q ⊆ S
h₃ : q ∈ S
⊢ Supports (insert (Λ'.push k✝ s✝ q) (trStmts₁ q)) S
[PROOFSTEP]
exact
  supports_insert.2
    ⟨⟨fun _ => h₃, fun _ => h₃⟩, q_ih H₁ h₂⟩
      -- push
[GOAL]
case read.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), Λ'.Supports S (q a) → trStmts₁ (q a) ⊆ S → Supports (trStmts₁ (q a)) S
H₁ : Λ'.Supports S (Λ'.read q)
HS₁ : insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) ⊆ S
h₁ : Λ'.read q ∈ S
h₂ : ∀ ⦃x : Λ'⦄ (x_1 : Option Γ'), x ∈ trStmts₁ (q x_1) → x ∈ S
⊢ Supports (insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s))) S
[PROOFSTEP]
refine'
  supports_insert.2
    ⟨fun _ => h₂ _ W, _⟩
      -- read
[GOAL]
case read.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Option Γ' → Λ'
q_ih : ∀ (a : Option Γ'), Λ'.Supports S (q a) → trStmts₁ (q a) ⊆ S → Supports (trStmts₁ (q a)) S
H₁ : Λ'.Supports S (Λ'.read q)
HS₁ : insert (Λ'.read q) (Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) ⊆ S
h₁ : Λ'.read q ∈ S
h₂ : ∀ ⦃x : Λ'⦄ (x_1 : Option Γ'), x ∈ trStmts₁ (q x_1) → x ∈ S
⊢ Supports (Finset.biUnion Finset.univ fun s => trStmts₁ (q s)) S
[PROOFSTEP]
exact supports_biUnion.2 fun _ => q_ih _ (H₁ _) fun _ h => h₂ _ h
[GOAL]
case succ.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.succ q)
HS₁ : insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)) ⊆ S
h₁ : Λ'.succ q ∈ S
h₂ : unrev q ∈ S ∧ ∀ (a : Λ'), a ∈ trStmts₁ q → a ∈ S
⊢ Supports (insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q))) S
[PROOFSTEP]
refine'
  supports_insert.2
    ⟨⟨fun _ => h₁, fun _ => h₂.1, fun _ => h₂.1⟩, _⟩
      -- succ
[GOAL]
case succ.intro
S : Finset Λ'
q✝ : Λ'
H₁✝ : Λ'.Supports S q✝
HS₁✝ : trStmts₁ q✝ ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q : Λ'
q_ih : Λ'.Supports S q → trStmts₁ q ⊆ S → Supports (trStmts₁ q) S
H₁ : Λ'.Supports S (Λ'.succ q)
HS₁ : insert (Λ'.succ q) (insert (unrev q) (trStmts₁ q)) ⊆ S
h₁ : Λ'.succ q ∈ S
h₂ : unrev q ∈ S ∧ ∀ (a : Λ'), a ∈ trStmts₁ q → a ∈ S
⊢ Supports (insert (unrev q) (trStmts₁ q)) S
[PROOFSTEP]
exact supports_insert.2 ⟨⟨fun _ => h₂.2 _ W, fun _ => h₂.1⟩, q_ih H₁ h₂.2⟩
[GOAL]
case pred.intro
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q₁ q₂ : Λ'
q₁_ih : Λ'.Supports S q₁ → trStmts₁ q₁ ⊆ S → Supports (trStmts₁ q₁) S
q₂_ih : Λ'.Supports S q₂ → trStmts₁ q₂ ⊆ S → Supports (trStmts₁ q₂) S
H₁ : Λ'.Supports S (Λ'.pred q₁ q₂)
HS₁ : insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂)) ⊆ S
h₁ : Λ'.pred q₁ q₂ ∈ S
h₂ : unrev q₂ ∈ S ∧ ∀ (a : Λ'), a ∈ trStmts₁ q₁ ∨ a ∈ trStmts₁ q₂ → a ∈ S
⊢ Supports (insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂))) S
[PROOFSTEP]
refine'
  -- predsupports_insert.2 ⟨⟨fun _ => h₁, fun _ => h₂.2 _ (Or.inl W), fun _ => h₂.1, fun _ => h₂.1⟩, _⟩
[GOAL]
case pred.intro
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q₁ q₂ : Λ'
q₁_ih : Λ'.Supports S q₁ → trStmts₁ q₁ ⊆ S → Supports (trStmts₁ q₁) S
q₂_ih : Λ'.Supports S q₂ → trStmts₁ q₂ ⊆ S → Supports (trStmts₁ q₂) S
H₁ : Λ'.Supports S (Λ'.pred q₁ q₂)
HS₁ : insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂)) ⊆ S
h₁ : Λ'.pred q₁ q₂ ∈ S
h₂ : unrev q₂ ∈ S ∧ ∀ (a : Λ'), a ∈ trStmts₁ q₁ ∨ a ∈ trStmts₁ q₂ → a ∈ S
⊢ Supports (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂)) S
[PROOFSTEP]
refine' supports_insert.2 ⟨⟨fun _ => h₂.2 _ (Or.inr W), fun _ => h₂.1⟩, _⟩
[GOAL]
case pred.intro
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q₁ q₂ : Λ'
q₁_ih : Λ'.Supports S q₁ → trStmts₁ q₁ ⊆ S → Supports (trStmts₁ q₁) S
q₂_ih : Λ'.Supports S q₂ → trStmts₁ q₂ ⊆ S → Supports (trStmts₁ q₂) S
H₁ : Λ'.Supports S (Λ'.pred q₁ q₂)
HS₁ : insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂)) ⊆ S
h₁ : Λ'.pred q₁ q₂ ∈ S
h₂ : unrev q₂ ∈ S ∧ ∀ (a : Λ'), a ∈ trStmts₁ q₁ ∨ a ∈ trStmts₁ q₂ → a ∈ S
⊢ Supports (trStmts₁ q₁ ∪ trStmts₁ q₂) S
[PROOFSTEP]
refine' supports_union.2 ⟨_, _⟩
[GOAL]
case pred.intro.refine'_1
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q₁ q₂ : Λ'
q₁_ih : Λ'.Supports S q₁ → trStmts₁ q₁ ⊆ S → Supports (trStmts₁ q₁) S
q₂_ih : Λ'.Supports S q₂ → trStmts₁ q₂ ⊆ S → Supports (trStmts₁ q₂) S
H₁ : Λ'.Supports S (Λ'.pred q₁ q₂)
HS₁ : insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂)) ⊆ S
h₁ : Λ'.pred q₁ q₂ ∈ S
h₂ : unrev q₂ ∈ S ∧ ∀ (a : Λ'), a ∈ trStmts₁ q₁ ∨ a ∈ trStmts₁ q₂ → a ∈ S
⊢ Supports (trStmts₁ q₁) S
[PROOFSTEP]
exact q₁_ih H₁.1 fun _ h => h₂.2 _ (Or.inl h)
[GOAL]
case pred.intro.refine'_2
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
q₁ q₂ : Λ'
q₁_ih : Λ'.Supports S q₁ → trStmts₁ q₁ ⊆ S → Supports (trStmts₁ q₁) S
q₂_ih : Λ'.Supports S q₂ → trStmts₁ q₂ ⊆ S → Supports (trStmts₁ q₂) S
H₁ : Λ'.Supports S (Λ'.pred q₁ q₂)
HS₁ : insert (Λ'.pred q₁ q₂) (insert (unrev q₂) (trStmts₁ q₁ ∪ trStmts₁ q₂)) ⊆ S
h₁ : Λ'.pred q₁ q₂ ∈ S
h₂ : unrev q₂ ∈ S ∧ ∀ (a : Λ'), a ∈ trStmts₁ q₁ ∨ a ∈ trStmts₁ q₂ → a ∈ S
⊢ Supports (trStmts₁ q₂) S
[PROOFSTEP]
exact q₂_ih H₁.2 fun _ h => h₂.2 _ (Or.inr h)
[GOAL]
case ret
S : Finset Λ'
q : Λ'
H₁✝ : Λ'.Supports S q
HS₁✝ : trStmts₁ q ⊆ S
W : ∀ {q : Λ'}, q ∈ trStmts₁ q
k✝ : Cont'
H₁ : Λ'.Supports S (Λ'.ret k✝)
HS₁ : {Λ'.ret k✝} ⊆ S
⊢ Supports {Λ'.ret k✝} S
[PROOFSTEP]
exact
  supports_singleton.2
    (ret_supports H₁)
      -- ret
[GOAL]
S : Finset Λ'
q : Λ'
K : Finset Λ'
H₁ : Λ'.Supports S q
H₂ : trStmts₁ q ∪ K ⊆ S
H₃ : K ⊆ S → Supports K S
⊢ Supports (trStmts₁ q ∪ K) S
[PROOFSTEP]
simp [Finset.union_subset_iff] at H₂
[GOAL]
S : Finset Λ'
q : Λ'
K : Finset Λ'
H₁ : Λ'.Supports S q
H₃ : K ⊆ S → Supports K S
H₂ : trStmts₁ q ⊆ S ∧ K ⊆ S
⊢ Supports (trStmts₁ q ∪ K) S
[PROOFSTEP]
exact supports_union.2 ⟨trStmts₁_supports H₁ H₂.1, H₃ H₂.2⟩
[GOAL]
S : Finset Λ'
c : Code
k : Cont'
Hk : codeSupp c k ⊆ S
⊢ Λ'.Supports S (trNormal c k)
[PROOFSTEP]
induction c generalizing k
[GOAL]
case zero'
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.zero' k ⊆ S
⊢ Λ'.Supports S (trNormal Code.zero' k)
[PROOFSTEP]
simp [Λ'.Supports, head]
[GOAL]
case succ
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.succ k ⊆ S
⊢ Λ'.Supports S (trNormal Code.succ k)
[PROOFSTEP]
simp [Λ'.Supports, head]
[GOAL]
case tail
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.tail k ⊆ S
⊢ Λ'.Supports S (trNormal Code.tail k)
[PROOFSTEP]
simp [Λ'.Supports, head]
[GOAL]
case cons
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.cons a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal (Code.cons a✝¹ a✝) k)
[PROOFSTEP]
simp [Λ'.Supports, head]
[GOAL]
case comp
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.comp a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal (Code.comp a✝¹ a✝) k)
[PROOFSTEP]
simp [Λ'.Supports, head]
[GOAL]
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal (Code.case a✝¹ a✝) k)
[PROOFSTEP]
simp [Λ'.Supports, head]
[GOAL]
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.fix a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal (Code.fix a✝) k)
[PROOFSTEP]
simp [Λ'.Supports, head]
[GOAL]
case zero'
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.zero' k ⊆ S
⊢ contSupp k ⊆ S
case succ
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.succ k ⊆ S
⊢ ∀ (s : Option Γ'),
    Λ'.Supports S
      (ite (s = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev (Λ'.succ (Λ'.ret k))))
case tail
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.tail k ⊆ S
⊢ contSupp k ⊆ S
case cons
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.cons a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝¹ (Cont'.cons₁ a✝ k))
case comp
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.comp a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝ (Cont'.comp a✝¹ k))
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝¹ k) ∧ Λ'.Supports S (trNormal a✝ k)
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.fix a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝ (Cont'.fix a✝ k))
[PROOFSTEP]
case zero' => exact Finset.union_subset_right Hk
[GOAL]
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.zero' k ⊆ S
⊢ contSupp k ⊆ S
[PROOFSTEP]
case zero' => exact Finset.union_subset_right Hk
[GOAL]
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.zero' k ⊆ S
⊢ contSupp k ⊆ S
[PROOFSTEP]
exact Finset.union_subset_right Hk
[GOAL]
case succ
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.succ k ⊆ S
⊢ ∀ (s : Option Γ'),
    Λ'.Supports S
      (ite (s = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev (Λ'.succ (Λ'.ret k))))
case tail
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.tail k ⊆ S
⊢ contSupp k ⊆ S
case cons
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.cons a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝¹ (Cont'.cons₁ a✝ k))
case comp
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.comp a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝ (Cont'.comp a✝¹ k))
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝¹ k) ∧ Λ'.Supports S (trNormal a✝ k)
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.fix a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝ (Cont'.fix a✝ k))
[PROOFSTEP]
case succ => intro; split_ifs <;> exact Finset.union_subset_right Hk
[GOAL]
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.succ k ⊆ S
⊢ ∀ (s : Option Γ'),
    Λ'.Supports S
      (ite (s = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev (Λ'.succ (Λ'.ret k))))
[PROOFSTEP]
case succ => intro; split_ifs <;> exact Finset.union_subset_right Hk
[GOAL]
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.succ k ⊆ S
⊢ ∀ (s : Option Γ'),
    Λ'.Supports S
      (ite (s = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev (Λ'.succ (Λ'.ret k))))
[PROOFSTEP]
intro
[GOAL]
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.succ k ⊆ S
s✝ : Option Γ'
⊢ Λ'.Supports S
    (ite (s✝ = some Γ'.consₗ) id (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main) (unrev (Λ'.succ (Λ'.ret k))))
[PROOFSTEP]
split_ifs
[GOAL]
case pos
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.succ k ⊆ S
s✝ : Option Γ'
h✝ : s✝ = some Γ'.consₗ
⊢ Λ'.Supports S (id (unrev (Λ'.succ (Λ'.ret k))))
[PROOFSTEP]
exact Finset.union_subset_right Hk
[GOAL]
case neg
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.succ k ⊆ S
s✝ : Option Γ'
h✝ : ¬s✝ = some Γ'.consₗ
⊢ Λ'.Supports S (Λ'.clear (fun x => decide (x = Γ'.consₗ)) main (unrev (Λ'.succ (Λ'.ret k))))
[PROOFSTEP]
exact Finset.union_subset_right Hk
[GOAL]
case tail
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.tail k ⊆ S
⊢ contSupp k ⊆ S
case cons
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.cons a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝¹ (Cont'.cons₁ a✝ k))
case comp
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.comp a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝ (Cont'.comp a✝¹ k))
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝¹ k) ∧ Λ'.Supports S (trNormal a✝ k)
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.fix a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝ (Cont'.fix a✝ k))
[PROOFSTEP]
case tail => exact Finset.union_subset_right Hk
[GOAL]
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.tail k ⊆ S
⊢ contSupp k ⊆ S
[PROOFSTEP]
case tail => exact Finset.union_subset_right Hk
[GOAL]
S : Finset Λ'
k : Cont'
Hk : codeSupp Code.tail k ⊆ S
⊢ contSupp k ⊆ S
[PROOFSTEP]
exact Finset.union_subset_right Hk
[GOAL]
case cons
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.cons a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝¹ (Cont'.cons₁ a✝ k))
case comp
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.comp a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝ (Cont'.comp a✝¹ k))
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝¹ k) ∧ Λ'.Supports S (trNormal a✝ k)
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.fix a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝ (Cont'.fix a✝ k))
[PROOFSTEP]
case cons f fs IHf _ =>
  apply IHf
  rw [codeSupp_cons] at Hk
  exact Finset.union_subset_right Hk
[GOAL]
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
a_ih✝ : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Λ'.Supports S (trNormal fs k)
k : Cont'
Hk : codeSupp (Code.cons f fs) k ⊆ S
⊢ Λ'.Supports S (trNormal f (Cont'.cons₁ fs k))
[PROOFSTEP]
case cons f fs IHf _ =>
  apply IHf
  rw [codeSupp_cons] at Hk
  exact Finset.union_subset_right Hk
[GOAL]
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
a_ih✝ : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Λ'.Supports S (trNormal fs k)
k : Cont'
Hk : codeSupp (Code.cons f fs) k ⊆ S
⊢ Λ'.Supports S (trNormal f (Cont'.cons₁ fs k))
[PROOFSTEP]
apply IHf
[GOAL]
case Hk
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
a_ih✝ : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Λ'.Supports S (trNormal fs k)
k : Cont'
Hk : codeSupp (Code.cons f fs) k ⊆ S
⊢ codeSupp f (Cont'.cons₁ fs k) ⊆ S
[PROOFSTEP]
rw [codeSupp_cons] at Hk
[GOAL]
case Hk
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
a_ih✝ : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Λ'.Supports S (trNormal fs k)
k : Cont'
Hk : trStmts₁ (trNormal (Code.cons f fs) k) ∪ codeSupp f (Cont'.cons₁ fs k) ⊆ S
⊢ codeSupp f (Cont'.cons₁ fs k) ⊆ S
[PROOFSTEP]
exact Finset.union_subset_right Hk
[GOAL]
case comp
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.comp a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝ (Cont'.comp a✝¹ k))
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝¹ k) ∧ Λ'.Supports S (trNormal a✝ k)
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.fix a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝ (Cont'.fix a✝ k))
[PROOFSTEP]
case comp f g _ IHg => apply IHg; rw [codeSupp_comp] at Hk ; exact Finset.union_subset_right Hk
[GOAL]
S : Finset Λ'
f g : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Λ'.Supports S (trNormal g k)
k : Cont'
Hk : codeSupp (Code.comp f g) k ⊆ S
⊢ Λ'.Supports S (trNormal g (Cont'.comp f k))
[PROOFSTEP]
case comp f g _ IHg => apply IHg; rw [codeSupp_comp] at Hk ; exact Finset.union_subset_right Hk
[GOAL]
S : Finset Λ'
f g : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Λ'.Supports S (trNormal g k)
k : Cont'
Hk : codeSupp (Code.comp f g) k ⊆ S
⊢ Λ'.Supports S (trNormal g (Cont'.comp f k))
[PROOFSTEP]
apply IHg
[GOAL]
case Hk
S : Finset Λ'
f g : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Λ'.Supports S (trNormal g k)
k : Cont'
Hk : codeSupp (Code.comp f g) k ⊆ S
⊢ codeSupp g (Cont'.comp f k) ⊆ S
[PROOFSTEP]
rw [codeSupp_comp] at Hk
[GOAL]
case Hk
S : Finset Λ'
f g : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Λ'.Supports S (trNormal g k)
k : Cont'
Hk : trStmts₁ (trNormal (Code.comp f g) k) ∪ codeSupp g (Cont'.comp f k) ⊆ S
⊢ codeSupp g (Cont'.comp f k) ⊆ S
[PROOFSTEP]
exact Finset.union_subset_right Hk
[GOAL]
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Λ'.Supports S (trNormal a✝¹ k)
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝¹ k) ∧ Λ'.Supports S (trNormal a✝ k)
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.fix a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝ (Cont'.fix a✝ k))
[PROOFSTEP]
case case f g IHf IHg =>
  simp only [codeSupp_case, Finset.union_subset_iff] at Hk
  exact ⟨IHf Hk.2.1, IHg Hk.2.2⟩
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Λ'.Supports S (trNormal g k)
k : Cont'
Hk : codeSupp (Code.case f g) k ⊆ S
⊢ Λ'.Supports S (trNormal f k) ∧ Λ'.Supports S (trNormal g k)
[PROOFSTEP]
case case f g IHf IHg =>
  simp only [codeSupp_case, Finset.union_subset_iff] at Hk
  exact ⟨IHf Hk.2.1, IHg Hk.2.2⟩
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Λ'.Supports S (trNormal g k)
k : Cont'
Hk : codeSupp (Code.case f g) k ⊆ S
⊢ Λ'.Supports S (trNormal f k) ∧ Λ'.Supports S (trNormal g k)
[PROOFSTEP]
simp only [codeSupp_case, Finset.union_subset_iff] at Hk
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Λ'.Supports S (trNormal g k)
k : Cont'
Hk : trStmts₁ (trNormal (Code.case f g) k) ⊆ S ∧ codeSupp f k ⊆ S ∧ codeSupp g k ⊆ S
⊢ Λ'.Supports S (trNormal f k) ∧ Λ'.Supports S (trNormal g k)
[PROOFSTEP]
exact ⟨IHf Hk.2.1, IHg Hk.2.2⟩
[GOAL]
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Λ'.Supports S (trNormal a✝ k)
k : Cont'
Hk : codeSupp (Code.fix a✝) k ⊆ S
⊢ Λ'.Supports S (trNormal a✝ (Cont'.fix a✝ k))
[PROOFSTEP]
case fix f IHf => apply IHf; rw [codeSupp_fix] at Hk ; exact Finset.union_subset_right Hk
[GOAL]
S : Finset Λ'
f : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
k : Cont'
Hk : codeSupp (Code.fix f) k ⊆ S
⊢ Λ'.Supports S (trNormal f (Cont'.fix f k))
[PROOFSTEP]
case fix f IHf => apply IHf; rw [codeSupp_fix] at Hk ; exact Finset.union_subset_right Hk
[GOAL]
S : Finset Λ'
f : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
k : Cont'
Hk : codeSupp (Code.fix f) k ⊆ S
⊢ Λ'.Supports S (trNormal f (Cont'.fix f k))
[PROOFSTEP]
apply IHf
[GOAL]
case Hk
S : Finset Λ'
f : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
k : Cont'
Hk : codeSupp (Code.fix f) k ⊆ S
⊢ codeSupp f (Cont'.fix f k) ⊆ S
[PROOFSTEP]
rw [codeSupp_fix] at Hk
[GOAL]
case Hk
S : Finset Λ'
f : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Λ'.Supports S (trNormal f k)
k : Cont'
Hk : trStmts₁ (trNormal (Code.fix f) k) ∪ codeSupp f (Cont'.fix f k) ⊆ S
⊢ codeSupp f (Cont'.fix f k) ⊆ S
[PROOFSTEP]
exact Finset.union_subset_right Hk
[GOAL]
S : Finset Λ'
c : Code
k : Cont'
H : codeSupp c k ⊆ S
⊢ Supports (codeSupp' c k) S
[PROOFSTEP]
induction c generalizing k
[GOAL]
case zero'
S : Finset Λ'
k : Cont'
H : codeSupp Code.zero' k ⊆ S
⊢ Supports (codeSupp' Code.zero' k) S
case succ
S : Finset Λ'
k : Cont'
H : codeSupp Code.succ k ⊆ S
⊢ Supports (codeSupp' Code.succ k) S
case tail
S : Finset Λ'
k : Cont'
H : codeSupp Code.tail k ⊆ S
⊢ Supports (codeSupp' Code.tail k) S
case cons
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.cons a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.cons a✝¹ a✝) k) S
case comp
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.comp a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.comp a✝¹ a✝) k) S
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.case a✝¹ a✝) k) S
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.fix a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.fix a✝) k) S
[PROOFSTEP]
iterate 3 exact trStmts₁_supports (trNormal_supports H) (Finset.Subset.trans (codeSupp_self _ _) H)
[GOAL]
case zero'
S : Finset Λ'
k : Cont'
H : codeSupp Code.zero' k ⊆ S
⊢ Supports (codeSupp' Code.zero' k) S
case succ
S : Finset Λ'
k : Cont'
H : codeSupp Code.succ k ⊆ S
⊢ Supports (codeSupp' Code.succ k) S
case tail
S : Finset Λ'
k : Cont'
H : codeSupp Code.tail k ⊆ S
⊢ Supports (codeSupp' Code.tail k) S
case cons
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.cons a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.cons a✝¹ a✝) k) S
case comp
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.comp a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.comp a✝¹ a✝) k) S
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.case a✝¹ a✝) k) S
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.fix a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.fix a✝) k) S
[PROOFSTEP]
exact trStmts₁_supports (trNormal_supports H) (Finset.Subset.trans (codeSupp_self _ _) H)
[GOAL]
case succ
S : Finset Λ'
k : Cont'
H : codeSupp Code.succ k ⊆ S
⊢ Supports (codeSupp' Code.succ k) S
case tail
S : Finset Λ'
k : Cont'
H : codeSupp Code.tail k ⊆ S
⊢ Supports (codeSupp' Code.tail k) S
case cons
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.cons a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.cons a✝¹ a✝) k) S
case comp
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.comp a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.comp a✝¹ a✝) k) S
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.case a✝¹ a✝) k) S
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.fix a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.fix a✝) k) S
[PROOFSTEP]
exact trStmts₁_supports (trNormal_supports H) (Finset.Subset.trans (codeSupp_self _ _) H)
[GOAL]
case tail
S : Finset Λ'
k : Cont'
H : codeSupp Code.tail k ⊆ S
⊢ Supports (codeSupp' Code.tail k) S
case cons
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.cons a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.cons a✝¹ a✝) k) S
case comp
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.comp a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.comp a✝¹ a✝) k) S
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.case a✝¹ a✝) k) S
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.fix a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.fix a✝) k) S
[PROOFSTEP]
exact trStmts₁_supports (trNormal_supports H) (Finset.Subset.trans (codeSupp_self _ _) H)
[GOAL]
case cons
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.cons a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.cons a✝¹ a✝) k) S
case comp
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.comp a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.comp a✝¹ a✝) k) S
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.case a✝¹ a✝) k) S
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.fix a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.fix a✝) k) S
[PROOFSTEP]
case cons f fs IHf IHfs =>
  have H' := H; simp only [codeSupp_cons, Finset.union_subset_iff] at H'
  refine' trStmts₁_supports' (trNormal_supports H) (Finset.union_subset_left H) fun h => _
  refine' supports_union.2 ⟨IHf H'.2, _⟩
  refine' trStmts₁_supports' (trNormal_supports _) (Finset.union_subset_right h) fun h => _
  · simp only [codeSupp, Finset.union_subset_iff, contSupp] at h H ⊢
    exact ⟨h.2.2.1, h.2.2.2, H.2⟩
  refine' supports_union.2 ⟨IHfs _, _⟩
  · rw [codeSupp, contSupp_cons₁] at H'
    exact Finset.union_subset_right (Finset.union_subset_right H'.2)
  exact trStmts₁_supports (head_supports <| Finset.union_subset_right H) (Finset.union_subset_right h)
[GOAL]
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHfs : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Supports (codeSupp' fs k) S
k : Cont'
H : codeSupp (Code.cons f fs) k ⊆ S
⊢ Supports (codeSupp' (Code.cons f fs) k) S
[PROOFSTEP]
case cons f fs IHf IHfs =>
  have H' := H; simp only [codeSupp_cons, Finset.union_subset_iff] at H'
  refine' trStmts₁_supports' (trNormal_supports H) (Finset.union_subset_left H) fun h => _
  refine' supports_union.2 ⟨IHf H'.2, _⟩
  refine' trStmts₁_supports' (trNormal_supports _) (Finset.union_subset_right h) fun h => _
  · simp only [codeSupp, Finset.union_subset_iff, contSupp] at h H ⊢
    exact ⟨h.2.2.1, h.2.2.2, H.2⟩
  refine' supports_union.2 ⟨IHfs _, _⟩
  · rw [codeSupp, contSupp_cons₁] at H'
    exact Finset.union_subset_right (Finset.union_subset_right H'.2)
  exact trStmts₁_supports (head_supports <| Finset.union_subset_right H) (Finset.union_subset_right h)
[GOAL]
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHfs : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Supports (codeSupp' fs k) S
k : Cont'
H : codeSupp (Code.cons f fs) k ⊆ S
⊢ Supports (codeSupp' (Code.cons f fs) k) S
[PROOFSTEP]
have H' := H
[GOAL]
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHfs : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Supports (codeSupp' fs k) S
k : Cont'
H H' : codeSupp (Code.cons f fs) k ⊆ S
⊢ Supports (codeSupp' (Code.cons f fs) k) S
[PROOFSTEP]
simp only [codeSupp_cons, Finset.union_subset_iff] at H'
[GOAL]
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHfs : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Supports (codeSupp' fs k) S
k : Cont'
H : codeSupp (Code.cons f fs) k ⊆ S
H' : trStmts₁ (trNormal (Code.cons f fs) k) ⊆ S ∧ codeSupp f (Cont'.cons₁ fs k) ⊆ S
⊢ Supports (codeSupp' (Code.cons f fs) k) S
[PROOFSTEP]
refine' trStmts₁_supports' (trNormal_supports H) (Finset.union_subset_left H) fun h => _
[GOAL]
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHfs : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Supports (codeSupp' fs k) S
k : Cont'
H : codeSupp (Code.cons f fs) k ⊆ S
H' : trStmts₁ (trNormal (Code.cons f fs) k) ⊆ S ∧ codeSupp f (Cont'.cons₁ fs k) ⊆ S
h :
  codeSupp' f (Cont'.cons₁ fs k) ∪
      (trStmts₁
          (move₂ (fun x => false) main aux
            (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
              (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ k))))) ∪
        (codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k)))) ⊆
    S
⊢ Supports
    (codeSupp' f (Cont'.cons₁ fs k) ∪
      (trStmts₁
          (move₂ (fun x => false) main aux
            (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
              (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ k))))) ∪
        (codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k)))))
    S
[PROOFSTEP]
refine' supports_union.2 ⟨IHf H'.2, _⟩
[GOAL]
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHfs : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Supports (codeSupp' fs k) S
k : Cont'
H : codeSupp (Code.cons f fs) k ⊆ S
H' : trStmts₁ (trNormal (Code.cons f fs) k) ⊆ S ∧ codeSupp f (Cont'.cons₁ fs k) ⊆ S
h :
  codeSupp' f (Cont'.cons₁ fs k) ∪
      (trStmts₁
          (move₂ (fun x => false) main aux
            (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
              (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ k))))) ∪
        (codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k)))) ⊆
    S
⊢ Supports
    (trStmts₁
        (move₂ (fun x => false) main aux
          (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
            (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ k))))) ∪
      (codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k))))
    S
[PROOFSTEP]
refine' trStmts₁_supports' (trNormal_supports _) (Finset.union_subset_right h) fun h => _
[GOAL]
case refine'_1
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHfs : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Supports (codeSupp' fs k) S
k : Cont'
H : codeSupp (Code.cons f fs) k ⊆ S
H' : trStmts₁ (trNormal (Code.cons f fs) k) ⊆ S ∧ codeSupp f (Cont'.cons₁ fs k) ⊆ S
h :
  codeSupp' f (Cont'.cons₁ fs k) ∪
      (trStmts₁
          (move₂ (fun x => false) main aux
            (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
              (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ k))))) ∪
        (codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k)))) ⊆
    S
⊢ codeSupp fs (Cont'.cons₂ k) ⊆ S
[PROOFSTEP]
simp only [codeSupp, Finset.union_subset_iff, contSupp] at h H ⊢
[GOAL]
case refine'_1
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHfs : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Supports (codeSupp' fs k) S
k : Cont'
H' : trStmts₁ (trNormal (Code.cons f fs) k) ⊆ S ∧ codeSupp f (Cont'.cons₁ fs k) ⊆ S
h :
  codeSupp' f (Cont'.cons₁ fs k) ⊆ S ∧
    trStmts₁
          (move₂ (fun x => false) main aux
            (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
              (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ k))))) ⊆
        S ∧
      codeSupp' fs (Cont'.cons₂ k) ⊆ S ∧ trStmts₁ (head stack (Λ'.ret k)) ⊆ S
H : codeSupp' (Code.cons f fs) k ⊆ S ∧ contSupp k ⊆ S
⊢ codeSupp' fs (Cont'.cons₂ k) ⊆ S ∧ trStmts₁ (head stack (Λ'.ret k)) ⊆ S ∧ contSupp k ⊆ S
[PROOFSTEP]
exact ⟨h.2.2.1, h.2.2.2, H.2⟩
[GOAL]
case refine'_2
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHfs : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Supports (codeSupp' fs k) S
k : Cont'
H : codeSupp (Code.cons f fs) k ⊆ S
H' : trStmts₁ (trNormal (Code.cons f fs) k) ⊆ S ∧ codeSupp f (Cont'.cons₁ fs k) ⊆ S
h✝ :
  codeSupp' f (Cont'.cons₁ fs k) ∪
      (trStmts₁
          (move₂ (fun x => false) main aux
            (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
              (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ k))))) ∪
        (codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k)))) ⊆
    S
h : codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k)) ⊆ S
⊢ Supports (codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k))) S
[PROOFSTEP]
refine' supports_union.2 ⟨IHfs _, _⟩
[GOAL]
case refine'_2.refine'_1
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHfs : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Supports (codeSupp' fs k) S
k : Cont'
H : codeSupp (Code.cons f fs) k ⊆ S
H' : trStmts₁ (trNormal (Code.cons f fs) k) ⊆ S ∧ codeSupp f (Cont'.cons₁ fs k) ⊆ S
h✝ :
  codeSupp' f (Cont'.cons₁ fs k) ∪
      (trStmts₁
          (move₂ (fun x => false) main aux
            (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
              (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ k))))) ∪
        (codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k)))) ⊆
    S
h : codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k)) ⊆ S
⊢ codeSupp fs (Cont'.cons₂ k) ⊆ S
[PROOFSTEP]
rw [codeSupp, contSupp_cons₁] at H'
[GOAL]
case refine'_2.refine'_1
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHfs : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Supports (codeSupp' fs k) S
k : Cont'
H : codeSupp (Code.cons f fs) k ⊆ S
H' :
  trStmts₁ (trNormal (Code.cons f fs) k) ⊆ S ∧
    codeSupp' f (Cont'.cons₁ fs k) ∪
        (trStmts₁
            (move₂ (fun x => false) main aux
              (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
                (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ k))))) ∪
          codeSupp fs (Cont'.cons₂ k)) ⊆
      S
h✝ :
  codeSupp' f (Cont'.cons₁ fs k) ∪
      (trStmts₁
          (move₂ (fun x => false) main aux
            (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
              (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ k))))) ∪
        (codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k)))) ⊆
    S
h : codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k)) ⊆ S
⊢ codeSupp fs (Cont'.cons₂ k) ⊆ S
[PROOFSTEP]
exact Finset.union_subset_right (Finset.union_subset_right H'.2)
[GOAL]
case refine'_2.refine'_2
S : Finset Λ'
f fs : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHfs : ∀ {k : Cont'}, codeSupp fs k ⊆ S → Supports (codeSupp' fs k) S
k : Cont'
H : codeSupp (Code.cons f fs) k ⊆ S
H' : trStmts₁ (trNormal (Code.cons f fs) k) ⊆ S ∧ codeSupp f (Cont'.cons₁ fs k) ⊆ S
h✝ :
  codeSupp' f (Cont'.cons₁ fs k) ∪
      (trStmts₁
          (move₂ (fun x => false) main aux
            (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
              (move₂ (fun x => false) aux stack (trNormal fs (Cont'.cons₂ k))))) ∪
        (codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k)))) ⊆
    S
h : codeSupp' fs (Cont'.cons₂ k) ∪ trStmts₁ (head stack (Λ'.ret k)) ⊆ S
⊢ Supports (trStmts₁ (head stack (Λ'.ret k))) S
[PROOFSTEP]
exact trStmts₁_supports (head_supports <| Finset.union_subset_right H) (Finset.union_subset_right h)
[GOAL]
case comp
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.comp a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.comp a✝¹ a✝) k) S
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.case a✝¹ a✝) k) S
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.fix a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.fix a✝) k) S
[PROOFSTEP]
case comp f g IHf IHg =>
  have H' := H; rw [codeSupp_comp] at H' ; have H' := Finset.union_subset_right H'
  refine' trStmts₁_supports' (trNormal_supports H) (Finset.union_subset_left H) fun h => _
  refine' supports_union.2 ⟨IHg H', _⟩
  refine' trStmts₁_supports' (trNormal_supports _) (Finset.union_subset_right h) fun _ => _
  · simp only [codeSupp', codeSupp, Finset.union_subset_iff, contSupp] at h H ⊢
    exact ⟨h.2.2, H.2⟩
  exact IHf (Finset.union_subset_right H')
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H : codeSupp (Code.comp f g) k ⊆ S
⊢ Supports (codeSupp' (Code.comp f g) k) S
[PROOFSTEP]
case comp f g IHf IHg =>
  have H' := H; rw [codeSupp_comp] at H' ; have H' := Finset.union_subset_right H'
  refine' trStmts₁_supports' (trNormal_supports H) (Finset.union_subset_left H) fun h => _
  refine' supports_union.2 ⟨IHg H', _⟩
  refine' trStmts₁_supports' (trNormal_supports _) (Finset.union_subset_right h) fun _ => _
  · simp only [codeSupp', codeSupp, Finset.union_subset_iff, contSupp] at h H ⊢
    exact ⟨h.2.2, H.2⟩
  exact IHf (Finset.union_subset_right H')
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H : codeSupp (Code.comp f g) k ⊆ S
⊢ Supports (codeSupp' (Code.comp f g) k) S
[PROOFSTEP]
have H' := H
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H H' : codeSupp (Code.comp f g) k ⊆ S
⊢ Supports (codeSupp' (Code.comp f g) k) S
[PROOFSTEP]
rw [codeSupp_comp] at H'
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H : codeSupp (Code.comp f g) k ⊆ S
H' : trStmts₁ (trNormal (Code.comp f g) k) ∪ codeSupp g (Cont'.comp f k) ⊆ S
⊢ Supports (codeSupp' (Code.comp f g) k) S
[PROOFSTEP]
have H' := Finset.union_subset_right H'
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H : codeSupp (Code.comp f g) k ⊆ S
H'✝ : trStmts₁ (trNormal (Code.comp f g) k) ∪ codeSupp g (Cont'.comp f k) ⊆ S
H' : codeSupp g (Cont'.comp f k) ⊆ S
⊢ Supports (codeSupp' (Code.comp f g) k) S
[PROOFSTEP]
refine' trStmts₁_supports' (trNormal_supports H) (Finset.union_subset_left H) fun h => _
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H : codeSupp (Code.comp f g) k ⊆ S
H'✝ : trStmts₁ (trNormal (Code.comp f g) k) ∪ codeSupp g (Cont'.comp f k) ⊆ S
H' : codeSupp g (Cont'.comp f k) ⊆ S
h : codeSupp' g (Cont'.comp f k) ∪ (trStmts₁ (trNormal f k) ∪ codeSupp' f k) ⊆ S
⊢ Supports (codeSupp' g (Cont'.comp f k) ∪ (trStmts₁ (trNormal f k) ∪ codeSupp' f k)) S
[PROOFSTEP]
refine' supports_union.2 ⟨IHg H', _⟩
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H : codeSupp (Code.comp f g) k ⊆ S
H'✝ : trStmts₁ (trNormal (Code.comp f g) k) ∪ codeSupp g (Cont'.comp f k) ⊆ S
H' : codeSupp g (Cont'.comp f k) ⊆ S
h : codeSupp' g (Cont'.comp f k) ∪ (trStmts₁ (trNormal f k) ∪ codeSupp' f k) ⊆ S
⊢ Supports (trStmts₁ (trNormal f k) ∪ codeSupp' f k) S
[PROOFSTEP]
refine' trStmts₁_supports' (trNormal_supports _) (Finset.union_subset_right h) fun _ => _
[GOAL]
case refine'_1
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H : codeSupp (Code.comp f g) k ⊆ S
H'✝ : trStmts₁ (trNormal (Code.comp f g) k) ∪ codeSupp g (Cont'.comp f k) ⊆ S
H' : codeSupp g (Cont'.comp f k) ⊆ S
h : codeSupp' g (Cont'.comp f k) ∪ (trStmts₁ (trNormal f k) ∪ codeSupp' f k) ⊆ S
⊢ codeSupp f k ⊆ S
[PROOFSTEP]
simp only [codeSupp', codeSupp, Finset.union_subset_iff, contSupp] at h H ⊢
[GOAL]
case refine'_1
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H'✝ : trStmts₁ (trNormal (Code.comp f g) k) ∪ codeSupp g (Cont'.comp f k) ⊆ S
H' : codeSupp g (Cont'.comp f k) ⊆ S
h : codeSupp' g (Cont'.comp f k) ⊆ S ∧ trStmts₁ (trNormal f k) ⊆ S ∧ codeSupp' f k ⊆ S
H :
  (trStmts₁ (trNormal (Code.comp f g) k) ⊆ S ∧
      codeSupp' g (Cont'.comp f k) ⊆ S ∧ trStmts₁ (trNormal f k) ⊆ S ∧ codeSupp' f k ⊆ S) ∧
    contSupp k ⊆ S
⊢ codeSupp' f k ⊆ S ∧ contSupp k ⊆ S
[PROOFSTEP]
exact ⟨h.2.2, H.2⟩
[GOAL]
case refine'_2
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H : codeSupp (Code.comp f g) k ⊆ S
H'✝ : trStmts₁ (trNormal (Code.comp f g) k) ∪ codeSupp g (Cont'.comp f k) ⊆ S
H' : codeSupp g (Cont'.comp f k) ⊆ S
h : codeSupp' g (Cont'.comp f k) ∪ (trStmts₁ (trNormal f k) ∪ codeSupp' f k) ⊆ S
x✝ : codeSupp' f k ⊆ S
⊢ Supports (codeSupp' f k) S
[PROOFSTEP]
exact IHf (Finset.union_subset_right H')
[GOAL]
case case
S : Finset Λ'
a✝¹ a✝ : Code
a_ih✝¹ : ∀ {k : Cont'}, codeSupp a✝¹ k ⊆ S → Supports (codeSupp' a✝¹ k) S
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.case a✝¹ a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.case a✝¹ a✝) k) S
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.fix a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.fix a✝) k) S
[PROOFSTEP]
case case f g IHf IHg =>
  have H' := H; simp only [codeSupp_case, Finset.union_subset_iff] at H'
  refine' trStmts₁_supports' (trNormal_supports H) (Finset.union_subset_left H) fun _ => _
  exact supports_union.2 ⟨IHf H'.2.1, IHg H'.2.2⟩
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H : codeSupp (Code.case f g) k ⊆ S
⊢ Supports (codeSupp' (Code.case f g) k) S
[PROOFSTEP]
case case f g IHf IHg =>
  have H' := H; simp only [codeSupp_case, Finset.union_subset_iff] at H'
  refine' trStmts₁_supports' (trNormal_supports H) (Finset.union_subset_left H) fun _ => _
  exact supports_union.2 ⟨IHf H'.2.1, IHg H'.2.2⟩
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H : codeSupp (Code.case f g) k ⊆ S
⊢ Supports (codeSupp' (Code.case f g) k) S
[PROOFSTEP]
have H' := H
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H H' : codeSupp (Code.case f g) k ⊆ S
⊢ Supports (codeSupp' (Code.case f g) k) S
[PROOFSTEP]
simp only [codeSupp_case, Finset.union_subset_iff] at H'
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H : codeSupp (Code.case f g) k ⊆ S
H' : trStmts₁ (trNormal (Code.case f g) k) ⊆ S ∧ codeSupp f k ⊆ S ∧ codeSupp g k ⊆ S
⊢ Supports (codeSupp' (Code.case f g) k) S
[PROOFSTEP]
refine' trStmts₁_supports' (trNormal_supports H) (Finset.union_subset_left H) fun _ => _
[GOAL]
S : Finset Λ'
f g : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
IHg : ∀ {k : Cont'}, codeSupp g k ⊆ S → Supports (codeSupp' g k) S
k : Cont'
H : codeSupp (Code.case f g) k ⊆ S
H' : trStmts₁ (trNormal (Code.case f g) k) ⊆ S ∧ codeSupp f k ⊆ S ∧ codeSupp g k ⊆ S
x✝ : codeSupp' f k ∪ codeSupp' g k ⊆ S
⊢ Supports (codeSupp' f k ∪ codeSupp' g k) S
[PROOFSTEP]
exact supports_union.2 ⟨IHf H'.2.1, IHg H'.2.2⟩
[GOAL]
case fix
S : Finset Λ'
a✝ : Code
a_ih✝ : ∀ {k : Cont'}, codeSupp a✝ k ⊆ S → Supports (codeSupp' a✝ k) S
k : Cont'
H : codeSupp (Code.fix a✝) k ⊆ S
⊢ Supports (codeSupp' (Code.fix a✝) k) S
[PROOFSTEP]
case fix f IHf =>
  have H' := H; simp only [codeSupp_fix, Finset.union_subset_iff] at H'
  refine' trStmts₁_supports' (trNormal_supports H) (Finset.union_subset_left H) fun h => _
  refine' supports_union.2 ⟨IHf H'.2, _⟩
  refine' trStmts₁_supports' (trNormal_supports _) (Finset.union_subset_right h) fun _ => _
  · simp only [codeSupp', codeSupp, Finset.union_subset_iff, contSupp, trStmts₁, Finset.insert_subset_iff] at h H ⊢
    exact ⟨h.1, ⟨H.1.1, h⟩, H.2⟩
  exact supports_singleton.2 (ret_supports <| Finset.union_subset_right H)
[GOAL]
S : Finset Λ'
f : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
k : Cont'
H : codeSupp (Code.fix f) k ⊆ S
⊢ Supports (codeSupp' (Code.fix f) k) S
[PROOFSTEP]
case fix f IHf =>
  have H' := H; simp only [codeSupp_fix, Finset.union_subset_iff] at H'
  refine' trStmts₁_supports' (trNormal_supports H) (Finset.union_subset_left H) fun h => _
  refine' supports_union.2 ⟨IHf H'.2, _⟩
  refine' trStmts₁_supports' (trNormal_supports _) (Finset.union_subset_right h) fun _ => _
  · simp only [codeSupp', codeSupp, Finset.union_subset_iff, contSupp, trStmts₁, Finset.insert_subset_iff] at h H ⊢
    exact ⟨h.1, ⟨H.1.1, h⟩, H.2⟩
  exact supports_singleton.2 (ret_supports <| Finset.union_subset_right H)
[GOAL]
S : Finset Λ'
f : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
k : Cont'
H : codeSupp (Code.fix f) k ⊆ S
⊢ Supports (codeSupp' (Code.fix f) k) S
[PROOFSTEP]
have H' := H
[GOAL]
S : Finset Λ'
f : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
k : Cont'
H H' : codeSupp (Code.fix f) k ⊆ S
⊢ Supports (codeSupp' (Code.fix f) k) S
[PROOFSTEP]
simp only [codeSupp_fix, Finset.union_subset_iff] at H'
[GOAL]
S : Finset Λ'
f : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
k : Cont'
H : codeSupp (Code.fix f) k ⊆ S
H' : trStmts₁ (trNormal (Code.fix f) k) ⊆ S ∧ codeSupp f (Cont'.fix f k) ⊆ S
⊢ Supports (codeSupp' (Code.fix f) k) S
[PROOFSTEP]
refine' trStmts₁_supports' (trNormal_supports H) (Finset.union_subset_left H) fun h => _
[GOAL]
S : Finset Λ'
f : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
k : Cont'
H : codeSupp (Code.fix f) k ⊆ S
H' : trStmts₁ (trNormal (Code.fix f) k) ⊆ S ∧ codeSupp f (Cont'.fix f k) ⊆ S
h : codeSupp' f (Cont'.fix f k) ∪ (trStmts₁ (Λ'.clear natEnd main (trNormal f (Cont'.fix f k))) ∪ {Λ'.ret k}) ⊆ S
⊢ Supports (codeSupp' f (Cont'.fix f k) ∪ (trStmts₁ (Λ'.clear natEnd main (trNormal f (Cont'.fix f k))) ∪ {Λ'.ret k})) S
[PROOFSTEP]
refine' supports_union.2 ⟨IHf H'.2, _⟩
[GOAL]
S : Finset Λ'
f : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
k : Cont'
H : codeSupp (Code.fix f) k ⊆ S
H' : trStmts₁ (trNormal (Code.fix f) k) ⊆ S ∧ codeSupp f (Cont'.fix f k) ⊆ S
h : codeSupp' f (Cont'.fix f k) ∪ (trStmts₁ (Λ'.clear natEnd main (trNormal f (Cont'.fix f k))) ∪ {Λ'.ret k}) ⊆ S
⊢ Supports (trStmts₁ (Λ'.clear natEnd main (trNormal f (Cont'.fix f k))) ∪ {Λ'.ret k}) S
[PROOFSTEP]
refine' trStmts₁_supports' (trNormal_supports _) (Finset.union_subset_right h) fun _ => _
[GOAL]
case refine'_1
S : Finset Λ'
f : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
k : Cont'
H : codeSupp (Code.fix f) k ⊆ S
H' : trStmts₁ (trNormal (Code.fix f) k) ⊆ S ∧ codeSupp f (Cont'.fix f k) ⊆ S
h : codeSupp' f (Cont'.fix f k) ∪ (trStmts₁ (Λ'.clear natEnd main (trNormal f (Cont'.fix f k))) ∪ {Λ'.ret k}) ⊆ S
⊢ codeSupp f (Cont'.fix f k) ⊆ S
[PROOFSTEP]
simp only [codeSupp', codeSupp, Finset.union_subset_iff, contSupp, trStmts₁, Finset.insert_subset_iff] at h H ⊢
[GOAL]
case refine'_1
S : Finset Λ'
f : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
k : Cont'
H' : trStmts₁ (trNormal (Code.fix f) k) ⊆ S ∧ codeSupp f (Cont'.fix f k) ⊆ S
h :
  codeSupp' f (Cont'.fix f k) ⊆ S ∧
    (Λ'.clear natEnd main (trNormal f (Cont'.fix f k)) ∈ S ∧ trStmts₁ (trNormal f (Cont'.fix f k)) ⊆ S) ∧ {Λ'.ret k} ⊆ S
H :
  (trStmts₁ (trNormal (Code.fix f) k) ⊆ S ∧
      codeSupp' f (Cont'.fix f k) ⊆ S ∧
        (Λ'.clear natEnd main (trNormal f (Cont'.fix f k)) ∈ S ∧ trStmts₁ (trNormal f (Cont'.fix f k)) ⊆ S) ∧
          {Λ'.ret k} ⊆ S) ∧
    contSupp k ⊆ S
⊢ codeSupp' f (Cont'.fix f k) ⊆ S ∧
    (trStmts₁ (trNormal (Code.fix f) k) ⊆ S ∧
        codeSupp' f (Cont'.fix f k) ⊆ S ∧
          (Λ'.clear natEnd main (trNormal f (Cont'.fix f k)) ∈ S ∧ trStmts₁ (trNormal f (Cont'.fix f k)) ⊆ S) ∧
            {Λ'.ret k} ⊆ S) ∧
      contSupp k ⊆ S
[PROOFSTEP]
exact ⟨h.1, ⟨H.1.1, h⟩, H.2⟩
[GOAL]
case refine'_2
S : Finset Λ'
f : Code
IHf : ∀ {k : Cont'}, codeSupp f k ⊆ S → Supports (codeSupp' f k) S
k : Cont'
H : codeSupp (Code.fix f) k ⊆ S
H' : trStmts₁ (trNormal (Code.fix f) k) ⊆ S ∧ codeSupp f (Cont'.fix f k) ⊆ S
h : codeSupp' f (Cont'.fix f k) ∪ (trStmts₁ (Λ'.clear natEnd main (trNormal f (Cont'.fix f k))) ∪ {Λ'.ret k}) ⊆ S
x✝ : {Λ'.ret k} ⊆ S
⊢ Supports {Λ'.ret k} S
[PROOFSTEP]
exact supports_singleton.2 (ret_supports <| Finset.union_subset_right H)
[GOAL]
S : Finset Λ'
k : Cont'
H : contSupp k ⊆ S
⊢ Supports (contSupp k) S
[PROOFSTEP]
induction k
[GOAL]
case halt
S : Finset Λ'
H : contSupp Cont'.halt ⊆ S
⊢ Supports (contSupp Cont'.halt) S
[PROOFSTEP]
simp [contSupp_halt, Supports]
[GOAL]
case cons₁
S : Finset Λ'
a✝¹ : Code
a✝ : Cont'
a_ih✝ : contSupp a✝ ⊆ S → Supports (contSupp a✝) S
H : contSupp (Cont'.cons₁ a✝¹ a✝) ⊆ S
⊢ Supports (contSupp (Cont'.cons₁ a✝¹ a✝)) S
case cons₂
S : Finset Λ'
a✝ : Cont'
a_ih✝ : contSupp a✝ ⊆ S → Supports (contSupp a✝) S
H : contSupp (Cont'.cons₂ a✝) ⊆ S
⊢ Supports (contSupp (Cont'.cons₂ a✝)) S
case comp
S : Finset Λ'
a✝¹ : Code
a✝ : Cont'
a_ih✝ : contSupp a✝ ⊆ S → Supports (contSupp a✝) S
H : contSupp (Cont'.comp a✝¹ a✝) ⊆ S
⊢ Supports (contSupp (Cont'.comp a✝¹ a✝)) S
case fix
S : Finset Λ'
a✝¹ : Code
a✝ : Cont'
a_ih✝ : contSupp a✝ ⊆ S → Supports (contSupp a✝) S
H : contSupp (Cont'.fix a✝¹ a✝) ⊆ S
⊢ Supports (contSupp (Cont'.fix a✝¹ a✝)) S
[PROOFSTEP]
case cons₁ f k IH =>
  have H₁ := H; rw [contSupp_cons₁] at H₁ ; have H₂ := Finset.union_subset_right H₁
  refine' trStmts₁_supports' (trNormal_supports H₂) H₁ fun h => _
  refine' supports_union.2 ⟨codeSupp'_supports H₂, _⟩
  simp only [codeSupp, contSupp_cons₂, Finset.union_subset_iff] at H₂
  exact trStmts₁_supports' (head_supports H₂.2.2) (Finset.union_subset_right h) IH
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.cons₁ f k) ⊆ S
⊢ Supports (contSupp (Cont'.cons₁ f k)) S
[PROOFSTEP]
case cons₁ f k IH =>
  have H₁ := H; rw [contSupp_cons₁] at H₁ ; have H₂ := Finset.union_subset_right H₁
  refine' trStmts₁_supports' (trNormal_supports H₂) H₁ fun h => _
  refine' supports_union.2 ⟨codeSupp'_supports H₂, _⟩
  simp only [codeSupp, contSupp_cons₂, Finset.union_subset_iff] at H₂
  exact trStmts₁_supports' (head_supports H₂.2.2) (Finset.union_subset_right h) IH
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.cons₁ f k) ⊆ S
⊢ Supports (contSupp (Cont'.cons₁ f k)) S
[PROOFSTEP]
have H₁ := H
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H H₁ : contSupp (Cont'.cons₁ f k) ⊆ S
⊢ Supports (contSupp (Cont'.cons₁ f k)) S
[PROOFSTEP]
rw [contSupp_cons₁] at H₁
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.cons₁ f k) ⊆ S
H₁ :
  trStmts₁
        (move₂ (fun x => false) main aux
          (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
            (move₂ (fun x => false) aux stack (trNormal f (Cont'.cons₂ k))))) ∪
      codeSupp f (Cont'.cons₂ k) ⊆
    S
⊢ Supports (contSupp (Cont'.cons₁ f k)) S
[PROOFSTEP]
have H₂ := Finset.union_subset_right H₁
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.cons₁ f k) ⊆ S
H₁ :
  trStmts₁
        (move₂ (fun x => false) main aux
          (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
            (move₂ (fun x => false) aux stack (trNormal f (Cont'.cons₂ k))))) ∪
      codeSupp f (Cont'.cons₂ k) ⊆
    S
H₂ : codeSupp f (Cont'.cons₂ k) ⊆ S
⊢ Supports (contSupp (Cont'.cons₁ f k)) S
[PROOFSTEP]
refine' trStmts₁_supports' (trNormal_supports H₂) H₁ fun h => _
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.cons₁ f k) ⊆ S
H₁ :
  trStmts₁
        (move₂ (fun x => false) main aux
          (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
            (move₂ (fun x => false) aux stack (trNormal f (Cont'.cons₂ k))))) ∪
      codeSupp f (Cont'.cons₂ k) ⊆
    S
H₂ : codeSupp f (Cont'.cons₂ k) ⊆ S
h : codeSupp' f (Cont'.cons₂ k) ∪ (trStmts₁ (head stack (Λ'.ret k)) ∪ contSupp k) ⊆ S
⊢ Supports (codeSupp' f (Cont'.cons₂ k) ∪ (trStmts₁ (head stack (Λ'.ret k)) ∪ contSupp k)) S
[PROOFSTEP]
refine' supports_union.2 ⟨codeSupp'_supports H₂, _⟩
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.cons₁ f k) ⊆ S
H₁ :
  trStmts₁
        (move₂ (fun x => false) main aux
          (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
            (move₂ (fun x => false) aux stack (trNormal f (Cont'.cons₂ k))))) ∪
      codeSupp f (Cont'.cons₂ k) ⊆
    S
H₂ : codeSupp f (Cont'.cons₂ k) ⊆ S
h : codeSupp' f (Cont'.cons₂ k) ∪ (trStmts₁ (head stack (Λ'.ret k)) ∪ contSupp k) ⊆ S
⊢ Supports (trStmts₁ (head stack (Λ'.ret k)) ∪ contSupp k) S
[PROOFSTEP]
simp only [codeSupp, contSupp_cons₂, Finset.union_subset_iff] at H₂
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.cons₁ f k) ⊆ S
H₁ :
  trStmts₁
        (move₂ (fun x => false) main aux
          (move₂ (fun s => decide (s = Γ'.consₗ)) stack main
            (move₂ (fun x => false) aux stack (trNormal f (Cont'.cons₂ k))))) ∪
      codeSupp f (Cont'.cons₂ k) ⊆
    S
h : codeSupp' f (Cont'.cons₂ k) ∪ (trStmts₁ (head stack (Λ'.ret k)) ∪ contSupp k) ⊆ S
H₂ : codeSupp' f (Cont'.cons₂ k) ⊆ S ∧ trStmts₁ (head stack (Λ'.ret k)) ⊆ S ∧ contSupp k ⊆ S
⊢ Supports (trStmts₁ (head stack (Λ'.ret k)) ∪ contSupp k) S
[PROOFSTEP]
exact trStmts₁_supports' (head_supports H₂.2.2) (Finset.union_subset_right h) IH
[GOAL]
case cons₂
S : Finset Λ'
a✝ : Cont'
a_ih✝ : contSupp a✝ ⊆ S → Supports (contSupp a✝) S
H : contSupp (Cont'.cons₂ a✝) ⊆ S
⊢ Supports (contSupp (Cont'.cons₂ a✝)) S
case comp
S : Finset Λ'
a✝¹ : Code
a✝ : Cont'
a_ih✝ : contSupp a✝ ⊆ S → Supports (contSupp a✝) S
H : contSupp (Cont'.comp a✝¹ a✝) ⊆ S
⊢ Supports (contSupp (Cont'.comp a✝¹ a✝)) S
case fix
S : Finset Λ'
a✝¹ : Code
a✝ : Cont'
a_ih✝ : contSupp a✝ ⊆ S → Supports (contSupp a✝) S
H : contSupp (Cont'.fix a✝¹ a✝) ⊆ S
⊢ Supports (contSupp (Cont'.fix a✝¹ a✝)) S
[PROOFSTEP]
case cons₂ k IH =>
  have H' := H; rw [contSupp_cons₂] at H'
  exact trStmts₁_supports' (head_supports <| Finset.union_subset_right H') H' IH
[GOAL]
S : Finset Λ'
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.cons₂ k) ⊆ S
⊢ Supports (contSupp (Cont'.cons₂ k)) S
[PROOFSTEP]
case cons₂ k IH =>
  have H' := H; rw [contSupp_cons₂] at H'
  exact trStmts₁_supports' (head_supports <| Finset.union_subset_right H') H' IH
[GOAL]
S : Finset Λ'
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.cons₂ k) ⊆ S
⊢ Supports (contSupp (Cont'.cons₂ k)) S
[PROOFSTEP]
have H' := H
[GOAL]
S : Finset Λ'
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H H' : contSupp (Cont'.cons₂ k) ⊆ S
⊢ Supports (contSupp (Cont'.cons₂ k)) S
[PROOFSTEP]
rw [contSupp_cons₂] at H'
[GOAL]
S : Finset Λ'
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.cons₂ k) ⊆ S
H' : trStmts₁ (head stack (Λ'.ret k)) ∪ contSupp k ⊆ S
⊢ Supports (contSupp (Cont'.cons₂ k)) S
[PROOFSTEP]
exact trStmts₁_supports' (head_supports <| Finset.union_subset_right H') H' IH
[GOAL]
case comp
S : Finset Λ'
a✝¹ : Code
a✝ : Cont'
a_ih✝ : contSupp a✝ ⊆ S → Supports (contSupp a✝) S
H : contSupp (Cont'.comp a✝¹ a✝) ⊆ S
⊢ Supports (contSupp (Cont'.comp a✝¹ a✝)) S
case fix
S : Finset Λ'
a✝¹ : Code
a✝ : Cont'
a_ih✝ : contSupp a✝ ⊆ S → Supports (contSupp a✝) S
H : contSupp (Cont'.fix a✝¹ a✝) ⊆ S
⊢ Supports (contSupp (Cont'.fix a✝¹ a✝)) S
[PROOFSTEP]
case comp f k IH =>
  have H' := H; rw [contSupp_comp] at H' ; have H₂ := Finset.union_subset_right H'
  exact supports_union.2 ⟨codeSupp'_supports H', IH H₂⟩
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.comp f k) ⊆ S
⊢ Supports (contSupp (Cont'.comp f k)) S
[PROOFSTEP]
case comp f k IH =>
  have H' := H; rw [contSupp_comp] at H' ; have H₂ := Finset.union_subset_right H'
  exact supports_union.2 ⟨codeSupp'_supports H', IH H₂⟩
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.comp f k) ⊆ S
⊢ Supports (contSupp (Cont'.comp f k)) S
[PROOFSTEP]
have H' := H
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H H' : contSupp (Cont'.comp f k) ⊆ S
⊢ Supports (contSupp (Cont'.comp f k)) S
[PROOFSTEP]
rw [contSupp_comp] at H'
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.comp f k) ⊆ S
H' : codeSupp f k ⊆ S
⊢ Supports (contSupp (Cont'.comp f k)) S
[PROOFSTEP]
have H₂ := Finset.union_subset_right H'
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.comp f k) ⊆ S
H' : codeSupp f k ⊆ S
H₂ : contSupp k ⊆ S
⊢ Supports (contSupp (Cont'.comp f k)) S
[PROOFSTEP]
exact supports_union.2 ⟨codeSupp'_supports H', IH H₂⟩
[GOAL]
case fix
S : Finset Λ'
a✝¹ : Code
a✝ : Cont'
a_ih✝ : contSupp a✝ ⊆ S → Supports (contSupp a✝) S
H : contSupp (Cont'.fix a✝¹ a✝) ⊆ S
⊢ Supports (contSupp (Cont'.fix a✝¹ a✝)) S
[PROOFSTEP]
case fix f k IH =>
  rw [contSupp] at H
  exact supports_union.2 ⟨codeSupp'_supports H, IH (Finset.union_subset_right H)⟩
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.fix f k) ⊆ S
⊢ Supports (contSupp (Cont'.fix f k)) S
[PROOFSTEP]
case fix f k IH =>
  rw [contSupp] at H
  exact supports_union.2 ⟨codeSupp'_supports H, IH (Finset.union_subset_right H)⟩
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : contSupp (Cont'.fix f k) ⊆ S
⊢ Supports (contSupp (Cont'.fix f k)) S
[PROOFSTEP]
rw [contSupp] at H
[GOAL]
S : Finset Λ'
f : Code
k : Cont'
IH : contSupp k ⊆ S → Supports (contSupp k) S
H : codeSupp' (Code.fix f) k ∪ contSupp k ⊆ S
⊢ Supports (contSupp (Cont'.fix f k)) S
[PROOFSTEP]
exact supports_union.2 ⟨codeSupp'_supports H, IH (Finset.union_subset_right H)⟩