6 | Success of Cic.term option * environment
10 type equality_sign = Negative | Positive;;
12 let string_of_sign = function
13 | Negative -> "Negative"
14 | Positive -> "Positive"
18 module OrderedEquality =
20 type t = Inference.equality
23 match meta_convertibility_eq eq1 eq2 with
26 let _, (ty, left, right), _, _ = eq1
27 and _, (ty', left', right'), _, _ = eq2 in
28 let weight_of t = fst (weight_of_term ~consider_metas:false t) in
29 let w1 = (weight_of ty) + (weight_of left) + (weight_of right)
30 and w2 = (weight_of ty') + (weight_of left') + (weight_of right') in
31 match Pervasives.compare w1 w2 with
32 | 0 -> Pervasives.compare eq1 eq2
36 module EqualitySet = Set.Make(OrderedEquality);;
39 let weight_age_ratio = ref 0;; (* settable by the user from the command line *)
40 let weight_age_counter = ref !weight_age_ratio;;
42 let set_selection = ref (fun set -> EqualitySet.min_elt set);;
44 let select env passive =
45 let (neg_list, neg_set), (pos_list, pos_set) = passive in
46 if !weight_age_ratio > 0 then
47 weight_age_counter := !weight_age_counter - 1;
48 match !weight_age_counter with
50 weight_age_counter := !weight_age_ratio;
51 match neg_list, pos_list with
53 (Negative, hd), ((tl, EqualitySet.remove hd neg_set), (pos, pos_set))
55 (Positive, hd), (([], neg_set), (tl, EqualitySet.remove hd pos_set))
56 | _, _ -> assert false
60 List.filter (fun e -> not (e = eq)) l
62 if EqualitySet.is_empty neg_set then
63 let current = !set_selection pos_set in
66 (remove current pos_list, EqualitySet.remove current pos_set)
68 (Positive, current), passive
70 let current = !set_selection neg_set in
72 (remove current neg_list, EqualitySet.remove current neg_set),
75 (Negative, current), passive
79 let make_passive neg pos =
80 let set_of equalities =
81 List.fold_left (fun s e -> EqualitySet.add e s) EqualitySet.empty equalities
83 (neg, set_of neg), (pos, set_of pos)
87 let add_to_passive passive (new_neg, new_pos) =
88 let (neg_list, neg_set), (pos_list, pos_set) = passive in
89 let ok set equality = not (EqualitySet.mem equality set) in
90 let neg = List.filter (ok neg_set) new_neg
91 and pos = List.filter (ok pos_set) new_pos in
92 let add set equalities =
93 List.fold_left (fun s e -> EqualitySet.add e s) set equalities
95 (neg @ neg_list, add neg_set neg), (pos_list @ pos, add pos_set pos)
99 let passive_is_empty = function
100 | ([], _), ([], _) -> true
105 (* TODO: find a better way! *)
106 let maxmeta = ref 0;;
108 let infer env sign current active =
109 let rec infer_negative current = function
111 | (Negative, _)::tl -> infer_negative current tl
112 | (Positive, equality)::tl ->
113 let res = superposition_left env current equality in
114 let neg, pos = infer_negative current tl in
117 and infer_positive current = function
119 | (Negative, equality)::tl ->
120 let res = superposition_left env equality current in
121 let neg, pos = infer_positive current tl in
123 | (Positive, equality)::tl ->
124 let maxm, res = superposition_right !maxmeta env current equality in
125 let maxm, res' = superposition_right maxm env equality current in
127 let neg, pos = infer_positive current tl in
129 (* Printf.printf "risultato di superposition_right: %s %s\n%s\n\n" *)
130 (* (string_of_equality ~env current) (string_of_equality ~env equality) *)
131 (* (String.concat "\n" (List.map (string_of_equality ~env) res)); *)
132 (* Printf.printf "risultato di superposition_right: %s %s\n%s\n\n" *)
133 (* (string_of_equality ~env equality) (string_of_equality ~env current) *)
134 (* (String.concat "\n" (List.map (string_of_equality ~env) res')); *)
136 neg, res @ res' @ pos
139 | Negative -> infer_negative current active
140 | Positive -> infer_positive current active
144 let contains_empty env (negative, positive) =
145 let metasenv, context, ugraph = env in
147 let (proof, _, _, _) =
149 (fun (proof, (ty, left, right), m, a) ->
150 fst (CicReduction.are_convertible context left right ugraph))
159 let forward_simplify env (sign, current) active =
160 (* first step, remove already present equalities *)
162 let rec aux = function
164 | (s, eq)::tl when s = sign ->
165 if meta_convertibility_eq current eq then true
174 let rec aux env (sign, current) = function
175 | [] -> Some (sign, current)
176 | (Negative, _)::tl -> aux env (sign, current) tl
177 | (Positive, equality)::tl ->
178 let newmeta, current =
179 demodulation !maxmeta env current equality in
181 if is_identity env current then
184 aux env (sign, current) tl
186 aux env (sign, current) active
190 let forward_simplify_new env (new_neg, new_pos) active =
191 let remove_identities equalities =
192 let ok eq = not (is_identity env eq) in
193 List.filter ok equalities
195 let rec simpl active target =
198 | (Negative, _)::tl -> simpl tl target
199 | (Positive, source)::tl ->
200 let newmeta, target = demodulation !maxmeta env target source in
202 if is_identity env target then target
205 let new_neg = List.map (simpl active) new_neg
206 and new_pos = List.map (simpl active) new_pos in
207 new_neg, remove_identities new_pos
211 let backward_simplify env (sign, current) active =
217 (fun (s, equality) ->
219 (* | Negative -> s, equality *)
221 let newmeta, equality =
222 demodulation !maxmeta env equality current in
228 List.filter (fun (s, eq) -> not (is_identity env eq)) active
231 List.exists (fun (s, e) -> meta_convertibility_eq eq1 e) where
234 (fun (s, eq) res -> if find eq res then res else (s, eq)::res)
239 let rec given_clause env passive active =
240 match passive_is_empty passive with
243 (* Printf.printf "before select\n"; *)
244 let (sign, current), passive = select env passive in
245 (* Printf.printf "before simplification: sign: %s\ncurrent: %s\n\n" *)
246 (* (string_of_sign sign) (string_of_equality ~env current); *)
247 match forward_simplify env (sign, current) active with
248 | None when sign = Negative ->
249 Printf.printf "OK!!! %s %s" (string_of_sign sign)
250 (string_of_equality ~env current);
252 let proof, _, _, _ = current in
253 Success (Some proof, env)
255 (* Printf.printf "avanti... %s %s" (string_of_sign sign) *)
256 (* (string_of_equality ~env current); *)
257 (* print_newline (); *)
258 given_clause env passive active
259 | Some (sign, current) ->
260 (* Printf.printf "selected: %s %s" *)
261 (* (string_of_sign sign) (string_of_equality ~env current); *)
262 (* print_newline (); *)
264 let new' = infer env sign current active in
266 let new' = forward_simplify_new env new' active in
269 backward_simplify env (sign, current) active
270 (* match new' with *)
271 (* | [], [] -> backward_simplify env (sign, current) active *)
275 print_endline "\n================================================";
277 Printf.printf "active:\n%s\n"
280 (fun (s, e) -> (string_of_sign s) ^ " " ^
281 (string_of_equality ~env e)) active)));
286 (* match new' with *)
288 (* Printf.printf "new':\n%s\n" *)
289 (* (String.concat "\n" *)
291 (* (fun e -> "Negative " ^ *)
292 (* (string_of_equality ~env e)) neg) @ *)
294 (* (fun e -> "Positive " ^ *)
295 (* (string_of_equality ~env e)) pos))); *)
296 (* print_newline (); *)
298 match contains_empty env new' with
302 | Negative -> (sign, current)::active
303 | Positive -> active @ [(sign, current)]
305 let passive = add_to_passive passive new' in
306 given_clause env passive active
312 let get_from_user () =
313 let dbd = Mysql.quick_connect
314 ~host:"localhost" ~user:"helm" ~database:"mowgli" () in
316 match read_line () with
320 let term_string = String.concat "\n" (get ()) in
321 let env, metasenv, term, ugraph =
322 List.nth (Disambiguate.Trivial.disambiguate_string dbd term_string) 0
324 term, metasenv, ugraph
329 let module C = Cic in
330 let module T = CicTypeChecker in
331 let module PET = ProofEngineTypes in
332 let module PP = CicPp in
333 let term, metasenv, ugraph = get_from_user () in
334 let proof = None, (1, [], term)::metasenv, C.Meta (1, []), term in
336 PET.apply_tactic (PrimitiveTactics.intros_tac ()) (proof, 1) in
337 let goal = List.nth goals 0 in
338 let _, metasenv, meta_proof, _ = proof in
339 let _, context, goal = CicUtil.lookup_meta goal metasenv in
340 let equalities, maxm = find_equalities context proof in
341 maxmeta := maxm; (* TODO ugly!! *)
342 let env = (metasenv, context, ugraph) in
344 let term_equality = equality_of_term meta_proof goal in
345 let meta_proof, (eq_ty, left, right), _, _ = term_equality in
347 let passive = make_passive [term_equality] equalities in
348 Printf.printf "\ncurrent goal: %s ={%s} %s\n"
349 (PP.ppterm left) (PP.ppterm eq_ty) (PP.ppterm right);
350 Printf.printf "\ncontext:\n%s\n" (PP.ppcontext context);
351 Printf.printf "\nmetasenv:\n%s\n" (print_metasenv metasenv);
352 Printf.printf "\nequalities:\n";
354 (function (_, (ty, t1, t2), _, _) ->
355 let w1 = weight_of_term t1 in
356 let w2 = weight_of_term t2 in
357 let res = nonrec_kbo t1 t2 in
358 Printf.printf "{%s}: %s<%s> %s %s<%s>\n" (PP.ppterm ty)
359 (PP.ppterm t1) (string_of_weight w1)
360 (string_of_comparison res)
361 (PP.ppterm t2) (string_of_weight w2))
363 print_endline "--------------------------------------------------";
364 let start = Sys.time () in
366 let res = given_clause env passive active in
367 let finish = Sys.time () in
370 Printf.printf "NO proof found! :-(\n\n"
371 | Success (Some proof, env) ->
372 Printf.printf "OK, found a proof!:\n%s\n%.9f\n" (PP.ppterm proof)
374 | Success (None, env) ->
375 Printf.printf "Success, but no proof?!?\n\n"
377 print_endline ("EXCEPTION: " ^ (Printexc.to_string exc));
381 let configuration_file = ref "../../gTopLevel/gTopLevel.conf.xml";;
384 let set_ratio v = weight_age_ratio := v; weight_age_counter := v
385 and set_sel () = set_selection := (fun s -> EqualitySet.max_elt s)
386 and set_conf f = configuration_file := f
389 "-r", Arg.Int set_ratio, "Weight-Age equality selection ratio";
391 "-i", Arg.Unit set_sel,
392 "Inverse selection (select heaviest equalities before)";
394 "-c", Arg.String set_conf, "Configuration file (for the db connection)";
395 ] (fun a -> ()) "Usage:"
397 Helm_registry.load_from !configuration_file;