-- Mathlib/ModelTheory/DirectLimit.lean
theorem exists_fg_substructure_in_Sigma (S : L.Substructure (DirectLimit G f)) (S_fg : S.FG) :
    ∃ i, ∃ T : L.Substructure (G i), T.map (of L ι G f i).toHom = S

Proof state:
case h
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → L.Structure (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x1 x2 => x1 ≤ x2
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
S : L.Substructure (DirectLimit G f)
S_fg : S.FG
A : Finset (DirectLimit G f)
A_closure : (Substructure.closure L).toFun ↑A = S
i : ι
y : { x // x ∈ A } → G i
eq_y : (fun a => ↑a) = fun a => ⟦Structure.Sigma.mk f i (y a)⟧
⊢ ∃ T, Substructure.map (of L ι G f i).toHom T = S

Tactic:
use Substructure.closure L (range y)

Result:
case h
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → L.Structure (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x1 x2 => x1 ≤ x2
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
S : L.Substructure (DirectLimit G f)
S_fg : S.FG
A : Finset (DirectLimit G f)
A_closure : (Substructure.closure L).toFun ↑A = S
i : ι
y : { x // x ∈ A } → G i
eq_y : (fun a => ↑a) = fun a => ⟦Structure.Sigma.mk f i (y a)⟧
⊢ Substructure.map (of L ι G f i).toHom ((Substructure.closure L).toFun (range y)) = S

Proof state:
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → L.Structure (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x1 x2 => x1 ≤ x2
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
S : L.Substructure (DirectLimit G f)
S_fg : S.FG
⊢ ∃ i T, Substructure.map (of L ι G f i).toHom T = S

Tactic:
let ⟨A, A_closure⟩ := S_fg

Result:
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → L.Structure (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x1 x2 => x1 ≤ x2
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
S : L.Substructure (DirectLimit G f)
S_fg : S.FG
A : Finset (DirectLimit G f)
A_closure : (Substructure.closure L).toFun ↑A = S
⊢ ∃ i T, Substructure.map (of L ι G f i).toHom T = S

Proof state:
case h
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → L.Structure (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x1 x2 => x1 ≤ x2
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
S : L.Substructure (DirectLimit G f)
S_fg : S.FG
A : Finset (DirectLimit G f)
A_closure : (Substructure.closure L).toFun ↑A = S
i : ι
y : { x // x ∈ A } → G i
eq_y : (fun a => ↑a) = fun a => ⟦Structure.Sigma.mk f i (y a)⟧
⊢ (Substructure.closure L).toFun ((fun a => ⟦Structure.Sigma.mk f i a⟧) '' range y) = S

Tactic:
rw [← image_univ, image_image, image_univ, ← eq_y,
  Subtype.range_coe_subtype, Finset.setOf_mem, A_closure]

Result:
no goals

Proof state:
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → L.Structure (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x1 x2 => x1 ≤ x2
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
S : L.Substructure (DirectLimit G f)
S_fg : S.FG
A : Finset (DirectLimit G f)
A_closure : (Substructure.closure L).toFun ↑A = S
i : ι
y : { x // x ∈ A } → G i
eq_y : (fun a => ↑a) = fun a => ⟦Structure.Sigma.mk f i (y a)⟧
⊢ ∃ i T, Substructure.map (of L ι G f i).toHom T = S

Tactic:
use i

Result:
case h
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → L.Structure (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x1 x2 => x1 ≤ x2
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
S : L.Substructure (DirectLimit G f)
S_fg : S.FG
A : Finset (DirectLimit G f)
A_closure : (Substructure.closure L).toFun ↑A = S
i : ι
y : { x // x ∈ A } → G i
eq_y : (fun a => ↑a) = fun a => ⟦Structure.Sigma.mk f i (y a)⟧
⊢ ∃ T, Substructure.map (of L ι G f i).toHom T = S

Proof state:
case h
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → L.Structure (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x1 x2 => x1 ≤ x2
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
S : L.Substructure (DirectLimit G f)
S_fg : S.FG
A : Finset (DirectLimit G f)
A_closure : (Substructure.closure L).toFun ↑A = S
i : ι
y : { x // x ∈ A } → G i
eq_y : (fun a => ↑a) = fun a => ⟦Structure.Sigma.mk f i (y a)⟧
⊢ Substructure.map (of L ι G f i).toHom ((Substructure.closure L).toFun (range y)) = S

Tactic:
rw [Substructure.map_closure]

Result:
case h
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → L.Structure (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x1 x2 => x1 ≤ x2
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
S : L.Substructure (DirectLimit G f)
S_fg : S.FG
A : Finset (DirectLimit G f)
A_closure : (Substructure.closure L).toFun ↑A = S
i : ι
y : { x // x ∈ A } → G i
eq_y : (fun a => ↑a) = fun a => ⟦Structure.Sigma.mk f i (y a)⟧
⊢ (Substructure.closure L).toFun (⇑(of L ι G f i).toHom '' range y) = S

Proof state:
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → L.Structure (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x1 x2 => x1 ≤ x2
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
S : L.Substructure (DirectLimit G f)
S_fg : S.FG
A : Finset (DirectLimit G f)
A_closure : (Substructure.closure L).toFun ↑A = S
⊢ ∃ i T, Substructure.map (of L ι G f i).toHom T = S

Tactic:
let ⟨i, y, eq_y⟩ := exists_quotient_mk'_sigma_mk'_eq G _ (fun a : A ↦ a.1)

Result:
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → L.Structure (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x1 x2 => x1 ≤ x2
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
S : L.Substructure (DirectLimit G f)
S_fg : S.FG
A : Finset (DirectLimit G f)
A_closure : (Substructure.closure L).toFun ↑A = S
i : ι
y : { x // x ∈ A } → G i
eq_y : (fun a => ↑a) = fun a => ⟦Structure.Sigma.mk f i (y a)⟧
⊢ ∃ i T, Substructure.map (of L ι G f i).toHom T = S

Proof state:
case h
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → L.Structure (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x1 x2 => x1 ≤ x2
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
S : L.Substructure (DirectLimit G f)
S_fg : S.FG
A : Finset (DirectLimit G f)
A_closure : (Substructure.closure L).toFun ↑A = S
i : ι
y : { x // x ∈ A } → G i
eq_y : (fun a => ↑a) = fun a => ⟦Structure.Sigma.mk f i (y a)⟧
⊢ (Substructure.closure L).toFun (⇑(of L ι G f i).toHom '' range y) = S

Tactic:
simp only [Embedding.coe_toHom, of_apply]

Result:
case h
L : Language
ι : Type v
inst✝⁴ : Preorder ι
G : ι → Type w
inst✝³ : (i : ι) → L.Structure (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝² : IsDirected ι fun x1 x2 => x1 ≤ x2
inst✝¹ : DirectedSystem G fun i j h => ⇑(f i j h)
inst✝ : Nonempty ι
S : L.Substructure (DirectLimit G f)
S_fg : S.FG
A : Finset (DirectLimit G f)
A_closure : (Substructure.closure L).toFun ↑A = S
i : ι
y : { x // x ∈ A } → G i
eq_y : (fun a => ↑a) = fun a => ⟦Structure.Sigma.mk f i (y a)⟧
⊢ (Substructure.closure L).toFun ((fun a => ⟦Structure.Sigma.mk f i a⟧) '' range y) = S