l3lab/ntp-mathlib huggingface dataset:
theorem cycle_eq : ∀ (l : List α) (h : l ≠ []), cycle l h = l ++ₛ cycle l h
  | [], h => absurd rfl h
  | List.cons a l, _ =>
    have gen : ∀ l' a', corec Stream'.cycleF Stream'.cycleG (a', l', a, l) =
        (a'::l') ++ₛ corec Stream'.cycleF Stream'.cycleG (a, l, a, l) := by
      intro l'
      induction' l' with a₁ l₁ ih
      · intros
        rw [corec_eq]
        rfl
      · intros
        

Proof state:
case cons
α : Type u
β : Type v
δ : Type w
a : α
l : List α
x✝ : a :: l ≠ []
a₁ : α
l₁ : List α
ih :
  ∀ (a' : α),
    corec Stream'.cycleF Stream'.cycleG (a', l₁, a, l) = a' :: l₁ ++ₛ corec Stream'.cycleF Stream'.cycleG (a, l, a, l)
a'✝ : α
⊢ corec Stream'.cycleF Stream'.cycleG (a'✝, a₁ :: l₁, a, l) =
    a'✝ :: a₁ :: l₁ ++ₛ corec Stream'.cycleF Stream'.cycleG (a, l, a, l)

Next tactic:
rw [corec_eq, Stream'.cycle_g_cons, ih a₁]
theorem cycle_eq : ∀ (l : List α) (h : l ≠ []), cycle l h = l ++ₛ cycle l h
  | [], h => absurd rfl h
  | List.cons a l, _ =>
    have gen : ∀ l' a', corec Stream'.cycleF Stream'.cycleG (a', l', a, l) =
        (a'::l') ++ₛ corec Stream'.cycleF Stream'.cycleG (a, l, a, l) := by
      intro l'
      induction' l' with a₁ l₁ ih
      · intros
        rw [corec_eq]
        rfl
      · intros
        rw [corec_eq, Stream'.cycle_g_cons, ih a₁]
        

Proof state:
case cons
α : Type u
β : Type v
δ : Type w
a : α
l : List α
x✝ : a :: l ≠ []
a₁ : α
l₁ : List α
ih :
  ∀ (a' : α),
    corec Stream'.cycleF Stream'.cycleG (a', l₁, a, l) = a' :: l₁ ++ₛ corec Stream'.cycleF Stream'.cycleG (a, l, a, l)
a'✝ : α
⊢ Stream'.cycleF (a'✝, a₁ :: l₁, a, l) :: (a₁ :: l₁ ++ₛ corec Stream'.cycleF Stream'.cycleG (a, l, a, l)) =
    a'✝ :: a₁ :: l₁ ++ₛ corec Stream'.cycleF Stream'.cycleG (a, l, a, l)

Next tactic:
rfl
theorem mem_cycle {a : α} {l : List α} : ∀ h : l ≠ [], a ∈ l → a ∈ cycle l h := fun h ainl => by
  

Proof state:
α : Type u
β : Type v
δ : Type w
a : α
l : List α
h : l ≠ []
ainl : a ∈ l
⊢ a ∈ cycle l h

Next tactic:
rw [cycle_eq]
theorem mem_cycle {a : α} {l : List α} : ∀ h : l ≠ [], a ∈ l → a ∈ cycle l h := fun h ainl => by
  rw [cycle_eq]; 

Proof state:
α : Type u
β : Type v
δ : Type w
a : α
l : List α
h : l ≠ []
ainl : a ∈ l
⊢ a ∈ l ++ₛ cycle l h

Next tactic:
exact mem_append_stream_left _ ainl
@[simp]
theorem cycle_singleton (a : α) : cycle [a] (by 

Proof state:
α : Type u
β : Type v
δ : Type w
a : α
⊢ [a] ≠ []

Next tactic:
simp
@[simp]
theorem cycle_singleton (a : α) : cycle [a] (by simp) = const a :=
  coinduction rfl fun β fr ch => by 

Proof state:
α : Type u
β✝ : Type v
δ : Type w
a : α
β : Type u
fr : Stream' α → β
ch : fr (cycle [a] (_ : ¬[a] = [])) = fr (const a)
⊢ fr (tail (cycle [a] (_ : ¬[a] = []))) = fr (tail (const a))

Next tactic:
rwa [cycle_eq, const_eq]
theorem tails_eq (s : Stream' α) : tails s = tail s::tails (tail s) := by
  

Proof state:
α : Type u
β : Type v
δ : Type w
s : Stream' α
⊢ tails s = tail s :: tails (tail s)

Next tactic:
unfold tails
theorem tails_eq (s : Stream' α) : tails s = tail s::tails (tail s) := by
  unfold tails; 

Proof state:
α : Type u
β : Type v
δ : Type w
s : Stream' α
⊢ corec id tail (tail s) = tail s :: corec id tail (tail (tail s))

Next tactic:
rw [corec_eq]
theorem tails_eq (s : Stream' α) : tails s = tail s::tails (tail s) := by
  unfold tails; rw [corec_eq]; 

Proof state:
α : Type u
β : Type v
δ : Type w
s : Stream' α
⊢ id (tail s) :: corec id tail (tail (tail s)) = tail s :: corec id tail (tail (tail s))

Next tactic:
rfl
@[simp]
theorem get_tails : ∀ (n : Nat) (s : Stream' α), get (tails s) n = drop n (tail s) := by
  

Proof state:
α : Type u
β : Type v
δ : Type w
⊢ ∀ (n : ℕ) (s : Stream' α), get (tails s) n = drop n (tail s)

Next tactic:
intro n
@[simp]
theorem get_tails : ∀ (n : Nat) (s : Stream' α), get (tails s) n = drop n (tail s) := by
  intro n; 

Proof state:
α : Type u
β : Type v
δ : Type w
n : ℕ
⊢ ∀ (s : Stream' α), get (tails s) n = drop n (tail s)

Next tactic:
induction' n with n' ih
@[simp]
theorem get_tails : ∀ (n : Nat) (s : Stream' α), get (tails s) n = drop n (tail s) := by
  intro n; induction' n with n' ih
  · 

Proof state:
case zero
α : Type u
β : Type v
δ : Type w
⊢ ∀ (s : Stream' α), get (tails s) zero = drop zero (tail s)

Next tactic:
intros
@[simp]
theorem get_tails : ∀ (n : Nat) (s : Stream' α), get (tails s) n = drop n (tail s) := by
  intro n; induction' n with n' ih
  · intros
    

Proof state:
case zero
α : Type u
β : Type v
δ : Type w
s✝ : Stream' α
⊢ get (tails s✝) zero = drop zero (tail s✝)

Next tactic:
rfl
@[simp]
theorem get_tails : ∀ (n : Nat) (s : Stream' α), get (tails s) n = drop n (tail s) := by
  intro n; induction' n with n' ih
  · intros
    rfl
  · 

Proof state:
case succ
α : Type u
β : Type v
δ : Type w
n' : ℕ
ih : ∀ (s : Stream' α), get (tails s) n' = drop n' (tail s)
⊢ ∀ (s : Stream' α), get (tails s) (succ n') = drop (succ n') (tail s)

Next tactic:
intro s
@[simp]
theorem get_tails : ∀ (n : Nat) (s : Stream' α), get (tails s) n = drop n (tail s) := by
  intro n; induction' n with n' ih
  · intros
    rfl
  · intro s
    

Proof state:
case succ
α : Type u
β : Type v
δ : Type w
n' : ℕ
ih : ∀ (s : Stream' α), get (tails s) n' = drop n' (tail s)
s : Stream' α
⊢ get (tails s) (succ n') = drop (succ n') (tail s)

Next tactic:
rw [get_succ, drop_succ, tails_eq, tail_cons, ih]
theorem inits_core_eq (l : List α) (s : Stream' α) :
    initsCore l s = l::initsCore (l ++ [head s]) (tail s) := by
    

Proof state:
α : Type u
β : Type v
δ : Type w
l : List α
s : Stream' α
⊢ initsCore l s = l :: initsCore (l ++ [head s]) (tail s)

Next tactic:
unfold initsCore corecOn
theorem inits_core_eq (l : List α) (s : Stream' α) :
    initsCore l s = l::initsCore (l ++ [head s]) (tail s) := by
    unfold initsCore corecOn
    

Proof state:
α : Type u
β : Type v
δ : Type w
l : List α
s : Stream' α
⊢ corec
      (fun x =>
        match x with
        | (a, snd) => a)
      (fun p =>
        match p with
        | (l', s') => (l' ++ [head s'], tail s'))
      (l, s) =
    l ::
      corec
        (fun x =>
          match x with
          | (a, snd) => a)
        (fun p =>
          match p with
          | (l', s') => (l' ++ [head s'], tail s'))
        (l ++ [head s], tail s)

Next tactic:
rw [corec_eq]
theorem tail_inits (s : Stream' α) :
    tail (inits s) = initsCore [head s, head (tail s)] (tail (tail s)) := by
    

Proof state:
α : Type u
β : Type v
δ : Type w
s : Stream' α
⊢ tail (inits s) = initsCore [head s, head (tail s)] (tail (tail s))

Next tactic:
unfold inits
theorem tail_inits (s : Stream' α) :
    tail (inits s) = initsCore [head s, head (tail s)] (tail (tail s)) := by
    unfold inits
    

Proof state:
α : Type u
β : Type v
δ : Type w
s : Stream' α
⊢ tail (initsCore [head s] (tail s)) = initsCore [head s, head (tail s)] (tail (tail s))

Next tactic:
rw [inits_core_eq]
theorem tail_inits (s : Stream' α) :
    tail (inits s) = initsCore [head s, head (tail s)] (tail (tail s)) := by
    unfold inits
    rw [inits_core_eq]; 

Proof state:
α : Type u
β : Type v
δ : Type w
s : Stream' α
⊢ tail ([head s] :: initsCore ([head s] ++ [head (tail s)]) (tail (tail s))) =
    initsCore [head s, head (tail s)] (tail (tail s))

Next tactic:
rfl
theorem cons_get_inits_core :
    ∀ (a : α) (n : Nat) (l : List α) (s : Stream' α),
      (a::get (initsCore l s) n) = get (initsCore (a::l) s) n := by
  

Proof state:
α : Type u
β : Type v
δ : Type w
⊢ ∀ (a : α) (n : ℕ) (l : List α) (s : Stream' α), a :: get (initsCore l s) n = get (initsCore (a :: l) s) n

Next tactic:
intro a n
theorem cons_get_inits_core :
    ∀ (a : α) (n : Nat) (l : List α) (s : Stream' α),
      (a::get (initsCore l s) n) = get (initsCore (a::l) s) n := by
  intro a n
  

Proof state:
α : Type u
β : Type v
δ : Type w
a : α
n : ℕ
⊢ ∀ (l : List α) (s : Stream' α), a :: get (initsCore l s) n = get (initsCore (a :: l) s) n

Next tactic:
induction' n with n' ih
theorem cons_get_inits_core :
    ∀ (a : α) (n : Nat) (l : List α) (s : Stream' α),
      (a::get (initsCore l s) n) = get (initsCore (a::l) s) n := by
  intro a n
  induction' n with n' ih
  · 

Proof state:
case zero
α : Type u
β : Type v
δ : Type w
a : α
⊢ ∀ (l : List α) (s : Stream' α), a :: get (initsCore l s) zero = get (initsCore (a :: l) s) zero

Next tactic:
intros
theorem cons_get_inits_core :
    ∀ (a : α) (n : Nat) (l : List α) (s : Stream' α),
      (a::get (initsCore l s) n) = get (initsCore (a::l) s) n := by
  intro a n
  induction' n with n' ih
  · intros
    

Proof state:
case zero
α : Type u
β : Type v
δ : Type w
a : α
l✝ : List α
s✝ : Stream' α
⊢ a :: get (initsCore l✝ s✝) zero = get (initsCore (a :: l✝) s✝) zero

Next tactic:
rfl
theorem cons_get_inits_core :
    ∀ (a : α) (n : Nat) (l : List α) (s : Stream' α),
      (a::get (initsCore l s) n) = get (initsCore (a::l) s) n := by
  intro a n
  induction' n with n' ih
  · intros
    rfl
  · 

Proof state:
case succ
α : Type u
β : Type v
δ : Type w
a : α
n' : ℕ
ih : ∀ (l : List α) (s : Stream' α), a :: get (initsCore l s) n' = get (initsCore (a :: l) s) n'
⊢ ∀ (l : List α) (s : Stream' α), a :: get (initsCore l s) (succ n') = get (initsCore (a :: l) s) (succ n')

Next tactic:
intro l s
theorem cons_get_inits_core :
    ∀ (a : α) (n : Nat) (l : List α) (s : Stream' α),
      (a::get (initsCore l s) n) = get (initsCore (a::l) s) n := by
  intro a n
  induction' n with n' ih
  · intros
    rfl
  · intro l s
    

Proof state:
case succ
α : Type u
β : Type v
δ : Type w
a : α
n' : ℕ
ih : ∀ (l : List α) (s : Stream' α), a :: get (initsCore l s) n' = get (initsCore (a :: l) s) n'
l : List α
s : Stream' α
⊢ a :: get (initsCore l s) (succ n') = get (initsCore (a :: l) s) (succ n')

Next tactic:
rw [get_succ, inits_core_eq, tail_cons, ih, inits_core_eq (a::l) s]
theorem cons_get_inits_core :
    ∀ (a : α) (n : Nat) (l : List α) (s : Stream' α),
      (a::get (initsCore l s) n) = get (initsCore (a::l) s) n := by
  intro a n
  induction' n with n' ih
  · intros
    rfl
  · intro l s
    rw [get_succ, inits_core_eq, tail_cons, ih, inits_core_eq (a::l) s]
    

Proof state:
case succ
α : Type u
β : Type v
δ : Type w
a : α
n' : ℕ
ih : ∀ (l : List α) (s : Stream' α), a :: get (initsCore l s) n' = get (initsCore (a :: l) s) n'
l : List α
s : Stream' α
⊢ get (initsCore (a :: (l ++ [head s])) (tail s)) n' =
    get ((a :: l) :: initsCore (a :: l ++ [head s]) (tail s)) (succ n')

Next tactic:
rfl
@[simp]
theorem get_inits : ∀ (n : Nat) (s : Stream' α), get (inits s) n = take (succ n) s := by
  

Proof state:
α : Type u
β : Type v
δ : Type w
⊢ ∀ (n : ℕ) (s : Stream' α), get (inits s) n = take (succ n) s

Next tactic:
intro n
@[simp]
theorem get_inits : ∀ (n : Nat) (s : Stream' α), get (inits s) n = take (succ n) s := by
  intro n; 

Proof state:
α : Type u
β : Type v
δ : Type w
n : ℕ
⊢ ∀ (s : Stream' α), get (inits s) n = take (succ n) s

Next tactic:
induction' n with n' ih
@[simp]
theorem get_inits : ∀ (n : Nat) (s : Stream' α), get (inits s) n = take (succ n) s := by
  intro n; induction' n with n' ih
  · 

Proof state:
case zero
α : Type u
β : Type v
δ : Type w
⊢ ∀ (s : Stream' α), get (inits s) zero = take (succ zero) s

Next tactic:
intros
@[simp]
theorem get_inits : ∀ (n : Nat) (s : Stream' α), get (inits s) n = take (succ n) s := by
  intro n; induction' n with n' ih
  · intros
    

Proof state:
case zero
α : Type u
β : Type v
δ : Type w
s✝ : Stream' α
⊢ get (inits s✝) zero = take (succ zero) s✝

Next tactic:
rfl
@[simp]
theorem get_inits : ∀ (n : Nat) (s : Stream' α), get (inits s) n = take (succ n) s := by
  intro n; induction' n with n' ih
  · intros
    rfl
  · 

Proof state:
case succ
α : Type u
β : Type v
δ : Type w
n' : ℕ
ih : ∀ (s : Stream' α), get (inits s) n' = take (succ n') s
⊢ ∀ (s : Stream' α), get (inits s) (succ n') = take (succ (succ n')) s

Next tactic:
intros
@[simp]
theorem get_inits : ∀ (n : Nat) (s : Stream' α), get (inits s) n = take (succ n) s := by
  intro n; induction' n with n' ih
  · intros
    rfl
  · intros
    

Proof state:
case succ
α : Type u
β : Type v
δ : Type w
n' : ℕ
ih : ∀ (s : Stream' α), get (inits s) n' = take (succ n') s
s✝ : Stream' α
⊢ get (inits s✝) (succ n') = take (succ (succ n')) s✝

Next tactic:
rw [get_succ, take_succ, ← ih, tail_inits, inits_tail, cons_get_inits_core]
theorem inits_eq (s : Stream' α) :
    inits s = [head s]::map (List.cons (head s)) (inits (tail s)) := by
  

Proof state:
α : Type u
β : Type v
δ : Type w
s : Stream' α
⊢ inits s = [head s] :: map (List.cons (head s)) (inits (tail s))

Next tactic:
apply Stream'.ext
theorem inits_eq (s : Stream' α) :
    inits s = [head s]::map (List.cons (head s)) (inits (tail s)) := by
  apply Stream'.ext; 

Proof state:
case a
α : Type u
β : Type v
δ : Type w
s : Stream' α
⊢ ∀ (n : ℕ), get (inits s) n = get ([head s] :: map (List.cons (head s)) (inits (tail s))) n

Next tactic:
intro n
theorem inits_eq (s : Stream' α) :
    inits s = [head s]::map (List.cons (head s)) (inits (tail s)) := by
  apply Stream'.ext; intro n
  

Proof state:
case a
α : Type u
β : Type v
δ : Type w
s : Stream' α
n : ℕ
⊢ get (inits s) n = get ([head s] :: map (List.cons (head s)) (inits (tail s))) n

Next tactic:
cases n
theorem inits_eq (s : Stream' α) :
    inits s = [head s]::map (List.cons (head s)) (inits (tail s)) := by
  apply Stream'.ext; intro n
  cases n
  · 

Proof state:
case a.zero
α : Type u
β : Type v
δ : Type w
s : Stream' α
⊢ get (inits s) zero = get ([head s] :: map (List.cons (head s)) (inits (tail s))) zero

Next tactic:
rfl
theorem inits_eq (s : Stream' α) :
    inits s = [head s]::map (List.cons (head s)) (inits (tail s)) := by
  apply Stream'.ext; intro n
  cases n
  · rfl
  · 

Proof state:
case a.succ
α : Type u
β : Type v
δ : Type w
s : Stream' α
n✝ : ℕ
⊢ get (inits s) (succ n✝) = get ([head s] :: map (List.cons (head s)) (inits (tail s))) (succ n✝)

Next tactic:
rw [get_inits, get_succ, tail_cons, get_map, get_inits]
theorem inits_eq (s : Stream' α) :
    inits s = [head s]::map (List.cons (head s)) (inits (tail s)) := by
  apply Stream'.ext; intro n
  cases n
  · rfl
  · rw [get_inits, get_succ, tail_cons, get_map, get_inits]
    

Proof state:
case a.succ
α : Type u
β : Type v
δ : Type w
s : Stream' α
n✝ : ℕ
⊢ take (succ (succ n✝)) s = head s :: take (succ n✝) (tail s)

Next tactic:
rfl
theorem zip_inits_tails (s : Stream' α) : zip appendStream' (inits s) (tails s) = const s := by
  

Proof state:
α : Type u
β : Type v
δ : Type w
s : Stream' α
⊢ zip appendStream' (inits s) (tails s) = const s

Next tactic:
apply Stream'.ext
theorem zip_inits_tails (s : Stream' α) : zip appendStream' (inits s) (tails s) = const s := by
  apply Stream'.ext; 

Proof state:
case a
α : Type u
β : Type v
δ : Type w
s : Stream' α
⊢ ∀ (n : ℕ), get (zip appendStream' (inits s) (tails s)) n = get (const s) n

Next tactic:
intro n
theorem zip_inits_tails (s : Stream' α) : zip appendStream' (inits s) (tails s) = const s := by
  apply Stream'.ext; intro n
  

Proof state:
case a
α : Type u
β : Type v
δ : Type w
s : Stream' α
n : ℕ
⊢ get (zip appendStream' (inits s) (tails s)) n = get (const s) n

Next tactic:
rw [get_zip, get_inits, get_tails, get_const, take_succ, cons_append_stream, append_take_drop,
    Stream'.eta]
theorem nats_eq : nats = cons 0 (map succ nats) := by
  

Proof state:
α : Type u
β : Type v
δ : Type w
⊢ nats = 0 :: map succ nats

Next tactic:
apply Stream'.ext
theorem nats_eq : nats = cons 0 (map succ nats) := by
  apply Stream'.ext; 

Proof state:
case a
α : Type u
β : Type v
δ : Type w
⊢ ∀ (n : ℕ), get nats n = get (0 :: map succ nats) n

Next tactic:
intro n
theorem nats_eq : nats = cons 0 (map succ nats) := by
  apply Stream'.ext; intro n
  

Proof state:
case a
α : Type u
β : Type v
δ : Type w
n : ℕ
⊢ get nats n = get (0 :: map succ nats) n

Next tactic:
cases n
theorem nats_eq : nats = cons 0 (map succ nats) := by
  apply Stream'.ext; intro n
  cases n; 

Proof state:
case a.zero
α : Type u
β : Type v
δ : Type w
⊢ get nats zero = get (0 :: map succ nats) zero
case a.succ α : Type u β : Type v δ : Type w n✝ : ℕ ⊢ get nats (succ n✝) = get (0 :: map succ nats) (succ n✝)

Next tactic:
rfl
theorem nats_eq : nats = cons 0 (map succ nats) := by
  apply Stream'.ext; intro n
  cases n; rfl; 

Proof state:
case a.succ
α : Type u
β : Type v
δ : Type w
n✝ : ℕ
⊢ get nats (succ n✝) = get (0 :: map succ nats) (succ n✝)

Next tactic:
rw [get_succ]
theorem nats_eq : nats = cons 0 (map succ nats) := by
  apply Stream'.ext; intro n
  cases n; rfl; rw [get_succ]; 

Proof state:
case a.succ
α : Type u
β : Type v
δ : Type w
n✝ : ℕ
⊢ get (tail nats) n✝ = get (0 :: map succ nats) (succ n✝)

Next tactic:
rfl
/-- The determinant of a unit matrix is itself a unit. -/
@[simps]
def det : GL n R →* Rˣ where
  toFun A :=
    { val := (↑A : Matrix n n R).det
      inv := (↑A⁻¹ : Matrix n n R).det
      val_inv := by 

Proof state:
n : Type u
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
A : GL n R
⊢ Matrix.det ↑A * Matrix.det ↑A⁻¹ = 1

Next tactic:
rw [← det_mul, A.mul_inv, det_one]
/-- The determinant of a unit matrix is itself a unit. -/
@[simps]
def det : GL n R →* Rˣ where
  toFun A :=
    { val := (↑A : Matrix n n R).det
      inv := (↑A⁻¹ : Matrix n n R).det
      val_inv := by rw [← det_mul, A.mul_inv, det_one]
      inv_val := by 

Proof state:
n : Type u
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
A : GL n R
⊢ Matrix.det ↑A⁻¹ * Matrix.det ↑A = 1

Next tactic:
rw [← det_mul, A.inv_mul, det_one]
/-- Formal operation of negation on general linear group on even cardinality `n` given by negating
each element. -/
instance : Neg (GLPos n R) :=
  ⟨fun g =>
    ⟨-g, by
      

Proof state:
n : Type u
R : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
inst✝¹ : LinearOrderedCommRing R
inst✝ : Fact (Even (Fintype.card n))
g : ↥(GLPos n R)
⊢ -↑g ∈ GLPos n R

Next tactic:
rw [mem_glpos, GeneralLinearGroup.val_det_apply, Units.val_neg, det_neg,
        (Fact.out (p := Even <| Fintype.card n)).neg_one_pow, one_mul]
/-- Formal operation of negation on general linear group on even cardinality `n` given by negating
each element. -/
instance : Neg (GLPos n R) :=
  ⟨fun g =>
    ⟨-g, by
      rw [mem_glpos, GeneralLinearGroup.val_det_apply, Units.val_neg, det_neg,
        (Fact.out (p := Even <| Fintype.card n)).neg_one_pow, one_mul]
      

Proof state:
n : Type u
R : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
inst✝¹ : LinearOrderedCommRing R
inst✝ : Fact (Even (Fintype.card n))
g : ↥(GLPos n R)
⊢ 0 < det ↑↑g

Next tactic:
exact g.prop
/-- The matrix [a, -b; b, a] (inspired by multiplication by a complex number); it is an element of
$GL_2(R)$ if `a ^ 2 + b ^ 2` is nonzero. -/
@[simps! (config := .asFn) val]
def planeConformalMatrix {R} [Field R] (a b : R) (hab : a ^ 2 + b ^ 2 ≠ 0) :
    Matrix.GeneralLinearGroup (Fin 2) R :=
  GeneralLinearGroup.mkOfDetNeZero !![a, -b; b, a] (by 

Proof state:
R : Type ?u.1637651
inst✝ : Field R
a b : R
hab : a ^ 2 + b ^ 2 ≠ 0
⊢ det (of ![![a, -b], ![b, a]]) ≠ 0

Next tactic:
simpa [det_fin_two, sq] using hab
@[simp]
theorem annIdealGenerator_eq_zero_iff {a : A} : annIdealGenerator 𝕜 a = 0 ↔ annIdeal 𝕜 a = ⊥ := by
  

Proof state:
𝕜 : Type u_1
A : Type u_2
inst✝² : Field 𝕜
inst✝¹ : Ring A
inst✝ : Algebra 𝕜 A
a : A
⊢ annIdealGenerator 𝕜 a = 0 ↔ annIdeal 𝕜 a = ⊥

Next tactic:
simp only [annIdealGenerator, mul_eq_zero, IsPrincipal.eq_bot_iff_generator_eq_zero,
    Polynomial.C_eq_zero, inv_eq_zero, Polynomial.leadingCoeff_eq_zero, or_self_iff]
/-- `annIdealGenerator 𝕜 a` is indeed a generator. -/
@[simp]
theorem span_singleton_annIdealGenerator (a : A) :
    Ideal.span {annIdealGenerator 𝕜 a} = annIdeal 𝕜 a := by
  

Proof state:
𝕜 : Type u_1
A : Type u_2
inst✝² : Field 𝕜
inst✝¹ : Ring A
inst✝ : Algebra 𝕜 A
a : A
⊢ Ideal.span {annIdealGenerator 𝕜 a} = annIdeal 𝕜 a

Next tactic:
by_cases h : annIdealGenerator 𝕜 a = 0
/-- `annIdealGenerator 𝕜 a` is indeed a generator. -/
@[simp]
theorem span_singleton_annIdealGenerator (a : A) :
    Ideal.span {annIdealGenerator 𝕜 a} = annIdeal 𝕜 a := by
  by_cases h : annIdealGenerator 𝕜 a = 0
  · 

Proof state:
case pos
𝕜 : Type u_1
A : Type u_2
inst✝² : Field 𝕜
inst✝¹ : Ring A
inst✝ : Algebra 𝕜 A
a : A
h : annIdealGenerator 𝕜 a = 0
⊢ Ideal.span {annIdealGenerator 𝕜 a} = annIdeal 𝕜 a

Next tactic:
rw [h, annIdealGenerator_eq_zero_iff.mp h, Set.singleton_zero, Ideal.span_zero]
/-- `annIdealGenerator 𝕜 a` is indeed a generator. -/
@[simp]
theorem span_singleton_annIdealGenerator (a : A) :
    Ideal.span {annIdealGenerator 𝕜 a} = annIdeal 𝕜 a := by
  by_cases h : annIdealGenerator 𝕜 a = 0
  · rw [h, annIdealGenerator_eq_zero_iff.mp h, Set.singleton_zero, Ideal.span_zero]
  · 

Proof state:
case neg
𝕜 : Type u_1
A : Type u_2
inst✝² : Field 𝕜
inst✝¹ : Ring A
inst✝ : Algebra 𝕜 A
a : A
h : ¬annIdealGenerator 𝕜 a = 0
⊢ Ideal.span {annIdealGenerator 𝕜 a} = annIdeal 𝕜 a

Next tactic:
rw [annIdealGenerator, Ideal.span_singleton_mul_right_unit, Ideal.span_singleton_generator]
/-- `annIdealGenerator 𝕜 a` is indeed a generator. -/
@[simp]
theorem span_singleton_annIdealGenerator (a : A) :
    Ideal.span {annIdealGenerator 𝕜 a} = annIdeal 𝕜 a := by
  by_cases h : annIdealGenerator 𝕜 a = 0
  · rw [h, annIdealGenerator_eq_zero_iff.mp h, Set.singleton_zero, Ideal.span_zero]
  · rw [annIdealGenerator, Ideal.span_singleton_mul_right_unit, Ideal.span_singleton_generator]
    

Proof state:
case neg.h2
𝕜 : Type u_1
A : Type u_2
inst✝² : Field 𝕜
inst✝¹ : Ring A
inst✝ : Algebra 𝕜 A
a : A
h : ¬annIdealGenerator 𝕜 a = 0
⊢ IsUnit (C (leadingCoeff (IsPrincipal.generator (annIdeal 𝕜 a)))⁻¹)

Next tactic:
apply Polynomial.isUnit_C.mpr
/-- `annIdealGenerator 𝕜 a` is indeed a generator. -/
@[simp]
theorem span_singleton_annIdealGenerator (a : A) :
    Ideal.span {annIdealGenerator 𝕜 a} = annIdeal 𝕜 a := by
  by_cases h : annIdealGenerator 𝕜 a = 0
  · rw [h, annIdealGenerator_eq_zero_iff.mp h, Set.singleton_zero, Ideal.span_zero]
  · rw [annIdealGenerator, Ideal.span_singleton_mul_right_unit, Ideal.span_singleton_generator]
    apply Polynomial.isUnit_C.mpr
    

Proof state:
case neg.h2
𝕜 : Type u_1
A : Type u_2
inst✝² : Field 𝕜
inst✝¹ : Ring A
inst✝ : Algebra 𝕜 A
a : A
h : ¬annIdealGenerator 𝕜 a = 0
⊢ IsUnit (leadingCoeff (IsPrincipal.generator (annIdeal 𝕜 a)))⁻¹

Next tactic:
apply IsUnit.mk0
/-- `annIdealGenerator 𝕜 a` is indeed a generator. -/
@[simp]
theorem span_singleton_annIdealGenerator (a : A) :
    Ideal.span {annIdealGenerator 𝕜 a} = annIdeal 𝕜 a := by
  by_cases h : annIdealGenerator 𝕜 a = 0
  · rw [h, annIdealGenerator_eq_zero_iff.mp h, Set.singleton_zero, Ideal.span_zero]
  · rw [annIdealGenerator, Ideal.span_singleton_mul_right_unit, Ideal.span_singleton_generator]
    apply Polynomial.isUnit_C.mpr
    apply IsUnit.mk0
    

Proof state:
case neg.h2.hx
𝕜 : Type u_1
A : Type u_2
inst✝² : Field 𝕜
inst✝¹ : Ring A
inst✝ : Algebra 𝕜 A
a : A
h : ¬annIdealGenerator 𝕜 a = 0
⊢ (leadingCoeff (IsPrincipal.generator (annIdeal 𝕜 a)))⁻¹ ≠ 0

Next tactic:
apply inv_eq_zero.not.mpr
/-- `annIdealGenerator 𝕜 a` is indeed a generator. -/
@[simp]
theorem span_singleton_annIdealGenerator (a : A) :
    Ideal.span {annIdealGenerator 𝕜 a} = annIdeal 𝕜 a := by
  by_cases h : annIdealGenerator 𝕜 a = 0
  · rw [h, annIdealGenerator_eq_zero_iff.mp h, Set.singleton_zero, Ideal.span_zero]
  · rw [annIdealGenerator, Ideal.span_singleton_mul_right_unit, Ideal.span_singleton_generator]
    apply Polynomial.isUnit_C.mpr
    apply IsUnit.mk0
    apply inv_eq_zero.not.mpr
    

Proof state:
case neg.h2.hx
𝕜 : Type u_1
A : Type u_2
inst✝² : Field 𝕜
inst✝¹ : Ring A
inst✝ : Algebra 𝕜 A
a : A
h : ¬annIdealGenerator 𝕜 a = 0
⊢ ¬leadingCoeff (IsPrincipal.generator (annIdeal 𝕜 a)) = 0

Next tactic:
apply Polynomial.leadingCoeff_eq_zero.not.mpr