Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Class function_cost_model(cost: FunctionCostModel) :={
  
  cost_ident : 
  forall (A : Type),
    cost _ _ (fun (a : A) => a) 0;
  
  cost_ext : 
    forall (A B : Type)(f1 f2 : A -> B) n,
      (forall a, f1 a = f2 a) ->
      cost _ _ f2 n ->
      cost _ _ f1 n;
  
  cost_const : 
    forall (A B : Type)(b : B),
      cost _ _ (fun (_ : A) => b) 0;
  
  cost_le :
    forall A B (f : A -> B) c1 c2,
      cost _ _ f c1 ->
      c1 <= c2  ->
      cost _ _ f c2;
  
  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);
  
  cost_uncurry_1 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      cost _ _ f n;
  
  cost_uncurry_2 : 
    forall (A B C : Type)(f : A -> B -> C) n,
      cost _ _ (fun a => f (fst a) (snd a)) n ->
      forall a, cost _ _ (f a) n;
  
  cost_curry : 
    forall (A B C : Type)(f : A -> B -> C) c1 c2,
      cost _ _ f c1 ->
      (forall a, cost _ _ (f a) c2) ->
      cost _ _ (fun p => f (fst p) (snd p)) (c1 + c2);
  
  cost_fst : 
    forall (A B : Type),
      cost _ _ (@fst A B) 0;
  
  cost_snd : 
    forall (A B : Type),
      cost _ _ (@snd A B) 0;
  
  cost_BVxor : 
    forall n,
      cost _ _ (fun p => @BVxor n (fst p) (snd p)) n;
  
  cost_vec_head : 
    forall (A : Type) n,
      cost _ _ (@Vector.hd A n) 0;
  
  cost_eqb_bool : 
    cost _ _ (fun (p : bool * bool) => eqb (fst p) (snd p)) 1;
  
  cost_if_bool : 
    forall (A B : Type) (f : A -> bool) (f_so f_not : A -> B) c1 c2 c3,
      cost _ _ f c1 ->
      cost _ _ f_so c2 ->
      cost _ _ f_not c3 ->
      cost _ _ (fun p => if (f p) then (f_so p) else (f_not p)) (c1 + c2 + c3);
  
  cost_Ret : 
    forall (A : Set)(eqd : eq_dec A),
      cost _ _ (Ret eqd) 0;
  
  cost_OC_Ret : 
    forall (A B C: Set),
      cost _ _ (@OC_Ret A B C) 0;
  
  cost_OC_Bind : 
    forall (A B C C' : Set),
      cost _ _ (fun p => (@OC_Bind A B C C' (fst p) (snd p))) 0;
  
  cost_OC_Query : 
    forall (A B : Set),
      cost _ _ (@OC_Query A B) 0;
  
  cost_OC_Run_1 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B),
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda)
      0;
  
  cost_OC_Run_2 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c)
      0;
  
  cost_OC_Run_3 : 
    forall (A B C A' B' S : Set)(eqds : EqDec S)(eqda : EqDec A)(eqdb : EqDec B) c o,
      cost _ _ 
      (@OC_Run A B C A' B' S eqds eqdb eqda c o)
      0 
      
}.Inductive comp_cost(fm : FunctionCostModel) : CompCostModel :=
| comp_cost_Ret : 
  forall (A : Set)(eqd : eq_dec A)(a : A),
    comp_cost fm (Ret eqd a) 0
| comp_cost_Bind : 
  forall (A B : Set)(c : Comp A)(f : A -> Comp B) x1 x2 x3,
    comp_cost fm c x1 ->
    fm _ _ f x2 ->
    (forall a, comp_cost fm (f a) x3) ->
    comp_cost fm (Bind c f) (x1 + x2 + x3)
| comp_cost_Rnd : 
  forall n,
    comp_cost fm (Rnd n) n.Inductive comp_cost(fm : FunctionCostModel) : CompCostModel :=
| comp_cost_Ret : 
  forall (A : Set)(eqd : eq_dec A)(a : A),
    comp_cost fm (Ret eqd a) 0
| comp_cost_Bind : 
  forall (A B : Set)(c : Comp A)(f : A -> Comp B) x1 x2 x3,
    comp_cost fm c x1 ->
    fm _ _ f x2 ->
    (forall a, comp_cost fm (f a) x3) ->
    comp_cost fm (Bind c f) (x1 + x2 + x3)
| comp_cost_Rnd : 
  forall n,
    comp_cost fm (Rnd n) n.Inductive comp_cost(fm : FunctionCostModel) : CompCostModel :=
| comp_cost_Ret : 
  forall (A : Set)(eqd : eq_dec A)(a : A),
    comp_cost fm (Ret eqd a) 0
| comp_cost_Bind : 
  forall (A B : Set)(c : Comp A)(f : A -> Comp B) x1 x2 x3,
    comp_cost fm c x1 ->
    fm _ _ f x2 ->
    (forall a, comp_cost fm (f a) x3) ->
    comp_cost fm (Bind c f) (x1 + x2 + x3)
| comp_cost_Rnd : 
  forall n,
    comp_cost fm (Rnd n) n.Inductive comp_cost(fm : FunctionCostModel) : CompCostModel :=
| comp_cost_Ret : 
  forall (A : Set)(eqd : eq_dec A)(a : A),
    comp_cost fm (Ret eqd a) 0
| comp_cost_Bind : 
  forall (A B : Set)(c : Comp A)(f : A -> Comp B) x1 x2 x3,
    comp_cost fm c x1 ->
    fm _ _ f x2 ->
    (forall a, comp_cost fm (f a) x3) ->
    comp_cost fm (Bind c f) (x1 + x2 + x3)
| comp_cost_Rnd : 
  forall n,
    comp_cost fm (Rnd n) n.Inductive oc_cost(fm : FunctionCostModel)(cm : CompCostModel) : OC_CostModel :=
| oc_cost_Query : 
  forall (A B : Set)(a : A),
    oc_cost fm cm (OC_Query B a) (fun n => n)
| oc_cost_Run : 
  forall (A B C : Set)(c : OracleComp A B C) f1,
    oc_cost fm cm c f1 ->
    forall (A' B' S : Set)(eqds : EqDec S)(eqdb : EqDec B)(eqda : EqDec A) 
      (o : S -> A -> OracleComp A' B' (B * S)) x1 x2 f2,
      fm _ _ o x1 ->
      (forall x, fm _ _ (o x) x2) ->
      (forall x y, oc_cost fm cm (o x y) f2) ->
      forall s, 
        oc_cost fm cm (OC_Run _ _ _ c o s) (fun n => f1 (x1 + x2 + (f2 n)))
| oc_cost_Ret : 
  forall (A B C : Set)(c : Comp C) n,
    cm _ c n ->
    oc_cost fm cm (OC_Ret A B c) (fun _ => n)
| oc_cost_Bind :
  forall (A B C C' : Set)(c : OracleComp A B C)(f : C -> OracleComp A B C') f1 x f2,
    oc_cost fm cm c f1 ->
    fm _ _ f x->
    (forall y, oc_cost fm cm (f y) f2) ->
    oc_cost fm cm (OC_Bind c f) (fun n => (f1 n) + x + (f2 n))
| oc_cost_le : 
  forall (A B C : Set)(c : OracleComp A B C) f1 f2,
    oc_cost fm cm c f1 ->
    (forall x, f1 x <= f2 x) ->
    oc_cost fm cm c f2.Inductive oc_cost(fm : FunctionCostModel)(cm : CompCostModel) : OC_CostModel :=
| oc_cost_Query : 
  forall (A B : Set)(a : A),
    oc_cost fm cm (OC_Query B a) (fun n => n)
| oc_cost_Run : 
  forall (A B C : Set)(c : OracleComp A B C) f1,
    oc_cost fm cm c f1 ->
    forall (A' B' S : Set)(eqds : EqDec S)(eqdb : EqDec B)(eqda : EqDec A) 
      (o : S -> A -> OracleComp A' B' (B * S)) x1 x2 f2,
      fm _ _ o x1 ->
      (forall x, fm _ _ (o x) x2) ->
      (forall x y, oc_cost fm cm (o x y) f2) ->
      forall s, 
        oc_cost fm cm (OC_Run _ _ _ c o s) (fun n => f1 (x1 + x2 + (f2 n)))
| oc_cost_Ret : 
  forall (A B C : Set)(c : Comp C) n,
    cm _ c n ->
    oc_cost fm cm (OC_Ret A B c) (fun _ => n)
| oc_cost_Bind :
  forall (A B C C' : Set)(c : OracleComp A B C)(f : C -> OracleComp A B C') f1 x f2,
    oc_cost fm cm c f1 ->
    fm _ _ f x->
    (forall y, oc_cost fm cm (f y) f2) ->
    oc_cost fm cm (OC_Bind c f) (fun n => (f1 n) + x + (f2 n))
| oc_cost_le : 
  forall (A B C : Set)(c : OracleComp A B C) f1 f2,
    oc_cost fm cm c f1 ->
    (forall x, f1 x <= f2 x) ->
    oc_cost fm cm c f2.Inductive oc_cost(fm : FunctionCostModel)(cm : CompCostModel) : OC_CostModel :=
| oc_cost_Query : 
  forall (A B : Set)(a : A),
    oc_cost fm cm (OC_Query B a) (fun n => n)
| oc_cost_Run : 
  forall (A B C : Set)(c : OracleComp A B C) f1,
    oc_cost fm cm c f1 ->
    forall (A' B' S : Set)(eqds : EqDec S)(eqdb : EqDec B)(eqda : EqDec A) 
      (o : S -> A -> OracleComp A' B' (B * S)) x1 x2 f2,
      fm _ _ o x1 ->
      (forall x, fm _ _ (o x) x2) ->
      (forall x y, oc_cost fm cm (o x y) f2) ->
      forall s, 
        oc_cost fm cm (OC_Run _ _ _ c o s) (fun n => f1 (x1 + x2 + (f2 n)))
| oc_cost_Ret : 
  forall (A B C : Set)(c : Comp C) n,
    cm _ c n ->
    oc_cost fm cm (OC_Ret A B c) (fun _ => n)
| oc_cost_Bind :
  forall (A B C C' : Set)(c : OracleComp A B C)(f : C -> OracleComp A B C') f1 x f2,
    oc_cost fm cm c f1 ->
    fm _ _ f x->
    (forall y, oc_cost fm cm (f y) f2) ->
    oc_cost fm cm (OC_Bind c f) (fun n => (f1 n) + x + (f2 n))
| oc_cost_le : 
  forall (A B C : Set)(c : OracleComp A B C) f1 f2,
    oc_cost fm cm c f1 ->
    (forall x, f1 x <= f2 x) ->
    oc_cost fm cm c f2.Inductive oc_cost(fm : FunctionCostModel)(cm : CompCostModel) : OC_CostModel :=
| oc_cost_Query : 
  forall (A B : Set)(a : A),
    oc_cost fm cm (OC_Query B a) (fun n => n)
| oc_cost_Run : 
  forall (A B C : Set)(c : OracleComp A B C) f1,
    oc_cost fm cm c f1 ->
    forall (A' B' S : Set)(eqds : EqDec S)(eqdb : EqDec B)(eqda : EqDec A) 
      (o : S -> A -> OracleComp A' B' (B * S)) x1 x2 f2,
      fm _ _ o x1 ->
      (forall x, fm _ _ (o x) x2) ->
      (forall x y, oc_cost fm cm (o x y) f2) ->
      forall s, 
        oc_cost fm cm (OC_Run _ _ _ c o s) (fun n => f1 (x1 + x2 + (f2 n)))
| oc_cost_Ret : 
  forall (A B C : Set)(c : Comp C) n,
    cm _ c n ->
    oc_cost fm cm (OC_Ret A B c) (fun _ => n)
| oc_cost_Bind :
  forall (A B C C' : Set)(c : OracleComp A B C)(f : C -> OracleComp A B C') f1 x f2,
    oc_cost fm cm c f1 ->
    fm _ _ f x->
    (forall y, oc_cost fm cm (f y) f2) ->
    oc_cost fm cm (OC_Bind c f) (fun n => (f1 n) + x + (f2 n))
| oc_cost_le : 
  forall (A B C : Set)(c : OracleComp A B C) f1 f2,
    oc_cost fm cm c f1 ->
    (forall x, f1 x <= f2 x) ->
    oc_cost fm cm c f2.Inductive oc_cost(fm : FunctionCostModel)(cm : CompCostModel) : OC_CostModel :=
| oc_cost_Query : 
  forall (A B : Set)(a : A),
    oc_cost fm cm (OC_Query B a) (fun n => n)
| oc_cost_Run : 
  forall (A B C : Set)(c : OracleComp A B C) f1,
    oc_cost fm cm c f1 ->
    forall (A' B' S : Set)(eqds : EqDec S)(eqdb : EqDec B)(eqda : EqDec A) 
      (o : S -> A -> OracleComp A' B' (B * S)) x1 x2 f2,
      fm _ _ o x1 ->
      (forall x, fm _ _ (o x) x2) ->
      (forall x y, oc_cost fm cm (o x y) f2) ->
      forall s, 
        oc_cost fm cm (OC_Run _ _ _ c o s) (fun n => f1 (x1 + x2 + (f2 n)))
| oc_cost_Ret : 
  forall (A B C : Set)(c : Comp C) n,
    cm _ c n ->
    oc_cost fm cm (OC_Ret A B c) (fun _ => n)
| oc_cost_Bind :
  forall (A B C C' : Set)(c : OracleComp A B C)(f : C -> OracleComp A B C') f1 x f2,
    oc_cost fm cm c f1 ->
    fm _ _ f x->
    (forall y, oc_cost fm cm (f y) f2) ->
    oc_cost fm cm (OC_Bind c f) (fun n => (f1 n) + x + (f2 n))
| oc_cost_le : 
  forall (A B C : Set)(c : OracleComp A B C) f1 f2,
    oc_cost fm cm c f1 ->
    (forall x, f1 x <= f2 x) ->
    oc_cost fm cm c f2.Inductive oc_cost(fm : FunctionCostModel)(cm : CompCostModel) : OC_CostModel :=
| oc_cost_Query : 
  forall (A B : Set)(a : A),
    oc_cost fm cm (OC_Query B a) (fun n => n)
| oc_cost_Run : 
  forall (A B C : Set)(c : OracleComp A B C) f1,
    oc_cost fm cm c f1 ->
    forall (A' B' S : Set)(eqds : EqDec S)(eqdb : EqDec B)(eqda : EqDec A) 
      (o : S -> A -> OracleComp A' B' (B * S)) x1 x2 f2,
      fm _ _ o x1 ->
      (forall x, fm _ _ (o x) x2) ->
      (forall x y, oc_cost fm cm (o x y) f2) ->
      forall s, 
        oc_cost fm cm (OC_Run _ _ _ c o s) (fun n => f1 (x1 + x2 + (f2 n)))
| oc_cost_Ret : 
  forall (A B C : Set)(c : Comp C) n,
    cm _ c n ->
    oc_cost fm cm (OC_Ret A B c) (fun _ => n)
| oc_cost_Bind :
  forall (A B C C' : Set)(c : OracleComp A B C)(f : C -> OracleComp A B C') f1 x f2,
    oc_cost fm cm c f1 ->
    fm _ _ f x->
    (forall y, oc_cost fm cm (f y) f2) ->
    oc_cost fm cm (OC_Bind c f) (fun n => (f1 n) + x + (f2 n))
| oc_cost_le : 
  forall (A B C : Set)(c : OracleComp A B C) f1 f2,
    oc_cost fm cm c f1 ->
    (forall x, f1 x <= f2 x) ->
    oc_cost fm cm c f2.

Theorem cost_compose_binary : forall (A B C D: Type) (f1 : A -> B)(f2 : A ->C)(f3 : B -> C -> D) c1 c2 c3 c4, cost f1 c1 -> cost f2 c2 -> cost f3 c3 -> (forall a, cost (f3 a) c4) -> cost (fun a => f3 (f1 a) (f2 a)) (c1 + c2 + c3 + c4).