5 (* set to false to disable paramodulation inside auto_tac *)
6 let connect_to_auto = true;;
10 let debug_print = if debug then prerr_endline else ignore;;
13 (* profiling statistics... *)
14 let infer_time = ref 0.;;
15 let forward_simpl_time = ref 0.;;
16 let forward_simpl_new_time = ref 0.;;
17 let backward_simpl_time = ref 0.;;
18 let passive_maintainance_time = ref 0.;;
20 (* limited-resource-strategy related globals *)
21 let processed_clauses = ref 0;; (* number of equalities selected so far... *)
22 let time_limit = ref 0.;; (* in seconds, settable by the user... *)
23 let start_time = ref 0.;; (* time at which the execution started *)
24 let elapsed_time = ref 0.;;
25 (* let maximal_weight = ref None;; *)
26 let maximal_retained_equality = ref None;;
28 (* equality-selection related globals *)
29 let use_fullred = ref true;;
30 let weight_age_ratio = ref 3;; (* settable by the user from the command line *)
31 let weight_age_counter = ref !weight_age_ratio;;
32 let symbols_ratio = ref 2;;
33 let symbols_counter = ref 0;;
36 let derived_clauses = ref 0;;
37 let kept_clauses = ref 0;;
39 (* index of the greatest Cic.Meta created - TODO: find a better way! *)
45 | Success of Inference.equality option * environment
50 let symbols_of_equality (_, (_, left, right), _, _) =
51 TermSet.union (symbols_of_term left) (symbols_of_term right)
55 let symbols_of_equality ((_, _, (_, left, right, _), _, _) as equality) =
56 let m1 = symbols_of_term left in
61 let c = TermMap.find k res in
62 TermMap.add k (c+v) res
65 (symbols_of_term right) m1
67 (* Printf.printf "symbols_of_equality %s:\n" *)
68 (* (string_of_equality equality); *)
69 (* TermMap.iter (fun k v -> Printf.printf "%s: %d\n" (CicPp.ppterm k) v) m; *)
70 (* print_newline (); *)
75 module OrderedEquality = struct
76 type t = Inference.equality
79 match meta_convertibility_eq eq1 eq2 with
82 let w1, _, (ty, left, right, _), _, a = eq1
83 and w2, _, (ty', left', right', _), _, a' = eq2 in
84 (* let weight_of t = fst (weight_of_term ~consider_metas:false t) in *)
85 (* let w1 = (weight_of ty) + (weight_of left) + (weight_of right) *)
86 (* and w2 = (weight_of ty') + (weight_of left') + (weight_of right') in *)
87 match Pervasives.compare w1 w2 with
89 let res = (List.length a) - (List.length a') in
90 if res <> 0 then res else (
92 let res = Pervasives.compare (List.hd a) (List.hd a') in
93 if res <> 0 then res else Pervasives.compare eq1 eq2
94 with _ -> Pervasives.compare eq1 eq2
95 (* match a, a' with *)
96 (* | (Cic.Meta (i, _)::_), (Cic.Meta (j, _)::_) -> *)
97 (* let res = Pervasives.compare i j in *)
98 (* if res <> 0 then res else Pervasives.compare eq1 eq2 *)
99 (* | _, _ -> Pervasives.compare eq1 eq2 *)
104 module EqualitySet = Set.Make(OrderedEquality);;
107 let select env passive (active, _) =
108 processed_clauses := !processed_clauses + 1;
110 let (neg_list, neg_set), (pos_list, pos_set), passive_table = passive in
112 List.filter (fun e -> e <> eq) l
114 if !weight_age_ratio > 0 then
115 weight_age_counter := !weight_age_counter - 1;
116 match !weight_age_counter with
118 weight_age_counter := !weight_age_ratio;
119 match neg_list, pos_list with
121 (* Negatives aren't indexed, no need to remove them... *)
123 ((tl, EqualitySet.remove hd neg_set), (pos, pos_set), passive_table)
126 Indexing.remove_index passive_table hd
127 (* if !use_fullred then Indexing.remove_index passive_table hd *)
128 (* else passive_table *)
131 (([], neg_set), (tl, EqualitySet.remove hd pos_set), passive_table)
132 | _, _ -> assert false
134 | _ when (!symbols_counter > 0) && (EqualitySet.is_empty neg_set) -> (
135 symbols_counter := !symbols_counter - 1;
136 let cardinality map =
137 TermMap.fold (fun k v res -> res + v) map 0
140 | (Negative, e)::_ ->
141 let symbols = symbols_of_equality e in
142 let card = cardinality symbols in
143 let foldfun k v (r1, r2) =
144 if TermMap.mem k symbols then
145 let c = TermMap.find k symbols in
146 let c1 = abs (c - v) in
152 let f equality (i, e) =
154 TermMap.fold foldfun (symbols_of_equality equality) (0, 0)
156 let c = others + (abs (common - card)) in
157 if c < i then (c, equality)
158 (* else if c = i then *)
159 (* match OrderedEquality.compare equality e with *)
160 (* | -1 -> (c, equality) *)
161 (* | res -> (i, e) *)
164 let e1 = EqualitySet.min_elt pos_set in
167 TermMap.fold foldfun (symbols_of_equality e1) (0, 0)
169 (others + (abs (common - card))), e1
171 let _, current = EqualitySet.fold f pos_set initial in
172 (* Printf.printf "\nsymbols-based selection: %s\n\n" *)
173 (* (string_of_equality ~env current); *)
175 Indexing.remove_index passive_table current
176 (* if !use_fullred then Indexing.remove_index passive_table current *)
177 (* else passive_table *)
181 (remove current pos_list, EqualitySet.remove current pos_set),
184 let current = EqualitySet.min_elt pos_set in
186 Indexing.remove_index passive_table current
187 (* if !use_fullred then Indexing.remove_index passive_table current *)
188 (* else passive_table *)
192 (remove current pos_list, EqualitySet.remove current pos_set),
195 (Positive, current), passive
198 symbols_counter := !symbols_ratio;
199 let set_selection set = EqualitySet.min_elt set in
200 if EqualitySet.is_empty neg_set then
201 let current = set_selection pos_set in
204 (remove current pos_list, EqualitySet.remove current pos_set),
205 Indexing.remove_index passive_table current
206 (* if !use_fullred then Indexing.remove_index passive_table current *)
207 (* else passive_table *)
209 (Positive, current), passive
211 let current = set_selection neg_set in
213 (remove current neg_list, EqualitySet.remove current neg_set),
217 (Negative, current), passive
221 let make_passive neg pos =
222 let set_of equalities =
223 List.fold_left (fun s e -> EqualitySet.add e s) EqualitySet.empty equalities
226 List.fold_left (fun tbl e -> Indexing.index tbl e)
227 (Indexing.empty_table ()) pos
228 (* if !use_fullred then *)
229 (* List.fold_left (fun tbl e -> Indexing.index tbl e) *)
230 (* (Indexing.empty_table ()) pos *)
232 (* Indexing.empty_table () *)
241 [], Indexing.empty_table ()
245 let add_to_passive passive (new_neg, new_pos) =
246 let (neg_list, neg_set), (pos_list, pos_set), table = passive in
247 let ok set equality = not (EqualitySet.mem equality set) in
248 let neg = List.filter (ok neg_set) new_neg
249 and pos = List.filter (ok pos_set) new_pos in
251 List.fold_left (fun tbl e -> Indexing.index tbl e) table pos
252 (* if !use_fullred then *)
253 (* List.fold_left (fun tbl e -> Indexing.index tbl e) table pos *)
257 let add set equalities =
258 List.fold_left (fun s e -> EqualitySet.add e s) set equalities
260 (neg @ neg_list, add neg_set neg),
261 (pos_list @ pos, add pos_set pos),
266 let passive_is_empty = function
267 | ([], _), ([], _), _ -> true
272 let size_of_passive ((_, ns), (_, ps), _) =
273 (EqualitySet.cardinal ns) + (EqualitySet.cardinal ps)
277 let size_of_active (active_list, _) =
278 List.length active_list
282 let prune_passive howmany (active, _) passive =
283 let (nl, ns), (pl, ps), tbl = passive in
284 let howmany = float_of_int howmany
285 and ratio = float_of_int !weight_age_ratio in
286 let in_weight = int_of_float (howmany *. ratio /. (ratio +. 1.))
287 and in_age = int_of_float (howmany /. (ratio +. 1.)) in
288 debug_print (Printf.sprintf "in_weight: %d, in_age: %d\n" in_weight in_age);
291 | (Negative, e)::_ ->
292 let symbols = symbols_of_equality e in
293 let card = TermMap.fold (fun k v res -> res + v) symbols 0 in
297 let counter = ref !symbols_ratio in
298 let rec pickw w ns ps =
300 if not (EqualitySet.is_empty ns) then
301 let e = EqualitySet.min_elt ns in
302 let ns', ps = pickw (w-1) (EqualitySet.remove e ns) ps in
303 EqualitySet.add e ns', ps
304 else if !counter > 0 then
306 counter := !counter - 1;
307 if !counter = 0 then counter := !symbols_ratio
311 let e = EqualitySet.min_elt ps in
312 let ns, ps' = pickw (w-1) ns (EqualitySet.remove e ps) in
313 ns, EqualitySet.add e ps'
315 let foldfun k v (r1, r2) =
316 if TermMap.mem k symbols then
317 let c = TermMap.find k symbols in
318 let c1 = abs (c - v) in
324 let f equality (i, e) =
326 TermMap.fold foldfun (symbols_of_equality equality) (0, 0)
328 let c = others + (abs (common - card)) in
329 if c < i then (c, equality)
332 let e1 = EqualitySet.min_elt ps in
335 TermMap.fold foldfun (symbols_of_equality e1) (0, 0)
337 (others + (abs (common - card))), e1
339 let _, e = EqualitySet.fold f ps initial in
340 let ns, ps' = pickw (w-1) ns (EqualitySet.remove e ps) in
341 ns, EqualitySet.add e ps'
343 let e = EqualitySet.min_elt ps in
344 let ns, ps' = pickw (w-1) ns (EqualitySet.remove e ps) in
345 ns, EqualitySet.add e ps'
347 EqualitySet.empty, EqualitySet.empty
349 (* let in_weight, ns = pickw in_weight ns in *)
350 (* let _, ps = pickw in_weight ps in *)
351 let ns, ps = pickw in_weight ns ps in
352 let rec picka w s l =
356 | hd::tl when not (EqualitySet.mem hd s) ->
357 let w, s, l = picka (w-1) s tl in
358 w, EqualitySet.add hd s, hd::l
360 let w, s, l = picka w s tl in
365 let in_age, ns, nl = picka in_age ns nl in
366 let _, ps, pl = picka in_age ps pl in
367 if not (EqualitySet.is_empty ps) then
368 (* maximal_weight := Some (weight_of_equality (EqualitySet.max_elt ps)); *)
369 maximal_retained_equality := Some (EqualitySet.max_elt ps);
372 (fun e tbl -> Indexing.index tbl e) ps (Indexing.empty_table ())
373 (* if !use_fullred then *)
374 (* EqualitySet.fold *)
375 (* (fun e tbl -> Indexing.index tbl e) ps (Indexing.empty_table ()) *)
379 (nl, ns), (pl, ps), tbl
383 let infer env sign current (active_list, active_table) =
384 let new_neg, new_pos =
388 Indexing.superposition_left !maxmeta env active_table current in
393 Indexing.superposition_right !maxmeta env active_table current in
395 let rec infer_positive table = function
397 | (Negative, equality)::tl ->
399 Indexing.superposition_left !maxmeta env table equality in
401 let neg, pos = infer_positive table tl in
403 | (Positive, equality)::tl ->
405 Indexing.superposition_right !maxmeta env table equality in
407 let neg, pos = infer_positive table tl in
410 let curr_table = Indexing.index (Indexing.empty_table ()) current in
411 let neg, pos = infer_positive curr_table active_list in
414 derived_clauses := !derived_clauses + (List.length new_neg) +
415 (List.length new_pos);
416 match (* !maximal_weight *)!maximal_retained_equality with
417 | None -> new_neg, new_pos
420 List.filter (fun e -> (* (weight_of_equality e) <= w *) OrderedEquality.compare e eq <= 0) new_pos in
425 let contains_empty env (negative, positive) =
426 let metasenv, context, ugraph = env in
430 (fun (w, proof, (ty, left, right, ordering), m, a) ->
431 fst (CicReduction.are_convertible context left right ugraph))
440 let forward_simplify env (sign, current) ?passive (active_list, active_table) =
441 let pl, passive_table =
444 | Some ((pn, _), (pp, _), pt) ->
445 let pn = List.map (fun e -> (Negative, e)) pn
446 and pp = List.map (fun e -> (Positive, e)) pp in
449 let all = if pl = [] then active_list else active_list @ pl in
451 (* let rec find_duplicate sign current = function *)
453 (* | (s, eq)::tl when s = sign -> *)
454 (* if meta_convertibility_eq current eq then true *)
455 (* else find_duplicate sign current tl *)
456 (* | _::tl -> find_duplicate sign current tl *)
460 (* if sign = Positive then *)
461 (* Indexing.subsumption env active_table current *)
469 let demodulate table current =
470 let newmeta, newcurrent =
471 Indexing.demodulation !maxmeta env table sign current in
473 if is_identity env newcurrent then
474 if sign = Negative then Some (sign, newcurrent)
477 Some (sign, newcurrent)
480 let res = demodulate active_table current in
483 | Some (sign, newcurrent) ->
484 match passive_table with
486 | Some passive_table -> demodulate passive_table newcurrent
490 | Some (Negative, c) ->
493 (fun (s, eq) -> s = Negative && meta_convertibility_eq eq c)
496 if ok then res else None
497 | Some (Positive, c) ->
498 if Indexing.in_index active_table c then
501 match passive_table with
503 | Some passive_table ->
504 if Indexing.in_index passive_table c then None
507 (* | Some (s, c) -> if find_duplicate s c all then None else res *)
509 (* if s = Utils.Negative then *)
512 (* if Indexing.subsumption env active_table c then *)
515 (* match passive_table with *)
517 (* | Some passive_table -> *)
518 (* if Indexing.subsumption env passive_table c then *)
524 (* let pred (sign, eq) = *)
525 (* if sign <> s then false *)
526 (* else subsumption env c eq *)
528 (* if List.exists pred all then None *)
532 type fs_time_info_t = {
533 mutable build_all: float;
534 mutable demodulate: float;
535 mutable subsumption: float;
538 let fs_time_info = { build_all = 0.; demodulate = 0.; subsumption = 0. };;
541 let forward_simplify_new env (new_neg, new_pos) ?passive active =
542 let t1 = Unix.gettimeofday () in
544 let active_list, active_table = active in
545 let pl, passive_table =
548 | Some ((pn, _), (pp, _), pt) ->
549 let pn = List.map (fun e -> (Negative, e)) pn
550 and pp = List.map (fun e -> (Positive, e)) pp in
553 let all = active_list @ pl in
555 let t2 = Unix.gettimeofday () in
556 fs_time_info.build_all <- fs_time_info.build_all +. (t2 -. t1);
558 let demodulate sign table target =
559 let newmeta, newtarget =
560 Indexing.demodulation !maxmeta env table sign target in
564 (* let f sign' target (sign, eq) = *)
565 (* if sign <> sign' then false *)
566 (* else subsumption env target eq *)
569 let t1 = Unix.gettimeofday () in
571 let new_neg, new_pos =
572 let new_neg = List.map (demodulate Negative active_table) new_neg
573 and new_pos = List.map (demodulate Positive active_table) new_pos in
574 match passive_table with
575 | None -> new_neg, new_pos
576 | Some passive_table ->
577 List.map (demodulate Negative passive_table) new_neg,
578 List.map (demodulate Positive passive_table) new_pos
581 let t2 = Unix.gettimeofday () in
582 fs_time_info.demodulate <- fs_time_info.demodulate +. (t2 -. t1);
587 if not (Inference.is_identity env e) then
588 if EqualitySet.mem e s then s
589 else EqualitySet.add e s
591 EqualitySet.empty new_pos
593 let new_pos = EqualitySet.elements new_pos_set in
596 match passive_table with
598 (fun e -> not (Indexing.subsumption env active_table e))
599 | Some passive_table ->
600 (fun e -> not ((Indexing.subsumption env active_table e) ||
601 (Indexing.subsumption env passive_table e)))
604 let t1 = Unix.gettimeofday () in
606 (* let new_neg, new_pos = *)
607 (* List.filter subs new_neg, *)
608 (* List.filter subs new_pos *)
611 (* let new_neg, new_pos = *)
612 (* (List.filter (fun e -> not (List.exists (f Negative e) all)) new_neg, *)
613 (* List.filter (fun e -> not (List.exists (f Positive e) all)) new_pos) *)
616 let t2 = Unix.gettimeofday () in
617 fs_time_info.subsumption <- fs_time_info.subsumption +. (t2 -. t1);
620 match passive_table with
622 (fun e -> not (Indexing.in_index active_table e))
623 | Some passive_table ->
625 not ((Indexing.in_index active_table e) ||
626 (Indexing.in_index passive_table e)))
628 new_neg, List.filter is_duplicate new_pos
630 (* new_neg, new_pos *)
633 (* (List.filter (fun e -> not (List.exists (f Negative e) all)) new_neg, *)
634 (* List.filter (fun e -> not (List.exists (f Positive e) all)) new_pos) *)
640 let backward_simplify_active env new_pos new_table active =
641 let active_list, active_table = active in
642 let active_list, newa =
644 (fun (s, equality) (res, newn) ->
645 match forward_simplify env (s, equality) (new_pos, new_table) with
655 List.exists (fun (s, e) -> meta_convertibility_eq eq1 e) where
659 (fun (s, eq) (res, tbl) ->
660 if List.mem (s, eq) res then
662 else if (is_identity env eq) || (find eq res) then (
664 ) (* else if (find eq res) then *)
667 (s, eq)::res, if s = Negative then tbl else Indexing.index tbl eq)
668 active_list ([], Indexing.empty_table ()),
670 (fun (s, eq) (n, p) ->
671 if (s <> Negative) && (is_identity env eq) then (
674 if s = Negative then eq::n, p
679 | [], [] -> active, None
680 | _ -> active, Some newa
684 let backward_simplify_passive env new_pos new_table passive =
685 let (nl, ns), (pl, ps), passive_table = passive in
686 let f sign equality (resl, ress, newn) =
687 match forward_simplify env (sign, equality) (new_pos, new_table) with
688 | None -> resl, EqualitySet.remove equality ress, newn
691 equality::resl, ress, newn
693 let ress = EqualitySet.remove equality ress in
696 let nl, ns, newn = List.fold_right (f Negative) nl ([], ns, [])
697 and pl, ps, newp = List.fold_right (f Positive) pl ([], ps, []) in
700 (fun tbl e -> Indexing.index tbl e) (Indexing.empty_table ()) pl
702 match newn, newp with
703 | [], [] -> ((nl, ns), (pl, ps), passive_table), None
704 | _, _ -> ((nl, ns), (pl, ps), passive_table), Some (newn, newp)
708 let backward_simplify env new' ?passive active =
709 let new_pos, new_table =
711 (fun (l, t) e -> (Positive, e)::l, Indexing.index t e)
712 ([], Indexing.empty_table ()) (snd new')
714 let active, newa = backward_simplify_active env new_pos new_table active in
717 active, (make_passive [] []), newa, None
720 backward_simplify_passive env new_pos new_table passive in
721 active, passive, newa, newp
725 let get_selection_estimate () =
726 elapsed_time := (Unix.gettimeofday ()) -. !start_time;
727 (* !processed_clauses * (int_of_float (!time_limit /. !elapsed_time)) *)
729 ceil ((float_of_int !processed_clauses) *.
730 ((!time_limit (* *. 2. *)) /. !elapsed_time -. 1.)))
734 let rec given_clause env passive active =
735 let time1 = Unix.gettimeofday () in
737 let selection_estimate = get_selection_estimate () in
738 let kept = size_of_passive passive in
740 if !time_limit = 0. || !processed_clauses = 0 then
742 else if !elapsed_time > !time_limit then (
743 debug_print (Printf.sprintf "Time limit (%.2f) reached: %.2f\n"
744 !time_limit !elapsed_time);
746 ) else if kept > selection_estimate then (
747 debug_print (Printf.sprintf ("Too many passive equalities: pruning..." ^^
748 "(kept: %d, selection_estimate: %d)\n")
749 kept selection_estimate);
750 prune_passive selection_estimate active passive
755 let time2 = Unix.gettimeofday () in
756 passive_maintainance_time := !passive_maintainance_time +. (time2 -. time1);
758 kept_clauses := (size_of_passive passive) + (size_of_active active);
760 match passive_is_empty passive with
763 let (sign, current), passive = select env passive active in
764 let time1 = Unix.gettimeofday () in
765 let res = forward_simplify env (sign, current) ~passive active in
766 let time2 = Unix.gettimeofday () in
767 forward_simpl_time := !forward_simpl_time +. (time2 -. time1);
770 given_clause env passive active
771 | Some (sign, current) ->
772 if (sign = Negative) && (is_identity env current) then (
773 debug_print (Printf.sprintf "OK!!! %s %s" (string_of_sign sign)
774 (string_of_equality ~env current));
775 Success (Some current, env)
777 debug_print "\n================================================";
778 debug_print (Printf.sprintf "selected: %s %s"
779 (string_of_sign sign)
780 (string_of_equality ~env current));
782 let t1 = Unix.gettimeofday () in
783 let new' = infer env sign current active in
784 let t2 = Unix.gettimeofday () in
785 infer_time := !infer_time +. (t2 -. t1);
787 let res, goal = contains_empty env new' in
791 let t1 = Unix.gettimeofday () in
792 let new' = forward_simplify_new env new' (* ~passive *) active in
793 let t2 = Unix.gettimeofday () in
795 forward_simpl_new_time := !forward_simpl_new_time +. (t2 -. t1)
801 let t1 = Unix.gettimeofday () in
802 let active, _, newa, _ =
803 backward_simplify env ([], [current]) active
805 let t2 = Unix.gettimeofday () in
806 backward_simpl_time := !backward_simpl_time +. (t2 -. t1);
810 let al, tbl = active in
811 let nn = List.map (fun e -> Negative, e) n in
816 Indexing.index tbl e)
822 (* Printf.printf "active:\n%s\n" *)
823 (* (String.concat "\n" *)
825 (* (fun (s, e) -> (string_of_sign s) ^ " " ^ *)
826 (* (string_of_equality ~env e)) (fst active)))); *)
827 (* print_newline (); *)
830 (* match new' with *)
832 (* Printf.printf "new':\n%s\n" *)
833 (* (String.concat "\n" *)
835 (* (fun e -> "Negative " ^ *)
836 (* (string_of_equality ~env e)) neg) @ *)
838 (* (fun e -> "Positive " ^ *)
839 (* (string_of_equality ~env e)) pos))); *)
840 (* print_newline (); *)
842 match contains_empty env new' with
845 let al, tbl = active in
847 | Negative -> (sign, current)::al, tbl
849 al @ [(sign, current)], Indexing.index tbl current
851 let passive = add_to_passive passive new' in
852 let (_, ns), (_, ps), _ = passive in
853 (* Printf.printf "passive:\n%s\n" *)
854 (* (String.concat "\n" *)
855 (* ((List.map (fun e -> "Negative " ^ *)
856 (* (string_of_equality ~env e)) *)
857 (* (EqualitySet.elements ns)) @ *)
858 (* (List.map (fun e -> "Positive " ^ *)
859 (* (string_of_equality ~env e)) *)
860 (* (EqualitySet.elements ps)))); *)
861 (* print_newline (); *)
862 given_clause env passive active
869 let rec given_clause_fullred env passive active =
870 let time1 = Unix.gettimeofday () in
872 let selection_estimate = get_selection_estimate () in
873 let kept = size_of_passive passive in
875 if !time_limit = 0. || !processed_clauses = 0 then
877 else if !elapsed_time > !time_limit then (
878 debug_print (Printf.sprintf "Time limit (%.2f) reached: %.2f\n"
879 !time_limit !elapsed_time);
881 ) else if kept > selection_estimate then (
882 debug_print (Printf.sprintf ("Too many passive equalities: pruning..." ^^
883 "(kept: %d, selection_estimate: %d)\n")
884 kept selection_estimate);
885 prune_passive selection_estimate active passive
890 let time2 = Unix.gettimeofday () in
891 passive_maintainance_time := !passive_maintainance_time +. (time2 -. time1);
893 kept_clauses := (size_of_passive passive) + (size_of_active active);
895 match passive_is_empty passive with
898 let (sign, current), passive = select env passive active in
899 let time1 = Unix.gettimeofday () in
900 let res = forward_simplify env (sign, current) ~passive active in
901 let time2 = Unix.gettimeofday () in
902 forward_simpl_time := !forward_simpl_time +. (time2 -. time1);
905 given_clause_fullred env passive active
906 | Some (sign, current) ->
907 if (sign = Negative) && (is_identity env current) then (
908 debug_print (Printf.sprintf "OK!!! %s %s" (string_of_sign sign)
909 (string_of_equality ~env current));
910 Success (Some current, env)
912 debug_print "\n================================================";
913 debug_print (Printf.sprintf "selected: %s %s"
914 (string_of_sign sign)
915 (string_of_equality ~env current));
917 let t1 = Unix.gettimeofday () in
918 let new' = infer env sign current active in
919 let t2 = Unix.gettimeofday () in
920 infer_time := !infer_time +. (t2 -. t1);
923 if is_identity env current then active
925 let al, tbl = active in
927 | Negative -> (sign, current)::al, tbl
928 | Positive -> al @ [(sign, current)], Indexing.index tbl current
930 let rec simplify new' active passive =
931 let t1 = Unix.gettimeofday () in
932 let new' = forward_simplify_new env new' ~passive active in
933 let t2 = Unix.gettimeofday () in
934 forward_simpl_new_time := !forward_simpl_new_time +. (t2 -. t1);
935 let t1 = Unix.gettimeofday () in
936 let active, passive, newa, retained =
937 backward_simplify env new' ~passive active in
938 let t2 = Unix.gettimeofday () in
939 backward_simpl_time := !backward_simpl_time +. (t2 -. t1);
940 match newa, retained with
941 | None, None -> active, passive, new'
943 | None, Some (n, p) ->
945 simplify (nn @ n, np @ p) active passive
946 | Some (n, p), Some (rn, rp) ->
948 simplify (nn @ n @ rn, np @ p @ rp) active passive
950 let active, passive, new' = simplify new' active passive in
952 let k = size_of_passive passive in
953 if k < (kept - 1) then
954 processed_clauses := !processed_clauses + (kept - 1 - k);
958 Printf.sprintf "active:\n%s\n"
961 (fun (s, e) -> (string_of_sign s) ^ " " ^
962 (string_of_equality ~env e)) (fst active)))))
968 Printf.sprintf "new':\n%s\n"
971 (fun e -> "Negative " ^
972 (string_of_equality ~env e)) neg) @
974 (fun e -> "Positive " ^
975 (string_of_equality ~env e)) pos))))
977 match contains_empty env new' with
979 let passive = add_to_passive passive new' in
980 (* let (_, ns), (_, ps), _ = passive in *)
981 (* Printf.printf "passive:\n%s\n" *)
982 (* (String.concat "\n" *)
983 (* ((List.map (fun e -> "Negative " ^ *)
984 (* (string_of_equality ~env e)) *)
985 (* (EqualitySet.elements ns)) @ *)
986 (* (List.map (fun e -> "Positive " ^ *)
987 (* (string_of_equality ~env e)) *)
988 (* (EqualitySet.elements ps)))); *)
989 (* print_newline (); *)
990 given_clause_fullred env passive active
997 let given_clause_ref = ref given_clause;;
1000 let main dbd term metasenv ugraph =
1001 let module C = Cic in
1002 let module T = CicTypeChecker in
1003 let module PET = ProofEngineTypes in
1004 let module PP = CicPp in
1005 let proof = None, (1, [], term)::metasenv, C.Meta (1, []), term in
1006 let status = PET.apply_tactic (PrimitiveTactics.intros_tac ()) (proof, 1) in
1007 let proof, goals = status in
1008 let goal' = List.nth goals 0 in
1009 let _, metasenv, meta_proof, _ = proof in
1010 let _, context, goal = CicUtil.lookup_meta goal' metasenv in
1011 let equalities, maxm = find_equalities context proof in
1012 let library_equalities, maxm =
1013 find_library_equalities ~dbd context (proof, goal') (maxm+1)
1015 maxmeta := maxm+2; (* TODO ugly!! *)
1016 let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
1017 let new_meta_goal, metasenv, type_of_goal =
1018 let _, context, ty = CicUtil.lookup_meta goal' metasenv in
1019 Printf.printf "\n\nTIPO DEL GOAL: %s\n" (CicPp.ppterm ty);
1021 Cic.Meta (maxm+1, irl),
1022 (maxm+1, context, ty)::metasenv,
1025 (* let new_meta_goal = Cic.Meta (goal', irl) in *)
1026 let env = (metasenv, context, ugraph) in
1028 let term_equality = equality_of_term new_meta_goal goal in
1029 let _, meta_proof, (eq_ty, left, right, ordering), _, _ = term_equality in
1030 let active = make_active () in
1032 make_passive [term_equality] (equalities @ library_equalities)
1034 Printf.printf "\ncurrent goal: %s\n"
1035 (string_of_equality ~env term_equality);
1036 Printf.printf "\ncontext:\n%s\n" (PP.ppcontext context);
1037 Printf.printf "\nmetasenv:\n%s\n" (print_metasenv metasenv);
1038 Printf.printf "\nequalities:\n%s\n"
1041 (string_of_equality ~env)
1043 print_endline "--------------------------------------------------";
1044 let start = Unix.gettimeofday () in
1045 print_endline "GO!";
1046 start_time := Unix.gettimeofday ();
1048 (if !use_fullred then given_clause_fullred else given_clause)
1051 let finish = Unix.gettimeofday () in
1055 Printf.printf "NO proof found! :-(\n\n"
1056 | Success (Some goal, env) ->
1057 let proof = Inference.build_proof_term goal in
1060 (fun m (_, _, _, menv, _) -> m @ menv) metasenv equalities
1065 CicTypeChecker.type_of_aux' newmetasenv context proof ugraph
1067 Printf.printf "OK, found a proof!\n";
1068 (* REMEMBER: we have to instantiate meta_proof, we should use
1069 apply the "apply" tactic to proof and status
1071 let names = names_of_context context in
1072 print_endline (PP.pp proof names);
1073 (* print_endline (PP.ppterm proof); *)
1075 print_endline (string_of_float (finish -. start));
1077 "\nGOAL was: %s\nPROOF has type: %s\nconvertible?: %s\n\n"
1078 (CicPp.pp type_of_goal names) (CicPp.pp ty names)
1080 (fst (CicReduction.are_convertible
1081 context type_of_goal ty ug)));
1083 Printf.printf "\nEXCEPTION!!! %s\n" (Printexc.to_string e);
1084 Printf.printf "MAXMETA USED: %d\n" !maxmeta;
1088 | Success (None, env) ->
1089 Printf.printf "Success, but no proof?!?\n\n"
1091 Printf.printf ("infer_time: %.9f\nforward_simpl_time: %.9f\n" ^^
1092 "forward_simpl_new_time: %.9f\n" ^^
1093 "backward_simpl_time: %.9f\n")
1094 !infer_time !forward_simpl_time !forward_simpl_new_time
1095 !backward_simpl_time;
1096 Printf.printf "passive_maintainance_time: %.9f\n"
1097 !passive_maintainance_time;
1098 Printf.printf " successful unification/matching time: %.9f\n"
1099 !Indexing.match_unif_time_ok;
1100 Printf.printf " failed unification/matching time: %.9f\n"
1101 !Indexing.match_unif_time_no;
1102 Printf.printf " indexing retrieval time: %.9f\n"
1103 !Indexing.indexing_retrieval_time;
1104 Printf.printf " demodulate_term.build_newtarget_time: %.9f\n"
1105 !Indexing.build_newtarget_time;
1106 Printf.printf "derived %d clauses, kept %d clauses.\n"
1107 !derived_clauses !kept_clauses;
1109 print_endline ("EXCEPTION: " ^ (Printexc.to_string exc));
1114 exception Failure of string
1116 let saturate dbd (proof, goal) =
1117 let module C = Cic in
1120 let uri, metasenv, meta_proof, term_to_prove = proof in
1121 let _, context, goal = CicUtil.lookup_meta goal' metasenv in
1122 let equalities, maxm = find_equalities context proof in
1123 let library_equalities, maxm =
1124 find_library_equalities ~dbd context (proof, goal') (maxm+2)
1127 let new_meta_goal, metasenv, type_of_goal =
1129 CicMkImplicit.identity_relocation_list_for_metavariable context in
1130 let _, context, ty = CicUtil.lookup_meta goal' metasenv in
1131 debug_print (Printf.sprintf "\n\nTIPO DEL GOAL: %s\n" (CicPp.ppterm ty));
1132 Cic.Meta (maxm+1, irl),
1133 (maxm+1, context, ty)::metasenv,
1136 let ugraph = CicUniv.empty_ugraph in
1137 let env = (metasenv, context, ugraph) in
1139 let term_equality = equality_of_term new_meta_goal goal in
1140 let active = make_active () in
1142 make_passive [term_equality] (equalities @ library_equalities)
1144 let res = given_clause_fullred env passive active in
1146 | Success (Some goal, env) ->
1147 debug_print "OK, found a proof!";
1148 let proof = Inference.build_proof_term goal in
1149 let names = names_of_context context in
1152 match new_meta_goal with
1153 | C.Meta (i, _) -> i | _ -> assert false
1156 (* match meta_proof with *)
1157 (* | C.Meta (i, _) -> i *)
1159 (* Printf.printf "\nHMMM!!! meta_proof: %s\ngoal': %s" *)
1160 (* (CicPp.pp meta_proof names) (string_of_int goal'); *)
1161 (* print_newline (); *)
1164 List.filter (fun (i, _, _) -> i <> i1 && i <> goal') metasenv
1169 CicTypeChecker.type_of_aux' newmetasenv context proof ugraph
1171 debug_print (CicPp.pp proof [](* names *));
1174 "\nGOAL was: %s\nPROOF has type: %s\nconvertible?: %s\n"
1175 (CicPp.pp type_of_goal names) (CicPp.pp ty names)
1177 (fst (CicReduction.are_convertible
1178 context type_of_goal ty ug))));
1179 let equality_for_replace t1 i =
1181 | C.Meta (n, _) -> n = i
1185 ProofEngineReduction.replace
1186 ~equality:equality_for_replace
1187 ~what:[goal'] ~with_what:[proof]
1191 Printf.sprintf "status:\n%s\n%s\n%s\n%s\n"
1192 (match uri with Some uri -> UriManager.string_of_uri uri
1194 (print_metasenv newmetasenv)
1195 (CicPp.pp real_proof [](* names *))
1196 (CicPp.pp term_to_prove names));
1197 ((uri, newmetasenv, real_proof, term_to_prove), [])
1199 debug_print "THE PROOF DOESN'T TYPECHECK!!!";
1200 debug_print (CicPp.pp proof names);
1201 raise (Failure "Found a proof, but it doesn't typecheck")
1205 raise (Failure "NO proof found")
1207 (* raise (Failure "saturation failed") *)
1211 (* dummy function called within matita to trigger linkage *)
1215 (* UGLY SIDE EFFECT... *)
1216 if connect_to_auto then (
1217 AutoTactic.paramodulation_tactic := saturate;
1218 AutoTactic.term_is_equality := Inference.term_is_equality;