Theory MFMC_Countable.MFMC_Finite
theory MFMC_Finite imports
EdmondsKarp_Maxflow.EdmondsKarp_Termination_Abstract
"HOL-Library.While_Combinator"
begin
section ‹Existence of maximum flows and minimal cuts in finite graphs›
text ‹This theory derives the existencs of a maximal flow or a minimal cut for finite graphs
from the termination proof of the Edmonds-Karp algorithm.›
context Graph begin
lemma outgoing_outside: "x ∉ V ⟹ outgoing x = {}"
by(auto simp add: outgoing_def V_def)
lemma incoming_outside: "x ∉ V ⟹ incoming x = {}"
by(auto simp add: incoming_def V_def)
end
context NFlow begin
lemma conservation: "⟦ x ≠ s; x ≠ t ⟧ ⟹ sum f (incoming x) = sum f (outgoing x)"
by(cases "x ∈ V")(auto simp add: conservation_const outgoing_outside incoming_outside)
lemma augmenting_path_imp_shortest:
"isAugmentingPath p ⟹ ∃p. Graph.isShortestPath cf s p t"
using Graph.obtain_shortest_path unfolding isAugmentingPath_def
by (fastforce simp: Graph.isSimplePath_def Graph.connected_def)
lemma shortest_is_augmenting:
"Graph.isShortestPath cf s p t ⟹ isAugmentingPath p"
unfolding isAugmentingPath_def using Graph.shortestPath_is_simple
by (fastforce)
definition "augment_with_path p ≡ augment (augmentingFlow p)"
end
context Network begin
definition "shortest_augmenting_path f = (SOME p. Graph.isShortestPath (residualGraph c f) s p t)"
lemma shortest_augmenting_path:
assumes "NFlow c s t f"
and "∃p. NPreflow.isAugmentingPath c s t f p"
shows "Graph.isShortestPath (residualGraph c f) s (shortest_augmenting_path f) t"
using assms unfolding shortest_augmenting_path_def
by clarify(rule someI_ex, rule NFlow.augmenting_path_imp_shortest)
definition max_flow where
"max_flow = while
(λf. ∃p. NPreflow.isAugmentingPath c s t f p)
(λf. NFlow.augment_with_path c f (shortest_augmenting_path f)) (λ_. 0)"
lemma max_flow:
"NFlow c s t max_flow" (is ?thesis1)
"¬ (∃p. NPreflow.isAugmentingPath c s t max_flow p)" (is ?thesis2)
proof -
have "NFlow c s t (λ_. 0)"
by unfold_locales(simp_all add: cap_non_negative)
moreover have "NFlow c s t (NFlow.augment_with_path c f (shortest_augmenting_path f))"
if "NFlow c s t f" and "∃p. NPreflow.isAugmentingPath c s t f p" for f
proof -
interpret NFlow c s t f using that(1) .
interpret F: Flow c s t "NFlow.augment c f (NPreflow.augmentingFlow c f (shortest_augmenting_path f))"
by(intro augment_flow_presv augFlow_resFlow shortest_is_augmenting shortest_augmenting_path[OF that])
show ?thesis using that
by(simp add: NFlow.augment_with_path_def)(unfold_locales)
qed
ultimately have "NFlow c s t max_flow ∧ ¬ (∃p. NPreflow.isAugmentingPath c s t max_flow p)"
unfolding max_flow_def
by(rule while_rule[where P="NFlow c s t" and r="measure (λf. ek_analysis_defs.ekMeasure (residualGraph c f) s t)"])
(auto intro: shortest_augmenting_path NFlow.shortest_path_decr_ek_measure simp add: NFlow.augment_with_path_def)
thus ?thesis1 ?thesis2 by simp_all
qed
end
end