Definition procedure_family(A : nat -> Type) := forall n, A n.Definition efficiency_predicate := forall (A : nat -> Type), procedure_family A -> Prop.

(* Specifications: *)
Theorem expected_poly_time_compose_simp : forall (A B C : nat -> Type)(f1 : forall n, A n -> B n)(f2 : forall n, B n -> C n), efficient _ f1 -> efficient _ f2 -> efficient _ (fun n (a : A n) => f2 n (f1 n a)).
Theorem expected_poly_time_compose_binary : forall (A B C D : nat -> Type)(f1 : forall n, A n -> B n)(f2 : forall n, A n -> C n)(f3 : forall n, B n -> C n -> D n) , efficient _ f1 -> efficient _ f2 -> efficient _ f3 -> efficient _ (fun n (a : A n) => f3 n (f1 n a) (f2 n a)).
Theorem expected_poly_time_pair_f : forall (A B C : nat -> Type)(f1 : forall n, A n -> B n)(f2 : forall n, A n -> C n), efficient _ f1 -> efficient _ f2 -> efficient _ (fun n (a : A n) => (f1 n a, f2 n a)).
Theorem expected_poly_time_bvxor_f : forall (A : nat -> Type)(f1 : forall n, A n -> Bvector n)(f2 : forall n, A n -> Bvector n), efficient _ f1 -> efficient _ f2 -> efficient _ (fun n (a : A n) => BVxor n (f1 n a) (f2 n a)).
Theorem expected_poly_time_eqb_bool_f : forall (A : nat -> Type)(f1 : forall n, A n -> bool)(f2 : forall n, A n -> bool), efficient _ f1 -> efficient _ f2 -> efficient _ (fun n (a : A n) => eqb (f1 n a) (f2 n a)).
Theorem expected_poly_time_fst_f : forall (A B C : nat -> Type)(f : forall n, A n -> (B n * C n)), efficient _ f -> efficient _ (fun n (a : A n) => fst (f n a)).
Theorem expected_poly_time_snd_f : forall (A B C : nat -> Type)(f : forall n, A n -> (B n * C n)), efficient _ f -> efficient _ (fun n (a : A n) => snd (f n a)).
Theorem expected_poly_time_compose_0_binary : forall (A B C : nat -> Type)(f1 : forall n, A n)(f2 : forall n, B n)(f3 : forall n, A n -> B n -> C n) , efficient _ f1 -> efficient _ f2 -> efficient _ f3 -> efficient _ (fun n => f3 n (f1 n) (f2 n)).
Theorem expected_poly_time_bind_0_f : forall (A B : nat -> Set) (a : forall n, Comp (A n)) (b : forall n, A n -> Comp (B n)), efficient _ a -> efficient _ b -> efficient _ (fun n => (Bind (a n) (b n))).
Theorem expected_poly_time_bind_f : forall (A : nat -> Type)(B C : nat -> Set) (b : forall n, A n -> Comp (B n)) (c : forall n, A n -> B n -> Comp (C n)), efficient _ b -> efficient _ c -> efficient _ (fun n a => (Bind (b n a) (c n a))).
Theorem expected_poly_time_ret_f : forall (A : nat -> Type)(B : nat -> Set)(eqd : forall n, eq_dec (B n))(f : forall n, (A n) -> (B n)), efficient _ f -> efficient _ (fun n (a : A n) => Ret (eqd n) (f n a)).
Theorem expected_poly_time_if_f : forall (A B: nat -> Type)(f_b : forall n, (A n) -> bool)(f_so f_not : forall n, A n -> B n), efficient _ f_b -> efficient _ f_so -> efficient _ f_not -> efficient _ (fun n (a : A n) => if (f_b n a) then (f_so n a) else (f_not n a)).
Theorem expected_poly_time_cons_f : forall A B (f1 : forall n, A n -> B n) (f2 : forall n, A n -> list (B n)), efficient _ f1 -> efficient _ f2 -> efficient _ (fun n (a : A n) => (cons (f1 n a) (f2 n a))).