l3lab/ntp-mathlib huggingface dataset:
/-- An ingredient of Tannaka duality for rings:
A ring `R` is equivalent to
the endomorphisms of the additive forgetful functor `Module R ⥤ AddCommGroup`.
-/
def ringEquivEndForget₂ (R : Type u) [Ring R] :
    R ≃+* End (AdditiveFunctor.of (forget₂ (ModuleCat.{u} R) AddCommGroupCat.{u})) where
  toFun r :=
    { app := fun M =>
        @AddCommGroupCat.ofHom M.carrier M.carrier _ _ (DistribMulAction.toAddMonoidHom M r)
      naturality := fun M N f => by
        ext
        exact (f.map_smul _ _).symm }
  invFun φ := φ.app (ModuleCat.of R R) (1 : R)
  left_inv := by
    intro r
    simp
  right_inv := by
    intro φ
    apply NatTrans.ext
    ext M (x : M)
    have w := congr_fun ((forget _).congr_map
      (φ.naturality (ModuleCat.asHomRight (LinearMap.toSpanSingleton R M x)))) (1 : R)
    exact w.symm.trans (congr_arg (φ.app M) (one_smul R x))
  map_add' := by
    intros
    apply NatTrans.ext
    ext
    dsimp
    simp only [AddCommGroupCat.ofHom_apply, DistribMulAction.toAddMonoidHom_apply, add_smul]
    rfl
  map_mul' := by
    intros
    apply NatTrans.ext
    ext
    dsimp
    simp only [AddCommGroupCat.ofHom_apply, DistribMulAction.toAddMonoidHom_apply, mul_smul]
    

Proof state:
case app.h.w
R : Type u
inst✝ : Ring R
x✝² y✝ : R
x✝¹ : ModuleCat R
x✝ : ↑((AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat)).obj.obj x✝¹)
⊢ x✝² • y✝ • x✝ =
    (((NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) x✝²)) *
            NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) y✝)).app
        x✝¹)
      x✝

Next tactic:
rfl
/-- An ingredient of Tannaka duality for rings:
A ring `R` is equivalent to
the endomorphisms of the additive forgetful functor `Module R ⥤ AddCommGroup`.
-/
def ringEquivEndForget₂ (R : Type u) [Ring R] :
    R ≃+* End (AdditiveFunctor.of (forget₂ (ModuleCat.{u} R) AddCommGroupCat.{u})) where
  toFun r :=
    { app := fun M =>
        @AddCommGroupCat.ofHom M.carrier M.carrier _ _ (DistribMulAction.toAddMonoidHom M r)
      naturality := fun M N f => by
        ext
        exact (f.map_smul _ _).symm }
  invFun φ := φ.app (ModuleCat.of R R) (1 : R)
  left_inv := by
    intro r
    simp
  right_inv := by
    intro φ
    apply NatTrans.ext
    ext M (x : M)
    have w := congr_fun ((forget _).congr_map
      (φ.naturality (ModuleCat.asHomRight (LinearMap.toSpanSingleton R M x)))) (1 : R)
    exact w.symm.trans (congr_arg (φ.app M) (one_smul R x))
  map_add' := by
    

Proof state:
R : Type u
inst✝ : Ring R
⊢ ∀ (x y : R),
    Equiv.toFun
        { toFun := fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r),
          invFun := fun φ => (φ.app (ModuleCat.of R R)) 1, left_inv := (_ : ∀ (r : R), r * 1 = r),
          right_inv :=
            (_ :
              ∀ (φ : End (AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat))),
                (fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r))
                    ((fun φ => (φ.app (ModuleCat.of R R)) 1) φ) =
                  φ) }
        (x + y) =
      Equiv.toFun
          { toFun := fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r),
            invFun := fun φ => (φ.app (ModuleCat.of R R)) 1, left_inv := (_ : ∀ (r : R), r * 1 = r),
            right_inv :=
              (_ :
                ∀ (φ : End (AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat))),
                  (fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r))
                      ((fun φ => (φ.app (ModuleCat.of R R)) 1) φ) =
                    φ) }
          x +
        Equiv.toFun
          { toFun := fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r),
            invFun := fun φ => (φ.app (ModuleCat.of R R)) 1, left_inv := (_ : ∀ (r : R), r * 1 = r),
            right_inv :=
              (_ :
                ∀ (φ : End (AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat))),
                  (fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r))
                      ((fun φ => (φ.app (ModuleCat.of R R)) 1) φ) =
                    φ) }
          y

Next tactic:
intros
/-- An ingredient of Tannaka duality for rings:
A ring `R` is equivalent to
the endomorphisms of the additive forgetful functor `Module R ⥤ AddCommGroup`.
-/
def ringEquivEndForget₂ (R : Type u) [Ring R] :
    R ≃+* End (AdditiveFunctor.of (forget₂ (ModuleCat.{u} R) AddCommGroupCat.{u})) where
  toFun r :=
    { app := fun M =>
        @AddCommGroupCat.ofHom M.carrier M.carrier _ _ (DistribMulAction.toAddMonoidHom M r)
      naturality := fun M N f => by
        ext
        exact (f.map_smul _ _).symm }
  invFun φ := φ.app (ModuleCat.of R R) (1 : R)
  left_inv := by
    intro r
    simp
  right_inv := by
    intro φ
    apply NatTrans.ext
    ext M (x : M)
    have w := congr_fun ((forget _).congr_map
      (φ.naturality (ModuleCat.asHomRight (LinearMap.toSpanSingleton R M x)))) (1 : R)
    exact w.symm.trans (congr_arg (φ.app M) (one_smul R x))
  map_add' := by
    intros
    

Proof state:
R : Type u
inst✝ : Ring R
x✝ y✝ : R
⊢ Equiv.toFun
      { toFun := fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r),
        invFun := fun φ => (φ.app (ModuleCat.of R R)) 1, left_inv := (_ : ∀ (r : R), r * 1 = r),
        right_inv :=
          (_ :
            ∀ (φ : End (AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat))),
              (fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r))
                  ((fun φ => (φ.app (ModuleCat.of R R)) 1) φ) =
                φ) }
      (x✝ + y✝) =
    Equiv.toFun
        { toFun := fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r),
          invFun := fun φ => (φ.app (ModuleCat.of R R)) 1, left_inv := (_ : ∀ (r : R), r * 1 = r),
          right_inv :=
            (_ :
              ∀ (φ : End (AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat))),
                (fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r))
                    ((fun φ => (φ.app (ModuleCat.of R R)) 1) φ) =
                  φ) }
        x✝ +
      Equiv.toFun
        { toFun := fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r),
          invFun := fun φ => (φ.app (ModuleCat.of R R)) 1, left_inv := (_ : ∀ (r : R), r * 1 = r),
          right_inv :=
            (_ :
              ∀ (φ : End (AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat))),
                (fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r))
                    ((fun φ => (φ.app (ModuleCat.of R R)) 1) φ) =
                  φ) }
        y✝

Next tactic:
apply NatTrans.ext
/-- An ingredient of Tannaka duality for rings:
A ring `R` is equivalent to
the endomorphisms of the additive forgetful functor `Module R ⥤ AddCommGroup`.
-/
def ringEquivEndForget₂ (R : Type u) [Ring R] :
    R ≃+* End (AdditiveFunctor.of (forget₂ (ModuleCat.{u} R) AddCommGroupCat.{u})) where
  toFun r :=
    { app := fun M =>
        @AddCommGroupCat.ofHom M.carrier M.carrier _ _ (DistribMulAction.toAddMonoidHom M r)
      naturality := fun M N f => by
        ext
        exact (f.map_smul _ _).symm }
  invFun φ := φ.app (ModuleCat.of R R) (1 : R)
  left_inv := by
    intro r
    simp
  right_inv := by
    intro φ
    apply NatTrans.ext
    ext M (x : M)
    have w := congr_fun ((forget _).congr_map
      (φ.naturality (ModuleCat.asHomRight (LinearMap.toSpanSingleton R M x)))) (1 : R)
    exact w.symm.trans (congr_arg (φ.app M) (one_smul R x))
  map_add' := by
    intros
    apply NatTrans.ext
    

Proof state:
case app
R : Type u
inst✝ : Ring R
x✝ y✝ : R
⊢ (Equiv.toFun
        { toFun := fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r),
          invFun := fun φ => (φ.app (ModuleCat.of R R)) 1, left_inv := (_ : ∀ (r : R), r * 1 = r),
          right_inv :=
            (_ :
              ∀ (φ : End (AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat))),
                (fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r))
                    ((fun φ => (φ.app (ModuleCat.of R R)) 1) φ) =
                  φ) }
        (x✝ + y✝)).app =
    (Equiv.toFun
          { toFun := fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r),
            invFun := fun φ => (φ.app (ModuleCat.of R R)) 1, left_inv := (_ : ∀ (r : R), r * 1 = r),
            right_inv :=
              (_ :
                ∀ (φ : End (AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat))),
                  (fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r))
                      ((fun φ => (φ.app (ModuleCat.of R R)) 1) φ) =
                    φ) }
          x✝ +
        Equiv.toFun
          { toFun := fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r),
            invFun := fun φ => (φ.app (ModuleCat.of R R)) 1, left_inv := (_ : ∀ (r : R), r * 1 = r),
            right_inv :=
              (_ :
                ∀ (φ : End (AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat))),
                  (fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r))
                      ((fun φ => (φ.app (ModuleCat.of R R)) 1) φ) =
                    φ) }
          y✝).app

Next tactic:
ext
/-- An ingredient of Tannaka duality for rings:
A ring `R` is equivalent to
the endomorphisms of the additive forgetful functor `Module R ⥤ AddCommGroup`.
-/
def ringEquivEndForget₂ (R : Type u) [Ring R] :
    R ≃+* End (AdditiveFunctor.of (forget₂ (ModuleCat.{u} R) AddCommGroupCat.{u})) where
  toFun r :=
    { app := fun M =>
        @AddCommGroupCat.ofHom M.carrier M.carrier _ _ (DistribMulAction.toAddMonoidHom M r)
      naturality := fun M N f => by
        ext
        exact (f.map_smul _ _).symm }
  invFun φ := φ.app (ModuleCat.of R R) (1 : R)
  left_inv := by
    intro r
    simp
  right_inv := by
    intro φ
    apply NatTrans.ext
    ext M (x : M)
    have w := congr_fun ((forget _).congr_map
      (φ.naturality (ModuleCat.asHomRight (LinearMap.toSpanSingleton R M x)))) (1 : R)
    exact w.symm.trans (congr_arg (φ.app M) (one_smul R x))
  map_add' := by
    intros
    apply NatTrans.ext
    ext
    

Proof state:
case app.h.w
R : Type u
inst✝ : Ring R
x✝² y✝ : R
x✝¹ : ModuleCat R
x✝ : ↑((AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat)).obj.obj x✝¹)
⊢ ((Equiv.toFun
            { toFun := fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r),
              invFun := fun φ => (φ.app (ModuleCat.of R R)) 1, left_inv := (_ : ∀ (r : R), r * 1 = r),
              right_inv :=
                (_ :
                  ∀ (φ : End (AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat))),
                    (fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r))
                        ((fun φ => (φ.app (ModuleCat.of R R)) 1) φ) =
                      φ) }
            (x✝² + y✝)).app
        x✝¹)
      x✝ =
    ((Equiv.toFun
              { toFun := fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r),
                invFun := fun φ => (φ.app (ModuleCat.of R R)) 1, left_inv := (_ : ∀ (r : R), r * 1 = r),
                right_inv :=
                  (_ :
                    ∀ (φ : End (AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat))),
                      (fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r))
                          ((fun φ => (φ.app (ModuleCat.of R R)) 1) φ) =
                        φ) }
              x✝² +
            Equiv.toFun
              { toFun := fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r),
                invFun := fun φ => (φ.app (ModuleCat.of R R)) 1, left_inv := (_ : ∀ (r : R), r * 1 = r),
                right_inv :=
                  (_ :
                    ∀ (φ : End (AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat))),
                      (fun r => NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) r))
                          ((fun φ => (φ.app (ModuleCat.of R R)) 1) φ) =
                        φ) }
              y✝).app
        x✝¹)
      x✝

Next tactic:
dsimp
/-- An ingredient of Tannaka duality for rings:
A ring `R` is equivalent to
the endomorphisms of the additive forgetful functor `Module R ⥤ AddCommGroup`.
-/
def ringEquivEndForget₂ (R : Type u) [Ring R] :
    R ≃+* End (AdditiveFunctor.of (forget₂ (ModuleCat.{u} R) AddCommGroupCat.{u})) where
  toFun r :=
    { app := fun M =>
        @AddCommGroupCat.ofHom M.carrier M.carrier _ _ (DistribMulAction.toAddMonoidHom M r)
      naturality := fun M N f => by
        ext
        exact (f.map_smul _ _).symm }
  invFun φ := φ.app (ModuleCat.of R R) (1 : R)
  left_inv := by
    intro r
    simp
  right_inv := by
    intro φ
    apply NatTrans.ext
    ext M (x : M)
    have w := congr_fun ((forget _).congr_map
      (φ.naturality (ModuleCat.asHomRight (LinearMap.toSpanSingleton R M x)))) (1 : R)
    exact w.symm.trans (congr_arg (φ.app M) (one_smul R x))
  map_add' := by
    intros
    apply NatTrans.ext
    ext
    dsimp
    

Proof state:
case app.h.w
R : Type u
inst✝ : Ring R
x✝² y✝ : R
x✝¹ : ModuleCat R
x✝ : ↑((AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat)).obj.obj x✝¹)
⊢ (x✝² + y✝) • x✝ =
    (((NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) x✝²)) +
            NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) y✝)).app
        x✝¹)
      x✝

Next tactic:
simp only [AddCommGroupCat.ofHom_apply, DistribMulAction.toAddMonoidHom_apply, add_smul]
/-- An ingredient of Tannaka duality for rings:
A ring `R` is equivalent to
the endomorphisms of the additive forgetful functor `Module R ⥤ AddCommGroup`.
-/
def ringEquivEndForget₂ (R : Type u) [Ring R] :
    R ≃+* End (AdditiveFunctor.of (forget₂ (ModuleCat.{u} R) AddCommGroupCat.{u})) where
  toFun r :=
    { app := fun M =>
        @AddCommGroupCat.ofHom M.carrier M.carrier _ _ (DistribMulAction.toAddMonoidHom M r)
      naturality := fun M N f => by
        ext
        exact (f.map_smul _ _).symm }
  invFun φ := φ.app (ModuleCat.of R R) (1 : R)
  left_inv := by
    intro r
    simp
  right_inv := by
    intro φ
    apply NatTrans.ext
    ext M (x : M)
    have w := congr_fun ((forget _).congr_map
      (φ.naturality (ModuleCat.asHomRight (LinearMap.toSpanSingleton R M x)))) (1 : R)
    exact w.symm.trans (congr_arg (φ.app M) (one_smul R x))
  map_add' := by
    intros
    apply NatTrans.ext
    ext
    dsimp
    simp only [AddCommGroupCat.ofHom_apply, DistribMulAction.toAddMonoidHom_apply, add_smul]
    

Proof state:
case app.h.w
R : Type u
inst✝ : Ring R
x✝² y✝ : R
x✝¹ : ModuleCat R
x✝ : ↑((AdditiveFunctor.of (forget₂ (ModuleCat R) AddCommGroupCat)).obj.obj x✝¹)
⊢ x✝² • x✝ + y✝ • x✝ =
    (((NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) x✝²)) +
            NatTrans.mk fun M => AddCommGroupCat.ofHom (DistribMulAction.toAddMonoidHom (↑M) y✝)).app
        x✝¹)
      x✝

Next tactic:
rfl
@[simp]
lemma bitwise_zero_right (n : Nat) : bitwise f n 0 = if f true false then n else 0 := by
  

Proof state:
f : Bool → Bool → Bool
n : ℕ
⊢ bitwise f n 0 = if f true false = true then n else 0

Next tactic:
unfold bitwise
@[simp]
lemma bitwise_zero_right (n : Nat) : bitwise f n 0 = if f true false then n else 0 := by
  unfold bitwise
  

Proof state:
f : Bool → Bool → Bool
n : ℕ
⊢ (if n = 0 then if f false true = true then 0 else 0
    else
      if 0 = 0 then if f true false = true then n else 0
      else
        let n' := n / 2;
        let m' := 0 / 2;
        let b₁ := n % 2 = 1;
        let b₂ := 0 % 2 = 1;
        let r := bitwise f n' m';
        if f (decide b₁) (decide b₂) = true then r + r + 1 else r + r) =
    if f true false = true then n else 0

Next tactic:
simp only [ite_self, decide_False, Nat.zero_div, ite_true, ite_eq_right_iff]
@[simp]
lemma bitwise_zero_right (n : Nat) : bitwise f n 0 = if f true false then n else 0 := by
  unfold bitwise
  simp only [ite_self, decide_False, Nat.zero_div, ite_true, ite_eq_right_iff]
  

Proof state:
f : Bool → Bool → Bool
n : ℕ
⊢ n = 0 → 0 = if f true false = true then n else 0

Next tactic:
rintro ⟨⟩
@[simp]
lemma bitwise_zero_right (n : Nat) : bitwise f n 0 = if f true false then n else 0 := by
  unfold bitwise
  simp only [ite_self, decide_False, Nat.zero_div, ite_true, ite_eq_right_iff]
  rintro ⟨⟩
  

Proof state:
case refl
f : Bool → Bool → Bool
⊢ 0 = if f true false = true then 0 else 0

Next tactic:
split_ifs
@[simp]
lemma bitwise_zero_right (n : Nat) : bitwise f n 0 = if f true false then n else 0 := by
  unfold bitwise
  simp only [ite_self, decide_False, Nat.zero_div, ite_true, ite_eq_right_iff]
  rintro ⟨⟩
  split_ifs <;> 

Proof state:
case pos
f : Bool → Bool → Bool
h✝ : f true false = true
⊢ 0 = 0

Next tactic:
rfl
@[simp]
lemma bitwise_zero_right (n : Nat) : bitwise f n 0 = if f true false then n else 0 := by
  unfold bitwise
  simp only [ite_self, decide_False, Nat.zero_div, ite_true, ite_eq_right_iff]
  rintro ⟨⟩
  split_ifs <;> 

Proof state:
case neg
f : Bool → Bool → Bool
h✝ : ¬f true false = true
⊢ 0 = 0

Next tactic:
rfl
lemma bitwise_zero : bitwise f 0 0 = 0 := by
  

Proof state:
f : Bool → Bool → Bool
⊢ bitwise f 0 0 = 0

Next tactic:
simp only [bitwise_zero_right, ite_self]
lemma bitwise_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) :
    bitwise f n m = bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2)) := by
  

Proof state:
f : Bool → Bool → Bool
n m : ℕ
hn : n ≠ 0
hm : m ≠ 0
⊢ bitwise f n m = bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2))

Next tactic:
conv_lhs => unfold bitwise
lemma bitwise_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) :
    bitwise f n m = bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2)) := by
  conv_lhs => 

Proof state:
f : Bool → Bool → Bool
n m : ℕ
hn : n ≠ 0
hm : m ≠ 0
| bitwise f n m

Next tactic:
unfold bitwise
lemma bitwise_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) :
    bitwise f n m = bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2)) := by
  conv_lhs => unfold bitwise
  

Proof state:
f : Bool → Bool → Bool
n m : ℕ
hn : n ≠ 0
hm : m ≠ 0
⊢ (if n = 0 then if f false true = true then m else 0
    else
      if m = 0 then if f true false = true then n else 0
      else
        let n' := n / 2;
        let m' := m / 2;
        let b₁ := n % 2 = 1;
        let b₂ := m % 2 = 1;
        let r := bitwise f n' m';
        if f (decide b₁) (decide b₂) = true then r + r + 1 else r + r) =
    bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2))

Next tactic:
have mod_two_iff_bod x : (x % 2 = 1 : Bool) = bodd x := by
    simp [mod_two_of_bodd, cond]; cases bodd x <;> rfl
lemma bitwise_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) :
    bitwise f n m = bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2)) := by
  conv_lhs => unfold bitwise
  have mod_two_iff_bod x : (x % 2 = 1 : Bool) = bodd x := by
    

Proof state:
f : Bool → Bool → Bool
n m : ℕ
hn : n ≠ 0
hm : m ≠ 0
x : ℕ
⊢ decide (x % 2 = 1) = bodd x

Next tactic:
simp [mod_two_of_bodd, cond]
lemma bitwise_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) :
    bitwise f n m = bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2)) := by
  conv_lhs => unfold bitwise
  have mod_two_iff_bod x : (x % 2 = 1 : Bool) = bodd x := by
    simp [mod_two_of_bodd, cond]; 

Proof state:
f : Bool → Bool → Bool
n m : ℕ
hn : n ≠ 0
hm : m ≠ 0
x : ℕ
⊢ decide
      ((match bodd x with
        | true => 1
        | false => 0) =
        1) =
    bodd x

Next tactic:
cases bodd x
lemma bitwise_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) :
    bitwise f n m = bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2)) := by
  conv_lhs => unfold bitwise
  have mod_two_iff_bod x : (x % 2 = 1 : Bool) = bodd x := by
    simp [mod_two_of_bodd, cond]; cases bodd x <;> 

Proof state:
case false
f : Bool → Bool → Bool
n m : ℕ
hn : n ≠ 0
hm : m ≠ 0
x : ℕ
⊢ decide
      ((match false with
        | true => 1
        | false => 0) =
        1) =
    false

Next tactic:
rfl
lemma bitwise_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) :
    bitwise f n m = bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2)) := by
  conv_lhs => unfold bitwise
  have mod_two_iff_bod x : (x % 2 = 1 : Bool) = bodd x := by
    simp [mod_two_of_bodd, cond]; cases bodd x <;> 

Proof state:
case true
f : Bool → Bool → Bool
n m : ℕ
hn : n ≠ 0
hm : m ≠ 0
x : ℕ
⊢ decide
      ((match true with
        | true => 1
        | false => 0) =
        1) =
    true

Next tactic:
rfl
lemma bitwise_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) :
    bitwise f n m = bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2)) := by
  conv_lhs => unfold bitwise
  have mod_two_iff_bod x : (x % 2 = 1 : Bool) = bodd x := by
    simp [mod_two_of_bodd, cond]; cases bodd x <;> rfl
  

Proof state:
f : Bool → Bool → Bool
n m : ℕ
hn : n ≠ 0
hm : m ≠ 0
mod_two_iff_bod : ∀ (x : ℕ), decide (x % 2 = 1) = bodd x
⊢ (if n = 0 then if f false true = true then m else 0
    else
      if m = 0 then if f true false = true then n else 0
      else
        let n' := n / 2;
        let m' := m / 2;
        let b₁ := n % 2 = 1;
        let b₂ := m % 2 = 1;
        let r := bitwise f n' m';
        if f (decide b₁) (decide b₂) = true then r + r + 1 else r + r) =
    bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2))

Next tactic:
simp only [hn, hm, mod_two_iff_bod, ite_false, bit, bit1, bit0, Bool.cond_eq_ite]
lemma bitwise_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) :
    bitwise f n m = bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2)) := by
  conv_lhs => unfold bitwise
  have mod_two_iff_bod x : (x % 2 = 1 : Bool) = bodd x := by
    simp [mod_two_of_bodd, cond]; cases bodd x <;> rfl
  simp only [hn, hm, mod_two_iff_bod, ite_false, bit, bit1, bit0, Bool.cond_eq_ite]
  

Proof state:
f : Bool → Bool → Bool
n m : ℕ
hn : n ≠ 0
hm : m ≠ 0
mod_two_iff_bod : ∀ (x : ℕ), decide (x % 2 = 1) = bodd x
⊢ (if f (bodd n) (bodd m) = true then bitwise f (n / 2) (m / 2) + bitwise f (n / 2) (m / 2) + 1
    else bitwise f (n / 2) (m / 2) + bitwise f (n / 2) (m / 2)) =
    ite (f (bodd n) (bodd m) = true) bit1 bit0 (bitwise f (n / 2) (m / 2))

Next tactic:
split_ifs
lemma bitwise_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) :
    bitwise f n m = bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2)) := by
  conv_lhs => unfold bitwise
  have mod_two_iff_bod x : (x % 2 = 1 : Bool) = bodd x := by
    simp [mod_two_of_bodd, cond]; cases bodd x <;> rfl
  simp only [hn, hm, mod_two_iff_bod, ite_false, bit, bit1, bit0, Bool.cond_eq_ite]
  split_ifs <;> 

Proof state:
case pos
f : Bool → Bool → Bool
n m : ℕ
hn : n ≠ 0
hm : m ≠ 0
mod_two_iff_bod : ∀ (x : ℕ), decide (x % 2 = 1) = bodd x
h✝ : f (bodd n) (bodd m) = true
⊢ bitwise f (n / 2) (m / 2) + bitwise f (n / 2) (m / 2) + 1 = bit1 (bitwise f (n / 2) (m / 2))

Next tactic:
rfl
lemma bitwise_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) :
    bitwise f n m = bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2)) := by
  conv_lhs => unfold bitwise
  have mod_two_iff_bod x : (x % 2 = 1 : Bool) = bodd x := by
    simp [mod_two_of_bodd, cond]; cases bodd x <;> rfl
  simp only [hn, hm, mod_two_iff_bod, ite_false, bit, bit1, bit0, Bool.cond_eq_ite]
  split_ifs <;> 

Proof state:
case neg
f : Bool → Bool → Bool
n m : ℕ
hn : n ≠ 0
hm : m ≠ 0
mod_two_iff_bod : ∀ (x : ℕ), decide (x % 2 = 1) = bodd x
h✝ : ¬f (bodd n) (bodd m) = true
⊢ bitwise f (n / 2) (m / 2) + bitwise f (n / 2) (m / 2) = bit0 (bitwise f (n / 2) (m / 2))

Next tactic:
rfl