l3lab/ntp-mathlib huggingface dataset:
/-- The direct limit `setoid` respects the structure `sigmaStructure`, so quotienting by it
  gives rise to a valid structure. -/
noncomputable instance prestructure : L.Prestructure (DirectLimit.setoid G f) where
  toStructure := sigmaStructure G f
  fun_equiv {n} {F} x y xy := by
    obtain ⟨i, hx, hy, h⟩ := exists_unify_eq G f xy
    refine'
      Setoid.trans (funMap_equiv_unify G f F x i hx)
        (Setoid.trans _ (Setoid.symm (funMap_equiv_unify G f F y i hy)))
    

Proof state:
case intro.intro.intro
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
F : Functions L n
x y : Fin n → Σˣ f
xy : x ≈ y
i : ι
hx : i ∈ upperBounds (range (Sigma.fst ∘ x))
hy : i ∈ upperBounds (range (Sigma.fst ∘ y))
h : unify f x i hx = unify f y i hy
⊢ Structure.Sigma.mk f i (funMap F (unify f x i hx)) ≈ Structure.Sigma.mk f i (funMap F (unify f y i hy))

Next tactic:
rw [h]
/-- The direct limit `setoid` respects the structure `sigmaStructure`, so quotienting by it
  gives rise to a valid structure. -/
noncomputable instance prestructure : L.Prestructure (DirectLimit.setoid G f) where
  toStructure := sigmaStructure G f
  fun_equiv {n} {F} x y xy := by
    obtain ⟨i, hx, hy, h⟩ := exists_unify_eq G f xy
    refine'
      Setoid.trans (funMap_equiv_unify G f F x i hx)
        (Setoid.trans _ (Setoid.symm (funMap_equiv_unify G f F y i hy)))
    rw [h]
  rel_equiv {n} {R} x y xy := by
    

Proof state:
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
R : Relations L n
x y : Fin n → Σˣ f
xy : x ≈ y
⊢ RelMap R x = RelMap R y

Next tactic:
obtain ⟨i, hx, hy, h⟩ := exists_unify_eq G f xy
/-- The direct limit `setoid` respects the structure `sigmaStructure`, so quotienting by it
  gives rise to a valid structure. -/
noncomputable instance prestructure : L.Prestructure (DirectLimit.setoid G f) where
  toStructure := sigmaStructure G f
  fun_equiv {n} {F} x y xy := by
    obtain ⟨i, hx, hy, h⟩ := exists_unify_eq G f xy
    refine'
      Setoid.trans (funMap_equiv_unify G f F x i hx)
        (Setoid.trans _ (Setoid.symm (funMap_equiv_unify G f F y i hy)))
    rw [h]
  rel_equiv {n} {R} x y xy := by
    obtain ⟨i, hx, hy, h⟩ := exists_unify_eq G f xy
    

Proof state:
case intro.intro.intro
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
R : Relations L n
x y : Fin n → Σˣ f
xy : x ≈ y
i : ι
hx : i ∈ upperBounds (range (Sigma.fst ∘ x))
hy : i ∈ upperBounds (range (Sigma.fst ∘ y))
h : unify f x i hx = unify f y i hy
⊢ RelMap R x = RelMap R y

Next tactic:
refine' _root_.trans (relMap_equiv_unify G f R x i hx)
      (_root_.trans _ (symm (relMap_equiv_unify G f R y i hy)))
/-- The direct limit `setoid` respects the structure `sigmaStructure`, so quotienting by it
  gives rise to a valid structure. -/
noncomputable instance prestructure : L.Prestructure (DirectLimit.setoid G f) where
  toStructure := sigmaStructure G f
  fun_equiv {n} {F} x y xy := by
    obtain ⟨i, hx, hy, h⟩ := exists_unify_eq G f xy
    refine'
      Setoid.trans (funMap_equiv_unify G f F x i hx)
        (Setoid.trans _ (Setoid.symm (funMap_equiv_unify G f F y i hy)))
    rw [h]
  rel_equiv {n} {R} x y xy := by
    obtain ⟨i, hx, hy, h⟩ := exists_unify_eq G f xy
    refine' _root_.trans (relMap_equiv_unify G f R x i hx)
      (_root_.trans _ (symm (relMap_equiv_unify G f R y i hy)))
    

Proof state:
case intro.intro.intro
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
R : Relations L n
x y : Fin n → Σˣ f
xy : x ≈ y
i : ι
hx : i ∈ upperBounds (range (Sigma.fst ∘ x))
hy : i ∈ upperBounds (range (Sigma.fst ∘ y))
h : unify f x i hx = unify f y i hy
⊢ RelMap R (unify f x i hx) = RelMap R (unify f y i hy)

Next tactic:
rw [h]
@[simp]
theorem funMap_quotient_mk'_sigma_mk' {n : ℕ} {F : L.Functions n} {i : ι} {x : Fin n → G i} :
    funMap F (fun a => (⟦.mk f i (x a)⟧ : DirectLimit G f)) = ⟦.mk f i (funMap F x)⟧ := by
  

Proof state:
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
F : Functions L n
i : ι
x : Fin n → G i
⊢ (funMap F fun a => ⟦Structure.Sigma.mk f i (x a)⟧) = ⟦Structure.Sigma.mk f i (funMap F x)⟧

Next tactic:
simp only [funMap_quotient_mk', Quotient.eq]
@[simp]
theorem funMap_quotient_mk'_sigma_mk' {n : ℕ} {F : L.Functions n} {i : ι} {x : Fin n → G i} :
    funMap F (fun a => (⟦.mk f i (x a)⟧ : DirectLimit G f)) = ⟦.mk f i (funMap F x)⟧ := by
  simp only [funMap_quotient_mk', Quotient.eq]
  

Proof state:
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
F : Functions L n
i : ι
x : Fin n → G i
⊢ (funMap F fun i_1 => Structure.Sigma.mk f i (x i_1)) ≈ Structure.Sigma.mk f i (funMap F x)

Next tactic:
obtain ⟨k, ik, jk⟩ :=
    directed_of (· ≤ ·) i (Classical.choose (Fintype.bddAbove_range fun _ : Fin n => i))
@[simp]
theorem funMap_quotient_mk'_sigma_mk' {n : ℕ} {F : L.Functions n} {i : ι} {x : Fin n → G i} :
    funMap F (fun a => (⟦.mk f i (x a)⟧ : DirectLimit G f)) = ⟦.mk f i (funMap F x)⟧ := by
  simp only [funMap_quotient_mk', Quotient.eq]
  obtain ⟨k, ik, jk⟩ :=
    directed_of (· ≤ ·) i (Classical.choose (Fintype.bddAbove_range fun _ : Fin n => i))
  

Proof state:
case intro.intro
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
F : Functions L n
i : ι
x : Fin n → G i
k : ι
ik : i ≤ k
jk : Classical.choose (_ : BddAbove (range fun x => i)) ≤ k
⊢ (funMap F fun i_1 => Structure.Sigma.mk f i (x i_1)) ≈ Structure.Sigma.mk f i (funMap F x)

Next tactic:
refine' ⟨k, jk, ik, _⟩
@[simp]
theorem funMap_quotient_mk'_sigma_mk' {n : ℕ} {F : L.Functions n} {i : ι} {x : Fin n → G i} :
    funMap F (fun a => (⟦.mk f i (x a)⟧ : DirectLimit G f)) = ⟦.mk f i (funMap F x)⟧ := by
  simp only [funMap_quotient_mk', Quotient.eq]
  obtain ⟨k, ik, jk⟩ :=
    directed_of (· ≤ ·) i (Classical.choose (Fintype.bddAbove_range fun _ : Fin n => i))
  refine' ⟨k, jk, ik, _⟩
  

Proof state:
case intro.intro
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
F : Functions L n
i : ι
x : Fin n → G i
k : ι
ik : i ≤ k
jk : Classical.choose (_ : BddAbove (range fun x => i)) ≤ k
⊢ (f (Classical.choose (_ : BddAbove (range fun a => (Structure.Sigma.mk f i (x a)).fst))) k jk)
      (funMap F
        (unify f (fun i_1 => Structure.Sigma.mk f i (x i_1))
          (Classical.choose (_ : BddAbove (range fun a => (Structure.Sigma.mk f i (x a)).fst)))
          (_ :
            Classical.choose (_ : BddAbove (range fun a => (Structure.Sigma.mk f i (x a)).fst)) ∈
              upperBounds (range fun a => (Structure.Sigma.mk f i (x a)).fst)))) =
    (f i k ik) (funMap F x)

Next tactic:
simp only [Embedding.map_fun, comp_unify]
@[simp]
theorem funMap_quotient_mk'_sigma_mk' {n : ℕ} {F : L.Functions n} {i : ι} {x : Fin n → G i} :
    funMap F (fun a => (⟦.mk f i (x a)⟧ : DirectLimit G f)) = ⟦.mk f i (funMap F x)⟧ := by
  simp only [funMap_quotient_mk', Quotient.eq]
  obtain ⟨k, ik, jk⟩ :=
    directed_of (· ≤ ·) i (Classical.choose (Fintype.bddAbove_range fun _ : Fin n => i))
  refine' ⟨k, jk, ik, _⟩
  simp only [Embedding.map_fun, comp_unify]
  

Proof state:
case intro.intro
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
F : Functions L n
i : ι
x : Fin n → G i
k : ι
ik : i ≤ k
jk : Classical.choose (_ : BddAbove (range fun x => i)) ≤ k
⊢ funMap F
      (unify f (fun i_1 => Structure.Sigma.mk f i (x i_1)) k
        (_ : ∀ k_1 ∈ range (Sigma.fst ∘ fun i_1 => Structure.Sigma.mk f i (x i_1)), k_1 ≤ k)) =
    funMap F (⇑(f i k ik) ∘ x)

Next tactic:
rfl
@[simp]
theorem relMap_quotient_mk'_sigma_mk' {n : ℕ} {R : L.Relations n} {i : ι} {x : Fin n → G i} :
    RelMap R (fun a => (⟦.mk f i (x a)⟧ : DirectLimit G f)) = RelMap R x := by
  

Proof state:
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
R : Relations L n
i : ι
x : Fin n → G i
⊢ (RelMap R fun a => ⟦Structure.Sigma.mk f i (x a)⟧) = RelMap R x

Next tactic:
rw [relMap_quotient_mk']
@[simp]
theorem relMap_quotient_mk'_sigma_mk' {n : ℕ} {R : L.Relations n} {i : ι} {x : Fin n → G i} :
    RelMap R (fun a => (⟦.mk f i (x a)⟧ : DirectLimit G f)) = RelMap R x := by
  rw [relMap_quotient_mk']
  

Proof state:
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
R : Relations L n
i : ι
x : Fin n → G i
⊢ (RelMap R fun a => Structure.Sigma.mk f i (x a)) = RelMap R x

Next tactic:
obtain ⟨k, _, _⟩ :=
    directed_of (· ≤ ·) i (Classical.choose (Fintype.bddAbove_range fun _ : Fin n => i))
@[simp]
theorem relMap_quotient_mk'_sigma_mk' {n : ℕ} {R : L.Relations n} {i : ι} {x : Fin n → G i} :
    RelMap R (fun a => (⟦.mk f i (x a)⟧ : DirectLimit G f)) = RelMap R x := by
  rw [relMap_quotient_mk']
  obtain ⟨k, _, _⟩ :=
    directed_of (· ≤ ·) i (Classical.choose (Fintype.bddAbove_range fun _ : Fin n => i))
  

Proof state:
case intro.intro
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
R : Relations L n
i : ι
x : Fin n → G i
k : ι
left✝ : i ≤ k
right✝ : Classical.choose (_ : BddAbove (range fun x => i)) ≤ k
⊢ (RelMap R fun a => Structure.Sigma.mk f i (x a)) = RelMap R x

Next tactic:
rw [relMap_equiv_unify G f R (fun a => .mk f i (x a)) i]
@[simp]
theorem relMap_quotient_mk'_sigma_mk' {n : ℕ} {R : L.Relations n} {i : ι} {x : Fin n → G i} :
    RelMap R (fun a => (⟦.mk f i (x a)⟧ : DirectLimit G f)) = RelMap R x := by
  rw [relMap_quotient_mk']
  obtain ⟨k, _, _⟩ :=
    directed_of (· ≤ ·) i (Classical.choose (Fintype.bddAbove_range fun _ : Fin n => i))
  rw [relMap_equiv_unify G f R (fun a => .mk f i (x a)) i]
  

Proof state:
case intro.intro
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
R : Relations L n
i : ι
x : Fin n → G i
k : ι
left✝ : i ≤ k
right✝ : Classical.choose (_ : BddAbove (range fun x => i)) ≤ k
⊢ RelMap R (unify f (fun a => Structure.Sigma.mk f i (x a)) i ?intro.intro) = RelMap R x
case intro.intro
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
n : ℕ
R : Relations L n
i : ι
x : Fin n → G i
k : ι
left✝ : i ≤ k
right✝ : Classical.choose (_ : BddAbove (range fun x => i)) ≤ k
⊢ i ∈ upperBounds (range (Sigma.fst ∘ fun a => Structure.Sigma.mk f i (x a)))

Next tactic:
rw [unify_sigma_mk_self]
theorem exists_quotient_mk'_sigma_mk'_eq {α : Type*} [Fintype α] (x : α → DirectLimit G f) :
    ∃ (i : ι) (y : α → G i), x = fun a => ⟦.mk f i (y a)⟧ := by
  

Proof state:
L : Language
ι : Type v
inst✝⁵ : Preorder ι
G : ι → Type w
inst✝⁴ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝¹ : Nonempty ι
α : Type u_1
inst✝ : Fintype α
x : α → DirectLimit G f
⊢ ∃ i y, x = fun a => ⟦Structure.Sigma.mk f i (y a)⟧

Next tactic:
obtain ⟨i, hi⟩ := Fintype.bddAbove_range fun a => (x a).out.1
theorem exists_quotient_mk'_sigma_mk'_eq {α : Type*} [Fintype α] (x : α → DirectLimit G f) :
    ∃ (i : ι) (y : α → G i), x = fun a => ⟦.mk f i (y a)⟧ := by
  obtain ⟨i, hi⟩ := Fintype.bddAbove_range fun a => (x a).out.1
  

Proof state:
case intro
L : Language
ι : Type v
inst✝⁵ : Preorder ι
G : ι → Type w
inst✝⁴ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝¹ : Nonempty ι
α : Type u_1
inst✝ : Fintype α
x : α → DirectLimit G f
i : ι
hi : i ∈ upperBounds (range fun a => (Quotient.out (x a)).fst)
⊢ ∃ i y, x = fun a => ⟦Structure.Sigma.mk f i (y a)⟧

Next tactic:
refine' ⟨i, unify f (Quotient.out ∘ x) i hi, _⟩
theorem exists_quotient_mk'_sigma_mk'_eq {α : Type*} [Fintype α] (x : α → DirectLimit G f) :
    ∃ (i : ι) (y : α → G i), x = fun a => ⟦.mk f i (y a)⟧ := by
  obtain ⟨i, hi⟩ := Fintype.bddAbove_range fun a => (x a).out.1
  refine' ⟨i, unify f (Quotient.out ∘ x) i hi, _⟩
  

Proof state:
case intro
L : Language
ι : Type v
inst✝⁵ : Preorder ι
G : ι → Type w
inst✝⁴ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝¹ : Nonempty ι
α : Type u_1
inst✝ : Fintype α
x : α → DirectLimit G f
i : ι
hi : i ∈ upperBounds (range fun a => (Quotient.out (x a)).fst)
⊢ x = fun a => ⟦Structure.Sigma.mk f i (unify f (Quotient.out ∘ x) i hi a)⟧

Next tactic:
ext a
theorem exists_quotient_mk'_sigma_mk'_eq {α : Type*} [Fintype α] (x : α → DirectLimit G f) :
    ∃ (i : ι) (y : α → G i), x = fun a => ⟦.mk f i (y a)⟧ := by
  obtain ⟨i, hi⟩ := Fintype.bddAbove_range fun a => (x a).out.1
  refine' ⟨i, unify f (Quotient.out ∘ x) i hi, _⟩
  ext a
  

Proof state:
case intro.h
L : Language
ι : Type v
inst✝⁵ : Preorder ι
G : ι → Type w
inst✝⁴ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝¹ : Nonempty ι
α : Type u_1
inst✝ : Fintype α
x : α → DirectLimit G f
i : ι
hi : i ∈ upperBounds (range fun a => (Quotient.out (x a)).fst)
a : α
⊢ x a = ⟦Structure.Sigma.mk f i (unify f (Quotient.out ∘ x) i hi a)⟧

Next tactic:
rw [Quotient.eq_mk_iff_out, unify]
theorem exists_quotient_mk'_sigma_mk'_eq {α : Type*} [Fintype α] (x : α → DirectLimit G f) :
    ∃ (i : ι) (y : α → G i), x = fun a => ⟦.mk f i (y a)⟧ := by
  obtain ⟨i, hi⟩ := Fintype.bddAbove_range fun a => (x a).out.1
  refine' ⟨i, unify f (Quotient.out ∘ x) i hi, _⟩
  ext a
  rw [Quotient.eq_mk_iff_out, unify]
  

Proof state:
case intro.h
L : Language
ι : Type v
inst✝⁵ : Preorder ι
G : ι → Type w
inst✝⁴ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝¹ : Nonempty ι
α : Type u_1
inst✝ : Fintype α
x : α → DirectLimit G f
i : ι
hi : i ∈ upperBounds (range fun a => (Quotient.out (x a)).fst)
a : α
⊢ Quotient.out (x a) ≈
    Structure.Sigma.mk f i
      ((f ((Quotient.out ∘ x) a).fst i (_ : ((Quotient.out ∘ x) a).fst ≤ i)) ((Quotient.out ∘ x) a).snd)

Next tactic:
generalize_proofs r
theorem exists_quotient_mk'_sigma_mk'_eq {α : Type*} [Fintype α] (x : α → DirectLimit G f) :
    ∃ (i : ι) (y : α → G i), x = fun a => ⟦.mk f i (y a)⟧ := by
  obtain ⟨i, hi⟩ := Fintype.bddAbove_range fun a => (x a).out.1
  refine' ⟨i, unify f (Quotient.out ∘ x) i hi, _⟩
  ext a
  rw [Quotient.eq_mk_iff_out, unify]
  generalize_proofs r
  

Proof state:
case intro.h
L : Language
ι : Type v
inst✝⁵ : Preorder ι
G : ι → Type w
inst✝⁴ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝¹ : Nonempty ι
α : Type u_1
inst✝ : Fintype α
x : α → DirectLimit G f
i : ι
hi : i ∈ upperBounds (range fun a => (Quotient.out (x a)).fst)
a : α
r : ((Quotient.out ∘ x) a).fst ≤ i
⊢ Quotient.out (x a) ≈ Structure.Sigma.mk f i ((f ((Quotient.out ∘ x) a).fst i r) ((Quotient.out ∘ x) a).snd)

Next tactic:
change _ ≈ .mk f i (f (Quotient.out (x a)).fst i r (Quotient.out (x a)).snd)
theorem exists_quotient_mk'_sigma_mk'_eq {α : Type*} [Fintype α] (x : α → DirectLimit G f) :
    ∃ (i : ι) (y : α → G i), x = fun a => ⟦.mk f i (y a)⟧ := by
  obtain ⟨i, hi⟩ := Fintype.bddAbove_range fun a => (x a).out.1
  refine' ⟨i, unify f (Quotient.out ∘ x) i hi, _⟩
  ext a
  rw [Quotient.eq_mk_iff_out, unify]
  generalize_proofs r
  change _ ≈ .mk f i (f (Quotient.out (x a)).fst i r (Quotient.out (x a)).snd)
  

Proof state:
case intro.h
L : Language
ι : Type v
inst✝⁵ : Preorder ι
G : ι → Type w
inst✝⁴ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝¹ : Nonempty ι
α : Type u_1
inst✝ : Fintype α
x : α → DirectLimit G f
i : ι
hi : i ∈ upperBounds (range fun a => (Quotient.out (x a)).fst)
a : α
r : ((Quotient.out ∘ x) a).fst ≤ i
⊢ Quotient.out (x a) ≈ Structure.Sigma.mk f i ((f (Quotient.out (x a)).fst i r) (Quotient.out (x a)).snd)

Next tactic:
have : (.mk f i (f (Quotient.out (x a)).fst i r (Quotient.out (x a)).snd) : Σˣ f).fst ≤ i :=
    le_rfl
theorem exists_quotient_mk'_sigma_mk'_eq {α : Type*} [Fintype α] (x : α → DirectLimit G f) :
    ∃ (i : ι) (y : α → G i), x = fun a => ⟦.mk f i (y a)⟧ := by
  obtain ⟨i, hi⟩ := Fintype.bddAbove_range fun a => (x a).out.1
  refine' ⟨i, unify f (Quotient.out ∘ x) i hi, _⟩
  ext a
  rw [Quotient.eq_mk_iff_out, unify]
  generalize_proofs r
  change _ ≈ .mk f i (f (Quotient.out (x a)).fst i r (Quotient.out (x a)).snd)
  have : (.mk f i (f (Quotient.out (x a)).fst i r (Quotient.out (x a)).snd) : Σˣ f).fst ≤ i :=
    le_rfl
  

Proof state:
case intro.h
L : Language
ι : Type v
inst✝⁵ : Preorder ι
G : ι → Type w
inst✝⁴ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝¹ : Nonempty ι
α : Type u_1
inst✝ : Fintype α
x : α → DirectLimit G f
i : ι
hi : i ∈ upperBounds (range fun a => (Quotient.out (x a)).fst)
a : α
r : ((Quotient.out ∘ x) a).fst ≤ i
this : (Structure.Sigma.mk f i ((f (Quotient.out (x a)).fst i r) (Quotient.out (x a)).snd)).fst ≤ i
⊢ Quotient.out (x a) ≈ Structure.Sigma.mk f i ((f (Quotient.out (x a)).fst i r) (Quotient.out (x a)).snd)

Next tactic:
rw [equiv_iff G f (i := i) (hi _) this]
theorem exists_quotient_mk'_sigma_mk'_eq {α : Type*} [Fintype α] (x : α → DirectLimit G f) :
    ∃ (i : ι) (y : α → G i), x = fun a => ⟦.mk f i (y a)⟧ := by
  obtain ⟨i, hi⟩ := Fintype.bddAbove_range fun a => (x a).out.1
  refine' ⟨i, unify f (Quotient.out ∘ x) i hi, _⟩
  ext a
  rw [Quotient.eq_mk_iff_out, unify]
  generalize_proofs r
  change _ ≈ .mk f i (f (Quotient.out (x a)).fst i r (Quotient.out (x a)).snd)
  have : (.mk f i (f (Quotient.out (x a)).fst i r (Quotient.out (x a)).snd) : Σˣ f).fst ≤ i :=
    le_rfl
  rw [equiv_iff G f (i := i) (hi _) this]
  · 

Proof state:
case intro.h
L : Language
ι : Type v
inst✝⁵ : Preorder ι
G : ι → Type w
inst✝⁴ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝¹ : Nonempty ι
α : Type u_1
inst✝ : Fintype α
x : α → DirectLimit G f
i : ι
hi : i ∈ upperBounds (range fun a => (Quotient.out (x a)).fst)
a : α
r : ((Quotient.out ∘ x) a).fst ≤ i
this : (Structure.Sigma.mk f i ((f (Quotient.out (x a)).fst i r) (Quotient.out (x a)).snd)).fst ≤ i
⊢ (f (Quotient.out (x a)).fst i (_ : (Quotient.out (x a)).fst ≤ i)) (Quotient.out (x a)).snd =
    (f (Structure.Sigma.mk f i ((f (Quotient.out (x a)).fst i r) (Quotient.out (x a)).snd)).fst i this)
      (Structure.Sigma.mk f i ((f (Quotient.out (x a)).fst i r) (Quotient.out (x a)).snd)).snd

Next tactic:
simp only [DirectedSystem.map_self]
theorem exists_quotient_mk'_sigma_mk'_eq {α : Type*} [Fintype α] (x : α → DirectLimit G f) :
    ∃ (i : ι) (y : α → G i), x = fun a => ⟦.mk f i (y a)⟧ := by
  obtain ⟨i, hi⟩ := Fintype.bddAbove_range fun a => (x a).out.1
  refine' ⟨i, unify f (Quotient.out ∘ x) i hi, _⟩
  ext a
  rw [Quotient.eq_mk_iff_out, unify]
  generalize_proofs r
  change _ ≈ .mk f i (f (Quotient.out (x a)).fst i r (Quotient.out (x a)).snd)
  have : (.mk f i (f (Quotient.out (x a)).fst i r (Quotient.out (x a)).snd) : Σˣ f).fst ≤ i :=
    le_rfl
  rw [equiv_iff G f (i := i) (hi _) this]
  · simp only [DirectedSystem.map_self]
  

Proof state:
L : Language
ι : Type v
inst✝⁵ : Preorder ι
G : ι → Type w
inst✝⁴ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝¹ : Nonempty ι
α : Type u_1
inst✝ : Fintype α
x : α → DirectLimit G f
i : ι
hi : i ∈ upperBounds (range fun a => (Quotient.out (x a)).fst)
a : α
r : ((Quotient.out ∘ x) a).fst ≤ i
this : (Structure.Sigma.mk f i ((f (Quotient.out (x a)).fst i r) (Quotient.out (x a)).snd)).fst ≤ i
⊢ (Quotient.out (x a)).fst ∈ range fun a => (Quotient.out (x a)).fst

Next tactic:
exact ⟨a, rfl⟩
/-- The canonical map from a component to the direct limit. -/
def of (i : ι) : G i ↪[L] DirectLimit G f where
  toFun := fun a => ⟦.mk f i a⟧
  inj' x y h := by
    

Proof state:
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
i : ι
x y : G i
h : (fun a => ⟦Structure.Sigma.mk f i a⟧) x = (fun a => ⟦Structure.Sigma.mk f i a⟧) y
⊢ x = y

Next tactic:
rw [Quotient.eq] at h
/-- The canonical map from a component to the direct limit. -/
def of (i : ι) : G i ↪[L] DirectLimit G f where
  toFun := fun a => ⟦.mk f i a⟧
  inj' x y h := by
    rw [Quotient.eq] at h
    

Proof state:
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
i : ι
x y : G i
h : Structure.Sigma.mk f i x ≈ Structure.Sigma.mk f i y
⊢ x = y

Next tactic:
obtain ⟨j, h1, _, h3⟩ := h
/-- The canonical map from a component to the direct limit. -/
def of (i : ι) : G i ↪[L] DirectLimit G f where
  toFun := fun a => ⟦.mk f i a⟧
  inj' x y h := by
    rw [Quotient.eq] at h
    obtain ⟨j, h1, _, h3⟩ := h
    

Proof state:
case intro.intro.intro
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x x_1 => x ≤ x_1
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
i : ι
x y : G i
j : ι
h1 w✝ : i ≤ j
h3 : (f i j h1) x = (f i j w✝) y
⊢ x = y

Next tactic:
exact (f i j h1).injective h3