Theory BMSSP_Bucketed_Cost_Bridge
theory BMSSP_Bucketed_Cost_Bridge
imports BMSSP_Bucketed_Partition BMSSP_Top_Level_Bounds
begin
section ‹Bridging the Bucketed Operation Costs to the Schedule Parameters›
text ‹
This theory closes the gap between the two cost layers of the development.
The costed BMSSP recurrence (the relations ‹direct_insert_costed_bmssp› and
‹exact_concrete_bmssp›) charges every direct insert at the
abstract parameter ‹t› and every batch-prepended item at the abstract
parameter ‹h›, through the predicates @{const partition_insert_cost_bound}
and @{const partition_batch_cost_bound}. The top-level analysis then sets
‹t› to the two-thirds logarithmic schedule parameter and ‹h› to the
one-third parameter.
Independently, the bucketed partition theory proves that its concrete
operations realise the abstract predicates with the
paper-tight budgets @{const bp_insert_paper_budget} and
@{const bp_batch_prepend_paper_budget}, each of the shape
‹const + floor_log (Suc (N div M))›.
What was missing is the arithmetic bridge: the realised bucketed budget
‹const + floor_log (Suc (N div M))› is no larger than the schedule parameter
whenever the ratio ‹N div M› is below the corresponding power of two. The
bucket directory is searched in ‹floor_log (Suc (N div M))› steps, so the only
fact needed is that @{const floor_log} of a number strictly below ‹2 ^ E›
does not exceed ‹E›. This theory proves that arithmetic, packages it into the
two interface predicates, and exposes the resulting connected statements:
with the bucketed costs in force, the per-level ratio bound is exactly what
makes the abstract Insert and BatchPrepend cost parameters realisable at the
logarithmic schedule scales used by the headline recurrence.
›
subsection ‹Logarithmic Arithmetic›
text ‹
The single arithmetic fact underlying the whole bridge: if a positive number
is strictly below ‹2 ^ E›, its binary logarithm is at most ‹E›. Everything
about the bucketed budgets reduces to this through monotonicity of
@{const floor_log}.
›
lemma floor_log_less_exp2_le:
assumes "n < 2 ^ E"
shows "floor_log n ≤ E"
proof -
have "n ≤ 2 ^ E"
using assms by simp
then have "floor_log n ≤ floor_log (2 ^ E)"
by (rule floor_log_le_iff)
also have "… = E"
by (rule floor_log_power)
finally show ?thesis .
qed
lemma floor_log_Suc_div_le:
assumes "Suc (N div M) ≤ 2 ^ E"
shows "floor_log (Suc (N div M)) ≤ E"
proof -
have "floor_log (Suc (N div M)) ≤ floor_log (2 ^ E)"
using assms by (rule floor_log_le_iff)
also have "… = E"
by (rule floor_log_power)
finally show ?thesis .
qed
text ‹
The ratio condition we use throughout: at most ‹2 ^ E› blocks worth of
entries are live, i.e. ‹N div M < 2 ^ E›. Equivalently ‹Suc (N div M) ≤
2 ^ E›, the form consumed by @{thm floor_log_Suc_div_le}.
›
definition ratio_below_pow2 :: "nat ⇒ nat ⇒ nat ⇒ bool" where
"ratio_below_pow2 N M E ⟷ N div M < 2 ^ E"
lemma ratio_below_pow2_floor_log:
assumes "ratio_below_pow2 N M E"
shows "floor_log (Suc (N div M)) ≤ E"
proof -
have "Suc (N div M) ≤ 2 ^ E"
using assms unfolding ratio_below_pow2_def by simp
then show ?thesis
by (rule floor_log_Suc_div_le)
qed
subsection ‹Bucketed Budgets at the Ratio Bound›
text ‹
Under the ratio bound the two paper budgets collapse to a constant plus the
exponent ‹E›. These are the budgets that the realisation corollaries
@{thm bp_realises_partition_insert_cost_bound} and
@{thm bp_realises_partition_batch_cost_bound} attach to the concrete bucketed
operations.
›
lemma bp_insert_paper_budget_le_const_plus_exp:
assumes "ratio_below_pow2 N M E"
shows "bp_insert_paper_budget N M ≤ 9 + E"
unfolding bp_insert_paper_budget_def
using ratio_below_pow2_floor_log[OF assms] by simp
lemma bp_batch_prepend_paper_budget_le_const_plus_exp:
assumes "ratio_below_pow2 N M E"
shows "bp_batch_prepend_paper_budget N M ≤ 2 + E"
unfolding bp_batch_prepend_paper_budget_def
using ratio_below_pow2_floor_log[OF assms] by simp
subsection ‹Monotonicity of the Abstract Cost Predicates›
text ‹
The abstract cost predicates are ‹c ≤ t› and ‹c ≤ t * length xs›, so they are
monotone in the budget parameter. Weakening a realised budget to a larger one
therefore preserves the predicate; this is what lets us replace the precise
bucketed budget by the constant-plus-exponent bound and then by the schedule
parameter.
›
lemma partition_insert_cost_bound_mono:
fixes c t t' :: nat
assumes "partition_insert_cost_bound c t"
and "t ≤ t'"
shows "partition_insert_cost_bound c t'"
proof -
have "c ≤ t"
using assms(1) unfolding partition_insert_cost_bound_def .
then have "c ≤ t'"
using assms(2) by (rule le_trans)
then show ?thesis
unfolding partition_insert_cost_bound_def .
qed
lemma partition_batch_cost_bound_mono:
fixes c t t' :: nat
assumes "partition_batch_cost_bound c t xs"
and "t ≤ t'"
shows "partition_batch_cost_bound c t' xs"
proof -
have "c ≤ t * length xs"
using assms(1) unfolding partition_batch_cost_bound_def .
also have "… ≤ t' * length xs"
using assms(2) by (rule mult_right_mono) simp
finally show ?thesis
unfolding partition_batch_cost_bound_def .
qed
subsection ‹Bucketed Operations Realise the Schedule Cost Parameters›
text ‹
These are the central connecting facts. Each says: the \emph{actual} step
count of a concrete bucketed operation satisfies the abstract cost predicate
with the budget set to ‹const + E›, provided the operation runs on a state
whose live ratio is below ‹2 ^ E›. No free abstract parameter remains: the
budget is the measured cost of the bucketed implementation, bounded through
the logarithmic arithmetic above.
These bridge the realisation corollaries
@{thm bp_realises_partition_insert_cost_bound} and
@{thm bp_realises_partition_batch_cost_bound} (which exhibit the budget as
\emph{some} value equal to the paper budget) to a concrete, schedule-facing
inequality.
›
theorem c_bp_paper_insert_realises_const_plus_exp:
assumes reg: "bp_regular_invariant P"
and ratio: "ratio_below_pow2 (length (bp_entries P)) (bp_block_size P) E"
shows "partition_insert_cost_bound
(bp_steps_of (c_bp_paper_insert x b P)) (9 + E)"
proof -
have base: "partition_insert_cost_bound
(bp_steps_of (c_bp_paper_insert x b P))
(bp_lazy_insert_amortized_budget P)"
by (rule c_bp_paper_insert_regular_partition_insert_cost_bound[OF reg])
have budget_eq: "bp_lazy_insert_amortized_budget P =
bp_insert_paper_budget (length (bp_entries P)) (bp_block_size P)"
by (rule bp_lazy_insert_amortized_budget_paper_form)
have budget_le: "bp_insert_paper_budget
(length (bp_entries P)) (bp_block_size P) ≤ 9 + E"
by (rule bp_insert_paper_budget_le_const_plus_exp[OF ratio])
show ?thesis
by (rule partition_insert_cost_bound_mono[OF base])
(use budget_eq budget_le in linarith)
qed
theorem c_bp_paper_batch_prepend_realises_const_plus_exp:
assumes ratio: "ratio_below_pow2 (length xs) (bp_block_size P) E"
shows "partition_batch_cost_bound
(bp_steps_of (c_bp_paper_batch_prepend xs P)) (2 + E) xs"
proof -
have base: "partition_batch_cost_bound
(bp_steps_of (c_bp_paper_batch_prepend xs P))
(bp_ratio_log_budget (length xs) (bp_block_size P)) xs"
by (rule c_bp_paper_batch_prepend_batch_cost_bound)
have budget_le: "bp_ratio_log_budget (length xs) (bp_block_size P) ≤ 2 + E"
proof -
have "bp_ratio_log_budget (length xs) (bp_block_size P) ≤
bp_batch_prepend_paper_budget (length xs) (bp_block_size P)"
by (rule bp_ratio_log_budget_le_batch_prepend_paper_budget)
also have "… ≤ 2 + E"
by (rule bp_batch_prepend_paper_budget_le_const_plus_exp[OF ratio])
finally show ?thesis .
qed
show ?thesis
by (rule partition_batch_cost_bound_mono[OF base budget_le])
qed
text ‹
The Pull cost needs no ratio bound: the bucketed Pull already realises the
abstract pull predicate exactly (cost ‹= card S›), independent of the live
ratio. We re-expose it here so the three operation costs sit together as the
connected interface used by the recurrence.
›
theorem c_bp_paper_pull_realises_partition_pull_cost_bound:
assumes pull: "bp_result_of (c_bp_paper_pull M B P) = (S, beta, P')"
shows "partition_pull_cost_bound (bp_steps_of (c_bp_paper_pull M B P)) S"
by (rule bp_realises_partition_pull_cost_bound[OF pull])
subsection ‹The Bucketed Cost Parameters Sit at the Schedule Scales›
text ‹
The previous theorems show, per operation, that the measured bucketed step
count satisfies the abstract cost predicate with budget ‹const + E›, where
‹E› is the live-ratio exponent. The headline recurrence is solved by
@{thm bmssp_refined_cost_bound_bigo_sssp_time_target_from_component_bounds},
which needs the Insert cost parameter ‹t› to grow like ‹log⇧2⇧/⇧3› and the
BatchPrepend cost parameter ‹H› to grow like ‹log⇧1⇧/⇧3›.
We now discharge exactly those two envelope facts for the bucketed budgets.
For Insert, the live ratio is allowed to reach the two-thirds schedule
parameter, so the budget is ‹9 + sssp_log_two_thirds_param n›; a constant
added to ‹log⇧2⇧/⇧3› is still ‹O(log⇧2⇧/⇧3)›. For BatchPrepend, the
per-pull batch has length at most a constant multiple of the block size
(bounded out-degree), so its ratio exponent is a constant ‹c›; the budget is
then ‹2 + c›, a constant, which is ‹O(log⇧1⇧/⇧3)› because the one-third
factor tends to infinity. These are the genuine reasons the bucketed costs
fit the deterministic schedule.
›
lemma sssp_log_factor_at_top:
"filterlim sssp_log_factor at_top at_top"
proof -
have "filterlim (λn. sssp_log_factor_one_third n * sssp_log_factor_one_third n)
at_top at_top"
by (rule filterlim_at_top_mult_at_top
[OF sssp_log_factor_one_third_at_top sssp_log_factor_one_third_at_top])
moreover have
"(λn. sssp_log_factor_one_third n * sssp_log_factor_one_third n) =
sssp_log_factor"
by (rule ext) (rule sssp_log_factor_one_third_square)
ultimately show ?thesis by simp
qed
text ‹
Insert envelope: a constant plus the two-thirds schedule parameter is
eventually dominated by twice the two-thirds log factor. This is the
@{term t_bound} hypothesis with the bucketed Insert budget in the parameter
slot.
›
lemma const_plus_two_thirds_param_le_two_thirds_factor:
"eventually
(λn. real (c + sssp_log_two_thirds_param n) ≤
real (c + 2) * sssp_log_factor n) at_top"
using eventually_one_le_sssp_log_factor
proof eventually_elim
case (elim n)
have one_le: "1 ≤ sssp_log_factor n"
using elim .
have param_le: "real (sssp_log_two_thirds_param n) ≤ sssp_log_factor n + 1"
proof -
have nonneg: "0 ≤ sssp_log_factor n"
using one_le by linarith
have "real (nat ⌈sssp_log_factor n⌉) = of_int ⌈sssp_log_factor n⌉"
using of_nat_int_ceiling[OF nonneg] .
moreover have "of_int ⌈sssp_log_factor n⌉ ≤ sssp_log_factor n + 1"
using ceiling_correct[of "sssp_log_factor n"] by linarith
ultimately show ?thesis
unfolding sssp_log_two_thirds_param_def by simp
qed
have c_le: "real c ≤ real c * sssp_log_factor n"
proof -
have "real c * 1 ≤ real c * sssp_log_factor n"
by (rule mult_left_mono[OF one_le]) simp
then show ?thesis by simp
qed
have "real (c + sssp_log_two_thirds_param n) =
real c + real (sssp_log_two_thirds_param n)"
by simp
also have "… ≤ real c + (sssp_log_factor n + 1)"
using param_le by linarith
also have "… ≤ real c * sssp_log_factor n + 2 * sssp_log_factor n"
using c_le one_le by linarith
also have "… = real (c + 2) * sssp_log_factor n"
by (simp add: algebra_simps)
finally show ?case .
qed
text ‹
BatchPrepend envelope: a constant budget is eventually dominated by any
positive multiple of the one-third log factor, because that factor tends to
infinity. This is the @{term H_bound} hypothesis with the bucketed
BatchPrepend budget (a constant under bounded out-degree) in the parameter
slot.
›
lemma const_le_one_third_factor:
"eventually
(λn. real (c::nat) ≤ sssp_log_factor_one_third n) at_top"
proof -
have "filterlim sssp_log_factor_one_third at_top at_top"
by (rule sssp_log_factor_one_third_at_top)
then have "eventually (λn. real c ≤ sssp_log_factor_one_third n) at_top"
unfolding filterlim_at_top by blast
then show ?thesis .
qed
text ‹
The two envelopes packaged as the schedule-facing component bounds. The first
states that the bucketed Insert cost parameter
‹λn. 9 + sssp_log_two_thirds_param n› is ‹O(log⇧2⇧/⇧3)›; the second that the
bucketed BatchPrepend cost parameter ‹λn. 2 + c› is ‹O(log⇧1⇧/⇧3)›. These
are exactly the ‹t_bound› and ‹H_bound› premises consumed by the recurrence
solver, now justified by the realised bucketed budgets instead of left as
free parameters.
›
theorem bucketed_insert_param_two_thirds_envelope:
"eventually
(λn. real (9 + sssp_log_two_thirds_param n) ≤
11 * sssp_log_factor n) at_top"
using const_plus_two_thirds_param_le_two_thirds_factor[of 9]
by simp
theorem bucketed_batch_param_one_third_envelope:
"eventually
(λn. real (2 + c) ≤ real (Suc (2 + c)) * sssp_log_factor_one_third n)
at_top"
using const_le_one_third_factor[of "2 + c"]
proof eventually_elim
case (elim n)
have nonneg: "0 ≤ sssp_log_factor_one_third n"
using sssp_log_factor_one_third_pos[of n] by linarith
have "real (2 + c) ≤ sssp_log_factor_one_third n"
using elim .
also have "… ≤ real (Suc (2 + c)) * sssp_log_factor_one_third n"
proof -
have "sssp_log_factor_one_third n * 1 ≤
sssp_log_factor_one_third n * real (Suc (2 + c))"
by (rule mult_left_mono) (use nonneg in simp_all)
then show ?thesis
by (simp add: mult.commute)
qed
finally show ?case .
qed
subsection ‹Connected Headline: Bucketed-Costed BMSSP is ‹O(m log⇧2⇧/⇧3 n)››
text ‹
The capstone. It plugs the bucketed cost parameters directly into the
recurrence solver
@{thm bmssp_refined_cost_bound_bigo_sssp_time_target_from_component_bounds}.
The Insert cost slot ‹t› carries the bucketed Insert budget
‹λn. 9 + sssp_log_two_thirds_param n›, and the BatchPrepend cost slot ‹H›
carries the bucketed BatchPrepend budget ‹λ_. 2 + cbatch› (a constant under
bounded out-degree, when the per-pull batch length stays within a constant
multiple of the block size). Crucially, no cost parameter is left free: both
are the measured bucketed budgets established above. The conclusion is the
deterministic SSSP target ‹O(m * log⇧2⇧/⇧3 n)›.
Recall the argument order of @{const bmssp_refined_graph_time_bound} is
‹A R H l t m n›, with body ‹2 A (2 l + 1) n + (R + t + l H) m›; here the
fifth argument ‹t› is the Insert cost and the third argument ‹H› is the
BatchPrepend per-item cost.
This theorem is what unifies the two previously separate claims of the entry:
the asymptotic recurrence (claim 2) and the bucketed operation costs (claim
3). In the original development the recurrence's Insert cost was a free
parameter that the headline simply set to the schedule scale; here that
parameter is the actual bucketed budget, and the bound still holds.
›
theorem bucketed_refined_cost_bigo_sssp_time_target:
fixes m A l R T :: "nat ⇒ nat"
and cbatch :: nat
and Cn Ca Cl Cr :: real
assumes Cn_pos: "0 < Cn"
and Ca_pos: "0 < Ca"
and Cl_nonneg: "0 ≤ Cl"
and Cr_pos: "0 < Cr"
and vertex_count_dominated:
"eventually (λn. real n ≤ Cn * real (m n)) at_top"
and A_bound:
"eventually (λn. real (A n) ≤ Ca * sssp_log_factor_one_third n) at_top"
and l_bound:
"eventually (λn. real (l n) ≤ Cl * sssp_log_factor_one_third n) at_top"
and R_bound:
"eventually (λn. real (R n) ≤ Cr * sssp_log_factor n) at_top"
and cost_bound:
"eventually
(λn. T n ≤ bmssp_refined_graph_time_bound
A R (λ_. 2 + cbatch) l
(λn. 9 + sssp_log_two_thirds_param n) m n)
at_top"
shows "(λn. real (T n)) ∈ O(λn. sssp_time_target m n)"
proof (rule bmssp_refined_cost_bound_bigo_sssp_time_target_from_component_bounds
[where Cn = Cn and Ca = Ca and Cl = Cl and Cr = Cr
and Ct = 11 and Ch = "real (Suc (2 + cbatch))"
and A = A and l = l and R = R
and t = "λn. 9 + sssp_log_two_thirds_param n"
and H = "λ_. 2 + cbatch" and m = m and T = T])
show "0 < Cn" by (rule Cn_pos)
show "0 < Ca" by (rule Ca_pos)
show "0 ≤ Cl" by (rule Cl_nonneg)
show "0 < Cr" by (rule Cr_pos)
show "0 < (11::real)" by simp
show "0 < real (Suc (2 + cbatch))" by simp
show "eventually (λn. real n ≤ Cn * real (m n)) at_top"
by (rule vertex_count_dominated)
show "eventually (λn. real (A n) ≤ Ca * sssp_log_factor_one_third n) at_top"
by (rule A_bound)
show "eventually (λn. real (l n) ≤ Cl * sssp_log_factor_one_third n) at_top"
by (rule l_bound)
show "eventually (λn. real (R n) ≤ Cr * sssp_log_factor n) at_top"
by (rule R_bound)
show "eventually
(λn. real (9 + sssp_log_two_thirds_param n) ≤ 11 * sssp_log_factor n)
at_top"
by (rule bucketed_insert_param_two_thirds_envelope)
show "eventually
(λn. real ((λ_. 2 + cbatch) n) ≤
real (Suc (2 + cbatch)) * sssp_log_factor_one_third n) at_top"
by (rule bucketed_batch_param_one_third_envelope)
show "eventually
(λn. T n ≤ bmssp_refined_graph_time_bound
A R (λ_. 2 + cbatch) l
(λn. 9 + sssp_log_two_thirds_param n) m n) at_top"
by (rule cost_bound)
qed
text ‹
Specialised to the sparse-graph regime where the vertex term is dominated by
the edge term, this is the familiar deterministic SSSP envelope
‹O(m * (ln n) powr (2/3))›, now carrying the bucketed Insert and BatchPrepend
costs in the recurrence rather than free abstract parameters.
›
corollary bucketed_refined_cost_bigo_log_target:
fixes m A l R T :: "nat ⇒ nat"
and cbatch :: nat
and Cn Ca Cl Cr :: real
assumes Cn_pos: "0 < Cn"
and Ca_pos: "0 < Ca"
and Cl_nonneg: "0 ≤ Cl"
and Cr_pos: "0 < Cr"
and vertex_count_dominated:
"eventually (λn. real n ≤ Cn * real (m n)) at_top"
and A_bound:
"eventually (λn. real (A n) ≤ Ca * sssp_log_factor_one_third n) at_top"
and l_bound:
"eventually (λn. real (l n) ≤ Cl * sssp_log_factor_one_third n) at_top"
and R_bound:
"eventually (λn. real (R n) ≤ Cr * sssp_log_factor n) at_top"
and cost_bound:
"eventually
(λn. T n ≤ bmssp_refined_graph_time_bound
A R (λ_. 2 + cbatch) l
(λn. 9 + sssp_log_two_thirds_param n) m n)
at_top"
shows "(λn. real (T n)) ∈
O(λn. real (m n) * (ln (real n + 2)) powr (2 / 3))"
proof -
have "(λn. real (T n)) ∈ O(λn. sssp_time_target m n)"
by (rule bucketed_refined_cost_bigo_sssp_time_target
[OF Cn_pos Ca_pos Cl_nonneg Cr_pos vertex_count_dominated
A_bound l_bound R_bound cost_bound])
then show ?thesis
unfolding sssp_time_target_def sssp_log_factor_def .
qed
end