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/.
27 * implementazione del'interprete MathQL
31 (* FG: ROBA VECCHIA DA BUTTARE (tranne apertura e chiusura database *)
49 open Mathql_semantics;;
53 let prop_pool = ref None;;
67 "/" ^ (string_of_int j)
72 let see_prop_pool () =
73 let _ = print_endline "eccomi" in
75 (fun elem -> print_endline (fst elem ^ ": " ^ snd elem))
76 (match !prop_pool with Some l -> l | _ -> print_endline "ciao"; assert false)
80 * inizializzazione della connessione al database
83 let _ = Dbconn.init () in
86 c#exec "select name,id from property where ns_id in (select id from namespace where url='http://www.cs.unibo.it/helm/schemas/mattone.rdf#')"
93 | _ -> print_endline "no"; assert false
99 let get_prop_id prop =
100 if prop="refObj" then "F"
101 else if prop="backPointer" then "B"
102 else List.assoc prop (match !prop_pool with Some l -> l | _ -> assert false)
105 (* execute_ex env q *)
106 (* [env] is the attributed uri environment in which the query [q] *)
107 (* must be evaluated *)
108 (* [q] is the query to evaluate *)
109 (* It returns a [Mathql_semantics.result] *)
110 let rec execute_ex env =
112 MQSelect (apvar, alist, abool) ->
113 select_ex env apvar (execute_ex env alist) abool
114 | MQUsedBy (alist, asvar) ->
115 use_ex (execute_ex env alist) asvar (get_prop_id "refObj") (* "F" (*"refObj"*) *)
116 | MQUse (alist, asvar) ->
117 use_ex (execute_ex env alist) asvar (get_prop_id "backPointer") (* "B" (*"backPointer"*) *)
118 | MQPattern (apreamble, apattern, afragid) ->
119 pattern_ex (apreamble, apattern, afragid)
120 | MQUnion (l1, l2) ->
121 union_ex (execute_ex env l1) (execute_ex env l2)
123 diff_ex (execute_ex env l1) (execute_ex env l2)
124 | MQSortedBy (l, o, f) ->
125 sortedby_ex (execute_ex env l) o f
126 | MQIntersect (l1, l2) ->
127 intersect_ex (execute_ex env l1) (execute_ex env l2)
128 | MQListRVar rvar -> [List.assoc rvar env]
129 | MQLetIn (lvar, l1, l2) ->
130 let t = Unix.time () in
132 (*CSC: The interesting code *)
133 let _ = letin_ex lvar (execute_ex env l1) in
135 (*CSC: end of the interesting code *)
138 print_string ("LETIN = " ^ string_of_int (List.length res) ^ ": ") ;
139 print_endline (string_of_float (Unix.time () -. t) ^ "s") ;
145 let rec build_result = function
148 {uri = s ; attributes = [] ; extra = ""} :: build_result tail
149 in build_result (List.sort compare l)
152 (* Let's initialize the execute in Select, creating a cyclical recursion *)
153 Select.execute := execute_ex;;
156 * converte il risultato interno di una query (uri + contesto)
157 * in un risultato di sole uri
160 * l: string list list;
165 * il tipo del risultato mantenuto internamente e' diverso dal tipo di risultato
166 * restituito in output poiche', mentre chi effettua le query vuole come risultato
167 * solo le eventuali uri che soddisfano le query stesse, internamente ad una uri
168 * sono associati anche i valori delle variabili che ancora non sono state valutate
169 * perche', ad esempio, si trovano in altri rami dell'albero.
172 * SELECT x IN USE PATTERN "cic:/**.con" POSITION $a WHERE $a IS MainConclusion
173 * L'albero corrispondente a questa query e':
179 * PATTERN $a $a MainConclusion
181 * Nel momento in cui si esegue il ramo USE non sono noti i vincoli sullla variabile $a
182 * percui e' necessario considerare, oltre alle uri, i valori della variabile per i quali
183 * la uri puo' far parte del risultato.
186 MQRefs (List.map (function {Mathql_semantics.uri = uri} -> uri) l)
188 let tmp = List.map (function {Mathql_semantics.uri = uri} -> uri) l in
192 (*let _ = print_endline ("DEBUG: (mqint.ml: xres_to_res)" ^ l) in*)
193 match Str.split (Str.regexp ":\|#\|/\|(\|)") l with
195 match List.rev tl with
196 n::"1"::"xpointer"::tail ->
203 | _ -> (MQBC t) :: MQBD :: par
207 [MQFC (int_of_string n)]
209 | n::m::"1"::"xpointer"::tail ->
216 | _ -> (MQBC t) :: MQBD :: par
220 [MQFC (int_of_string m); MQFC (int_of_string n)]
229 | _ -> (MQBC t) :: MQBD :: par
249 MQList qq -> xres_to_res (execute_ex [] qq)
253 * chiusura della connessione al database
255 let close () = Dbconn.close ();;
257 *****************************************************************************)
259 let init () = () (* FG: implementare l'apertura del database *)
261 let close () = () (* FG: implementare la chiusura del database *)
265 exception BooleExpTrue
267 (* valuta una MathQL.set_exp e ritorna un MathQL.resource_set *)
269 let rec exec_set_exp c = function
270 |MathQL.SVar svar -> List.assoc svar c.svars
271 |MathQL.RVar rvar -> [List.assoc rvar c.rvars]
272 | MathQL.Ref vexp -> List.map (fun s -> (s,[])) (exec_val_exp c vexp)
273 | MathQL.Intersect (sexp1, sexp2) -> intersect_ex (exec_set_exp c sexp1) (exec_set_exp c sexp2)
274 | MathQL.Union (sexp1, sexp2) -> union_ex (exec_set_exp c sexp1) (exec_set_exp c sexp2)
275 | MathQL.LetSVar (svar, sexp1, sexp2) -> let _ = (svar, (exec_set_exp c sexp1)):: (List.remove_assoc svar c.svars)
276 in (exec_set_exp c sexp2)
277 | MathQL.LetVVar (vvar, vexp, sexp) -> let _ = (vvar, (exec_val_exp c vexp)):: (List.remove_assoc vvar c.vvars)
278 in (exec_set_exp c sexp)
279 | MathQL.Relation (rop, path, sexp, attl) -> relation_ex rop path (exec_set_exp c sexp) attl
280 | MathQL.Select (rvar, sexp, bexp) -> let rset = (exec_set_exp c sexp) in
281 let rec select_ex rset =
284 | r::tl -> let c1 = upd_rvars c ((rvar,r)::c.rvars) in
285 if (exec_boole_exp c1 bexp) then r::(select_ex tl)
291 | MathQL.Diff (sexp1, sexp2) -> diff_ex (exec_set_exp c sexp1) (exec_set_exp c sexp2)
294 (* valuta una MathQL.boole_exp e ritorna un boole *)
296 and exec_boole_exp c = function
297 | MathQL.False -> false
298 | MathQL.True -> true
299 | MathQL.Not x -> not (exec_boole_exp c x)
300 | MathQL.And (x, y) -> (exec_boole_exp c x) && (exec_boole_exp c y)
301 | MathQL.Or (x, y) -> (exec_boole_exp c x) || (exec_boole_exp c y)
302 | MathQL.Sub (vexp1, vexp2) -> sub_ex (exec_val_exp c vexp1) (exec_val_exp c vexp2)
303 | MathQL.Meet (vexp1, vexp2) -> meet_ex (exec_val_exp c vexp1) (exec_val_exp c vexp2)
304 | MathQL.Eq (vexp1, vexp2) -> (exec_val_exp c vexp1) = (exec_val_exp c vexp2)
305 | MathQL.Ex l bexp ->
306 if l = [] then (exec_boole_exp c bexp)
308 let latt = List.map (fun uri ->
309 let (r,attl) = List.assoc uri c.rvars
310 in (uri,attl)) l (*latt = l + attributi*)
313 let rec prod c = function
314 [] -> if (exec_boole_exp c bexp) then raise BooleExpTrue
315 | (uri,attl)::tail1 -> let rec sub_prod attl =
317 (*per ogni el. di attl *) [] -> ()
318 (*devo andare in ric. su tail1*) | att::tail2 -> let c1 = upd_groups c ((uri,att)::c.groups) in
319 prod c1 tail1; sub_prod tail2
324 with BooleExpTrue -> true
327 (* valuta una MathQL.val_exp e ritorna un MathQL.value *)
329 and exec_val_exp c = function
330 | MathQL.Const x -> let ol = List.sort compare x in
331 let rec edup = function
334 | s::tl -> if tl <> [] then
335 if s = (List.hd tl) then edup tl
340 | MathQL.Record (rvar, vvar) -> List.assoc vvar (List.assoc rvar c.groups)
342 | MathQL.VVar s -> List.assoc s c.vvars
343 | MathQL.RefOf sexp -> List.map (fun (s,_) -> s) (exec_set_exp c sexp)
348 (* valuta una MathQL.set_exp nel contesto vuoto e ritorna un MathQL.resource_set *)
351 exec_set_exp {svars = []; rvars = []; groups = []; vvars = []} x