l3lab/ntp-mathlib huggingface dataset:
/-- Every element of the direct limit corresponds to some element in
some component of the directed system. -/
theorem exists_of [Nonempty ι] [IsDirected ι (· ≤ ·)] (z : DirectLimit G f) :
    ∃ i x, of G f i x = z :=
  Nonempty.elim (by infer_instance) fun ind : ι =>
    Quotient.inductionOn' z fun x =>
      FreeAbelianGroup.induction_on x ⟨ind, 0, (of _ _ ind).map_zero⟩
        (fun s =>
          Multiset.induction_on s ⟨ind, 1, (of _ _ ind).map_one⟩ fun a s ih =>
            let ⟨i, x⟩ := a
            let ⟨j, y, hs⟩ := ih
            let ⟨k, hik, hjk⟩ := exists_ge_ge i j
            ⟨k, f i k hik x * f j k hjk y, by
              rw [(of G f k).map_mul, of_f, of_f, hs]
              /- porting note: In Lean3, from here, this was `by refl`. I have added
              the lemma `FreeCommRing.of_cons` to fix this proof. -/
              apply congr_arg Quotient.mk''
              symm
              apply FreeCommRing.of_cons⟩)
        (fun s ⟨i, x, ih⟩ => ⟨i, -x, by
          -- porting note: Lean 3 was `of _ _ _`; Lean 4 is not as good at unification
          -- here as Lean 3 is, for some reason.
          

Proof state:
R : Type u
inst✝⁴ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝³ : Preorder ι
G : ι → Type w
inst✝² : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
inst✝¹ : Nonempty ι
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
z : DirectLimit G f
ind : ι
x✝¹ : FreeCommRing ((i : ι) × G i)
s : Multiplicative (Multiset ((i : ι) × G i))
x✝ : ∃ i x, (of G f i) x = Quotient.mk'' (FreeAbelianGroup.of s)
i : ι
x : G i
ih : (of G f i) x = Quotient.mk'' (FreeAbelianGroup.of s)
⊢ (of G f i) (-x) = Quotient.mk'' (-FreeAbelianGroup.of s)

Next tactic:
rw [(of G f i).map_neg, ih]
/-- Every element of the direct limit corresponds to some element in
some component of the directed system. -/
theorem exists_of [Nonempty ι] [IsDirected ι (· ≤ ·)] (z : DirectLimit G f) :
    ∃ i x, of G f i x = z :=
  Nonempty.elim (by infer_instance) fun ind : ι =>
    Quotient.inductionOn' z fun x =>
      FreeAbelianGroup.induction_on x ⟨ind, 0, (of _ _ ind).map_zero⟩
        (fun s =>
          Multiset.induction_on s ⟨ind, 1, (of _ _ ind).map_one⟩ fun a s ih =>
            let ⟨i, x⟩ := a
            let ⟨j, y, hs⟩ := ih
            let ⟨k, hik, hjk⟩ := exists_ge_ge i j
            ⟨k, f i k hik x * f j k hjk y, by
              rw [(of G f k).map_mul, of_f, of_f, hs]
              /- porting note: In Lean3, from here, this was `by refl`. I have added
              the lemma `FreeCommRing.of_cons` to fix this proof. -/
              apply congr_arg Quotient.mk''
              symm
              apply FreeCommRing.of_cons⟩)
        (fun s ⟨i, x, ih⟩ => ⟨i, -x, by
          -- porting note: Lean 3 was `of _ _ _`; Lean 4 is not as good at unification
          -- here as Lean 3 is, for some reason.
          rw [(of G f i).map_neg, ih]
          

Proof state:
R : Type u
inst✝⁴ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝³ : Preorder ι
G : ι → Type w
inst✝² : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
inst✝¹ : Nonempty ι
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
z : DirectLimit G f
ind : ι
x✝¹ : FreeCommRing ((i : ι) × G i)
s : Multiplicative (Multiset ((i : ι) × G i))
x✝ : ∃ i x, (of G f i) x = Quotient.mk'' (FreeAbelianGroup.of s)
i : ι
x : G i
ih : (of G f i) x = Quotient.mk'' (FreeAbelianGroup.of s)
⊢ -Quotient.mk'' (FreeAbelianGroup.of s) = Quotient.mk'' (-FreeAbelianGroup.of s)

Next tactic:
rfl
/-- Every element of the direct limit corresponds to some element in
some component of the directed system. -/
theorem exists_of [Nonempty ι] [IsDirected ι (· ≤ ·)] (z : DirectLimit G f) :
    ∃ i x, of G f i x = z :=
  Nonempty.elim (by infer_instance) fun ind : ι =>
    Quotient.inductionOn' z fun x =>
      FreeAbelianGroup.induction_on x ⟨ind, 0, (of _ _ ind).map_zero⟩
        (fun s =>
          Multiset.induction_on s ⟨ind, 1, (of _ _ ind).map_one⟩ fun a s ih =>
            let ⟨i, x⟩ := a
            let ⟨j, y, hs⟩ := ih
            let ⟨k, hik, hjk⟩ := exists_ge_ge i j
            ⟨k, f i k hik x * f j k hjk y, by
              rw [(of G f k).map_mul, of_f, of_f, hs]
              /- porting note: In Lean3, from here, this was `by refl`. I have added
              the lemma `FreeCommRing.of_cons` to fix this proof. -/
              apply congr_arg Quotient.mk''
              symm
              apply FreeCommRing.of_cons⟩)
        (fun s ⟨i, x, ih⟩ => ⟨i, -x, by
          -- porting note: Lean 3 was `of _ _ _`; Lean 4 is not as good at unification
          -- here as Lean 3 is, for some reason.
          rw [(of G f i).map_neg, ih]
          rfl⟩)
        fun p q ⟨i, x, ihx⟩ ⟨j, y, ihy⟩ =>
        let ⟨k, hik, hjk⟩ := exists_ge_ge i j
        ⟨k, f i k hik x + f j k hjk y, by 

Proof state:
R : Type u
inst✝⁴ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝³ : Preorder ι
G : ι → Type w
inst✝² : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
inst✝¹ : Nonempty ι
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
z : DirectLimit G f
ind : ι
x✝² : FreeCommRing ((i : ι) × G i)
p q : FreeAbelianGroup (Multiplicative (Multiset ((i : ι) × G i)))
x✝¹ : ∃ i x, (of G f i) x = Quotient.mk'' p
x✝ : ∃ i x, (of G f i) x = Quotient.mk'' q
i : ι
x : G i
ihx : (of G f i) x = Quotient.mk'' p
j : ι
y : G j
ihy : (of G f j) y = Quotient.mk'' q
k : ι
hik : i ≤ k
hjk : j ≤ k
⊢ (of G f k) (f i k hik x + f j k hjk y) = Quotient.mk'' (p + q)

Next tactic:
rw [(of _ _ _).map_add, of_f, of_f, ihx, ihy]
/-- Every element of the direct limit corresponds to some element in
some component of the directed system. -/
theorem exists_of [Nonempty ι] [IsDirected ι (· ≤ ·)] (z : DirectLimit G f) :
    ∃ i x, of G f i x = z :=
  Nonempty.elim (by infer_instance) fun ind : ι =>
    Quotient.inductionOn' z fun x =>
      FreeAbelianGroup.induction_on x ⟨ind, 0, (of _ _ ind).map_zero⟩
        (fun s =>
          Multiset.induction_on s ⟨ind, 1, (of _ _ ind).map_one⟩ fun a s ih =>
            let ⟨i, x⟩ := a
            let ⟨j, y, hs⟩ := ih
            let ⟨k, hik, hjk⟩ := exists_ge_ge i j
            ⟨k, f i k hik x * f j k hjk y, by
              rw [(of G f k).map_mul, of_f, of_f, hs]
              /- porting note: In Lean3, from here, this was `by refl`. I have added
              the lemma `FreeCommRing.of_cons` to fix this proof. -/
              apply congr_arg Quotient.mk''
              symm
              apply FreeCommRing.of_cons⟩)
        (fun s ⟨i, x, ih⟩ => ⟨i, -x, by
          -- porting note: Lean 3 was `of _ _ _`; Lean 4 is not as good at unification
          -- here as Lean 3 is, for some reason.
          rw [(of G f i).map_neg, ih]
          rfl⟩)
        fun p q ⟨i, x, ihx⟩ ⟨j, y, ihy⟩ =>
        let ⟨k, hik, hjk⟩ := exists_ge_ge i j
        ⟨k, f i k hik x + f j k hjk y, by rw [(of _ _ _).map_add, of_f, of_f, ihx, ihy]; 

Proof state:
R : Type u
inst✝⁴ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝³ : Preorder ι
G : ι → Type w
inst✝² : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
inst✝¹ : Nonempty ι
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
z : DirectLimit G f
ind : ι
x✝² : FreeCommRing ((i : ι) × G i)
p q : FreeAbelianGroup (Multiplicative (Multiset ((i : ι) × G i)))
x✝¹ : ∃ i x, (of G f i) x = Quotient.mk'' p
x✝ : ∃ i x, (of G f i) x = Quotient.mk'' q
i : ι
x : G i
ihx : (of G f i) x = Quotient.mk'' p
j : ι
y : G j
ihy : (of G f j) y = Quotient.mk'' q
k : ι
hik : i ≤ k
hjk : j ≤ k
⊢ Quotient.mk'' p + Quotient.mk'' q = Quotient.mk'' (p + q)

Next tactic:
rfl
nonrec theorem Polynomial.exists_of [Nonempty ι] [IsDirected ι (· ≤ ·)]
    (q : Polynomial (DirectLimit G fun i j h => f' i j h)) :
    ∃ i p, Polynomial.map (of G (fun i j h => f' i j h) i) p = q :=
  Polynomial.induction_on q
    (fun z =>
      let ⟨i, x, h⟩ := exists_of z
      ⟨i, C x, by 

Proof state:
R : Type u
inst✝⁴ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝³ : Preorder ι
G : ι → Type w
inst✝² : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
f' : (i j : ι) → i ≤ j → G i →+* G j
inst✝¹ : Nonempty ι
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
q : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
z : DirectLimit G fun i j h => ⇑(f' i j h)
i : ι
x : G i
h : (of G (fun i j h => ⇑(f' i j h)) i) x = z
⊢ Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) (C x) = C z

Next tactic:
rw [map_C, h]
nonrec theorem Polynomial.exists_of [Nonempty ι] [IsDirected ι (· ≤ ·)]
    (q : Polynomial (DirectLimit G fun i j h => f' i j h)) :
    ∃ i p, Polynomial.map (of G (fun i j h => f' i j h) i) p = q :=
  Polynomial.induction_on q
    (fun z =>
      let ⟨i, x, h⟩ := exists_of z
      ⟨i, C x, by rw [map_C, h]⟩)
    (fun q₁ q₂ ⟨i₁, p₁, ih₁⟩ ⟨i₂, p₂, ih₂⟩ =>
      let ⟨i, h1, h2⟩ := exists_ge_ge i₁ i₂
      ⟨i, p₁.map (f' i₁ i h1) + p₂.map (f' i₂ i h2), by
        

Proof state:
R : Type u
inst✝⁴ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝³ : Preorder ι
G : ι → Type w
inst✝² : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
f' : (i j : ι) → i ≤ j → G i →+* G j
inst✝¹ : Nonempty ι
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
q : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
q₁ q₂ : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
x✝¹ : ∃ i p, Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) p = q₁
x✝ : ∃ i p, Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) p = q₂
i₁ : ι
p₁ : (G i₁)[X]
ih₁ : Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₁) p₁ = q₁
i₂ : ι
p₂ : (G i₂)[X]
ih₂ : Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₂) p₂ = q₂
i : ι
h1 : i₁ ≤ i
h2 : i₂ ≤ i
⊢ Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) (Polynomial.map (f' i₁ i h1) p₁ + Polynomial.map (f' i₂ i h2) p₂) =
    q₁ + q₂

Next tactic:
rw [Polynomial.map_add, map_map, map_map, ← ih₁, ← ih₂]
nonrec theorem Polynomial.exists_of [Nonempty ι] [IsDirected ι (· ≤ ·)]
    (q : Polynomial (DirectLimit G fun i j h => f' i j h)) :
    ∃ i p, Polynomial.map (of G (fun i j h => f' i j h) i) p = q :=
  Polynomial.induction_on q
    (fun z =>
      let ⟨i, x, h⟩ := exists_of z
      ⟨i, C x, by rw [map_C, h]⟩)
    (fun q₁ q₂ ⟨i₁, p₁, ih₁⟩ ⟨i₂, p₂, ih₂⟩ =>
      let ⟨i, h1, h2⟩ := exists_ge_ge i₁ i₂
      ⟨i, p₁.map (f' i₁ i h1) + p₂.map (f' i₂ i h2), by
        rw [Polynomial.map_add, map_map, map_map, ← ih₁, ← ih₂]
        

Proof state:
R : Type u
inst✝⁴ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝³ : Preorder ι
G : ι → Type w
inst✝² : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
f' : (i j : ι) → i ≤ j → G i →+* G j
inst✝¹ : Nonempty ι
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
q : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
q₁ q₂ : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
x✝¹ : ∃ i p, Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) p = q₁
x✝ : ∃ i p, Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) p = q₂
i₁ : ι
p₁ : (G i₁)[X]
ih₁ : Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₁) p₁ = q₁
i₂ : ι
p₂ : (G i₂)[X]
ih₂ : Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₂) p₂ = q₂
i : ι
h1 : i₁ ≤ i
h2 : i₂ ≤ i
⊢ Polynomial.map (RingHom.comp (of G (fun i j h => ⇑(f' i j h)) i) (f' i₁ i h1)) p₁ +
      Polynomial.map (RingHom.comp (of G (fun i j h => ⇑(f' i j h)) i) (f' i₂ i h2)) p₂ =
    Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₁) p₁ + Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₂) p₂

Next tactic:
congr 2
nonrec theorem Polynomial.exists_of [Nonempty ι] [IsDirected ι (· ≤ ·)]
    (q : Polynomial (DirectLimit G fun i j h => f' i j h)) :
    ∃ i p, Polynomial.map (of G (fun i j h => f' i j h) i) p = q :=
  Polynomial.induction_on q
    (fun z =>
      let ⟨i, x, h⟩ := exists_of z
      ⟨i, C x, by rw [map_C, h]⟩)
    (fun q₁ q₂ ⟨i₁, p₁, ih₁⟩ ⟨i₂, p₂, ih₂⟩ =>
      let ⟨i, h1, h2⟩ := exists_ge_ge i₁ i₂
      ⟨i, p₁.map (f' i₁ i h1) + p₂.map (f' i₂ i h2), by
        rw [Polynomial.map_add, map_map, map_map, ← ih₁, ← ih₂]
        congr 2 <;> 

Proof state:
case e_a.e_f
R : Type u
inst✝⁴ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝³ : Preorder ι
G : ι → Type w
inst✝² : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
f' : (i j : ι) → i ≤ j → G i →+* G j
inst✝¹ : Nonempty ι
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
q : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
q₁ q₂ : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
x✝¹ : ∃ i p, Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) p = q₁
x✝ : ∃ i p, Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) p = q₂
i₁ : ι
p₁ : (G i₁)[X]
ih₁ : Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₁) p₁ = q₁
i₂ : ι
p₂ : (G i₂)[X]
ih₂ : Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₂) p₂ = q₂
i : ι
h1 : i₁ ≤ i
h2 : i₂ ≤ i
⊢ RingHom.comp (of G (fun i j h => ⇑(f' i j h)) i) (f' i₁ i h1) = of G (fun i j h => ⇑(f' i j h)) i₁

Next tactic:
ext x
nonrec theorem Polynomial.exists_of [Nonempty ι] [IsDirected ι (· ≤ ·)]
    (q : Polynomial (DirectLimit G fun i j h => f' i j h)) :
    ∃ i p, Polynomial.map (of G (fun i j h => f' i j h) i) p = q :=
  Polynomial.induction_on q
    (fun z =>
      let ⟨i, x, h⟩ := exists_of z
      ⟨i, C x, by rw [map_C, h]⟩)
    (fun q₁ q₂ ⟨i₁, p₁, ih₁⟩ ⟨i₂, p₂, ih₂⟩ =>
      let ⟨i, h1, h2⟩ := exists_ge_ge i₁ i₂
      ⟨i, p₁.map (f' i₁ i h1) + p₂.map (f' i₂ i h2), by
        rw [Polynomial.map_add, map_map, map_map, ← ih₁, ← ih₂]
        congr 2 <;> 

Proof state:
case e_a.e_f
R : Type u
inst✝⁴ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝³ : Preorder ι
G : ι → Type w
inst✝² : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
f' : (i j : ι) → i ≤ j → G i →+* G j
inst✝¹ : Nonempty ι
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
q : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
q₁ q₂ : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
x✝¹ : ∃ i p, Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) p = q₁
x✝ : ∃ i p, Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) p = q₂
i₁ : ι
p₁ : (G i₁)[X]
ih₁ : Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₁) p₁ = q₁
i₂ : ι
p₂ : (G i₂)[X]
ih₂ : Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₂) p₂ = q₂
i : ι
h1 : i₁ ≤ i
h2 : i₂ ≤ i
⊢ RingHom.comp (of G (fun i j h => ⇑(f' i j h)) i) (f' i₂ i h2) = of G (fun i j h => ⇑(f' i j h)) i₂

Next tactic:
ext x
nonrec theorem Polynomial.exists_of [Nonempty ι] [IsDirected ι (· ≤ ·)]
    (q : Polynomial (DirectLimit G fun i j h => f' i j h)) :
    ∃ i p, Polynomial.map (of G (fun i j h => f' i j h) i) p = q :=
  Polynomial.induction_on q
    (fun z =>
      let ⟨i, x, h⟩ := exists_of z
      ⟨i, C x, by rw [map_C, h]⟩)
    (fun q₁ q₂ ⟨i₁, p₁, ih₁⟩ ⟨i₂, p₂, ih₂⟩ =>
      let ⟨i, h1, h2⟩ := exists_ge_ge i₁ i₂
      ⟨i, p₁.map (f' i₁ i h1) + p₂.map (f' i₂ i h2), by
        rw [Polynomial.map_add, map_map, map_map, ← ih₁, ← ih₂]
        congr 2 <;> ext x <;> 

Proof state:
case e_a.e_f.a
R : Type u
inst✝⁴ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝³ : Preorder ι
G : ι → Type w
inst✝² : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
f' : (i j : ι) → i ≤ j → G i →+* G j
inst✝¹ : Nonempty ι
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
q : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
q₁ q₂ : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
x✝¹ : ∃ i p, Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) p = q₁
x✝ : ∃ i p, Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) p = q₂
i₁ : ι
p₁ : (G i₁)[X]
ih₁ : Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₁) p₁ = q₁
i₂ : ι
p₂ : (G i₂)[X]
ih₂ : Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₂) p₂ = q₂
i : ι
h1 : i₁ ≤ i
h2 : i₂ ≤ i
x : G i₁
⊢ (RingHom.comp (of G (fun i j h => ⇑(f' i j h)) i) (f' i₁ i h1)) x = (of G (fun i j h => ⇑(f' i j h)) i₁) x

Next tactic:
simp_rw [RingHom.comp_apply, of_f]
nonrec theorem Polynomial.exists_of [Nonempty ι] [IsDirected ι (· ≤ ·)]
    (q : Polynomial (DirectLimit G fun i j h => f' i j h)) :
    ∃ i p, Polynomial.map (of G (fun i j h => f' i j h) i) p = q :=
  Polynomial.induction_on q
    (fun z =>
      let ⟨i, x, h⟩ := exists_of z
      ⟨i, C x, by rw [map_C, h]⟩)
    (fun q₁ q₂ ⟨i₁, p₁, ih₁⟩ ⟨i₂, p₂, ih₂⟩ =>
      let ⟨i, h1, h2⟩ := exists_ge_ge i₁ i₂
      ⟨i, p₁.map (f' i₁ i h1) + p₂.map (f' i₂ i h2), by
        rw [Polynomial.map_add, map_map, map_map, ← ih₁, ← ih₂]
        congr 2 <;> ext x <;> 

Proof state:
case e_a.e_f.a
R : Type u
inst✝⁴ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝³ : Preorder ι
G : ι → Type w
inst✝² : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
f' : (i j : ι) → i ≤ j → G i →+* G j
inst✝¹ : Nonempty ι
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
q : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
q₁ q₂ : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
x✝¹ : ∃ i p, Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) p = q₁
x✝ : ∃ i p, Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) p = q₂
i₁ : ι
p₁ : (G i₁)[X]
ih₁ : Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₁) p₁ = q₁
i₂ : ι
p₂ : (G i₂)[X]
ih₂ : Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i₂) p₂ = q₂
i : ι
h1 : i₁ ≤ i
h2 : i₂ ≤ i
x : G i₂
⊢ (RingHom.comp (of G (fun i j h => ⇑(f' i j h)) i) (f' i₂ i h2)) x = (of G (fun i j h => ⇑(f' i j h)) i₂) x

Next tactic:
simp_rw [RingHom.comp_apply, of_f]
nonrec theorem Polynomial.exists_of [Nonempty ι] [IsDirected ι (· ≤ ·)]
    (q : Polynomial (DirectLimit G fun i j h => f' i j h)) :
    ∃ i p, Polynomial.map (of G (fun i j h => f' i j h) i) p = q :=
  Polynomial.induction_on q
    (fun z =>
      let ⟨i, x, h⟩ := exists_of z
      ⟨i, C x, by rw [map_C, h]⟩)
    (fun q₁ q₂ ⟨i₁, p₁, ih₁⟩ ⟨i₂, p₂, ih₂⟩ =>
      let ⟨i, h1, h2⟩ := exists_ge_ge i₁ i₂
      ⟨i, p₁.map (f' i₁ i h1) + p₂.map (f' i₂ i h2), by
        rw [Polynomial.map_add, map_map, map_map, ← ih₁, ← ih₂]
        congr 2 <;> ext x <;> simp_rw [RingHom.comp_apply, of_f]⟩)
    fun n z _ =>
    let ⟨i, x, h⟩ := exists_of z
    ⟨i, C x * X ^ (n + 1), by 

Proof state:
R : Type u
inst✝⁴ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝³ : Preorder ι
G : ι → Type w
inst✝² : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
f' : (i j : ι) → i ≤ j → G i →+* G j
inst✝¹ : Nonempty ι
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
q : (DirectLimit G fun i j h => ⇑(f' i j h))[X]
n : ℕ
z : DirectLimit G fun i j h => ⇑(f' i j h)
x✝ : ∃ i p, Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) p = C z * X ^ n
i : ι
x : G i
h : (of G (fun i j h => ⇑(f' i j h)) i) x = z
⊢ Polynomial.map (of G (fun i j h => ⇑(f' i j h)) i) (C x * X ^ (n + 1)) = C z * X ^ (n + 1)

Next tactic:
rw [Polynomial.map_mul, map_C, h, Polynomial.map_pow, map_X]
theorem of.zero_exact_aux2 {x : FreeCommRing (Σi, G i)} {s t} (hxs : IsSupported x s) {j k}
    (hj : ∀ z : Σi, G i, z ∈ s → z.1 ≤ j) (hk : ∀ z : Σi, G i, z ∈ t → z.1 ≤ k) (hjk : j ≤ k)
    (hst : s ⊆ t) :
    f' j k hjk (lift (fun ix : s => f' ix.1.1 j (hj ix ix.2) ix.1.2) (restriction s x)) =
      lift (fun ix : t => f' ix.1.1 k (hk ix ix.2) ix.1.2) (restriction t x) := by
  

Proof state:
R : Type u
inst✝³ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝² : Preorder ι
G : ι → Type w
inst✝¹ : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
f' : (i j : ι) → i ≤ j → G i →+* G j
inst✝ : DirectedSystem G fun i j h => ⇑(f' i j h)
x : FreeCommRing ((i : ι) × G i)
s t : Set ((i : ι) × G i)
hxs : IsSupported x s
j k : ι
hj : ∀ z ∈ s, z.fst ≤ j
hk : ∀ z ∈ t, z.fst ≤ k
hjk : j ≤ k
hst : s ⊆ t
⊢ (f' j k hjk) ((lift fun ix => (f' (↑ix).fst j (_ : (↑ix).fst ≤ j)) (↑ix).snd) ((restriction s) x)) =
    (lift fun ix => (f' (↑ix).fst k (_ : (↑ix).fst ≤ k)) (↑ix).snd) ((restriction t) x)

Next tactic:
refine' Subring.InClosure.recOn hxs _ _ _ _
theorem of.zero_exact_aux2 {x : FreeCommRing (Σi, G i)} {s t} (hxs : IsSupported x s) {j k}
    (hj : ∀ z : Σi, G i, z ∈ s → z.1 ≤ j) (hk : ∀ z : Σi, G i, z ∈ t → z.1 ≤ k) (hjk : j ≤ k)
    (hst : s ⊆ t) :
    f' j k hjk (lift (fun ix : s => f' ix.1.1 j (hj ix ix.2) ix.1.2) (restriction s x)) =
      lift (fun ix : t => f' ix.1.1 k (hk ix ix.2) ix.1.2) (restriction t x) := by
  refine' Subring.InClosure.recOn hxs _ _ _ _
  · 

Proof state:
case refine'_1
R : Type u
inst✝³ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝² : Preorder ι
G : ι → Type w
inst✝¹ : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
f' : (i j : ι) → i ≤ j → G i →+* G j
inst✝ : DirectedSystem G fun i j h => ⇑(f' i j h)
x : FreeCommRing ((i : ι) × G i)
s t : Set ((i : ι) × G i)
hxs : IsSupported x s
j k : ι
hj : ∀ z ∈ s, z.fst ≤ j
hk : ∀ z ∈ t, z.fst ≤ k
hjk : j ≤ k
hst : s ⊆ t
⊢ (f' j k hjk) ((lift fun ix => (f' (↑ix).fst j (_ : (↑ix).fst ≤ j)) (↑ix).snd) ((restriction s) 1)) =
    (lift fun ix => (f' (↑ix).fst k (_ : (↑ix).fst ≤ k)) (↑ix).snd) ((restriction t) 1)

Next tactic:
rw [(restriction _).map_one, (FreeCommRing.lift _).map_one, (f' j k hjk).map_one,
      (restriction _).map_one, (FreeCommRing.lift _).map_one]
theorem of.zero_exact_aux2 {x : FreeCommRing (Σi, G i)} {s t} (hxs : IsSupported x s) {j k}
    (hj : ∀ z : Σi, G i, z ∈ s → z.1 ≤ j) (hk : ∀ z : Σi, G i, z ∈ t → z.1 ≤ k) (hjk : j ≤ k)
    (hst : s ⊆ t) :
    f' j k hjk (lift (fun ix : s => f' ix.1.1 j (hj ix ix.2) ix.1.2) (restriction s x)) =
      lift (fun ix : t => f' ix.1.1 k (hk ix ix.2) ix.1.2) (restriction t x) := by
  refine' Subring.InClosure.recOn hxs _ _ _ _
  · rw [(restriction _).map_one, (FreeCommRing.lift _).map_one, (f' j k hjk).map_one,
      (restriction _).map_one, (FreeCommRing.lift _).map_one]
  · -- porting note: Lean 3 had `(FreeCommRing.lift _).map_neg` but I needed to replace it with
  -- `RingHom.map_neg` to get the rewrite to compile
    

Proof state:
case refine'_2
R : Type u
inst✝³ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝² : Preorder ι
G : ι → Type w
inst✝¹ : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
f' : (i j : ι) → i ≤ j → G i →+* G j
inst✝ : DirectedSystem G fun i j h => ⇑(f' i j h)
x : FreeCommRing ((i : ι) × G i)
s t : Set ((i : ι) × G i)
hxs : IsSupported x s
j k : ι
hj : ∀ z ∈ s, z.fst ≤ j
hk : ∀ z ∈ t, z.fst ≤ k
hjk : j ≤ k
hst : s ⊆ t
⊢ (f' j k hjk) ((lift fun ix => (f' (↑ix).fst j (_ : (↑ix).fst ≤ j)) (↑ix).snd) ((restriction s) (-1))) =
    (lift fun ix => (f' (↑ix).fst k (_ : (↑ix).fst ≤ k)) (↑ix).snd) ((restriction t) (-1))

Next tactic:
rw [(restriction _).map_neg, (restriction _).map_one, RingHom.map_neg,
      (FreeCommRing.lift _).map_one, (f' j k hjk).map_neg, (f' j k hjk).map_one,
      -- porting note: similarly here I give strictly less information
      (restriction _).map_neg, (restriction _).map_one, RingHom.map_neg,
      (FreeCommRing.lift _).map_one]
theorem of.zero_exact_aux2 {x : FreeCommRing (Σi, G i)} {s t} (hxs : IsSupported x s) {j k}
    (hj : ∀ z : Σi, G i, z ∈ s → z.1 ≤ j) (hk : ∀ z : Σi, G i, z ∈ t → z.1 ≤ k) (hjk : j ≤ k)
    (hst : s ⊆ t) :
    f' j k hjk (lift (fun ix : s => f' ix.1.1 j (hj ix ix.2) ix.1.2) (restriction s x)) =
      lift (fun ix : t => f' ix.1.1 k (hk ix ix.2) ix.1.2) (restriction t x) := by
  refine' Subring.InClosure.recOn hxs _ _ _ _
  · rw [(restriction _).map_one, (FreeCommRing.lift _).map_one, (f' j k hjk).map_one,
      (restriction _).map_one, (FreeCommRing.lift _).map_one]
  · -- porting note: Lean 3 had `(FreeCommRing.lift _).map_neg` but I needed to replace it with
  -- `RingHom.map_neg` to get the rewrite to compile
    rw [(restriction _).map_neg, (restriction _).map_one, RingHom.map_neg,
      (FreeCommRing.lift _).map_one, (f' j k hjk).map_neg, (f' j k hjk).map_one,
      -- porting note: similarly here I give strictly less information
      (restriction _).map_neg, (restriction _).map_one, RingHom.map_neg,
      (FreeCommRing.lift _).map_one]
  · 

Proof state:
case refine'_3
R : Type u
inst✝³ : Ring R
ι : Type v
dec_ι : DecidableEq ι
inst✝² : Preorder ι
G : ι → Type w
inst✝¹ : (i : ι) → CommRing (G i)
f : (i j : ι) → i ≤ j → G i → G j
f' : (i j : ι) → i ≤ j → G i →+* G j
inst✝ : DirectedSystem G fun i j h => ⇑(f' i j h)
x : FreeCommRing ((i : ι) × G i)
s t : Set ((i : ι) × G i)
hxs : IsSupported x s
j k : ι
hj : ∀ z ∈ s, z.fst ≤ j
hk : ∀ z ∈ t, z.fst ≤ k
hjk : j ≤ k
hst : s ⊆ t
⊢ ∀ z ∈ FreeCommRing.of '' s,
    ∀ (n : FreeCommRing ((i : ι) × G i)),
      (f' j k hjk) ((lift fun ix => (f' (↑ix).fst j (_ : (↑ix).fst ≤ j)) (↑ix).snd) ((restriction s) n)) =
          (lift fun ix => (f' (↑ix).fst k (_ : (↑ix).fst ≤ k)) (↑ix).snd) ((restriction t) n) →
        (f' j k hjk) ((lift fun ix => (f' (↑ix).fst j (_ : (↑ix).fst ≤ j)) (↑ix).snd) ((restriction s) (z * n))) =
          (lift fun ix => (f' (↑ix).fst k (_ : (↑ix).fst ≤ k)) (↑ix).snd) ((restriction t) (z * n))

Next tactic:
rintro _ ⟨p, hps, rfl⟩ n ih