Theory Matching
theory Matching
imports Main
begin
type_synonym label = nat
section ‹Definitions›
definition finite_graph :: "'v set => ('v * 'v) set ⇒ bool" where
"finite_graph V E = (finite V ∧ finite E ∧
(∀ e ∈ E. fst e ∈ V ∧ snd e ∈ V ∧ fst e ~= snd e))"
definition degree :: "('v * 'v) set ⇒ 'v ⇒ nat" where
"degree E v = card {e ∈ E. fst e = v ∨ snd e = v}"
definition edge_as_set :: "('v * 'v) ⇒ 'v set" where
"edge_as_set e = {fst e, snd e}"
definition N :: "'v set ⇒ ('v ⇒ label) ⇒ nat ⇒ nat" where
"N V L i = card {v ∈ V. L v = i}"
definition weight:: "label set ⇒ (label ⇒ nat) ⇒ nat" where
"weight LV f = f 1 + (∑i∈LV. (f i) div 2)"
definition OSC :: "('v ⇒ label) ⇒ ('v * 'v) set ⇒ bool" where
"OSC L E = (∀e ∈ E. L (fst e) = 1 ∨ L (snd e) = 1 ∨
L (fst e) = L (snd e) ∧ L (fst e) > 1)"
definition disjoint_edges :: "('v * 'v) ⇒ ('v * 'v) ⇒ bool" where
"disjoint_edges e1 e2 = (fst e1 ≠ fst e2 ∧ fst e1 ≠ snd e2 ∧
snd e1 ≠ fst e2 ∧ snd e1 ≠ snd e2)"
definition matching :: "'v set ⇒ ('v * 'v) set ⇒ ('v * 'v) set ⇒ bool" where
"matching V E M = (M ⊆ E ∧ finite_graph V E ∧
(∀e1 ∈ M. ∀ e2 ∈ M. e1 ≠ e2 ⟶ disjoint_edges e1 e2))"
definition matching_i :: "nat ⇒ 'v set ⇒ ('v * 'v) set ⇒ ('v * 'v) set ⇒
('v ⇒ label) ⇒ ('v * 'v) set" where
"matching_i i V E M L = {e ∈ M. i=1 ∧ (L (fst e) = i ∨ L (snd e) = i)
∨ i>1 ∧ L (fst e) = i ∧ L (snd e) = i}"
definition V_i:: "nat ⇒ 'v set ⇒ ('v * 'v) set ⇒ ('v * 'v) set ⇒
('v ⇒ label) ⇒ 'v set" where
"V_i i V E M L = ⋃ (edge_as_set ` matching_i i V E M L)"
definition endpoint_inV :: "'v set ⇒ ('v * 'v) ⇒ 'v" where
"endpoint_inV V e = (if fst e ∈ V then fst e else snd e)"
definition relevant_endpoint :: "('v ⇒ label) ⇒ 'v set ⇒
('v * 'v) ⇒ 'v" where
"relevant_endpoint L V e = (if L (fst e) = 1 then fst e else snd e)"
section ‹Lemmas›
lemma definition_of_range:
"endpoint_inV V1 ` matching_i 1 V E M L =
{ v. ∃ e ∈ matching_i 1 V E M L. endpoint_inV V1 e = v }" by auto
lemma matching_i_edges_as_sets:
"edge_as_set ` matching_i i V E M L =
{ e1. ∃ (u, v) ∈ matching_i i V E M L. edge_as_set (u, v) = e1}" by auto
lemma matching_disjointness:
assumes "matching V E M"
assumes "e1 ∈ M"
assumes "e2 ∈ M"
assumes "e1 ≠ e2"
shows "edge_as_set e1 ∩ edge_as_set e2 = {}"
using assms
by (auto simp add: edge_as_set_def disjoint_edges_def matching_def)
lemma expand_set_containment:
assumes "matching V E M"
assumes "e ∈ M"
shows "e ∈ E"
using assms
by (auto simp add:matching_def)
theorem injectivity:
assumes is_osc: "OSC L E"
assumes is_m: "matching V E M"
assumes e1_in_M1: "e1 ∈ matching_i 1 V E M L"
and e2_in_M1: "e2 ∈ matching_i 1 V E M L"
assumes diff: "(e1 ≠ e2)"
shows "endpoint_inV {v ∈ V. L v = 1} e1 ≠ endpoint_inV {v ∈ V. L v = 1} e2"
proof -
from e1_in_M1 have "e1 ∈ M" by (auto simp add: matching_i_def)
moreover
from e2_in_M1 have "e2 ∈ M" by (auto simp add: matching_i_def)
ultimately
have disjoint_edge_sets: "edge_as_set e1 ∩ edge_as_set e2 = {}"
using diff is_m matching_disjointness by fast
then show ?thesis by (auto simp add: edge_as_set_def endpoint_inV_def)
qed
subsection ‹‹|M1| ≤ n1››
lemma card_M1_le_NVL1:
assumes "matching V E M"
assumes "OSC L E"
shows "card (matching_i 1 V E M L) ≤ ( N V L 1)"
proof -
let ?f = "endpoint_inV {v ∈ V. L v = 1}"
let ?A = "matching_i 1 V E M L"
let ?B = "{v ∈ V. L v = 1}"
have "inj_on ?f ?A" using assms injectivity
unfolding inj_on_def by blast
moreover have "?f ` ?A ⊆ ?B"
proof -
{
fix e assume "e ∈ matching_i 1 V E M L"
then have "endpoint_inV {v ∈ V. L v = 1} e ∈ {v ∈ V. L v = 1}"
using assms
by (auto simp add: endpoint_inV_def matching_def
matching_i_def OSC_def finite_graph_def definition_of_range)
}
then show ?thesis using assms definition_of_range by blast
qed
moreover have "finite ?B" using assms
by (simp add: matching_def finite_graph_def)
ultimately show ?thesis unfolding N_def by (rule card_inj_on_le)
qed
lemma edge_as_set_inj_on_Mi:
assumes "matching V E M"
shows "inj_on edge_as_set (matching_i i V E M L)"
using assms
unfolding inj_on_def edge_as_set_def matching_def
disjoint_edges_def matching_i_def
by blast
lemma card_Mi_eq_card_edge_as_set_Mi:
assumes "matching V E M"
shows "card (matching_i i V E M L) = card (edge_as_set` matching_i i V E M L)"
(is "card ?Mi = card (?f ` _)")
proof -
from assms have "bij_betw ?f ?Mi (?f ` ?Mi)"
by (simp add: bij_betw_def matching_i_edges_as_sets edge_as_set_inj_on_Mi)
then show ?thesis by (rule bij_betw_same_card)
qed
lemma card_edge_as_set_Mi_twice_card_partitions:
assumes "OSC L E ∧ matching V E M ∧ i > 1"
shows "2 * card (edge_as_set`matching_i i V E M L)
= card (V_i i V E M L)" (is "2 * card ?C = card ?Vi")
proof -
from assms have 1: "finite (⋃ ?C)"
by (auto simp add: matching_def finite_graph_def
matching_i_def edge_as_set_def finite_subset)
show ?thesis unfolding V_i_def
proof (rule card_partition)
show "finite ?C" using 1 by (rule finite_UnionD)
next
show "finite (⋃ ?C)" using 1 .
next
fix c assume "c ∈ ?C" then show "card c = 2"
proof (rule imageE)
fix x
assume 2: "c = edge_as_set x" and 3: "x ∈ matching_i i V E M L"
with assms have "x ∈ E"
unfolding matching_i_def matching_def by blast
then have "fst x ≠ snd x" using assms 3
by (auto simp add: matching_def finite_graph_def)
with 2 show ?thesis by (auto simp add: edge_as_set_def)
qed
next
fix x1 x2
assume 4: "x1 ∈ ?C" and 5: "x2 ∈ ?C" and 6: "x1 ≠ x2"
{
fix e1 e2
assume 7: "x1 = edge_as_set e1" "e1 ∈ matching_i i V E M L"
"x2 = edge_as_set e2" "e2 ∈ matching_i i V E M L"
from assms have "matching V E M" by simp
moreover
from 7 assms have "e1 ∈ M" and "e2 ∈ M"
by (simp_all add: matching_i_def)
moreover from 6 7 have "e1 ≠ e2" by blast
ultimately have "x1 ∩ x2 = {}" unfolding 7
by (rule matching_disjointness)
}
with 4 5 show "x1 ∩ x2 = {}" by clarsimp
qed
qed
lemma card_Mi_twice_card_Vi:
assumes "OSC L E ∧ matching V E M ∧ i > 1"
shows "2 * card (matching_i i V E M L) = card (V_i i V E M L)"
proof -
from assms have "finite (V_i i V E M L)"
by (auto simp add: edge_as_set_def finite_subset
matching_def finite_graph_def V_i_def matching_i_def )
with assms show ?thesis
by (simp add: card_Mi_eq_card_edge_as_set_Mi
card_edge_as_set_Mi_twice_card_partitions V_i_def)
qed
lemma card_Mi_le_floor_div_2_Vi:
assumes "OSC L E ∧ matching V E M ∧ i > 1"
shows "card (matching_i i V E M L) ≤ (card (V_i i V E M L)) div 2"
using card_Mi_twice_card_Vi[OF assms]
by arith
lemma card_Vi_le_NVLi:
assumes "i>1 ∧ matching V E M"
shows "card (V_i i V E M L) ≤ N V L i"
unfolding N_def
proof (rule card_mono)
show "finite {v ∈ V. L v = i}" using assms
by (simp add: matching_def finite_graph_def)
next
let ?A = "edge_as_set ` matching_i i V E M L"
let ?C = "{v ∈ V. L v = i}"
show "V_i i V E M L ⊆ ?C" using assms unfolding V_i_def
proof (intro Union_least)
fix X assume "X ∈ ?A"
with assms have "∃x ∈ matching_i i V E M L. edge_as_set x = X"
by (simp add: matching_i_edges_as_sets)
with assms show "X ⊆ ?C"
unfolding finite_graph_def matching_def
matching_i_def edge_as_set_def by blast
qed
qed
subsection ‹‹|Mi| ≤ ⌊ni/2⌋››
lemma card_Mi_le_floor_div_2_NVLi:
assumes "OSC L E ∧ matching V E M ∧ i > 1"
shows "card (matching_i i V E M L) ≤ (N V L i) div 2"
proof -
from assms have "card (V_i i V E M L) ≤ (N V L i)"
by (simp add: card_Vi_le_NVLi)
then have "card (V_i i V E M L) div 2 ≤ (N V L i) div 2"
by simp
moreover from assms have
"card (matching_i i V E M L) ≤ card (V_i i V E M L) div 2"
by (intro card_Mi_le_floor_div_2_Vi)
ultimately show ?thesis by auto
qed
subsection ‹‹|M| ≤ ∑|Mi|››
lemma card_M_le_sum_card_Mi:
assumes "matching V E M" and "OSC L E"
shows "card M ≤ (∑ i ∈ L`V. card (matching_i i V E M L))"
(is "card _ ≤ ?CardMi")
proof -
let ?UnMi = "⋃x ∈ L`V. matching_i x V E M L"
from assms have 1: "finite ?UnMi"
by (auto simp add: matching_def
finite_graph_def matching_i_def finite_subset)
{
fix e assume e_inM: "e ∈ M"
let ?v = "relevant_endpoint L V e"
have 1: "e ∈ matching_i (L ?v) V E M L" using assms e_inM
proof cases
assume "L (fst e) = 1"
thus ?thesis using assms e_inM
by (simp add: relevant_endpoint_def matching_i_def)
next
assume a: "L (fst e) ≠ 1"
have "L (fst e) = 1 ∨ L (snd e) = 1
∨ (L (fst e) = L (snd e) ∧ L (fst e) >1)"
using assms e_inM unfolding OSC_def
by (blast intro: expand_set_containment)
thus ?thesis using assms e_inM a
by (auto simp add: relevant_endpoint_def matching_i_def)
qed
have 2: "?v ∈ V" using assms e_inM
by (auto simp add: matching_def
relevant_endpoint_def matching_i_def finite_graph_def)
then have "∃ v ∈ V. e ∈ matching_i (L v) V E M L" using assms 1 2
by (intro bexI)
}
with assms have "M ⊆ ?UnMi" by (auto)
with assms and 1 have "card M ≤ card ?UnMi" by (intro card_mono)
moreover from assms have "card ?UnMi = ?CardMi"
proof (intro card_UN_disjoint)
show "finite (L`V)" using assms
by (simp add: matching_def finite_graph_def)
next
show "∀i∈L`V. finite (matching_i i V E M L)" using assms
unfolding matching_def finite_graph_def matching_i_def
by (blast intro: finite_subset)
next
show "∀i ∈ L`V. ∀j ∈ L`V. i ≠ j ⟶
matching_i i V E M L ∩ matching_i j V E M L = {}" using assms
by (auto simp add: matching_i_def)
qed
ultimately show ?thesis by simp
qed
theorem card_M_le_weight_NVLi:
assumes "matching V E M" and "OSC L E"
shows "card M ≤ weight {i ∈ L ` V. i > 1} (N V L)" (is "_ ≤ ?W")
proof -
let ?M01 = "∑i| i ∈ L`V ∧ (i=1 ∨ i=0). card (matching_i i V E M L)"
let ?Mgr1 = "∑i| i ∈ L`V ∧ 1 < i. card (matching_i i V E M L)"
let ?Mi = "∑ i∈L`V. card (matching_i i V E M L)"
have "card M ≤ ?Mi" using assms by (rule card_M_le_sum_card_Mi)
moreover
have "?Mi ≤ ?W"
proof -
let ?A = "{i ∈ L ` V. i = 1 ∨ i = 0}"
let ?B = "{i ∈ L ` V. 1 < i}"
let ?g = "λ i. card (matching_i i V E M L)"
let ?set01 = "{ i. i : L ` V & (i = 1 | i = 0)}"
have a: "L ` V = ?A ∪ ?B" using assms by auto
have "finite V" using assms
by (simp add: matching_def finite_graph_def)
have b: "sum ?g (?A ∪ ?B) = sum ?g ?A + sum ?g ?B"
using assms ‹finite V› by (auto intro: sum.union_disjoint)
have 1: "?Mi = ?M01+ ?Mgr1" using assms a b
by (simp add: matching_def finite_graph_def)
moreover
have 0: "card (matching_i 0 V E M L) = 0" using assms
by (simp add: matching_i_def)
have 2: "?M01 ≤ N V L 1"
proof cases
assume a: "1 ∈ L`V"
have "?M01 = card (matching_i 1 V E M L)"
proof cases
assume b: "0 ∈ L`V"
with a assms have "?set01 = {0, 1}" by blast
thus ?thesis using assms 0 by simp
next
assume b: "0 ∉ L`V"
with a have "?set01 = {1}" by (auto simp del:One_nat_def)
thus ?thesis by simp
qed
thus ?thesis using assms a
by (simp del: One_nat_def, intro card_M1_le_NVL1)
next
assume a: "1 ∉ L`V"
show ?thesis
proof cases
assume b: "0 ∈ L`V"
with a assms have "?set01 = {0}" by (auto simp del:One_nat_def)
thus ?thesis using assms 0 by auto
next
assume b: "0 ∉ L`V"
with a have "?set01 = {}" by (auto simp del:One_nat_def)
then have "?M01 = (∑i∈{}. card (matching_i i V E M L))" by auto
thus ?thesis by simp
qed
qed
moreover
have 3: "?Mgr1 ≤ (∑i|i∈L`V ∧ 1 < i. N V L i div 2)" using assms
by (intro sum_mono card_Mi_le_floor_div_2_NVLi, simp)
ultimately
show ?thesis using 1 2 3 assms by (simp add: weight_def)
qed
ultimately show ?thesis by simp
qed
section ‹Final Theorem›
text‹The following theorem is due to Edmond~\<^cite>‹"Edmonds:matching"›:›
theorem maximum_cardinality_matching:
assumes "matching V E M" and "OSC L E"
and "card M = weight {i ∈ L ` V. i > 1} (N V L)"
and "matching V E M'"
shows "card M' ≤ card M"
using assms card_M_le_weight_NVLi
by simp
text‹The widely used algorithmic library LEDA has a certifying algorithm for maximum cardinality matching.
This Isabelle proof is part of the work done to verify the checker of this certifying algorithm. For more information see \<^cite>‹"VerificationofCertifyingComputations"›.›
end