@@ -357,108 +357,88 @@ lemma isTree_iff_minimal_connected : IsTree G ↔ Minimal Connected G := by
357357 simp only [edges_map, Hom.coe_ofLE, Sym2.map_id, List.map_id_fun, id_eq] at this
358358 simp [this, p.adj_of_mem_edges]
359359
360- set_option backward.isDefEq.respectTransparency false in
361- /--
362- Adding an edge to an acyclic graph preserves acyclicity if the endpoints are not reachable.
363- -/
360+ /-- Connecting two unreachable vertices by an edge preserves acyclicity. -/
361+ theorem IsAcyclic.isAcyclic_sup_fromEdgeSet_of_not_reachable {u v : V} (hnreach : ¬G.Reachable u v)
362+ (hacyc : G.IsAcyclic) : (G ⊔ fromEdgeSet {s(u, v)}).IsAcyclic := by
363+ grind [isAcyclic_iff_forall_edge_isBridge, IsBridge.sup_fromEdgeSet_of_not_reachable,
364+ edgeSet_sup, IsBridge.sup_fromEdgeSet_of_not_reachable_of_isBridge, edgeSet_fromEdgeSet]
365+
364366theorem isAcyclic_add_edge_iff_of_not_reachable (x y : V) (hxy : ¬ G.Reachable x y) :
365- (G ⊔ fromEdgeSet {s(x, y)}).IsAcyclic ↔ IsAcyclic G := by
366- refine ⟨fun h ↦ h.anti le_sup_left, fun hG ↦ ?_⟩
367- have x_ne_y : x ≠ y := fun c => (c ▸ hxy) (Reachable.refl y)
368- have h_add_remove : (G ⊔ fromEdgeSet {s(x, y)}) \ fromEdgeSet {s(x, y)} = G := by
369- simpa using fun h => hxy h.reachable
370- have h_bridge : (G ⊔ fromEdgeSet {s(x, y)}).IsBridge s(x, y) := by
371- simpa [isBridge_iff, x_ne_y, h_add_remove]
372- rw [isBridge_iff_adj_and_forall_cycle_notMem] at h_bridge
373- intro u c hc
374- let c' : G.Walk u u := Walk.transfer c G (fun e he ↦ by
375- have eneq : e ≠ s(x, y) := fun h => h_bridge.2 c hc (h ▸ he)
376- simpa [eneq] using Walk.edges_subset_edgeSet c he)
377- exact hG c' (Walk.IsCycle.transfer (qc := hc) ..)
367+ (G ⊔ fromEdgeSet {s(x, y)}).IsAcyclic ↔ IsAcyclic G :=
368+ ⟨.anti le_sup_left, .isAcyclic_sup_fromEdgeSet_of_not_reachable hxy⟩
369+
370+ /-- Adding an edge results in an acyclic graph iff the original graph was acyclic and
371+ the edge connects vertices that previously had no path between them. -/
372+ theorem isAcyclic_sup_fromEdgeSet_iff {u v : V} :
373+ (G ⊔ fromEdgeSet {s(u, v)}).IsAcyclic ↔
374+ G.IsAcyclic ∧ (G.Reachable u v → u = v ∨ G.Adj u v) := by
375+ by_cases huv : u = v
376+ · grind [sup_eq_left, fromEdgeSet_le, Sym2.mem_diagSet, Sym2.mk_isDiag_iff]
377+ by_cases hadj : G.Adj u v
378+ · grind [sup_eq_left, fromEdgeSet_le, mem_edgeSet]
379+ refine ⟨?_, fun ⟨hacyc, hreach⟩ ↦ hacyc.isAcyclic_sup_fromEdgeSet_of_not_reachable <| by grind⟩
380+ refine fun hacyc ↦ ⟨hacyc.anti le_sup_left, fun hreach ↦ False.elim ?_⟩
381+ have := isAcyclic_iff_forall_edge_isBridge.mp (e := s(u, v)) hacyc <| by simp [huv]
382+ refine isBridge_iff.mp this |>.right <| hreach.mono <| Eq.le <| Eq.symm ?_
383+ rw [sup_sdiff_right_self]
384+ exact deleteEdges_eq_self.mpr <| Set.disjoint_singleton_right.mpr hadj
378385
379386/--
380387The reachability relation of a maximal acyclic subgraph agrees with that of the larger graph.
381388-/
382389lemma reachable_eq_of_maximal_isAcyclic (F : SimpleGraph V)
383- (h : Maximal (fun H => H ≤ G ∧ H.IsAcyclic) F) : F.Reachable = G.Reachable := by
384- obtain ⟨hF : F ≤ G, hF' : F.IsAcyclic⟩ := h.prop
385- replace h : ∀ {H : SimpleGraph V}, H ≤ G ∧ H.IsAcyclic → F ≤ H → H ≤ F := h.le_of_ge
390+ (h : Maximal (fun H ↦ H ≤ G ∧ H.IsAcyclic) F) : F.Reachable = G.Reachable := by
386391 ext u v
387- refine ⟨fun h ↦ h.mono hF, ?_⟩
388- contrapose! h
389- obtain ⟨⟨p : G.Walk u v⟩, h : ¬ F.Reachable u v⟩ := h
390- let s : Set V := F.connectedComponentMk u
391- have hus : u ∈ s := ConnectedComponent.connectedComponentMk_mem
392- have hvs : v ∉ s := h ∘ (F.connectedComponentMk u).reachable_of_mem_supp hus
393- obtain ⟨⟨⟨u', v'⟩, huv : G.Adj u' v'⟩, -, hu : u' ∈ s, hv : v' ∉ s⟩ :=
394- p.exists_boundary_dart s hus hvs
395- suffices (F ⊔ fromEdgeSet {s(u', v')}).IsAcyclic by
396- refine ⟨F ⊔ fromEdgeSet {s(u', v')}, ⟨?_, this⟩, le_sup_left, ?_⟩
397- · have : G.Adj v' u' := G.symm huv
398- simp only [sup_le_iff, le_iff_adj, fromEdgeSet_adj, Set.mem_singleton_iff, Sym2.eq,
399- Sym2.rel_iff'] at hF ⊢
400- grind
401- · rw [le_iff_adj]
402- push_neg
403- refine ⟨u', v', ?_, fun hc ↦ ?_⟩
404- · simpa using Or.inr huv.ne
405- · have := (F.connectedComponentMk u).mem_supp_congr_adj hc
406- grind
407- suffices ¬ F.Reachable u' v' by rwa [isAcyclic_add_edge_iff_of_not_reachable u' v' this]
408- suffices F.connectedComponentMk u' = s by
409- rw [← ConnectedComponent.eq]
410- exact fun hc ↦ (hc ▸ this ▸ hv) ConnectedComponent.connectedComponentMk_mem
411- simp_rw [s, SetLike.coe, ConnectedComponent.supp_inj, ← ConnectedComponent.mem_supp_iff]
412- grind
392+ refine ⟨.mono h.prop.left, fun ⟨p⟩ ↦ ?_⟩
393+ by_contra
394+ let s : F.ConnectedComponent := .mk _ u
395+ have : v ∉ s := this ∘ s.reachable_of_mem_supp rfl
396+ have : ∃ d ∈ p.darts, d.fst ∈ s ∧ d.snd ∉ s := p.exists_boundary_dart s rfl this
397+ rcases this with ⟨⟨⟨u', v'⟩, huv⟩, _, hu, hv⟩
398+ have : ¬F.Reachable v' u' := mt ConnectedComponent.sound <| s.mem_supp_iff u' |>.mp hu ▸ hv
399+ suffices F ⊔ fromEdgeSet {s(v', u')} ≤ F by
400+ grind [Adj.reachable, sup_le_iff, le_iff_adj, fromEdgeSet_adj]
401+ refine h.le_of_ge ⟨?_, h.prop.right.isAcyclic_sup_fromEdgeSet_of_not_reachable this⟩ le_sup_left
402+ grind [Maximal, sup_le, le_iff_adj, fromEdgeSet_adj, huv.symm]
413403
414404set_option backward.isDefEq.respectTransparency false in
415405/-- A subgraph is maximal acyclic iff its reachability relation agrees with the larger graph. -/
416- theorem maximal_isAcyclic_iff_reachable_eq {F : SimpleGraph V} (hF : F ≤ G) (hF' : F.IsAcyclic) :
417- Maximal (fun H => H ≤ G ∧ H.IsAcyclic) F ↔ F.Reachable = G.Reachable := by
418- refine ⟨reachable_eq_of_maximal_isAcyclic F, fun h => ?_⟩
419- by_contra!
420- obtain ⟨F', hF'⟩ := exists_gt_of_not_maximal (P := fun H => H ≤ G ∧ H.IsAcyclic) ⟨hF, hF'⟩ this
421- obtain ⟨e, he⟩ := Set.exists_of_ssubset <| edgeSet_strict_mono hF'.1
422- have : (F ⊔ fromEdgeSet {e}).IsAcyclic := by
423- apply hF'.2 .2 .anti
424- refine sup_le_iff.mpr ⟨by grind, ?_⟩
425- rw [← F'.fromEdgeSet_edgeSet]
426- grind [fromEdgeSet_mono]
427- have F_sdiff_eq : (F ⊔ fromEdgeSet {e}) \ fromEdgeSet {e} = F := by
428- simpa using he.2
406+ theorem maximal_isAcyclic_iff_reachable_eq {F : SimpleGraph V} (hle : F ≤ G) (hF : F.IsAcyclic) :
407+ Maximal (fun F ↦ F ≤ G ∧ F.IsAcyclic) F ↔ F.Reachable = G.Reachable := by
408+ refine ⟨reachable_eq_of_maximal_isAcyclic F, fun h ↦ ?_⟩
409+ by_contra
410+ have ⟨H, hFH, hHG, hH⟩ := exists_gt_of_not_maximal ⟨hle, hF⟩ this
411+ have ⟨e, heH, heF⟩ := Set.exists_of_ssubset <| edgeSet_strict_mono hFH
429412 have h_bridge : (F ⊔ fromEdgeSet {e}).IsBridge e := by
430- apply isAcyclic_iff_forall_edge_isBridge.mp this
431- simp [F'.not_isDiag_of_mem_edgeSet he. 1 ]
432- simp only [IsBridge, F_sdiff_eq] at h_bridge
413+ refine isAcyclic_iff_forall_edge_isBridge.mp ?_ <| by simp [H.not_isDiag_of_mem_edgeSet heH]
414+ exact hH.anti <| sup_le_iff.mpr ⟨hFH.le, H.fromEdgeSet_le.mpr <| by grind⟩
415+ have : (F ⊔ fromEdgeSet {e}) \ fromEdgeSet {e} = F := by simpa using heF
433416 cases e
434- case h u v =>
435- simp only [Sym2.lift_mk] at h_bridge
436- suffices G.Reachable u v by exact (h ▸ h_bridge.2 ) this
437- apply Reachable.mono hF'.2 .1
438- apply Adj.reachable
439- simpa using he.1
417+ rw [isBridge_iff, this, h] at h_bridge
418+ exact h_bridge.right <| hHG heH |>.reachable
440419
441420/-- A subgraph of a connected graph is maximal acyclic iff it is a tree. -/
442421theorem Connected.maximal_le_isAcyclic_iff_isTree {T : SimpleGraph V} (hG : G.Connected)
443- (hT : T ≤ G) : Maximal (fun H => H ≤ G ∧ H.IsAcyclic) T ↔ T.IsTree := by
444- have : Nonempty V : = hG.nonempty
422+ (hT : T ≤ G) : Maximal (fun H ↦ H ≤ G ∧ H.IsAcyclic) T ↔ T.IsTree := by
423+ have := hG.nonempty
445424 refine ⟨fun h ↦ ⟨⟨fun u v ↦ ?_⟩, h.1 .2 ⟩, fun hT' ↦ ?_⟩
446- · rw [G.reachable_eq_of_maximal_isAcyclic T h]
447- exact hG.preconnected u v
448- · rw [maximal_isAcyclic_iff_reachable_eq hT hT'.IsAcyclic]
449- replace hT' : T.Reachable = ⊤ := by
450- rw [← preconnected_iff_reachable_eq_top]
451- exact hT'.isConnected.preconnected
452- replace hG : G.Reachable = ⊤ := by
453- rw [← preconnected_iff_reachable_eq_top]
454- exact hG.preconnected
455- rw [hT', hG]
425+ · exact G.reachable_eq_of_maximal_isAcyclic T h ▸ hG.preconnected u v
426+ · rw [maximal_isAcyclic_iff_reachable_eq hT hT'.IsAcyclic,
427+ T.preconnected_iff_reachable_eq_top.mp hT'.isConnected.preconnected,
428+ G.preconnected_iff_reachable_eq_top.mp hG.preconnected]
456429
457430@[simp]
458431theorem maximal_isAcyclic_iff_isTree [Nonempty V] {T : SimpleGraph V} :
459432 Maximal IsAcyclic T ↔ T.IsTree := by
460433 simp [← connected_top.maximal_le_isAcyclic_iff_isTree le_top]
461434
435+ /-- A maximally acyclic graph is a tree. This is similar to `maximal_isAcyclic_iff_isTree` except
436+ with `Nonempty V` as part of the iff rather than an assumption. -/
437+ theorem isTree_iff_maximal_isAcyclic : G.IsTree ↔ Nonempty V ∧ Maximal IsAcyclic G := by
438+ refine ⟨fun h ↦ ?_, fun ⟨_, h⟩ ↦ G.maximal_isAcyclic_iff_isTree.mp h⟩
439+ have := h.isConnected.nonempty
440+ exact ⟨this, G.maximal_isAcyclic_iff_isTree.mpr h⟩
441+
462442/-- Every acyclic subgraph can be extended to a spanning forest. -/
463443theorem exists_isAcyclic_reachable_eq_le_of_le_of_isAcyclic {H : SimpleGraph V} (hH_le : H ≤ G)
464444 (hH_isAcyclic : H.IsAcyclic) :
0 commit comments