l3lab/ntp-mathlib huggingface dataset:
/-- The bijection between the (normalized) prime factors of `r` and the (normalized) prime factors
    of `span {r}` -/
-- @[simps] -- Porting note: simpNF complains about the lemmas generated by simps
noncomputable def normalizedFactorsEquivSpanNormalizedFactors {r : R} (hr : r ≠ 0) :
    { d : R | d ∈ normalizedFactors r } ≃
      { I : Ideal R | I ∈ normalizedFactors (Ideal.span ({r} : Set R)) } := by
  refine Equiv.ofBijective ?_ ?_
  · exact fun d =>
      ⟨Ideal.span {↑d}, singleton_span_mem_normalizedFactors_of_mem_normalizedFactors d.prop⟩
  · refine ⟨?_, ?_⟩
    · rintro ⟨a, ha⟩ ⟨b, hb⟩ h
      rw [Subtype.mk_eq_mk, Ideal.span_singleton_eq_span_singleton, Subtype.coe_mk,
          Subtype.coe_mk] at h
      exact Subtype.mk_eq_mk.mpr (mem_normalizedFactors_eq_of_associated ha hb h)
    · rintro ⟨i, hi⟩
      have : i.IsPrime := isPrime_of_prime (prime_of_normalized_factor i hi)
      have := exists_mem_normalizedFactors_of_dvd hr
        (Submodule.IsPrincipal.prime_generator_of_isPrime i
        (prime_of_normalized_factor i hi).ne_zero).irreducible ?_
      · obtain ⟨a, ha, ha'⟩ := this
        use ⟨a, ha⟩
        simp only [Subtype.coe_mk, Subtype.mk_eq_mk, ← span_singleton_eq_span_singleton.mpr ha',
            Ideal.span_singleton_generator]
      · 

Proof state:
case refine_2.refine_2.mk.refine_1
R : Type u_1
A : Type u_2
K : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : CommRing A
inst✝⁶ : Field K
inst✝⁵ : IsDomain A
inst✝⁴ : IsDomain R
inst✝³ : IsPrincipalIdealRing R
inst✝² : DecidableEq R
inst✝¹ : DecidableEq (Ideal R)
inst✝ : NormalizationMonoid R
r : R
hr : r ≠ 0
i : Ideal R
hi : i ∈ {I | I ∈ normalizedFactors (span {r})}
this : IsPrime i
⊢ Submodule.IsPrincipal.generator i ∣ r

Next tactic:
exact (Submodule.IsPrincipal.mem_iff_generator_dvd i).mp
          ((show Ideal.span {r} ≤ i from dvd_iff_le.mp (dvd_of_mem_normalizedFactors hi))
            (mem_span_singleton.mpr (dvd_refl r)))
/-- The bijection `normalizedFactorsEquivSpanNormalizedFactors` between the set of prime
    factors of `r` and the set of prime factors of the ideal `⟨r⟩` preserves multiplicities. -/
theorem multiplicity_normalizedFactorsEquivSpanNormalizedFactors_eq_multiplicity {r d : R}
    (hr : r ≠ 0) (hd : d ∈ normalizedFactors r) :
    multiplicity d r =
      multiplicity (normalizedFactorsEquivSpanNormalizedFactors hr ⟨d, hd⟩ : Ideal R)
        (Ideal.span {r}) := by
  

Proof state:
R : Type u_1
A : Type u_2
K : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : CommRing A
inst✝⁸ : Field K
inst✝⁷ : IsDomain A
inst✝⁶ : IsDomain R
inst✝⁵ : IsPrincipalIdealRing R
inst✝⁴ : DecidableEq R
inst✝³ : DecidableEq (Ideal R)
inst✝² : NormalizationMonoid R
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
r d : R
hr : r ≠ 0
hd : d ∈ normalizedFactors r
⊢ multiplicity d r =
    multiplicity (↑((normalizedFactorsEquivSpanNormalizedFactors hr) { val := d, property := hd })) (span {r})

Next tactic:
simp only [normalizedFactorsEquivSpanNormalizedFactors, multiplicity_eq_multiplicity_span,
    Subtype.coe_mk, Equiv.ofBijective_apply]
/-- The bijection `normalized_factors_equiv_span_normalized_factors.symm` between the set of prime
    factors of the ideal `⟨r⟩` and the set of prime factors of `r` preserves multiplicities. -/
theorem multiplicity_normalizedFactorsEquivSpanNormalizedFactors_symm_eq_multiplicity {r : R}
    (hr : r ≠ 0) (I : { I : Ideal R | I ∈ normalizedFactors (Ideal.span ({r} : Set R)) }) :
    multiplicity ((normalizedFactorsEquivSpanNormalizedFactors hr).symm I : R) r =
      multiplicity (I : Ideal R) (Ideal.span {r}) := by
  

Proof state:
R : Type u_1
A : Type u_2
K : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : CommRing A
inst✝⁸ : Field K
inst✝⁷ : IsDomain A
inst✝⁶ : IsDomain R
inst✝⁵ : IsPrincipalIdealRing R
inst✝⁴ : DecidableEq R
inst✝³ : DecidableEq (Ideal R)
inst✝² : NormalizationMonoid R
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
r : R
hr : r ≠ 0
I : ↑{I | I ∈ normalizedFactors (span {r})}
⊢ multiplicity (↑((normalizedFactorsEquivSpanNormalizedFactors hr).symm I)) r = multiplicity (↑I) (span {r})

Next tactic:
obtain ⟨x, hx⟩ := (normalizedFactorsEquivSpanNormalizedFactors hr).surjective I
/-- The bijection `normalized_factors_equiv_span_normalized_factors.symm` between the set of prime
    factors of the ideal `⟨r⟩` and the set of prime factors of `r` preserves multiplicities. -/
theorem multiplicity_normalizedFactorsEquivSpanNormalizedFactors_symm_eq_multiplicity {r : R}
    (hr : r ≠ 0) (I : { I : Ideal R | I ∈ normalizedFactors (Ideal.span ({r} : Set R)) }) :
    multiplicity ((normalizedFactorsEquivSpanNormalizedFactors hr).symm I : R) r =
      multiplicity (I : Ideal R) (Ideal.span {r}) := by
  obtain ⟨x, hx⟩ := (normalizedFactorsEquivSpanNormalizedFactors hr).surjective I
  

Proof state:
case intro
R : Type u_1
A : Type u_2
K : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : CommRing A
inst✝⁸ : Field K
inst✝⁷ : IsDomain A
inst✝⁶ : IsDomain R
inst✝⁵ : IsPrincipalIdealRing R
inst✝⁴ : DecidableEq R
inst✝³ : DecidableEq (Ideal R)
inst✝² : NormalizationMonoid R
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
r : R
hr : r ≠ 0
I : ↑{I | I ∈ normalizedFactors (span {r})}
x : ↑{d | d ∈ normalizedFactors r}
hx : (normalizedFactorsEquivSpanNormalizedFactors hr) x = I
⊢ multiplicity (↑((normalizedFactorsEquivSpanNormalizedFactors hr).symm I)) r = multiplicity (↑I) (span {r})

Next tactic:
obtain ⟨a, ha⟩ := x
/-- The bijection `normalized_factors_equiv_span_normalized_factors.symm` between the set of prime
    factors of the ideal `⟨r⟩` and the set of prime factors of `r` preserves multiplicities. -/
theorem multiplicity_normalizedFactorsEquivSpanNormalizedFactors_symm_eq_multiplicity {r : R}
    (hr : r ≠ 0) (I : { I : Ideal R | I ∈ normalizedFactors (Ideal.span ({r} : Set R)) }) :
    multiplicity ((normalizedFactorsEquivSpanNormalizedFactors hr).symm I : R) r =
      multiplicity (I : Ideal R) (Ideal.span {r}) := by
  obtain ⟨x, hx⟩ := (normalizedFactorsEquivSpanNormalizedFactors hr).surjective I
  obtain ⟨a, ha⟩ := x
  

Proof state:
case intro.mk
R : Type u_1
A : Type u_2
K : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : CommRing A
inst✝⁸ : Field K
inst✝⁷ : IsDomain A
inst✝⁶ : IsDomain R
inst✝⁵ : IsPrincipalIdealRing R
inst✝⁴ : DecidableEq R
inst✝³ : DecidableEq (Ideal R)
inst✝² : NormalizationMonoid R
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
r : R
hr : r ≠ 0
I : ↑{I | I ∈ normalizedFactors (span {r})}
a : R
ha : a ∈ {d | d ∈ normalizedFactors r}
hx : (normalizedFactorsEquivSpanNormalizedFactors hr) { val := a, property := ha } = I
⊢ multiplicity (↑((normalizedFactorsEquivSpanNormalizedFactors hr).symm I)) r = multiplicity (↑I) (span {r})

Next tactic:
rw [hx.symm, Equiv.symm_apply_apply, Subtype.coe_mk,
    multiplicity_normalizedFactorsEquivSpanNormalizedFactors_eq_multiplicity hr ha, hx]
theorem length_set : ∀ {m : ℕ} {as : List α}, as {m ↦ a}.length = max as.length (m + 1)
  | 0, [] => rfl
  | 0, a :: as => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
as : List α
⊢ length ((a :: as) {0 ↦ a✝}) = max (length (a :: as)) (0 + 1)

Next tactic:
rw [max_eq_left]
theorem length_set : ∀ {m : ℕ} {as : List α}, as {m ↦ a}.length = max as.length (m + 1)
  | 0, [] => rfl
  | 0, a :: as => by
    rw [max_eq_left]
    · 

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
as : List α
⊢ length ((a :: as) {0 ↦ a✝}) = length (a :: as)

Next tactic:
rfl
theorem length_set : ∀ {m : ℕ} {as : List α}, as {m ↦ a}.length = max as.length (m + 1)
  | 0, [] => rfl
  | 0, a :: as => by
    rw [max_eq_left]
    · rfl
    · 

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
as : List α
⊢ 0 + 1 ≤ length (a :: as)

Next tactic:
simp [Nat.le_add_right]
theorem length_set : ∀ {m : ℕ} {as : List α}, as {m ↦ a}.length = max as.length (m + 1)
  | 0, [] => rfl
  | 0, a :: as => by
    rw [max_eq_left]
    · rfl
    · simp [Nat.le_add_right]
      

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
as : List α
⊢ 1 ≤ Nat.succ (length as)

Next tactic:
exact Nat.succ_le_succ (Nat.zero_le _)
theorem length_set : ∀ {m : ℕ} {as : List α}, as {m ↦ a}.length = max as.length (m + 1)
  | 0, [] => rfl
  | 0, a :: as => by
    rw [max_eq_left]
    · rfl
    · simp [Nat.le_add_right]
      exact Nat.succ_le_succ (Nat.zero_le _)
  | m + 1, [] => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
m : ℕ
⊢ length ([] {m + 1 ↦ a}) = max (length []) (m + 1 + 1)

Next tactic:
have := @length_set m []
theorem length_set : ∀ {m : ℕ} {as : List α}, as {m ↦ a}.length = max as.length (m + 1)
  | 0, [] => rfl
  | 0, a :: as => by
    rw [max_eq_left]
    · rfl
    · simp [Nat.le_add_right]
      exact Nat.succ_le_succ (Nat.zero_le _)
  | m + 1, [] => by
    have := @length_set m []
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
m : ℕ
this : length ([] {m ↦ a}) = max (length []) (m + 1)
⊢ length ([] {m + 1 ↦ a}) = max (length []) (m + 1 + 1)

Next tactic:
simp [set, length, @length_set m, Nat.zero_max]
theorem length_set : ∀ {m : ℕ} {as : List α}, as {m ↦ a}.length = max as.length (m + 1)
  | 0, [] => rfl
  | 0, a :: as => by
    rw [max_eq_left]
    · rfl
    · simp [Nat.le_add_right]
      exact Nat.succ_le_succ (Nat.zero_le _)
  | m + 1, [] => by
    have := @length_set m []
    simp [set, length, @length_set m, Nat.zero_max]
  | m + 1, _ :: as => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
m : ℕ
head✝ : α
as : List α
⊢ length ((head✝ :: as) {m + 1 ↦ a}) = max (length (head✝ :: as)) (m + 1 + 1)

Next tactic:
simp [set, length, @length_set m, Nat.succ_max_succ]
theorem get_nil {k : ℕ} : (get k [] : α) = default := by 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
k : ℕ
⊢ get k [] = default

Next tactic:
cases k
theorem get_nil {k : ℕ} : (get k [] : α) = default := by cases k <;> 

Proof state:
case zero
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
⊢ get Nat.zero [] = default

Next tactic:
rfl
theorem get_nil {k : ℕ} : (get k [] : α) = default := by cases k <;> 

Proof state:
case succ
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
n✝ : ℕ
⊢ get (Nat.succ n✝) [] = default

Next tactic:
rfl
theorem get_eq_default_of_le : ∀ (k : ℕ) {as : List α}, as.length ≤ k → get k as = default
  | 0, [], _ => rfl
  | 0, a :: as, h1 => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
as : List α
h1 : length (a :: as) ≤ 0
⊢ get 0 (a :: as) = default

Next tactic:
cases h1
theorem get_eq_default_of_le : ∀ (k : ℕ) {as : List α}, as.length ≤ k → get k as = default
  | 0, [], _ => rfl
  | 0, a :: as, h1 => by cases h1
  | k + 1, [], _ => rfl
  | k + 1, _ :: as, h1 => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
k : ℕ
head✝ : α
as : List α
h1 : length (head✝ :: as) ≤ k + 1
⊢ get (k + 1) (head✝ :: as) = default

Next tactic:
apply get_eq_default_of_le k
theorem get_eq_default_of_le : ∀ (k : ℕ) {as : List α}, as.length ≤ k → get k as = default
  | 0, [], _ => rfl
  | 0, a :: as, h1 => by cases h1
  | k + 1, [], _ => rfl
  | k + 1, _ :: as, h1 => by
    apply get_eq_default_of_le k
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
k : ℕ
head✝ : α
as : List α
h1 : length (head✝ :: as) ≤ k + 1
⊢ length as ≤ k

Next tactic:
rw [← Nat.succ_le_succ_iff]
theorem get_eq_default_of_le : ∀ (k : ℕ) {as : List α}, as.length ≤ k → get k as = default
  | 0, [], _ => rfl
  | 0, a :: as, h1 => by cases h1
  | k + 1, [], _ => rfl
  | k + 1, _ :: as, h1 => by
    apply get_eq_default_of_le k
    rw [← Nat.succ_le_succ_iff]; 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
k : ℕ
head✝ : α
as : List α
h1 : length (head✝ :: as) ≤ k + 1
⊢ Nat.succ (length as) ≤ Nat.succ k

Next tactic:
apply h1
@[simp]
theorem get_set {a : α} : ∀ {k : ℕ} {as : List α}, get k (as {k ↦ a}) = a
  | 0, as => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
as : List α
⊢ get 0 (as {0 ↦ a}) = a

Next tactic:
cases as
@[simp]
theorem get_set {a : α} : ∀ {k : ℕ} {as : List α}, get k (as {k ↦ a}) = a
  | 0, as => by cases as <;> 

Proof state:
case nil
α : Type u
β : Type v
γ : Type w
a✝ : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
⊢ get 0 ([] {0 ↦ a}) = a

Next tactic:
rfl
@[simp]
theorem get_set {a : α} : ∀ {k : ℕ} {as : List α}, get k (as {k ↦ a}) = a
  | 0, as => by cases as <;> 

Proof state:
case cons
α : Type u
β : Type v
γ : Type w
a✝ : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a head✝ : α
tail✝ : List α
⊢ get 0 ((head✝ :: tail✝) {0 ↦ a}) = a

Next tactic:
rfl
@[simp]
theorem get_set {a : α} : ∀ {k : ℕ} {as : List α}, get k (as {k ↦ a}) = a
  | 0, as => by cases as <;> rfl
  | k + 1, as => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
k : ℕ
as : List α
⊢ get (k + 1) (as {k + 1 ↦ a}) = a

Next tactic:
cases as
@[simp]
theorem get_set {a : α} : ∀ {k : ℕ} {as : List α}, get k (as {k ↦ a}) = a
  | 0, as => by cases as <;> rfl
  | k + 1, as => by cases as <;> 

Proof state:
case nil
α : Type u
β : Type v
γ : Type w
a✝ : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
k : ℕ
⊢ get (k + 1) ([] {k + 1 ↦ a}) = a

Next tactic:
simp [get_set]
@[simp]
theorem get_set {a : α} : ∀ {k : ℕ} {as : List α}, get k (as {k ↦ a}) = a
  | 0, as => by cases as <;> rfl
  | k + 1, as => by cases as <;> 

Proof state:
case cons
α : Type u
β : Type v
γ : Type w
a✝ : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
k : ℕ
head✝ : α
tail✝ : List α
⊢ get (k + 1) ((head✝ :: tail✝) {k + 1 ↦ a}) = a

Next tactic:
simp [get_set]
theorem eq_get_of_mem {a : α} : ∀ {as : List α}, a ∈ as → ∃ n : Nat, a = get n as
  | [], h => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
h : a ∈ []
⊢ ∃ n, a = get n []

Next tactic:
cases h
theorem eq_get_of_mem {a : α} : ∀ {as : List α}, a ∈ as → ∃ n : Nat, a = get n as
  | [], h => by cases h
  | b :: as, h => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a b : α
as : List α
h : a ∈ b :: as
⊢ ∃ n, a = get n (b :: as)

Next tactic:
rw [mem_cons] at h
theorem eq_get_of_mem {a : α} : ∀ {as : List α}, a ∈ as → ∃ n : Nat, a = get n as
  | [], h => by cases h
  | b :: as, h => by
    rw [mem_cons] at h -- porting note : `mem_cons_iff` is now named `mem_cons`
    

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a b : α
as : List α
h : a = b ∨ a ∈ as
⊢ ∃ n, a = get n (b :: as)

Next tactic:
cases h with
    | inl h => exact ⟨0, h⟩
    | inr h =>
      rcases eq_get_of_mem h with ⟨n, h⟩
      exact ⟨n + 1, h⟩
theorem eq_get_of_mem {a : α} : ∀ {as : List α}, a ∈ as → ∃ n : Nat, a = get n as
  | [], h => by cases h
  | b :: as, h => by
    rw [mem_cons] at h -- porting note : `mem_cons_iff` is now named `mem_cons`
    cases h with
    

Proof state:
case inl
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a b : α
as : List α
h : a = b
⊢ ∃ n, a = get n (b :: as)

Next tactic:
| inl h => exact ⟨0, h⟩
theorem eq_get_of_mem {a : α} : ∀ {as : List α}, a ∈ as → ∃ n : Nat, a = get n as
  | [], h => by cases h
  | b :: as, h => by
    rw [mem_cons] at h -- porting note : `mem_cons_iff` is now named `mem_cons`
    cases h with
    | inl h => 

Proof state:
case inl
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a b : α
as : List α
h : a = b
⊢ ∃ n, a = get n (b :: as)

Next tactic:
exact ⟨0, h⟩
theorem eq_get_of_mem {a : α} : ∀ {as : List α}, a ∈ as → ∃ n : Nat, a = get n as
  | [], h => by cases h
  | b :: as, h => by
    rw [mem_cons] at h -- porting note : `mem_cons_iff` is now named `mem_cons`
    cases h with
    | inl h => exact ⟨0, h⟩
    

Proof state:
case inr
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a b : α
as : List α
h : a ∈ as
⊢ ∃ n, a = get n (b :: as)

Next tactic:
| inr h =>
      rcases eq_get_of_mem h with ⟨n, h⟩
      exact ⟨n + 1, h⟩
theorem eq_get_of_mem {a : α} : ∀ {as : List α}, a ∈ as → ∃ n : Nat, a = get n as
  | [], h => by cases h
  | b :: as, h => by
    rw [mem_cons] at h -- porting note : `mem_cons_iff` is now named `mem_cons`
    cases h with
    | inl h => exact ⟨0, h⟩
    | inr h =>
      

Proof state:
case inr
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a b : α
as : List α
h : a ∈ as
⊢ ∃ n, a = get n (b :: as)

Next tactic:
rcases eq_get_of_mem h with ⟨n, h⟩
theorem eq_get_of_mem {a : α} : ∀ {as : List α}, a ∈ as → ∃ n : Nat, a = get n as
  | [], h => by cases h
  | b :: as, h => by
    rw [mem_cons] at h -- porting note : `mem_cons_iff` is now named `mem_cons`
    cases h with
    | inl h => exact ⟨0, h⟩
    | inr h =>
      rcases eq_get_of_mem h with ⟨n, h⟩
      

Proof state:
case inr.intro
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a b : α
as : List α
h✝ : a ∈ as
n : ℕ
h : a = get n as
⊢ ∃ n, a = get n (b :: as)

Next tactic:
exact ⟨n + 1, h⟩
theorem mem_get_of_le : ∀ {n : ℕ} {as : List α}, n < as.length → get n as ∈ as
  | _, [], h1 => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
x✝ : ℕ
h1 : x✝ < length []
⊢ get x✝ [] ∈ []

Next tactic:
cases h1
theorem mem_get_of_le : ∀ {n : ℕ} {as : List α}, n < as.length → get n as ∈ as
  | _, [], h1 => by cases h1
  -- porting note : needed to add to `rw [mem_cons] here` in the two cases below
  -- and in other lemmas (presumably because previously lean could see through the def of `mem` ?)
  | 0, a :: as, _ => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
as : List α
x✝ : 0 < length (a :: as)
⊢ get 0 (a :: as) ∈ a :: as

Next tactic:
rw [mem_cons]
theorem mem_get_of_le : ∀ {n : ℕ} {as : List α}, n < as.length → get n as ∈ as
  | _, [], h1 => by cases h1
  -- porting note : needed to add to `rw [mem_cons] here` in the two cases below
  -- and in other lemmas (presumably because previously lean could see through the def of `mem` ?)
  | 0, a :: as, _ => by rw [mem_cons]; 

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
as : List α
x✝ : 0 < length (a :: as)
⊢ get 0 (a :: as) = a ∨ get 0 (a :: as) ∈ as

Next tactic:
exact Or.inl rfl
theorem mem_get_of_le : ∀ {n : ℕ} {as : List α}, n < as.length → get n as ∈ as
  | _, [], h1 => by cases h1
  -- porting note : needed to add to `rw [mem_cons] here` in the two cases below
  -- and in other lemmas (presumably because previously lean could see through the def of `mem` ?)
  | 0, a :: as, _ => by rw [mem_cons]; exact Or.inl rfl
  | n + 1, a :: as, h1 => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
n : ℕ
a : α
as : List α
h1 : n + 1 < length (a :: as)
⊢ get (n + 1) (a :: as) ∈ a :: as

Next tactic:
rw [mem_cons]
theorem mem_get_of_le : ∀ {n : ℕ} {as : List α}, n < as.length → get n as ∈ as
  | _, [], h1 => by cases h1
  -- porting note : needed to add to `rw [mem_cons] here` in the two cases below
  -- and in other lemmas (presumably because previously lean could see through the def of `mem` ?)
  | 0, a :: as, _ => by rw [mem_cons]; exact Or.inl rfl
  | n + 1, a :: as, h1 => by
    rw [mem_cons]; 

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
n : ℕ
a : α
as : List α
h1 : n + 1 < length (a :: as)
⊢ get (n + 1) (a :: as) = a ∨ get (n + 1) (a :: as) ∈ as

Next tactic:
apply Or.inr
theorem mem_get_of_le : ∀ {n : ℕ} {as : List α}, n < as.length → get n as ∈ as
  | _, [], h1 => by cases h1
  -- porting note : needed to add to `rw [mem_cons] here` in the two cases below
  -- and in other lemmas (presumably because previously lean could see through the def of `mem` ?)
  | 0, a :: as, _ => by rw [mem_cons]; exact Or.inl rfl
  | n + 1, a :: as, h1 => by
    rw [mem_cons]; apply Or.inr; 

Proof state:
case h
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
n : ℕ
a : α
as : List α
h1 : n + 1 < length (a :: as)
⊢ get (n + 1) (a :: as) ∈ as

Next tactic:
unfold get
theorem mem_get_of_le : ∀ {n : ℕ} {as : List α}, n < as.length → get n as ∈ as
  | _, [], h1 => by cases h1
  -- porting note : needed to add to `rw [mem_cons] here` in the two cases below
  -- and in other lemmas (presumably because previously lean could see through the def of `mem` ?)
  | 0, a :: as, _ => by rw [mem_cons]; exact Or.inl rfl
  | n + 1, a :: as, h1 => by
    rw [mem_cons]; apply Or.inr; unfold get
    

Proof state:
case h
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
n : ℕ
a : α
as : List α
h1 : n + 1 < length (a :: as)
⊢ get (Nat.add n 0) as ∈ as

Next tactic:
apply mem_get_of_le
theorem mem_get_of_le : ∀ {n : ℕ} {as : List α}, n < as.length → get n as ∈ as
  | _, [], h1 => by cases h1
  -- porting note : needed to add to `rw [mem_cons] here` in the two cases below
  -- and in other lemmas (presumably because previously lean could see through the def of `mem` ?)
  | 0, a :: as, _ => by rw [mem_cons]; exact Or.inl rfl
  | n + 1, a :: as, h1 => by
    rw [mem_cons]; apply Or.inr; unfold get
    apply mem_get_of_le
    

Proof state:
case h.a
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
n : ℕ
a : α
as : List α
h1 : n + 1 < length (a :: as)
⊢ Nat.add n 0 < length as

Next tactic:
apply Nat.lt_of_succ_lt_succ h1
theorem mem_get_of_ne_zero : ∀ {n : ℕ} {as : List α}, get n as ≠ default → get n as ∈ as
  | _, [], h1 => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
x✝ : ℕ
h1 : get x✝ [] ≠ default
⊢ get x✝ [] ∈ []

Next tactic:
exfalso
theorem mem_get_of_ne_zero : ∀ {n : ℕ} {as : List α}, get n as ≠ default → get n as ∈ as
  | _, [], h1 => by exfalso; 

Proof state:
case h
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
x✝ : ℕ
h1 : get x✝ [] ≠ default
⊢ False

Next tactic:
apply h1
theorem mem_get_of_ne_zero : ∀ {n : ℕ} {as : List α}, get n as ≠ default → get n as ∈ as
  | _, [], h1 => by exfalso; apply h1; 

Proof state:
case h
α : Type u
β : Type v
γ : Type w
a : α
as as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
x✝ : ℕ
h1 : get x✝ [] ≠ default
⊢ get x✝ [] = default

Next tactic:
rw [get_nil]
theorem mem_get_of_ne_zero : ∀ {n : ℕ} {as : List α}, get n as ≠ default → get n as ∈ as
  | _, [], h1 => by exfalso; apply h1; rw [get_nil]
  | 0, a :: as, _ => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
as✝ as1 as2 as3 : List α
inst✝¹ : Inhabited α
inst✝ : Inhabited β
a : α
as : List α
x✝ : get 0 (a :: as) ≠ default
⊢ get 0 (a :: as) ∈ a :: as

Next tactic:
rw [mem_cons]