]> matita.cs.unibo.it Git - helm.git/blob - helm/gTopLevel/mQueryGenerator.ml
Initial revision
[helm.git] / helm / gTopLevel / mQueryGenerator.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 (*                                                                            *)
28 (*                               PROJECT HELM                                 *)
29 (*                                                                            *)
30 (*                     Ferruccio Guidi <fguidi@cs.unibo.it>                   *)
31 (*                                 30/04/2002                                 *)
32 (*                                                                            *)
33 (*                                                                            *)
34 (******************************************************************************)
35
36 (* level managing functions *************************************************)
37
38 type levels_spec = (string * bool * int) list
39
40 let levels_of_term metasenv context term =
41    let module TC = CicTypeChecker in
42    let module Red = CicReduction in
43    let module Util = MQueryUtil in
44    let degree t =
45       let rec degree_aux = function
46          | Cic.Sort _         -> 1 
47          | Cic.Cast (u, _)    -> degree_aux u
48          | Cic.Prod (_, _, t) -> degree_aux t
49          | _                  -> 2
50       in 
51       let u = TC.type_of_aux' metasenv context t in
52       degree_aux (Red.whd context u)
53    in
54    let entry_eq (s1, b1, v1) (s2, b2, v2) =
55       s1 = s2 && b1 = b2 
56    in
57    let rec entry_in e = function
58       | []           -> [e]
59       | head :: tail -> 
60          head :: if entry_eq head e then tail else entry_in e tail
61    in
62    let inspect_uri main l uri tc v term =
63       let d = degree term in 
64       entry_in (Util.string_of_uriref (uri, tc), main, 2 * v + d - 1) l 
65    in
66    let rec inspect_term main l v term = match term with
67       | Cic.Rel _                        -> l 
68       | Cic.Meta (_, _)                  -> l
69       | Cic.Sort _                       -> l 
70       | Cic.Implicit                     -> l 
71       | Cic.Var u                        -> inspect_uri main l u [] v term
72       | Cic.Const (u, _)                 -> inspect_uri main l u [] v term
73       | Cic.MutInd (u, _, t)             -> inspect_uri main l u [t] v term
74       | Cic.MutConstruct (u, _, t, c)    -> inspect_uri main l u [t; c] v term
75       | Cic.Cast (uu, _)                 -> 
76          inspect_term main l v uu
77       | Cic.Prod (_, uu, tt)             ->
78          let luu = inspect_term false l (v + 1) uu in
79          inspect_term main luu (v + 1) tt         
80       | Cic.Lambda (_, uu, tt)           ->
81          let luu = inspect_term false l (v + 1) uu in
82          inspect_term false luu (v + 1) tt 
83       | Cic.LetIn (_, uu, tt)            ->
84          let luu = inspect_term false l (v + 1) uu in
85          inspect_term false luu (v + 1) tt
86       | Cic.Appl m                       -> inspect_list main l true v m 
87       | Cic.MutCase (u, _, t, tt, uu, m) -> 
88          let lu = inspect_uri main l u [t] (v + 1) term in
89          let ltt = inspect_term false lu (v + 1) tt in
90          let luu = inspect_term false ltt (v + 1) uu in
91          inspect_list main luu false (v + 1) m
92       | Cic.Fix (_, m)                   -> inspect_ind l (v + 1) m 
93       | Cic.CoFix (_, m)                 -> inspect_coind l (v + 1) m 
94    and inspect_list main l head v = function
95       | []      -> l
96       | tt :: m -> 
97          let ltt = inspect_term main l (if head then v else v + 1) tt in
98          inspect_list false ltt false v m
99    and inspect_ind l v = function
100       | []                  -> l
101       | (_, _, tt, uu) :: m ->  
102          let ltt = inspect_term false l v tt in
103          let luu = inspect_term false ltt v uu in
104          inspect_ind luu v m
105    and inspect_coind l v = function
106       | []               -> l
107       | (_, tt, uu) :: m ->
108          let ltt = inspect_term false l v tt in
109          let luu = inspect_term false ltt v uu in
110          inspect_coind luu v m
111    in
112    let rec inspect_backbone = function
113       | Cic.Cast (uu, _)      -> inspect_backbone uu
114       | Cic.Prod (_, _, tt)   -> inspect_backbone tt                
115       | Cic.LetIn (_, uu, tt) -> inspect_backbone tt
116       | t                     -> inspect_term true [] 0 t
117    in 
118    inspect_backbone term  
119
120 let string_of_levels l sep =
121    let entry_out (s, b, v) =
122       let pos = if b then " HEAD: " else " TAIL: " in
123       string_of_int v ^ pos ^ s ^ sep 
124    in
125    let rec levels_out = function
126       | []           -> ""
127       | head :: tail -> entry_out head ^ levels_out tail
128    in
129    levels_out l
130
131 (* Query issuing functions **************************************************)
132
133 exception Discard  
134
135 let nl = " <p>\n"
136
137 let query_num = ref 1
138
139 let log_file = ref ""
140
141 let confirm_query = ref (fun _ -> true)
142
143 let info = ref []
144
145 let set_log_file f = 
146    log_file := f
147
148 let set_confirm_query f =
149    confirm_query := f
150
151 let get_query_info () = ! info
152
153 let execute_query query =
154    let module Util = MQueryUtil in
155    let mode = [Open_wronly; Open_append; Open_creat; Open_text] in
156    let perm = 64 * 6 + 8 * 6 + 4 in
157    let time () =
158       let lt = Unix.localtime (Unix.time ()) in
159       "NEW LOG: " ^
160       string_of_int (lt.Unix.tm_mon + 1) ^ "-" ^
161       string_of_int (lt.Unix.tm_mday + 1) ^ "-" ^
162       string_of_int (lt.Unix.tm_year + 1900) ^ " " ^
163       string_of_int (lt.Unix.tm_hour) ^ ":" ^
164       string_of_int (lt.Unix.tm_min) ^ ":" ^
165       string_of_int (lt.Unix.tm_sec) 
166    in
167    let log q r = 
168       let och = open_out_gen mode perm ! log_file in
169       if ! query_num = 1 then output_string och (time () ^ nl);
170       let str = "Query: " ^ string_of_int ! query_num ^ nl ^ Util.text_of_query q ^ nl ^ 
171                 "Result:" ^ nl ^ Util.text_of_result r nl in
172       output_string och str; 
173       flush och 
174    in
175    let execute q =
176       let r = Mqint.execute q in    
177       if ! log_file <> "" then log q r; 
178       info := string_of_int ! query_num :: ! info;
179       incr query_num;
180       r
181    in 
182    if ! confirm_query query then execute query else raise Discard
183                           
184 (* Query building functions  ************************************************)   
185
186 let locate s =
187    let module M = MathQL in
188    let q = M.Ref (M.Attribute true M.RefineExact ("objectName", []) (M.Const [s])) in
189    execute_query q
190
191 let backward e c t level =
192    let module M = MathQL in
193    let v_pos = M.Const ["MainConclusion"; "InConclusion"] in
194    let q_where = M.Sub (M.RefOf (
195       M.Select ("uri", 
196                 M.Relation (false, M.RefineExact, ("refObj", []), M.RVar "uri0", ["pos"]),
197                 M.Ex ["uri"] (M.Meet (M.VVar "positions", M.Record ("uri", ("pos", [])))) 
198                )),      M.VVar "universe"
199                        )
200    in
201    let uri_of_entry (r, b, v) = r in
202    let rec restrict level = function
203       | []                -> []
204       | (u, b, v) :: tail ->
205          if v <= level then (u, b, v) :: restrict level tail
206          else restrict level tail
207    in
208    let build_select (r, b, v) =
209       let pos = if b then "MainConclusion" else "InConclusion" in
210       M.Select ("uri", 
211                 M.Relation (false, M.RefineExact, ("backPointer", []), M.Ref (M.Const [r]), ["pos"]),
212                 M.Ex ["uri"] (M.Sub (M.Const [pos], M.Record ("uri", ("pos", []))))
213                )
214    in 
215    let rec build_intersect = function
216       | []       -> M.Pattern (M.Const [".*"])
217       | [hd]     -> build_select hd
218       | hd :: tl -> M.Intersect (build_select hd, build_intersect tl)
219    in
220    let levels = levels_of_term e c t in
221    let rest = restrict level levels in
222    info := [string_of_int (List.length rest)];
223    let q_in = build_intersect rest in
224    let q_select = M.Select ("uri0", q_in, q_where) in
225    let universe = M.Const (List.map uri_of_entry levels) in
226    let q_let_u = M.LetVVar ("universe", universe, q_select) in
227    let q_let_p = M.LetVVar ("positions", v_pos, q_let_u) in
228    execute_query q_let_p