l3lab/ntp-mathlib huggingface dataset:
theorem succ_ofInt' : ∀ n, ZNum.ofInt' (n + 1) = ZNum.ofInt' n + 1
  | (n : ℕ) => by
    change ZNum.ofInt' (n + 1 : ℕ) = ZNum.ofInt' (n : ℕ) + 1
    dsimp only [ZNum.ofInt', ZNum.ofInt']
    rw [Num.ofNat'_succ, Num.add_one, toZNum_succ, ZNum.add_one]
  | -[0+1] => by
    change ZNum.ofInt' 0 = ZNum.ofInt' (-[0+1]) + 1
    dsimp only [ZNum.ofInt', ZNum.ofInt']
    

Proof state:
α : Type u_1
⊢ toZNum (ofNat' 0) = toZNumNeg (ofNat' (0 + 1)) + 1

Next tactic:
rw [ofNat'_succ, ofNat'_zero]
theorem succ_ofInt' : ∀ n, ZNum.ofInt' (n + 1) = ZNum.ofInt' n + 1
  | (n : ℕ) => by
    change ZNum.ofInt' (n + 1 : ℕ) = ZNum.ofInt' (n : ℕ) + 1
    dsimp only [ZNum.ofInt', ZNum.ofInt']
    rw [Num.ofNat'_succ, Num.add_one, toZNum_succ, ZNum.add_one]
  | -[0+1] => by
    change ZNum.ofInt' 0 = ZNum.ofInt' (-[0+1]) + 1
    dsimp only [ZNum.ofInt', ZNum.ofInt']
    rw [ofNat'_succ, ofNat'_zero]; 

Proof state:
α : Type u_1
⊢ toZNum 0 = toZNumNeg (0 + 1) + 1

Next tactic:
rfl
theorem succ_ofInt' : ∀ n, ZNum.ofInt' (n + 1) = ZNum.ofInt' n + 1
  | (n : ℕ) => by
    change ZNum.ofInt' (n + 1 : ℕ) = ZNum.ofInt' (n : ℕ) + 1
    dsimp only [ZNum.ofInt', ZNum.ofInt']
    rw [Num.ofNat'_succ, Num.add_one, toZNum_succ, ZNum.add_one]
  | -[0+1] => by
    change ZNum.ofInt' 0 = ZNum.ofInt' (-[0+1]) + 1
    dsimp only [ZNum.ofInt', ZNum.ofInt']
    rw [ofNat'_succ, ofNat'_zero]; rfl
  | -[(n + 1)+1] => by
    

Proof state:
α : Type u_1
n : ℕ
⊢ ZNum.ofInt' (-[n + 1+1] + 1) = ZNum.ofInt' -[n + 1+1] + 1

Next tactic:
change ZNum.ofInt' -[n+1] = ZNum.ofInt' -[(n + 1)+1] + 1
theorem succ_ofInt' : ∀ n, ZNum.ofInt' (n + 1) = ZNum.ofInt' n + 1
  | (n : ℕ) => by
    change ZNum.ofInt' (n + 1 : ℕ) = ZNum.ofInt' (n : ℕ) + 1
    dsimp only [ZNum.ofInt', ZNum.ofInt']
    rw [Num.ofNat'_succ, Num.add_one, toZNum_succ, ZNum.add_one]
  | -[0+1] => by
    change ZNum.ofInt' 0 = ZNum.ofInt' (-[0+1]) + 1
    dsimp only [ZNum.ofInt', ZNum.ofInt']
    rw [ofNat'_succ, ofNat'_zero]; rfl
  | -[(n + 1)+1] => by
    change ZNum.ofInt' -[n+1] = ZNum.ofInt' -[(n + 1)+1] + 1
    

Proof state:
α : Type u_1
n : ℕ
⊢ ZNum.ofInt' -[n+1] = ZNum.ofInt' -[n + 1+1] + 1

Next tactic:
dsimp only [ZNum.ofInt', ZNum.ofInt']
theorem succ_ofInt' : ∀ n, ZNum.ofInt' (n + 1) = ZNum.ofInt' n + 1
  | (n : ℕ) => by
    change ZNum.ofInt' (n + 1 : ℕ) = ZNum.ofInt' (n : ℕ) + 1
    dsimp only [ZNum.ofInt', ZNum.ofInt']
    rw [Num.ofNat'_succ, Num.add_one, toZNum_succ, ZNum.add_one]
  | -[0+1] => by
    change ZNum.ofInt' 0 = ZNum.ofInt' (-[0+1]) + 1
    dsimp only [ZNum.ofInt', ZNum.ofInt']
    rw [ofNat'_succ, ofNat'_zero]; rfl
  | -[(n + 1)+1] => by
    change ZNum.ofInt' -[n+1] = ZNum.ofInt' -[(n + 1)+1] + 1
    dsimp only [ZNum.ofInt', ZNum.ofInt']
    

Proof state:
α : Type u_1
n : ℕ
⊢ toZNumNeg (ofNat' (n + 1)) = toZNumNeg (ofNat' (n + 1 + 1)) + 1

Next tactic:
rw [@Num.ofNat'_succ (n + 1), Num.add_one, toZNumNeg_succ,
      @ofNat'_succ n, Num.add_one, ZNum.add_one, pred_succ]
theorem ofInt'_toZNum : ∀ n : ℕ, toZNum n = ZNum.ofInt' n
  | 0 => rfl
  | n + 1 => by
    

Proof state:
α : Type u_1
n : ℕ
⊢ toZNum ↑(n + 1) = ZNum.ofInt' ↑(n + 1)

Next tactic:
rw [Nat.cast_succ, Num.add_one, toZNum_succ, ofInt'_toZNum n, Nat.cast_succ, succ_ofInt',
      ZNum.add_one]
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by 

Proof state:
α : Type u_1
m : Num
p : PosNum
⊢ pos p = m ↔ ZNum.pos p = toZNum m

Next tactic:
cases m
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> 

Proof state:
case zero
α : Type u_1
p : PosNum
⊢ pos p = zero ↔ ZNum.pos p = toZNum zero

Next tactic:
constructor
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> 

Proof state:
case pos
α : Type u_1
p a✝ : PosNum
⊢ pos p = pos a✝ ↔ ZNum.pos p = toZNum (pos a✝)

Next tactic:
constructor
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> 

Proof state:
case zero.mp
α : Type u_1
p : PosNum
⊢ pos p = zero → ZNum.pos p = toZNum zero

Next tactic:
intro h
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> 

Proof state:
case zero.mpr
α : Type u_1
p : PosNum
⊢ ZNum.pos p = toZNum zero → pos p = zero

Next tactic:
intro h
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> 

Proof state:
case pos.mp
α : Type u_1
p a✝ : PosNum
⊢ pos p = pos a✝ → ZNum.pos p = toZNum (pos a✝)

Next tactic:
intro h
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> 

Proof state:
case pos.mpr
α : Type u_1
p a✝ : PosNum
⊢ ZNum.pos p = toZNum (pos a✝) → pos p = pos a✝

Next tactic:
intro h
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> 

Proof state:
case zero.mp
α : Type u_1
p : PosNum
h : pos p = zero
⊢ ZNum.pos p = toZNum zero

Next tactic:
try cases h <;> rfl
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> try 

Proof state:
case zero.mp
α : Type u_1
p : PosNum
h : pos p = zero
⊢ ZNum.pos p = toZNum zero

Next tactic:
cases h
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> 

Proof state:
case zero.mpr
α : Type u_1
p : PosNum
h : ZNum.pos p = toZNum zero
⊢ pos p = zero

Next tactic:
try cases h <;> rfl
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> try 

Proof state:
case zero.mpr
α : Type u_1
p : PosNum
h : ZNum.pos p = toZNum zero
⊢ pos p = zero

Next tactic:
cases h
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> 

Proof state:
case pos.mp
α : Type u_1
p a✝ : PosNum
h : pos p = pos a✝
⊢ ZNum.pos p = toZNum (pos a✝)

Next tactic:
try cases h <;> rfl
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> try 

Proof state:
case pos.mp
α : Type u_1
p a✝ : PosNum
h : pos p = pos a✝
⊢ ZNum.pos p = toZNum (pos a✝)

Next tactic:
cases h
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> try cases h <;> 

Proof state:
case pos.mp.refl
α : Type u_1
p : PosNum
⊢ ZNum.pos p = toZNum (pos p)

Next tactic:
rfl
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> 

Proof state:
case pos.mpr
α : Type u_1
p a✝ : PosNum
h : ZNum.pos p = toZNum (pos a✝)
⊢ pos p = pos a✝

Next tactic:
try cases h <;> rfl
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> try 

Proof state:
case pos.mpr
α : Type u_1
p a✝ : PosNum
h : ZNum.pos p = toZNum (pos a✝)
⊢ pos p = pos a✝

Next tactic:
cases h
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> try cases h <;> 

Proof state:
case pos.mpr.refl
α : Type u_1
p : PosNum
⊢ pos p = pos p

Next tactic:
rfl
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> try cases h <;> rfl
  | m, ZNum.neg p => ⟨fun., fun h => by 

Proof state:
α : Type u_1
m : Num
p : PosNum
h : ZNum.neg p = toZNum m
⊢ m ∈ ofZNum' (ZNum.neg p)

Next tactic:
cases m
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> try cases h <;> rfl
  | m, ZNum.neg p => ⟨fun., fun h => by cases m <;> 

Proof state:
case zero
α : Type u_1
p : PosNum
h : ZNum.neg p = toZNum zero
⊢ zero ∈ ofZNum' (ZNum.neg p)

Next tactic:
cases h
theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m
  | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩
  | pos m, 0 => ⟨fun., fun.⟩
  | m, ZNum.pos p =>
    Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> try cases h <;> rfl
  | m, ZNum.neg p => ⟨fun., fun h => by cases m <;> 

Proof state:
case pos
α : Type u_1
p a✝ : PosNum
h : ZNum.neg p = toZNum (pos a✝)
⊢ pos a✝ ∈ ofZNum' (ZNum.neg p)

Next tactic:
cases h
theorem ofZNum'_toNat : ∀ n : ZNum, (↑) <$> ofZNum' n = Int.toNat' n
  | 0 => rfl
  | ZNum.pos p => show _ = Int.toNat' p by 

Proof state:
α : Type u_1
p : PosNum
⊢ castNum <$> ofZNum' (ZNum.pos p) = toNat' ↑p

Next tactic:
rw [← PosNum.to_nat_to_int p]
theorem ofZNum'_toNat : ∀ n : ZNum, (↑) <$> ofZNum' n = Int.toNat' n
  | 0 => rfl
  | ZNum.pos p => show _ = Int.toNat' p by rw [← PosNum.to_nat_to_int p]; 

Proof state:
α : Type u_1
p : PosNum
⊢ castNum <$> ofZNum' (ZNum.pos p) = toNat' ↑↑p

Next tactic:
rfl
theorem ofZNum'_toNat : ∀ n : ZNum, (↑) <$> ofZNum' n = Int.toNat' n
  | 0 => rfl
  | ZNum.pos p => show _ = Int.toNat' p by rw [← PosNum.to_nat_to_int p]; rfl
  | ZNum.neg p =>
    (congr_arg fun x => Int.toNat' (-x)) <|
      show ((p.pred' + 1 : ℕ) : ℤ) = p by 

Proof state:
α : Type u_1
p : PosNum
⊢ ↑(↑(PosNum.pred' p) + 1) = ↑p

Next tactic:
rw [← succ'_to_nat]
theorem ofZNum'_toNat : ∀ n : ZNum, (↑) <$> ofZNum' n = Int.toNat' n
  | 0 => rfl
  | ZNum.pos p => show _ = Int.toNat' p by rw [← PosNum.to_nat_to_int p]; rfl
  | ZNum.neg p =>
    (congr_arg fun x => Int.toNat' (-x)) <|
      show ((p.pred' + 1 : ℕ) : ℤ) = p by rw [← succ'_to_nat]; 

Proof state:
α : Type u_1
p : PosNum
⊢ ↑↑(succ' (PosNum.pred' p)) = ↑p

Next tactic:
simp
@[simp]
theorem ofZNum_toNat : ∀ n : ZNum, (ofZNum n : ℕ) = Int.toNat n
  | 0 => rfl
  | ZNum.pos p => show _ = Int.toNat p by 

Proof state:
α : Type u_1
p : PosNum
⊢ ↑(ofZNum (ZNum.pos p)) = toNat ↑p

Next tactic:
rw [← PosNum.to_nat_to_int p]
@[simp]
theorem ofZNum_toNat : ∀ n : ZNum, (ofZNum n : ℕ) = Int.toNat n
  | 0 => rfl
  | ZNum.pos p => show _ = Int.toNat p by rw [← PosNum.to_nat_to_int p]; 

Proof state:
α : Type u_1
p : PosNum
⊢ ↑(ofZNum (ZNum.pos p)) = toNat ↑↑p

Next tactic:
rfl
@[simp]
theorem ofZNum_toNat : ∀ n : ZNum, (ofZNum n : ℕ) = Int.toNat n
  | 0 => rfl
  | ZNum.pos p => show _ = Int.toNat p by rw [← PosNum.to_nat_to_int p]; rfl
  | ZNum.neg p =>
    (congr_arg fun x => Int.toNat (-x)) <|
      show ((p.pred' + 1 : ℕ) : ℤ) = p by 

Proof state:
α : Type u_1
p : PosNum
⊢ ↑(↑(PosNum.pred' p) + 1) = ↑p

Next tactic:
rw [← succ'_to_nat]
@[simp]
theorem ofZNum_toNat : ∀ n : ZNum, (ofZNum n : ℕ) = Int.toNat n
  | 0 => rfl
  | ZNum.pos p => show _ = Int.toNat p by rw [← PosNum.to_nat_to_int p]; rfl
  | ZNum.neg p =>
    (congr_arg fun x => Int.toNat (-x)) <|
      show ((p.pred' + 1 : ℕ) : ℤ) = p by rw [← succ'_to_nat]; 

Proof state:
α : Type u_1
p : PosNum
⊢ ↑↑(succ' (PosNum.pred' p)) = ↑p

Next tactic:
simp
@[simp]
theorem cast_ofZNum [AddGroupWithOne α] (n : ZNum) : (ofZNum n : α) = Int.toNat n := by
  

Proof state:
α : Type u_1
inst✝ : AddGroupWithOne α
n : ZNum
⊢ ↑(ofZNum n) = ↑(toNat ↑n)

Next tactic:
rw [← cast_to_nat, ofZNum_toNat]
@[simp, norm_cast]
theorem sub_to_nat (m n) : ((m - n : Num) : ℕ) = m - n :=
  show (ofZNum _ : ℕ) = _ by
    

Proof state:
α : Type u_1
m n : Num
⊢ ↑(ofZNum (sub' m n)) = ↑m - ↑n

Next tactic:
rw [ofZNum_toNat, cast_sub', ← to_nat_to_int, ← to_nat_to_int, Int.toNat_sub]
@[simp, norm_cast]
theorem cast_add [AddGroupWithOne α] : ∀ m n, ((m + n : ZNum) : α) = m + n
  | 0, a => by 

Proof state:
α : Type u_1
inst✝ : AddGroupWithOne α
a : ZNum
⊢ ↑(0 + a) = ↑0 + ↑a

Next tactic:
cases a
@[simp, norm_cast]
theorem cast_add [AddGroupWithOne α] : ∀ m n, ((m + n : ZNum) : α) = m + n
  | 0, a => by cases a <;> 

Proof state:
case zero
α : Type u_1
inst✝ : AddGroupWithOne α
⊢ ↑(0 + zero) = ↑0 + ↑zero

Next tactic:
exact (_root_.zero_add _).symm
@[simp, norm_cast]
theorem cast_add [AddGroupWithOne α] : ∀ m n, ((m + n : ZNum) : α) = m + n
  | 0, a => by cases a <;> 

Proof state:
case pos
α : Type u_1
inst✝ : AddGroupWithOne α
a✝ : PosNum
⊢ ↑(0 + pos a✝) = ↑0 + ↑(pos a✝)

Next tactic:
exact (_root_.zero_add _).symm
@[simp, norm_cast]
theorem cast_add [AddGroupWithOne α] : ∀ m n, ((m + n : ZNum) : α) = m + n
  | 0, a => by cases a <;> 

Proof state:
case neg
α : Type u_1
inst✝ : AddGroupWithOne α
a✝ : PosNum
⊢ ↑(0 + neg a✝) = ↑0 + ↑(neg a✝)

Next tactic:
exact (_root_.zero_add _).symm
@[simp, norm_cast]
theorem cast_add [AddGroupWithOne α] : ∀ m n, ((m + n : ZNum) : α) = m + n
  | 0, a => by cases a <;> exact (_root_.zero_add _).symm
  | b, 0 => by 

Proof state:
α : Type u_1
inst✝ : AddGroupWithOne α
b : ZNum
⊢ ↑(b + 0) = ↑b + ↑0

Next tactic:
cases b
@[simp, norm_cast]
theorem cast_add [AddGroupWithOne α] : ∀ m n, ((m + n : ZNum) : α) = m + n
  | 0, a => by cases a <;> exact (_root_.zero_add _).symm
  | b, 0 => by cases b <;> 

Proof state:
case zero
α : Type u_1
inst✝ : AddGroupWithOne α
⊢ ↑(zero + 0) = ↑zero + ↑0

Next tactic:
exact (_root_.add_zero _).symm
@[simp, norm_cast]
theorem cast_add [AddGroupWithOne α] : ∀ m n, ((m + n : ZNum) : α) = m + n
  | 0, a => by cases a <;> exact (_root_.zero_add _).symm
  | b, 0 => by cases b <;> 

Proof state:
case pos
α : Type u_1
inst✝ : AddGroupWithOne α
a✝ : PosNum
⊢ ↑(pos a✝ + 0) = ↑(pos a✝) + ↑0

Next tactic:
exact (_root_.add_zero _).symm
@[simp, norm_cast]
theorem cast_add [AddGroupWithOne α] : ∀ m n, ((m + n : ZNum) : α) = m + n
  | 0, a => by cases a <;> exact (_root_.zero_add _).symm
  | b, 0 => by cases b <;> 

Proof state:
case neg
α : Type u_1
inst✝ : AddGroupWithOne α
a✝ : PosNum
⊢ ↑(neg a✝ + 0) = ↑(neg a✝) + ↑0

Next tactic:
exact (_root_.add_zero _).symm
@[simp, norm_cast]
theorem cast_add [AddGroupWithOne α] : ∀ m n, ((m + n : ZNum) : α) = m + n
  | 0, a => by cases a <;> exact (_root_.zero_add _).symm
  | b, 0 => by cases b <;> exact (_root_.add_zero _).symm
  | pos a, pos b => PosNum.cast_add _ _
  | pos a, neg b => by 

Proof state:
α : Type u_1
inst✝ : AddGroupWithOne α
a b : PosNum
⊢ ↑(pos a + neg b) = ↑(pos a) + ↑(neg b)

Next tactic:
simpa only [sub_eq_add_neg] using PosNum.cast_sub' (α := α) _ _
@[simp, norm_cast]
theorem cast_add [AddGroupWithOne α] : ∀ m n, ((m + n : ZNum) : α) = m + n
  | 0, a => by cases a <;> exact (_root_.zero_add _).symm
  | b, 0 => by cases b <;> exact (_root_.add_zero _).symm
  | pos a, pos b => PosNum.cast_add _ _
  | pos a, neg b => by simpa only [sub_eq_add_neg] using PosNum.cast_sub' (α := α) _ _
  | neg a, pos b =>
    have : (↑b + -↑a : α) = -↑a + ↑b := by
      

Proof state:
α : Type u_1
inst✝ : AddGroupWithOne α
a b : PosNum
⊢ ↑b + -↑a = -↑a + ↑b

Next tactic:
rw [← PosNum.cast_to_int a, ← PosNum.cast_to_int b, ← Int.cast_neg, ← Int.cast_add (-a)]
@[simp, norm_cast]
theorem cast_add [AddGroupWithOne α] : ∀ m n, ((m + n : ZNum) : α) = m + n
  | 0, a => by cases a <;> exact (_root_.zero_add _).symm
  | b, 0 => by cases b <;> exact (_root_.add_zero _).symm
  | pos a, pos b => PosNum.cast_add _ _
  | pos a, neg b => by simpa only [sub_eq_add_neg] using PosNum.cast_sub' (α := α) _ _
  | neg a, pos b =>
    have : (↑b + -↑a : α) = -↑a + ↑b := by
      rw [← PosNum.cast_to_int a, ← PosNum.cast_to_int b, ← Int.cast_neg, ← Int.cast_add (-a)]
      

Proof state:
α : Type u_1
inst✝ : AddGroupWithOne α
a b : PosNum
⊢ ↑↑b + ↑(-↑a) = ↑(-↑a + ↑b)

Next tactic:
simp [add_comm]
@[simp, norm_cast]
theorem cast_add [AddGroupWithOne α] : ∀ m n, ((m + n : ZNum) : α) = m + n
  | 0, a => by cases a <;> exact (_root_.zero_add _).symm
  | b, 0 => by cases b <;> exact (_root_.add_zero _).symm
  | pos a, pos b => PosNum.cast_add _ _
  | pos a, neg b => by simpa only [sub_eq_add_neg] using PosNum.cast_sub' (α := α) _ _
  | neg a, pos b =>
    have : (↑b + -↑a : α) = -↑a + ↑b := by
      rw [← PosNum.cast_to_int a, ← PosNum.cast_to_int b, ← Int.cast_neg, ← Int.cast_add (-a)]
      simp [add_comm]
    (PosNum.cast_sub' _ _).trans <| (sub_eq_add_neg _ _).trans this
  | neg a, neg b =>
    show -(↑(a + b) : α) = -a + -b by
      

Proof state:
α : Type u_1
inst✝ : AddGroupWithOne α
a b : PosNum
⊢ -↑(a + b) = -↑a + -↑b

Next tactic:
rw [PosNum.cast_add, neg_eq_iff_eq_neg, neg_add_rev, neg_neg, neg_neg,
          ← PosNum.cast_to_int a, ← PosNum.cast_to_int b, ← Int.cast_add, ← Int.cast_add, add_comm]
@[simp]
theorem cast_succ [AddGroupWithOne α] (n) : ((succ n : ZNum) : α) = n + 1 := by
  

Proof state:
α : Type u_1
inst✝ : AddGroupWithOne α
n : ZNum
⊢ ↑(succ n) = ↑n + 1

Next tactic:
rw [← add_one, cast_add, cast_one]
@[simp, norm_cast]
theorem mul_to_int : ∀ m n, ((m * n : ZNum) : ℤ) = m * n
  | 0, a => by 

Proof state:
α : Type u_1
a : ZNum
⊢ ↑(0 * a) = ↑0 * ↑a

Next tactic:
cases a
@[simp, norm_cast]
theorem mul_to_int : ∀ m n, ((m * n : ZNum) : ℤ) = m * n
  | 0, a => by cases a <;> 

Proof state:
case zero
α : Type u_1
⊢ ↑(0 * zero) = ↑0 * ↑zero

Next tactic:
exact (zero_mul _).symm
@[simp, norm_cast]
theorem mul_to_int : ∀ m n, ((m * n : ZNum) : ℤ) = m * n
  | 0, a => by cases a <;> 

Proof state:
case pos
α : Type u_1
a✝ : PosNum
⊢ ↑(0 * pos a✝) = ↑0 * ↑(pos a✝)

Next tactic:
exact (zero_mul _).symm
@[simp, norm_cast]
theorem mul_to_int : ∀ m n, ((m * n : ZNum) : ℤ) = m * n
  | 0, a => by cases a <;> 

Proof state:
case neg
α : Type u_1
a✝ : PosNum
⊢ ↑(0 * neg a✝) = ↑0 * ↑(neg a✝)

Next tactic:
exact (zero_mul _).symm
@[simp, norm_cast]
theorem mul_to_int : ∀ m n, ((m * n : ZNum) : ℤ) = m * n
  | 0, a => by cases a <;> exact (zero_mul _).symm
  | b, 0 => by 

Proof state:
α : Type u_1
b : ZNum
⊢ ↑(b * 0) = ↑b * ↑0

Next tactic:
cases b
@[simp, norm_cast]
theorem mul_to_int : ∀ m n, ((m * n : ZNum) : ℤ) = m * n
  | 0, a => by cases a <;> exact (zero_mul _).symm
  | b, 0 => by cases b <;> 

Proof state:
case zero
α : Type u_1
⊢ ↑(zero * 0) = ↑zero * ↑0

Next tactic:
exact (mul_zero _).symm
@[simp, norm_cast]
theorem mul_to_int : ∀ m n, ((m * n : ZNum) : ℤ) = m * n
  | 0, a => by cases a <;> exact (zero_mul _).symm
  | b, 0 => by cases b <;> 

Proof state:
case pos
α : Type u_1
a✝ : PosNum
⊢ ↑(pos a✝ * 0) = ↑(pos a✝) * ↑0

Next tactic:
exact (mul_zero _).symm
@[simp, norm_cast]
theorem mul_to_int : ∀ m n, ((m * n : ZNum) : ℤ) = m * n
  | 0, a => by cases a <;> exact (zero_mul _).symm
  | b, 0 => by cases b <;> 

Proof state:
case neg
α : Type u_1
a✝ : PosNum
⊢ ↑(neg a✝ * 0) = ↑(neg a✝) * ↑0

Next tactic:
exact (mul_zero _).symm
@[simp, norm_cast]
theorem mul_to_int : ∀ m n, ((m * n : ZNum) : ℤ) = m * n
  | 0, a => by cases a <;> exact (zero_mul _).symm
  | b, 0 => by cases b <;> exact (mul_zero _).symm
  | pos a, pos b => PosNum.cast_mul a b
  | pos a, neg b => show -↑(a * b) = ↑a * -↑b by 

Proof state:
α : Type u_1
a b : PosNum
⊢ -↑(a * b) = ↑a * -↑b

Next tactic:
rw [PosNum.cast_mul, neg_mul_eq_mul_neg]
@[simp, norm_cast]
theorem mul_to_int : ∀ m n, ((m * n : ZNum) : ℤ) = m * n
  | 0, a => by cases a <;> exact (zero_mul _).symm
  | b, 0 => by cases b <;> exact (mul_zero _).symm
  | pos a, pos b => PosNum.cast_mul a b
  | pos a, neg b => show -↑(a * b) = ↑a * -↑b by rw [PosNum.cast_mul, neg_mul_eq_mul_neg]
  | neg a, pos b => show -↑(a * b) = -↑a * ↑b by 

Proof state:
α : Type u_1
a b : PosNum
⊢ -↑(a * b) = -↑a * ↑b

Next tactic:
rw [PosNum.cast_mul, neg_mul_eq_neg_mul]
@[simp, norm_cast]
theorem mul_to_int : ∀ m n, ((m * n : ZNum) : ℤ) = m * n
  | 0, a => by cases a <;> exact (zero_mul _).symm
  | b, 0 => by cases b <;> exact (mul_zero _).symm
  | pos a, pos b => PosNum.cast_mul a b
  | pos a, neg b => show -↑(a * b) = ↑a * -↑b by rw [PosNum.cast_mul, neg_mul_eq_mul_neg]
  | neg a, pos b => show -↑(a * b) = -↑a * ↑b by rw [PosNum.cast_mul, neg_mul_eq_neg_mul]
  | neg a, neg b => show ↑(a * b) = -↑a * -↑b by 

Proof state:
α : Type u_1
a b : PosNum
⊢ ↑(a * b) = -↑a * -↑b

Next tactic:
rw [PosNum.cast_mul, neg_mul_neg]
theorem cast_mul [Ring α] (m n) : ((m * n : ZNum) : α) = m * n := by
  

Proof state:
α : Type u_1
inst✝ : Ring α
m n : ZNum
⊢ ↑(m * n) = ↑m * ↑n

Next tactic:
rw [← cast_to_int, mul_to_int, Int.cast_mul, cast_to_int, cast_to_int]
theorem ofInt'_neg : ∀ n : ℤ, ofInt' (-n) = -ofInt' n
  | -[n+1] => show ofInt' (n + 1 : ℕ) = _ by 

Proof state:
α : Type u_1
n : ℕ
⊢ ofInt' ↑(n + 1) = -ofInt' -[n+1]

Next tactic:
simp only [ofInt', Num.zneg_toZNumNeg]
theorem ofInt'_neg : ∀ n : ℤ, ofInt' (-n) = -ofInt' n
  | -[n+1] => show ofInt' (n + 1 : ℕ) = _ by simp only [ofInt', Num.zneg_toZNumNeg]
  | 0 => show Num.toZNum (Num.ofNat' 0) = -Num.toZNum (Num.ofNat' 0) by 

Proof state:
α : Type u_1
⊢ Num.toZNum (Num.ofNat' 0) = -Num.toZNum (Num.ofNat' 0)

Next tactic:
rw [Num.ofNat'_zero]
theorem ofInt'_neg : ∀ n : ℤ, ofInt' (-n) = -ofInt' n
  | -[n+1] => show ofInt' (n + 1 : ℕ) = _ by simp only [ofInt', Num.zneg_toZNumNeg]
  | 0 => show Num.toZNum (Num.ofNat' 0) = -Num.toZNum (Num.ofNat' 0) by rw [Num.ofNat'_zero]; 

Proof state:
α : Type u_1
⊢ Num.toZNum 0 = -Num.toZNum 0

Next tactic:
rfl
theorem ofInt'_neg : ∀ n : ℤ, ofInt' (-n) = -ofInt' n
  | -[n+1] => show ofInt' (n + 1 : ℕ) = _ by simp only [ofInt', Num.zneg_toZNumNeg]
  | 0 => show Num.toZNum (Num.ofNat' 0) = -Num.toZNum (Num.ofNat' 0) by rw [Num.ofNat'_zero]; rfl
  | (n + 1 : ℕ) => show Num.toZNumNeg _ = -Num.toZNum _ by 

Proof state:
α : Type u_1
n : ℕ
⊢ Num.toZNumNeg (Num.ofNat' (Nat.add n 0 + 1)) = -Num.toZNum (Num.ofNat' (n + 1))

Next tactic:
rw [Num.zneg_toZNum]
theorem of_to_int' : ∀ n : ZNum, ZNum.ofInt' n = n
  | 0 => by 

Proof state:
α : Type u_1
⊢ ofInt' ↑0 = 0

Next tactic:
dsimp [ofInt', cast_zero]
theorem of_to_int' : ∀ n : ZNum, ZNum.ofInt' n = n
  | 0 => by dsimp [ofInt', cast_zero]; 

Proof state:
α : Type u_1
⊢ Num.toZNum (Num.ofNat' 0) = 0

Next tactic:
erw [Num.ofNat'_zero, Num.toZNum]
theorem of_to_int' : ∀ n : ZNum, ZNum.ofInt' n = n
  | 0 => by dsimp [ofInt', cast_zero]; erw [Num.ofNat'_zero, Num.toZNum]
  | pos a => by 

Proof state:
α : Type u_1
a : PosNum
⊢ ofInt' ↑(pos a) = pos a

Next tactic:
rw [cast_pos, ← PosNum.cast_to_nat, ← Num.ofInt'_toZNum, PosNum.of_to_nat]
theorem of_to_int' : ∀ n : ZNum, ZNum.ofInt' n = n
  | 0 => by dsimp [ofInt', cast_zero]; erw [Num.ofNat'_zero, Num.toZNum]
  | pos a => by rw [cast_pos, ← PosNum.cast_to_nat, ← Num.ofInt'_toZNum, PosNum.of_to_nat]; 

Proof state:
α : Type u_1
a : PosNum
⊢ Num.toZNum (Num.pos a) = pos a

Next tactic:
rfl