l3lab/ntp-mathlib huggingface dataset:
/-- Proof that `Nat.Partrec.Code.ofNatCode` is the inverse of `Nat.Partrec.Code.encodeCode`-/
private theorem encode_ofNatCode : ∀ n, encodeCode (ofNatCode n) = n
  | 0 => by simp [ofNatCode, encodeCode]
  | 1 => by simp [ofNatCode, encodeCode]
  | 2 => by simp [ofNatCode, encodeCode]
  | 3 => by simp [ofNatCode, encodeCode]
  | n + 4 => by
    let m := n.div2.div2
    have hm : m < n + 4 := by
      simp only [div2_val]
      exact
        lt_of_le_of_lt (le_trans (Nat.div_le_self _ _) (Nat.div_le_self _ _))
          (Nat.succ_le_succ (Nat.le_add_right _ _))
    have _m1 : m.unpair.1 < n + 4 := lt_of_le_of_lt m.unpair_left_le hm
    have _m2 : m.unpair.2 < n + 4 := lt_of_le_of_lt m.unpair_right_le hm
    have IH := encode_ofNatCode m
    have IH1 := encode_ofNatCode m.unpair.1
    have IH2 := encode_ofNatCode m.unpair.2
    conv_rhs => rw [← Nat.bit_decomp n, ← Nat.bit_decomp n.div2]
    simp only [ofNatCode._eq_5]
    cases n.bodd <;> 

Proof state:
case false
n : ℕ
m : ℕ := div2 (div2 n)
hm : m < n + 4
_m1 : (unpair m).1 < n + 4
_m2 : (unpair m).2 < n + 4
IH : encodeCode (ofNatCode m) = m
IH1 : encodeCode (ofNatCode (unpair m).1) = (unpair m).1
IH2 : encodeCode (ofNatCode (unpair m).2) = (unpair m).2
⊢ encodeCode
      (match false, bodd (div2 n) with
      | false, false => pair (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | false, true => comp (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | true, false => prec (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | true, true => rfind' (ofNatCode (div2 (div2 n)))) =
    bit false (bit (bodd (div2 n)) (div2 (div2 n))) + 4

Next tactic:
cases n.div2.bodd
/-- Proof that `Nat.Partrec.Code.ofNatCode` is the inverse of `Nat.Partrec.Code.encodeCode`-/
private theorem encode_ofNatCode : ∀ n, encodeCode (ofNatCode n) = n
  | 0 => by simp [ofNatCode, encodeCode]
  | 1 => by simp [ofNatCode, encodeCode]
  | 2 => by simp [ofNatCode, encodeCode]
  | 3 => by simp [ofNatCode, encodeCode]
  | n + 4 => by
    let m := n.div2.div2
    have hm : m < n + 4 := by
      simp only [div2_val]
      exact
        lt_of_le_of_lt (le_trans (Nat.div_le_self _ _) (Nat.div_le_self _ _))
          (Nat.succ_le_succ (Nat.le_add_right _ _))
    have _m1 : m.unpair.1 < n + 4 := lt_of_le_of_lt m.unpair_left_le hm
    have _m2 : m.unpair.2 < n + 4 := lt_of_le_of_lt m.unpair_right_le hm
    have IH := encode_ofNatCode m
    have IH1 := encode_ofNatCode m.unpair.1
    have IH2 := encode_ofNatCode m.unpair.2
    conv_rhs => rw [← Nat.bit_decomp n, ← Nat.bit_decomp n.div2]
    simp only [ofNatCode._eq_5]
    cases n.bodd <;> 

Proof state:
case true
n : ℕ
m : ℕ := div2 (div2 n)
hm : m < n + 4
_m1 : (unpair m).1 < n + 4
_m2 : (unpair m).2 < n + 4
IH : encodeCode (ofNatCode m) = m
IH1 : encodeCode (ofNatCode (unpair m).1) = (unpair m).1
IH2 : encodeCode (ofNatCode (unpair m).2) = (unpair m).2
⊢ encodeCode
      (match true, bodd (div2 n) with
      | false, false => pair (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | false, true => comp (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | true, false => prec (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | true, true => rfind' (ofNatCode (div2 (div2 n)))) =
    bit true (bit (bodd (div2 n)) (div2 (div2 n))) + 4

Next tactic:
cases n.div2.bodd
/-- Proof that `Nat.Partrec.Code.ofNatCode` is the inverse of `Nat.Partrec.Code.encodeCode`-/
private theorem encode_ofNatCode : ∀ n, encodeCode (ofNatCode n) = n
  | 0 => by simp [ofNatCode, encodeCode]
  | 1 => by simp [ofNatCode, encodeCode]
  | 2 => by simp [ofNatCode, encodeCode]
  | 3 => by simp [ofNatCode, encodeCode]
  | n + 4 => by
    let m := n.div2.div2
    have hm : m < n + 4 := by
      simp only [div2_val]
      exact
        lt_of_le_of_lt (le_trans (Nat.div_le_self _ _) (Nat.div_le_self _ _))
          (Nat.succ_le_succ (Nat.le_add_right _ _))
    have _m1 : m.unpair.1 < n + 4 := lt_of_le_of_lt m.unpair_left_le hm
    have _m2 : m.unpair.2 < n + 4 := lt_of_le_of_lt m.unpair_right_le hm
    have IH := encode_ofNatCode m
    have IH1 := encode_ofNatCode m.unpair.1
    have IH2 := encode_ofNatCode m.unpair.2
    conv_rhs => rw [← Nat.bit_decomp n, ← Nat.bit_decomp n.div2]
    simp only [ofNatCode._eq_5]
    cases n.bodd <;> cases n.div2.bodd <;>
      

Proof state:
case false.false
n : ℕ
m : ℕ := div2 (div2 n)
hm : m < n + 4
_m1 : (unpair m).1 < n + 4
_m2 : (unpair m).2 < n + 4
IH : encodeCode (ofNatCode m) = m
IH1 : encodeCode (ofNatCode (unpair m).1) = (unpair m).1
IH2 : encodeCode (ofNatCode (unpair m).2) = (unpair m).2
⊢ encodeCode
      (match false, false with
      | false, false => pair (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | false, true => comp (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | true, false => prec (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | true, true => rfind' (ofNatCode (div2 (div2 n)))) =
    bit false (bit false (div2 (div2 n))) + 4

Next tactic:
simp [encodeCode, ofNatCode, IH, IH1, IH2, Nat.bit_val]
/-- Proof that `Nat.Partrec.Code.ofNatCode` is the inverse of `Nat.Partrec.Code.encodeCode`-/
private theorem encode_ofNatCode : ∀ n, encodeCode (ofNatCode n) = n
  | 0 => by simp [ofNatCode, encodeCode]
  | 1 => by simp [ofNatCode, encodeCode]
  | 2 => by simp [ofNatCode, encodeCode]
  | 3 => by simp [ofNatCode, encodeCode]
  | n + 4 => by
    let m := n.div2.div2
    have hm : m < n + 4 := by
      simp only [div2_val]
      exact
        lt_of_le_of_lt (le_trans (Nat.div_le_self _ _) (Nat.div_le_self _ _))
          (Nat.succ_le_succ (Nat.le_add_right _ _))
    have _m1 : m.unpair.1 < n + 4 := lt_of_le_of_lt m.unpair_left_le hm
    have _m2 : m.unpair.2 < n + 4 := lt_of_le_of_lt m.unpair_right_le hm
    have IH := encode_ofNatCode m
    have IH1 := encode_ofNatCode m.unpair.1
    have IH2 := encode_ofNatCode m.unpair.2
    conv_rhs => rw [← Nat.bit_decomp n, ← Nat.bit_decomp n.div2]
    simp only [ofNatCode._eq_5]
    cases n.bodd <;> cases n.div2.bodd <;>
      

Proof state:
case false.true
n : ℕ
m : ℕ := div2 (div2 n)
hm : m < n + 4
_m1 : (unpair m).1 < n + 4
_m2 : (unpair m).2 < n + 4
IH : encodeCode (ofNatCode m) = m
IH1 : encodeCode (ofNatCode (unpair m).1) = (unpair m).1
IH2 : encodeCode (ofNatCode (unpair m).2) = (unpair m).2
⊢ encodeCode
      (match false, true with
      | false, false => pair (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | false, true => comp (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | true, false => prec (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | true, true => rfind' (ofNatCode (div2 (div2 n)))) =
    bit false (bit true (div2 (div2 n))) + 4

Next tactic:
simp [encodeCode, ofNatCode, IH, IH1, IH2, Nat.bit_val]
/-- Proof that `Nat.Partrec.Code.ofNatCode` is the inverse of `Nat.Partrec.Code.encodeCode`-/
private theorem encode_ofNatCode : ∀ n, encodeCode (ofNatCode n) = n
  | 0 => by simp [ofNatCode, encodeCode]
  | 1 => by simp [ofNatCode, encodeCode]
  | 2 => by simp [ofNatCode, encodeCode]
  | 3 => by simp [ofNatCode, encodeCode]
  | n + 4 => by
    let m := n.div2.div2
    have hm : m < n + 4 := by
      simp only [div2_val]
      exact
        lt_of_le_of_lt (le_trans (Nat.div_le_self _ _) (Nat.div_le_self _ _))
          (Nat.succ_le_succ (Nat.le_add_right _ _))
    have _m1 : m.unpair.1 < n + 4 := lt_of_le_of_lt m.unpair_left_le hm
    have _m2 : m.unpair.2 < n + 4 := lt_of_le_of_lt m.unpair_right_le hm
    have IH := encode_ofNatCode m
    have IH1 := encode_ofNatCode m.unpair.1
    have IH2 := encode_ofNatCode m.unpair.2
    conv_rhs => rw [← Nat.bit_decomp n, ← Nat.bit_decomp n.div2]
    simp only [ofNatCode._eq_5]
    cases n.bodd <;> cases n.div2.bodd <;>
      

Proof state:
case true.false
n : ℕ
m : ℕ := div2 (div2 n)
hm : m < n + 4
_m1 : (unpair m).1 < n + 4
_m2 : (unpair m).2 < n + 4
IH : encodeCode (ofNatCode m) = m
IH1 : encodeCode (ofNatCode (unpair m).1) = (unpair m).1
IH2 : encodeCode (ofNatCode (unpair m).2) = (unpair m).2
⊢ encodeCode
      (match true, false with
      | false, false => pair (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | false, true => comp (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | true, false => prec (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | true, true => rfind' (ofNatCode (div2 (div2 n)))) =
    bit true (bit false (div2 (div2 n))) + 4

Next tactic:
simp [encodeCode, ofNatCode, IH, IH1, IH2, Nat.bit_val]
/-- Proof that `Nat.Partrec.Code.ofNatCode` is the inverse of `Nat.Partrec.Code.encodeCode`-/
private theorem encode_ofNatCode : ∀ n, encodeCode (ofNatCode n) = n
  | 0 => by simp [ofNatCode, encodeCode]
  | 1 => by simp [ofNatCode, encodeCode]
  | 2 => by simp [ofNatCode, encodeCode]
  | 3 => by simp [ofNatCode, encodeCode]
  | n + 4 => by
    let m := n.div2.div2
    have hm : m < n + 4 := by
      simp only [div2_val]
      exact
        lt_of_le_of_lt (le_trans (Nat.div_le_self _ _) (Nat.div_le_self _ _))
          (Nat.succ_le_succ (Nat.le_add_right _ _))
    have _m1 : m.unpair.1 < n + 4 := lt_of_le_of_lt m.unpair_left_le hm
    have _m2 : m.unpair.2 < n + 4 := lt_of_le_of_lt m.unpair_right_le hm
    have IH := encode_ofNatCode m
    have IH1 := encode_ofNatCode m.unpair.1
    have IH2 := encode_ofNatCode m.unpair.2
    conv_rhs => rw [← Nat.bit_decomp n, ← Nat.bit_decomp n.div2]
    simp only [ofNatCode._eq_5]
    cases n.bodd <;> cases n.div2.bodd <;>
      

Proof state:
case true.true
n : ℕ
m : ℕ := div2 (div2 n)
hm : m < n + 4
_m1 : (unpair m).1 < n + 4
_m2 : (unpair m).2 < n + 4
IH : encodeCode (ofNatCode m) = m
IH1 : encodeCode (ofNatCode (unpair m).1) = (unpair m).1
IH2 : encodeCode (ofNatCode (unpair m).2) = (unpair m).2
⊢ encodeCode
      (match true, true with
      | false, false => pair (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | false, true => comp (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | true, false => prec (ofNatCode (unpair (div2 (div2 n))).1) (ofNatCode (unpair (div2 (div2 n))).2)
      | true, true => rfind' (ofNatCode (div2 (div2 n)))) =
    bit true (bit true (div2 (div2 n))) + 4

Next tactic:
simp [encodeCode, ofNatCode, IH, IH1, IH2, Nat.bit_val]
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        

Proof state:
c : Code
⊢ ofNatCode (encodeCode c) = c

Next tactic:
induction c
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> 

Proof state:
case zero
⊢ ofNatCode (encodeCode zero) = zero

Next tactic:
try {rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try 

Proof state:
case zero
⊢ ofNatCode (encodeCode zero) = zero

Next tactic:
{rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try {

Proof state:
case zero
⊢ ofNatCode (encodeCode zero) = zero

Next tactic:
rfl
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> 

Proof state:
case succ
⊢ ofNatCode (encodeCode succ) = succ

Next tactic:
try {rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try 

Proof state:
case succ
⊢ ofNatCode (encodeCode succ) = succ

Next tactic:
{rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try {

Proof state:
case succ
⊢ ofNatCode (encodeCode succ) = succ

Next tactic:
rfl
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> 

Proof state:
case left
⊢ ofNatCode (encodeCode left) = left

Next tactic:
try {rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try 

Proof state:
case left
⊢ ofNatCode (encodeCode left) = left

Next tactic:
{rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try {

Proof state:
case left
⊢ ofNatCode (encodeCode left) = left

Next tactic:
rfl
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> 

Proof state:
case right
⊢ ofNatCode (encodeCode right) = right

Next tactic:
try {rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try 

Proof state:
case right
⊢ ofNatCode (encodeCode right) = right

Next tactic:
{rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try {

Proof state:
case right
⊢ ofNatCode (encodeCode right) = right

Next tactic:
rfl
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> 

Proof state:
case pair
a✝¹ a✝ : Code
a_ih✝¹ : ofNatCode (encodeCode a✝¹) = a✝¹
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (pair a✝¹ a✝)) = pair a✝¹ a✝

Next tactic:
try {rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try 

Proof state:
case pair
a✝¹ a✝ : Code
a_ih✝¹ : ofNatCode (encodeCode a✝¹) = a✝¹
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (pair a✝¹ a✝)) = pair a✝¹ a✝

Next tactic:
{rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try {

Proof state:
case pair
a✝¹ a✝ : Code
a_ih✝¹ : ofNatCode (encodeCode a✝¹) = a✝¹
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (pair a✝¹ a✝)) = pair a✝¹ a✝

Next tactic:
rfl
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> 

Proof state:
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ofNatCode (encodeCode a✝¹) = a✝¹
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (comp a✝¹ a✝)) = comp a✝¹ a✝

Next tactic:
try {rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try 

Proof state:
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ofNatCode (encodeCode a✝¹) = a✝¹
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (comp a✝¹ a✝)) = comp a✝¹ a✝

Next tactic:
{rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try {

Proof state:
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ofNatCode (encodeCode a✝¹) = a✝¹
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (comp a✝¹ a✝)) = comp a✝¹ a✝

Next tactic:
rfl
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> 

Proof state:
case prec
a✝¹ a✝ : Code
a_ih✝¹ : ofNatCode (encodeCode a✝¹) = a✝¹
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (prec a✝¹ a✝)) = prec a✝¹ a✝

Next tactic:
try {rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try 

Proof state:
case prec
a✝¹ a✝ : Code
a_ih✝¹ : ofNatCode (encodeCode a✝¹) = a✝¹
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (prec a✝¹ a✝)) = prec a✝¹ a✝

Next tactic:
{rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try {

Proof state:
case prec
a✝¹ a✝ : Code
a_ih✝¹ : ofNatCode (encodeCode a✝¹) = a✝¹
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (prec a✝¹ a✝)) = prec a✝¹ a✝

Next tactic:
rfl
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> 

Proof state:
case rfind'
a✝ : Code
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (rfind' a✝)) = rfind' a✝

Next tactic:
try {rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try 

Proof state:
case rfind'
a✝ : Code
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (rfind' a✝)) = rfind' a✝

Next tactic:
{rfl}
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try {

Proof state:
case rfind'
a✝ : Code
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (rfind' a✝)) = rfind' a✝

Next tactic:
rfl
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try {rfl} <;> 

Proof state:
case pair
a✝¹ a✝ : Code
a_ih✝¹ : ofNatCode (encodeCode a✝¹) = a✝¹
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (pair a✝¹ a✝)) = pair a✝¹ a✝

Next tactic:
simp [encodeCode, ofNatCode, Nat.div2_val, *]
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try {rfl} <;> 

Proof state:
case comp
a✝¹ a✝ : Code
a_ih✝¹ : ofNatCode (encodeCode a✝¹) = a✝¹
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (comp a✝¹ a✝)) = comp a✝¹ a✝

Next tactic:
simp [encodeCode, ofNatCode, Nat.div2_val, *]
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try {rfl} <;> 

Proof state:
case prec
a✝¹ a✝ : Code
a_ih✝¹ : ofNatCode (encodeCode a✝¹) = a✝¹
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (prec a✝¹ a✝)) = prec a✝¹ a✝

Next tactic:
simp [encodeCode, ofNatCode, Nat.div2_val, *]
instance instDenumerable : Denumerable Code :=
  mk'
    ⟨encodeCode, ofNatCode, fun c => by
        induction c <;> try {rfl} <;> 

Proof state:
case rfind'
a✝ : Code
a_ih✝ : ofNatCode (encodeCode a✝) = a✝
⊢ ofNatCode (encodeCode (rfind' a✝)) = rfind' a✝

Next tactic:
simp [encodeCode, ofNatCode, Nat.div2_val, *]
theorem encode_lt_pair (cf cg) :
    encode cf < encode (pair cf cg) ∧ encode cg < encode (pair cf cg) := by
  

Proof state:
cf cg : Code
⊢ encode cf < encode (pair cf cg) ∧ encode cg < encode (pair cf cg)

Next tactic:
simp only [encodeCode_eq, encodeCode]
theorem encode_lt_pair (cf cg) :
    encode cf < encode (pair cf cg) ∧ encode cg < encode (pair cf cg) := by
  simp only [encodeCode_eq, encodeCode]
  

Proof state:
cf cg : Code
⊢ encodeCode cf < 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg)) + 4 ∧
    encodeCode cg < 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg)) + 4

Next tactic:
have := Nat.mul_le_mul_right (Nat.pair cf.encodeCode cg.encodeCode) (by decide : 1 ≤ 2 * 2)
theorem encode_lt_pair (cf cg) :
    encode cf < encode (pair cf cg) ∧ encode cg < encode (pair cf cg) := by
  simp only [encodeCode_eq, encodeCode]
  have := Nat.mul_le_mul_right (Nat.pair cf.encodeCode cg.encodeCode) (by 

Proof state:
cf cg : Code
⊢ 1 ≤ 2 * 2

Next tactic:
decide
theorem encode_lt_pair (cf cg) :
    encode cf < encode (pair cf cg) ∧ encode cg < encode (pair cf cg) := by
  simp only [encodeCode_eq, encodeCode]
  have := Nat.mul_le_mul_right (Nat.pair cf.encodeCode cg.encodeCode) (by decide : 1 ≤ 2 * 2)
  

Proof state:
cf cg : Code
this : 1 * Nat.pair (encodeCode cf) (encodeCode cg) ≤ 2 * 2 * Nat.pair (encodeCode cf) (encodeCode cg)
⊢ encodeCode cf < 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg)) + 4 ∧
    encodeCode cg < 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg)) + 4

Next tactic:
rw [one_mul, mul_assoc] at this
theorem encode_lt_pair (cf cg) :
    encode cf < encode (pair cf cg) ∧ encode cg < encode (pair cf cg) := by
  simp only [encodeCode_eq, encodeCode]
  have := Nat.mul_le_mul_right (Nat.pair cf.encodeCode cg.encodeCode) (by decide : 1 ≤ 2 * 2)
  rw [one_mul, mul_assoc] at this
  

Proof state:
cf cg : Code
this : Nat.pair (encodeCode cf) (encodeCode cg) ≤ 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg))
⊢ encodeCode cf < 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg)) + 4 ∧
    encodeCode cg < 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg)) + 4

Next tactic:
have := lt_of_le_of_lt this (lt_add_of_pos_right _ (by decide : 0 < 4))
theorem encode_lt_pair (cf cg) :
    encode cf < encode (pair cf cg) ∧ encode cg < encode (pair cf cg) := by
  simp only [encodeCode_eq, encodeCode]
  have := Nat.mul_le_mul_right (Nat.pair cf.encodeCode cg.encodeCode) (by decide : 1 ≤ 2 * 2)
  rw [one_mul, mul_assoc] at this
  have := lt_of_le_of_lt this (lt_add_of_pos_right _ (by 

Proof state:
cf cg : Code
this : Nat.pair (encodeCode cf) (encodeCode cg) ≤ 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg))
⊢ 0 < 4

Next tactic:
decide
theorem encode_lt_pair (cf cg) :
    encode cf < encode (pair cf cg) ∧ encode cg < encode (pair cf cg) := by
  simp only [encodeCode_eq, encodeCode]
  have := Nat.mul_le_mul_right (Nat.pair cf.encodeCode cg.encodeCode) (by decide : 1 ≤ 2 * 2)
  rw [one_mul, mul_assoc] at this
  have := lt_of_le_of_lt this (lt_add_of_pos_right _ (by decide : 0 < 4))
  

Proof state:
cf cg : Code
this✝ : Nat.pair (encodeCode cf) (encodeCode cg) ≤ 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg))
this : Nat.pair (encodeCode cf) (encodeCode cg) < 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg)) + 4
⊢ encodeCode cf < 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg)) + 4 ∧
    encodeCode cg < 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg)) + 4

Next tactic:
exact ⟨lt_of_le_of_lt (Nat.left_le_pair _ _) this, lt_of_le_of_lt (Nat.right_le_pair _ _) this⟩
theorem encode_lt_comp (cf cg) :
    encode cf < encode (comp cf cg) ∧ encode cg < encode (comp cf cg) := by
  

Proof state:
cf cg : Code
⊢ encode cf < encode (comp cf cg) ∧ encode cg < encode (comp cf cg)

Next tactic:
suffices
theorem encode_lt_comp (cf cg) :
    encode cf < encode (comp cf cg) ∧ encode cg < encode (comp cf cg) := by
  suffices; 

Proof state:
cf cg : Code
this : ?m.392686
⊢ encode cf < encode (comp cf cg) ∧ encode cg < encode (comp cf cg)
case this cf cg : Code ⊢ ?m.392686

Next tactic:
exact (encode_lt_pair cf cg).imp (fun h => lt_trans h this) fun h => lt_trans h this
theorem encode_lt_comp (cf cg) :
    encode cf < encode (comp cf cg) ∧ encode cg < encode (comp cf cg) := by
  suffices; exact (encode_lt_pair cf cg).imp (fun h => lt_trans h this) fun h => lt_trans h this
  

Proof state:
case this
cf cg : Code
⊢ encode (pair cf cg) < encode (comp cf cg)

Next tactic:
change _
theorem encode_lt_comp (cf cg) :
    encode cf < encode (comp cf cg) ∧ encode cg < encode (comp cf cg) := by
  suffices; exact (encode_lt_pair cf cg).imp (fun h => lt_trans h this) fun h => lt_trans h this
  change _; 

Proof state:
case this
cf cg : Code
⊢ encode (pair cf cg) < encode (comp cf cg)

Next tactic:
simp [encodeCode_eq, encodeCode]
theorem encode_lt_prec (cf cg) :
    encode cf < encode (prec cf cg) ∧ encode cg < encode (prec cf cg) := by
  

Proof state:
cf cg : Code
⊢ encode cf < encode (prec cf cg) ∧ encode cg < encode (prec cf cg)

Next tactic:
suffices
theorem encode_lt_prec (cf cg) :
    encode cf < encode (prec cf cg) ∧ encode cg < encode (prec cf cg) := by
  suffices; 

Proof state:
cf cg : Code
this : ?m.395648
⊢ encode cf < encode (prec cf cg) ∧ encode cg < encode (prec cf cg)
case this cf cg : Code ⊢ ?m.395648

Next tactic:
exact (encode_lt_pair cf cg).imp (fun h => lt_trans h this) fun h => lt_trans h this
theorem encode_lt_prec (cf cg) :
    encode cf < encode (prec cf cg) ∧ encode cg < encode (prec cf cg) := by
  suffices; exact (encode_lt_pair cf cg).imp (fun h => lt_trans h this) fun h => lt_trans h this
  

Proof state:
case this
cf cg : Code
⊢ encode (pair cf cg) < encode (prec cf cg)

Next tactic:
change _
theorem encode_lt_prec (cf cg) :
    encode cf < encode (prec cf cg) ∧ encode cg < encode (prec cf cg) := by
  suffices; exact (encode_lt_pair cf cg).imp (fun h => lt_trans h this) fun h => lt_trans h this
  change _; 

Proof state:
case this
cf cg : Code
⊢ encode (pair cf cg) < encode (prec cf cg)

Next tactic:
simp [encodeCode_eq, encodeCode]