let compile_predicate pdef =
    let o_name = Fol_decl.identifier (pdef.l_var_info.lv_name) in
    let p_name = "D_" ^ o_name in
    let d_name = "Def_" ^ o_name in
    let context, profile, env = user_env pdef in
    try
      let body,filter =
        match pdef.l_body with
          | LBpred named ->
              let v = prop env named in Some v , pred_filter v
          | LBterm def  ->
              let v = term env def in Some (F.p_bool (F.unwrap v)) , term_filter v
          | LBnone -> 
              Wp_parameters.warning ~once:true ~current:false
                "No definition for '%s' interpreted as reads nothing" o_name ;
              None , all_filter
          | LBreads xs ->
              (*TODO: Below is an incorrect translation (LC+BM) (Idem for "\from")
                (LC) Reason : xs are to be interpreted as left-values.
                (Use case : f reads t[0..n])
                let vs = List.map (fun x -> term env x.it_content) xs in
                None,vs,[]
              *)

              Wp_parameters.warning ~once:true ~current:false
                "Interpreting reads-definition as expressions rather than tsets" ;
              List.iter (fun x -> ignore (term env x.it_content)) xs ;
              None , all_filter
          | LBinductive _ ->
              Wp_parameters.not_yet_implemented "Inductive predicates"
      in
      let signature = collect_signature profile filter env in
      let formals = flatten_formals signature in
      let declaration = 
        p_name , Formula.Predicate(List.map F.tau_of_var formals) in
      let definitions =
        match body with
          | None -> kill_context "compile" context ; []
          | Some body ->
              let p_axiom =
                L.forall formals
                  (F.p_iff
                     (F.p_call p_name (List.map F.var formals))
                     (flush_context "compile" context body))
              in
              [ d_name , Formula.Axiom p_axiom ]
      in
      {
        d_info = pdef ;
        d_callname = p_name ;
        d_formals = signature ;
      } ,
      declaration :: definitions
    with err ->
      kill_context "compile" context ;
      raise err