let compile_predicate pdef =
    let o_name = Datalib.identifier (pdef.l_var_info.lv_name) in
    let p_name = "D_" ^ o_name in
    let d_name = "Def_" ^ o_name in
    let context, formals, env = user_env pdef in
    try
      let body,tused,pused =
        match pdef.l_body with
          | LBpred named ->
              let v= prop env named in (Some v, [],[v])
          | LBterm def  ->
              let v = term env def in (Some (F.p_bool (F.unwrap v)), [v],[])
          | LBnone ->
              None,[],[]
          | 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 "Interpreting reads-definition as expressions rather than tsets" ;
              let vs = List.map (fun x -> term env x.it_content) xs in
              None,vs,[]
          | LBinductive _ ->
              Wp_parameters.not_yet_implemented "Inductive predicates"
      in
      let implicits , closures = M.userdef_signature env.frame tused pused in
      let p_formals = List.map snd formals @ implicits in
      let declaration =
        p_name ,
        Formula.Predicate(List.map F.tau_of_var p_formals) in
      let definitions =
        match body with
          | None -> kill_context "compile" context ; []
          | Some body ->
              let p_axiom =
                D.forall p_formals
                  (F.p_iff
                     (F.p_call p_name (List.map F.var p_formals))
                     (flush_context "compile" context body))
              in
              [ d_name , Formula.Axiom p_axiom ]
      in
      {
        d_info = pdef ;
        d_callname = p_name ;
        d_implicit = implicits ;
        d_closure = closures ;
        d_formals = List.map snd formals ;
      } ,
      declaration :: definitions
    with err ->
      kill_context "compile" context ;
      raise err