@@ -61,9 +61,27 @@ structure subgraph {V : Type u} (G : simple_graph V) :=
61
61
(edge_vert : ∀ {v w : V}, adj v w → v ∈ verts)
62
62
(symm : symmetric adj . obviously)
63
63
64
+ variables {V : Type u} {W : Type v}
65
+
66
+ /-- The one-vertex subgraph. -/
67
+ @[simps]
68
+ protected def singleton_subgraph (G : simple_graph V) (v : V) : G.subgraph :=
69
+ { verts := {v},
70
+ adj := ⊥,
71
+ adj_sub := by simp [-set.bot_eq_empty],
72
+ edge_vert := by simp [-set.bot_eq_empty] }
73
+
74
+ /-- The one-edge subgraph. -/
75
+ @[simps]
76
+ def subgraph_of_adj (G : simple_graph V) {v w : V} (hvw : G.adj v w) : G.subgraph :=
77
+ { verts := {v, w},
78
+ adj := λ a b, ⟦(v, w)⟧ = ⟦(a, b)⟧,
79
+ adj_sub := λ a b h, by { rw [← G.mem_edge_set, ← h], exact hvw },
80
+ edge_vert := λ a b h, by { apply_fun (λ e, a ∈ e) at h, simpa using h } }
81
+
64
82
namespace subgraph
65
83
66
- variables {V : Type u} {W : Type v} { G : simple_graph V}
84
+ variables {G : simple_graph V}
67
85
68
86
protected lemma loopless (G' : subgraph G) : irreflexive G'.adj :=
69
87
λ v h, G.loopless v (G'.adj_sub h)
@@ -75,6 +93,16 @@ lemma adj_comm (G' : subgraph G) (v w : V) : G'.adj v w ↔ G'.adj w v :=
75
93
76
94
protected lemma adj.symm {G' : subgraph G} {u v : V} (h : G'.adj u v) : G'.adj v u := G'.symm h
77
95
96
+ protected lemma adj.adj_sub {H : G.subgraph} {u v : V} (h : H.adj u v) : G.adj u v := H.adj_sub h
97
+
98
+ protected lemma adj.fst_mem {H : G.subgraph} {u v : V} (h : H.adj u v) : u ∈ H.verts :=
99
+ H.edge_vert h
100
+
101
+ protected lemma adj.snd_mem {H : G.subgraph} {u v : V} (h : H.adj u v) : v ∈ H.verts :=
102
+ h.symm.fst_mem
103
+
104
+ protected lemma adj.ne {H : G.subgraph} {u v : V} (h : H.adj u v) : u ≠ v := h.adj_sub.ne
105
+
78
106
/-- Coercion from `G' : subgraph G` to a `simple_graph ↥G'.verts`. -/
79
107
@[simps] protected def coe (G' : subgraph G) : simple_graph G'.verts :=
80
108
{ adj := λ v w, G'.adj v w,
@@ -84,6 +112,10 @@ protected lemma adj.symm {G' : subgraph G} {u v : V} (h : G'.adj u v) : G'.adj v
84
112
@[simp] lemma coe_adj_sub (G' : subgraph G) (u v : G'.verts) (h : G'.coe.adj u v) : G.adj u v :=
85
113
G'.adj_sub h
86
114
115
+ /- Given `h : H.adj u v`, then `h.coe : H.coe.adj ⟨u, _⟩ ⟨v, _⟩`. -/
116
+ protected lemma adj.coe {H : G.subgraph} {u v : V} (h : H.adj u v) :
117
+ H.coe.adj ⟨u, H.edge_vert h⟩ ⟨v, H.edge_vert h.symm⟩ := h
118
+
87
119
/-- A subgraph is called a *spanning subgraph* if it contains all the vertices of `G`. --/
88
120
def is_spanning (G' : subgraph G) : Prop := ∀ (v : V), v ∈ G'.verts
89
121
@@ -493,7 +525,135 @@ begin
493
525
simp only [set.mem_to_finset, mem_neighbor_set],
494
526
end
495
527
496
- /-! ## Subgraphs of subgraphs -/
528
+ end subgraph
529
+
530
+ section mk_properties
531
+ /-! ### Properties of `singleton_subgraph` and `subgraph_of_adj` -/
532
+
533
+ variables {G : simple_graph V} {G' : simple_graph W}
534
+
535
+ instance nonempty_singleton_subgraph_verts (v : V) : nonempty (G.singleton_subgraph v).verts :=
536
+ ⟨⟨v, set.mem_singleton v⟩⟩
537
+
538
+ @[simp] lemma singleton_subgraph_le_iff (v : V) (H : G.subgraph) :
539
+ G.singleton_subgraph v ≤ H ↔ v ∈ H.verts :=
540
+ begin
541
+ refine ⟨λ h, h.1 (set.mem_singleton v), _⟩,
542
+ intro h,
543
+ split,
544
+ { simp [h] },
545
+ { simp [-set.bot_eq_empty] }
546
+ end
547
+
548
+ @[simp] lemma map_singleton_subgraph (f : G →g G') {v : V} :
549
+ subgraph.map f (G.singleton_subgraph v) = G'.singleton_subgraph (f v) :=
550
+ by ext; simp only [relation.map, subgraph.map_adj, singleton_subgraph_adj, pi.bot_apply,
551
+ exists_and_distrib_left, and_iff_left_iff_imp, is_empty.forall_iff, subgraph.map_verts,
552
+ singleton_subgraph_verts, set.image_singleton]
553
+
554
+ @[simp] lemma neighbor_set_singleton_subgraph (v w : V) :
555
+ (G.singleton_subgraph v).neighbor_set w = ∅ :=
556
+ by { ext u, refl }
557
+
558
+ @[simp] lemma edge_set_singleton_subgraph (v : V) :
559
+ (G.singleton_subgraph v).edge_set = ∅ :=
560
+ sym2.from_rel_bot
561
+
562
+ lemma eq_singleton_subgraph_iff_verts_eq (H : G.subgraph) {v : V} :
563
+ H = G.singleton_subgraph v ↔ H.verts = {v} :=
564
+ begin
565
+ refine ⟨λ h, by simp [h], λ h, _⟩,
566
+ ext,
567
+ { rw [h, singleton_subgraph_verts] },
568
+ { simp only [Prop .bot_eq_false, singleton_subgraph_adj, pi.bot_apply, iff_false],
569
+ intro ha,
570
+ have ha1 := ha.fst_mem,
571
+ have ha2 := ha.snd_mem,
572
+ rw [h, set.mem_singleton_iff] at ha1 ha2,
573
+ subst_vars,
574
+ exact ha.ne rfl },
575
+ end
576
+
577
+ instance nonempty_subgraph_of_adj_verts {v w : V} (hvw : G.adj v w) :
578
+ nonempty (G.subgraph_of_adj hvw).verts := ⟨⟨v, by simp⟩⟩
579
+
580
+ @[simp] lemma edge_set_subgraph_of_adj {v w : V} (hvw : G.adj v w) :
581
+ (G.subgraph_of_adj hvw).edge_set = {⟦(v, w)⟧} :=
582
+ begin
583
+ ext e,
584
+ refine e.ind _,
585
+ simp only [eq_comm, set.mem_singleton_iff, subgraph.mem_edge_set, subgraph_of_adj_adj,
586
+ iff_self, forall_2_true_iff],
587
+ end
588
+
589
+ lemma subgraph_of_adj_symm {v w : V} (hvw : G.adj v w) :
590
+ G.subgraph_of_adj hvw.symm = G.subgraph_of_adj hvw :=
591
+ by ext; simp [or_comm, and_comm]
592
+
593
+ @[simp] lemma map_subgraph_of_adj (f : G →g G')
594
+ {v w : V} (hvw : G.adj v w) :
595
+ subgraph.map f (G.subgraph_of_adj hvw) = G'.subgraph_of_adj (f.map_adj hvw) :=
596
+ begin
597
+ ext,
598
+ { simp only [subgraph.map_verts, subgraph_of_adj_verts, set.mem_image,
599
+ set.mem_insert_iff, set.mem_singleton_iff],
600
+ split,
601
+ { rintro ⟨u, rfl|rfl, rfl⟩; simp },
602
+ { rintro (rfl|rfl),
603
+ { use v, simp },
604
+ { use w, simp } } },
605
+ { simp only [relation.map, subgraph.map_adj, subgraph_of_adj_adj, quotient.eq, sym2.rel_iff],
606
+ split,
607
+ { rintro ⟨a, b, (⟨rfl,rfl⟩|⟨rfl,rfl⟩), rfl, rfl⟩; simp },
608
+ { rintro (⟨rfl,rfl⟩|⟨rfl,rfl⟩),
609
+ { use [v, w], simp },
610
+ { use [w, v], simp } } }
611
+ end
612
+
613
+ lemma neighbor_set_subgraph_of_adj_subset {u v w : V} (hvw : G.adj v w) :
614
+ (G.subgraph_of_adj hvw).neighbor_set u ⊆ {v, w} :=
615
+ (G.subgraph_of_adj hvw).neighbor_set_subset_verts _
616
+
617
+ @[simp] lemma neighbor_set_fst_subgraph_of_adj {v w : V} (hvw : G.adj v w) :
618
+ (G.subgraph_of_adj hvw).neighbor_set v = {w} :=
619
+ begin
620
+ ext u,
621
+ suffices : w = u ↔ u = w, by simpa [hvw.ne.symm] using this ,
622
+ rw eq_comm,
623
+ end
624
+
625
+ @[simp] lemma neighbor_set_snd_subgraph_of_adj {v w : V} (hvw : G.adj v w) :
626
+ (G.subgraph_of_adj hvw).neighbor_set w = {v} :=
627
+ begin
628
+ rw subgraph_of_adj_symm hvw.symm,
629
+ exact neighbor_set_fst_subgraph_of_adj hvw.symm,
630
+ end
631
+
632
+ @[simp] lemma neighbor_set_subgraph_of_adj_of_ne_of_ne {u v w : V} (hvw : G.adj v w)
633
+ (hv : u ≠ v) (hw : u ≠ w) :
634
+ (G.subgraph_of_adj hvw).neighbor_set u = ∅ :=
635
+ by { ext, simp [hv.symm, hw.symm] }
636
+
637
+ lemma neighbor_set_subgraph_of_adj [decidable_eq V] {u v w : V} (hvw : G.adj v w) :
638
+ (G.subgraph_of_adj hvw).neighbor_set u =
639
+ (if u = v then {w} else ∅) ∪ (if u = w then {v} else ∅) :=
640
+ by split_ifs; subst_vars; simp [*]
641
+
642
+ lemma singleton_subgraph_fst_le_subgraph_of_adj {u v : V} {h : G.adj u v} :
643
+ G.singleton_subgraph u ≤ G.subgraph_of_adj h :=
644
+ by split; simp [-set.bot_eq_empty]
645
+
646
+ lemma singleton_subgraph_snd_le_subgraph_of_adj {u v : V} {h : G.adj u v} :
647
+ G.singleton_subgraph v ≤ G.subgraph_of_adj h :=
648
+ by split; simp [-set.bot_eq_empty]
649
+
650
+ end mk_properties
651
+
652
+ namespace subgraph
653
+
654
+ variables {G : simple_graph V}
655
+
656
+ /-! ### Subgraphs of subgraphs -/
497
657
498
658
/-- Given a subgraph of a subgraph of `G`, construct a subgraph of `G`. -/
499
659
@[reducible]
@@ -519,7 +679,7 @@ lemma coe_subgraph_injective (G' : G.subgraph) :
519
679
function.injective (subgraph.coe_subgraph : G'.coe.subgraph → G.subgraph) :=
520
680
function.left_inverse.injective restrict_coe_subgraph
521
681
522
- /-! ## Edge deletion -/
682
+ /-! ### Edge deletion -/
523
683
524
684
/-- Given a subgraph `G'` and a set of vertex pairs, remove all of the corresponding edges
525
685
from its edge set, if present.
@@ -602,7 +762,7 @@ spanning_coe_le_of_le (delete_edges_le s)
602
762
603
763
end delete_edges
604
764
605
- /-! ## Induced subgraphs -/
765
+ /-! ### Induced subgraphs -/
606
766
607
767
/- Given a subgraph, we can change its vertex set while removing any invalid edges, which
608
768
gives induced subgraphs. See also `simple_graph.induce` for the `simple_graph` version, which,
@@ -652,6 +812,25 @@ begin
652
812
exact λ ha, ⟨G'.edge_vert ha, G'.edge_vert ha.symm⟩ }
653
813
end
654
814
815
+ lemma singleton_subgraph_eq_induce {v : V} :
816
+ G.singleton_subgraph v = (⊤ : G.subgraph).induce {v} :=
817
+ by ext; simp [-set.bot_eq_empty, Prop .bot_eq_false] { contextual := tt }
818
+
819
+ lemma subgraph_of_adj_eq_induce {v w : V} (hvw : G.adj v w) :
820
+ G.subgraph_of_adj hvw = (⊤ : G.subgraph).induce {v, w} :=
821
+ begin
822
+ ext,
823
+ { simp },
824
+ { split,
825
+ { intro h,
826
+ simp only [subgraph_of_adj_adj, quotient.eq, sym2.rel_iff] at h,
827
+ obtain ⟨rfl, rfl⟩|⟨rfl, rfl⟩ := h; simp [hvw, hvw.symm], },
828
+ { intro h,
829
+ simp only [induce_adj, set.mem_insert_iff, set.mem_singleton_iff, top_adj_iff] at h,
830
+ obtain ⟨rfl|rfl, rfl|rfl, ha⟩ := h;
831
+ exact (ha.ne rfl).elim <|> simp } }
832
+ end
833
+
655
834
end induce
656
835
657
836
/-- Given a subgraph and a set of vertices, delete all the vertices from the subgraph,
0 commit comments