let compile_function fdef =
    let o_name = Datalib.identifier (fdef.l_var_info.lv_name) in
    let f_name = "D_" ^ o_name in
    let d_name = "Def_" ^ o_name in
    let context, formals, env = user_env fdef in
    try
      let body, used =
        match fdef.l_body with
          | LBterm def  ->
              let v = term env def in (Some v, [v])
          | LBreads xs ->
              (*TODO: Incorrect translation (Cf. predicates)
              None,List.map (fun x -> term env x.it_content) xs
              *)

              Wp_parameters.warning ~once:true "Interpreting reads-definition as expressions rather than tsets" ;
              let vs = List.map (fun x -> term env x.it_content) xs in
              None,vs
          | LBnone ->
              None,[]
          | LBinductive _ ->
              Wp_parameters.fatal "Inductive function"
          | LBpred _ ->
              Wp_parameters.fatal "Function defined by a predicate"
      in
      let t_result =
        match fdef.l_type with
          | Some ltyp -> D.tau_of_logic_type ltyp
          | None -> Wp_parameters.fatal "Function defined with not result type"
      in
      let implicits , closures = M.userdef_signature env.frame used [] in
      let f_formals = List.map snd formals @ implicits in
      let declaration =
        f_name ,
        Formula.Function(List.map F.tau_of_var f_formals,t_result)
      in
      let definitions =
        match body with
          | None -> kill_context "compile" context ; []
          | Some def ->
              let f_axiom = F.p_forall f_formals
                (flush_context "compile" context
                   (F.p_eq (F.e_call f_name (List.map F.var f_formals)) def))
              in
              [ d_name , Formula.Axiom f_axiom ]
      in
      {
        d_info = fdef ;
        d_callname = f_name ;
        d_implicit = implicits ;
        d_closure = closures ;
        d_formals = List.map snd formals ;
      } ,
      declaration :: definitions
    with err ->
      kill_context "compile" context ;
      raise err