1 (* Copyright (C) 2000-2002, 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 (*********************************************************************)
30 (* Andrea Asperti, Matteo Selmi *)
34 (*********************************************************************)
38 - functions executing must, just and only constraints on the mysql
40 - the general function cmatch for retrieving all statements matching
44 type count_condition =
45 NIL | EQ of int | GT of int
49 "'http://www.cs.unibo.it/helm/schemas/schema-helm#MainConclusion'"
53 "'http://www.cs.unibo.it/helm/schemas/schema-helm#InConclusion'"
56 let escape = Str.global_replace (Str.regexp_string "\'") "\\'";;
59 let get_inconcl (conn:Mysql.dbd) uri =
60 let uri = escape uri in
62 "select h_occurrence from refObj where source='"^uri^
63 "' and (h_position="^main_conclusion^" or h_position="^in_conclusion^")" in
65 let result = Mysql.exec conn query in
66 (* now we transform the result in a set *)
68 match (Array.to_list a) with
70 | _ -> assert false in
71 let result = Mysql.map ~f:f result in
74 NewConstraints.StringSet.add uri set)
75 NewConstraints.StringSet.empty result
78 let test_only (conn:Mysql.dbd) only u =
79 let inconcl = get_inconcl conn u in
80 NewConstraints.StringSet.subset inconcl only
83 let rec exec_must (conn:Mysql.dbd) (l:MQGTypes.r_obj list) (cc:count_condition) =
84 let add_must (n,from,where) (pos,uri) =
86 `MainHypothesis _ -> assert false
87 | `MainConclusion None ->
88 let refObjn = "refObj" ^ (string_of_int n) in
90 [ refObjn^".h_occurrence = '" ^ uri ^ "'";
91 refObjn^".h_position = " ^ main_conclusion] in
93 if n = 0 then new_must@where
95 (refObjn^".source = refObj" ^ (string_of_int (n-1))
96 ^ ".source")::new_must@where in
97 (n+1,("refObj as "^refObjn)::from,where')
98 | `MainConclusion(Some(d)) ->
99 let refObjn = "refObj" ^ (string_of_int n) in
101 [ refObjn^".h_occurrence = '" ^ uri ^ "'";
102 refObjn^".h_position = " ^ main_conclusion;
103 refObjn^".h_depth = " ^ (string_of_int d)] in
105 if n = 0 then new_must@where
107 (refObjn^".source = refObj" ^ (string_of_int (n-1))
108 ^ ".source")::new_must@where in
109 (n+1,("refObj as "^refObjn)::from,where')
110 | `InHypothesis -> assert false
112 let refObjn = "refObj" ^ (string_of_int n) in
114 [ refObjn^".h_occurrence = '" ^ uri ^ "'";
115 refObjn^".h_position = " ^ in_conclusion] in
117 if n = 0 then new_must@where
119 (refObjn^".source = refObj" ^ (string_of_int (n-1))
120 ^ ".source")::new_must@where in
121 (n+1,("refObj as "^refObjn)::from,where')
122 | `InBody -> assert false
125 List.fold_left add_must (0,[],[]) l in
130 "no_inconcl_aux"::from,
131 ("no=" ^ (string_of_int n))::
132 ("no_inconcl_aux.source = refObj0.source")::where
134 "no_inconcl_aux"::from,
135 ("no>" ^ (string_of_int n))::
136 ("no_inconcl_aux.source = refObj0.source")::where) in
137 let from = String.concat "," from in
138 let where = String.concat " and " where in
140 "select refObj0.source from " ^ from ^ " where " ^ where in
141 (* prerr_endline query;*)
142 Mysql.exec conn query
146 let (must_of_prefix m s):MQGTypes.r_obj list =
147 let s' = List.map (fun u -> (`InConclusion, u)) s in
148 (`MainConclusion None,m)::s'
151 (* takes a list of lists and returns the list of all elements
152 without repetitions *)
154 let rec drop_repetitions = function
157 | u1::u2::l when u1 = u2 -> drop_repetitions (u2::l)
158 | u::l -> u::(drop_repetitions l) in
159 drop_repetitions (List.sort Pervasives.compare (List.concat l))
162 let critical_value = 6;;
163 let just_factor = 3;;
165 let cmatch (conn:Mysql.dbd) t =
166 let eq,constants = NewConstraints.constants_of t in
167 (* the type of eq is not counted in constants_no *)
169 if eq then (NewConstraints.StringSet.cardinal constants)
170 else (NewConstraints.StringSet.cardinal constants) in
171 if (constants_no > critical_value) then
172 let prefixes = NewConstraints.prefixes just_factor t in
174 Some main, all_concl ->
176 NewConstraints.pp_prefixes all_concl;
178 (* in some cases, max_prefix_length could be less than n *)
179 let max_prefix_length =
182 | (max,_)::_ -> max in
183 let maximal_prefixes =
184 let rec filter res = function
186 | (n,s)::l when n = max_prefix_length -> filter ((n,s)::res) l
188 filter [] all_concl in
189 let greater_than :(int*string) list=
195 exec_must conn (must_of_prefix main s) (GT (m+1)) in
197 match (Array.to_list a) with
198 (* we tag the uri with m+1, for sorting purposes *)
199 [Some uri] -> (m+1,uri)
200 | _ -> assert false in
204 (function (_,uri) -> test_only conn constants uri) all in
210 exec_must conn (must_of_prefix main s) (EQ (m+1)) in
212 match (Array.to_list a) with
213 (* we tag the uri with m, for sorting purposes *)
214 [Some uri] -> (m,uri)
215 | _ -> assert false in
218 greater_than @ equal_to
220 else if constants_no = 0 then []
222 (* in this case we compute all prefixes, and we do not need
223 to apply the only constraints *)
224 let prefixes = NewConstraints.prefixes constants_no t in
226 Some main, all_concl ->
231 exec_must conn (must_of_prefix main s) (EQ (m+1)) in
233 match (Array.to_list a) with
234 (* we tag the uri with m, for sorting purposes *)
235 [Some uri] -> (m,uri)
236 | _ -> assert false in