(* Title: Negligible.thy
Author: Andreas Lochbihler, ETH Zurich *)
section ‹ Negligibility›
theory Negligible imports
Complex_Main
Landau_Symbols.Landau_More
begin
named_theorems negligible_intros
definition negligible :: "(nat ==> real) ==> bool" (* TODO: generalise types? *)
where "negligible f ⟷ (∀ c>0. f ∈ o(λx. inverse (x powr c)))"
lemma negligibleI [intro?]:
"(∧ c. c > 0 ==> f ∈ o(λx. inverse (x powr c))) ==> negligible f"
unfolding negligible_def by (simp)
lemma negligibleD:
"[ negligible f; c > 0 ] ==> f ∈ o(λx. inverse (x powr c))"
unfolding negligible_def by (simp)
lemma negligibleD_real:
assumes "negligible f"
shows "f ∈ o(λx. inverse (x powr c))"
proof -
let ?c = "max 1 c"
have "f ∈ o(λx. inverse (x powr ?c))" using assms by (rule negligibleD) simp
also have "(λx. x powr c) ∈ O(λx. real x powr max 1 c)"
by (rule bigoI[where c=1 ])(auto simp add: eventually_at_top_linorder intro!: exI[where x=1 ] powr_mono)
then have "(λx. inverse (real x powr max 1 c)) ∈ O(λx. inverse (x powr c))"
by (auto simp add: eventually_at_top_linorder exI[where x=1 ] intro: landau_o.big.inverse)
finally show ?thesis .
qed
lemma negligible_mono: "[ negligible g; f ∈ O(g) ] ==> negligible f"
by (rule negligibleI)(drule (1 ) negligibleD; erule (1 ) landau_o.big_small_trans)
lemma negligible_le: "[ negligible g; ∧ η. ∣ f η∣ ≤ g η ] ==> negligible f"
by (erule negligible_mono)(force intro: order_trans intro!: eventually_sequentiallyI landau_o.big_mono)
lemma negligible_K0 [negligible_intros, simp, intro!]: "negligible (λ_. 0)"
by (rule negligibleI) simp
lemma negligible_0 [negligible_intros, simp, intro!]: "negligible 0"
by (simp add: zero_fun_def)
lemma negligible_const_iff [simp]: "negligible (λ_. c :: real) ⟷ c = 0"
by (auto simp add: negligible_def const_smallo_inverse_powr filterlim_real_sequentially dest!: spec[where x=1 ])
lemma not_negligible_1: "¬ negligible (λ_. 1 :: real)"
by simp
lemma negligible_plus [negligible_intros]:
"[ negligible f; negligible g ] ==> negligible (λη. f η + g η)"
by (auto intro!: negligibleI dest!: negligibleD intro: sum_in_smallo)
lemma negligible_uminus [simp]: "negligible (λη. - f η) ⟷ negligible f"
by (simp add: negligible_def)
lemma negligible_uminusI [negligible_intros]: "negligible f ==> negligible (λη. - f η)"
by simp
lemma negligible_minus [negligible_intros]:
"[ negligible f; negligible g ] ==> negligible (λη. f η - g η)"
by (auto simp add: uminus_add_conv_diff[symmetric] negligible_plus simp del: uminus_add_conv_diff)
lemma negligible_cmult: "negligible (λη. c * f η) ⟷ negligible f ∨ c = 0"
by (auto intro!: negligibleI dest!: negligibleD)
lemma negligible_cmultI [negligible_intros]:
"(c ≠ 0 ==> negligible f) ==> negligible (λη. c * f η)"
by (auto simp add: negligible_cmult)
lemma negligible_multc: "negligible (λη. f η * c) ⟷ negligible f ∨ c = 0"
by (subst mult.commute)(simp add: negligible_cmult)
lemma negligible_multcI [negligible_intros]:
"(c ≠ 0 ==> negligible f) ==> negligible (λη. f η * c)"
by (auto simp add: negligible_multc)
lemma negligible_times [negligible_intros]:
assumes f: "negligible f"
and g: "negligible g"
shows "negligible (λη. f η * g η :: real)"
proof
fix c :: real
assume "0 < c"
hence "0 < c / 2" by simp
from negligibleD[OF f this] negligibleD[OF g this]
have "(λη. f η * g η) ∈ o(λx. inverse (x powr (c / 2)) * inverse (x powr (c / 2)))"
by (rule landau_o.small_mult)
also have "… = o(λx. inverse (x powr c))"
by (rule landau_o.small.cong)(auto simp add: inverse_mult_distrib[symmetric] powr_add[symmetric] eventually_at_top_linorder intro!: exI[where x=1 ] simp del: inverse_mult_distrib)
finally show "(λη. f η * g η) ∈ … " .
qed
lemma negligible_power [negligible_intros]:
assumes "negligible f"
and "n > 0"
shows "negligible (λη. f η ^ n :: real)"
using ‹ n > 0›
proof (induct n)
case (Suc n)
thus ?case using ‹ negligible f› by (cases n)(simp_all add: negligible_times)
qed simp
lemma negligible_powr [negligible_intros]:
assumes f: "negligible f"
and p: "p > 0"
shows "negligible (λx. ∣ f x∣ powr p :: real)"
proof
fix c :: real
let ?c = "c / p"
assume c: "0 < c"
with p have "0 < ?c" by simp
with f have "f ∈ o(λx. inverse (x powr ?c))" by (rule negligibleD)
hence "(λx. ∣ f x∣ powr p) ∈ o(λx. ∣ inverse (x powr ?c)∣ powr p)" using p by (rule smallo_powr)
also have "… = o(λx. inverse (x powr c))"
apply (rule landau_o.small.cong) using p by (auto simp add: powr_powr)
finally show "(λx. ∣ f x∣ powr p) ∈ … " .
qed
lemma negligible_abs [simp]: "negligible (λx. ∣ f x∣ ) ⟷ negligible f"
by (simp add: negligible_def)
lemma negligible_absI [negligible_intros]: "negligible f ==> negligible (λx. ∣ f x∣ )"
by (simp)
lemma negligible_powrI [negligible_intros]:
assumes "0 ≤ k" "k < 1"
shows "negligible (λx. k powr x)"
proof (cases "k = 0" )
case True
thus ?thesis by simp
next
case False
show ?thesis
proof
fix c :: real
assume "0 < c"
then have "(λx. real x powr c) ∈ o(λx. inverse k powr real x)" using assms False
by (intro powr_fast_growth_tendsto)(simp_all add: one_less_inverse_iff filterlim_real_sequentially)
then have "(λx. inverse (k powr - real x)) ∈ o(λx. inverse (real x powr c))" using assms
by (intro landau_o.small.inverse)(auto simp add: False eventually_sequentially powr_minus intro: exI[where x=1 ])
also have "(λx. inverse (k powr - real x)) = (λx. k powr real x)" by (simp add: powr_minus)
finally show "… ∈ o(λx. inverse (x powr c))" .
qed
qed
lemma negligible_powerI [negligible_intros]:
fixes k :: real
assumes "∣ k∣ < 1"
shows "negligible (λn. k ^ n)"
proof (cases "k = 0" )
case True
show ?thesis using negligible_K0
by (rule negligible_mono)(auto intro: exI[where x=1 ] simp add: True eventually_at_top_linorder)
next
case False
hence "0 < ∣ k∣ " by auto
from assms have "negligible (λx. ∣ k∣ powr real x)" using negligible_powrI[of "∣ k∣ " ] by simp
hence "negligible (λx. ∣ k∣ ^ x)" using False
by (elim negligible_mono)(simp add: powr_realpow)
then show ?thesis by (simp add: power_abs[symmetric])
qed
lemma negligible_inverse_powerI [negligible_intros]: "∣ k∣ > 1 ==> negligible (λη. 1 / k ^ η)"
using negligible_powerI[of "1 / k" ] by (simp add: power_one_over)
inductive polynomial :: "(nat ==> real) ==> bool"
for f
where "f ∈ O(λx. x powr n) ==> polynomial f"
lemma negligible_times_poly:
assumes f: "negligible f"
and g: "g ∈ O(λx. x powr n)"
shows "negligible (λx. f x * g x)"
proof
fix c :: real
assume c: "0 < c"
from negligibleD_real[OF f] g
have "(λx. f x * g x) ∈ o(λx. inverse (x powr (c + n)) * x powr n)"
by (rule landau_o.small_big_mult)
also have "… = o(λx. inverse (x powr c))"
by (rule landau_o.small.cong)(auto simp add: powr_minus[symmetric] powr_add[symmetric] intro!: exI[where x=0 ])
finally show "(λx. f x * g x) ∈ o(λx. inverse (x powr c))" .
qed
lemma negligible_poly_times:
"[ f ∈ O(λx. x powr n); negligible g ] ==> negligible (λx. f x * g x)"
by (subst mult.commute)(rule negligible_times_poly)
lemma negligible_times_polynomial [negligible_intros]:
"[ negligible f; polynomial g ] ==> negligible (λx. f x * g x)"
by (clarsimp simp add: polynomial.simps negligible_times_poly)
lemma negligible_polynomial_times [negligible_intros]:
"[ polynomial f; negligible g ] ==> negligible (λx. f x * g x)"
by (clarsimp simp add: polynomial.simps negligible_poly_times)
lemma negligible_divide_poly1:
"[ f ∈ O(λx. x powr n); negligible (λη. 1 / g η) ] ==> negligible (λη. real (f η) / g η)"
by (drule (1 ) negligible_times_poly) simp
lemma negligible_divide_polynomial1 [negligible_intros]:
"[ polynomial f; negligible (λη. 1 / g η) ] ==> negligible (λη. real (f η) / g η)"
by (clarsimp simp add: polynomial.simps negligible_divide_poly1)
end
Messung V0.5 in Prozent C=91 H=98 G=94
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland