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 ->
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