Theory BMSSP_Partition_Pull_Bridge
theory BMSSP_Partition_Pull_Bridge
imports BMSSP_Pull_Minimum BMSSP_Partition_Interface
begin
section ‹Partition Pull to BMSSP Pull Minimum›
text ‹
The partition interface is graph-independent: it knows about keys and labels,
but not about shortest-path trees. BMSSP, on the other hand, phrases a child
recursive call as a lower split of the current source set by a tentative
distance bound. This small bridge theory identifies those two views.
The conversion is simple but important. A label function ‹d› and a source
set ‹S› induce a partition view whose keys are exactly ‹S› and whose
values are the labels ‹d›. A pull from that view is therefore a pull by
tentative distance. The theorems below prove that the pulled key set is
exactly ‹split_below› at the returned bound, and that the BMSSP
precondition descends from the parent problem to the child problem selected by
the pull.
This file is used twice in the development. The sorted reference pull uses it
to justify the executable specification path. The operational and bucketed
theories use the abstract @{const pull_separates} statement, so they can
reason about BMSSP recursion without mentioning the representation of the
partition data structure.
›
context unique_shortest_digraph
begin
definition label_partition_view where
"label_partition_view d S = ⦇keys_of = S, value_of = d⦈"
lemma label_partition_view_keys [simp]:
"keys_of (label_partition_view d S) = S"
unfolding label_partition_view_def by simp
lemma label_partition_view_value [simp]:
"value_of (label_partition_view d S) = d"
unfolding label_partition_view_def by simp
text ‹
The first two theorems are the semantic translation. For the sorted reference
operation, ‹sorted_pull_set_eq_split_below› unfolds the sorted pull and the
label partition view to obtain the mathematical lower split. For any
implementation satisfying the abstract separator predicate,
‹pull_separates_label_set_eq_split_below› gives the same conclusion from
@{const pull_separates}. The latter is the theorem used by the bucketed
implementation after it proves its pull operation realises the separator
contract.
›
theorem sorted_pull_set_eq_split_below:
fixes M :: nat
and Bmax :: real
assumes finite_S: "finite S"
and upper: "⋀u. u ∈ S ⟹ d u < Bmax"
and D_def: "D = label_partition_view d S"
and beta_def: "beta = sorted_pull_bound M Bmax D"
shows "sorted_pull_set M D = split_below d S beta"
proof -
have "sorted_pull_set M D =
{u ∈ keys_of D. value_of D u < sorted_pull_bound M Bmax D}"
using sorted_pull_exact_split[of D Bmax M] finite_S upper
unfolding D_def by simp
then show ?thesis
unfolding D_def beta_def split_below_def by simp
qed
theorem pull_separates_label_set_eq_split_below:
fixes Bmax :: real
assumes pull: "pull_separates (label_partition_view d S) M Bmax S' beta D'"
and upper: "⋀u. u ∈ S ⟹ d u < Bmax"
shows "S' = split_below d S beta"
proof -
have "S' =
{u ∈ keys_of (label_partition_view d S).
value_of (label_partition_view d S) u < beta}"
by (rule pull_separates_exact_split[OF pull]) (simp add: upper)
then show ?thesis
unfolding split_below_def by simp
qed
theorem sorted_pull_establishes_lower_pre:
fixes M :: nat
and Bmax :: real
assumes pre: "bmssp_pre_full d S (Fin Bmax)"
and upper: "⋀u. u ∈ S ⟹ d u < Bmax"
and D_def: "D = label_partition_view d S"
and S'_def: "S' = sorted_pull_set M D"
and beta_def: "beta = sorted_pull_bound M Bmax D"
shows "bmssp_pre_full d S' (Fin beta)"
proof -
have S_subset: "S ⊆ V"
using pre unfolding bmssp_pre_full_def by blast
have finite_S: "finite S"
using finite_subset[OF S_subset finite_V] .
let ?xs = "partition_key_order D"
have set_xs: "set ?xs = S"
using partition_key_order_properties(1)[of D] finite_S
unfolding D_def by simp
show ?thesis
proof (cases "length ?xs ≤ M")
case True
have S'_eq: "S' = S"
using True set_xs unfolding S'_def sorted_pull_set_def by (simp add: Let_def)
have beta_eq: "beta = Bmax"
using True unfolding beta_def sorted_pull_bound_def by (simp add: Let_def)
show ?thesis
using pre unfolding S'_eq beta_eq .
next
case False
then have M_lt: "M < length ?xs"
by simp
have beta_eq: "beta = d (?xs ! M)"
using False unfolding beta_def sorted_pull_bound_def D_def by (simp add: Let_def)
have nth_in: "?xs ! M ∈ S"
using set_xs M_lt nth_mem by metis
have beta_lt: "beta < Bmax"
using upper[OF nth_in] beta_eq by simp
have S'_split: "S' = split_below d S beta"
using sorted_pull_set_eq_split_below[OF finite_S upper D_def beta_def]
unfolding S'_def .
show ?thesis
unfolding S'_split
by (rule pull_minimum_pre_for_lower_split[OF pre]) (simp add: beta_lt)
qed
qed
text ‹
The final theorem packages the precondition transfer needed by a recursive
BMSSP child call. If the parent problem is valid up to ‹Bmax› and all
current source labels lie below ‹Bmax›, then the set returned by a sorted
pull is valid up to the returned child bound. The all-keys case is just the
parent precondition again; the proper-prefix case uses the pull-minimum lemma
for lower splits.
Later operational proofs use this theorem as a template for arbitrary
partition implementations: once a pull is known to select the same lower
split, the recursive child precondition follows from the same argument.
›
end
end