l3lab/ntp-mathlib huggingface dataset:
theorem option_iget [Inhabited α] : Primrec (@Option.iget α _) :=
  (option_casesOn .id (const <| @default α _) .right).of_eq fun o => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁵ : Primcodable α
inst✝⁴ : Primcodable β
inst✝³ : Primcodable γ
inst✝² : Primcodable δ
inst✝¹ : Primcodable σ
inst✝ : Inhabited α
o : Option α
⊢ (Option.casesOn (id o) default fun b => b) = Option.iget o

Next tactic:
cases o
theorem option_iget [Inhabited α] : Primrec (@Option.iget α _) :=
  (option_casesOn .id (const <| @default α _) .right).of_eq fun o => by cases o <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁵ : Primcodable α
inst✝⁴ : Primcodable β
inst✝³ : Primcodable γ
inst✝² : Primcodable δ
inst✝¹ : Primcodable σ
inst✝ : Inhabited α
⊢ (Option.casesOn (id none) default fun b => b) = Option.iget none

Next tactic:
rfl
theorem option_iget [Inhabited α] : Primrec (@Option.iget α _) :=
  (option_casesOn .id (const <| @default α _) .right).of_eq fun o => by cases o <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁵ : Primcodable α
inst✝⁴ : Primcodable β
inst✝³ : Primcodable γ
inst✝² : Primcodable δ
inst✝¹ : Primcodable σ
inst✝ : Inhabited α
val✝ : α
⊢ (Option.casesOn (id (some val✝)) default fun b => b) = Option.iget (some val✝)

Next tactic:
rfl
theorem option_isSome : Primrec (@Option.isSome α) :=
  (option_casesOn .id (const false) (const true).to₂).of_eq fun o => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
o : Option α
⊢ (Option.casesOn (id o) false fun b => true) = Option.isSome o

Next tactic:
cases o
theorem option_isSome : Primrec (@Option.isSome α) :=
  (option_casesOn .id (const false) (const true).to₂).of_eq fun o => by cases o <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
⊢ (Option.casesOn (id none) false fun b => true) = Option.isSome none

Next tactic:
rfl
theorem option_isSome : Primrec (@Option.isSome α) :=
  (option_casesOn .id (const false) (const true).to₂).of_eq fun o => by cases o <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
val✝ : α
⊢ (Option.casesOn (id (some val✝)) false fun b => true) = Option.isSome (some val✝)

Next tactic:
rfl
theorem option_getD : Primrec₂ (@Option.getD α) :=
  Primrec.of_eq (option_casesOn Primrec₂.left Primrec₂.right .right) fun ⟨o, a⟩ => by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
x✝ : Option α × α
o : Option α
a : α
⊢ (Option.casesOn ((fun a x => a) (o, a).1 (o, a).2) ((fun x b => b) (o, a).1 (o, a).2) fun b => b) =
    Option.getD (o, a).1 (o, a).2

Next tactic:
cases o
theorem option_getD : Primrec₂ (@Option.getD α) :=
  Primrec.of_eq (option_casesOn Primrec₂.left Primrec₂.right .right) fun ⟨o, a⟩ => by
    cases o <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
x✝ : Option α × α
a : α
⊢ (Option.casesOn ((fun a x => a) (none, a).1 (none, a).2) ((fun x b => b) (none, a).1 (none, a).2) fun b => b) =
    Option.getD (none, a).1 (none, a).2

Next tactic:
rfl
theorem option_getD : Primrec₂ (@Option.getD α) :=
  Primrec.of_eq (option_casesOn Primrec₂.left Primrec₂.right .right) fun ⟨o, a⟩ => by
    cases o <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
x✝ : Option α × α
a val✝ : α
⊢ (Option.casesOn ((fun a x => a) (some val✝, a).1 (some val✝, a).2) ((fun x b => b) (some val✝, a).1 (some val✝, a).2)
      fun b => b) =
    Option.getD (some val✝, a).1 (some val✝, a).2

Next tactic:
rfl
theorem bind_decode_iff {f : α → β → Option σ} :
    (Primrec₂ fun a n => (@decode β _ n).bind (f a)) ↔ Primrec₂ f :=
  ⟨fun h => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : α → β → Option σ
h : Primrec₂ fun a n => Option.bind (decode n) (f a)
⊢ Primrec₂ f

Next tactic:
simpa [encodek] using h.comp fst ((@Primrec.encode β _).comp snd)
theorem map_decode_iff {f : α → β → σ} :
    (Primrec₂ fun a n => (@decode β _ n).map (f a)) ↔ Primrec₂ f := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : α → β → σ
⊢ (Primrec₂ fun a n => Option.map (f a) (decode n)) ↔ Primrec₂ f

Next tactic:
simp only [Option.map_eq_bind]
theorem map_decode_iff {f : α → β → σ} :
    (Primrec₂ fun a n => (@decode β _ n).map (f a)) ↔ Primrec₂ f := by
  simp only [Option.map_eq_bind]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : α → β → σ
⊢ (Primrec₂ fun a n => Option.bind (decode n) (some ∘ f a)) ↔ Primrec₂ f

Next tactic:
exact bind_decode_iff.trans Primrec₂.option_some_iff
theorem cond {c : α → Bool} {f : α → σ} {g : α → σ} (hc : Primrec c) (hf : Primrec f)
    (hg : Primrec g) : Primrec fun a => bif (c a) then (f a) else (g a) :=
  (nat_casesOn (encode_iff.2 hc) hg (hf.comp fst).to₂).of_eq fun a => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
c : α → Bool
f g : α → σ
hc : Primrec c
hf : Primrec f
hg : Primrec g
a : α
⊢ (Nat.casesOn (encode (c a)) (g a) fun b => f (a, b).1) = bif c a then f a else g a

Next tactic:
cases c a
theorem cond {c : α → Bool} {f : α → σ} {g : α → σ} (hc : Primrec c) (hf : Primrec f)
    (hg : Primrec g) : Primrec fun a => bif (c a) then (f a) else (g a) :=
  (nat_casesOn (encode_iff.2 hc) hg (hf.comp fst).to₂).of_eq fun a => by cases c a <;> 

Proof state:
case false
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
c : α → Bool
f g : α → σ
hc : Primrec c
hf : Primrec f
hg : Primrec g
a : α
⊢ (Nat.casesOn (encode false) (g a) fun b => f (a, b).1) = bif false then f a else g a

Next tactic:
rfl
theorem cond {c : α → Bool} {f : α → σ} {g : α → σ} (hc : Primrec c) (hf : Primrec f)
    (hg : Primrec g) : Primrec fun a => bif (c a) then (f a) else (g a) :=
  (nat_casesOn (encode_iff.2 hc) hg (hf.comp fst).to₂).of_eq fun a => by cases c a <;> 

Proof state:
case true
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
c : α → Bool
f g : α → σ
hc : Primrec c
hf : Primrec f
hg : Primrec g
a : α
⊢ (Nat.casesOn (encode true) (g a) fun b => f (a, b).1) = bif true then f a else g a

Next tactic:
rfl
theorem ite {c : α → Prop} [DecidablePred c] {f : α → σ} {g : α → σ} (hc : PrimrecPred c)
    (hf : Primrec f) (hg : Primrec g) : Primrec fun a => if c a then f a else g a := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁵ : Primcodable α
inst✝⁴ : Primcodable β
inst✝³ : Primcodable γ
inst✝² : Primcodable δ
inst✝¹ : Primcodable σ
c : α → Prop
inst✝ : DecidablePred c
f g : α → σ
hc : PrimrecPred c
hf : Primrec f
hg : Primrec g
⊢ Primrec fun a => if c a then f a else g a

Next tactic:
simpa using cond hc hf hg
theorem nat_le : PrimrecRel ((· ≤ ·) : ℕ → ℕ → Prop) :=
  (nat_casesOn nat_sub (const true) (const false).to₂).of_eq fun p => by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
p : ℕ × ℕ
⊢ (Nat.casesOn ((fun x x_1 => x - x_1) p.1 p.2) true fun b => false) =
    (fun a b => decide ((fun x x_1 => x ≤ x_1) a b)) p.1 p.2

Next tactic:
dsimp [swap]
theorem nat_le : PrimrecRel ((· ≤ ·) : ℕ → ℕ → Prop) :=
  (nat_casesOn nat_sub (const true) (const false).to₂).of_eq fun p => by
    dsimp [swap]
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
p : ℕ × ℕ
⊢ Nat.rec true (fun n n_ih => false) (p.1 - p.2) = decide (p.1 ≤ p.2)

Next tactic:
cases' e : p.1 - p.2 with n
theorem nat_le : PrimrecRel ((· ≤ ·) : ℕ → ℕ → Prop) :=
  (nat_casesOn nat_sub (const true) (const false).to₂).of_eq fun p => by
    dsimp [swap]
    cases' e : p.1 - p.2 with n
    · 

Proof state:
case zero
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
p : ℕ × ℕ
e : p.1 - p.2 = Nat.zero
⊢ Nat.rec true (fun n n_ih => false) Nat.zero = decide (p.1 ≤ p.2)

Next tactic:
simp [tsub_eq_zero_iff_le.1 e]
theorem nat_le : PrimrecRel ((· ≤ ·) : ℕ → ℕ → Prop) :=
  (nat_casesOn nat_sub (const true) (const false).to₂).of_eq fun p => by
    dsimp [swap]
    cases' e : p.1 - p.2 with n
    · simp [tsub_eq_zero_iff_le.1 e]
    · 

Proof state:
case succ
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
p : ℕ × ℕ
n : ℕ
e : p.1 - p.2 = Nat.succ n
⊢ Nat.rec true (fun n n_ih => false) (Nat.succ n) = decide (p.1 ≤ p.2)

Next tactic:
simp [not_le.2 (Nat.lt_of_sub_eq_succ e)]
theorem dom_bool (f : Bool → α) : Primrec f :=
  (cond .id (const (f true)) (const (f false))).of_eq fun b => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : Bool → α
b : Bool
⊢ (bif id b then f true else f false) = f b

Next tactic:
cases b
theorem dom_bool (f : Bool → α) : Primrec f :=
  (cond .id (const (f true)) (const (f false))).of_eq fun b => by cases b <;> 

Proof state:
case false
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : Bool → α
⊢ (bif id false then f true else f false) = f false

Next tactic:
rfl
theorem dom_bool (f : Bool → α) : Primrec f :=
  (cond .id (const (f true)) (const (f false))).of_eq fun b => by cases b <;> 

Proof state:
case true
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : Bool → α
⊢ (bif id true then f true else f false) = f true

Next tactic:
rfl
theorem dom_bool₂ (f : Bool → Bool → α) : Primrec₂ f :=
  (cond fst ((dom_bool (f true)).comp snd) ((dom_bool (f false)).comp snd)).of_eq fun ⟨a, b⟩ => by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : Bool → Bool → α
x✝ : Bool × Bool
a b : Bool
⊢ (bif (a, b).1 then f true (a, b).2 else f false (a, b).2) = f (a, b).1 (a, b).2

Next tactic:
cases a
theorem dom_bool₂ (f : Bool → Bool → α) : Primrec₂ f :=
  (cond fst ((dom_bool (f true)).comp snd) ((dom_bool (f false)).comp snd)).of_eq fun ⟨a, b⟩ => by
    cases a <;> 

Proof state:
case false
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : Bool → Bool → α
x✝ : Bool × Bool
b : Bool
⊢ (bif (false, b).1 then f true (false, b).2 else f false (false, b).2) = f (false, b).1 (false, b).2

Next tactic:
rfl
theorem dom_bool₂ (f : Bool → Bool → α) : Primrec₂ f :=
  (cond fst ((dom_bool (f true)).comp snd) ((dom_bool (f false)).comp snd)).of_eq fun ⟨a, b⟩ => by
    cases a <;> 

Proof state:
case true
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : Bool → Bool → α
x✝ : Bool × Bool
b : Bool
⊢ (bif (true, b).1 then f true (true, b).2 else f false (true, b).2) = f (true, b).1 (true, b).2

Next tactic:
rfl
theorem _root_.PrimrecPred.not {p : α → Prop} [DecidablePred p] (hp : PrimrecPred p) :
    PrimrecPred fun a => ¬p a :=
  (Primrec.not.comp hp).of_eq fun n => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁵ : Primcodable α
inst✝⁴ : Primcodable β
inst✝³ : Primcodable γ
inst✝² : Primcodable δ
inst✝¹ : Primcodable σ
p : α → Prop
inst✝ : DecidablePred p
hp : PrimrecPred p
n : α
⊢ (!decide (p n)) = decide ((fun a => ¬p a) n)

Next tactic:
simp
theorem _root_.PrimrecPred.and {p q : α → Prop} [DecidablePred p] [DecidablePred q]
    (hp : PrimrecPred p) (hq : PrimrecPred q) : PrimrecPred fun a => p a ∧ q a :=
  (Primrec.and.comp hp hq).of_eq fun n => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁶ : Primcodable α
inst✝⁵ : Primcodable β
inst✝⁴ : Primcodable γ
inst✝³ : Primcodable δ
inst✝² : Primcodable σ
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
hp : PrimrecPred p
hq : PrimrecPred q
n : α
⊢ (decide (p n) && decide (q n)) = decide ((fun a => p a ∧ q a) n)

Next tactic:
simp
theorem _root_.PrimrecPred.or {p q : α → Prop} [DecidablePred p] [DecidablePred q]
    (hp : PrimrecPred p) (hq : PrimrecPred q) : PrimrecPred fun a => p a ∨ q a :=
  (Primrec.or.comp hp hq).of_eq fun n => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁶ : Primcodable α
inst✝⁵ : Primcodable β
inst✝⁴ : Primcodable γ
inst✝³ : Primcodable δ
inst✝² : Primcodable σ
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
hp : PrimrecPred p
hq : PrimrecPred q
n : α
⊢ (decide (p n) || decide (q n)) = decide ((fun a => p a ∨ q a) n)

Next tactic:
simp
protected theorem beq [DecidableEq α] : Primrec₂ (@BEq.beq α _) :=
  have : PrimrecRel fun a b : ℕ => a = b :=
    (PrimrecPred.and nat_le nat_le.swap).of_eq fun a => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁵ : Primcodable α
inst✝⁴ : Primcodable β
inst✝³ : Primcodable γ
inst✝² : Primcodable δ
inst✝¹ : Primcodable σ
inst✝ : DecidableEq α
a : ℕ × ℕ
⊢ (fun x x_1 => x ≤ x_1) a.1 a.2 ∧ (fun x x_1 => x ≤ x_1) a.2 a.1 ↔ (fun a b => a = b) a.1 a.2

Next tactic:
simp [le_antisymm_iff]
theorem nat_lt : PrimrecRel ((· < ·) : ℕ → ℕ → Prop) :=
  (nat_le.comp snd fst).not.of_eq fun p => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
p : ℕ × ℕ
⊢ ¬p.2 ≤ p.1 ↔ (fun x x_1 => x < x_1) p.1 p.2

Next tactic:
simp
theorem option_orElse : Primrec₂ ((· <|> ·) : Option α → Option α → Option α) :=
  (option_casesOn fst snd (fst.comp fst).to₂).of_eq fun ⟨o₁, o₂⟩ => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
x✝ : Option α × Option α
o₁ o₂ : Option α
⊢ (Option.casesOn (o₁, o₂).1 (o₁, o₂).2 fun b => ((o₁, o₂), b).1.1) =
    (fun x x_1 => HOrElse.hOrElse x fun x => x_1) (o₁, o₂).1 (o₁, o₂).2

Next tactic:
cases o₁
theorem option_orElse : Primrec₂ ((· <|> ·) : Option α → Option α → Option α) :=
  (option_casesOn fst snd (fst.comp fst).to₂).of_eq fun ⟨o₁, o₂⟩ => by cases o₁ <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
x✝ : Option α × Option α
o₂ : Option α
⊢ (Option.casesOn (none, o₂).1 (none, o₂).2 fun b => ((none, o₂), b).1.1) =
    (fun x x_1 => HOrElse.hOrElse x fun x => x_1) (none, o₂).1 (none, o₂).2

Next tactic:
cases o₂
theorem option_orElse : Primrec₂ ((· <|> ·) : Option α → Option α → Option α) :=
  (option_casesOn fst snd (fst.comp fst).to₂).of_eq fun ⟨o₁, o₂⟩ => by cases o₁ <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
x✝ : Option α × Option α
o₂ : Option α
val✝ : α
⊢ (Option.casesOn (some val✝, o₂).1 (some val✝, o₂).2 fun b => ((some val✝, o₂), b).1.1) =
    (fun x x_1 => HOrElse.hOrElse x fun x => x_1) (some val✝, o₂).1 (some val✝, o₂).2

Next tactic:
cases o₂
theorem option_orElse : Primrec₂ ((· <|> ·) : Option α → Option α → Option α) :=
  (option_casesOn fst snd (fst.comp fst).to₂).of_eq fun ⟨o₁, o₂⟩ => by cases o₁ <;> cases o₂ <;> 

Proof state:
case none.none
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
x✝ : Option α × Option α
⊢ (Option.casesOn (none, none).1 (none, none).2 fun b => ((none, none), b).1.1) =
    (fun x x_1 => HOrElse.hOrElse x fun x => x_1) (none, none).1 (none, none).2

Next tactic:
rfl
theorem option_orElse : Primrec₂ ((· <|> ·) : Option α → Option α → Option α) :=
  (option_casesOn fst snd (fst.comp fst).to₂).of_eq fun ⟨o₁, o₂⟩ => by cases o₁ <;> cases o₂ <;> 

Proof state:
case none.some
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
x✝ : Option α × Option α
val✝ : α
⊢ (Option.casesOn (none, some val✝).1 (none, some val✝).2 fun b => ((none, some val✝), b).1.1) =
    (fun x x_1 => HOrElse.hOrElse x fun x => x_1) (none, some val✝).1 (none, some val✝).2

Next tactic:
rfl
theorem option_orElse : Primrec₂ ((· <|> ·) : Option α → Option α → Option α) :=
  (option_casesOn fst snd (fst.comp fst).to₂).of_eq fun ⟨o₁, o₂⟩ => by cases o₁ <;> cases o₂ <;> 

Proof state:
case some.none
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
x✝ : Option α × Option α
val✝ : α
⊢ (Option.casesOn (some val✝, none).1 (some val✝, none).2 fun b => ((some val✝, none), b).1.1) =
    (fun x x_1 => HOrElse.hOrElse x fun x => x_1) (some val✝, none).1 (some val✝, none).2

Next tactic:
rfl
theorem option_orElse : Primrec₂ ((· <|> ·) : Option α → Option α → Option α) :=
  (option_casesOn fst snd (fst.comp fst).to₂).of_eq fun ⟨o₁, o₂⟩ => by cases o₁ <;> cases o₂ <;> 

Proof state:
case some.some
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
x✝ : Option α × Option α
val✝¹ val✝ : α
⊢ (Option.casesOn (some val✝¹, some val✝).1 (some val✝¹, some val✝).2 fun b => ((some val✝¹, some val✝), b).1.1) =
    (fun x x_1 => HOrElse.hOrElse x fun x => x_1) (some val✝¹, some val✝).1 (some val✝¹, some val✝).2

Next tactic:
rfl
protected theorem decode₂ : Primrec (decode₂ α) :=
  option_bind .decode <|
    option_guard (Primrec.beq.comp₂ (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
⊢ Primrec₂ fun p a => encode a

Next tactic:
exact encode_iff.mpr snd
protected theorem decode₂ : Primrec (decode₂ α) :=
  option_bind .decode <|
    option_guard (Primrec.beq.comp₂ (by exact encode_iff.mpr snd) (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
⊢ Primrec₂ fun p a => p.1

Next tactic:
exact fst.comp fst
theorem list_findIdx₁ {p : α → β → Bool} (hp : Primrec₂ p) :
    ∀ l : List β, Primrec fun a => l.findIdx (p a)
| [] => const 0
| a :: l => (cond (hp.comp .id (const a)) (const 0) (succ.comp (list_findIdx₁ hp l))).of_eq fun n =>
  by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
p : α → β → Bool
hp : Primrec₂ p
a : β
l : List β
n : α
⊢ (bif p (id n) a then 0 else Nat.succ (List.findIdx (p n) l)) = List.findIdx (p n) (a :: l)

Next tactic:
simp [List.findIdx_cons]
theorem dom_fintype [Fintype α] (f : α → σ) : Primrec f :=
  let ⟨l, _, m⟩ := Finite.exists_univ_list α
  option_some_iff.1 <| by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁵ : Primcodable α
inst✝⁴ : Primcodable β
inst✝³ : Primcodable γ
inst✝² : Primcodable δ
inst✝¹ : Primcodable σ
inst✝ : Fintype α
f : α → σ
l : List α
left✝ : List.Nodup l
m : ∀ (x : α), x ∈ l
⊢ Primrec fun a => some (f a)

Next tactic:
haveI := decidableEqOfEncodable α
theorem dom_fintype [Fintype α] (f : α → σ) : Primrec f :=
  let ⟨l, _, m⟩ := Finite.exists_univ_list α
  option_some_iff.1 <| by
    haveI := decidableEqOfEncodable α
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁵ : Primcodable α
inst✝⁴ : Primcodable β
inst✝³ : Primcodable γ
inst✝² : Primcodable δ
inst✝¹ : Primcodable σ
inst✝ : Fintype α
f : α → σ
l : List α
left✝ : List.Nodup l
m : ∀ (x : α), x ∈ l
this : DecidableEq α
⊢ Primrec fun a => some (f a)

Next tactic:
refine ((list_get?₁ (l.map f)).comp (list_indexOf₁ l)).of_eq fun a => ?_
theorem dom_fintype [Fintype α] (f : α → σ) : Primrec f :=
  let ⟨l, _, m⟩ := Finite.exists_univ_list α
  option_some_iff.1 <| by
    haveI := decidableEqOfEncodable α
    refine ((list_get?₁ (l.map f)).comp (list_indexOf₁ l)).of_eq fun a => ?_
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁵ : Primcodable α
inst✝⁴ : Primcodable β
inst✝³ : Primcodable γ
inst✝² : Primcodable δ
inst✝¹ : Primcodable σ
inst✝ : Fintype α
f : α → σ
l : List α
left✝ : List.Nodup l
m : ∀ (x : α), x ∈ l
this : DecidableEq α
a : α
⊢ List.get? (List.map f l) (List.indexOf a l) = some (f a)

Next tactic:
rw [List.get?_map, List.indexOf_get? (m a), Option.map_some']
theorem nat_findGreatest {f : α → ℕ} {p : α → ℕ → Prop} [∀ x n, Decidable (p x n)]
    (hf : Primrec f) (hp : PrimrecRel p) : Primrec fun x => (f x).findGreatest (p x) :=
  (nat_rec' (h := fun x nih => if p x (nih.1 + 1) then nih.1 + 1 else nih.2)
    hf (const 0) (ite (hp.comp fst (snd |> fst.comp |> succ.comp))
      (snd |> fst.comp |> succ.comp) (snd.comp snd))).of_eq fun x => by
        

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
σ : Type u_5
inst✝⁵ : Primcodable α
inst✝⁴ : Primcodable β
inst✝³ : Primcodable γ
inst✝² : Primcodable δ
inst✝¹ : Primcodable σ
f : α → ℕ
p : α → ℕ → Prop
inst✝ : (x : α) → (n : ℕ) → Decidable (p x n)
hf : Primrec f
hp : PrimrecRel p
x : α
⊢ Nat.rec 0 (fun n IH => if p x ((n, IH).1 + 1) then (n, IH).1 + 1 else (n, IH).2) (f x) = Nat.findGreatest (p x) (f x)

Next tactic:
induction f x