@@ -3,8 +3,9 @@ Copyright (c) 2020 Alena Gusakov. All rights reserved.
3
3
Released under Apache 2.0 license as described in the file LICENSE.
4
4
Authors: Alena Gusakov, Arthur Paulino, Kyle Miller, Pim Otte
5
5
-/
6
- import Mathlib.Combinatorics.SimpleGraph.DegreeSum
6
+ import Mathlib.Combinatorics.SimpleGraph.Connectivity.Subgraph
7
7
import Mathlib.Combinatorics.SimpleGraph.Connectivity.WalkCounting
8
+ import Mathlib.Combinatorics.SimpleGraph.DegreeSum
8
9
import Mathlib.Data.Fintype.Order
9
10
import Mathlib.Data.Set.Functor
10
11
@@ -334,6 +335,16 @@ lemma IsCycles.other_adj_of_adj (h : G.IsCycles) (hadj : G.Adj v w) :
334
335
obtain ⟨w', hww'⟩ := (G.neighborSet v).exists_ne_of_one_lt_ncard (by omega) w
335
336
exact ⟨w', ⟨hww'.2 .symm, hww'.1 ⟩⟩
336
337
338
+ lemma IsCycles.existsUnique_ne_adj (h : G.IsCycles) (hadj : G.Adj v w) :
339
+ ∃! w', w ≠ w' ∧ G.Adj v w' := by
340
+ obtain ⟨w', ⟨hww, hww'⟩⟩ := h.other_adj_of_adj hadj
341
+ use w'
342
+ refine ⟨⟨hww, hww'⟩, ?_⟩
343
+ intro y ⟨hwy, hwy'⟩
344
+ obtain ⟨x, y', hxy'⟩ := Set.ncard_eq_two.mp (h ⟨w, hadj⟩)
345
+ simp_rw [← SimpleGraph.mem_neighborSet] at *
346
+ aesop
347
+
337
348
lemma IsCycles.induce_supp (c : G.ConnectedComponent) (h : G.IsCycles) :
338
349
(G.induce c.supp).spanningCoe.IsCycles := by
339
350
intro v ⟨w, hw⟩
@@ -360,6 +371,110 @@ lemma Subgraph.IsPerfectMatching.symmDiff_isCycles
360
371
use w, w'
361
372
aesop
362
373
374
+ lemma IsCycles.snd_of_mem_support_of_isPath_of_adj [Finite V] {v w w' : V}
375
+ (hcyc : G.IsCycles) (p : G.Walk v w) (hw : w ≠ w') (hw' : w' ∈ p.support) (hp : p.IsPath)
376
+ (hadj : G.Adj v w') : p.snd = w' := by
377
+ classical
378
+ apply hp.snd_of_toSubgraph_adj
379
+ rw [Walk.mem_support_iff_exists_getVert] at hw'
380
+ obtain ⟨n, ⟨rfl, hnl⟩⟩ := hw'
381
+ by_cases hn : n = 0 ∨ n = p.length
382
+ · aesop
383
+ have e : G.neighborSet (p.getVert n) ≃ p.toSubgraph.neighborSet (p.getVert n) := by
384
+ refine @Classical.ofNonempty _ ?_
385
+ rw [← Cardinal.eq, ← Set.cast_ncard (Set.toFinite _), ← Set.cast_ncard (Set.toFinite _),
386
+ hp.ncard_neighborSet_toSubgraph_internal_eq_two (by omega) (by omega),
387
+ hcyc (Set.nonempty_of_mem hadj.symm)]
388
+ rw [Subgraph.adj_comm, Subgraph.adj_iff_of_neighborSet_equiv e (Set.toFinite _).fintype]
389
+ exact hadj.symm
390
+
391
+ private lemma IsCycles.reachable_sdiff_toSubgraph_spanningCoe_aux [Fintype V] {v w : V}
392
+ (hcyc : G.IsCycles) (p : G.Walk v w) (hp : p.IsPath) :
393
+ (G \ p.toSubgraph.spanningCoe).Reachable w v := by
394
+ classical
395
+ -- Consider the case when p is nil
396
+ by_cases hvw : v = w
397
+ · subst hvw
398
+ use .nil
399
+ have hpn : ¬p.Nil := Walk.not_nil_of_ne hvw
400
+ obtain ⟨w', ⟨hw'1 , hw'2 ⟩, hwu⟩ := hcyc.existsUnique_ne_adj
401
+ (p.toSubgraph_adj_snd hpn).adj_sub
402
+ -- The edge (v, w) can't be in p, because then it would be the second node
403
+ have hnpvw' : ¬ p.toSubgraph.Adj v w' := by
404
+ intro h
405
+ exact hw'1 (hp.snd_of_toSubgraph_adj h)
406
+ -- If w = w', then then the reachability can be proved with just one edge
407
+ by_cases hww' : w = w'
408
+ · subst hww'
409
+ have : (G \ p.toSubgraph.spanningCoe).Adj w v := by
410
+ simp only [sdiff_adj, Subgraph.spanningCoe_adj]
411
+ exact ⟨hw'2 .symm, fun h ↦ hnpvw' h.symm⟩
412
+ exact this.reachable
413
+ -- Construct the walk needed recursively by extending p
414
+ have hle : (G \ (p.cons hw'2 .symm).toSubgraph.spanningCoe) ≤ (G \ p.toSubgraph.spanningCoe) := by
415
+ apply sdiff_le_sdiff (by rfl) ?hcd
416
+ aesop
417
+ have hp'p : (p.cons hw'2 .symm).IsPath := by
418
+ rw [Walk.cons_isPath_iff]
419
+ refine ⟨hp, fun hw' ↦ ?_⟩
420
+ exact hw'1 (hcyc.snd_of_mem_support_of_isPath_of_adj _ hww' hw' hp hw'2 )
421
+ have : (G \ p.toSubgraph.spanningCoe).Adj w' v := by
422
+ simp only [sdiff_adj, Subgraph.spanningCoe_adj]
423
+ refine ⟨hw'2 .symm, fun h ↦ ?_⟩
424
+ exact hnpvw' h.symm
425
+ use (((hcyc.reachable_sdiff_toSubgraph_spanningCoe_aux
426
+ (p.cons hw'2 .symm) hp'p).some).mapLe hle).append this.toWalk
427
+ termination_by Fintype.card V + 1 - p.length
428
+ decreasing_by
429
+ simp_wf
430
+ have := Walk.IsPath.length_lt hp
431
+ omega
432
+
433
+ lemma IsCycles.reachable_sdiff_toSubgraph_spanningCoe [Finite V] {v w : V} (hcyc : G.IsCycles)
434
+ (p : G.Walk v w) (hp : p.IsPath) : (G \ p.toSubgraph.spanningCoe).Reachable w v := by
435
+ have : Fintype V := Fintype.ofFinite V
436
+ exact reachable_sdiff_toSubgraph_spanningCoe_aux hcyc p hp
437
+
438
+ lemma IsCycles.reachable_deleteEdges [Finite V] (hadj : G.Adj v w)
439
+ (hcyc : G.IsCycles) : (G.deleteEdges {s(v, w)}).Reachable v w := by
440
+ have : fromEdgeSet {s(v, w)} = hadj.toWalk.toSubgraph.spanningCoe := by
441
+ simp only [Walk.toSubgraph, singletonSubgraph_le_iff, subgraphOfAdj_verts, Set.mem_insert_iff,
442
+ Set.mem_singleton_iff, or_true, sup_of_le_left]
443
+ exact (Subgraph.spanningCoe_subgraphOfAdj hadj).symm
444
+ rw [show G.deleteEdges {s(v, w)} = G \ fromEdgeSet {s(v, w)} from by rfl]
445
+ exact this ▸ (hcyc.reachable_sdiff_toSubgraph_spanningCoe hadj.toWalk
446
+ (Walk.IsPath.of_adj hadj)).symm
447
+
448
+ lemma IsCycles.exists_cycle_toSubgraph_verts_eq_connectedComponentSupp [Finite V]
449
+ {c : G.ConnectedComponent} (h : G.IsCycles) (hv : v ∈ c.supp)
450
+ (hn : (G.neighborSet v).Nonempty) :
451
+ ∃ (p : G.Walk v v), p.IsCycle ∧ p.toSubgraph.verts = c.supp := by
452
+ classical
453
+ obtain ⟨w, hw⟩ := hn
454
+ obtain ⟨u, p, hp⟩ := SimpleGraph.adj_and_reachable_delete_edges_iff_exists_cycle.mp
455
+ ⟨hw, h.reachable_deleteEdges hw⟩
456
+ have hvp : v ∈ p.support := SimpleGraph.Walk.fst_mem_support_of_mem_edges _ hp.2
457
+ have : p.toSubgraph.verts = c.supp := by
458
+ obtain ⟨c', hc'⟩ := p.toSubgraph_connected.exists_verts_eq_connectedComponentSupp (by
459
+ intro v hv w hadj
460
+ refine (Subgraph.adj_iff_of_neighborSet_equiv ?_ (Set.toFinite _).fintype).mpr hadj
461
+ have : (G.neighborSet v).Nonempty := by
462
+ rw [Walk.mem_verts_toSubgraph] at hv
463
+ refine (Set.nonempty_of_ncard_ne_zero ?_).mono (p.toSubgraph.neighborSet_subset v)
464
+ rw [hp.1 .ncard_neighborSet_toSubgraph_eq_two hv]
465
+ omega
466
+ refine @Classical.ofNonempty _ ?_
467
+ rw [← Cardinal.eq, ← Set.cast_ncard (Set.toFinite _), ← Set.cast_ncard (Set.toFinite _),
468
+ h this, hp.1 .ncard_neighborSet_toSubgraph_eq_two (p.mem_verts_toSubgraph.mp hv)])
469
+ rw [hc']
470
+ have : v ∈ c'.supp := by
471
+ rw [← hc', Walk.mem_verts_toSubgraph]
472
+ exact hvp
473
+ simp_all
474
+ use p.rotate hvp
475
+ rw [← this]
476
+ exact ⟨hp.1 .rotate _, by simp_all⟩
477
+
363
478
/--
364
479
A graph `G` is alternating with respect to some other graph `G'`, if exactly every other edge in
365
480
`G` is in `G'`. Note that the degree of each vertex needs to be at most 2 for this to be
0 commit comments