]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/mathql_interpreter/mqint.ml
f0fd0a7c059172f0c99fb4004e03fe8e7a4a6a57
[helm.git] / helm / ocaml / mathql_interpreter / mqint.ml
1 (* Copyright (C) 2000, HELM Team.
2  * 
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.
6  * 
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.
11  * 
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.
16  *
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,
20  * MA  02111-1307, USA.
21  * 
22  * For details, see the HELM World-Wide-Web page,
23  * http://cs.unibo.it/helm/.
24  *)
25
26 (*
27  * implementazione del'interprete MathQL
28  *)
29
30 (*
31 (* FG: ROBA VECCHIA DA BUTTARE (tranne apertura e chiusura database *)
32
33 open MathQL;;
34 open Eval;;
35 open Utility;;
36
37 open Pattern;;*)
38 open Dbconn;;
39 open Union;;
40 open Intersect;;
41 open Meet;;
42 open Sub;;
43 open Context;;
44 open Diff;;
45 open Relation;;
46 (*open Sortedby;;
47 open Use;;
48 open Select;;
49 open Letin;;
50 open Mathql_semantics;;
51
52
53
54 let prop_pool = ref None;;
55
56 let fi_to_string fi =
57  match fi with
58     (None, _)   ->
59      ""
60  |  (Some i, y) ->
61      "#xpointer(1/"       ^
62      string_of_int i      ^
63      (
64       match y with
65          None   ->
66           ""
67       |  Some j ->
68           "/" ^ (string_of_int j)
69      )                    ^
70      ")"
71 ;;
72
73 let see_prop_pool () =
74  let _ = print_endline "eccomi" in
75  List.iter
76   (fun elem -> print_endline (fst elem ^ ": " ^ snd elem))
77   (match !prop_pool with Some l -> l | _ -> print_endline "ciao"; assert false)
78 ;;
79
80 (*
81  * inizializzazione della connessione al database
82  *)
83 let init () =
84  let _ = Dbconn.init () in
85   let c = pgc () in
86    let res = 
87     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#')"
88    in
89     prop_pool := Some
90      (
91       List.map
92        (function
93            a::b::_ -> (a, b)
94          | _       -> print_endline "no"; assert false
95        )
96        res#get_list
97      )
98 ;;
99
100 let get_prop_id prop =
101  if prop="refObj" then "F"
102  else if prop="backPointer" then "B"
103  else List.assoc prop (match !prop_pool with Some l -> l | _ -> assert false)
104 ;;
105
106 (* execute_ex env q                                                   *)
107 (*  [env] is the attributed uri environment in which the query [q]    *)
108 (*        must be evaluated                                           *)
109 (*  [q]   is the query to evaluate                                    *)
110 (*  It returns a [Mathql_semantics.result]                            *)
111 let rec execute_ex env =
112  function
113     MQSelect (apvar, alist, abool) ->
114      select_ex env apvar (execute_ex env alist) abool
115  |  MQUsedBy (alist, asvar) ->
116      use_ex (execute_ex env alist) asvar (get_prop_id "refObj")      (* "F" (*"refObj"*) *)
117  |  MQUse (alist, asvar) ->
118      use_ex (execute_ex env alist) asvar (get_prop_id "backPointer") (* "B" (*"backPointer"*) *)
119  |  MQPattern (apreamble, apattern, afragid) ->
120      pattern_ex (apreamble, apattern, afragid)
121  |  MQUnion (l1, l2) ->
122      union_ex (execute_ex env l1) (execute_ex env l2)
123  |  MQDiff (l1, l2) ->
124      diff_ex (execute_ex env l1) (execute_ex env l2)
125  |  MQSortedBy (l, o, f) ->
126      sortedby_ex (execute_ex env l) o f
127  |  MQIntersect (l1, l2) ->
128      intersect_ex (execute_ex env l1) (execute_ex env l2)
129  |  MQListRVar rvar -> [List.assoc rvar env]
130  |  MQLetIn (lvar, l1, l2) ->
131      let t = Unix.time () in
132       let res =
133        (*CSC: The interesting code *)
134        let _ = letin_ex lvar (execute_ex env l1) in
135         execute_ex env l2
136        (*CSC: end of the interesting code *)
137       in
138        letdispose ();
139        print_string ("LETIN = " ^ string_of_int (List.length res) ^ ": ") ;
140        print_endline (string_of_float (Unix.time () -. t) ^ "s") ;
141        flush stdout ;
142        res
143  |  MQListLVar lvar ->
144      letref_ex lvar
145  |  MQReference l ->
146      let rec build_result = function
147        | [] -> []
148        | s :: tail -> 
149          {uri = s ; attributes = [] ; extra = ""} :: build_result tail
150      in build_result (List.sort compare l)
151 ;;
152
153 (* Let's initialize the execute in Select, creating a cyclical recursion *)
154 Select.execute := execute_ex;;
155
156 (*
157  * converte il risultato interno di una query (uri + contesto)
158  * in un risultato di sole uri
159  *
160  * parametri:
161  * l: string list list;
162  *
163  * output: mqresult;
164  *
165  * note:
166  * il tipo del risultato mantenuto internamente e' diverso dal tipo di risultato
167  * restituito in output poiche', mentre chi effettua le query vuole come risultato
168  * solo le eventuali uri che soddisfano le query stesse, internamente ad una uri
169  * sono associati anche i valori delle variabili che ancora non sono state valutate
170  * perche', ad esempio, si trovano in altri rami dell'albero.
171  *
172  * Esempio:
173  * SELECT x IN USE PATTERN "cic:/**.con" POSITION $a WHERE $a IS MainConclusion
174  * L'albero corrispondente a questa query e':
175  *
176  *                  SELECT
177  *                /   |    \
178  *               x   USE    IS
179  *                  /   \    /\
180  *           PATTERN    $a  $a MainConclusion
181  *
182  * Nel momento in cui si esegue il ramo USE non sono noti i vincoli sullla variabile $a
183  * percui e' necessario considerare, oltre alle uri, i valori della variabile per i quali
184  * la uri puo' far parte del risultato.
185  *)
186 let xres_to_res l =
187  MQRefs (List.map (function {Mathql_semantics.uri = uri} -> uri) l)
188 (*
189  let tmp = List.map (function {Mathql_semantics.uri = uri} -> uri) l in
190   MQRefs
191    (List.map
192     (function l ->
193       (*let _ = print_endline ("DEBUG: (mqint.ml: xres_to_res)" ^ l) in*)
194       match Str.split (Str.regexp ":\|#\|/\|(\|)") l with
195          hd::""::tl -> (
196           match List.rev tl with
197              n::"1"::"xpointer"::tail    ->
198               (
199                Some hd,
200                List.fold_left
201                 (fun par t ->
202                  match par with
203                     [] -> [MQBC t] 
204                  |  _  -> (MQBC t) :: MQBD :: par
205                 )
206                 []
207                 tail, 
208                [MQFC (int_of_string n)]
209               )
210           |  n::m::"1"::"xpointer"::tail ->
211               (
212                Some hd,
213                List.fold_left
214                 (fun par t ->
215                  match par with
216                     [] -> [MQBC t] 
217                  |  _  -> (MQBC t) :: MQBD :: par
218                 )
219                 []
220                 tail,
221                [MQFC (int_of_string m); MQFC (int_of_string n)]
222               )
223           |  tail                          ->
224               (
225                Some hd,
226                List.fold_left
227                 (fun par t ->
228                  match par with
229                     [] -> [MQBC t] 
230                  |  _  -> (MQBC t) :: MQBD :: par
231                 )
232                 []
233                 tail, 
234                []
235               )
236       )  
237        | _ -> assert false
238     )
239     tmp
240    )
241 *)
242 ;;
243
244
245 (*
246  * 
247  *)
248 let execute q =
249  match q with
250     MQList qq -> xres_to_res (execute_ex [] qq)
251 ;;
252
253 (*
254  * chiusura della connessione al database
255  *)
256 let close () = Dbconn.close ();;
257
258 *****************************************************************************)
259
260 let prop_pool = ref None;;
261
262 (*
263  * inizializzazione della connessione al database
264   *)
265   
266
267 let init () =
268  let _ = Dbconn.init () in
269   let c = pgc () in
270    let res =
271     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#')"
272    in
273    prop_pool := Some
274    (
275     List.map
276     (function
277       a::b::_ -> (a, b)
278       | _       -> print_endline "no"; assert false
279     )
280      res#get_list
281    )
282                                                                           
283
284
285
286 exception BooleExpTrue
287
288 (* valuta una MathQL.set_exp e ritorna un MathQL.resource_set *)
289
290 let rec exec_set_exp c = function
291    |MathQL.SVar svar -> List.assoc svar c.svars
292    |MathQL.RVar rvar -> [List.assoc rvar c.rvars]  
293    | MathQL.Ref vexp -> List.map (fun s -> (s,[])) (exec_val_exp c vexp)
294    | MathQL.Intersect (sexp1, sexp2) -> intersect_ex (exec_set_exp c sexp1) (exec_set_exp c sexp2)    
295    | MathQL.Union (sexp1, sexp2) -> union_ex (exec_set_exp c sexp1) (exec_set_exp c sexp2)
296    | MathQL.LetSVar (svar, sexp1, sexp2) -> let _ = (svar, (exec_set_exp c sexp1)):: (List.remove_assoc svar c.svars) 
297                                         in (exec_set_exp c sexp2)
298    | MathQL.LetVVar (vvar, vexp, sexp) -> let _ = (vvar, (exec_val_exp c vexp)):: (List.remove_assoc vvar c.vvars)
299                                         in (exec_set_exp c sexp)
300    | MathQL.Relation (rop, path, sexp, attl) -> relation_ex rop path (exec_set_exp c sexp) attl
301    | MathQL.Select (rvar, sexp, bexp) -> let rset = (exec_set_exp c sexp) in
302                                           let rec select_ex rset =
303                                             match rset with 
304                                                       [] -> []
305                                             | r::tl -> let c1 = upd_rvars c ((rvar,r)::c.rvars) in                      
306                                                if (exec_boole_exp c1 bexp) then r::(select_ex tl)
307                                                else select_ex tl
308                                           in select_ex rset
309                                                        
310                                                                                    
311    
312    | MathQL.Diff (sexp1, sexp2) -> diff_ex (exec_set_exp c sexp1) (exec_set_exp c sexp2)
313    | _ -> assert false
314    
315 (* valuta una MathQL.boole_exp e ritorna un boole *)
316
317 and exec_boole_exp c = function
318    | MathQL.False      -> false
319    | MathQL.True       -> true
320    | MathQL.Not x      -> not (exec_boole_exp c x)
321    | MathQL.And (x, y) -> (exec_boole_exp c x) && (exec_boole_exp c y)
322    | MathQL.Or (x, y)  -> (exec_boole_exp c x) || (exec_boole_exp c y)
323    | MathQL.Sub (vexp1, vexp2) -> sub_ex (exec_val_exp c vexp1) (exec_val_exp c vexp2)
324    | MathQL.Meet (vexp1, vexp2) -> meet_ex (exec_val_exp c vexp1) (exec_val_exp c vexp2)
325    | MathQL.Eq (vexp1, vexp2) -> (exec_val_exp c vexp1) = (exec_val_exp c vexp2)
326    | MathQL.Ex l bexp -> 
327         if l = [] then (exec_boole_exp c bexp)
328         else
329           let latt = List.map (fun uri -> 
330                                        let (r,attl) = List.assoc uri c.rvars 
331                                        in (uri,attl)) l (*latt = l + attributi*)
332           in
333            try
334              let rec prod c = function
335                 [] -> if (exec_boole_exp c bexp) then raise BooleExpTrue 
336               | (uri,attl)::tail1 -> let rec sub_prod attl =
337                                       match attl with
338 (*per ogni el. di attl  *)              [] -> () 
339 (*devo andare in ric. su tail1*)      | att::tail2 -> let c1 = upd_groups c ((uri,att)::c.groups) in             
340                                                        prod c1 tail1; sub_prod tail2 
341                                      in       
342                                       sub_prod attl 
343              in
344               prod c latt; false
345            with BooleExpTrue -> true  
346    | _ -> assert false    
347
348 (* valuta una MathQL.val_exp e ritorna un MathQL.value *)
349
350 and exec_val_exp c = function
351    | MathQL.Const x -> let ol = List.sort compare x in 
352                         let rec edup = function
353                         
354                            [] -> [] 
355                          | s::tl -> if tl <> [] then  
356                                                  if s = (List.hd tl) then edup tl
357                                                  else s::(edup tl)
358                                     else s::[]
359                         in
360                          edup ol
361    | MathQL.Record (rvar, vvar) -> List.assoc vvar (List.assoc rvar c.groups) 
362                                   
363    | MathQL.VVar s -> List.assoc s c.vvars                                
364    | MathQL.RefOf sexp -> List.map (fun (s,_) -> s) (exec_set_exp c sexp)
365    
366    | _ -> assert false
367
368
369 (* valuta una MathQL.set_exp nel contesto vuoto e ritorna un MathQL.resource_set *)
370
371 and execute x =
372    exec_set_exp {svars = []; rvars = []; groups = []; vvars = []} x 
373
374
375
376
377 (*
378  * chiusura della connessione al database
379   *)
380   let close () = Dbconn.close ();;
381