section ‹Residual Graph›
theory ResidualGraph
imports Network
begin
text ‹
In this theory, we define the residual graph.
›
subsection ‹Definition›
text ‹The \emph{residual graph} of a network and a flow indicates how much
flow can be effectively pushed along or reverse to a network edge,
by increasing or decreasing the flow on that edge:›
definition residualGraph :: "_ graph => _ flow => _ graph"
where "residualGraph c f ≡ λ(u, v).
if (u, v) ∈ Graph.E c then
c (u, v) - f (u, v)
else if (v, u) ∈ Graph.E c then
f (v, u)
else
0"
notation (in Graph_Syntax) residualGraph ("〈\<C>⇩\<f>/ _,/ _〉" 1000)
text ‹Let's fix a network with a flow @{term f} on it›
context NFlow
begin
text ‹We abbreviate the residual graph by @{term cf}.›
abbreviation "cf ≡ residualGraph c f"
sublocale cf!: Graph cf .
lemmas cf_def = residualGraph_def[of c f]
subsection ‹Properties›
text ‹The edges of the residual graph are either parallel or reverse
to the edges of the network.›
lemma cfE_ss_invE: "Graph.E cf ⊆ E ∪ E¯"
unfolding residualGraph_def Graph.E_def
by auto
text ‹The nodes of the residual graph are exactly the nodes of the network.›
lemma resV_netV[simp]: "cf.V = V"
proof
show "V ⊆ Graph.V cf"
proof
fix u
assume "u ∈ V"
then obtain v where "(u, v) ∈ E ∨ (v, u) ∈ E" unfolding V_def by auto
moreover {
assume "(u, v) ∈ E"
then have "(u, v) ∈ Graph.E cf ∨ (v, u) ∈ Graph.E cf"
proof (cases)
assume "f (u, v) = 0"
then have "cf (u, v) = c (u, v)"
unfolding residualGraph_def using `(u, v) ∈ E` by (auto simp:)
then have "cf (u, v) ≠ 0" using `(u, v) ∈ E` unfolding E_def by auto
thus ?thesis unfolding Graph.E_def by auto
next
assume "f (u, v) ≠ 0"
then have "cf (v, u) = f (u, v)" unfolding residualGraph_def
using `(u, v) ∈ E` no_parallel_edge by auto
then have "cf (v, u) ≠ 0" using ‹f (u, v) ≠ 0› by auto
thus ?thesis unfolding Graph.E_def by auto
qed
} moreover {
assume "(v, u) ∈ E"
then have "(v, u) ∈ Graph.E cf ∨ (u, v) ∈ Graph.E cf"
proof (cases)
assume "f (v, u) = 0"
then have "cf (v, u) = c (v, u)"
unfolding residualGraph_def using `(v, u) ∈ E` by (auto)
then have "cf (v, u) ≠ 0" using `(v, u) ∈ E` unfolding E_def by auto
thus ?thesis unfolding Graph.E_def by auto
next
assume "f (v, u) ≠ 0"
then have "cf (u, v) = f (v, u)" unfolding residualGraph_def
using `(v, u) ∈ E` no_parallel_edge by auto
then have "cf (u, v) ≠ 0" using ‹f (v, u) ≠ 0› by auto
thus ?thesis unfolding Graph.E_def by auto
qed
} ultimately show "u∈cf.V" unfolding cf.V_def by auto
qed
next
show "Graph.V cf ⊆ V" using cfE_ss_invE unfolding Graph.V_def by auto
qed
text ‹Note, that Isabelle is powerful enough to prove the above case
distinctions completely automatically, although it takes some time:›
lemma "cf.V = V"
unfolding residualGraph_def Graph.E_def Graph.V_def
using no_parallel_edge[unfolded E_def]
by auto
text ‹As the residual graph has the same nodes as the network, it is also finite:›
sublocale cf!: Finite_Graph cf
by unfold_locales auto
text ‹The capacities on the edges of the residual graph are non-negative›
lemma resE_nonNegative: "cf e ≥ 0"
proof (cases e; simp)
fix u v
{
assume "(u, v) ∈ E"
then have "cf (u, v) = c (u, v) - f (u, v)" unfolding cf_def by auto
hence "cf (u,v) ≥ 0"
using capacity_const cap_non_negative by auto
} moreover {
assume "(v, u) ∈ E"
then have "cf (u,v) = f (v, u)"
using no_parallel_edge unfolding cf_def by auto
hence "cf (u,v) ≥ 0"
using capacity_const by auto
} moreover {
assume "(u, v) ∉ E" "(v, u) ∉ E"
hence "cf (u,v) ≥ 0" unfolding residualGraph_def by simp
} ultimately show "cf (u,v) ≥ 0" by blast
qed
text ‹Again, there is an automatic proof›
lemma "cf e ≥ 0"
apply (cases e)
unfolding residualGraph_def
using no_parallel_edge capacity_const cap_positive
by auto
text ‹All edges of the residual graph are labeled with positive capacities:›
corollary resE_positive: "e ∈ cf.E ==> cf e > 0"
proof -
assume "e ∈ cf.E"
hence "cf e ≠ 0" unfolding cf.E_def by auto
thus ?thesis using resE_nonNegative by (meson eq_iff not_le)
qed
lemma reverse_flow: "Flow cf s t f' ==> ∀(u, v) ∈ E. f' (v, u) ≤ f (u, v)"
proof -
assume asm: "Flow cf s t f'"
{
fix u v
assume "(u, v) ∈ E"
then have "cf (v, u) = f (u, v)"
unfolding residualGraph_def using no_parallel_edge by auto
moreover have "f' (v, u) ≤ cf (v, u)" using asm[unfolded Flow_def] by auto
ultimately have "f' (v, u) ≤ f (u, v)" by metis
}
thus ?thesis by auto
qed
end -- ‹Network with flow›
end -- ‹Theory›