l3lab/ntp-mathlib huggingface dataset:
/-- The universal property of the direct limit: maps from the components to another module
that respect the directed system structure (i.e. make some diagram commute) give rise
to a unique map out of the direct limit. -/
def lift : DirectLimit G f ↪[L] P where
  toFun :=
    Quotient.lift (fun x : Σˣ f => (g x.1) x.2) fun x y xy => by
      simp only
      obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.1 y.1
      rw [← Hg x.1 i hx, ← Hg y.1 i hy]
      exact congr_arg _ ((equiv_iff ..).1 xy)
  inj' x y xy := by
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.lift_mk, Quotient.lift_mk] at xy
    obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.out.1 y.out.1
    rw [← Hg x.out.1 i hx, ← Hg y.out.1 i hy] at xy
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.eq, equiv_iff G f hx hy]
    exact (g i).injective xy
  map_fun' F x := by
    obtain ⟨i, y, rfl⟩ := exists_quotient_mk'_sigma_mk'_eq G f x
    change _ = funMap F (Quotient.lift _ _ ∘ Quotient.mk _ ∘ Structure.Sigma.mk f i ∘ y)
    

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 ι
P : Type u₁
inst✝ : Structure L P
g : (i : ι) → G i ↪[L] P
Hg : ∀ (i j : ι) (hij : i ≤ j) (x : G i), (g j) ((f i j hij) x) = (g i) x
n✝ : ℕ
F : Functions L n✝
i : ι
y : Fin n✝ → G i
⊢ Function.Embedding.toFun
      {
        toFun :=
          Quotient.lift (fun x => (g x.fst) x.snd)
            (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y),
        inj' :=
          (_ :
            ∀ (x y : DirectLimit G f),
              Quotient.lift (fun x => (g x.fst) x.snd)
                    (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y) x =
                  Quotient.lift (fun x => (g x.fst) x.snd)
                    (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y) y →
                x = y) }
      (funMap F fun a => ⟦Structure.Sigma.mk f i (y a)⟧) =
    funMap F
      (Quotient.lift (fun x => (g x.fst) x.snd)
          (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y) ∘
        Quotient.mk (setoid G f) ∘ Structure.Sigma.mk f i ∘ y)

Next tactic:
rw [funMap_quotient_mk'_sigma_mk', ← Function.comp.assoc, Quotient.lift_comp_mk]
/-- The universal property of the direct limit: maps from the components to another module
that respect the directed system structure (i.e. make some diagram commute) give rise
to a unique map out of the direct limit. -/
def lift : DirectLimit G f ↪[L] P where
  toFun :=
    Quotient.lift (fun x : Σˣ f => (g x.1) x.2) fun x y xy => by
      simp only
      obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.1 y.1
      rw [← Hg x.1 i hx, ← Hg y.1 i hy]
      exact congr_arg _ ((equiv_iff ..).1 xy)
  inj' x y xy := by
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.lift_mk, Quotient.lift_mk] at xy
    obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.out.1 y.out.1
    rw [← Hg x.out.1 i hx, ← Hg y.out.1 i hy] at xy
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.eq, equiv_iff G f hx hy]
    exact (g i).injective xy
  map_fun' F x := by
    obtain ⟨i, y, rfl⟩ := exists_quotient_mk'_sigma_mk'_eq G f x
    change _ = funMap F (Quotient.lift _ _ ∘ Quotient.mk _ ∘ Structure.Sigma.mk f i ∘ y)
    rw [funMap_quotient_mk'_sigma_mk', ← Function.comp.assoc, Quotient.lift_comp_mk]
    

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 ι
P : Type u₁
inst✝ : Structure L P
g : (i : ι) → G i ↪[L] P
Hg : ∀ (i j : ι) (hij : i ≤ j) (x : G i), (g j) ((f i j hij) x) = (g i) x
n✝ : ℕ
F : Functions L n✝
i : ι
y : Fin n✝ → G i
⊢ Function.Embedding.toFun
      {
        toFun :=
          Quotient.lift (fun x => (g x.fst) x.snd)
            (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y),
        inj' :=
          (_ :
            ∀ (x y : DirectLimit G f),
              Quotient.lift (fun x => (g x.fst) x.snd)
                    (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y) x =
                  Quotient.lift (fun x => (g x.fst) x.snd)
                    (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y) y →
                x = y) }
      ⟦Structure.Sigma.mk f i (funMap F fun a => y a)⟧ =
    funMap F ((fun x => (g x.fst) x.snd) ∘ Structure.Sigma.mk f i ∘ y)

Next tactic:
simp only [Quotient.lift_mk, Embedding.map_fun]
/-- The universal property of the direct limit: maps from the components to another module
that respect the directed system structure (i.e. make some diagram commute) give rise
to a unique map out of the direct limit. -/
def lift : DirectLimit G f ↪[L] P where
  toFun :=
    Quotient.lift (fun x : Σˣ f => (g x.1) x.2) fun x y xy => by
      simp only
      obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.1 y.1
      rw [← Hg x.1 i hx, ← Hg y.1 i hy]
      exact congr_arg _ ((equiv_iff ..).1 xy)
  inj' x y xy := by
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.lift_mk, Quotient.lift_mk] at xy
    obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.out.1 y.out.1
    rw [← Hg x.out.1 i hx, ← Hg y.out.1 i hy] at xy
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.eq, equiv_iff G f hx hy]
    exact (g i).injective xy
  map_fun' F x := by
    obtain ⟨i, y, rfl⟩ := exists_quotient_mk'_sigma_mk'_eq G f x
    change _ = funMap F (Quotient.lift _ _ ∘ Quotient.mk _ ∘ Structure.Sigma.mk f i ∘ y)
    rw [funMap_quotient_mk'_sigma_mk', ← Function.comp.assoc, Quotient.lift_comp_mk]
    simp only [Quotient.lift_mk, Embedding.map_fun]
    

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 ι
P : Type u₁
inst✝ : Structure L P
g : (i : ι) → G i ↪[L] P
Hg : ∀ (i j : ι) (hij : i ≤ j) (x : G i), (g j) ((f i j hij) x) = (g i) x
n✝ : ℕ
F : Functions L n✝
i : ι
y : Fin n✝ → G i
⊢ funMap F (⇑(g i) ∘ fun a => y a) = funMap F ((fun x => (g x.fst) x.snd) ∘ Structure.Sigma.mk f i ∘ y)

Next tactic:
rfl
/-- The universal property of the direct limit: maps from the components to another module
that respect the directed system structure (i.e. make some diagram commute) give rise
to a unique map out of the direct limit. -/
def lift : DirectLimit G f ↪[L] P where
  toFun :=
    Quotient.lift (fun x : Σˣ f => (g x.1) x.2) fun x y xy => by
      simp only
      obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.1 y.1
      rw [← Hg x.1 i hx, ← Hg y.1 i hy]
      exact congr_arg _ ((equiv_iff ..).1 xy)
  inj' x y xy := by
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.lift_mk, Quotient.lift_mk] at xy
    obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.out.1 y.out.1
    rw [← Hg x.out.1 i hx, ← Hg y.out.1 i hy] at xy
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.eq, equiv_iff G f hx hy]
    exact (g i).injective xy
  map_fun' F x := by
    obtain ⟨i, y, rfl⟩ := exists_quotient_mk'_sigma_mk'_eq G f x
    change _ = funMap F (Quotient.lift _ _ ∘ Quotient.mk _ ∘ Structure.Sigma.mk f i ∘ y)
    rw [funMap_quotient_mk'_sigma_mk', ← Function.comp.assoc, Quotient.lift_comp_mk]
    simp only [Quotient.lift_mk, Embedding.map_fun]
    rfl
  map_rel' 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 ι
P : Type u₁
inst✝ : Structure L P
g : (i : ι) → G i ↪[L] P
Hg : ∀ (i j : ι) (hij : i ≤ j) (x : G i), (g j) ((f i j hij) x) = (g i) x
n✝ : ℕ
R : Relations L n✝
x : Fin n✝ → DirectLimit G f
⊢ RelMap R
      ({
            toFun :=
              Quotient.lift (fun x => (g x.fst) x.snd)
                (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y),
            inj' :=
              (_ :
                ∀ (x y : DirectLimit G f),
                  Quotient.lift (fun x => (g x.fst) x.snd)
                        (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y) x =
                      Quotient.lift (fun x => (g x.fst) x.snd)
                        (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y) y →
                    x = y) }.toFun ∘
        x) ↔
    RelMap R x

Next tactic:
obtain ⟨i, y, rfl⟩ := exists_quotient_mk'_sigma_mk'_eq G f x
/-- The universal property of the direct limit: maps from the components to another module
that respect the directed system structure (i.e. make some diagram commute) give rise
to a unique map out of the direct limit. -/
def lift : DirectLimit G f ↪[L] P where
  toFun :=
    Quotient.lift (fun x : Σˣ f => (g x.1) x.2) fun x y xy => by
      simp only
      obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.1 y.1
      rw [← Hg x.1 i hx, ← Hg y.1 i hy]
      exact congr_arg _ ((equiv_iff ..).1 xy)
  inj' x y xy := by
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.lift_mk, Quotient.lift_mk] at xy
    obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.out.1 y.out.1
    rw [← Hg x.out.1 i hx, ← Hg y.out.1 i hy] at xy
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.eq, equiv_iff G f hx hy]
    exact (g i).injective xy
  map_fun' F x := by
    obtain ⟨i, y, rfl⟩ := exists_quotient_mk'_sigma_mk'_eq G f x
    change _ = funMap F (Quotient.lift _ _ ∘ Quotient.mk _ ∘ Structure.Sigma.mk f i ∘ y)
    rw [funMap_quotient_mk'_sigma_mk', ← Function.comp.assoc, Quotient.lift_comp_mk]
    simp only [Quotient.lift_mk, Embedding.map_fun]
    rfl
  map_rel' R x := by
    obtain ⟨i, y, rfl⟩ := exists_quotient_mk'_sigma_mk'_eq G f x
    

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 ι
P : Type u₁
inst✝ : Structure L P
g : (i : ι) → G i ↪[L] P
Hg : ∀ (i j : ι) (hij : i ≤ j) (x : G i), (g j) ((f i j hij) x) = (g i) x
n✝ : ℕ
R : Relations L n✝
i : ι
y : Fin n✝ → G i
⊢ RelMap R
      ({
            toFun :=
              Quotient.lift (fun x => (g x.fst) x.snd)
                (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y),
            inj' :=
              (_ :
                ∀ (x y : DirectLimit G f),
                  Quotient.lift (fun x => (g x.fst) x.snd)
                        (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y) x =
                      Quotient.lift (fun x => (g x.fst) x.snd)
                        (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y) y →
                    x = y) }.toFun ∘
        fun a => ⟦Structure.Sigma.mk f i (y a)⟧) ↔
    RelMap R fun a => ⟦Structure.Sigma.mk f i (y a)⟧

Next tactic:
change RelMap R (Quotient.lift _ _ ∘ Quotient.mk _ ∘ Structure.Sigma.mk f i ∘ y) ↔ _
/-- The universal property of the direct limit: maps from the components to another module
that respect the directed system structure (i.e. make some diagram commute) give rise
to a unique map out of the direct limit. -/
def lift : DirectLimit G f ↪[L] P where
  toFun :=
    Quotient.lift (fun x : Σˣ f => (g x.1) x.2) fun x y xy => by
      simp only
      obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.1 y.1
      rw [← Hg x.1 i hx, ← Hg y.1 i hy]
      exact congr_arg _ ((equiv_iff ..).1 xy)
  inj' x y xy := by
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.lift_mk, Quotient.lift_mk] at xy
    obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.out.1 y.out.1
    rw [← Hg x.out.1 i hx, ← Hg y.out.1 i hy] at xy
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.eq, equiv_iff G f hx hy]
    exact (g i).injective xy
  map_fun' F x := by
    obtain ⟨i, y, rfl⟩ := exists_quotient_mk'_sigma_mk'_eq G f x
    change _ = funMap F (Quotient.lift _ _ ∘ Quotient.mk _ ∘ Structure.Sigma.mk f i ∘ y)
    rw [funMap_quotient_mk'_sigma_mk', ← Function.comp.assoc, Quotient.lift_comp_mk]
    simp only [Quotient.lift_mk, Embedding.map_fun]
    rfl
  map_rel' R x := by
    obtain ⟨i, y, rfl⟩ := exists_quotient_mk'_sigma_mk'_eq G f x
    change RelMap R (Quotient.lift _ _ ∘ Quotient.mk _ ∘ Structure.Sigma.mk f i ∘ y) ↔ _
    

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 ι
P : Type u₁
inst✝ : Structure L P
g : (i : ι) → G i ↪[L] P
Hg : ∀ (i j : ι) (hij : i ≤ j) (x : G i), (g j) ((f i j hij) x) = (g i) x
n✝ : ℕ
R : Relations L n✝
i : ι
y : Fin n✝ → G i
⊢ RelMap R
      (Quotient.lift (fun x => (g x.fst) x.snd)
          (_ : ∀ (x y : Σˣ f), x ≈ y → (fun x => (g x.fst) x.snd) x = (fun x => (g x.fst) x.snd) y) ∘
        Quotient.mk (setoid G f) ∘ Structure.Sigma.mk f i ∘ y) ↔
    RelMap R fun a => ⟦Structure.Sigma.mk f i (y a)⟧

Next tactic:
rw [relMap_quotient_mk'_sigma_mk' G f, ← (g i).map_rel R y, ← Function.comp.assoc,
      Quotient.lift_comp_mk]
/-- The universal property of the direct limit: maps from the components to another module
that respect the directed system structure (i.e. make some diagram commute) give rise
to a unique map out of the direct limit. -/
def lift : DirectLimit G f ↪[L] P where
  toFun :=
    Quotient.lift (fun x : Σˣ f => (g x.1) x.2) fun x y xy => by
      simp only
      obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.1 y.1
      rw [← Hg x.1 i hx, ← Hg y.1 i hy]
      exact congr_arg _ ((equiv_iff ..).1 xy)
  inj' x y xy := by
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.lift_mk, Quotient.lift_mk] at xy
    obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.out.1 y.out.1
    rw [← Hg x.out.1 i hx, ← Hg y.out.1 i hy] at xy
    rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.eq, equiv_iff G f hx hy]
    exact (g i).injective xy
  map_fun' F x := by
    obtain ⟨i, y, rfl⟩ := exists_quotient_mk'_sigma_mk'_eq G f x
    change _ = funMap F (Quotient.lift _ _ ∘ Quotient.mk _ ∘ Structure.Sigma.mk f i ∘ y)
    rw [funMap_quotient_mk'_sigma_mk', ← Function.comp.assoc, Quotient.lift_comp_mk]
    simp only [Quotient.lift_mk, Embedding.map_fun]
    rfl
  map_rel' R x := by
    obtain ⟨i, y, rfl⟩ := exists_quotient_mk'_sigma_mk'_eq G f x
    change RelMap R (Quotient.lift _ _ ∘ Quotient.mk _ ∘ Structure.Sigma.mk f i ∘ y) ↔ _
    rw [relMap_quotient_mk'_sigma_mk' G f, ← (g i).map_rel R y, ← Function.comp.assoc,
      Quotient.lift_comp_mk]
    

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 ι
P : Type u₁
inst✝ : Structure L P
g : (i : ι) → G i ↪[L] P
Hg : ∀ (i j : ι) (hij : i ≤ j) (x : G i), (g j) ((f i j hij) x) = (g i) x
n✝ : ℕ
R : Relations L n✝
i : ι
y : Fin n✝ → G i
⊢ RelMap R ((fun x => (g x.fst) x.snd) ∘ Structure.Sigma.mk f i ∘ y) ↔ RelMap R (⇑(g i) ∘ y)

Next tactic:
rfl
@[simp]
theorem lift_quotient_mk'_sigma_mk' {i} (x : G i) : lift L ι G f g Hg ⟦.mk f i x⟧ = (g i) 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 ι
P : Type u₁
inst✝ : Structure L P
g : (i : ι) → G i ↪[L] P
Hg : ∀ (i j : ι) (hij : i ≤ j) (x : G i), (g j) ((f i j hij) x) = (g i) x
i : ι
x : G i
⊢ (lift L ι G f g Hg) ⟦Structure.Sigma.mk f i x⟧ = (g i) x

Next tactic:
change (lift L ι G f g Hg).toFun ⟦.mk f i x⟧ = _
@[simp]
theorem lift_quotient_mk'_sigma_mk' {i} (x : G i) : lift L ι G f g Hg ⟦.mk f i x⟧ = (g i) x := by
  change (lift L ι G f g Hg).toFun ⟦.mk f i x⟧ = _
  

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 ι
P : Type u₁
inst✝ : Structure L P
g : (i : ι) → G i ↪[L] P
Hg : ∀ (i j : ι) (hij : i ≤ j) (x : G i), (g j) ((f i j hij) x) = (g i) x
i : ι
x : G i
⊢ Function.Embedding.toFun (lift L ι G f g Hg).toEmbedding ⟦Structure.Sigma.mk f i x⟧ = (g i) x

Next tactic:
simp only [lift, Quotient.lift_mk]
theorem lift_of {i} (x : G i) : lift L ι G f g Hg (of L ι G f i x) = g i 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 ι
P : Type u₁
inst✝ : Structure L P
g : (i : ι) → G i ↪[L] P
Hg : ∀ (i j : ι) (hij : i ≤ j) (x : G i), (g j) ((f i j hij) x) = (g i) x
i : ι
x : G i
⊢ (lift L ι G f g Hg) ((of L ι G f i) x) = (g i) x

Next tactic:
simp
theorem lift_unique (F : DirectLimit G f ↪[L] P) (x) :
    F x =
      lift L ι G f (fun i => F.comp <| of L ι G f i)
        (fun i j hij 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 ι
P : Type u₁
inst✝ : Structure L P
g : (i : ι) → G i ↪[L] P
Hg : ∀ (i j : ι) (hij : i ≤ j) (x : G i), (g j) ((f i j hij) x) = (g i) x
F : DirectLimit G f ↪[L] P
x✝ : DirectLimit G f
i j : ι
hij : i ≤ j
x : G i
⊢ ((fun i => Embedding.comp F (of L ι G f i)) j) ((f i j hij) x) = ((fun i => Embedding.comp F (of L ι G f i)) i) x

Next tactic:
rw [F.comp_apply, F.comp_apply, of_f]
theorem lift_unique (F : DirectLimit G f ↪[L] P) (x) :
    F x =
      lift L ι G f (fun i => F.comp <| of L ι G f i)
        (fun i j hij x => by rw [F.comp_apply, F.comp_apply, of_f]) x :=
  DirectLimit.inductionOn x fun i 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 ι
P : Type u₁
inst✝ : Structure L P
g : (i : ι) → G i ↪[L] P
Hg : ∀ (i j : ι) (hij : i ≤ j) (x : G i), (g j) ((f i j hij) x) = (g i) x
F : DirectLimit G f ↪[L] P
x✝ : DirectLimit G f
i : ι
x : G i
⊢ F ((of L ι G f i) x) =
    (lift L ι G f (fun i => Embedding.comp F (of L ι G f i))
        (_ :
          ∀ (i j : ι) (hij : i ≤ j) (x : G i),
            ((fun i => Embedding.comp F (of L ι G f i)) j) ((f i j hij) x) =
              ((fun i => Embedding.comp F (of L ι G f i)) i) x))
      ((of L ι G f i) x)

Next tactic:
rw [lift_of]
theorem lift_unique (F : DirectLimit G f ↪[L] P) (x) :
    F x =
      lift L ι G f (fun i => F.comp <| of L ι G f i)
        (fun i j hij x => by rw [F.comp_apply, F.comp_apply, of_f]) x :=
  DirectLimit.inductionOn x fun i x => by rw [lift_of]; 

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 ι
P : Type u₁
inst✝ : Structure L P
g : (i : ι) → G i ↪[L] P
Hg : ∀ (i j : ι) (hij : i ≤ j) (x : G i), (g j) ((f i j hij) x) = (g i) x
F : DirectLimit G f ↪[L] P
x✝ : DirectLimit G f
i : ι
x : G i
⊢ F ((of L ι G f i) x) = (Embedding.comp F (of L ι G f i)) x

Next tactic:
rfl
/-- The direct limit of countably many countably generated structures is countably generated. -/
theorem cg {ι : Type*} [Encodable ι] [Preorder ι] [IsDirected ι (· ≤ ·)] [Nonempty ι]
    {G : ι → Type w} [∀ i, L.Structure (G i)] (f : ∀ i j, i ≤ j → G i ↪[L] G j)
    (h : ∀ i, Structure.CG L (G i)) [DirectedSystem G fun i j h => f i j h] :
    Structure.CG L (DirectLimit G f) := 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 ι✝
P : Type u₁
inst✝⁶ : Structure L P
g : (i : ι✝) → G✝ i ↪[L] P
Hg : ∀ (i j : ι✝) (hij : i ≤ j) (x : G✝ i), (g j) ((f✝ i j hij) x) = (g i) x
ι : Type u_1
inst✝⁵ : Encodable ι
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type w
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
h : ∀ (i : ι), CG L (G i)
inst✝ : DirectedSystem G fun i j h => ⇑(f i j h)
⊢ CG L (DirectLimit G f)

Next tactic:
refine' ⟨⟨⋃ i, DirectLimit.of L ι G f i '' Classical.choose (h i).out, _, _⟩⟩
/-- The direct limit of countably many countably generated structures is countably generated. -/
theorem cg {ι : Type*} [Encodable ι] [Preorder ι] [IsDirected ι (· ≤ ·)] [Nonempty ι]
    {G : ι → Type w} [∀ i, L.Structure (G i)] (f : ∀ i j, i ≤ j → G i ↪[L] G j)
    (h : ∀ i, Structure.CG L (G i)) [DirectedSystem G fun i j h => f i j h] :
    Structure.CG L (DirectLimit G f) := by
  refine' ⟨⟨⋃ i, DirectLimit.of L ι G f i '' Classical.choose (h i).out, _, _⟩⟩
  · 

Proof state:
case refine'_1
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 ι✝
P : Type u₁
inst✝⁶ : Structure L P
g : (i : ι✝) → G✝ i ↪[L] P
Hg : ∀ (i j : ι✝) (hij : i ≤ j) (x : G✝ i), (g j) ((f✝ i j hij) x) = (g i) x
ι : Type u_1
inst✝⁵ : Encodable ι
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type w
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
h : ∀ (i : ι), CG L (G i)
inst✝ : DirectedSystem G fun i j h => ⇑(f i j h)
⊢ Set.Countable (⋃ i, ⇑(of L ι G f i) '' Classical.choose (_ : Substructure.CG ⊤))

Next tactic:
exact Set.countable_iUnion fun i => Set.Countable.image (Classical.choose_spec (h i).out).1 _
/-- The direct limit of countably many countably generated structures is countably generated. -/
theorem cg {ι : Type*} [Encodable ι] [Preorder ι] [IsDirected ι (· ≤ ·)] [Nonempty ι]
    {G : ι → Type w} [∀ i, L.Structure (G i)] (f : ∀ i j, i ≤ j → G i ↪[L] G j)
    (h : ∀ i, Structure.CG L (G i)) [DirectedSystem G fun i j h => f i j h] :
    Structure.CG L (DirectLimit G f) := by
  refine' ⟨⟨⋃ i, DirectLimit.of L ι G f i '' Classical.choose (h i).out, _, _⟩⟩
  · exact Set.countable_iUnion fun i => Set.Countable.image (Classical.choose_spec (h i).out).1 _
  · 

Proof state:
case refine'_2
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 ι✝
P : Type u₁
inst✝⁶ : Structure L P
g : (i : ι✝) → G✝ i ↪[L] P
Hg : ∀ (i j : ι✝) (hij : i ≤ j) (x : G✝ i), (g j) ((f✝ i j hij) x) = (g i) x
ι : Type u_1
inst✝⁵ : Encodable ι
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type w
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
h : ∀ (i : ι), CG L (G i)
inst✝ : DirectedSystem G fun i j h => ⇑(f i j h)
⊢ LowerAdjoint.toFun (Substructure.closure L) (⋃ i, ⇑(of L ι G f i) '' Classical.choose (_ : Substructure.CG ⊤)) = ⊤

Next tactic:
rw [eq_top_iff, Substructure.closure_unionᵢ]