l3lab/ntp-mathlib huggingface dataset:
/-- The diagonal elements of a complex hermitian matrix are real. -/
theorem IsHermitian.coe_re_apply_self {A : Matrix n n α} (h : A.IsHermitian) (i : n) :
    (re (A i i) : α) = A i i := by 

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
A✝ : Matrix n n α
inst✝¹ : IsROrC α
inst✝ : IsROrC β
A : Matrix n n α
h : IsHermitian A
i : n
⊢ ↑(re (A i i)) = A i i

Next tactic:
rw [← conj_eq_iff_re, ← star_def, ← conjTranspose_apply, h.eq]
/-- A matrix is hermitian iff the corresponding linear map is self adjoint. -/
theorem isHermitian_iff_isSymmetric [Fintype n] [DecidableEq n] {A : Matrix n n α} :
    IsHermitian A ↔ A.toEuclideanLin.IsSymmetric := by
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
A✝ : Matrix n n α
inst✝³ : IsROrC α
inst✝² : IsROrC β
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n α
⊢ IsHermitian A ↔ LinearMap.IsSymmetric (toEuclideanLin A)

Next tactic:
rw [LinearMap.IsSymmetric, (WithLp.equiv 2 (n → α)).symm.surjective.forall₂]
/-- A matrix is hermitian iff the corresponding linear map is self adjoint. -/
theorem isHermitian_iff_isSymmetric [Fintype n] [DecidableEq n] {A : Matrix n n α} :
    IsHermitian A ↔ A.toEuclideanLin.IsSymmetric := by
  rw [LinearMap.IsSymmetric, (WithLp.equiv 2 (n → α)).symm.surjective.forall₂]
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
A✝ : Matrix n n α
inst✝³ : IsROrC α
inst✝² : IsROrC β
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n α
⊢ IsHermitian A ↔
    ∀ (x₁ x₂ : n → α),
      inner ((toEuclideanLin A) ((WithLp.equiv 2 (n → α)).symm x₁)) ((WithLp.equiv 2 (n → α)).symm x₂) =
        inner ((WithLp.equiv 2 (n → α)).symm x₁) ((toEuclideanLin A) ((WithLp.equiv 2 (n → α)).symm x₂))

Next tactic:
simp only [toEuclideanLin_piLp_equiv_symm, EuclideanSpace.inner_piLp_equiv_symm, toLin'_apply,
    star_mulVec, dotProduct_mulVec]
/-- A matrix is hermitian iff the corresponding linear map is self adjoint. -/
theorem isHermitian_iff_isSymmetric [Fintype n] [DecidableEq n] {A : Matrix n n α} :
    IsHermitian A ↔ A.toEuclideanLin.IsSymmetric := by
  rw [LinearMap.IsSymmetric, (WithLp.equiv 2 (n → α)).symm.surjective.forall₂]
  simp only [toEuclideanLin_piLp_equiv_symm, EuclideanSpace.inner_piLp_equiv_symm, toLin'_apply,
    star_mulVec, dotProduct_mulVec]
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
A✝ : Matrix n n α
inst✝³ : IsROrC α
inst✝² : IsROrC β
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n α
⊢ IsHermitian A ↔ ∀ (x₁ x₂ : n → α), vecMul (star x₁) Aᴴ ⬝ᵥ x₂ = vecMul (star x₁) A ⬝ᵥ x₂

Next tactic:
constructor
/-- A matrix is hermitian iff the corresponding linear map is self adjoint. -/
theorem isHermitian_iff_isSymmetric [Fintype n] [DecidableEq n] {A : Matrix n n α} :
    IsHermitian A ↔ A.toEuclideanLin.IsSymmetric := by
  rw [LinearMap.IsSymmetric, (WithLp.equiv 2 (n → α)).symm.surjective.forall₂]
  simp only [toEuclideanLin_piLp_equiv_symm, EuclideanSpace.inner_piLp_equiv_symm, toLin'_apply,
    star_mulVec, dotProduct_mulVec]
  constructor
  · 

Proof state:
case mp
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
A✝ : Matrix n n α
inst✝³ : IsROrC α
inst✝² : IsROrC β
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n α
⊢ IsHermitian A → ∀ (x₁ x₂ : n → α), vecMul (star x₁) Aᴴ ⬝ᵥ x₂ = vecMul (star x₁) A ⬝ᵥ x₂

Next tactic:
rintro (h : Aᴴ = A) x y
/-- A matrix is hermitian iff the corresponding linear map is self adjoint. -/
theorem isHermitian_iff_isSymmetric [Fintype n] [DecidableEq n] {A : Matrix n n α} :
    IsHermitian A ↔ A.toEuclideanLin.IsSymmetric := by
  rw [LinearMap.IsSymmetric, (WithLp.equiv 2 (n → α)).symm.surjective.forall₂]
  simp only [toEuclideanLin_piLp_equiv_symm, EuclideanSpace.inner_piLp_equiv_symm, toLin'_apply,
    star_mulVec, dotProduct_mulVec]
  constructor
  · rintro (h : Aᴴ = A) x y
    

Proof state:
case mp
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
A✝ : Matrix n n α
inst✝³ : IsROrC α
inst✝² : IsROrC β
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n α
h : Aᴴ = A
x y : n → α
⊢ vecMul (star x) Aᴴ ⬝ᵥ y = vecMul (star x) A ⬝ᵥ y

Next tactic:
rw [h]
/-- A matrix is hermitian iff the corresponding linear map is self adjoint. -/
theorem isHermitian_iff_isSymmetric [Fintype n] [DecidableEq n] {A : Matrix n n α} :
    IsHermitian A ↔ A.toEuclideanLin.IsSymmetric := by
  rw [LinearMap.IsSymmetric, (WithLp.equiv 2 (n → α)).symm.surjective.forall₂]
  simp only [toEuclideanLin_piLp_equiv_symm, EuclideanSpace.inner_piLp_equiv_symm, toLin'_apply,
    star_mulVec, dotProduct_mulVec]
  constructor
  · rintro (h : Aᴴ = A) x y
    rw [h]
  · 

Proof state:
case mpr
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
A✝ : Matrix n n α
inst✝³ : IsROrC α
inst✝² : IsROrC β
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n α
⊢ (∀ (x₁ x₂ : n → α), vecMul (star x₁) Aᴴ ⬝ᵥ x₂ = vecMul (star x₁) A ⬝ᵥ x₂) → IsHermitian A

Next tactic:
intro h
/-- A matrix is hermitian iff the corresponding linear map is self adjoint. -/
theorem isHermitian_iff_isSymmetric [Fintype n] [DecidableEq n] {A : Matrix n n α} :
    IsHermitian A ↔ A.toEuclideanLin.IsSymmetric := by
  rw [LinearMap.IsSymmetric, (WithLp.equiv 2 (n → α)).symm.surjective.forall₂]
  simp only [toEuclideanLin_piLp_equiv_symm, EuclideanSpace.inner_piLp_equiv_symm, toLin'_apply,
    star_mulVec, dotProduct_mulVec]
  constructor
  · rintro (h : Aᴴ = A) x y
    rw [h]
  · intro h
    

Proof state:
case mpr
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
A✝ : Matrix n n α
inst✝³ : IsROrC α
inst✝² : IsROrC β
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n α
h : ∀ (x₁ x₂ : n → α), vecMul (star x₁) Aᴴ ⬝ᵥ x₂ = vecMul (star x₁) A ⬝ᵥ x₂
⊢ IsHermitian A

Next tactic:
ext i j
/-- A matrix is hermitian iff the corresponding linear map is self adjoint. -/
theorem isHermitian_iff_isSymmetric [Fintype n] [DecidableEq n] {A : Matrix n n α} :
    IsHermitian A ↔ A.toEuclideanLin.IsSymmetric := by
  rw [LinearMap.IsSymmetric, (WithLp.equiv 2 (n → α)).symm.surjective.forall₂]
  simp only [toEuclideanLin_piLp_equiv_symm, EuclideanSpace.inner_piLp_equiv_symm, toLin'_apply,
    star_mulVec, dotProduct_mulVec]
  constructor
  · rintro (h : Aᴴ = A) x y
    rw [h]
  · intro h
    ext i j
    

Proof state:
case mpr.a.h
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
A✝ : Matrix n n α
inst✝³ : IsROrC α
inst✝² : IsROrC β
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n α
h : ∀ (x₁ x₂ : n → α), vecMul (star x₁) Aᴴ ⬝ᵥ x₂ = vecMul (star x₁) A ⬝ᵥ x₂
i j : n
⊢ Aᴴ i j = A i j

Next tactic:
simpa only [(Pi.single_star i 1).symm, ← star_mulVec, mul_one, dotProduct_single,
      single_vecMul, star_one, one_mul] using h (Pi.single i 1) (Pi.single j 1)
theorem nonempty_embedding_to_cardinal : Nonempty (σ ↪ Cardinal.{u}) :=
  (Embedding.total _ _).resolve_left fun ⟨⟨f, hf⟩⟩ =>
    let g : σ → Cardinal.{u} := invFun f
    let ⟨x, (hx : g x = 2 ^ sum g)⟩ := invFun_surjective hf (2 ^ sum g)
    have : g x ≤ sum g := le_sum.{u, u} g x
    not_le_of_gt (by 

Proof state:
α : Type u
β : Type u_1
γ : Type u_2
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
σ : Type u
x✝ : Nonempty (Cardinal.{u} ↪ σ)
f : Cardinal.{u} → σ
hf : Injective f
g : σ → Cardinal.{u} := invFun f
x : σ
hx : g x = 2 ^ sum g
this : g x ≤ sum g
⊢ g x > sum g

Next tactic:
rw [hx]
theorem nonempty_embedding_to_cardinal : Nonempty (σ ↪ Cardinal.{u}) :=
  (Embedding.total _ _).resolve_left fun ⟨⟨f, hf⟩⟩ =>
    let g : σ → Cardinal.{u} := invFun f
    let ⟨x, (hx : g x = 2 ^ sum g)⟩ := invFun_surjective hf (2 ^ sum g)
    have : g x ≤ sum g := le_sum.{u, u} g x
    not_le_of_gt (by rw [hx]; 

Proof state:
α : Type u
β : Type u_1
γ : Type u_2
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
σ : Type u
x✝ : Nonempty (Cardinal.{u} ↪ σ)
f : Cardinal.{u} → σ
hf : Injective f
g : σ → Cardinal.{u} := invFun f
x : σ
hx : g x = 2 ^ sum g
this : g x ≤ sum g
⊢ 2 ^ sum g > sum g

Next tactic:
exact cantor _
@[simp]
theorem eta (o : WellOrder) : mk o.α o.r o.wo = o := by
  

Proof state:
α : Type u
β : Type u_1
γ : Type u_2
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
o : WellOrder
⊢ { α := o.α, r := o.r, wo := (_ : IsWellOrder o.α o.r) } = o

Next tactic:
cases o
@[simp]
theorem eta (o : WellOrder) : mk o.α o.r o.wo = o := by
  cases o
  

Proof state:
case mk
α : Type u
β : Type u_1
γ : Type u_2
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
α✝ : Type u_3
r✝ : α✝ → α✝ → Prop
wo✝ : IsWellOrder α✝ r✝
⊢ { α := { α := α✝, r := r✝, wo := wo✝ }.α, r := { α := α✝, r := r✝, wo := wo✝ }.r,
      wo := (_ : IsWellOrder { α := α✝, r := r✝, wo := wo✝ }.α { α := α✝, r := r✝, wo := wo✝ }.r) } =
    { α := α✝, r := r✝, wo := wo✝ }

Next tactic:
rfl
@[simp]
theorem type_def' (w : WellOrder) : ⟦w⟧ = type w.r := by
  

Proof state:
α : Type u
β : Type u_1
γ : Type u_2
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
w : WellOrder
⊢ ⟦w⟧ = type w.r

Next tactic:
cases w
@[simp]
theorem type_def' (w : WellOrder) : ⟦w⟧ = type w.r := by
  cases w
  

Proof state:
case mk
α : Type u
β : Type u_1
γ : Type u_2
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
α✝ : Type u_3
r✝ : α✝ → α✝ → Prop
wo✝ : IsWellOrder α✝ r✝
⊢ ⟦{ α := α✝, r := r✝, wo := wo✝ }⟧ = type { α := α✝, r := r✝, wo := wo✝ }.r

Next tactic:
rfl
@[simp, nolint simpNF] -- Porting note: dsimp can not prove this
theorem type_def (r) [wo : IsWellOrder α r] : (⟦⟨α, r, wo⟩⟧ : Ordinal) = type r := by
  

Proof state:
α : Type u
β : Type u_1
γ : Type u_2
r✝ : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
r : α → α → Prop
wo : IsWellOrder α r
⊢ ⟦{ α := α, r := r, wo := wo }⟧ = type r

Next tactic:
rfl
@[simp]
theorem type_out (o : Ordinal) : Ordinal.type o.out.r = o := by
  

Proof state:
α : Type u
β : Type u_1
γ : Type u_2
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
o : Ordinal.{u_3}
⊢ type (Quotient.out o).r = o

Next tactic:
rw [Ordinal.type, WellOrder.eta, Quotient.out_eq]
theorem type_ne_zero_iff_nonempty [IsWellOrder α r] : type r ≠ 0 ↔ Nonempty α := by 

Proof state:
α : Type u
β : Type u_1
γ : Type u_2
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
inst✝ : IsWellOrder α r
⊢ type r ≠ 0 ↔ Nonempty α

Next tactic:
simp
@[simp]
theorem out_empty_iff_eq_zero {o : Ordinal} : IsEmpty o.out.α ↔ o = 0 := by
  

Proof state:
α : Type u
β : Type u_1
γ : Type u_2
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
o : Ordinal.{u_3}
⊢ IsEmpty (Quotient.out o).α ↔ o = 0

Next tactic:
rw [← @type_eq_zero_iff_isEmpty o.out.α (· < ·), type_lt]
@[simp]
theorem out_nonempty_iff_ne_zero {o : Ordinal} : Nonempty o.out.α ↔ o ≠ 0 := by
  

Proof state:
α : Type u
β : Type u_1
γ : Type u_2
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
o : Ordinal.{u_3}
⊢ Nonempty (Quotient.out o).α ↔ o ≠ 0

Next tactic:
rw [← @type_ne_zero_iff_nonempty o.out.α (· < ·), type_lt]
@[simp, nolint simpNF] -- `simpNF` incorrectly complains the LHS doesn't simplify.
theorem type_preimage_aux {α β : Type u} (r : α → α → Prop) [IsWellOrder α r] (f : β ≃ α) :
    @type _ (fun x y => r (f x) (f y)) (inferInstanceAs (IsWellOrder β (↑f ⁻¹'o r))) = type r := by
  

Proof state:
α✝ : Type u
β✝ : Type u_1
γ : Type u_2
r✝ : α✝ → α✝ → Prop
s : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Type u
r : α → α → Prop
inst✝ : IsWellOrder α r
f : β ≃ α
⊢ (type fun x y => r (f x) (f y)) = type r

Next tactic:
convert (RelIso.preimage f r).ordinal_type_eq
/-- Given two ordinals `α ≤ β`, then `initialSegOut α β` is the initial segment embedding
of `α` to `β`, as map from a model type for `α` to a model type for `β`. -/
def initialSegOut {α β : Ordinal} (h : α ≤ β) :
    InitialSeg ((· < ·) : α.out.α → α.out.α → Prop) ((· < ·) : β.out.α → β.out.α → Prop) := by
  

Proof state:
α✝ : Type u
β✝ : Type u_1
γ : Type u_2
r : α✝ → α✝ → Prop
s : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Ordinal.{?u.59276}
h : α ≤ β
⊢ (fun x x_1 => x < x_1) ≼i fun x x_1 => x < x_1

Next tactic:
change α.out.r ≼i β.out.r
/-- Given two ordinals `α ≤ β`, then `initialSegOut α β` is the initial segment embedding
of `α` to `β`, as map from a model type for `α` to a model type for `β`. -/
def initialSegOut {α β : Ordinal} (h : α ≤ β) :
    InitialSeg ((· < ·) : α.out.α → α.out.α → Prop) ((· < ·) : β.out.α → β.out.α → Prop) := by
  change α.out.r ≼i β.out.r
  

Proof state:
α✝ : Type u
β✝ : Type u_1
γ : Type u_2
r : α✝ → α✝ → Prop
s : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Ordinal.{?u.59783}
h : α ≤ β
⊢ (Quotient.out α).r ≼i (Quotient.out β).r

Next tactic:
rw [← Quotient.out_eq α, ← Quotient.out_eq β] at h
/-- Given two ordinals `α ≤ β`, then `initialSegOut α β` is the initial segment embedding
of `α` to `β`, as map from a model type for `α` to a model type for `β`. -/
def initialSegOut {α β : Ordinal} (h : α ≤ β) :
    InitialSeg ((· < ·) : α.out.α → α.out.α → Prop) ((· < ·) : β.out.α → β.out.α → Prop) := by
  change α.out.r ≼i β.out.r
  rw [← Quotient.out_eq α, ← Quotient.out_eq β] at h; 

Proof state:
α✝ : Type u
β✝ : Type u_1
γ : Type u_2
r : α✝ → α✝ → Prop
s : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Ordinal.{?u.59783}
h : ⟦Quotient.out α⟧ ≤ ⟦Quotient.out β⟧
⊢ (Quotient.out α).r ≼i (Quotient.out β).r

Next tactic:
revert h
/-- Given two ordinals `α ≤ β`, then `initialSegOut α β` is the initial segment embedding
of `α` to `β`, as map from a model type for `α` to a model type for `β`. -/
def initialSegOut {α β : Ordinal} (h : α ≤ β) :
    InitialSeg ((· < ·) : α.out.α → α.out.α → Prop) ((· < ·) : β.out.α → β.out.α → Prop) := by
  change α.out.r ≼i β.out.r
  rw [← Quotient.out_eq α, ← Quotient.out_eq β] at h; revert h
  

Proof state:
α✝ : Type u
β✝ : Type u_1
γ : Type u_2
r : α✝ → α✝ → Prop
s : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Ordinal.{?u.59783}
⊢ ⟦Quotient.out α⟧ ≤ ⟦Quotient.out β⟧ → (Quotient.out α).r ≼i (Quotient.out β).r

Next tactic:
cases Quotient.out α
/-- Given two ordinals `α ≤ β`, then `initialSegOut α β` is the initial segment embedding
of `α` to `β`, as map from a model type for `α` to a model type for `β`. -/
def initialSegOut {α β : Ordinal} (h : α ≤ β) :
    InitialSeg ((· < ·) : α.out.α → α.out.α → Prop) ((· < ·) : β.out.α → β.out.α → Prop) := by
  change α.out.r ≼i β.out.r
  rw [← Quotient.out_eq α, ← Quotient.out_eq β] at h; revert h
  cases Quotient.out α; 

Proof state:
case mk
α✝¹ : Type u
β✝ : Type u_1
γ : Type u_2
r : α✝¹ → α✝¹ → Prop
s : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Ordinal.{?u.59939}
α✝ : Type ?u.59939
r✝ : α✝ → α✝ → Prop
wo✝ : IsWellOrder α✝ r✝
⊢ ⟦{ α := α✝, r := r✝, wo := wo✝ }⟧ ≤ ⟦Quotient.out β⟧ → { α := α✝, r := r✝, wo := wo✝ }.r ≼i (Quotient.out β).r

Next tactic:
cases Quotient.out β
/-- Given two ordinals `α ≤ β`, then `initialSegOut α β` is the initial segment embedding
of `α` to `β`, as map from a model type for `α` to a model type for `β`. -/
def initialSegOut {α β : Ordinal} (h : α ≤ β) :
    InitialSeg ((· < ·) : α.out.α → α.out.α → Prop) ((· < ·) : β.out.α → β.out.α → Prop) := by
  change α.out.r ≼i β.out.r
  rw [← Quotient.out_eq α, ← Quotient.out_eq β] at h; revert h
  cases Quotient.out α; cases Quotient.out β; 

Proof state:
case mk.mk
α✝² : Type u
β✝ : Type u_1
γ : Type u_2
r : α✝² → α✝² → Prop
s : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Ordinal.{?u.59997}
α✝¹ : Type ?u.59997
r✝¹ : α✝¹ → α✝¹ → Prop
wo✝¹ : IsWellOrder α✝¹ r✝¹
α✝ : Type ?u.59997
r✝ : α✝ → α✝ → Prop
wo✝ : IsWellOrder α✝ r✝
⊢ ⟦{ α := α✝¹, r := r✝¹, wo := wo✝¹ }⟧ ≤ ⟦{ α := α✝, r := r✝, wo := wo✝ }⟧ →
    { α := α✝¹, r := r✝¹, wo := wo✝¹ }.r ≼i { α := α✝, r := r✝, wo := wo✝ }.r

Next tactic:
exact Classical.choice
/-- Given two ordinals `α < β`, then `principalSegOut α β` is the principal segment embedding
of `α` to `β`, as map from a model type for `α` to a model type for `β`. -/
def principalSegOut {α β : Ordinal} (h : α < β) :
    PrincipalSeg ((· < ·) : α.out.α → α.out.α → Prop) ((· < ·) : β.out.α → β.out.α → Prop) := by
  

Proof state:
α✝ : Type u
β✝ : Type u_1
γ : Type u_2
r : α✝ → α✝ → Prop
s : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Ordinal.{?u.60968}
h : α < β
⊢ (fun x x_1 => x < x_1) ≺i fun x x_1 => x < x_1

Next tactic:
change α.out.r ≺i β.out.r
/-- Given two ordinals `α < β`, then `principalSegOut α β` is the principal segment embedding
of `α` to `β`, as map from a model type for `α` to a model type for `β`. -/
def principalSegOut {α β : Ordinal} (h : α < β) :
    PrincipalSeg ((· < ·) : α.out.α → α.out.α → Prop) ((· < ·) : β.out.α → β.out.α → Prop) := by
  change α.out.r ≺i β.out.r
  

Proof state:
α✝ : Type u
β✝ : Type u_1
γ : Type u_2
r : α✝ → α✝ → Prop
s : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Ordinal.{?u.61475}
h : α < β
⊢ (Quotient.out α).r ≺i (Quotient.out β).r

Next tactic:
rw [← Quotient.out_eq α, ← Quotient.out_eq β] at h
/-- Given two ordinals `α < β`, then `principalSegOut α β` is the principal segment embedding
of `α` to `β`, as map from a model type for `α` to a model type for `β`. -/
def principalSegOut {α β : Ordinal} (h : α < β) :
    PrincipalSeg ((· < ·) : α.out.α → α.out.α → Prop) ((· < ·) : β.out.α → β.out.α → Prop) := by
  change α.out.r ≺i β.out.r
  rw [← Quotient.out_eq α, ← Quotient.out_eq β] at h; 

Proof state:
α✝ : Type u
β✝ : Type u_1
γ : Type u_2
r : α✝ → α✝ → Prop
s : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Ordinal.{?u.61475}
h : ⟦Quotient.out α⟧ < ⟦Quotient.out β⟧
⊢ (Quotient.out α).r ≺i (Quotient.out β).r

Next tactic:
revert h
/-- Given two ordinals `α < β`, then `principalSegOut α β` is the principal segment embedding
of `α` to `β`, as map from a model type for `α` to a model type for `β`. -/
def principalSegOut {α β : Ordinal} (h : α < β) :
    PrincipalSeg ((· < ·) : α.out.α → α.out.α → Prop) ((· < ·) : β.out.α → β.out.α → Prop) := by
  change α.out.r ≺i β.out.r
  rw [← Quotient.out_eq α, ← Quotient.out_eq β] at h; revert h
  

Proof state:
α✝ : Type u
β✝ : Type u_1
γ : Type u_2
r : α✝ → α✝ → Prop
s : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Ordinal.{?u.61475}
⊢ ⟦Quotient.out α⟧ < ⟦Quotient.out β⟧ → (Quotient.out α).r ≺i (Quotient.out β).r

Next tactic:
cases Quotient.out α
/-- Given two ordinals `α < β`, then `principalSegOut α β` is the principal segment embedding
of `α` to `β`, as map from a model type for `α` to a model type for `β`. -/
def principalSegOut {α β : Ordinal} (h : α < β) :
    PrincipalSeg ((· < ·) : α.out.α → α.out.α → Prop) ((· < ·) : β.out.α → β.out.α → Prop) := by
  change α.out.r ≺i β.out.r
  rw [← Quotient.out_eq α, ← Quotient.out_eq β] at h; revert h
  cases Quotient.out α; 

Proof state:
case mk
α✝¹ : Type u
β✝ : Type u_1
γ : Type u_2
r : α✝¹ → α✝¹ → Prop
s : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Ordinal.{?u.61611}
α✝ : Type ?u.61611
r✝ : α✝ → α✝ → Prop
wo✝ : IsWellOrder α✝ r✝
⊢ ⟦{ α := α✝, r := r✝, wo := wo✝ }⟧ < ⟦Quotient.out β⟧ → { α := α✝, r := r✝, wo := wo✝ }.r ≺i (Quotient.out β).r

Next tactic:
cases Quotient.out β
/-- Given two ordinals `α < β`, then `principalSegOut α β` is the principal segment embedding
of `α` to `β`, as map from a model type for `α` to a model type for `β`. -/
def principalSegOut {α β : Ordinal} (h : α < β) :
    PrincipalSeg ((· < ·) : α.out.α → α.out.α → Prop) ((· < ·) : β.out.α → β.out.α → Prop) := by
  change α.out.r ≺i β.out.r
  rw [← Quotient.out_eq α, ← Quotient.out_eq β] at h; revert h
  cases Quotient.out α; cases Quotient.out β; 

Proof state:
case mk.mk
α✝² : Type u
β✝ : Type u_1
γ : Type u_2
r : α✝² → α✝² → Prop
s : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Ordinal.{?u.61669}
α✝¹ : Type ?u.61669
r✝¹ : α✝¹ → α✝¹ → Prop
wo✝¹ : IsWellOrder α✝¹ r✝¹
α✝ : Type ?u.61669
r✝ : α✝ → α✝ → Prop
wo✝ : IsWellOrder α✝ r✝
⊢ ⟦{ α := α✝¹, r := r✝¹, wo := wo✝¹ }⟧ < ⟦{ α := α✝, r := r✝, wo := wo✝ }⟧ →
    { α := α✝¹, r := r✝¹, wo := wo✝¹ }.r ≺i { α := α✝, r := r✝, wo := wo✝ }.r

Next tactic:
exact Classical.choice
theorem typein_lt_self {o : Ordinal} (i : o.out.α) :
    @typein _ (· < ·) (isWellOrder_out_lt _) i < o := by
  

Proof state:
α : Type u
β : Type u_1
γ : Type u_2
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
o : Ordinal.{u_3}
i : (Quotient.out o).α
⊢ typein (fun x x_1 => x < x_1) i < o

Next tactic:
simp_rw [← type_lt o]
theorem typein_lt_self {o : Ordinal} (i : o.out.α) :
    @typein _ (· < ·) (isWellOrder_out_lt _) i < o := by
  simp_rw [← type_lt o]
  

Proof state:
α : Type u
β : Type u_1
γ : Type u_2
r : α → α → Prop
s : β → β → Prop
t : γ → γ → Prop
o : Ordinal.{u_3}
i : (Quotient.out o).α
⊢ typein (fun x x_1 => x < x_1) i < type fun x x_1 => x < x_1

Next tactic:
apply typein_lt_type
@[simp]
theorem typein_top {α β} {r : α → α → Prop} {s : β → β → Prop} [IsWellOrder α r] [IsWellOrder β s]
    (f : r ≺i s) : typein s f.top = type r :=
  Eq.symm <|
    Quot.sound
      ⟨RelIso.ofSurjective (RelEmbedding.codRestrict _ f f.lt_top) fun ⟨a, h⟩ => by
          

Proof state:
α✝ : Type u
β✝ : Type u_1
γ : Type u_2
r✝ : α✝ → α✝ → Prop
s✝ : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Type u_3
r : α → α → Prop
s : β → β → Prop
inst✝¹ : IsWellOrder α r
inst✝ : IsWellOrder β s
f : r ≺i s
x✝ : ↑{b | s b f.top}
a : β
h : a ∈ {b | s b f.top}
⊢ ∃ a_1,
    (RelEmbedding.codRestrict {b | s b f.top}
          { toRelEmbedding := f.toRelEmbedding,
              init' :=
                (_ : ∀ (x : α) (x_1 : β), s x_1 (f.toRelEmbedding x) → ∃ a', f.toRelEmbedding a' = x_1) }.toRelEmbedding
          (_ : ∀ (a : α), s (f.toRelEmbedding a) f.top))
        a_1 =
      { val := a, property := h }

Next tactic:
rcases f.down.1 h with ⟨b, rfl⟩
@[simp]
theorem typein_top {α β} {r : α → α → Prop} {s : β → β → Prop} [IsWellOrder α r] [IsWellOrder β s]
    (f : r ≺i s) : typein s f.top = type r :=
  Eq.symm <|
    Quot.sound
      ⟨RelIso.ofSurjective (RelEmbedding.codRestrict _ f f.lt_top) fun ⟨a, h⟩ => by
          rcases f.down.1 h with ⟨b, rfl⟩; 

Proof state:
case intro
α✝ : Type u
β✝ : Type u_1
γ : Type u_2
r✝ : α✝ → α✝ → Prop
s✝ : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Type u_3
r : α → α → Prop
s : β → β → Prop
inst✝¹ : IsWellOrder α r
inst✝ : IsWellOrder β s
f : r ≺i s
x✝ : ↑{b | s b f.top}
b : α
h : f.toRelEmbedding b ∈ {b | s b f.top}
⊢ ∃ a,
    (RelEmbedding.codRestrict {b | s b f.top}
          { toRelEmbedding := f.toRelEmbedding,
              init' :=
                (_ : ∀ (x : α) (x_1 : β), s x_1 (f.toRelEmbedding x) → ∃ a', f.toRelEmbedding a' = x_1) }.toRelEmbedding
          (_ : ∀ (a : α), s (f.toRelEmbedding a) f.top))
        a =
      { val := f.toRelEmbedding b, property := h }

Next tactic:
exact ⟨b, rfl⟩
@[simp]
theorem typein_apply {α β} {r : α → α → Prop} {s : β → β → Prop} [IsWellOrder α r] [IsWellOrder β s]
    (f : r ≼i s) (a : α) : Ordinal.typein s (f a) = Ordinal.typein r a :=
  Eq.symm <|
    Quotient.sound
      ⟨RelIso.ofSurjective
        (RelEmbedding.codRestrict _ ((Subrel.relEmbedding _ _).trans f) fun ⟨x, h⟩ => by
          

Proof state:
α✝ : Type u
β✝ : Type u_1
γ : Type u_2
r✝ : α✝ → α✝ → Prop
s✝ : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Type u_3
r : α → α → Prop
s : β → β → Prop
inst✝¹ : IsWellOrder α r
inst✝ : IsWellOrder β s
f : r ≼i s
a : α
x✝ : ↑{b | r b a}
x : α
h : x ∈ {b | r b a}
⊢ (RelEmbedding.trans (Subrel.relEmbedding r {b | r b a}) f.toRelEmbedding) { val := x, property := h } ∈
    {b | s b (f a)}

Next tactic:
rw [RelEmbedding.trans_apply]
@[simp]
theorem typein_apply {α β} {r : α → α → Prop} {s : β → β → Prop} [IsWellOrder α r] [IsWellOrder β s]
    (f : r ≼i s) (a : α) : Ordinal.typein s (f a) = Ordinal.typein r a :=
  Eq.symm <|
    Quotient.sound
      ⟨RelIso.ofSurjective
        (RelEmbedding.codRestrict _ ((Subrel.relEmbedding _ _).trans f) fun ⟨x, h⟩ => by
          rw [RelEmbedding.trans_apply]; 

Proof state:
α✝ : Type u
β✝ : Type u_1
γ : Type u_2
r✝ : α✝ → α✝ → Prop
s✝ : β✝ → β✝ → Prop
t : γ → γ → Prop
α β : Type u_3
r : α → α → Prop
s : β → β → Prop
inst✝¹ : IsWellOrder α r
inst✝ : IsWellOrder β s
f : r ≼i s
a : α
x✝ : ↑{b | r b a}
x : α
h : x ∈ {b | r b a}
⊢ f.toRelEmbedding ((Subrel.relEmbedding r {b | r b a}) { val := x, property := h }) ∈ {b | s b (f a)}

Next tactic:
exact f.toRelEmbedding.map_rel_iff.2 h