]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/mathql_interpreter/mqint.ml
After Union and Relation
[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 open Dbconn;;
37 open Pattern;;*)
38 open Union;;
39 open Intersect;;
40 open Meet;;
41 open Sub;;
42 open Context;;
43 open Diff;;
44 open Relation;;
45 (*open Sortedby;;
46 open Use;;
47 open Select;;
48 open Letin;;
49 open Mathql_semantics;;
50
51
52
53 let prop_pool = ref None;;
54
55 let fi_to_string fi =
56  match fi with
57     (None, _)   ->
58      ""
59  |  (Some i, y) ->
60      "#xpointer(1/"       ^
61      string_of_int i      ^
62      (
63       match y with
64          None   ->
65           ""
66       |  Some j ->
67           "/" ^ (string_of_int j)
68      )                    ^
69      ")"
70 ;;
71
72 let see_prop_pool () =
73  let _ = print_endline "eccomi" in
74  List.iter
75   (fun elem -> print_endline (fst elem ^ ": " ^ snd elem))
76   (match !prop_pool with Some l -> l | _ -> print_endline "ciao"; assert false)
77 ;;
78
79 (*
80  * inizializzazione della connessione al database
81  *)
82 let init () =
83  let _ = Dbconn.init () in
84   let c = pgc () in
85    let res = 
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#')"
87    in
88     prop_pool := Some
89      (
90       List.map
91        (function
92            a::b::_ -> (a, b)
93          | _       -> print_endline "no"; assert false
94        )
95        res#get_list
96      )
97 ;;
98
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)
103 ;;
104
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 =
111  function
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)
122  |  MQDiff (l1, 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
131       let res =
132        (*CSC: The interesting code *)
133        let _ = letin_ex lvar (execute_ex env l1) in
134         execute_ex env l2
135        (*CSC: end of the interesting code *)
136       in
137        letdispose ();
138        print_string ("LETIN = " ^ string_of_int (List.length res) ^ ": ") ;
139        print_endline (string_of_float (Unix.time () -. t) ^ "s") ;
140        flush stdout ;
141        res
142  |  MQListLVar lvar ->
143      letref_ex lvar
144  |  MQReference l ->
145      let rec build_result = function
146        | [] -> []
147        | s :: tail -> 
148          {uri = s ; attributes = [] ; extra = ""} :: build_result tail
149      in build_result (List.sort compare l)
150 ;;
151
152 (* Let's initialize the execute in Select, creating a cyclical recursion *)
153 Select.execute := execute_ex;;
154
155 (*
156  * converte il risultato interno di una query (uri + contesto)
157  * in un risultato di sole uri
158  *
159  * parametri:
160  * l: string list list;
161  *
162  * output: mqresult;
163  *
164  * note:
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.
170  *
171  * Esempio:
172  * SELECT x IN USE PATTERN "cic:/**.con" POSITION $a WHERE $a IS MainConclusion
173  * L'albero corrispondente a questa query e':
174  *
175  *                  SELECT
176  *                /   |    \
177  *               x   USE    IS
178  *                  /   \    /\
179  *           PATTERN    $a  $a MainConclusion
180  *
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.
184  *)
185 let xres_to_res l =
186  MQRefs (List.map (function {Mathql_semantics.uri = uri} -> uri) l)
187 (*
188  let tmp = List.map (function {Mathql_semantics.uri = uri} -> uri) l in
189   MQRefs
190    (List.map
191     (function l ->
192       (*let _ = print_endline ("DEBUG: (mqint.ml: xres_to_res)" ^ l) in*)
193       match Str.split (Str.regexp ":\|#\|/\|(\|)") l with
194          hd::""::tl -> (
195           match List.rev tl with
196              n::"1"::"xpointer"::tail    ->
197               (
198                Some hd,
199                List.fold_left
200                 (fun par t ->
201                  match par with
202                     [] -> [MQBC t] 
203                  |  _  -> (MQBC t) :: MQBD :: par
204                 )
205                 []
206                 tail, 
207                [MQFC (int_of_string n)]
208               )
209           |  n::m::"1"::"xpointer"::tail ->
210               (
211                Some hd,
212                List.fold_left
213                 (fun par t ->
214                  match par with
215                     [] -> [MQBC t] 
216                  |  _  -> (MQBC t) :: MQBD :: par
217                 )
218                 []
219                 tail,
220                [MQFC (int_of_string m); MQFC (int_of_string n)]
221               )
222           |  tail                          ->
223               (
224                Some hd,
225                List.fold_left
226                 (fun par t ->
227                  match par with
228                     [] -> [MQBC t] 
229                  |  _  -> (MQBC t) :: MQBD :: par
230                 )
231                 []
232                 tail, 
233                []
234               )
235       )  
236        | _ -> assert false
237     )
238     tmp
239    )
240 *)
241 ;;
242
243
244 (*
245  * 
246  *)
247 let execute q =
248  match q with
249     MQList qq -> xres_to_res (execute_ex [] qq)
250 ;;
251
252 (*
253  * chiusura della connessione al database
254  *)
255 let close () = Dbconn.close ();;
256
257 *****************************************************************************)
258
259 let init () = () (* FG: implementare l'apertura del database *)
260
261 let close () = () (* FG: implementare la chiusura del database *)
262
263
264
265 exception BooleExpTrue
266
267 (* valuta una MathQL.set_exp e ritorna un MathQL.resource_set *)
268
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 =
282                                             match rset with 
283                                                       [] -> []
284                                             | r::tl -> upd_rvars c ((rvar,r)::c.rvars);                     
285                                                if (exec_boole_exp c bexp) then r::(select_ex tl)
286                                                else select_ex tl
287                                           in select_ex rset
288                                                        
289                                                                                    
290    
291    | MathQL.Diff (sexp1, sexp2) -> diff_ex (exec_set_exp c sexp1) (exec_set_exp c sexp2)
292    | _ -> assert false
293    
294 (* valuta una MathQL.boole_exp e ritorna un boole *)
295
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)
307         else
308           let latt = List.map (fun uri -> 
309                                        let (r,attl) = List.assoc uri c.rvars 
310                                        in (uri,attl)) l (*latt = l + attributi*)
311           in
312            try
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 =
316                                       match attl with
317 (*per ogni el. di attl  *)              [] -> () 
318 (*devo andare in ric. su tail1*)      | att::tail2 -> upd_groups c ((uri,att)::c.groups);             
319                                                        prod c tail1; sub_prod tail2 
320                                      in       
321                                       sub_prod attl 
322              in
323               prod c latt; false
324            with BooleExpTrue -> true  
325    | _ -> assert false    
326
327 (* valuta una MathQL.val_exp e ritorna un MathQL.value *)
328
329 and exec_val_exp c = function
330    | MathQL.Const x -> List.sort compare x
331    | MathQL.Record (rvar, vvar) -> List.assoc vvar (List.assoc rvar c.groups) 
332                                   
333    | MathQL.VVar s -> List.assoc s c.vvars                                
334    | MathQL.RefOf sexp -> List.map (fun (s,_) -> s) (exec_set_exp c sexp)
335    
336    | _ -> assert false
337
338
339 (* valuta una MathQL.set_exp nel contesto vuoto e ritorna un MathQL.resource_set *)
340
341 and execute x =
342    exec_set_exp {svars = []; rvars = []; groups = []; vvars = []} x 
343