Theory BMSSP_Concrete_Step
theory BMSSP_Concrete_Step
imports BMSSP_Pull_Minimum
begin
section ‹Concrete One-Step BMSSP Assembly›
text ‹
This theory packages the concrete part of a non-base BMSSP call. The
abstract correctness skeleton states its recursive middle phase with the
predicate ‹partition_loop_post›: after FindPivots has chosen a pivot
set, the loop must solve the bounded tree induced by those pivots. That
statement is intentionally compact, but it hides the range structure that the
implementation actually follows.
The concrete step exposed here replaces that abstract loop contract by an
explicit monotone trace of child ranges. A trace contains the first lower
boundary, the list of subsequent boundaries, the label function after the
loop, and the collection of vertex sets solved by the child calls. The trace
proof checks that the boundaries are nondecreasing, remain below the returned
BMSSP bound, and cover exactly the chain of bounded shortest-path trees that
the partition loop is supposed to assemble.
The final step definitions then restore FindPivots. The uncapped version
uses the conceptual FindPivots operation, while the capped version uses the
executable bounded search from the paper. Both definitions have the same
shape: perform FindPivots, solve the pivot loop, keep the vertices completed
directly by FindPivots, and return their union. The two correctness theorems
below show that this concrete assembly is still a valid
‹bmssp_post_full› result.
›
context unique_shortest_digraph
begin
definition concrete_partition_loop_trace where
"concrete_partition_loop_trace P B a bs d' B' Us U ⟷
bound_le B' B ∧
nondecreasing_from a bs ∧
bounds_le B' (a # bs) ∧
complete_on d' (bound_tree P (Fin a)) ∧
list_all2 (λU X. U = X ∧ complete_on d' U) Us
(range_tree_chain_list P a bs B') ∧
U = bound_tree P (Fin a) ∪ ⋃(set Us)"
theorem concrete_partition_loop_trace_post:
assumes trace: "concrete_partition_loop_trace P B a bs d' B' Us U"
shows "bmssp_post_full d P B d' B' U"
proof -
have le: "bound_le B' B"
and mono: "nondecreasing_from a bs"
and bounds: "bounds_le B' (a # bs)"
and lower: "complete_on d' (bound_tree P (Fin a))"
and children: "list_all2 (λU X. U = X ∧ complete_on d' U) Us
(range_tree_chain_list P a bs B')"
and U: "U = bound_tree P (Fin a) ∪ ⋃(set Us)"
using trace unfolding concrete_partition_loop_trace_def by blast+
show ?thesis
by (rule partition_loop_trace_assembly_post
[OF le mono bounds lower children U])
qed
definition concrete_bmssp_step where
"concrete_bmssp_step k d S B a bs d' B' Us U ⟷
(let d_fp = find_pivots_label k d S B;
P = find_pivots_pivots k d S B;
W = {v ∈ bound_tree S B'. d_fp v = dist s v}
in ∃U_loop.
concrete_partition_loop_trace P B a bs d' B' Us U_loop ∧
complete_on d' W ∧
U = U_loop ∪ W)"
definition concrete_capped_bmssp_step where
"concrete_capped_bmssp_step k cap d S B a bs d' B' Us U ⟷
(let d_fp = find_pivots_label_capped k cap d S B;
P = find_pivots_pivots_capped k cap d S B;
W = {v ∈ bound_tree S B'. d_fp v = dist s v}
in ∃U_loop.
concrete_partition_loop_trace P B a bs d' B' Us U_loop ∧
complete_on d' W ∧
U = U_loop ∪ W)"
text ‹
The definition @{const concrete_partition_loop_trace} is the local certificate
for the recursive partition loop. It does not say how pulls are generated;
it says what must be true of the resulting range sequence. The theorem
@{thm concrete_partition_loop_trace_post} then converts such a trace into
@{const bmssp_post_full} for the pivot set. The step predicates
@{const concrete_bmssp_step} and @{const concrete_capped_bmssp_step} wrap the
trace with FindPivots and the final union of loop-completed and
FindPivots-completed vertices.
›
theorem concrete_bmssp_step_correct:
assumes sound: "sound_label d"
and pre: "bmssp_pre_full d S B"
and S_reaches: "⋀x. x ∈ S ⟹ reachable s x"
and step: "concrete_bmssp_step k d S B a bs d' B' Us U"
shows "bmssp_post_full d S B d' B' U"
proof -
let ?d_fp = "find_pivots_label k d S B"
let ?P = "find_pivots_pivots k d S B"
let ?W = "{v ∈ bound_tree S B'. ?d_fp v = dist s v}"
obtain U_loop where
trace: "concrete_partition_loop_trace ?P B a bs d' B' Us U_loop"
and compW: "complete_on d' ?W"
and U: "U = U_loop ∪ ?W"
using step unfolding concrete_bmssp_step_def by (auto simp: Let_def)
have loop: "bmssp_post_full ?d_fp ?P B d' B' U_loop"
using concrete_partition_loop_trace_post[OF trace] .
have le: "bound_le B' B"
using loop unfolding bmssp_post_full_def by blast
have U_tree: "U_loop ∪ ?W = bound_tree S B'"
using concrete_find_pivots_final_tree_assembly[OF sound pre S_reaches loop] .
have loop_complete: "complete_on d' U_loop"
using loop unfolding bmssp_post_full_def by blast
have complete: "complete_on d' (U_loop ∪ ?W)"
using complete_on_Un[OF loop_complete compW] .
have "bmssp_post_full d S B d' B' (U_loop ∪ ?W)"
using le U_tree complete unfolding bmssp_post_full_def by blast
then show ?thesis
using U by simp
qed
theorem concrete_capped_bmssp_step_correct:
assumes sound: "sound_label d"
and pre: "bmssp_pre_full d S B"
and S_reaches: "⋀x. x ∈ S ⟹ reachable s x"
and step: "concrete_capped_bmssp_step k cap d S B a bs d' B' Us U"
shows "bmssp_post_full d S B d' B' U"
proof -
let ?d_fp = "find_pivots_label_capped k cap d S B"
let ?P = "find_pivots_pivots_capped k cap d S B"
let ?W = "{v ∈ bound_tree S B'. ?d_fp v = dist s v}"
obtain U_loop where
trace: "concrete_partition_loop_trace ?P B a bs d' B' Us U_loop"
and compW: "complete_on d' ?W"
and U: "U = U_loop ∪ ?W"
using step unfolding concrete_capped_bmssp_step_def by (auto simp: Let_def)
have loop: "bmssp_post_full ?d_fp ?P B d' B' U_loop"
using concrete_partition_loop_trace_post[OF trace] .
have le: "bound_le B' B"
using loop unfolding bmssp_post_full_def by blast
have U_tree: "U_loop ∪ ?W = bound_tree S B'"
using concrete_capped_find_pivots_final_tree_assembly[OF sound pre S_reaches loop] .
have loop_complete: "complete_on d' U_loop"
using loop unfolding bmssp_post_full_def by blast
have complete: "complete_on d' (U_loop ∪ ?W)"
using complete_on_Un[OF loop_complete compW] .
have "bmssp_post_full d S B d' B' (U_loop ∪ ?W)"
using le U_tree complete unfolding bmssp_post_full_def by blast
then show ?thesis
using U by simp
qed
end
end