@@ -11,6 +11,7 @@ public import Mathlib.LinearAlgebra.Matrix.Trace
1111public import Mathlib.LinearAlgebra.Matrix.Hadamard
1212
1313import Mathlib.Algebra.GroupWithZero.Idempotent
14+ import Mathlib.Combinatorics.SimpleGraph.DegreeSum
1415
1516/-!
1617# Adjacency Matrices
@@ -46,7 +47,7 @@ open Matrix
4647
4748open Finset SimpleGraph
4849
49- variable {V α : Type *}
50+ variable {α V : Type *}
5051
5152namespace Matrix
5253
@@ -63,6 +64,8 @@ namespace IsAdjMatrix
6364
6465variable {A : Matrix V V α}
6566
67+ @[simp] protected theorem zero [Zero α] [One α] : (0 : Matrix V V α).IsAdjMatrix where
68+
6669@[simp]
6770theorem apply_diag_ne [MulZeroOneClass α] [Nontrivial α] (h : IsAdjMatrix A) (i : V) :
6871 ¬A i i = 1 := by simp [h.apply_diag i]
@@ -88,19 +91,22 @@ instance [MulZeroOneClass α] [Nontrivial α] [DecidableEq α] (h : IsAdjMatrix
8891 simp only [toGraph]
8992 infer_instance
9093
94+ @[simp] theorem hadamard_self [MulZeroOneClass α] {A : Matrix V V α} (hA : A.IsAdjMatrix) :
95+ A ⊙ A = A := by ext i j; have := hA.zero_or_one i j; aesop
96+
9197end IsAdjMatrix
9298
9399theorem isAdjMatrix_iff_hadamard [DecidableEq V] [MonoidWithZero α]
94100 [IsLeftCancelMulZero α] {A : Matrix V V α} :
95101 A.IsAdjMatrix ↔ (A ⊙ A = A ∧ A.IsSymm ∧ 1 ⊙ A = 0 ) := by
96102 simp only [hadamard_self_eq_self_iff, IsIdempotentElem.iff_eq_zero_or_one,
97- one_hadamard_eq_zero_iff, funext_iff, diag]
98- exact ⟨ fun ⟨h1, h2, h3⟩ ↦ ⟨h1, h2, h3⟩, fun ⟨h1, h2, h3⟩ ↦ ⟨h1, h2, h3⟩⟩
103+ one_hadamard_eq_zero_iff, funext_iff, diag, Pi.zero_apply ]
104+ grind [IsAdjMatrix]
99105
100106/-- For `A : Matrix V V α`, `A.compl` is supposed to be the adjacency matrix of
101107the complement graph of the graph induced by `A.adjMatrix`. -/
102108def compl [Zero α] [One α] [DecidableEq α] [DecidableEq V] (A : Matrix V V α) : Matrix V V α :=
103- fun i j => ite ( i = j) 0 (ite ( A i j = 0 ) 1 0 )
109+ of fun i j ↦ if i = j then 0 else if A i j = 0 then 1 else 0
104110
105111section Compl
106112
@@ -111,8 +117,7 @@ theorem compl_apply_diag [Zero α] [One α] (i : V) : A.compl i i = 0 := by simp
111117
112118@[simp]
113119theorem compl_apply [Zero α] [One α] (i j : V) : A.compl i j = 0 ∨ A.compl i j = 1 := by
114- unfold compl
115- split_ifs <;> simp
120+ grind [compl, of]
116121
117122@[simp]
118123theorem isSymm_compl [Zero α] [One α] (h : A.IsSymm) : A.compl.IsSymm := by
@@ -123,6 +128,13 @@ theorem isSymm_compl [Zero α] [One α] (h : A.IsSymm) : A.compl.IsSymm := by
123128theorem isAdjMatrix_compl [Zero α] [One α] (h : A.IsSymm) : IsAdjMatrix A.compl :=
124129 { symm := by simp [h] }
125130
131+ theorem IsAdjMatrix.compl_inj [Zero α] [One α] {A B : Matrix V V α}
132+ (hA : A.IsAdjMatrix) (hB : B.IsAdjMatrix) : A.compl = B.compl ↔ A = B :=
133+ ⟨fun h ↦ ext fun i j ↦ by grind [of, congr($h i j), compl, IsAdjMatrix], fun h ↦ h ▸ rfl⟩
134+
135+ @[simp] theorem IsAdjMatrix.compl_compl [Zero α] [One α] {A : Matrix V V α} (hA : A.IsAdjMatrix) :
136+ A.compl.compl = A := by ext; grind [of, compl, IsAdjMatrix]
137+
126138namespace IsAdjMatrix
127139
128140variable {A}
@@ -169,10 +181,12 @@ theorem isSymm_adjMatrix [Zero α] [One α] : (G.adjMatrix α).IsSymm :=
169181
170182variable (α)
171183
184+ @[simp] theorem diag_adjMatrix [Zero α] [One α] : (G.adjMatrix α).diag = 0 := by ext; simp
185+
172186/-- The adjacency matrix of `G` is an adjacency matrix. -/
173187@[simp]
174- theorem isAdjMatrix_adjMatrix [Zero α] [One α] : (G.adjMatrix α).IsAdjMatrix :=
175- { zero_or_one := fun i j => by by_cases h : G.Adj i j <;> simp [h] }
188+ theorem isAdjMatrix_adjMatrix [Zero α] [One α] : (G.adjMatrix α).IsAdjMatrix where
189+ zero_or_one := by grind [adjMatrix_apply]
176190
177191/-- The graph induced by the adjacency matrix of `G` is `G` itself. -/
178192theorem toGraph_adjMatrix_eq [MulZeroOneClass α] [Nontrivial α] :
@@ -181,18 +195,58 @@ theorem toGraph_adjMatrix_eq [MulZeroOneClass α] [Nontrivial α] :
181195 simp only [IsAdjMatrix.toGraph_adj, adjMatrix_apply, ite_eq_left_iff, zero_ne_one]
182196 apply Classical.not_not
183197
184- variable {α}
198+ theorem compl_adjMatrix_eq_adjMatrix_compl [DecidableEq V] [DecidableEq α] [Zero α] [One α] :
199+ (G.adjMatrix α).compl = Gᶜ.adjMatrix α := by aesop (add simp [Matrix.compl])
200+
201+ set_option backward.isDefEq.respectTransparency false in
202+ variable {G} in
203+ theorem IsCompl.adjMatrix_add_adjMatrix_eq_adjMatrix_completeGraph [DecidableEq V] [AddZeroClass α]
204+ [One α] {H : SimpleGraph V} [DecidableRel H.Adj] (h : IsCompl G H) :
205+ G.adjMatrix α + H.adjMatrix α = (completeGraph V).adjMatrix α := calc
206+ _ = G.adjMatrix α + Gᶜ.adjMatrix α := by have := h.compl_eq; subst this; congr
207+ _ = _ := by aesop (add simp Matrix.compl)
208+
209+ @[simp] theorem adjMatrix_add_compl_adjMatrix_eq_adjMatrix_completeGraph [DecidableEq V]
210+ [DecidableEq α] [AddZeroClass α] [One α] :
211+ G.adjMatrix α + (G.adjMatrix α).compl = (completeGraph V).adjMatrix α :=
212+ G.compl_adjMatrix_eq_adjMatrix_compl α ▸
213+ isCompl_compl.adjMatrix_add_adjMatrix_eq_adjMatrix_completeGraph α
185214
186215/-- The sum of the identity, the adjacency matrix, and its complement is the all-ones matrix. -/
187- theorem one_add_adjMatrix_add_compl_adjMatrix_eq_allOnes [DecidableEq V] [DecidableEq α]
188- [AddMonoidWithOne α] : 1 + G.adjMatrix α + (G.adjMatrix α).compl = Matrix.of fun _ _ ↦ 1 := by
189- ext i j
190- unfold Matrix.compl
191- rw [of_apply, add_apply, adjMatrix_apply, add_apply, adjMatrix_apply, one_apply]
192- by_cases h : G.Adj i j
193- · aesop
194- · split_ifs <;> simp_all
216+ theorem one_add_adjMatrix_add_compl_adjMatrix_eq_of_one [DecidableEq V] [DecidableEq α]
217+ [AddMonoid α] [One α] : 1 + G.adjMatrix α + (G.adjMatrix α).compl = of 1 := by
218+ aesop (add simp [add_assoc])
219+
220+ @ [deprecated (since := "2026-01-30" )] alias one_add_adjMatrix_add_compl_adjMatrix_eq_allOnes :=
221+ one_add_adjMatrix_add_compl_adjMatrix_eq_of_one
222+
223+ variable (V)
224+
225+ @[simp] theorem compl_adjMatrix_completeGraph [Zero α] [One α] [DecidableEq α] [DecidableEq V] :
226+ ((completeGraph V).adjMatrix α).compl = 0 := by aesop (add simp Matrix.compl)
227+
228+ @[simp] theorem _root_.Matrix.compl_zero [Zero α] [One α] [DecidableEq α] [DecidableEq V] :
229+ (0 : Matrix V V α).compl = (completeGraph V).adjMatrix α := by simp [← IsAdjMatrix.compl_inj]
230+
231+ theorem adjMatrix_completeGraph_eq_of_one_sub_one [AddGroup α] [One α] [DecidableEq V] :
232+ (completeGraph V).adjMatrix α = of 1 - 1 := by ext; simp [one_apply, sub_ite]
233+
234+ theorem _root_.Matrix.compl_zero_eq_of_one_sub_one [AddGroup α] [One α] [DecidableEq V]
235+ [DecidableEq α] : (0 : Matrix V V α).compl = of 1 - 1 := by
236+ simp [adjMatrix_completeGraph_eq_of_one_sub_one]
237+
238+ @[simp] theorem _root_.Matrix.compl_of_one_sub_one [AddGroup α] [One α] [DecidableEq V]
239+ [DecidableEq α] : (of 1 - 1 : Matrix V V α).compl = 0 := by
240+ simp [← adjMatrix_completeGraph_eq_of_one_sub_one]
241+
242+ variable {V}
243+
244+ theorem adjMatrix_hadamard_self [MulZeroOneClass α] :
245+ G.adjMatrix α ⊙ G.adjMatrix α = G.adjMatrix α := by simp
195246
247+ variable {α}
248+
249+ section fintype
196250variable [Fintype V]
197251
198252@[simp]
@@ -235,6 +289,13 @@ theorem trace_adjMatrix [AddCommMonoid α] [One α] : Matrix.trace (G.adjMatrix
235289theorem adjMatrix_mul_self_apply_self [NonAssocSemiring α] (i : V) :
236290 (G.adjMatrix α * G.adjMatrix α) i i = degree G i := by simp [filter_true_of_mem]
237291
292+ variable (R) in
293+ /-- The number of all darts in a simple finite graph is equal to the dot product of
294+ `G.adjMatrix α *ᵥ 1` and `1`. -/
295+ theorem natCast_card_dart_eq_dotProduct [NonAssocSemiring α] :
296+ (Fintype.card G.Dart : α) = adjMatrix α G *ᵥ 1 ⬝ᵥ 1 := by
297+ simp [G.dart_card_eq_sum_degrees, dotProduct_one]
298+
238299variable {G}
239300
240301theorem adjMatrix_mulVec_const_apply [NonAssocSemiring α] {a : α} {v : V} :
@@ -266,8 +327,46 @@ theorem adjMatrix_pow_apply_eq_card_walk [DecidableEq V] [Semiring α] (n : ℕ)
266327
267328theorem dotProduct_mulVec_adjMatrix [NonAssocSemiring α] (x y : V → α) :
268329 x ⬝ᵥ G.adjMatrix α *ᵥ y = ∑ i : V, ∑ j : V, if G.Adj i j then x i * y j else 0 := by
269- simp only [dotProduct, mulVec, adjMatrix_apply, ite_mul, one_mul, zero_mul, mul_sum, mul_ite,
270- mul_zero]
330+ simp [dotProduct, mulVec, mul_sum]
331+
332+ end fintype
333+
334+ section hadamard
335+ variable (α) [DecidableEq V] [MulZeroOneClass α]
336+
337+ open Matrix
338+
339+ @[simp] theorem adjMatrix_hadamard_diagonal (d : V → α) :
340+ G.adjMatrix α ⊙ diagonal d = 0 := by simp [hadamard_diagonal]
341+
342+ @[simp] theorem diagonal_hadamard_adjMatrix (d : V → α) :
343+ diagonal d ⊙ G.adjMatrix α = 0 := by simp [diagonal_hadamard]
344+
345+ @[simp] theorem adjMatrix_hadamard_natCast [NatCast α] (a : ℕ) :
346+ G.adjMatrix α ⊙ a.cast = 0 := adjMatrix_hadamard_diagonal _ _ _
347+
348+ @[simp] theorem natCast_hadamard_adjMatrix [NatCast α] (a : ℕ) :
349+ a.cast ⊙ G.adjMatrix α = 0 := diagonal_hadamard_adjMatrix _ _ _
350+
351+ @[simp] theorem adjMatrix_hadamard_ofNat [NatCast α] (a : ℕ) [a.AtLeastTwo] :
352+ G.adjMatrix α ⊙ ofNat(a) = 0 := adjMatrix_hadamard_diagonal _ _ _
353+
354+ @[simp] theorem ofNat_hadamard_adjMatrix [NatCast α] (a : ℕ) [a.AtLeastTwo] :
355+ ofNat(a) ⊙ G.adjMatrix α = 0 := diagonal_hadamard_adjMatrix _ _ _
356+
357+ @[simp] theorem adjMatrix_hadamard_intCast [IntCast α] (a : ℤ) :
358+ G.adjMatrix α ⊙ a.cast = 0 := adjMatrix_hadamard_diagonal _ _ _
359+
360+ @[simp] theorem intCast_hadamard_adjMatrix [IntCast α] (a : ℤ) :
361+ a.cast ⊙ G.adjMatrix α = 0 := diagonal_hadamard_adjMatrix _ _ _
362+
363+ @[simp] theorem adjMatrix_hadamard_one :
364+ G.adjMatrix α ⊙ 1 = 0 := adjMatrix_hadamard_diagonal _ _ _
365+
366+ @[simp] theorem one_hadamard_adjMatrix :
367+ 1 ⊙ G.adjMatrix α = 0 := diagonal_hadamard_adjMatrix _ _ _
368+
369+ end hadamard
271370
272371end SimpleGraph
273372
0 commit comments