]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/tactics/metadataQuery.ml
implemented in place old Filter_auto filtering
[helm.git] / helm / ocaml / tactics / metadataQuery.ml
1 (* Copyright (C) 2004, 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://helm.cs.unibo.it/
24  *)
25
26 open Printf
27
28 module Constr = MetadataConstraints
29
30 let locate ~(dbh:Dbi.connection) name =
31   let query =
32     dbh#prepare (sprintf "SELECT value FROM %s WHERE source = \"%s\""
33       MetadataTypes.name_tbl name)
34   in
35   query#execute [];
36   List.map (function [`String s] -> s | _ -> assert false) (query#fetchall ())
37
38 let match_term ~(dbh:Dbi.connection) ty =
39   let constraints =
40     List.map MetadataTypes.constr_of_metadata
41       (MetadataExtractor.compute ~body:None ~ty)
42   in
43   Constr.at_least ~dbh constraints
44
45 let nonvar s =
46   let len = String.length s in
47   let suffix = String.sub s (len-4) 4 in
48   not (suffix  = ".var")
49
50 let ( ** ) x y = int_of_float ((float_of_int x) ** (float_of_int y))
51
52 let signature_of_hypothesis context =
53   List.fold_left
54     (fun set hyp ->
55       match hyp with
56       | None -> set
57       | Some (_, Cic.Decl t)
58       | Some (_, Cic.Def (t, _)) ->
59           Constr.StringSet.union set (Constr.constants_of t))
60     Constr.StringSet.empty context
61
62 let intersect l1 l2 =
63   let set1 = List.fold_right Constr.StringSet.add l1 Constr.StringSet.empty in
64   let set2 = List.fold_right Constr.StringSet.add l2 Constr.StringSet.empty in
65   Constr.StringSet.elements (Constr.StringSet.inter set1 set2)
66
67 let filter_uris_forward ~dbh (main, constants) uris =
68   let main_uris =
69     match main with
70     | None -> []
71     | Some (main, types) -> main :: types
72   in
73   let full_signature =
74     List.fold_right Constr.StringSet.add main_uris constants
75   in
76   List.filter (Constr.at_most ~dbh full_signature) uris
77
78 let filter_uris_backward ~dbh signature uris =
79   let siguris =
80     List.map snd (MetadataConstraints.sigmatch ~dbh ~where:`Statement signature)
81   in
82   intersect uris siguris
83
84 let hint ~(dbh:Dbi.connection) ?signature ((proof, goal) as status) =
85   let (_, metasenv, _, _) = proof in
86   let (_, context, ty) = CicUtil.lookup_meta goal metasenv in
87   let (uris, (main, sig_constants)) =
88     match signature with
89     | Some signature -> (Constr.sigmatch ~dbh signature, signature)
90     | None -> (Constr.cmatch' ~dbh ty, Constr.signature_of ty)
91   in
92   let uris = List.filter nonvar (List.map snd uris) in
93   let types_constants =
94     match main with
95     | None -> Constr.StringSet.empty
96     | Some (main, types) ->
97         List.fold_right Constr.StringSet.add (main :: types)
98           Constr.StringSet.empty
99   in
100   let hyp_constants =
101     Constr.StringSet.diff (signature_of_hypothesis context) types_constants
102   in
103   let other_constants = Constr.StringSet.union sig_constants hyp_constants in
104   let uris = 
105     if (List.length uris < 2 ** (Constr.StringSet.cardinal other_constants))
106     then begin
107       prerr_endline "MetadataQuery: large sig, falling back to old method";
108       filter_uris_forward ~dbh (main, other_constants) uris
109     end else
110       filter_uris_backward ~dbh (main, other_constants) uris
111   in
112   List.map
113     (fun uri ->
114       (uri,
115        ProofEngineTypes.apply_tactic
116         (PrimitiveTactics.apply_tac ~term:(CicUtil.term_of_uri uri))
117         status))
118     uris
119