l3lab/ntp-mathlib huggingface dataset:
instance Γ'.fintype : Fintype Γ' :=
  ⟨⟨{.blank, .bit true, .bit false, .bra, .ket, .comma}, by decide⟩,
    by intro; cases_type* Γ' Bool <;> 

Proof state:
case ket
⊢ ket ∈
    { val := {blank, bit true, bit false, bra, ket, comma},
      nodup := (_ : Multiset.Nodup {blank, bit true, bit false, bra, ket, comma}) }

Next tactic:
decide
instance Γ'.fintype : Fintype Γ' :=
  ⟨⟨{.blank, .bit true, .bit false, .bra, .ket, .comma}, by decide⟩,
    by intro; cases_type* Γ' Bool <;> 

Proof state:
case comma
⊢ comma ∈
    { val := {blank, bit true, bit false, bra, ket, comma},
      nodup := (_ : Multiset.Nodup {blank, bit true, bit false, bra, ket, comma}) }

Next tactic:
decide
theorem decode_encodePosNum : ∀ n, decodePosNum (encodePosNum n) = n := by
  

Proof state:
⊢ ∀ (n : PosNum), decodePosNum (encodePosNum n) = n

Next tactic:
intro n
theorem decode_encodePosNum : ∀ n, decodePosNum (encodePosNum n) = n := by
  intro n
  

Proof state:
n : PosNum
⊢ decodePosNum (encodePosNum n) = n

Next tactic:
induction' n with m hm m hm
theorem decode_encodePosNum : ∀ n, decodePosNum (encodePosNum n) = n := by
  intro n
  induction' n with m hm m hm <;> 

Proof state:
case one
⊢ decodePosNum (encodePosNum PosNum.one) = PosNum.one

Next tactic:
unfold encodePosNum decodePosNum
theorem decode_encodePosNum : ∀ n, decodePosNum (encodePosNum n) = n := by
  intro n
  induction' n with m hm m hm <;> 

Proof state:
case bit1
m : PosNum
hm : decodePosNum (encodePosNum m) = m
⊢ decodePosNum (encodePosNum (PosNum.bit1 m)) = PosNum.bit1 m

Next tactic:
unfold encodePosNum decodePosNum
theorem decode_encodePosNum : ∀ n, decodePosNum (encodePosNum n) = n := by
  intro n
  induction' n with m hm m hm <;> 

Proof state:
case bit0
m : PosNum
hm : decodePosNum (encodePosNum m) = m
⊢ decodePosNum (encodePosNum (PosNum.bit0 m)) = PosNum.bit0 m

Next tactic:
unfold encodePosNum decodePosNum
theorem decode_encodePosNum : ∀ n, decodePosNum (encodePosNum n) = n := by
  intro n
  induction' n with m hm m hm <;> unfold encodePosNum decodePosNum
  · 

Proof state:
case one
⊢ (if [] = [] then PosNum.one else PosNum.bit1 (decodePosNum [])) = PosNum.one

Next tactic:
rfl
theorem decode_encodePosNum : ∀ n, decodePosNum (encodePosNum n) = n := by
  intro n
  induction' n with m hm m hm <;> unfold encodePosNum decodePosNum
  · rfl
  · 

Proof state:
case bit1
m : PosNum
hm : decodePosNum (encodePosNum m) = m
⊢ (if encodePosNum m = [] then PosNum.one else PosNum.bit1 (decodePosNum (encodePosNum m))) = PosNum.bit1 m

Next tactic:
rw [hm]
theorem decode_encodePosNum : ∀ n, decodePosNum (encodePosNum n) = n := by
  intro n
  induction' n with m hm m hm <;> unfold encodePosNum decodePosNum
  · rfl
  · rw [hm]
    

Proof state:
case bit1
m : PosNum
hm : decodePosNum (encodePosNum m) = m
⊢ (if encodePosNum m = [] then PosNum.one else PosNum.bit1 m) = PosNum.bit1 m

Next tactic:
exact if_neg (encodePosNum_nonempty m)
theorem decode_encodePosNum : ∀ n, decodePosNum (encodePosNum n) = n := by
  intro n
  induction' n with m hm m hm <;> unfold encodePosNum decodePosNum
  · rfl
  · rw [hm]
    exact if_neg (encodePosNum_nonempty m)
  · 

Proof state:
case bit0
m : PosNum
hm : decodePosNum (encodePosNum m) = m
⊢ PosNum.bit0 (decodePosNum (encodePosNum m)) = PosNum.bit0 m

Next tactic:
exact congr_arg PosNum.bit0 hm
theorem decode_encodeNum : ∀ n, decodeNum (encodeNum n) = n := by
  

Proof state:
⊢ ∀ (n : Num), decodeNum (encodeNum n) = n

Next tactic:
intro n
theorem decode_encodeNum : ∀ n, decodeNum (encodeNum n) = n := by
  intro n
  

Proof state:
n : Num
⊢ decodeNum (encodeNum n) = n

Next tactic:
cases' n with n
theorem decode_encodeNum : ∀ n, decodeNum (encodeNum n) = n := by
  intro n
  cases' n with n <;> 

Proof state:
case zero
⊢ decodeNum (encodeNum Num.zero) = Num.zero

Next tactic:
unfold encodeNum decodeNum
theorem decode_encodeNum : ∀ n, decodeNum (encodeNum n) = n := by
  intro n
  cases' n with n <;> 

Proof state:
case pos
n : PosNum
⊢ decodeNum (encodeNum (Num.pos n)) = Num.pos n

Next tactic:
unfold encodeNum decodeNum
theorem decode_encodeNum : ∀ n, decodeNum (encodeNum n) = n := by
  intro n
  cases' n with n <;> unfold encodeNum decodeNum
  · 

Proof state:
case zero
⊢ (if
        (match Num.zero with
          | Num.zero => []
          | Num.pos n => encodePosNum n) =
          [] then
      Num.zero
    else
      ↑(decodePosNum
          (match Num.zero with
          | Num.zero => []
          | Num.pos n => encodePosNum n))) =
    Num.zero

Next tactic:
rfl
theorem decode_encodeNum : ∀ n, decodeNum (encodeNum n) = n := by
  intro n
  cases' n with n <;> unfold encodeNum decodeNum
  · rfl
  

Proof state:
case pos
n : PosNum
⊢ (if
        (match Num.pos n with
          | Num.zero => []
          | Num.pos n => encodePosNum n) =
          [] then
      Num.zero
    else
      ↑(decodePosNum
          (match Num.pos n with
          | Num.zero => []
          | Num.pos n => encodePosNum n))) =
    Num.pos n

Next tactic:
rw [decode_encodePosNum n]
theorem decode_encodeNum : ∀ n, decodeNum (encodeNum n) = n := by
  intro n
  cases' n with n <;> unfold encodeNum decodeNum
  · rfl
  rw [decode_encodePosNum n]
  

Proof state:
case pos
n : PosNum
⊢ (if
        (match Num.pos n with
          | Num.zero => []
          | Num.pos n => encodePosNum n) =
          [] then
      Num.zero
    else ↑n) =
    Num.pos n

Next tactic:
rw [PosNum.cast_to_num]
theorem decode_encodeNum : ∀ n, decodeNum (encodeNum n) = n := by
  intro n
  cases' n with n <;> unfold encodeNum decodeNum
  · rfl
  rw [decode_encodePosNum n]
  rw [PosNum.cast_to_num]
  

Proof state:
case pos
n : PosNum
⊢ (if
        (match Num.pos n with
          | Num.zero => []
          | Num.pos n => encodePosNum n) =
          [] then
      Num.zero
    else Num.pos n) =
    Num.pos n

Next tactic:
exact if_neg (encodePosNum_nonempty n)
theorem decode_encodeNat : ∀ n, decodeNat (encodeNat n) = n := by
  

Proof state:
⊢ ∀ (n : ℕ), decodeNat (encodeNat n) = n

Next tactic:
intro n
theorem decode_encodeNat : ∀ n, decodeNat (encodeNat n) = n := by
  intro n
  

Proof state:
n : ℕ
⊢ decodeNat (encodeNat n) = n

Next tactic:
conv_rhs => rw [← Num.to_of_nat n]
theorem decode_encodeNat : ∀ n, decodeNat (encodeNat n) = n := by
  intro n
  conv_rhs => 

Proof state:
n : ℕ
| n

Next tactic:
rw [← Num.to_of_nat n]
theorem decode_encodeNat : ∀ n, decodeNat (encodeNat n) = n := by
  intro n
  conv_rhs => rw [← Num.to_of_nat n]
  

Proof state:
n : ℕ
⊢ decodeNat (encodeNat n) = ↑↑n

Next tactic:
exact congr_arg ((↑) : Num → ℕ) (decode_encodeNum n)
/-- A binary encoding of ℕ in Γ'. -/
def encodingNatΓ' : Encoding ℕ where
  Γ := Γ'
  encode x := List.map inclusionBoolΓ' (encodeNat x)
  decode x := some (decodeNat (List.map sectionΓ'Bool x))
  decode_encode x :=
    congr_arg _ <| by
      -- Porting note: `rw` can't unify `g ∘ f` with `fun x => g (f x)`, used `LeftInverse.id`
      -- instead.
      

Proof state:
x : ℕ
⊢ decodeNat (List.map sectionΓ'Bool ((fun x => List.map inclusionBoolΓ' (encodeNat x)) x)) = x

Next tactic:
rw [List.map_map, leftInverse_section_inclusion.id, List.map_id, decode_encodeNat]
theorem Encoding.card_le_aleph0 {α : Type u} (e : Encoding.{u, v} α) [Encodable e.Γ] :
    #α ≤ ℵ₀ := by
  

Proof state:
α : Type u
e : Encoding α
inst✝ : Encodable e.Γ
⊢ #α ≤ ℵ₀

Next tactic:
refine' Cardinal.lift_le.1 (e.card_le_card_list.trans _)
theorem Encoding.card_le_aleph0 {α : Type u} (e : Encoding.{u, v} α) [Encodable e.Γ] :
    #α ≤ ℵ₀ := by
  refine' Cardinal.lift_le.1 (e.card_le_card_list.trans _)
  

Proof state:
α : Type u
e : Encoding α
inst✝ : Encodable e.Γ
⊢ lift.{u, v} #(List e.Γ) ≤ lift.{v, u} ℵ₀

Next tactic:
simp only [Cardinal.lift_aleph0, Cardinal.lift_le_aleph0]
theorem Encoding.card_le_aleph0 {α : Type u} (e : Encoding.{u, v} α) [Encodable e.Γ] :
    #α ≤ ℵ₀ := by
  refine' Cardinal.lift_le.1 (e.card_le_card_list.trans _)
  simp only [Cardinal.lift_aleph0, Cardinal.lift_le_aleph0]
  

Proof state:
α : Type u
e : Encoding α
inst✝ : Encodable e.Γ
⊢ #(List e.Γ) ≤ ℵ₀

Next tactic:
cases' isEmpty_or_nonempty e.Γ with h h
theorem Encoding.card_le_aleph0 {α : Type u} (e : Encoding.{u, v} α) [Encodable e.Γ] :
    #α ≤ ℵ₀ := by
  refine' Cardinal.lift_le.1 (e.card_le_card_list.trans _)
  simp only [Cardinal.lift_aleph0, Cardinal.lift_le_aleph0]
  cases' isEmpty_or_nonempty e.Γ with h h
  · 

Proof state:
case inl
α : Type u
e : Encoding α
inst✝ : Encodable e.Γ
h : IsEmpty e.Γ
⊢ #(List e.Γ) ≤ ℵ₀

Next tactic:
simp only [Cardinal.mk_le_aleph0]
theorem Encoding.card_le_aleph0 {α : Type u} (e : Encoding.{u, v} α) [Encodable e.Γ] :
    #α ≤ ℵ₀ := by
  refine' Cardinal.lift_le.1 (e.card_le_card_list.trans _)
  simp only [Cardinal.lift_aleph0, Cardinal.lift_le_aleph0]
  cases' isEmpty_or_nonempty e.Γ with h h
  · simp only [Cardinal.mk_le_aleph0]
  · 

Proof state:
case inr
α : Type u
e : Encoding α
inst✝ : Encodable e.Γ
h : Nonempty e.Γ
⊢ #(List e.Γ) ≤ ℵ₀

Next tactic:
rw [Cardinal.mk_list_eq_aleph0]
@[simp]
theorem symm_symm (c : ComplexShape ι) : c.symm.symm = c := by
  

Proof state:
ι : Type u_1
c : ComplexShape ι
⊢ symm (symm c) = c

Next tactic:
ext
@[simp]
theorem symm_symm (c : ComplexShape ι) : c.symm.symm = c := by
  ext
  

Proof state:
case Rel.h.h.a
ι : Type u_1
c : ComplexShape ι
x✝¹ x✝ : ι
⊢ Rel (symm (symm c)) x✝¹ x✝ ↔ Rel c x✝¹ x✝

Next tactic:
simp
/-- The "composition" of two `ComplexShape`s.

We need this to define "related in k steps" later.
-/
@[simp]
def trans (c₁ c₂ : ComplexShape ι) : ComplexShape ι where
  Rel := Relation.Comp c₁.Rel c₂.Rel
  next_eq w w' := by
    

Proof state:
ι : Type u_1
c₁ c₂ : ComplexShape ι
i✝ j✝ j'✝ : ι
w : Relation.Comp c₁.Rel c₂.Rel i✝ j✝
w' : Relation.Comp c₁.Rel c₂.Rel i✝ j'✝
⊢ j✝ = j'✝

Next tactic:
obtain ⟨k, w₁, w₂⟩ := w
/-- The "composition" of two `ComplexShape`s.

We need this to define "related in k steps" later.
-/
@[simp]
def trans (c₁ c₂ : ComplexShape ι) : ComplexShape ι where
  Rel := Relation.Comp c₁.Rel c₂.Rel
  next_eq w w' := by
    obtain ⟨k, w₁, w₂⟩ := w
    

Proof state:
case intro.intro
ι : Type u_1
c₁ c₂ : ComplexShape ι
i✝ j✝ j'✝ : ι
w' : Relation.Comp c₁.Rel c₂.Rel i✝ j'✝
k : ι
w₁ : Rel c₁ i✝ k
w₂ : Rel c₂ k j✝
⊢ j✝ = j'✝

Next tactic:
obtain ⟨k', w₁', w₂'⟩ := w'
/-- The "composition" of two `ComplexShape`s.

We need this to define "related in k steps" later.
-/
@[simp]
def trans (c₁ c₂ : ComplexShape ι) : ComplexShape ι where
  Rel := Relation.Comp c₁.Rel c₂.Rel
  next_eq w w' := by
    obtain ⟨k, w₁, w₂⟩ := w
    obtain ⟨k', w₁', w₂'⟩ := w'
    

Proof state:
case intro.intro.intro.intro
ι : Type u_1
c₁ c₂ : ComplexShape ι
i✝ j✝ j'✝ k : ι
w₁ : Rel c₁ i✝ k
w₂ : Rel c₂ k j✝
k' : ι
w₁' : Rel c₁ i✝ k'
w₂' : Rel c₂ k' j'✝
⊢ j✝ = j'✝

Next tactic:
rw [c₁.next_eq w₁ w₁'] at w₂
/-- The "composition" of two `ComplexShape`s.

We need this to define "related in k steps" later.
-/
@[simp]
def trans (c₁ c₂ : ComplexShape ι) : ComplexShape ι where
  Rel := Relation.Comp c₁.Rel c₂.Rel
  next_eq w w' := by
    obtain ⟨k, w₁, w₂⟩ := w
    obtain ⟨k', w₁', w₂'⟩ := w'
    rw [c₁.next_eq w₁ w₁'] at w₂
    

Proof state:
case intro.intro.intro.intro
ι : Type u_1
c₁ c₂ : ComplexShape ι
i✝ j✝ j'✝ k : ι
w₁ : Rel c₁ i✝ k
k' : ι
w₂ : Rel c₂ k' j✝
w₁' : Rel c₁ i✝ k'
w₂' : Rel c₂ k' j'✝
⊢ j✝ = j'✝

Next tactic:
exact c₂.next_eq w₂ w₂'
/-- The "composition" of two `ComplexShape`s.

We need this to define "related in k steps" later.
-/
@[simp]
def trans (c₁ c₂ : ComplexShape ι) : ComplexShape ι where
  Rel := Relation.Comp c₁.Rel c₂.Rel
  next_eq w w' := by
    obtain ⟨k, w₁, w₂⟩ := w
    obtain ⟨k', w₁', w₂'⟩ := w'
    rw [c₁.next_eq w₁ w₁'] at w₂
    exact c₂.next_eq w₂ w₂'
  prev_eq w w' := by
    

Proof state:
ι : Type u_1
c₁ c₂ : ComplexShape ι
i✝ i'✝ j✝ : ι
w : Relation.Comp c₁.Rel c₂.Rel i✝ j✝
w' : Relation.Comp c₁.Rel c₂.Rel i'✝ j✝
⊢ i✝ = i'✝

Next tactic:
obtain ⟨k, w₁, w₂⟩ := w
/-- The "composition" of two `ComplexShape`s.

We need this to define "related in k steps" later.
-/
@[simp]
def trans (c₁ c₂ : ComplexShape ι) : ComplexShape ι where
  Rel := Relation.Comp c₁.Rel c₂.Rel
  next_eq w w' := by
    obtain ⟨k, w₁, w₂⟩ := w
    obtain ⟨k', w₁', w₂'⟩ := w'
    rw [c₁.next_eq w₁ w₁'] at w₂
    exact c₂.next_eq w₂ w₂'
  prev_eq w w' := by
    obtain ⟨k, w₁, w₂⟩ := w
    

Proof state:
case intro.intro
ι : Type u_1
c₁ c₂ : ComplexShape ι
i✝ i'✝ j✝ : ι
w' : Relation.Comp c₁.Rel c₂.Rel i'✝ j✝
k : ι
w₁ : Rel c₁ i✝ k
w₂ : Rel c₂ k j✝
⊢ i✝ = i'✝

Next tactic:
obtain ⟨k', w₁', w₂'⟩ := w'
/-- The "composition" of two `ComplexShape`s.

We need this to define "related in k steps" later.
-/
@[simp]
def trans (c₁ c₂ : ComplexShape ι) : ComplexShape ι where
  Rel := Relation.Comp c₁.Rel c₂.Rel
  next_eq w w' := by
    obtain ⟨k, w₁, w₂⟩ := w
    obtain ⟨k', w₁', w₂'⟩ := w'
    rw [c₁.next_eq w₁ w₁'] at w₂
    exact c₂.next_eq w₂ w₂'
  prev_eq w w' := by
    obtain ⟨k, w₁, w₂⟩ := w
    obtain ⟨k', w₁', w₂'⟩ := w'
    

Proof state:
case intro.intro.intro.intro
ι : Type u_1
c₁ c₂ : ComplexShape ι
i✝ i'✝ j✝ k : ι
w₁ : Rel c₁ i✝ k
w₂ : Rel c₂ k j✝
k' : ι
w₁' : Rel c₁ i'✝ k'
w₂' : Rel c₂ k' j✝
⊢ i✝ = i'✝

Next tactic:
rw [c₂.prev_eq w₂ w₂'] at w₁
/-- The "composition" of two `ComplexShape`s.

We need this to define "related in k steps" later.
-/
@[simp]
def trans (c₁ c₂ : ComplexShape ι) : ComplexShape ι where
  Rel := Relation.Comp c₁.Rel c₂.Rel
  next_eq w w' := by
    obtain ⟨k, w₁, w₂⟩ := w
    obtain ⟨k', w₁', w₂'⟩ := w'
    rw [c₁.next_eq w₁ w₁'] at w₂
    exact c₂.next_eq w₂ w₂'
  prev_eq w w' := by
    obtain ⟨k, w₁, w₂⟩ := w
    obtain ⟨k', w₁', w₂'⟩ := w'
    rw [c₂.prev_eq w₂ w₂'] at w₁
    

Proof state:
case intro.intro.intro.intro
ι : Type u_1
c₁ c₂ : ComplexShape ι
i✝ i'✝ j✝ k : ι
w₂ : Rel c₂ k j✝
k' : ι
w₁ : Rel c₁ i✝ k'
w₁' : Rel c₁ i'✝ k'
w₂' : Rel c₂ k' j✝
⊢ i✝ = i'✝

Next tactic:
exact c₁.prev_eq w₁ w₁'
instance subsingleton_next (c : ComplexShape ι) (i : ι) : Subsingleton { j // c.Rel i j } := by
  

Proof state:
ι : Type u_1
c : ComplexShape ι
i : ι
⊢ Subsingleton { j // Rel c i j }

Next tactic:
constructor
instance subsingleton_next (c : ComplexShape ι) (i : ι) : Subsingleton { j // c.Rel i j } := by
  constructor
  

Proof state:
case allEq
ι : Type u_1
c : ComplexShape ι
i : ι
⊢ ∀ (a b : { j // Rel c i j }), a = b

Next tactic:
rintro ⟨j, rij⟩ ⟨k, rik⟩
instance subsingleton_next (c : ComplexShape ι) (i : ι) : Subsingleton { j // c.Rel i j } := by
  constructor
  rintro ⟨j, rij⟩ ⟨k, rik⟩
  

Proof state:
case allEq.mk.mk
ι : Type u_1
c : ComplexShape ι
i j : ι
rij : Rel c i j
k : ι
rik : Rel c i k
⊢ { val := j, property := rij } = { val := k, property := rik }

Next tactic:
congr
instance subsingleton_next (c : ComplexShape ι) (i : ι) : Subsingleton { j // c.Rel i j } := by
  constructor
  rintro ⟨j, rij⟩ ⟨k, rik⟩
  congr
  

Proof state:
case allEq.mk.mk.e_val
ι : Type u_1
c : ComplexShape ι
i j : ι
rij : Rel c i j
k : ι
rik : Rel c i k
⊢ j = k

Next tactic:
exact c.next_eq rij rik
instance subsingleton_prev (c : ComplexShape ι) (j : ι) : Subsingleton { i // c.Rel i j } := by
  

Proof state:
ι : Type u_1
c : ComplexShape ι
j : ι
⊢ Subsingleton { i // Rel c i j }

Next tactic:
constructor
instance subsingleton_prev (c : ComplexShape ι) (j : ι) : Subsingleton { i // c.Rel i j } := by
  constructor
  

Proof state:
case allEq
ι : Type u_1
c : ComplexShape ι
j : ι
⊢ ∀ (a b : { i // Rel c i j }), a = b

Next tactic:
rintro ⟨i, rik⟩ ⟨j, rjk⟩
instance subsingleton_prev (c : ComplexShape ι) (j : ι) : Subsingleton { i // c.Rel i j } := by
  constructor
  rintro ⟨i, rik⟩ ⟨j, rjk⟩
  

Proof state:
case allEq.mk.mk
ι : Type u_1
c : ComplexShape ι
j✝ i : ι
rik : Rel c i j✝
j : ι
rjk : Rel c j j✝
⊢ { val := i, property := rik } = { val := j, property := rjk }

Next tactic:
congr
instance subsingleton_prev (c : ComplexShape ι) (j : ι) : Subsingleton { i // c.Rel i j } := by
  constructor
  rintro ⟨i, rik⟩ ⟨j, rjk⟩
  congr
  

Proof state:
case allEq.mk.mk.e_val
ι : Type u_1
c : ComplexShape ι
j✝ i : ι
rik : Rel c i j✝
j : ι
rjk : Rel c j j✝
⊢ i = j

Next tactic:
exact c.prev_eq rik rjk
theorem next_eq' (c : ComplexShape ι) {i j : ι} (h : c.Rel i j) : c.next i = j := by
  

Proof state:
ι : Type u_1
c : ComplexShape ι
i j : ι
h : Rel c i j
⊢ next c i = j

Next tactic:
apply c.next_eq _ h
theorem next_eq' (c : ComplexShape ι) {i j : ι} (h : c.Rel i j) : c.next i = j := by
  apply c.next_eq _ h
  

Proof state:
ι : Type u_1
c : ComplexShape ι
i j : ι
h : Rel c i j
⊢ Rel c i (next c i)

Next tactic:
rw [next]
theorem next_eq' (c : ComplexShape ι) {i j : ι} (h : c.Rel i j) : c.next i = j := by
  apply c.next_eq _ h
  rw [next]
  

Proof state:
ι : Type u_1
c : ComplexShape ι
i j : ι
h : Rel c i j
⊢ Rel c i (if h : ∃ j, Rel c i j then Exists.choose h else i)

Next tactic:
rw [dif_pos]
theorem next_eq' (c : ComplexShape ι) {i j : ι} (h : c.Rel i j) : c.next i = j := by
  apply c.next_eq _ h
  rw [next]
  rw [dif_pos]
  

Proof state:
ι : Type u_1
c : ComplexShape ι
i j : ι
h : Rel c i j
⊢ Rel c i (Exists.choose ?hc)
case hc ι : Type u_1 c : ComplexShape ι i j : ι h : Rel c i j ⊢ ∃ j, Rel c i j

Next tactic:
exact Exists.choose_spec ⟨j, h⟩
theorem prev_eq' (c : ComplexShape ι) {i j : ι} (h : c.Rel i j) : c.prev j = i := by
  

Proof state:
ι : Type u_1
c : ComplexShape ι
i j : ι
h : Rel c i j
⊢ prev c j = i

Next tactic:
apply c.prev_eq _ h
theorem prev_eq' (c : ComplexShape ι) {i j : ι} (h : c.Rel i j) : c.prev j = i := by
  apply c.prev_eq _ h
  

Proof state:
ι : Type u_1
c : ComplexShape ι
i j : ι
h : Rel c i j
⊢ Rel c (prev c j) j

Next tactic:
rw [prev, dif_pos]
theorem prev_eq' (c : ComplexShape ι) {i j : ι} (h : c.Rel i j) : c.prev j = i := by
  apply c.prev_eq _ h
  rw [prev, dif_pos]
  

Proof state:
ι : Type u_1
c : ComplexShape ι
i j : ι
h : Rel c i j
⊢ Rel c (Exists.choose ?hc) j
case hc ι : Type u_1 c : ComplexShape ι i j : ι h : Rel c i j ⊢ ∃ i, Rel c i j

Next tactic:
exact Exists.choose_spec (⟨i, h⟩ : ∃ k, c.Rel k j)
instance UnitsInt.fintype : Fintype ℤˣ :=
  ⟨{1, -1}, fun x ↦ by 

Proof state:
α : Type u_1
x : ℤˣ
⊢ x ∈ {1, -1}

Next tactic:
cases Int.units_eq_one_or x
instance UnitsInt.fintype : Fintype ℤˣ :=
  ⟨{1, -1}, fun x ↦ by cases Int.units_eq_one_or x <;> 

Proof state:
case inl
α : Type u_1
x : ℤˣ
h✝ : x = 1
⊢ x ∈ {1, -1}

Next tactic:
simp [*]
instance UnitsInt.fintype : Fintype ℤˣ :=
  ⟨{1, -1}, fun x ↦ by cases Int.units_eq_one_or x <;> 

Proof state:
case inr
α : Type u_1
x : ℤˣ
h✝ : x = -1
⊢ x ∈ {1, -1}

Next tactic:
simp [*]
theorem Fintype.card_eq_card_units_add_one [GroupWithZero α] [Fintype α] [DecidableEq α] :
    Fintype.card α = Fintype.card αˣ + 1 := by
  

Proof state:
α : Type u_1
inst✝² : GroupWithZero α
inst✝¹ : Fintype α
inst✝ : DecidableEq α
⊢ card α = card αˣ + 1

Next tactic:
rw [eq_comm, Fintype.card_congr (unitsEquivNeZero α)]
theorem Fintype.card_eq_card_units_add_one [GroupWithZero α] [Fintype α] [DecidableEq α] :
    Fintype.card α = Fintype.card αˣ + 1 := by
  rw [eq_comm, Fintype.card_congr (unitsEquivNeZero α)]
  

Proof state:
α : Type u_1
inst✝² : GroupWithZero α
inst✝¹ : Fintype α
inst✝ : DecidableEq α
⊢ card { a // a ≠ 0 } + 1 = card α

Next tactic:
have := Fintype.card_congr (Equiv.sumCompl (· = (0 : α)))
theorem Fintype.card_eq_card_units_add_one [GroupWithZero α] [Fintype α] [DecidableEq α] :
    Fintype.card α = Fintype.card αˣ + 1 := by
  rw [eq_comm, Fintype.card_congr (unitsEquivNeZero α)]
  have := Fintype.card_congr (Equiv.sumCompl (· = (0 : α)))
  

Proof state:
α : Type u_1
inst✝² : GroupWithZero α
inst✝¹ : Fintype α
inst✝ : DecidableEq α
this : card ({ a // a = 0 } ⊕ { a // ¬a = 0 }) = card α
⊢ card { a // a ≠ 0 } + 1 = card α

Next tactic:
rwa [Fintype.card_sum, add_comm, Fintype.card_subtype_eq] at this
theorem Nat.card_eq_card_units_add_one [GroupWithZero α] [Finite α] :
    Nat.card α = Nat.card αˣ + 1 := by
  

Proof state:
α : Type u_1
inst✝¹ : GroupWithZero α
inst✝ : Finite α
⊢ Nat.card α = Nat.card αˣ + 1

Next tactic:
have : Fintype α := Fintype.ofFinite α
theorem Nat.card_eq_card_units_add_one [GroupWithZero α] [Finite α] :
    Nat.card α = Nat.card αˣ + 1 := by
  have : Fintype α := Fintype.ofFinite α
  

Proof state:
α : Type u_1
inst✝¹ : GroupWithZero α
inst✝ : Finite α
this : Fintype α
⊢ Nat.card α = Nat.card αˣ + 1

Next tactic:
classical
    rw [Nat.card_eq_fintype_card, Nat.card_eq_fintype_card, Fintype.card_eq_card_units_add_one]
theorem Nat.card_eq_card_units_add_one [GroupWithZero α] [Finite α] :
    Nat.card α = Nat.card αˣ + 1 := by
  have : Fintype α := Fintype.ofFinite α
  classical
    

Proof state:
α : Type u_1
inst✝¹ : GroupWithZero α
inst✝ : Finite α
this : Fintype α
⊢ Nat.card α = Nat.card αˣ + 1

Next tactic:
rw [Nat.card_eq_fintype_card, Nat.card_eq_fintype_card, Fintype.card_eq_card_units_add_one]
theorem Fintype.card_units [GroupWithZero α] [Fintype α] [DecidableEq α] :
    Fintype.card αˣ = Fintype.card α - 1 := by
  

Proof state:
α : Type u_1
inst✝² : GroupWithZero α
inst✝¹ : Fintype α
inst✝ : DecidableEq α
⊢ card αˣ = card α - 1

Next tactic:
rw [@Fintype.card_eq_card_units_add_one α, Nat.add_sub_cancel]
theorem cos_eq_zero_iff {θ : ℂ} : cos θ = 0 ↔ ∃ k : ℤ, θ = (2 * k + 1) * π / 2 := by
  

Proof state:
θ : ℂ
⊢ cos θ = 0 ↔ ∃ k, θ = (2 * ↑k + 1) * ↑π / 2

Next tactic:
have h : (exp (θ * I) + exp (-θ * I)) / 2 = 0 ↔ exp (2 * θ * I) = -1 := by
    rw [@div_eq_iff _ _ (exp (θ * I) + exp (-θ * I)) 2 0 two_ne_zero, zero_mul,
      add_eq_zero_iff_eq_neg, neg_eq_neg_one_mul, ← div_eq_iff (exp_ne_zero _), ← exp_sub]
    congr 3; ring_nf
theorem cos_eq_zero_iff {θ : ℂ} : cos θ = 0 ↔ ∃ k : ℤ, θ = (2 * k + 1) * π / 2 := by
  have h : (exp (θ * I) + exp (-θ * I)) / 2 = 0 ↔ exp (2 * θ * I) = -1 := by
    

Proof state:
θ : ℂ
⊢ (cexp (θ * I) + cexp (-θ * I)) / 2 = 0 ↔ cexp (2 * θ * I) = -1

Next tactic:
rw [@div_eq_iff _ _ (exp (θ * I) + exp (-θ * I)) 2 0 two_ne_zero, zero_mul,
      add_eq_zero_iff_eq_neg, neg_eq_neg_one_mul, ← div_eq_iff (exp_ne_zero _), ← exp_sub]
theorem cos_eq_zero_iff {θ : ℂ} : cos θ = 0 ↔ ∃ k : ℤ, θ = (2 * k + 1) * π / 2 := by
  have h : (exp (θ * I) + exp (-θ * I)) / 2 = 0 ↔ exp (2 * θ * I) = -1 := by
    rw [@div_eq_iff _ _ (exp (θ * I) + exp (-θ * I)) 2 0 two_ne_zero, zero_mul,
      add_eq_zero_iff_eq_neg, neg_eq_neg_one_mul, ← div_eq_iff (exp_ne_zero _), ← exp_sub]
    

Proof state:
θ : ℂ
⊢ cexp (θ * I - -θ * I) = -1 ↔ cexp (2 * θ * I) = -1

Next tactic:
congr 3
theorem cos_eq_zero_iff {θ : ℂ} : cos θ = 0 ↔ ∃ k : ℤ, θ = (2 * k + 1) * π / 2 := by
  have h : (exp (θ * I) + exp (-θ * I)) / 2 = 0 ↔ exp (2 * θ * I) = -1 := by
    rw [@div_eq_iff _ _ (exp (θ * I) + exp (-θ * I)) 2 0 two_ne_zero, zero_mul,
      add_eq_zero_iff_eq_neg, neg_eq_neg_one_mul, ← div_eq_iff (exp_ne_zero _), ← exp_sub]
    congr 3; 

Proof state:
θ : ℂ
⊢ cexp (θ * I - -θ * I) = -1 ↔ cexp (2 * θ * I) = -1

Next tactic:
ring_nf
theorem cos_eq_zero_iff {θ : ℂ} : cos θ = 0 ↔ ∃ k : ℤ, θ = (2 * k + 1) * π / 2 := by
  have h : (exp (θ * I) + exp (-θ * I)) / 2 = 0 ↔ exp (2 * θ * I) = -1 := by
    rw [@div_eq_iff _ _ (exp (θ * I) + exp (-θ * I)) 2 0 two_ne_zero, zero_mul,
      add_eq_zero_iff_eq_neg, neg_eq_neg_one_mul, ← div_eq_iff (exp_ne_zero _), ← exp_sub]
    congr 3; ring_nf
  

Proof state:
θ : ℂ
h : (cexp (θ * I) + cexp (-θ * I)) / 2 = 0 ↔ cexp (2 * θ * I) = -1
⊢ cos θ = 0 ↔ ∃ k, θ = (2 * ↑k + 1) * ↑π / 2

Next tactic:
rw [cos, h, ← exp_pi_mul_I, exp_eq_exp_iff_exists_int, mul_right_comm]
theorem cos_eq_zero_iff {θ : ℂ} : cos θ = 0 ↔ ∃ k : ℤ, θ = (2 * k + 1) * π / 2 := by
  have h : (exp (θ * I) + exp (-θ * I)) / 2 = 0 ↔ exp (2 * θ * I) = -1 := by
    rw [@div_eq_iff _ _ (exp (θ * I) + exp (-θ * I)) 2 0 two_ne_zero, zero_mul,
      add_eq_zero_iff_eq_neg, neg_eq_neg_one_mul, ← div_eq_iff (exp_ne_zero _), ← exp_sub]
    congr 3; ring_nf
  rw [cos, h, ← exp_pi_mul_I, exp_eq_exp_iff_exists_int, mul_right_comm]
  

Proof state:
θ : ℂ
h : (cexp (θ * I) + cexp (-θ * I)) / 2 = 0 ↔ cexp (2 * θ * I) = -1
⊢ (∃ n, 2 * I * θ = ↑π * I + ↑n * (2 * ↑π * I)) ↔ ∃ k, θ = (2 * ↑k + 1) * ↑π / 2

Next tactic:
refine' exists_congr fun x => _