l3lab/ntp-mathlib huggingface dataset:
/-- If every finite subgraph of a graph `G` has a homomorphism to a finite graph `F`, then there is
a homomorphism from the whole of `G` to `F`. -/
theorem nonempty_hom_of_forall_finite_subgraph_hom [Finite W]
    (h : ∀ G' : G.Subgraph, G'.verts.Finite → G'.coe →g F) : Nonempty (G →g F) := by
  -- Obtain a `Fintype` instance for `W`.
  cases nonempty_fintype W
  -- Establish the required interface instances.
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Nonempty ((finsubgraphHomFunctor G F).obj G') := fun G' =>
    ⟨h G'.unop G'.unop.property⟩
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Fintype ((finsubgraphHomFunctor G F).obj G') := by
    intro G'
    haveI : Fintype (G'.unop.val.verts : Type u) := G'.unop.property.fintype
    haveI : Fintype (↥G'.unop.val.verts → W) := by classical exact Pi.fintype
    exact Fintype.ofInjective (fun f => f.toFun) RelHom.coe_fn_injective
  -- Use compactness to obtain a section.
  obtain ⟨u, hu⟩ := nonempty_sections_of_finite_inverse_system (finsubgraphHomFunctor G F)
  refine' ⟨⟨fun v => _, _⟩⟩
  · -- Map each vertex using the homomorphism provided for its singleton subgraph.
    exact
      (u (Opposite.op (singletonFinsubgraph v))).toFun
        ⟨v, by
          

Proof state:
V : Type u
W : Type v
G : SimpleGraph V
F : SimpleGraph W
inst✝ : Finite W
h : (G' : Subgraph G) → Set.Finite G'.verts → Subgraph.coe G' →g F
val✝ : Fintype W
this✝ : ∀ (G' : (Finsubgraph G)ᵒᵖ), Nonempty ((finsubgraphHomFunctor G F).obj G')
this : (G' : (Finsubgraph G)ᵒᵖ) → Fintype ((finsubgraphHomFunctor G F).obj G')
u : (j : (Finsubgraph G)ᵒᵖ) → (finsubgraphHomFunctor G F).obj j
hu : u ∈ Functor.sections (finsubgraphHomFunctor G F)
v : V
⊢ v ∈ (↑(Opposite.op (singletonFinsubgraph v)).unop).verts

Next tactic:
unfold singletonFinsubgraph
/-- If every finite subgraph of a graph `G` has a homomorphism to a finite graph `F`, then there is
a homomorphism from the whole of `G` to `F`. -/
theorem nonempty_hom_of_forall_finite_subgraph_hom [Finite W]
    (h : ∀ G' : G.Subgraph, G'.verts.Finite → G'.coe →g F) : Nonempty (G →g F) := by
  -- Obtain a `Fintype` instance for `W`.
  cases nonempty_fintype W
  -- Establish the required interface instances.
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Nonempty ((finsubgraphHomFunctor G F).obj G') := fun G' =>
    ⟨h G'.unop G'.unop.property⟩
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Fintype ((finsubgraphHomFunctor G F).obj G') := by
    intro G'
    haveI : Fintype (G'.unop.val.verts : Type u) := G'.unop.property.fintype
    haveI : Fintype (↥G'.unop.val.verts → W) := by classical exact Pi.fintype
    exact Fintype.ofInjective (fun f => f.toFun) RelHom.coe_fn_injective
  -- Use compactness to obtain a section.
  obtain ⟨u, hu⟩ := nonempty_sections_of_finite_inverse_system (finsubgraphHomFunctor G F)
  refine' ⟨⟨fun v => _, _⟩⟩
  · -- Map each vertex using the homomorphism provided for its singleton subgraph.
    exact
      (u (Opposite.op (singletonFinsubgraph v))).toFun
        ⟨v, by
          unfold singletonFinsubgraph
          

Proof state:
V : Type u
W : Type v
G : SimpleGraph V
F : SimpleGraph W
inst✝ : Finite W
h : (G' : Subgraph G) → Set.Finite G'.verts → Subgraph.coe G' →g F
val✝ : Fintype W
this✝ : ∀ (G' : (Finsubgraph G)ᵒᵖ), Nonempty ((finsubgraphHomFunctor G F).obj G')
this : (G' : (Finsubgraph G)ᵒᵖ) → Fintype ((finsubgraphHomFunctor G F).obj G')
u : (j : (Finsubgraph G)ᵒᵖ) → (finsubgraphHomFunctor G F).obj j
hu : u ∈ Functor.sections (finsubgraphHomFunctor G F)
v : V
⊢ v ∈ (↑(Opposite.op { val := SimpleGraph.singletonSubgraph G v, property := (_ : Set.Finite {v}) }).unop).verts

Next tactic:
simp
/-- If every finite subgraph of a graph `G` has a homomorphism to a finite graph `F`, then there is
a homomorphism from the whole of `G` to `F`. -/
theorem nonempty_hom_of_forall_finite_subgraph_hom [Finite W]
    (h : ∀ G' : G.Subgraph, G'.verts.Finite → G'.coe →g F) : Nonempty (G →g F) := by
  -- Obtain a `Fintype` instance for `W`.
  cases nonempty_fintype W
  -- Establish the required interface instances.
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Nonempty ((finsubgraphHomFunctor G F).obj G') := fun G' =>
    ⟨h G'.unop G'.unop.property⟩
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Fintype ((finsubgraphHomFunctor G F).obj G') := by
    intro G'
    haveI : Fintype (G'.unop.val.verts : Type u) := G'.unop.property.fintype
    haveI : Fintype (↥G'.unop.val.verts → W) := by classical exact Pi.fintype
    exact Fintype.ofInjective (fun f => f.toFun) RelHom.coe_fn_injective
  -- Use compactness to obtain a section.
  obtain ⟨u, hu⟩ := nonempty_sections_of_finite_inverse_system (finsubgraphHomFunctor G F)
  refine' ⟨⟨fun v => _, _⟩⟩
  · -- Map each vertex using the homomorphism provided for its singleton subgraph.
    exact
      (u (Opposite.op (singletonFinsubgraph v))).toFun
        ⟨v, by
          unfold singletonFinsubgraph
          simp⟩
  · -- Prove that the above mapping preserves adjacency.
    

Proof state:
case intro.intro.refine'_2
V : Type u
W : Type v
G : SimpleGraph V
F : SimpleGraph W
inst✝ : Finite W
h : (G' : Subgraph G) → Set.Finite G'.verts → Subgraph.coe G' →g F
val✝ : Fintype W
this✝ : ∀ (G' : (Finsubgraph G)ᵒᵖ), Nonempty ((finsubgraphHomFunctor G F).obj G')
this : (G' : (Finsubgraph G)ᵒᵖ) → Fintype ((finsubgraphHomFunctor G F).obj G')
u : (j : (Finsubgraph G)ᵒᵖ) → (finsubgraphHomFunctor G F).obj j
hu : u ∈ Functor.sections (finsubgraphHomFunctor G F)
⊢ ∀ {a b : V},
    Adj G a b →
      Adj F
        ((fun v =>
            RelHom.toFun (u (Opposite.op (singletonFinsubgraph v)))
              { val := v, property := (_ : v ∈ (↑(Opposite.op (singletonFinsubgraph v)).unop).verts) })
          a)
        ((fun v =>
            RelHom.toFun (u (Opposite.op (singletonFinsubgraph v)))
              { val := v, property := (_ : v ∈ (↑(Opposite.op (singletonFinsubgraph v)).unop).verts) })
          b)

Next tactic:
intro v v' e
/-- If every finite subgraph of a graph `G` has a homomorphism to a finite graph `F`, then there is
a homomorphism from the whole of `G` to `F`. -/
theorem nonempty_hom_of_forall_finite_subgraph_hom [Finite W]
    (h : ∀ G' : G.Subgraph, G'.verts.Finite → G'.coe →g F) : Nonempty (G →g F) := by
  -- Obtain a `Fintype` instance for `W`.
  cases nonempty_fintype W
  -- Establish the required interface instances.
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Nonempty ((finsubgraphHomFunctor G F).obj G') := fun G' =>
    ⟨h G'.unop G'.unop.property⟩
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Fintype ((finsubgraphHomFunctor G F).obj G') := by
    intro G'
    haveI : Fintype (G'.unop.val.verts : Type u) := G'.unop.property.fintype
    haveI : Fintype (↥G'.unop.val.verts → W) := by classical exact Pi.fintype
    exact Fintype.ofInjective (fun f => f.toFun) RelHom.coe_fn_injective
  -- Use compactness to obtain a section.
  obtain ⟨u, hu⟩ := nonempty_sections_of_finite_inverse_system (finsubgraphHomFunctor G F)
  refine' ⟨⟨fun v => _, _⟩⟩
  · -- Map each vertex using the homomorphism provided for its singleton subgraph.
    exact
      (u (Opposite.op (singletonFinsubgraph v))).toFun
        ⟨v, by
          unfold singletonFinsubgraph
          simp⟩
  · -- Prove that the above mapping preserves adjacency.
    intro v v' e
    

Proof state:
case intro.intro.refine'_2
V : Type u
W : Type v
G : SimpleGraph V
F : SimpleGraph W
inst✝ : Finite W
h : (G' : Subgraph G) → Set.Finite G'.verts → Subgraph.coe G' →g F
val✝ : Fintype W
this✝ : ∀ (G' : (Finsubgraph G)ᵒᵖ), Nonempty ((finsubgraphHomFunctor G F).obj G')
this : (G' : (Finsubgraph G)ᵒᵖ) → Fintype ((finsubgraphHomFunctor G F).obj G')
u : (j : (Finsubgraph G)ᵒᵖ) → (finsubgraphHomFunctor G F).obj j
hu : u ∈ Functor.sections (finsubgraphHomFunctor G F)
v v' : V
e : Adj G v v'
⊢ Adj F
    ((fun v =>
        RelHom.toFun (u (Opposite.op (singletonFinsubgraph v)))
          { val := v, property := (_ : v ∈ (↑(Opposite.op (singletonFinsubgraph v)).unop).verts) })
      v)
    ((fun v =>
        RelHom.toFun (u (Opposite.op (singletonFinsubgraph v)))
          { val := v, property := (_ : v ∈ (↑(Opposite.op (singletonFinsubgraph v)).unop).verts) })
      v')

Next tactic:
simp only
/-- If every finite subgraph of a graph `G` has a homomorphism to a finite graph `F`, then there is
a homomorphism from the whole of `G` to `F`. -/
theorem nonempty_hom_of_forall_finite_subgraph_hom [Finite W]
    (h : ∀ G' : G.Subgraph, G'.verts.Finite → G'.coe →g F) : Nonempty (G →g F) := by
  -- Obtain a `Fintype` instance for `W`.
  cases nonempty_fintype W
  -- Establish the required interface instances.
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Nonempty ((finsubgraphHomFunctor G F).obj G') := fun G' =>
    ⟨h G'.unop G'.unop.property⟩
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Fintype ((finsubgraphHomFunctor G F).obj G') := by
    intro G'
    haveI : Fintype (G'.unop.val.verts : Type u) := G'.unop.property.fintype
    haveI : Fintype (↥G'.unop.val.verts → W) := by classical exact Pi.fintype
    exact Fintype.ofInjective (fun f => f.toFun) RelHom.coe_fn_injective
  -- Use compactness to obtain a section.
  obtain ⟨u, hu⟩ := nonempty_sections_of_finite_inverse_system (finsubgraphHomFunctor G F)
  refine' ⟨⟨fun v => _, _⟩⟩
  · -- Map each vertex using the homomorphism provided for its singleton subgraph.
    exact
      (u (Opposite.op (singletonFinsubgraph v))).toFun
        ⟨v, by
          unfold singletonFinsubgraph
          simp⟩
  · -- Prove that the above mapping preserves adjacency.
    intro v v' e
    simp only
    /- The homomorphism for each edge's singleton subgraph agrees with those for its source and
        target vertices. -/
    

Proof state:
case intro.intro.refine'_2
V : Type u
W : Type v
G : SimpleGraph V
F : SimpleGraph W
inst✝ : Finite W
h : (G' : Subgraph G) → Set.Finite G'.verts → Subgraph.coe G' →g F
val✝ : Fintype W
this✝ : ∀ (G' : (Finsubgraph G)ᵒᵖ), Nonempty ((finsubgraphHomFunctor G F).obj G')
this : (G' : (Finsubgraph G)ᵒᵖ) → Fintype ((finsubgraphHomFunctor G F).obj G')
u : (j : (Finsubgraph G)ᵒᵖ) → (finsubgraphHomFunctor G F).obj j
hu : u ∈ Functor.sections (finsubgraphHomFunctor G F)
v v' : V
e : Adj G v v'
⊢ Adj F
    (RelHom.toFun (u (Opposite.op (singletonFinsubgraph v)))
      { val := v, property := (_ : v ∈ (↑(Opposite.op (singletonFinsubgraph v)).unop).verts) })
    (RelHom.toFun (u (Opposite.op (singletonFinsubgraph v')))
      { val := v', property := (_ : v' ∈ (↑(Opposite.op (singletonFinsubgraph v')).unop).verts) })

Next tactic:
have hv : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v) :=
      Quiver.Hom.op (CategoryTheory.homOfLE singletonFinsubgraph_le_adj_left)
/-- If every finite subgraph of a graph `G` has a homomorphism to a finite graph `F`, then there is
a homomorphism from the whole of `G` to `F`. -/
theorem nonempty_hom_of_forall_finite_subgraph_hom [Finite W]
    (h : ∀ G' : G.Subgraph, G'.verts.Finite → G'.coe →g F) : Nonempty (G →g F) := by
  -- Obtain a `Fintype` instance for `W`.
  cases nonempty_fintype W
  -- Establish the required interface instances.
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Nonempty ((finsubgraphHomFunctor G F).obj G') := fun G' =>
    ⟨h G'.unop G'.unop.property⟩
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Fintype ((finsubgraphHomFunctor G F).obj G') := by
    intro G'
    haveI : Fintype (G'.unop.val.verts : Type u) := G'.unop.property.fintype
    haveI : Fintype (↥G'.unop.val.verts → W) := by classical exact Pi.fintype
    exact Fintype.ofInjective (fun f => f.toFun) RelHom.coe_fn_injective
  -- Use compactness to obtain a section.
  obtain ⟨u, hu⟩ := nonempty_sections_of_finite_inverse_system (finsubgraphHomFunctor G F)
  refine' ⟨⟨fun v => _, _⟩⟩
  · -- Map each vertex using the homomorphism provided for its singleton subgraph.
    exact
      (u (Opposite.op (singletonFinsubgraph v))).toFun
        ⟨v, by
          unfold singletonFinsubgraph
          simp⟩
  · -- Prove that the above mapping preserves adjacency.
    intro v v' e
    simp only
    /- The homomorphism for each edge's singleton subgraph agrees with those for its source and
        target vertices. -/
    have hv : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v) :=
      Quiver.Hom.op (CategoryTheory.homOfLE singletonFinsubgraph_le_adj_left)
    

Proof state:
case intro.intro.refine'_2
V : Type u
W : Type v
G : SimpleGraph V
F : SimpleGraph W
inst✝ : Finite W
h : (G' : Subgraph G) → Set.Finite G'.verts → Subgraph.coe G' →g F
val✝ : Fintype W
this✝ : ∀ (G' : (Finsubgraph G)ᵒᵖ), Nonempty ((finsubgraphHomFunctor G F).obj G')
this : (G' : (Finsubgraph G)ᵒᵖ) → Fintype ((finsubgraphHomFunctor G F).obj G')
u : (j : (Finsubgraph G)ᵒᵖ) → (finsubgraphHomFunctor G F).obj j
hu : u ∈ Functor.sections (finsubgraphHomFunctor G F)
v v' : V
e : Adj G v v'
hv : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v)
⊢ Adj F
    (RelHom.toFun (u (Opposite.op (singletonFinsubgraph v)))
      { val := v, property := (_ : v ∈ (↑(Opposite.op (singletonFinsubgraph v)).unop).verts) })
    (RelHom.toFun (u (Opposite.op (singletonFinsubgraph v')))
      { val := v', property := (_ : v' ∈ (↑(Opposite.op (singletonFinsubgraph v')).unop).verts) })

Next tactic:
have hv' : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v') :=
      Quiver.Hom.op (CategoryTheory.homOfLE singletonFinsubgraph_le_adj_right)
/-- If every finite subgraph of a graph `G` has a homomorphism to a finite graph `F`, then there is
a homomorphism from the whole of `G` to `F`. -/
theorem nonempty_hom_of_forall_finite_subgraph_hom [Finite W]
    (h : ∀ G' : G.Subgraph, G'.verts.Finite → G'.coe →g F) : Nonempty (G →g F) := by
  -- Obtain a `Fintype` instance for `W`.
  cases nonempty_fintype W
  -- Establish the required interface instances.
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Nonempty ((finsubgraphHomFunctor G F).obj G') := fun G' =>
    ⟨h G'.unop G'.unop.property⟩
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Fintype ((finsubgraphHomFunctor G F).obj G') := by
    intro G'
    haveI : Fintype (G'.unop.val.verts : Type u) := G'.unop.property.fintype
    haveI : Fintype (↥G'.unop.val.verts → W) := by classical exact Pi.fintype
    exact Fintype.ofInjective (fun f => f.toFun) RelHom.coe_fn_injective
  -- Use compactness to obtain a section.
  obtain ⟨u, hu⟩ := nonempty_sections_of_finite_inverse_system (finsubgraphHomFunctor G F)
  refine' ⟨⟨fun v => _, _⟩⟩
  · -- Map each vertex using the homomorphism provided for its singleton subgraph.
    exact
      (u (Opposite.op (singletonFinsubgraph v))).toFun
        ⟨v, by
          unfold singletonFinsubgraph
          simp⟩
  · -- Prove that the above mapping preserves adjacency.
    intro v v' e
    simp only
    /- The homomorphism for each edge's singleton subgraph agrees with those for its source and
        target vertices. -/
    have hv : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v) :=
      Quiver.Hom.op (CategoryTheory.homOfLE singletonFinsubgraph_le_adj_left)
    have hv' : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v') :=
      Quiver.Hom.op (CategoryTheory.homOfLE singletonFinsubgraph_le_adj_right)
    

Proof state:
case intro.intro.refine'_2
V : Type u
W : Type v
G : SimpleGraph V
F : SimpleGraph W
inst✝ : Finite W
h : (G' : Subgraph G) → Set.Finite G'.verts → Subgraph.coe G' →g F
val✝ : Fintype W
this✝ : ∀ (G' : (Finsubgraph G)ᵒᵖ), Nonempty ((finsubgraphHomFunctor G F).obj G')
this : (G' : (Finsubgraph G)ᵒᵖ) → Fintype ((finsubgraphHomFunctor G F).obj G')
u : (j : (Finsubgraph G)ᵒᵖ) → (finsubgraphHomFunctor G F).obj j
hu : u ∈ Functor.sections (finsubgraphHomFunctor G F)
v v' : V
e : Adj G v v'
hv : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v)
hv' : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v')
⊢ Adj F
    (RelHom.toFun (u (Opposite.op (singletonFinsubgraph v)))
      { val := v, property := (_ : v ∈ (↑(Opposite.op (singletonFinsubgraph v)).unop).verts) })
    (RelHom.toFun (u (Opposite.op (singletonFinsubgraph v')))
      { val := v', property := (_ : v' ∈ (↑(Opposite.op (singletonFinsubgraph v')).unop).verts) })

Next tactic:
rw [← hu hv, ← hu hv']
/-- If every finite subgraph of a graph `G` has a homomorphism to a finite graph `F`, then there is
a homomorphism from the whole of `G` to `F`. -/
theorem nonempty_hom_of_forall_finite_subgraph_hom [Finite W]
    (h : ∀ G' : G.Subgraph, G'.verts.Finite → G'.coe →g F) : Nonempty (G →g F) := by
  -- Obtain a `Fintype` instance for `W`.
  cases nonempty_fintype W
  -- Establish the required interface instances.
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Nonempty ((finsubgraphHomFunctor G F).obj G') := fun G' =>
    ⟨h G'.unop G'.unop.property⟩
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Fintype ((finsubgraphHomFunctor G F).obj G') := by
    intro G'
    haveI : Fintype (G'.unop.val.verts : Type u) := G'.unop.property.fintype
    haveI : Fintype (↥G'.unop.val.verts → W) := by classical exact Pi.fintype
    exact Fintype.ofInjective (fun f => f.toFun) RelHom.coe_fn_injective
  -- Use compactness to obtain a section.
  obtain ⟨u, hu⟩ := nonempty_sections_of_finite_inverse_system (finsubgraphHomFunctor G F)
  refine' ⟨⟨fun v => _, _⟩⟩
  · -- Map each vertex using the homomorphism provided for its singleton subgraph.
    exact
      (u (Opposite.op (singletonFinsubgraph v))).toFun
        ⟨v, by
          unfold singletonFinsubgraph
          simp⟩
  · -- Prove that the above mapping preserves adjacency.
    intro v v' e
    simp only
    /- The homomorphism for each edge's singleton subgraph agrees with those for its source and
        target vertices. -/
    have hv : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v) :=
      Quiver.Hom.op (CategoryTheory.homOfLE singletonFinsubgraph_le_adj_left)
    have hv' : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v') :=
      Quiver.Hom.op (CategoryTheory.homOfLE singletonFinsubgraph_le_adj_right)
    rw [← hu hv, ← hu hv']
    -- porting note: was `apply Hom.map_adj`
    

Proof state:
case intro.intro.refine'_2
V : Type u
W : Type v
G : SimpleGraph V
F : SimpleGraph W
inst✝ : Finite W
h : (G' : Subgraph G) → Set.Finite G'.verts → Subgraph.coe G' →g F
val✝ : Fintype W
this✝ : ∀ (G' : (Finsubgraph G)ᵒᵖ), Nonempty ((finsubgraphHomFunctor G F).obj G')
this : (G' : (Finsubgraph G)ᵒᵖ) → Fintype ((finsubgraphHomFunctor G F).obj G')
u : (j : (Finsubgraph G)ᵒᵖ) → (finsubgraphHomFunctor G F).obj j
hu : u ∈ Functor.sections (finsubgraphHomFunctor G F)
v v' : V
e : Adj G v v'
hv : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v)
hv' : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v')
⊢ Adj F
    (RelHom.toFun ((finsubgraphHomFunctor G F).map hv (u (Opposite.op (finsubgraphOfAdj e))))
      { val := v, property := (_ : v ∈ (↑(Opposite.op (singletonFinsubgraph v)).unop).verts) })
    (RelHom.toFun ((finsubgraphHomFunctor G F).map hv' (u (Opposite.op (finsubgraphOfAdj e))))
      { val := v', property := (_ : v' ∈ (↑(Opposite.op (singletonFinsubgraph v')).unop).verts) })

Next tactic:
refine' Hom.map_adj (u (Opposite.op (finsubgraphOfAdj e))) _
/-- If every finite subgraph of a graph `G` has a homomorphism to a finite graph `F`, then there is
a homomorphism from the whole of `G` to `F`. -/
theorem nonempty_hom_of_forall_finite_subgraph_hom [Finite W]
    (h : ∀ G' : G.Subgraph, G'.verts.Finite → G'.coe →g F) : Nonempty (G →g F) := by
  -- Obtain a `Fintype` instance for `W`.
  cases nonempty_fintype W
  -- Establish the required interface instances.
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Nonempty ((finsubgraphHomFunctor G F).obj G') := fun G' =>
    ⟨h G'.unop G'.unop.property⟩
  haveI : ∀ G' : G.Finsubgraphᵒᵖ, Fintype ((finsubgraphHomFunctor G F).obj G') := by
    intro G'
    haveI : Fintype (G'.unop.val.verts : Type u) := G'.unop.property.fintype
    haveI : Fintype (↥G'.unop.val.verts → W) := by classical exact Pi.fintype
    exact Fintype.ofInjective (fun f => f.toFun) RelHom.coe_fn_injective
  -- Use compactness to obtain a section.
  obtain ⟨u, hu⟩ := nonempty_sections_of_finite_inverse_system (finsubgraphHomFunctor G F)
  refine' ⟨⟨fun v => _, _⟩⟩
  · -- Map each vertex using the homomorphism provided for its singleton subgraph.
    exact
      (u (Opposite.op (singletonFinsubgraph v))).toFun
        ⟨v, by
          unfold singletonFinsubgraph
          simp⟩
  · -- Prove that the above mapping preserves adjacency.
    intro v v' e
    simp only
    /- The homomorphism for each edge's singleton subgraph agrees with those for its source and
        target vertices. -/
    have hv : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v) :=
      Quiver.Hom.op (CategoryTheory.homOfLE singletonFinsubgraph_le_adj_left)
    have hv' : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v') :=
      Quiver.Hom.op (CategoryTheory.homOfLE singletonFinsubgraph_le_adj_right)
    rw [← hu hv, ← hu hv']
    -- porting note: was `apply Hom.map_adj`
    refine' Hom.map_adj (u (Opposite.op (finsubgraphOfAdj e))) _
    -- `v` and `v'` are definitionally adjacent in `finsubgraphOfAdj e`
    

Proof state:
case intro.intro.refine'_2
V : Type u
W : Type v
G : SimpleGraph V
F : SimpleGraph W
inst✝ : Finite W
h : (G' : Subgraph G) → Set.Finite G'.verts → Subgraph.coe G' →g F
val✝ : Fintype W
this✝ : ∀ (G' : (Finsubgraph G)ᵒᵖ), Nonempty ((finsubgraphHomFunctor G F).obj G')
this : (G' : (Finsubgraph G)ᵒᵖ) → Fintype ((finsubgraphHomFunctor G F).obj G')
u : (j : (Finsubgraph G)ᵒᵖ) → (finsubgraphHomFunctor G F).obj j
hu : u ∈ Functor.sections (finsubgraphHomFunctor G F)
v v' : V
e : Adj G v v'
hv : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v)
hv' : Opposite.op (finsubgraphOfAdj e) ⟶ Opposite.op (singletonFinsubgraph v')
⊢ Adj (Subgraph.coe ↑(Opposite.op (finsubgraphOfAdj e)).unop)
    { val := v, property := (_ : v ∈ (↑(Opposite.op (finsubgraphOfAdj e)).unop).verts) }
    { val := v', property := (_ : v' ∈ (↑(Opposite.op (finsubgraphOfAdj e)).unop).verts) }

Next tactic:
simp [finsubgraphOfAdj]
theorem ext_iff : (∀ i j, M i j = N i j) ↔ M = N :=
  ⟨fun h => funext fun i => funext <| h i, fun h => by 

Proof state:
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
m' : o → Type u_5
n' : o → Type u_6
R : Type u_7
S : Type u_8
α : Type v
β : Type w
γ : Type u_9
M N : Matrix m n α
h : M = N
⊢ ∀ (i : m) (j : n), M i j = N i j

Next tactic:
simp [h]
@[ext]
theorem ext' : (∀ i, M i = N i) → M = N :=
  fun h => Matrix.ext <| fun i => by 

Proof state:
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
m' : o → Type u_5
n' : o → Type u_6
R : Type u_7
S : Type u_8
α : Type v
β : Type w
γ : Type u_9
M N : Matrix m n α
h : ∀ (i : m), M i = N i
i : m
⊢ ∀ (j : n), M i j = N i j

Next tactic:
simp[h]
@[simp]
theorem map_id (M : Matrix m n α) : M.map id = M := by
  

Proof state:
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
m' : o → Type u_5
n' : o → Type u_6
R : Type u_7
S : Type u_8
α : Type v
β : Type w
γ : Type u_9
M : Matrix m n α
⊢ map M id = M

Next tactic:
ext
@[simp]
theorem map_id (M : Matrix m n α) : M.map id = M := by
  ext
  

Proof state:
case a.h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
m' : o → Type u_5
n' : o → Type u_6
R : Type u_7
S : Type u_8
α : Type v
β : Type w
γ : Type u_9
M : Matrix m n α
i✝ : m
x✝ : n
⊢ map M id i✝ x✝ = M i✝ x✝

Next tactic:
rfl
@[simp]
theorem map_map {M : Matrix m n α} {β γ : Type*} {f : α → β} {g : β → γ} :
    (M.map f).map g = M.map (g ∘ f) := by
  

Proof state:
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
m' : o → Type u_5
n' : o → Type u_6
R : Type u_7
S : Type u_8
α : Type v
β✝ : Type w
γ✝ : Type u_9
M : Matrix m n α
β : Type u_10
γ : Type u_11
f : α → β
g : β → γ
⊢ map (map M f) g = map M (g ∘ f)

Next tactic:
ext
@[simp]
theorem map_map {M : Matrix m n α} {β γ : Type*} {f : α → β} {g : β → γ} :
    (M.map f).map g = M.map (g ∘ f) := by
  ext
  

Proof state:
case a.h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
m' : o → Type u_5
n' : o → Type u_6
R : Type u_7
S : Type u_8
α : Type v
β✝ : Type w
γ✝ : Type u_9
M : Matrix m n α
β : Type u_10
γ : Type u_11
f : α → β
g : β → γ
i✝ : m
x✝ : n
⊢ map (map M f) g i✝ x✝ = map M (g ∘ f) i✝ x✝

Next tactic:
rfl