1 (* Copyright (C) 2000, HELM Team.
3 * This file is part of HELM, an Hypertextual, Electronic
4 * Library of Mathematics, developed at the Computer Science
5 * Department, University of Bologna, Italy.
7 * HELM is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * HELM is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with HELM; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 * For details, see the HELM World-Wide-Web page,
23 * http://cs.unibo.it/helm/.
26 (* AUTOR: Ferruccio Guidi <fguidi@cs.unibo.it>
36 (* FALSE / EMPTY ************************************************************)
39 let s = if b then "false" else "empty" in
40 L.fun_arity0 [] s U.mql_false
42 let _ = L.fun_register ["empty"] (false_fun false)
44 let _ = L.fun_register ["false"] (false_fun true)
46 (* TRUE *********************************************************************)
48 let true_fun = L.fun_arity0 [] "true" U.mql_true
50 let _ = L.fun_register ["true"] true_fun
52 (* NOT **********************************************************************)
55 let aux r = if r = U.mql_false then U.mql_true else U.mql_false in
56 L.fun_arity1 [] "!" aux
58 let _ = L.fun_register ["not"] not_fun
60 (* COUNT ********************************************************************)
63 let aux r = [string_of_int (List.length r), []] in
64 L.fun_arity1 [] "#" aux
66 let _ = L.fun_register ["count"] count_fun
68 (* PEEK *********************************************************************)
71 let aux = function [] -> [] | hd :: _ -> [hd] in
72 L.fun_arity1 [] "peek" aux
74 let _ = L.fun_register ["peek"] peek_fun
76 (* DIFF *********************************************************************)
78 let diff_fun = L.fun_arity2 [] "diff" U.mql_diff
80 let _ = L.fun_register ["diff"] diff_fun
82 (* XOR **********************************************************************)
84 let xor_fun = L.fun_arity2 [] "xor" U.xor
86 let _ = L.fun_register ["xor"] xor_fun
88 (* SUB **********************************************************************)
90 let sub_fun = L.fun_arity2 [] "sub" U.set_sub
92 let _ = L.fun_register ["sub"] sub_fun
94 (* MEET *********************************************************************)
96 let meet_fun = L.fun_arity2 [] "meet" U.set_meet
98 let _ = L.fun_register ["meet"] meet_fun
100 (* EQ ***********************************************************************)
102 let eq_fun = L.fun_arity2 [] "==" U.set_eq
104 let _ = L.fun_register ["eq"] eq_fun
106 (* LE ***********************************************************************)
110 if U.int_of_set v1 <= U.int_of_set v2 then U.mql_true else U.mql_false
112 L.fun_arity2 [] "<=" le
114 let _ = L.fun_register ["le"] le_fun
116 (* LT ***********************************************************************)
120 if U.int_of_set v1 < U.int_of_set v2 then U.mql_true else U.mql_false
122 L.fun_arity2 [] "<" lt
124 let _ = L.fun_register ["lt"] lt_fun
126 (* STAT *********************************************************************)
129 let arity_p = L.Const 0 in
130 let arity_s = L.Const 1 in
131 let body e o _ _ = function
133 let t = P.start_time () in
134 let r = (e.L.eval x) in
135 let s = P.stop_time t in
136 o.L.out (Printf.sprintf "Stat: %s,%i\n" s (List.length r));
140 let txt_out o _ = function
141 | [x] -> let o = L.std o in o.L.s_out "stat "; o.L.s_query x
144 {L.arity_p = arity_p; L.arity_s = arity_s; L.body = body; L.txt_out = txt_out}
146 let _ = L.fun_register ["stat"] stat_fun
148 (* LOG **********************************************************************)
150 let log_fun xml src =
152 let t = P.start_time () in o.L.s_query x;
153 let s = P.stop_time t in
154 if C.set e.L.conn C.Stat then o.L.s_out (Printf.sprintf "Log source: %s\n" s);
158 let s = e.L.eval x in
159 let t = P.start_time () in o.L.s_result s;
160 let r = P.stop_time t in
161 if C.set e.L.conn C.Stat then o.L.s_out (Printf.sprintf "Log: %s\n" r); s
164 if xml then o.L.s_out "xml ";
165 if src then o.L.s_out "source "
167 let arity_p = L.Const 0 in
168 let arity_s = L.Const 1 in
169 let body e o _ _ = function
170 | [x] -> let o = L.std o in if src then log_src e o x else log_res e o x
173 let txt_out o _ = function
174 | [x] -> let o = L.std o in o.L.s_out "log "; txt_log o; o.L.s_query x
177 {L.arity_p = arity_p; L.arity_s = arity_s; L.body = body; L.txt_out = txt_out}
179 let _ = L.fun_register ["log"; "text"; "result"] (log_fun false false)
181 let _ = L.fun_register ["log"; "text"; "source"] (log_fun false true)
183 (* RENDER *******************************************************************)
186 let arity_p = L.Const 0 in
187 let arity_s = L.Const 1 in
188 let body e o _ _ = function
191 let out s = rs := ! rs ^ s in
192 o.L.result out " " (e.L.eval x);
196 let txt_out o _ = function
197 | [x] -> let o = L.std o in o.L.s_out "render "; o.L.s_query x
200 {L.arity_p = arity_p; L.arity_s = arity_s; L.body = body; L.txt_out = txt_out}
202 let _ = L.fun_register ["render"] render_fun
204 (* READ *********************************************************************)
207 let arity_p = L.Const 0 in
208 let arity_s = L.Const 1 in
209 let body e o i _ = function
212 let ich = open_in (fst av) in
213 let r = i.L.result_in (Lexing.from_channel ich) in
216 U.mql_iter aux (e.L.eval x)
219 let txt_out o _ = function
220 | [x] -> let o = L.std o in o.L.s_out "read "; o.L.s_query x
223 {L.arity_p = arity_p; L.arity_s = arity_s; L.body = body; L.txt_out = txt_out}
225 let _ = L.fun_register ["read"] read_fun
227 (* ALIGN ********************************************************************)
231 let c = String.length v in
232 if c < l then [(String.make (l - c) ' ' ^ v), g] else [v, g]
234 let arity_p = L.Const 0 in
235 let arity_s = L.Const 2 in
236 let body e _ _ _ = function
238 let l = U.int_of_set (e.L.eval y) in
239 U.mql_iter (aux l) (e.L.eval x)
242 let txt_out o _ = function
245 o.L.s_out "align "; o.L.s_query y; o.L.s_out " in "; o.L.s_query x
248 {L.arity_p = arity_p; L.arity_s = arity_s; L.body = body; L.txt_out = txt_out}
250 let _ = L.fun_register ["align"] align_fun
252 (* IF ***********************************************************************)
255 let arity_p = L.Const 0 in
256 let arity_s = L.Const 3 in
257 let body e _ _ _ = function
259 if (e.L.eval y) = U.mql_false then (e.L.eval x2) else (e.L.eval x1)
262 let txt_out o _ = function
265 o.L.s_out "if "; o.L.s_query y; o.L.s_out " then "; o.L.s_query x1;
266 o.L.s_out " else "; o.L.s_query x2
269 {L.arity_p = arity_p; L.arity_s = arity_s; L.body = body; L.txt_out = txt_out}
271 let _ = L.fun_register["if"] if_fun
273 (* INTERSECT ****************************************************************)
276 let rec iter f = function
279 | head :: tail -> U.mql_intersect (f head) (iter f tail)
281 let arity_p = L.Const 0 in
282 let arity_s = L.Positive in
283 let body e _ _ _ xl = iter e.L.eval xl in
284 let txt_out o _ = function
286 | [x1; x2] -> let o = L.std o in L.out_txt2 o "/\\" x1 x2
287 | xl -> let o = L.std o in L.out_txt_ o ["intersect"] xl
289 {L.arity_p = arity_p; L.arity_s = arity_s; L.body = body; L.txt_out = txt_out}
291 let _ = L.fun_register ["intersect"] intersect_fun
293 (* UNION ********************************************************************)
296 let arity_p = L.Const 0 in
297 let arity_s = L.Any in
298 let body e _ _ _ xl = U.mql_iter e.L.eval xl in
299 let txt_out o _ xl = let o = L.std o in L.out_txt_ o [] xl
301 {L.arity_p = arity_p; L.arity_s = arity_s; L.body = body; L.txt_out = txt_out}
303 let _ = L.fun_register ["union"] union_fun
305 (* OR ***********************************************************************)
308 let rec iter f = function
312 if r1 = U.mql_false then (iter f tail) else r1
314 let arity_p = L.Const 0 in
315 let arity_s = L.Any in
316 let body e _ _ _ xl = iter e.L.eval xl in
317 let txt_out o _ = function
318 | [x1; x2] -> let o = L.std o in L.out_txt2 o "||" x1 x2
319 | xl -> let o = L.std o in L.out_txt_ o ["or"] xl
321 {L.arity_p = arity_p; L.arity_s = arity_s; L.body = body; L.txt_out = txt_out}
323 let _ = L.fun_register ["or"] or_fun
325 (* AND **********************************************************************)
328 let rec iter f = function
332 if f head = U.mql_false then U.mql_false else iter f tail
334 let arity_p = L.Const 0 in
335 let arity_s = L.Any in
336 let body e _ _ _ xl = iter e.L.eval xl in
337 let txt_out o _ = function
338 | [x1; x2] -> let o = L.std o in L.out_txt2 o "&&" x1 x2
339 | xl -> let o = L.std o in L.out_txt_ o ["and"] xl
341 {L.arity_p = arity_p; L.arity_s = arity_s; L.body = body; L.txt_out = txt_out}
343 let _ = L.fun_register ["and"] and_fun
345 (* PROJ *********************************************************************)
348 let proj_group_aux p (q, v) = if q = p then U.mql_subj v else [] in
349 let proj_group p a = U.mql_iter (proj_group_aux p) a in
350 let proj_set p (_, g) = U.mql_iter (proj_group p) (List.rev g) in
351 let arity_p = L.Const 1 in
352 let arity_s = L.Const 1 in
353 let body e _ _ pl xl =
355 | [p], [x] -> U.mql_iter (proj_set p) (e.L.eval x)
358 let txt_out o pl xl =
362 o.L.s_out "proj "; o.L.s_path p; o.L.s_out " of "; o.L.s_query x
365 {L.arity_p = arity_p; L.arity_s = arity_s; L.body = body; L.txt_out = txt_out}
367 let _ = L.fun_register ["proj"] proj_fun
369 (* KEEP *********************************************************************)
372 let proj (r, _) = (r, []) in
373 let keep_path l (p, v) t = if List.mem p l = b then t else (p, v) :: t in
374 let keep_grp l a = List.fold_right (keep_path l) a [] in
376 let kg = keep_grp l a in
377 if kg = [] then g else kg :: g
379 let keep_av l (s, g) = (s, List.fold_right (keep_set l) g []) in
380 let txt_allbut o = if b then o.L.s_out "allbut " in
381 let txt_path_list o l = P.flat_list o.L.s_out o.L.s_path ", " l in
382 let arity_p = L.Any in
383 let arity_s = L.Const 1 in
384 let body e _ _ pl xl =
386 | true, [], [x] -> e.L.eval x
387 | false, [], [x] -> List.map proj (e.L.eval x)
388 | _, l, [x] -> List.map (keep_av l) (e.L.eval x)
391 let txt_out o pl xl =
395 o.L.s_out "keep "; txt_allbut o; o.L.s_query x
398 o.L.s_out "keep "; txt_allbut o; txt_path_list o l;
399 o.L.s_out " in "; o.L.s_query x
402 {L.arity_p = arity_p; L.arity_s = arity_s; L.body = body; L.txt_out = txt_out}
404 let _ = L.fun_register ["keep"; "these"] (keep_fun false)
406 let _ = L.fun_register ["keep"; "allbut"] (keep_fun true)