diff --git a/src/plugins/wp/Cfloat.ml b/src/plugins/wp/Cfloat.ml index e7d338eb65ac927c372450109ea548f80c755c25..447f155996c70d9e4f244ddeea2a43f7cba231f7 100644 --- a/src/plugins/wp/Cfloat.ml +++ b/src/plugins/wp/Cfloat.ml @@ -71,6 +71,10 @@ let tau_of_float f = | Real -> Logic.Real | Float -> ftau f +let float_name = function + | Float32 -> "float" + | Float64 -> "double" + (* -------------------------------------------------------------------------- *) (* --- Operators --- *) (* -------------------------------------------------------------------------- *) @@ -110,17 +114,22 @@ let op_name = function module REGISTRY = WpContext.Static (struct type key = lfun - type data = op * c_float + type data = op * c_float * (term list -> term) option let name = "Wp.Cfloat.REGISTRY" include Lang.Fun end) -let find = REGISTRY.find +let get_impl x = + match REGISTRY.find x with + | _, _, Some impl -> impl + | _ -> raise Not_found + +let find k = let tf, phi, _ = REGISTRY.find k in tf, phi let () = Context.register begin fun () -> - REGISTRY.define fq32 (EXACT,Float32) ; - REGISTRY.define fq64 (EXACT,Float64) ; + REGISTRY.define fq32 (EXACT,Float32,None) ; + REGISTRY.define fq64 (EXACT,Float64,None) ; end (* -------------------------------------------------------------------------- *) @@ -288,8 +297,8 @@ let compute_real op xs = | NE , [ x ; y ] -> F.e_neq x y | _ -> raise Not_found -let compute op ulp xs = - match Context.get model with +let compute model op ulp xs = + match model with | Real -> compute_real op xs | Float -> compute_float op ulp xs @@ -297,62 +306,142 @@ let compute op ulp xs = (* --- Operations --- *) (* -------------------------------------------------------------------------- *) -let make_fun_float ?result name op ft = +let make_fun_float ?result model name op ft = let result = match result with None -> ftau ft | Some r -> r in let phi = extern_f ~library ~result "%s_%a" name pp_suffix ft in - Lang.F.set_builtin phi (compute op ft) ; - REGISTRY.define phi (op,ft) ; phi + let impl = compute model op ft in + Lang.F.set_builtin phi impl ; + REGISTRY.define phi (op,ft, Some impl) ; + phi -let make_pred_float name op ft = +let make_pred_float model name op ft = let prop = Pretty_utils.sfprintf "%s_%a" name pp_suffix ft in let bool = Pretty_utils.sfprintf "%s_%ab" name pp_suffix ft in let phi = extern_p ~library ~bool ~prop () in - Lang.F.set_builtin phi (compute op ft) ; - REGISTRY.define phi (op,ft) ; phi + let impl = compute model op ft in + Lang.F.set_builtin phi impl ; + REGISTRY.define phi (op,ft, Some impl) ; + phi let f_memo = Ctypes.f_memo -let real_of_flt = f_memo (make_fun_float ~result:Logic.Real "of" REAL) -let flt_of_real = f_memo (make_fun_float "to" ROUND) -let flt_add = f_memo (make_fun_float "add" ADD) -let flt_mul = f_memo (make_fun_float "mul" MUL) -let flt_div = f_memo (make_fun_float "div" DIV) -let flt_neg = f_memo (make_fun_float "neg" NEG) +module Model (X: sig val kind: model end) = +struct + let make_fun_float ?result = make_fun_float ?result X.kind + let make_pred_float = make_pred_float X.kind + + let real_of_flt = f_memo (make_fun_float ~result:Logic.Real "of" REAL) + let flt_of_real = f_memo (make_fun_float "to" ROUND) + let flt_add = f_memo (make_fun_float "add" ADD) + let flt_mul = f_memo (make_fun_float "mul" MUL) + let flt_div = f_memo (make_fun_float "div" DIV) + let flt_neg = f_memo (make_fun_float "neg" NEG) + let flt_lt = f_memo (make_pred_float "lt" LT) + let flt_eq = f_memo (make_pred_float "eq" EQ) + let flt_le = f_memo (make_pred_float "le" LE) + let flt_neq = f_memo (make_pred_float "ne" NE) +end + +module Real_model = Model(struct let kind = Real end) +module Float_model = Model(struct let kind = Float end) + +let model_flt_add = function + | Real -> Real_model.flt_add + | Float -> Float_model.flt_add + +let model_flt_mul = function + | Real -> Real_model.flt_mul + | Float -> Float_model.flt_mul + +let model_flt_div = function + | Real -> Real_model.flt_div + | Float -> Float_model.flt_div + +let model_flt_neg = function + | Real -> Real_model.flt_neg + | Float -> Float_model.flt_neg + +let model_flt_lt = function + | Real -> Real_model.flt_lt + | Float -> Float_model.flt_lt + +let model_flt_eq = function + | Real -> Real_model.flt_eq + | Float -> Float_model.flt_eq + +let model_flt_le = function + | Real -> Real_model.flt_le + | Float -> Float_model.flt_le + +let model_flt_neq = function + | Real -> Real_model.flt_neq + | Float -> Float_model.flt_neq + +let model_real_of_flt = function + | Real -> Real_model.real_of_flt + | Float -> Float_model.real_of_flt + +let model_flt_of_real = function + | Real -> Real_model.flt_of_real + | Float -> Float_model.flt_of_real + +let flt_eq ft = model_flt_eq (Context.get model) ft +let flt_neq = model_flt_neq (Context.get model) +let flt_le = model_flt_le (Context.get model) +let flt_lt = model_flt_lt (Context.get model) +let flt_neg = model_flt_neg (Context.get model) +let flt_add ft = model_flt_add (Context.get model) ft +let flt_mul = model_flt_mul (Context.get model) +let flt_div = model_flt_div (Context.get model) +let flt_of_real = model_flt_of_real (Context.get model) +let real_of_flt = model_real_of_flt (Context.get model) -let flt_lt = f_memo (make_pred_float "lt" LT) -let flt_eq = f_memo (make_pred_float "eq" EQ) -let flt_le = f_memo (make_pred_float "le" LE) -let flt_neq = f_memo (make_pred_float "ne" NE) (* -------------------------------------------------------------------------- *) (* --- Builtins --- *) (* -------------------------------------------------------------------------- *) -let register_builtin_comparison suffix ft = - begin +let hack f ft xs = + let phi = f (Context.get model) ft in + try (get_impl phi) xs + with Not_found -> F.e_fun phi xs + +let make_converse_dispatch name dispatch ft = + let register model_name impl = let open Qed.Logic in - let params = [Sdata;Sdata] in - let sort = Sprop in - let gt = generated_f ~params ~sort "\\gt_%s" suffix in - let ge = generated_f ~params ~sort "\\ge_%s" suffix in - let open LogicBuiltins in - let signature = [F ft;F ft] in - add_builtin ("\\eq_" ^ suffix) signature (flt_eq ft) ; - add_builtin ("\\ne_" ^ suffix) signature (flt_neq ft) ; - add_builtin ("\\lt_" ^ suffix) signature (flt_lt ft) ; - add_builtin ("\\le_" ^ suffix) signature (flt_le ft) ; - add_builtin ("\\gt_" ^ suffix) signature gt ; - add_builtin ("\\ge_" ^ suffix) signature ge ; - let converse phi x y = e_fun phi [y;x] in - Lang.F.set_builtin_2 gt (converse (flt_lt ft)) ; - Lang.F.set_builtin_2 ge (converse (flt_le ft)) ; - end + let phi = generated_f ~params:[Sdata;Sdata] ~sort:Sprop "\\%s_%s_%s" + model_name name (float_name ft) + in + Lang.F.set_builtin phi impl + in + let op_r xs = (hack dispatch ft) (List.rev xs) in + let op_f xs = (hack dispatch ft) (List.rev xs) in + register "Real" op_r ; + register "Float" op_f ; + let hack params = + match Context.get model with + | Real -> op_r params + | Float -> op_f params + in + hack + +let make_all ft = + let suffix = float_name ft in + let gt_dispatch = make_converse_dispatch "gt" model_flt_lt ft in + let ge_dispatch = make_converse_dispatch "ge" model_flt_le ft in + LogicBuiltins.hack ("\\lt_" ^ suffix) (hack model_flt_lt ft) ; + LogicBuiltins.hack ("\\gt_" ^ suffix) gt_dispatch ; + LogicBuiltins.hack ("\\le_" ^ suffix) (hack model_flt_le ft) ; + LogicBuiltins.hack ("\\ge_" ^ suffix) ge_dispatch ; + LogicBuiltins.hack ("\\eq_" ^ suffix) (hack model_flt_eq ft) ; + LogicBuiltins.hack ("\\ne_" ^ suffix) (hack model_flt_neq ft) ; + () let () = Context.register begin fun () -> - register_builtin_comparison "float" Float32 ; - register_builtin_comparison "double" Float64 ; + make_all Float32 ; + make_all Float64 end (* -------------------------------------------------------------------------- *) @@ -360,17 +449,14 @@ let () = (* -------------------------------------------------------------------------- *) let () = - Context.register - begin fun () -> - let open LogicBuiltins in - let register_builtin ft = - add_builtin "\\model" [F ft] (f_model ft) ; - add_builtin "\\delta" [F ft] (f_delta ft) ; - add_builtin "\\epsilon" [F ft] (f_epsilon ft) ; - in - register_builtin Float32 ; - register_builtin Float64 ; - end + let open LogicBuiltins in + let register_builtin ft = + add_builtin "\\model" [F ft] (f_model ft) ; + add_builtin "\\delta" [F ft] (f_delta ft) ; + add_builtin "\\epsilon" [F ft] (f_epsilon ft) ; + in + register_builtin Float32 ; + register_builtin Float64 (* -------------------------------------------------------------------------- *) (* --- Conversion Symbols --- *)