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>
38 (* contexts *****************************************************************)
40 type svar_context = (M.svar * M.resource_set) list
42 type avar_context = (M.avar * M.resource) list
44 type group_context = (M.avar * M.attribute_group) list
46 type context = {svars: svar_context;
48 groups: group_context (* auxiliary context *)
51 (* execute ******************************************************************)
55 if C.set h C.Warn then
57 C.log h "MQIExecute: waring: reference to undefined variables: ";
58 F.text_of_query (C.log h) "\n" q
61 let proj v = List.map fst v in
62 let rec eval_query c = function
66 try c, U.mql_subj (List.assoc p (List.assoc i c.groups))
67 with Not_found -> warn (M.Dot i p); c, []
70 let rec ex_aux h = function
72 let d = {c with groups = h} in
73 if snd (eval_query d y) = U.mql_false then () else raise Found
77 let (_, a) = List.assoc i c.avars in
78 let rec add_group = function
80 | g :: t -> ex_aux ((i, g) :: h) tail; add_group t
86 begin try ex_aux [] l; c, U.mql_false with Found -> c, U.mql_true end
89 try c, List.assoc i c.svars
90 with Not_found -> warn (M.SVar i); c, []
94 try c, [List.assoc i c.avars]
95 with Not_found -> warn (M.AVar i); c, []
97 | M.Let (Some i) x1 x2 ->
98 let d, r = eval_query c x1 in
99 let d = {d with svars = P.add_assoc (i, r) d.svars} in
101 | M.Let None x1 x2 ->
102 let d, r = eval_query c x1 in eval_query d x2
105 | M.GenFJoin -> U.mql_union
106 | M.GenFMeet -> U.mql_intersect
108 let rec for_aux (d, r) = match r with
111 let d = {d with avars = P.add_assoc (i, h) d.avars} in
112 let d, r = eval_query d x2 in
113 let d, s = for_aux (d, t) in
116 for_aux (eval_query c x1)
119 | M.GenFJoin -> U.mql_union
120 | M.GenFMeet -> U.mql_intersect
122 let rec while_aux (d, r) =
123 let d, b = eval_query d x1 in
124 if b = U.mql_false then d, r else
125 let d, s = eval_query d x2 in
128 while_aux (c, U.mql_false)
130 let f = if b then U.mql_prod else U.set_union in
131 let g a s = (fst a, f (snd a) (eval_grp c z)) :: s in
132 let _, r = eval_query c x in
133 c, List.fold_right g r []
134 | M.Property q0 q1 q2 mc ct cfl el pat y ->
135 let _, r = eval_query c y in
137 if q0 then [], (pat, q2 @ mc, r) else (q2 @ mc), (pat, [], r)
139 let eval_cons (pat, p, y) =
140 let _, r = eval_query c y in (pat, q2 @ p, r)
142 let cons_true = mct :: List.map eval_cons ct in
143 let cons_false = List.map (List.map eval_cons) cfl in
144 let eval_exp (p, po) = (q2 @ p, po) in
145 let exp = List.map eval_exp el in
146 let t = P.start_time () in
147 let r = MQIProperty.exec h q1 subj cons_true cons_false exp in
148 let s = P.stop_time t in
149 if C.set h C.Stat then
150 C.log h (Printf.sprintf "Property: %s,%i\n" s (List.length r));
153 let rec select_aux (d, r) = match r with
156 let d = {d with avars = P.add_assoc (i, h) d.avars} in
157 let d, r = eval_query d y in
158 let d, s = select_aux (d, t) in
159 if r = U.mql_false then d, s else d, (h :: s)
161 select_aux (eval_query c x)
163 let e = {L.eval = (fun x -> snd (eval_query c x)); L.conn = h} in
164 c, L.fun_eval e (F.text_out_spec (C.log h) "\n") F.text_in_spec
167 let e = {L.eval = (fun x -> snd (eval_query c x)); L.conn = h} in
168 eval_query c (L.gen_eval e p xl)
169 and eval_grp c = function
171 let attr_aux g (p, y) =
172 let _, r = eval_query c y in
173 U.mql_union g [p, proj r]
175 let attr_auxs s l = U.set_union s [List.fold_left attr_aux [] l] in
176 List.fold_left attr_auxs [] gs
178 try snd (List.assoc i c.avars)
179 with Not_found -> warn (M.AVar i); []
181 let c = {svars = []; avars = []; groups = []} in
182 let t = P.start_time () in
183 let _, r = eval_query c x in
184 let s = P.stop_time t in
185 if C.set h C.Stat then
186 C.log h (Printf.sprintf "MQIExecute: %s,%s\n" s
187 (C.string_of_flags (C.flags h)));