@@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
4
4
Authors: Kyle Miller
5
5
-/
6
6
import Mathlib.Combinatorics.SimpleGraph.Subgraph
7
- import Mathlib.Data.List.Rotate
8
7
9
8
#align_import combinatorics.simple_graph.connectivity from "leanprover-community/mathlib" @"b99e2d58a5e6861833fa8de11e51a81144258db4"
10
9
@@ -2395,260 +2394,8 @@ theorem Connected.set_univ_walk_nonempty (hconn : G.Connected) (u v : V) :
2395
2394
hconn.preconnected.set_univ_walk_nonempty u v
2396
2395
#align simple_graph.connected.set_univ_walk_nonempty SimpleGraph.Connected.set_univ_walk_nonempty
2397
2396
2398
-
2399
- /-! ### Walks as subgraphs -/
2400
-
2401
- namespace Walk
2402
-
2403
- variable {u v w : V}
2404
-
2405
- /-- The subgraph consisting of the vertices and edges of the walk. -/
2406
- @[simp]
2407
- protected def toSubgraph {u v : V} : G.Walk u v → G.Subgraph
2408
- | nil => G.singletonSubgraph u
2409
- | cons h p => G.subgraphOfAdj h ⊔ p.toSubgraph
2410
- #align simple_graph.walk.to_subgraph SimpleGraph.Walk.toSubgraph
2411
-
2412
- theorem toSubgraph_cons_nil_eq_subgraphOfAdj (h : G.Adj u v) :
2413
- (cons h nil).toSubgraph = G.subgraphOfAdj h := by simp
2414
- #align simple_graph.walk.to_subgraph_cons_nil_eq_subgraph_of_adj SimpleGraph.Walk.toSubgraph_cons_nil_eq_subgraphOfAdj
2415
-
2416
- theorem mem_verts_toSubgraph (p : G.Walk u v) : w ∈ p.toSubgraph.verts ↔ w ∈ p.support := by
2417
- induction' p with _ x y z h p' ih
2418
- · simp
2419
- · have : w = y ∨ w ∈ p'.support ↔ w ∈ p'.support :=
2420
- ⟨by rintro (rfl | h) <;> simp [*], by simp (config := { contextual := true })⟩
2421
- simp [ih, or_assoc, this]
2422
- #align simple_graph.walk.mem_verts_to_subgraph SimpleGraph.Walk.mem_verts_toSubgraph
2423
-
2424
- lemma start_mem_verts_toSubgraph (p : G.Walk u v) : u ∈ p.toSubgraph.verts := by
2425
- simp [mem_verts_toSubgraph]
2426
-
2427
- lemma end_mem_verts_toSubgraph (p : G.Walk u v) : v ∈ p.toSubgraph.verts := by
2428
- simp [mem_verts_toSubgraph]
2429
-
2430
- @[simp]
2431
- theorem verts_toSubgraph (p : G.Walk u v) : p.toSubgraph.verts = { w | w ∈ p.support } :=
2432
- Set.ext fun _ => p.mem_verts_toSubgraph
2433
- #align simple_graph.walk.verts_to_subgraph SimpleGraph.Walk.verts_toSubgraph
2434
-
2435
- theorem mem_edges_toSubgraph (p : G.Walk u v) {e : Sym2 V} :
2436
- e ∈ p.toSubgraph.edgeSet ↔ e ∈ p.edges := by induction p <;> simp [*]
2437
- #align simple_graph.walk.mem_edges_to_subgraph SimpleGraph.Walk.mem_edges_toSubgraph
2438
-
2439
- @[simp]
2440
- theorem edgeSet_toSubgraph (p : G.Walk u v) : p.toSubgraph.edgeSet = { e | e ∈ p.edges } :=
2441
- Set.ext fun _ => p.mem_edges_toSubgraph
2442
- #align simple_graph.walk.edge_set_to_subgraph SimpleGraph.Walk.edgeSet_toSubgraph
2443
-
2444
- @[simp]
2445
- theorem toSubgraph_append (p : G.Walk u v) (q : G.Walk v w) :
2446
- (p.append q).toSubgraph = p.toSubgraph ⊔ q.toSubgraph := by induction p <;> simp [*, sup_assoc]
2447
- #align simple_graph.walk.to_subgraph_append SimpleGraph.Walk.toSubgraph_append
2448
-
2449
- @[simp]
2450
- theorem toSubgraph_reverse (p : G.Walk u v) : p.reverse.toSubgraph = p.toSubgraph := by
2451
- induction p with
2452
- | nil => simp
2453
- | cons _ _ _ =>
2454
- simp only [*, Walk.toSubgraph, reverse_cons, toSubgraph_append, subgraphOfAdj_symm]
2455
- rw [sup_comm]
2456
- congr
2457
- ext <;> simp [-Set.bot_eq_empty]
2458
- #align simple_graph.walk.to_subgraph_reverse SimpleGraph.Walk.toSubgraph_reverse
2459
-
2460
- @[simp]
2461
- theorem toSubgraph_rotate [DecidableEq V] (c : G.Walk v v) (h : u ∈ c.support) :
2462
- (c.rotate h).toSubgraph = c.toSubgraph := by
2463
- rw [rotate, toSubgraph_append, sup_comm, ← toSubgraph_append, take_spec]
2464
- #align simple_graph.walk.to_subgraph_rotate SimpleGraph.Walk.toSubgraph_rotate
2465
-
2466
- @[simp]
2467
- theorem toSubgraph_map (f : G →g G') (p : G.Walk u v) :
2468
- (p.map f).toSubgraph = p.toSubgraph.map f := by induction p <;> simp [*, Subgraph.map_sup]
2469
- #align simple_graph.walk.to_subgraph_map SimpleGraph.Walk.toSubgraph_map
2470
-
2471
- @[simp]
2472
- theorem finite_neighborSet_toSubgraph (p : G.Walk u v) : (p.toSubgraph.neighborSet w).Finite := by
2473
- induction p with
2474
- | nil =>
2475
- rw [Walk.toSubgraph, neighborSet_singletonSubgraph]
2476
- apply Set.toFinite
2477
- | cons ha _ ih =>
2478
- rw [Walk.toSubgraph, Subgraph.neighborSet_sup]
2479
- refine Set.Finite.union ?_ ih
2480
- refine Set.Finite.subset ?_ (neighborSet_subgraphOfAdj_subset ha)
2481
- apply Set.toFinite
2482
- #align simple_graph.walk.finite_neighbor_set_to_subgraph SimpleGraph.Walk.finite_neighborSet_toSubgraph
2483
-
2484
- lemma toSubgraph_le_induce_support (p : G.Walk u v) :
2485
- p.toSubgraph ≤ (⊤ : G.Subgraph).induce {v | v ∈ p.support} := by
2486
- convert Subgraph.le_induce_top_verts
2487
- exact p.verts_toSubgraph.symm
2488
-
2489
- end Walk
2490
-
2491
-
2492
- /-! ### Walks of a given length -/
2493
-
2494
- section WalkCounting
2495
-
2496
- theorem set_walk_self_length_zero_eq (u : V) : {p : G.Walk u u | p.length = 0 } = {Walk.nil} := by
2497
- ext p
2498
- simp
2499
- #align simple_graph.set_walk_self_length_zero_eq SimpleGraph.set_walk_self_length_zero_eq
2500
-
2501
- theorem set_walk_length_zero_eq_of_ne {u v : V} (h : u ≠ v) :
2502
- {p : G.Walk u v | p.length = 0 } = ∅ := by
2503
- ext p
2504
- simp only [Set.mem_setOf_eq, Set.mem_empty_iff_false, iff_false_iff]
2505
- exact fun h' => absurd (Walk.eq_of_length_eq_zero h') h
2506
- #align simple_graph.set_walk_length_zero_eq_of_ne SimpleGraph.set_walk_length_zero_eq_of_ne
2507
-
2508
- theorem set_walk_length_succ_eq (u v : V) (n : ℕ) :
2509
- {p : G.Walk u v | p.length = n.succ} =
2510
- ⋃ (w : V) (h : G.Adj u w), Walk.cons h '' {p' : G.Walk w v | p'.length = n} := by
2511
- ext p
2512
- cases' p with _ _ w _ huw pwv
2513
- · simp [eq_comm]
2514
- · simp only [Nat.succ_eq_add_one, Set.mem_setOf_eq, Walk.length_cons, add_left_inj,
2515
- Set.mem_iUnion, Set.mem_image, exists_prop]
2516
- constructor
2517
- · rintro rfl
2518
- exact ⟨w, huw, pwv, rfl, rfl⟩
2519
- · rintro ⟨w, huw, pwv, rfl, rfl, rfl⟩
2520
- rfl
2521
- #align simple_graph.set_walk_length_succ_eq SimpleGraph.set_walk_length_succ_eq
2522
-
2523
- variable (G) [DecidableEq V]
2524
-
2525
- /-- Walks of length two from `u` to `v` correspond bijectively to common neighbours of `u` and `v`.
2526
- Note that `u` and `v` may be the same. -/
2527
- @[simps]
2528
- def walkLengthTwoEquivCommonNeighbors (u v : V) :
2529
- {p : G.Walk u v // p.length = 2 } ≃ G.commonNeighbors u v where
2530
- toFun p := ⟨p.val.getVert 1 , match p with
2531
- | ⟨.cons _ (.cons _ .nil), hp⟩ => ⟨‹G.Adj u _›, ‹G.Adj _ v›.symm⟩⟩
2532
- invFun w := ⟨w.prop.1 .toWalk.concat w.prop.2 .symm, rfl⟩
2533
- left_inv | ⟨.cons _ (.cons _ .nil), hp⟩ => by rfl
2534
- right_inv _ := rfl
2535
-
2536
- section LocallyFinite
2537
-
2538
- variable [LocallyFinite G]
2539
-
2540
- /-- The `Finset` of length-`n` walks from `u` to `v`.
2541
- This is used to give `{p : G.walk u v | p.length = n}` a `Fintype` instance, and it
2542
- can also be useful as a recursive description of this set when `V` is finite.
2543
-
2544
- See `SimpleGraph.coe_finsetWalkLength_eq` for the relationship between this `Finset` and
2545
- the set of length-`n` walks. -/
2546
- def finsetWalkLength (n : ℕ) (u v : V) : Finset (G.Walk u v) :=
2547
- match n with
2548
- | 0 =>
2549
- if h : u = v then by
2550
- subst u
2551
- exact {Walk.nil}
2552
- else ∅
2553
- | n + 1 =>
2554
- Finset.univ.biUnion fun (w : G.neighborSet u) =>
2555
- (finsetWalkLength n w v).map ⟨fun p => Walk.cons w.property p, fun _ _ => by simp⟩
2556
- #align simple_graph.finset_walk_length SimpleGraph.finsetWalkLength
2557
-
2558
- theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) :
2559
- (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by
2560
- induction' n with n ih generalizing u v
2561
- · obtain rfl | huv := eq_or_ne u v <;> simp [finsetWalkLength, set_walk_length_zero_eq_of_ne, *]
2562
- · simp only [finsetWalkLength, set_walk_length_succ_eq, Finset.coe_biUnion, Finset.mem_coe,
2563
- Finset.mem_univ, Set.iUnion_true]
2564
- ext p
2565
- simp only [mem_neighborSet, Finset.coe_map, Embedding.coeFn_mk, Set.iUnion_coe_set,
2566
- Set.mem_iUnion, Set.mem_image, Finset.mem_coe, Set.mem_setOf_eq]
2567
- congr!
2568
- rename_i w _ q
2569
- have := Set.ext_iff.mp (ih w v) q
2570
- simp only [Finset.mem_coe, Set.mem_setOf_eq] at this
2571
- rw [← this]
2572
- #align simple_graph.coe_finset_walk_length_eq SimpleGraph.coe_finsetWalkLength_eq
2573
-
2574
- variable {G}
2575
-
2576
- theorem Walk.mem_finsetWalkLength_iff_length_eq {n : ℕ} {u v : V} (p : G.Walk u v) :
2577
- p ∈ G.finsetWalkLength n u v ↔ p.length = n :=
2578
- Set.ext_iff.mp (G.coe_finsetWalkLength_eq n u v) p
2579
- #align simple_graph.walk.mem_finset_walk_length_iff_length_eq SimpleGraph.Walk.mem_finsetWalkLength_iff_length_eq
2580
-
2581
- variable (G)
2582
-
2583
- instance fintypeSetWalkLength (u v : V) (n : ℕ) : Fintype {p : G.Walk u v | p.length = n} :=
2584
- Fintype.ofFinset (G.finsetWalkLength n u v) fun p => by
2585
- rw [← Finset.mem_coe, coe_finsetWalkLength_eq]
2586
- #align simple_graph.fintype_set_walk_length SimpleGraph.fintypeSetWalkLength
2587
-
2588
- instance fintypeSubtypeWalkLength (u v : V) (n : ℕ) : Fintype {p : G.Walk u v // p.length = n} :=
2589
- fintypeSetWalkLength G u v n
2590
-
2591
- theorem set_walk_length_toFinset_eq (n : ℕ) (u v : V) :
2592
- {p : G.Walk u v | p.length = n}.toFinset = G.finsetWalkLength n u v := by
2593
- ext p
2594
- simp [← coe_finsetWalkLength_eq]
2595
- #align simple_graph.set_walk_length_to_finset_eq SimpleGraph.set_walk_length_toFinset_eq
2596
-
2597
- /- See `SimpleGraph.adjMatrix_pow_apply_eq_card_walk` for the cardinality in terms of the `n`th
2598
- power of the adjacency matrix. -/
2599
- theorem card_set_walk_length_eq (u v : V) (n : ℕ) :
2600
- Fintype.card {p : G.Walk u v | p.length = n} = (G.finsetWalkLength n u v).card :=
2601
- Fintype.card_ofFinset (G.finsetWalkLength n u v) fun p => by
2602
- rw [← Finset.mem_coe, coe_finsetWalkLength_eq]
2603
- #align simple_graph.card_set_walk_length_eq SimpleGraph.card_set_walk_length_eq
2604
-
2605
- instance fintypeSetPathLength (u v : V) (n : ℕ) :
2606
- Fintype {p : G.Walk u v | p.IsPath ∧ p.length = n} :=
2607
- Fintype.ofFinset ((G.finsetWalkLength n u v).filter Walk.IsPath) <| by
2608
- simp [Walk.mem_finsetWalkLength_iff_length_eq, and_comm]
2609
- #align simple_graph.fintype_set_path_length SimpleGraph.fintypeSetPathLength
2610
-
2611
- end LocallyFinite
2612
-
2613
- section Finite
2614
-
2615
- variable [Fintype V] [DecidableRel G.Adj]
2616
-
2617
- theorem reachable_iff_exists_finsetWalkLength_nonempty (u v : V) :
2618
- G.Reachable u v ↔ ∃ n : Fin (Fintype.card V), (G.finsetWalkLength n u v).Nonempty := by
2619
- constructor
2620
- · intro r
2621
- refine r.elim_path fun p => ?_
2622
- refine ⟨⟨_, p.isPath.length_lt⟩, p, ?_⟩
2623
- simp [Walk.mem_finsetWalkLength_iff_length_eq]
2624
- · rintro ⟨_, p, _⟩
2625
- exact ⟨p⟩
2626
- #align simple_graph.reachable_iff_exists_finset_walk_length_nonempty SimpleGraph.reachable_iff_exists_finsetWalkLength_nonempty
2627
-
2628
- instance : DecidableRel G.Reachable := fun u v =>
2629
- decidable_of_iff' _ (reachable_iff_exists_finsetWalkLength_nonempty G u v)
2630
-
2631
- instance : Fintype G.ConnectedComponent :=
2632
- @Quotient.fintype _ _ G.reachableSetoid (inferInstance : DecidableRel G.Reachable)
2633
-
2634
- instance : Decidable G.Preconnected :=
2635
- inferInstanceAs <| Decidable (∀ u v, G.Reachable u v)
2636
-
2637
- instance : Decidable G.Connected := by
2638
- rw [connected_iff, ← Finset.univ_nonempty_iff]
2639
- infer_instance
2640
-
2641
- instance instDecidableMemSupp (c : G.ConnectedComponent) (v : V) : Decidable (v ∈ c.supp) :=
2642
- c.recOn (fun w ↦ decidable_of_iff (G.Reachable v w) $ by simp)
2643
- (fun _ _ _ _ ↦ Subsingleton.elim _ _)
2644
- end Finite
2645
-
2646
- end WalkCounting
2647
-
2648
- section BridgeEdges
2649
-
2650
-
2651
2397
/-! ### Bridge edges -/
2398
+ section BridgeEdges
2652
2399
2653
2400
/-- An edge of a graph is a *bridge* if, after removing it, its incident vertices
2654
2401
are no longer reachable from one another. -/
0 commit comments