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

Theorem polynomial_mult :
forall f1 f2 ,
polynomial f1 ->
polynomial f2 ->
polynomial (fun n => f1 n * f2 n).