Theory Bellman_Ford
subsection ‹The Bellman-Ford Algorithm›
theory Bellman_Ford
imports
"HOL-Library.IArray"
"HOL-Library.Code_Target_Numeral"
"HOL-Library.Product_Lexorder"
"HOL-Library.RBT_Mapping"
"../heap_monad/Heap_Main"
Example_Misc
"../util/Tracing"
"../util/Ground_Function"
begin
subsubsection ‹Misc›
lemma nat_le_cases:
fixes n :: nat
assumes "i ≤ n"
obtains "i < n" | "i = n"
using assms by (cases "i = n") auto
context dp_consistency_iterator
begin
lemma crel_vs_iterate_state:
"crel_vs (=) () (iter_state f x)" if "((=) ===>⇩T R) g f"
by (metis crel_vs_iterate_state iter_state_iterate_state that)
lemma consistent_crel_vs_iterate_state:
"crel_vs (=) () (iter_state f x)" if "consistentDP f"
using consistentDP_def crel_vs_iterate_state that by simp
end
instance extended :: (countable) countable
proof standard
obtain to_nat :: "'a ⇒ nat" where "inj to_nat"
by auto
let ?f = "λ x. case x of Fin n ⇒ to_nat n + 2 | Pinf ⇒ 0 | Minf ⇒ 1"
from ‹inj _ › have "inj ?f"
by (auto simp: inj_def split: extended.split)
then show "∃to_nat :: 'a extended ⇒ nat. inj to_nat"
by auto
qed
instance extended :: (heap) heap ..
instantiation "extended" :: (conditionally_complete_lattice) complete_lattice
begin
definition
"Inf A = (
if A = {} ∨ A = {∞} then ∞
else if -∞ ∈ A ∨ ¬ bdd_below (Fin -` A) then -∞
else Fin (Inf (Fin -` A)))"
definition
"Sup A = (
if A = {} ∨ A = {-∞} then -∞
else if ∞ ∈ A ∨ ¬ bdd_above (Fin -` A) then ∞
else Fin (Sup (Fin -` A)))"
instance
proof standard
have [dest]: "Inf (Fin -` A) ≤ x" if "Fin x ∈ A" "bdd_below (Fin -` A)" for A and x :: 'a
using that by (intro cInf_lower) auto
have *: False if "¬ z ≤ Inf (Fin -` A)" "⋀x. x ∈ A ⟹ Fin z ≤ x" "Fin x ∈ A" for A and x z :: 'a
using cInf_greatest[of "Fin -` A" z] that vimage_eq by force
show "Inf A ≤ x" if "x ∈ A" for x :: "'a extended" and A
using that unfolding Inf_extended_def by (cases x) auto
show "z ≤ Inf A" if "⋀x. x ∈ A ⟹ z ≤ x" for z :: "'a extended" and A
using that
unfolding Inf_extended_def
apply (clarsimp; safe)
apply force
apply force
subgoal
by (cases z; force simp: bdd_below_def)
subgoal
by (cases z; force simp: bdd_below_def)
subgoal for x y
by (cases z; cases y) (auto elim: *)
subgoal for x y
by (cases z; cases y; simp; metis * less_eq_extended.elims(2))
done
have [dest]: "x ≤ Sup (Fin -` A)" if "Fin x ∈ A" "bdd_above (Fin -` A)" for A and x :: 'a
using that by (intro cSup_upper) auto
have *: False if "¬ Sup (Fin -` A) ≤ z" "⋀x. x ∈ A ⟹ x ≤ Fin z" "Fin x ∈ A" for A and x z :: 'a
using cSup_least[of "Fin -` A" z] that vimage_eq by force
show "x ≤ Sup A" if "x ∈ A" for x :: "'a extended" and A
using that unfolding Sup_extended_def by (cases x) auto
show "Sup A ≤ z" if "⋀x. x ∈ A ⟹ x ≤ z" for z :: "'a extended" and A
using that
unfolding Sup_extended_def
apply (clarsimp; safe)
apply force
apply force
subgoal
by (cases z; force)
subgoal
by (cases z; force)
subgoal for x y
by (cases z; cases y) (auto elim: *)
subgoal for x y
by (cases z; cases y; simp; metis * extended.exhaust)
done
show "Inf {} = (top::'a extended)"
unfolding Inf_extended_def top_extended_def by simp
show "Sup {} = (bot::'a extended)"
unfolding Sup_extended_def bot_extended_def by simp
qed
end
instance "extended" :: ("{conditionally_complete_lattice,linorder}") complete_linorder ..
lemma Minf_eq_zero[simp]: "-∞ = 0 ⟷ False" and Pinf_eq_zero[simp]: "∞ = 0 ⟷ False"
unfolding zero_extended_def by auto
lemma Sup_int:
fixes x :: int and X :: "int set"
assumes "X ≠ {}" "bdd_above X"
shows "Sup X ∈ X ∧ (∀y∈X. y ≤ Sup X)"
proof -
from assms obtain x y where "X ⊆ {..y}" "x ∈ X"
by (auto simp: bdd_above_def)
then have *: "finite (X ∩ {x..y})" "X ∩ {x..y} ≠ {}" and "x ≤ y"
by (auto simp: subset_eq)
have "∃!x∈X. (∀y∈X. y ≤ x)"
proof
{ fix z assume "z ∈ X"
have "z ≤ Max (X ∩ {x..y})"
proof cases
assume "x ≤ z" with ‹z ∈ X› ‹X ⊆ {..y}› *(1) show ?thesis
by (auto intro!: Max_ge)
next
assume "¬ x ≤ z"
then have "z < x" by simp
also have "x ≤ Max (X ∩ {x..y})"
using ‹x ∈ X› *(1) ‹x ≤ y› by (intro Max_ge) auto
finally show ?thesis by simp
qed }
note le = this
with Max_in[OF *] show ex: "Max (X ∩ {x..y}) ∈ X ∧ (∀z∈X. z ≤ Max (X ∩ {x..y}))" by auto
fix z assume *: "z ∈ X ∧ (∀y∈X. y ≤ z)"
with le have "z ≤ Max (X ∩ {x..y})"
by auto
moreover have "Max (X ∩ {x..y}) ≤ z"
using * ex by auto
ultimately show "z = Max (X ∩ {x..y})"
by auto
qed
then show "Sup X ∈ X ∧ (∀y∈X. y ≤ Sup X)"
unfolding Sup_int_def by (rule theI')
qed
lemmas Sup_int_in = Sup_int[THEN conjunct1]
lemma Inf_int_in:
fixes S :: "int set"
assumes "S ≠ {}" "bdd_below S"
shows "Inf S ∈ S"
using assms unfolding Inf_int_def by (smt Sup_int_in bdd_above_uminus image_iff image_is_empty)
lemma finite_setcompr_eq_image: "finite {f x |x. P x} ⟷ finite (f ` {x. P x})"
by (simp add: setcompr_eq_image)
lemma finite_lists_length_le1: "finite {xs. length xs ≤ i ∧ set xs ⊆ {0..(n::nat)}}" for i
by (auto intro: finite_subset[OF _ finite_lists_length_le[OF finite_atLeastAtMost]])
lemma finite_lists_length_le2: "finite {xs. length xs + 1 ≤ i ∧ set xs ⊆ {0..(n::nat)}}" for i
by (auto intro: finite_subset[OF _ finite_lists_length_le1[of "i"]])
lemmas [simp] =
finite_setcompr_eq_image finite_lists_length_le2[simplified] finite_lists_length_le1
lemma get_return:
"run_state (State_Monad.bind State_Monad.get (λ m. State_Monad.return (f m))) m = (f m, m)"
by (simp add: State_Monad.bind_def State_Monad.get_def)
lemma list_pidgeonhole:
assumes "set xs ⊆ S" "card S < length xs" "finite S"
obtains as a bs cs where "xs = as @ a # bs @ a # cs"
proof -
from assms have "¬ distinct xs"
by (metis card_mono distinct_card not_le)
then show ?thesis
by (metis append.assoc append_Cons not_distinct_conv_prefix split_list that)
qed
lemma path_eq_cycleE:
assumes "v # ys @ [t] = as @ a # bs @ a # cs"
obtains (Nil_Nil) "as = []" "cs = []" "v = a" "a = t" "ys = bs"
| (Nil_Cons) cs' where "as = []" "v = a" "ys = bs @ a # cs'" "cs = cs' @ [t]"
| (Cons_Nil) as' where "as = v # as'" "cs = []" "a = t" "ys = as' @ a # bs"
| (Cons_Cons) as' cs' where "as = v # as'" "cs = cs' @ [t]" "ys = as' @ a # bs @ a # cs'"
using assms by (auto simp: Cons_eq_append_conv append_eq_Cons_conv append_eq_append_conv2)
lemma le_add_same_cancel1:
"a + b ≥ a ⟷ b ≥ 0" if "a < ∞" "-∞ < a" for a b :: "int extended"
using that by (cases a; cases b) (auto simp add: zero_extended_def)
lemma add_gt_minfI:
assumes "-∞ < a" "-∞ < b"
shows "-∞ < a + b"
using assms by (cases a; cases b) auto
lemma add_lt_infI:
assumes "a < ∞" "b < ∞"
shows "a + b < ∞"
using assms by (cases a; cases b) auto
lemma sum_list_not_infI:
"sum_list xs < ∞" if "∀ x ∈ set xs. x < ∞" for xs :: "int extended list"
using that
apply (induction xs)
apply (simp add: zero_extended_def)+
by (smt less_extended_simps(2) plus_extended.elims)
lemma sum_list_not_minfI:
"sum_list xs > -∞" if "∀ x ∈ set xs. x > -∞" for xs :: "int extended list"
using that by (induction xs) (auto intro: add_gt_minfI simp: zero_extended_def)
subsubsection ‹Single-Sink Shortest Path Problem›