X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Focaml%2Fmathql_interpreter%2FmQILib.ml;h=b2260244582f625ceb568cc342d43db8ffc55619;hb=efdc3184ccd0738fe48aa0056fc444fba23329e8;hp=f816590d102b687cf626d05ade27345e0d8954c7;hpb=5bef9ac5a9bfe07b11ce0e44fab51ea4b6eb4057;p=helm.git diff --git a/helm/ocaml/mathql_interpreter/mQILib.ml b/helm/ocaml/mathql_interpreter/mQILib.ml index f816590d1..b22602445 100644 --- a/helm/ocaml/mathql_interpreter/mQILib.ml +++ b/helm/ocaml/mathql_interpreter/mQILib.ml @@ -28,8 +28,8 @@ module M = MathQL module P = MQueryUtil +module C = MQIConn module U = MQIUtil -module C = MQIConn (* external function specification ******************************************) @@ -37,310 +37,138 @@ type arity_t = Const of int | Positive | Any -type eval_spec = {eval : M.query -> M.result; - handle : C.handle +type eval_spec = {eval : M.query -> M.result; + conn : C.handle } -type txt_out_spec = {out : string -> unit; - path : M.path -> unit; - query : M.query -> unit; - result : M.result -> unit - } +type text_out_spec = {out : string -> unit; + path : (string -> unit) -> M.path -> unit; + query : (string -> unit) -> string -> M.query -> unit; + result : (string -> unit) -> string -> M.result -> unit + } + +type text_in_spec = {result_in : Lexing.lexbuf -> M.result} type fun_spec = {arity_p : arity_t; arity_s : arity_t; - body : eval_spec -> txt_out_spec -> + body : eval_spec -> text_out_spec -> text_in_spec -> M.path list -> M.query list -> M.result; - txt_out : txt_out_spec -> + txt_out : text_out_spec -> M.path list -> M.query list -> unit } +type gen_spec = {arity : arity_t; + code : eval_spec -> M.query list -> M.query + } + exception ArityError of M.path * arity_t * int exception NameError of M.path exception NumberError of M.result +type std_text_out_spec = {s_out : string -> unit; + s_path : M.path -> unit; + s_query : M.query -> unit; + s_result : M.result -> unit +} + +let check_arity p i = function + | Const k when i = k -> () + | Positive when i > 0 -> () + | Any -> () + | a -> raise (ArityError (p, a, i)) + (* external functions implementation ****************************************) -let int_of_set s = - try match s with - | [s, _] -> int_of_string s - | _ -> raise (Failure "int_of_string") - with Failure "int_of_string" -> raise (NumberError s) +let std o = + {s_out = o.out; s_path = o.path o.out; + s_query = o.query o.out ""; s_result = o.result o.out "\n" + } -let out_txt2 out commit n x1 x2 = - out "(" ; commit x1; out (" " ^ n ^ " "); commit x2; out ")" +let out_txt2 o n x1 x2 = + o.s_out "(" ; o.s_query x1; o.s_out (" " ^ n ^ " "); o.s_query x2; o.s_out ")" -let out_txt_ out path commit p xl = - path p; out " {"; P.flat_list out commit ", " xl; out "}" +let out_txt_ o p xl = + if p <> [] then begin o.s_path p; o.s_out " " end; + o.s_out "{"; P.flat_list o.s_out o.s_query ", " xl; o.s_out "}" -let out_txt_full out path commit p pl xl = - path p; out " {"; P.flat_list out path ", " pl; out "} {"; - P.flat_list out commit ", " xl; out "}" +let out_txt_full o p pl xl = + o.s_path p; o.s_out " {"; P.flat_list o.s_out o.s_path ", " pl; o.s_out "} {"; + P.flat_list o.s_out o.s_query ", " xl; o.s_out "}" -let arity0 n r = +let fun_arity0 p n r = let arity_p = Const 0 in let arity_s = Const 0 in - let body _ _ _ _ = U.mql_true in - let txt_out s _ _ = s.out n in + let body _ _ _ _ _ = r in + let txt_out o _ _ = + if n = "" then out_txt_full (std o) p [] [] else (std o).s_out n + in {arity_p = arity_p; arity_s = arity_s; body = body; txt_out = txt_out} -let arity1 n f = +let fun_arity1 p n f = let arity_p = Const 0 in let arity_s = Const 1 in - let body eval _ _ = function - | [x] -> f (eval x) + let body e _ _ _ = function + | [x] -> f (e.eval x) | _ -> assert false in - let txt_out out _ commit _ = function - | [x] -> out (n ^ " "); commit x + let txt_out o _ = function + | [x] -> + let o = std o in + if n = "" then out_txt_full o p [] [x] else + begin o.s_out (n ^ " "); o.s_query x end | _ -> assert false in {arity_p = arity_p; arity_s = arity_s; body = body; txt_out = txt_out} -let arity2 n f = +let fun_arity2 p n f = let arity_p = Const 0 in let arity_s = Const 2 in - let body eval _ _ = function - | [x1; x2] -> f (eval x1) (eval x2) + let body e _ _ _ = function + | [x1; x2] -> f (e.eval x1) (e.eval x2) | _ -> assert false in - let txt_out out _ commit _ = function - | [x1; x2] -> out_txt2 out commit n x1 x2 + let txt_out o _ = function + | [x1; x2] -> + let o = std o in + if n = "" then out_txt_full o p [] [x1; x2] else out_txt2 o n x1 x2 | _ -> assert false in {arity_p = arity_p; arity_s = arity_s; body = body; txt_out = txt_out} -let false_fun = arity0 "false" U.mql_false +(* external functions interface *********************************************) -let true_fun = arity0 "true" U.mql_true +let funs = Hashtbl.create 11 -let not_fun = - let aux r = if r = U.mql_false then U.mql_true else U.mql_false in - arity1 "not" aux +let fun_register path spec = Hashtbl.add funs path spec -let count_fun = - let aux r = [string_of_int (List.length r), []] in - arity1 "count" aux +let fun_get_spec path = + try Hashtbl.find funs path + with Not_found -> raise (NameError path) -let diff_fun = arity2 "diff" U.mql_diff +let fun_arity p m n = + check_arity p m (fun_get_spec p).arity_p; + check_arity p n (fun_get_spec p).arity_s -let xor_fun = arity2 "xor" U.xor +let fun_eval e o i p pl xl = (fun_get_spec p).body e o i pl xl -let sub_fun = arity2 "sub" U.set_sub +let fun_txt_out o p pl xl = + try (fun_get_spec p).txt_out o pl xl + with NameError q when q = p -> out_txt_full (std o) p pl xl -let meet_fun = arity2 "meet" U.set_meet +(* generator functions implementation ***************************************) -let eq_fun = arity2 "eq" U.set_eq +(* generator functions interface ********************************************) -let le_fun = - let le v1 v2 = - if int_of_set v1 <= int_of_set v2 then U.mql_true else U.mql_false - in - arity2 "le" le +let gens = Hashtbl.create 11 -let lt_fun = - let lt v1 v2 = - if int_of_set v1 < int_of_set v2 then U.mql_true else U.mql_false - in - arity2 "lt" lt +let gen_register path spec = Hashtbl.add gens path spec -let stat_fun = - let arity_p = Const 0 in - let arity_s = Const 1 in - let body eval h _ = function - | [x] -> - let t = P.start_time () in - let r = (eval x) in - let s = P.stop_time t in - C.log h (Printf.sprintf "Stat: %s,%i\n" s (List.length r)); - r - | _ -> assert false - in - let txt_out out _ commit _ = function - | [x] -> out "stat "; commit x - | _ -> assert false - in - {arity_p = arity_p; arity_s = arity_s; body = body; txt_out = txt_out} +let gen_get_spec path = + try Hashtbl.find gens path + with Not_found -> raise (NameError path) -let align_fun = - let aux l (v, g) = - let c = String.length v in - if c < l then [(String.make (l - c) ' ' ^ v), g] else [v, g] - in - let arity_p = Const 0 in - let arity_s = Const 2 in - let body eval _ _ = function - | [y; x] -> - let l = int_of_set (eval y) in - U.mql_iter (aux l) (eval x) - | _ -> assert false - in - let txt_out out _ commit _ = function - | [y; x] -> out "align "; commit y; out " in "; commit x - | _ -> assert false - in - {arity_p = arity_p; arity_s = arity_s; body = body; txt_out = txt_out} - -let if_fun = - let arity_p = Const 0 in - let arity_s = Const 3 in - let body eval _ _ = function - | [y; x1; x2] -> - if (eval y) = U.mql_false then (eval x2) else (eval x1) - | _ -> assert false - in - let txt_out out _ commit _ = function - | [y; x1; x2] -> - out "if "; commit y; out " then "; commit x1; out " else "; commit x2 - | _ -> assert false - in - {arity_p = arity_p; arity_s = arity_s; body = body; txt_out = txt_out} - -let intersect_fun = - let rec iter f = function - | [] -> assert false - | [head] -> f head - | head :: tail -> U.mql_intersect (f head) (iter f tail) - in - let arity_p = Const 0 in - let arity_s = Positive in - let body eval _ _ xl = iter eval xl in - let txt_out out path commit _ = function - | [] -> assert false - | [x1; x2] -> out_txt2 out commit "intersect" x1 x2 - | xl -> out_txt_ out path commit ["intersect"] xl - in - {arity_p = arity_p; arity_s = arity_s; body = body; txt_out = txt_out} - -let union_fun = - let arity_p = Const 0 in - let arity_s = Any in - let body eval _ _ xl = U.mql_iter eval xl in - let txt_out out path commit _ = function - | [x1; x2] -> out_txt2 out commit "union" x1 x2 - | xl -> out_txt_ out path commit ["union"] xl - in - {arity_p = arity_p; arity_s = arity_s; body = body; txt_out = txt_out} - -let or_fun = - let rec iter f = function - | [] -> U.mql_false - | head :: tail -> - let r1 = f head in - if r1 = U.mql_false then (iter f tail) else r1 - in - let arity_p = Const 0 in - let arity_s = Any in - let body eval _ _ xl = iter eval xl in - let txt_out out path commit _ = function - | [x1; x2] -> out_txt2 out commit "or" x1 x2 - | xl -> out_txt_ out path commit ["or"] xl - in - {arity_p = arity_p; arity_s = arity_s; body = body; txt_out = txt_out} - -let and_fun = - let rec iter f = function - | [] -> U.mql_true - | head :: tail -> - if f head = U.mql_false then U.mql_false else (iter f tail) - in - let arity_p = Const 0 in - let arity_s = Any in - let body eval _ _ xl = iter eval xl in - let txt_out out path commit _ = function - | [x1; x2] -> out_txt2 out commit "and" x1 x2 - | xl -> out_txt_ out path commit ["and"] xl - in - {arity_p = arity_p; arity_s = arity_s; body = body; txt_out = txt_out} - -(* external functions interface *********************************************) +let gen_arity p n = check_arity p n (gen_get_spec p).arity -let get_spec = function - | ["false"] -> false_fun - | ["true"] -> true_fun - | ["not"] -> not_fun - | ["count"] -> count_fun - | ["stat"] -> stat_fun - | ["diff"] -> diff_fun - | ["xor"] -> xor_fun - | ["sub"] -> sub_fun - | ["meet"] -> meet_fun - | ["eq"] -> eq_fun - | ["le"] -> le_fun - | ["lt"] -> lt_fun - | ["align"] -> align_fun - | ["if"] -> if_fun - | ["intersect"] -> intersect_fun - | ["union"] -> union_fun - | ["or"] -> or_fun - | ["and"] -> and_fun - | p -> raise (NameError p) - -let check_arity p m n = - let aux i = function - | Const k when i = k -> () - | Positive when i > 0 -> () - | Any -> () - | a -> raise (ArityError (p, a, i)) - in - aux m (get_spec p).arity_p; aux n (get_spec p).arity_s - -let exec eval h p pl xl = (get_spec p).body eval h pl xl - -let txt_out out path commit p pl xl = - try (get_spec p).txt_out out path commit pl xl - with NameError q when q = p -> out_txt_full out path commit p pl xl - -(* - | M.Proj (Some p) x -> out "proj "; txt_path out p; out "of "; txt_set x - | M.Log a b x -> out "log "; txt_log a b; txt_set x - | M.Keep b l x -> out "keep "; txt_allbut b; txt_path_list l; - txt_set x - let txt_path_list l = P.flat_list out (txt_path out) ", " l in - let txt_log a b = - if a then out "xml "; - if b then out "source " - in - let txt_allbut b = if b then out "allbut " in - - | M.Proj None x -> List.map (fun (r, _) -> (r, [])) (eval_query c x) - | M.Proj (Some p) x -> - let proj_group_aux (q, v) = if q = p then subj v else [] in - let proj_group a = U.mql_iter proj_group_aux a in - let proj_set (_, g) = U.mql_iter proj_group g in - U.mql_iter proj_set (eval_query c x) - - - | M.Log _ b x -> - if b then begin - let t = P.start_time () in - F.text_of_query (C.log h) x "\n"; - let s = P.stop_time t in - if C.set h C.Stat then - C.log h (Printf.sprintf "Log source: %s\n" s); - eval_query c x - end else begin - let s = (eval_query c x) in - let t = P.start_time () in - F.text_of_result (C.log h) s "\n"; - let r = P.stop_time t in - if C.set h C.Stat then - C.log h (Printf.sprintf "Log: %s\n" r); - s - end - - | M.Keep b l x -> - let keep_path (p, v) t = - if List.mem p l = b then t else (p, v) :: t in - let keep_grp a = List.fold_right keep_path a [] in - let keep_set a g = - let kg = keep_grp a in - if kg = [] then g else kg :: g - in - let keep_av (s, g) = (s, List.fold_right keep_set g []) in - List.map keep_av (eval_query c x) - - -*) +let gen_eval e p xl = (gen_get_spec p).code e xl