(* 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.

Theorem polynomial_plus :
forall f1 f2 ,
polynomial f1 ->
polynomial f2 ->
polynomial (fun n => f1 n + f2 n).