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 *)
50 open Mathql_semantics;;
54 let prop_pool = ref None;;
68 "/" ^ (string_of_int j)
73 let see_prop_pool () =
74 let _ = print_endline "eccomi" in
76 (fun elem -> print_endline (fst elem ^ ": " ^ snd elem))
77 (match !prop_pool with Some l -> l | _ -> print_endline "ciao"; assert false)
82 let get_prop_id prop =
83 if prop="refObj" then "F"
84 else if prop="backPointer" then "B"
85 else List.assoc prop (match !prop_pool with Some l -> l | _ -> assert false)
88 (* execute_ex env q *)
89 (* [env] is the attributed uri environment in which the query [q] *)
90 (* must be evaluated *)
91 (* [q] is the query to evaluate *)
92 (* It returns a [Mathql_semantics.result] *)
93 let rec execute_ex env =
95 MQSelect (apvar, alist, abool) ->
96 select_ex env apvar (execute_ex env alist) abool
97 | MQUsedBy (alist, asvar) ->
98 use_ex (execute_ex env alist) asvar (get_prop_id "refObj") (* "F" (*"refObj"*) *)
99 | MQUse (alist, asvar) ->
100 use_ex (execute_ex env alist) asvar (get_prop_id "backPointer") (* "B" (*"backPointer"*) *)
101 | MQPattern (apreamble, apattern, afragid) ->
102 pattern_ex (apreamble, apattern, afragid)
103 | MQUnion (l1, l2) ->
104 union_ex (execute_ex env l1) (execute_ex env l2)
106 diff_ex (execute_ex env l1) (execute_ex env l2)
107 | MQSortedBy (l, o, f) ->
108 sortedby_ex (execute_ex env l) o f
109 | MQIntersect (l1, l2) ->
110 intersect_ex (execute_ex env l1) (execute_ex env l2)
111 | MQListRVar rvar -> [List.assoc rvar env]
112 | MQLetIn (lvar, l1, l2) ->
113 let t = Unix.time () in
115 (*CSC: The interesting code *)
116 let _ = letin_ex lvar (execute_ex env l1) in
118 (*CSC: end of the interesting code *)
121 print_string ("LETIN = " ^ string_of_int (List.length res) ^ ": ") ;
122 print_endline (string_of_float (Unix.time () -. t) ^ "s") ;
128 let rec build_result = function
131 {uri = s ; attributes = [] ; extra = ""} :: build_result tail
132 in build_result (List.sort compare l)
135 (* Let's initialize the execute in Select, creating a cyclical recursion *)
136 Select.execute := execute_ex;;
139 * converte il risultato interno di una query (uri + contesto)
140 * in un risultato di sole uri
143 * l: string list list;
148 * il tipo del risultato mantenuto internamente e' diverso dal tipo di risultato
149 * restituito in output poiche', mentre chi effettua le query vuole come risultato
150 * solo le eventuali uri che soddisfano le query stesse, internamente ad una uri
151 * sono associati anche i valori delle variabili che ancora non sono state valutate
152 * perche', ad esempio, si trovano in altri rami dell'albero.
155 * SELECT x IN USE PATTERN "cic:/**.con" POSITION $a WHERE $a IS MainConclusion
156 * L'albero corrispondente a questa query e':
162 * PATTERN $a $a MainConclusion
164 * Nel momento in cui si esegue il ramo USE non sono noti i vincoli sullla variabile $a
165 * percui e' necessario considerare, oltre alle uri, i valori della variabile per i quali
166 * la uri puo' far parte del risultato.
169 MQRefs (List.map (function {Mathql_semantics.uri = uri} -> uri) l)
171 let tmp = List.map (function {Mathql_semantics.uri = uri} -> uri) l in
175 (*let _ = print_endline ("DEBUG: (mqint.ml: xres_to_res)" ^ l) in*)
176 match Str.split (Str.regexp ":\|#\|/\|(\|)") l with
178 match List.rev tl with
179 n::"1"::"xpointer"::tail ->
186 | _ -> (MQBC t) :: MQBD :: par
190 [MQFC (int_of_string n)]
192 | n::m::"1"::"xpointer"::tail ->
199 | _ -> (MQBC t) :: MQBD :: par
203 [MQFC (int_of_string m); MQFC (int_of_string n)]
212 | _ -> (MQBC t) :: MQBD :: par
232 MQList qq -> xres_to_res (execute_ex [] qq)
235 let prop_pool = ref None;;
237 *****************************************************************************)
239 let init () = Dbconn.init ()
243 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#')"
250 | _ -> print_endline "no"; assert false
256 let close () = Dbconn.close ()
258 let check () = Dbconn.pgc ()
260 exception BooleExpTrue
262 (* valuta una MathQL.set_exp e ritorna un MathQL.resource_set *)
264 let rec exec_set_exp c = function
265 |MathQL.SVar svar -> List.assoc svar c.svars
266 |MathQL.RVar rvar -> [List.assoc rvar c.rvars]
267 | MathQL.Ref vexp -> List.map (fun s -> (s,[])) (exec_val_exp c vexp)
268 | MathQL.Intersect (sexp1, sexp2) -> intersect_ex (exec_set_exp c sexp1) (exec_set_exp c sexp2)
269 | MathQL.Union (sexp1, sexp2) -> union_ex (exec_set_exp c sexp1) (exec_set_exp c sexp2)
270 | MathQL.LetSVar (svar, sexp1, sexp2) -> let _ = (svar, (exec_set_exp c sexp1)):: (List.remove_assoc svar c.svars)
271 in (exec_set_exp c sexp2)
272 | MathQL.LetVVar (vvar, vexp, sexp) -> let _ = (vvar, (exec_val_exp c vexp)):: (List.remove_assoc vvar c.vvars)
273 in (exec_set_exp c sexp)
274 | MathQL.Relation (rop, path, sexp, attl) -> relation_ex rop path (exec_set_exp c sexp) attl
275 | MathQL.Select (rvar, sexp, bexp) -> let rset = (exec_set_exp c sexp) in
276 let rec select_ex rset =
279 | r::tl -> let c1 = upd_rvars c ((rvar,r)::c.rvars) in
280 if (exec_boole_exp c1 bexp) then r::(select_ex tl)
286 | MathQL.Diff (sexp1, sexp2) -> diff_ex (exec_set_exp c sexp1) (exec_set_exp c sexp2)
289 (* valuta una MathQL.boole_exp e ritorna un boole *)
291 and exec_boole_exp c = function
292 | MathQL.False -> false
293 | MathQL.True -> true
294 | MathQL.Not x -> not (exec_boole_exp c x)
295 | MathQL.And (x, y) -> (exec_boole_exp c x) && (exec_boole_exp c y)
296 | MathQL.Or (x, y) -> (exec_boole_exp c x) || (exec_boole_exp c y)
297 | MathQL.Sub (vexp1, vexp2) -> sub_ex (exec_val_exp c vexp1) (exec_val_exp c vexp2)
298 | MathQL.Meet (vexp1, vexp2) -> meet_ex (exec_val_exp c vexp1) (exec_val_exp c vexp2)
299 | MathQL.Eq (vexp1, vexp2) -> (exec_val_exp c vexp1) = (exec_val_exp c vexp2)
300 | MathQL.Ex l bexp ->
301 if l = [] then (exec_boole_exp c bexp)
303 let latt = List.map (fun uri ->
304 let (r,attl) = List.assoc uri c.rvars
305 in (uri,attl)) l (*latt = l + attributi*)
308 let rec prod c = function
309 [] -> if (exec_boole_exp c bexp) then raise BooleExpTrue
310 | (uri,attl)::tail1 -> let rec sub_prod attl =
312 (*per ogni el. di attl *) [] -> ()
313 (*devo andare in ric. su tail1*) | att::tail2 -> let c1 = upd_groups c ((uri,att)::c.groups) in
314 prod c1 tail1; sub_prod tail2
319 with BooleExpTrue -> true
322 (* valuta una MathQL.val_exp e ritorna un MathQL.value *)
324 and exec_val_exp c = function
325 | MathQL.Const x -> let
326 ol = List.sort compare x in
327 let rec edup = function
330 | s::tl -> if tl <> [] then
331 if s = (List.hd tl) then edup tl
336 | MathQL.Record (rvar, vvar) -> List.assoc vvar (List.assoc rvar c.groups)
338 | MathQL.VVar s -> List.assoc s c.vvars
339 | MathQL.RefOf sexp -> List.map (fun (s,_) -> s) (exec_set_exp c sexp)
344 (* valuta una MathQL.set_exp nel contesto vuoto e ritorna un MathQL.resource_set *)
347 exec_set_exp {svars = []; rvars = []; groups = []; vvars = []} x
353 * chiusura della connessione al database
355 let close () = Dbconn.close ();;