(* Copyright 2012-2015 by Adam Petcher.				* * Use of this source code is governed by the license described	* * in the LICENSE file at the root of the source tree.		*)
(* Definitions of asymptotic notions such as polynomial and negligible functions, and related theory. *)
Set Implicit Arguments.
Definition polynomial (f : nat -> nat) :=
exists x c1 c2, forall n,
(f n <= c1 * expnat n x + c2)%nat.
Definition polynomial_nz(f : nat -> nat) :=
exists x c1 c2,
x > 0 /\ c1 > 0 /\ c2 > 0 /\
forall n,
(f n <= c1 * expnat n x + c2)%nat.
intuition.
unfold polynomial, polynomial_nz in *.
do 3 (destruct H).
exists (S x).
exists (S x0).
exists (x0 + S x1).
intuition.
rewrite H.
rewrite plus_assoc.
eapply plus_le_compat; intuition.
simpl.
destruct (eq_nat_dec x 0).
subst.
simpl.
repeat rewrite mult_1_r.
rewrite <- plus_0_l at 1.
eapply plus_le_compat; intuition.
rewrite <- plus_0_l at 1.
rewrite <- plus_0_r at 1.
eapply plus_le_compat; intuition.
eapply plus_le_compat; intuition.
eapply mult_le_compat; intuition.
destruct (eq_nat_dec n 0); subst.
rewrite expnat_0;
omega.
rewrite <- mult_1_l at 1.
eapply mult_le_compat; intuition.
Qed.
intuition.
apply polynomial_nz_equiv in H.
apply polynomial_nz_equiv in H0.
unfold polynomial, polynomial_nz in *.
Ltac des :=
match goal with
| [H : exists _, _ |- _] => destruct H
end.
repeat des.
intuition.
exists (max x2 x).
exists (x3 + x0).
exists (x4 + x1).
intuition.
eapply le_trans.
eapply plus_le_compat.
eapply H6; trivial.
eapply H7; trivial.
rewrite mult_plus_distr_r.
repeat rewrite plus_assoc.
eapply plus_le_compat; trivial.
rewrite plus_comm.
rewrite plus_assoc.
eapply plus_le_compat; trivial.
rewrite plus_comm.
eapply plus_le_compat;
eapply mult_le_compat; intuition.
eapply expnat_exp_le; intuition.
eapply expnat_exp_le; intuition.
Qed.
intuition.
unfold polynomial.
exists 0.
exists 0.
exists c.
intuition.
Qed.
unfold polynomial.
intuition.
exists 1.
exists 1.
exists 0.
intuition.
simpl.
omega.
Qed.
intros f1 f2 H H0.
apply polynomial_nz_equiv in H.
apply polynomial_nz_equiv in H0.
unfold polynomial, polynomial_nz in *.
repeat des.
intuition.
exists (x + x2).
exists (3 * (x3 * x0 * x4 * x1)).
exists (x4 * x1).
intros n.
eapply le_trans.
eapply mult_le_compat.
eapply H6; intuition.
eapply H7; intuition.
repeat rewrite mult_plus_distr_l.
repeat rewrite mult_plus_distr_r.
rewrite plus_assoc.
eapply plus_le_compat; trivial.
rewrite expnat_plus.
simpl.
rewrite plus_0_r.
repeat rewrite mult_plus_distr_r.
rewrite plus_assoc.
eapply plus_le_compat.
eapply plus_le_compat.
rewrite (mult_comm (expnat n x)).
repeat rewrite mult_assoc.
eapply mult_le_compat. 2: reflexivity.
rewrite mult_comm.
rewrite mult_assoc.
eapply mult_le_compat. 2: reflexivity.
rewrite <- mult_1_r at 1.
rewrite <- mult_1_r at 1.
eapply mult_le_compat. 2: auto with zarith.
eapply mult_le_compat. 2: auto with zarith.
rewrite mult_comm.
reflexivity.
destruct (eq_nat_dec n 0); subst.
repeat rewrite expnat_0.
simpl.
repeat rewrite mult_0_r.
reflexivity.
trivial.
trivial.
rewrite (mult_comm (expnat n x)).
repeat rewrite mult_assoc.
eapply mult_le_compat; trivial.
rewrite <- mult_1_r at 1.
eapply mult_le_compat; trivial.
rewrite <- mult_1_r at 1.
eapply mult_le_compat; trivial.
rewrite mult_comm.
eapply mult_le_compat; trivial.
rewrite <- mult_1_l at 1.
eapply mult_le_compat; trivial.
eapply expnat_ge_1.
omega.
destruct (eq_nat_dec n 0); subst.
repeat rewrite expnat_0.
simpl.
repeat rewrite mult_0_r.
intuition.
trivial.
trivial.
rewrite (mult_comm (expnat n x)).
repeat rewrite mult_assoc.
rewrite <- mult_1_r at 1.
eapply mult_le_compat; trivial.
rewrite <- mult_assoc.
rewrite (mult_comm (expnat n x2)).
rewrite mult_assoc.
eapply mult_le_compat; trivial.
eapply mult_le_compat; trivial.
rewrite <- mult_1_r at 1.
eapply mult_le_compat; trivial.
rewrite <- mult_1_r at 1.
eapply mult_le_compat; trivial.
eapply expnat_ge_1.
omega.
Qed.
Local Open Scope rat_scope.
Definition negligible(f : nat -> Rat) :=
forall c, exists n, forall x (pf_nz : nz x),
x > n ->
~ ((1 / expnat x c) <= f x)%rat.

Theorem negligible_eq :
forall (f1 f2 : nat -> Rat),
negligible f1 ->
(forall n, f1 n == f2 n) ->
negligible f2.