(* n s : arities of e*)
Fixpoint BC_to_Cobham n s (e : BC) : Cobham :=
  match e with
    | zero => Zero
    | proj n s i => Proj (n + s) i
    | succ b => Succ b
    | pred => Pred
    | cond => Cond
    | rec g h0 h1 =>
        Rec (BC_to_Cobham (n - 1) s g)
        (move_arg (S (n+s)) 1 (n-1) (BC_to_Cobham n (S s) h0) )
        (move_arg (S (n+s)) 1 (n-1) (BC_to_Cobham n (S s) h1) )
        (Poly (pplus (psum n s) (poly_BC n e)))
    | comp n s h rl tl =>
      Comp (n + s) (BC_to_Cobham (length rl) (length tl) h)
      (map (fun e => (dummies n s (BC_to_Cobham n 0 e))) rl ++ 
        map (BC_to_Cobham n s) tl)
  end.

(* Specifications: *)
Lemma arity_BC_to_Cobham : forall (e : BC) n s, arities e = ok_arities n s -> arity (BC_to_Cobham n s e) = ok_arity (n + s).
Lemma BC_to_Cobham_correct : forall (e : BC) n s, arities e = ok_arities n s -> (forall xl yl, n = length xl -> s = length yl -> sem e xl yl = Sem (BC_to_Cobham n s e) (xl ++ yl)).
Lemma app_prop : forall {A} (l2 l1 : list A) (P : A -> Prop), (fix f (l : list A) : Prop := match l with | nil => True | e :: l' => P e /\ f l' end) l1 -> (fix f (l : list A) : Prop := match l with | nil => True | e :: l' => P e /\ f l' end) l2 -> (fix f (l : list A) : Prop := match l with | nil => True | e :: l' => P e /\ f l' end) (l1 ++ l2).
Lemma plusl_monotonic : forall l (f1 f2 : nat -> nat), (forall x, f1 x <= f2 x) -> plusl (map f1 l) <= plusl (map f2 l).
Lemma BC_to_Cobham_bounded : forall (e : BC) n s, arities e = ok_arities n s -> rec_bounded' (BC_to_Cobham n s e).