(* 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.		*)
(* An efficiency predicate that characterizes of non-uniform PPT turing machines.  *)
Set Implicit Arguments.
Definition CostModel := forall (A B : Type), (A -> B) -> nat -> Prop.
Local Open Scope nat_scope.
Class constant_cost_relation(cost : CostModel) :={
constant_cost_const :
forall (A B : Type)(b : B),
cost _ _ (fun (_ : A) => b) 0;
constant_cost_pair_args :
forall (A B C : Type)
(f : A -> B -> C) c,
cost _ _ (fun p => f (fst p) (snd p)) c ->
exists c1 c2,
cost _ _ f c1 /\ (forall a, cost _ _ (f a) c2) /\ c1 + c2 <= c;
constant_cost_unpair_args :
forall (A B C : Type)
(f : (A * B) -> C) c,
cost _ _ f c ->
cost _ _ (fun a b => f (a, b)) 0 /\
(forall a, cost _ _ (fun b => f (a, b)) c);
constant_cost_compose :
forall (A B C : Type)
(f1 : A -> B)(f2 : A -> B -> C) c1 c2 c3,
cost _ _ f1 c1 ->
cost _ _ f2 c2 ->
(forall a, cost _ _ (f2 a) c3) ->
cost _ _ (fun a => f2 a (f1 a)) (c1 + c2 + c3);
constant_cost_bind :
forall (Z : Type)(A B : Set)(f1 : Z -> Comp A) (f2 : Z -> A -> Comp B) c1 c2 c3,
cost _ _ f1 c1 ->
cost _ _ f2 c2 ->
(forall z, cost _ _ (f2 z) c3) ->
cost _ _ (fun a => Bind (f1 a) (f2 a)) (c1 + c2 + c3);
constant_cost_ret :
forall (A : Set)(eqd : eq_dec A),
cost _ _ (@Ret A eqd) 0;
constant_cost_le :
forall A B (f : A -> B) c1 c2,
cost _ _ f c1 ->
c1 <= c2 ->
cost _ _ f c2;
constant_cost_fst :
forall (A B : Type),
cost _ _ (@fst A B) 0;
constant_cost_snd :
forall (A B : Type),
cost _ _ (@snd A B) 0;
constant_cost_pair_1 :
forall (A B : Type),
cost _ _ (@pair A B) 0;
constant_cost_pair_2 :
forall (A B : Type) a,
cost _ _ (@pair A B a) 0;
constant_cost_pair :
forall (A B : Type),
cost _ _ (fun p => @pair A B (fst p) (snd p)) 0;
constant_cost_eqb_bool :
cost _ _ (fun p => @eqb bool _ (fst p) (snd p)) 1;
constant_cost_bvxor :
forall eta,
cost _ _ (fun p => BVxor eta (fst p) (snd p)) eta;
constant_cost_firstn :
forall k (A : Type),
cost _ _ (@firstn A k) k;
constant_cost_skipn :
forall k (A : Type),
cost _ _ (@skipn A k) k;
constant_cost_tl :
forall (A : Type),
cost _ _ (@tl A) 1;
constant_cost_hd :
forall (A : Type)(a : A),
cost _ _ (hd a) 1;
constant_cost_if_bool_f :
forall (A B : Type)(f1 : A -> bool)(f2 f3 : A -> B) c1 c2 c3,
cost _ _ f1 c1 ->
cost _ _ f2 c2 ->
cost _ _ f3 c3 ->
cost _ _ (fun a => if (f1 a) then (f2 a) else (f3 a)) (c1 + c2 + c3)
}.
Section constant_cost_theory.
Context `(constant_cost_relation).

Theorem constant_cost_pair_args_weak :
forall (A B C : Type)
(f : A -> B -> C) c,
cost (fun p => f (fst p) (snd p)) c ->
cost f c.