2 type retrieval_mode = Matching | Unification;;
5 let print_candidates mode term res =
9 Printf.printf "| candidates Matching %s\n" (CicPp.ppterm term)
11 Printf.printf "| candidates Unification %s\n" (CicPp.ppterm term)
17 Printf.sprintf "| (%s, %s)" (Utils.string_of_pos p)
18 (Inference.string_of_equality e))
24 let indexing_retrieval_time = ref 0.;;
27 (* let my_apply_subst subst term = *)
28 (* let module C = Cic in *)
29 (* let lookup lift_amount meta = *)
31 (* | C.Meta (i, _) -> ( *)
33 (* let _, (_, t, _) = List.find (fun (m, _) -> m = i) subst in *)
34 (* (\* CicSubstitution.lift lift_amount *\)t *)
35 (* with Not_found -> meta *)
37 (* | _ -> assert false *)
39 (* let rec apply_aux lift_amount = function *)
40 (* | C.Meta (i, l) as t -> lookup lift_amount t *)
41 (* | C.Appl l -> C.Appl (List.map (apply_aux lift_amount) l) *)
42 (* | C.Prod (nn, s, t) -> *)
43 (* C.Prod (nn, apply_aux lift_amount s, apply_aux (lift_amount+1) t) *)
44 (* | C.Lambda (nn, s, t) -> *)
45 (* C.Lambda (nn, apply_aux lift_amount s, apply_aux (lift_amount+1) t) *)
48 (* apply_aux 0 term *)
52 (* let apply_subst subst term = *)
53 (* Printf.printf "| apply_subst:\n| subst: %s\n| term: %s\n" *)
54 (* (Utils.print_subst ~prefix:" ; " subst) (CicPp.ppterm term); *)
55 (* let res = my_apply_subst subst term in *)
56 (* (\* let res = CicMetaSubst.apply_subst subst term in *\) *)
57 (* Printf.printf "| res: %s\n" (CicPp.ppterm res); *)
58 (* print_endline "|"; *)
62 (* let apply_subst = my_apply_subst *)
63 let apply_subst = CicMetaSubst.apply_subst
67 let profile = CicUtil.profile "apply_subst" in
68 (fun s a -> profile (apply_subst s) a)
74 Path_indexing.PSTrie.empty
77 let index = Path_indexing.index
78 and remove_index = Path_indexing.remove_index
79 and in_index = Path_indexing.in_index;;
81 let get_candidates mode trie term =
82 let t1 = Unix.gettimeofday () in
86 | Matching -> Path_indexing.retrieve_generalizations trie term
87 | Unification -> Path_indexing.retrieve_unifiables trie term
88 (* Path_indexing.retrieve_all trie term *)
90 Path_indexing.PosEqSet.elements s
92 (* print_candidates mode term res; *)
93 let t2 = Unix.gettimeofday () in
94 indexing_retrieval_time := !indexing_retrieval_time +. (t2 -. t1);
101 Discrimination_tree.DiscriminationTree.empty
104 let index = Discrimination_tree.index
105 and remove_index = Discrimination_tree.remove_index
106 and in_index = Discrimination_tree.in_index;;
108 let get_candidates mode tree term =
109 let t1 = Unix.gettimeofday () in
113 | Matching -> Discrimination_tree.retrieve_generalizations tree term
114 | Unification -> Discrimination_tree.retrieve_unifiables tree term
116 Discrimination_tree.PosEqSet.elements s
118 (* print_candidates mode term res; *)
119 (* print_endline (Discrimination_tree.string_of_discrimination_tree tree); *)
120 (* print_newline (); *)
121 let t2 = Unix.gettimeofday () in
122 indexing_retrieval_time := !indexing_retrieval_time +. (t2 -. t1);
127 (* let get_candidates = *)
128 (* let profile = CicUtil.profile "Indexing.get_candidates" in *)
129 (* (fun mode tree term -> profile (get_candidates mode tree) term) *)
133 let match_unif_time_ok = ref 0.;;
134 let match_unif_time_no = ref 0.;;
137 let rec find_matches metasenv context ugraph lift_amount term =
138 let module C = Cic in
139 let module U = Utils in
140 let module S = CicSubstitution in
141 let module M = CicMetaSubst in
142 let module HL = HelmLibraryObjects in
143 let cmp = !Utils.compare_terms in
144 let names = Utils.names_of_context context in
148 let pos, (_, proof, (ty, left, right, o), metas, args) = candidate in
149 let do_match c other eq_URI =
150 let subst', metasenv', ugraph' =
151 let t1 = Unix.gettimeofday () in
154 Inference.matching (metasenv @ metas) context
155 term (S.lift lift_amount c) ugraph in
156 let t2 = Unix.gettimeofday () in
157 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
160 let t2 = Unix.gettimeofday () in
161 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
164 Some (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
167 let c, other, eq_URI =
168 if pos = Utils.Left then left, right, HL.Logic.eq_ind_URI
169 else right, left, HL.Logic.eq_ind_r_URI
171 if o <> U.Incomparable then
173 do_match c other eq_URI
175 find_matches metasenv context ugraph lift_amount term tl
177 let res = try do_match c other eq_URI with e -> None in
179 | Some (_, s, _, _, _) ->
180 let c' = (* M. *)apply_subst s c
181 and other' = (* M. *)apply_subst s other in
182 let order = cmp c' other' in
183 let names = U.names_of_context context in
187 find_matches metasenv context ugraph lift_amount term tl
189 find_matches metasenv context ugraph lift_amount term tl
193 let rec find_all_matches ?(unif_fun=Inference.unification)
194 metasenv context ugraph lift_amount term =
195 let module C = Cic in
196 let module U = Utils in
197 let module S = CicSubstitution in
198 let module M = CicMetaSubst in
199 let module HL = HelmLibraryObjects in
200 let cmp = !Utils.compare_terms in
201 let names = Utils.names_of_context context in
205 let pos, (_, _, (ty, left, right, o), metas, args) = candidate in
206 let do_match c other eq_URI =
207 let subst', metasenv', ugraph' =
208 let t1 = Unix.gettimeofday () in
211 unif_fun (metasenv @ metas) context
212 term (S.lift lift_amount c) ugraph in
213 let t2 = Unix.gettimeofday () in
214 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
217 let t2 = Unix.gettimeofday () in
218 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
221 (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
224 let c, other, eq_URI =
225 if pos = Utils.Left then left, right, HL.Logic.eq_ind_URI
226 else right, left, HL.Logic.eq_ind_r_URI
228 if o <> U.Incomparable then
230 let res = do_match c other eq_URI in
231 res::(find_all_matches ~unif_fun metasenv context ugraph
234 find_all_matches ~unif_fun metasenv context ugraph
238 let res = do_match c other eq_URI in
241 let c' = (* M. *)apply_subst s c
242 and other' = (* M. *)apply_subst s other in
243 let order = cmp c' other' in
244 let names = U.names_of_context context in
245 if order <> U.Lt && order <> U.Le then
246 res::(find_all_matches ~unif_fun metasenv context ugraph
249 find_all_matches ~unif_fun metasenv context ugraph
252 find_all_matches ~unif_fun metasenv context ugraph
257 let subsumption env table target =
258 let _, (ty, left, right, _), tmetas, _ = target in
259 let metasenv, context, ugraph = env in
260 let metasenv = metasenv @ tmetas in
261 let samesubst subst subst' =
262 let tbl = Hashtbl.create (List.length subst) in
263 List.iter (fun (m, (c, t1, t2)) -> Hashtbl.add tbl m (c, t1, t2)) subst;
265 (fun (m, (c, t1, t2)) ->
267 let c', t1', t2' = Hashtbl.find tbl m in
268 if (c = c') && (t1 = t1') && (t2 = t2') then true
278 let leftc = get_candidates Matching table left in
279 find_all_matches ~unif_fun:Inference.matching
280 metasenv context ugraph 0 left leftc
282 let ok what (_, subst, menv, ug, ((pos, (_, _, (_, l, r, o), _, _)), _)) =
284 let other = if pos = Utils.Left then r else l in
285 let subst', menv', ug' =
286 let t1 = Unix.gettimeofday () in
289 Inference.matching metasenv context what other ugraph in
290 let t2 = Unix.gettimeofday () in
291 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
294 let t2 = Unix.gettimeofday () in
295 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
298 samesubst subst subst'
302 let r = List.exists (ok right) leftr in
310 let rightc = get_candidates Matching table right in
311 find_all_matches ~unif_fun:Inference.matching
312 metasenv context ugraph 0 right rightc
314 List.exists (ok left) rightr
318 let rec demodulate_term metasenv context ugraph table lift_amount term =
319 let module C = Cic in
320 let module S = CicSubstitution in
321 let module M = CicMetaSubst in
322 let module HL = HelmLibraryObjects in
323 let candidates = get_candidates Matching table term in
328 find_matches metasenv context ugraph lift_amount term candidates
339 (res, tl @ [S.lift 1 t])
342 demodulate_term metasenv context ugraph table
346 | None -> (None, tl @ [S.lift 1 t])
347 | Some (rel, _, _, _, _) -> (r, tl @ [rel]))
352 | Some (_, subst, menv, ug, eq_found) ->
353 Some (C.Appl ll, subst, menv, ug, eq_found)
355 | C.Prod (nn, s, t) ->
357 demodulate_term metasenv context ugraph table lift_amount s in (
361 demodulate_term metasenv
362 ((Some (nn, C.Decl s))::context) ugraph
363 table (lift_amount+1) t
367 | Some (t', subst, menv, ug, eq_found) ->
368 Some (C.Prod (nn, (S.lift 1 s), t'),
369 subst, menv, ug, eq_found)
371 | Some (s', subst, menv, ug, eq_found) ->
372 Some (C.Prod (nn, s', (S.lift 1 t)),
373 subst, menv, ug, eq_found)
380 let build_ens_for_sym_eq ty x y =
381 [(UriManager.uri_of_string
382 "cic:/Coq/Init/Logic/Logic_lemmas/equality/A.var", ty);
383 (UriManager.uri_of_string
384 "cic:/Coq/Init/Logic/Logic_lemmas/equality/x.var", x);
385 (UriManager.uri_of_string
386 "cic:/Coq/Init/Logic/Logic_lemmas/equality/y.var", y)]
390 let build_newtarget_time = ref 0.;;
393 let demod_counter = ref 1;;
395 let rec demodulation newmeta env table sign target =
396 let module C = Cic in
397 let module S = CicSubstitution in
398 let module M = CicMetaSubst in
399 let module HL = HelmLibraryObjects in
400 let metasenv, context, ugraph = env in
401 let _, proof, (eq_ty, left, right, order), metas, args = target in
402 let metasenv' = metasenv @ metas in
404 let maxmeta = ref newmeta in
406 let build_newtarget is_left (t, subst, menv, ug, (eq_found, eq_URI)) =
407 let time1 = Unix.gettimeofday () in
409 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
410 let what, other = if pos = Utils.Left then what, other else other, what in
411 let newterm, newproof =
412 let bo = (* M. *)apply_subst subst (S.subst other t) in
414 let name = C.Name ("x_Demod_" ^ (string_of_int !demod_counter)) in
417 if is_left then t, S.lift 1 right else S.lift 1 left, t in
418 (name, ty, S.lift 1 eq_ty, l, r)
420 if sign = Utils.Positive then
422 Inference.ProofBlock (subst, eq_URI, t', eq_found, proof))
427 CicMkImplicit.identity_relocation_list_for_metavariable context in
428 Printf.printf "\nADDING META: %d\n" !maxmeta;
430 C.Meta (!maxmeta, irl)
436 if pos = Utils.Left then
437 build_ens_for_sym_eq ty what other
439 build_ens_for_sym_eq ty other what
441 Inference.ProofSymBlock (ens, proof')
444 if pos = Utils.Left then what, other else other, what
446 pos, (0, proof', (ty, other, what, Utils.Incomparable),
451 Inference.ProofBlock (subst, eq_URI, t', eq_found,
452 Inference.BasicProof metaproof)
455 | Inference.BasicProof _ ->
456 print_endline "replacing a BasicProof";
458 | Inference.ProofGoalBlock (_, parent_eq) ->
459 print_endline "replacing another ProofGoalBlock";
460 Inference.ProofGoalBlock (pb, parent_eq)
463 (0, target_proof, (eq_ty, left, right, order), metas, args)
466 C.Appl [C.MutConstruct (* reflexivity *)
467 (HelmLibraryObjects.Logic.eq_URI, 0, 1, []);
468 eq_ty; if is_left then right else left]
471 Inference.ProofGoalBlock (Inference.BasicProof refl, target'))
473 let left, right = if is_left then newterm, right else left, newterm in
474 let m = (Inference.metas_of_term left) @ (Inference.metas_of_term right) in
475 let newmetasenv = List.filter (fun (i, _, _) -> List.mem i m) metas
478 (function C.Meta (i, _) -> List.mem i m | _ -> assert false)
481 let ordering = !Utils.compare_terms left right in
483 let time2 = Unix.gettimeofday () in
484 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
487 let w = Utils.compute_equality_weight eq_ty left right in
488 (w, newproof, (eq_ty, left, right, ordering), newmetasenv, newargs)
490 (* if sign = Utils.Positive then ( *)
491 (* let newm, res = Inference.fix_metas !maxmeta res in *)
492 (* maxmeta := newm; *)
495 !maxmeta(* newmeta *), res
497 let res = demodulate_term metasenv' context ugraph table 0 left in
498 (* let build_identity (w, p, (t, l, r, o), m, a) = *)
500 (* | Utils.Gt -> (w, p, (t, r, r, Utils.Eq), m, a) *)
501 (* | _ -> (w, p, (t, l, l, Utils.Eq), m, a) *)
505 let newmeta, newtarget = build_newtarget true t in
506 if (Inference.is_identity (metasenv', context, ugraph) newtarget) ||
507 (Inference.meta_convertibility_eq target newtarget) then
510 (* if subsumption env table newtarget then *)
511 (* newmeta, build_identity newtarget *)
513 demodulation newmeta env table sign newtarget
515 let res = demodulate_term metasenv' context ugraph table 0 right in
518 let newmeta, newtarget = build_newtarget false t in
519 if (Inference.is_identity (metasenv', context, ugraph) newtarget) ||
520 (Inference.meta_convertibility_eq target newtarget) then
523 (* if subsumption env table newtarget then *)
524 (* newmeta, build_identity newtarget *)
526 demodulation newmeta env table sign newtarget
532 let rec betaexpand_term metasenv context ugraph table lift_amount term =
533 let module C = Cic in
534 let module S = CicSubstitution in
535 let module M = CicMetaSubst in
536 let module HL = HelmLibraryObjects in
537 let candidates = get_candidates Unification table term in
538 let res, lifted_term =
543 (fun arg (res, lifted_tl) ->
546 let arg_res, lifted_arg =
547 betaexpand_term metasenv context ugraph table
551 (fun (t, s, m, ug, eq_found) ->
552 (Some t)::lifted_tl, s, m, ug, eq_found)
557 (fun (l, s, m, ug, eq_found) ->
558 (Some lifted_arg)::l, s, m, ug, eq_found)
560 (Some lifted_arg)::lifted_tl)
563 (fun (r, s, m, ug, eq_found) ->
564 None::r, s, m, ug, eq_found) res,
570 (fun (l, s, m, ug, eq_found) ->
571 (C.Meta (i, l), s, m, ug, eq_found)) l'
573 e, C.Meta (i, lifted_l)
576 [], if m <= lift_amount then C.Rel m else C.Rel (m+1)
578 | C.Prod (nn, s, t) ->
580 betaexpand_term metasenv context ugraph table lift_amount s in
582 betaexpand_term metasenv ((Some (nn, C.Decl s))::context) ugraph
583 table (lift_amount+1) t in
586 (fun (t, s, m, ug, eq_found) ->
587 C.Prod (nn, t, lifted_t), s, m, ug, eq_found) l1
590 (fun (t, s, m, ug, eq_found) ->
591 C.Prod (nn, lifted_s, t), s, m, ug, eq_found) l2 in
592 l1' @ l2', C.Prod (nn, lifted_s, lifted_t)
597 (fun arg (res, lifted_tl) ->
598 let arg_res, lifted_arg =
599 betaexpand_term metasenv context ugraph table lift_amount arg
603 (fun (a, s, m, ug, eq_found) ->
604 a::lifted_tl, s, m, ug, eq_found)
609 (fun (r, s, m, ug, eq_found) ->
610 lifted_arg::r, s, m, ug, eq_found)
612 lifted_arg::lifted_tl)
616 (fun (l, s, m, ug, eq_found) -> (C.Appl l, s, m, ug, eq_found)) l',
619 | t -> [], (S.lift lift_amount t)
622 | C.Meta _ -> res, lifted_term
625 find_all_matches metasenv context ugraph lift_amount term candidates
631 let sup_l_counter = ref 1;;
633 let superposition_left newmeta (metasenv, context, ugraph) table target =
634 let module C = Cic in
635 let module S = CicSubstitution in
636 let module M = CicMetaSubst in
637 let module HL = HelmLibraryObjects in
638 let module CR = CicReduction in
639 let module U = Utils in
640 let weight, proof, (eq_ty, left, right, ordering), _, _ = target in
642 let term = if ordering = U.Gt then left else right in
643 betaexpand_term metasenv context ugraph table 0 term
645 let maxmeta = ref newmeta in
646 let build_new (bo, s, m, ug, (eq_found, eq_URI)) =
648 print_endline "\nSUPERPOSITION LEFT\n";
650 let time1 = Unix.gettimeofday () in
652 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
653 let what, other = if pos = Utils.Left then what, other else other, what in
654 let newgoal, newproof =
655 let bo' = (* M. *)apply_subst s (S.subst other bo) in
657 let name = C.Name ("x_SupL_" ^ (string_of_int !sup_l_counter)) in
660 if ordering = U.Gt then bo, S.lift 1 right else S.lift 1 left, bo in
661 (name, ty, S.lift 1 eq_ty, l, r)
665 (* [C.MutInd (HL.Logic.eq_URI, 0, []); *)
666 (* S.lift 1 eq_ty] @ *)
667 (* if ordering = U.Gt then [S.lift 1 bo'; S.lift 1 right] *)
668 (* else [S.lift 1 left; S.lift 1 bo']) *)
671 (* let name = C.Name ("x_SupL_" ^ (string_of_int !sup_l_counter)) in *)
672 (* incr sup_l_counter; *)
673 (* C.Lambda (name, ty, bo'') *)
678 CicMkImplicit.identity_relocation_list_for_metavariable context in
679 C.Meta (!maxmeta, irl)
685 if pos = Utils.Left then
686 build_ens_for_sym_eq ty what other
688 build_ens_for_sym_eq ty other what
690 Inference.ProofSymBlock (ens, proof')
693 if pos = Utils.Left then what, other else other, what
695 pos, (0, proof', (ty, other, what, Utils.Incomparable), menv', args')
699 Inference.ProofBlock (s, eq_URI, t', eq_found,
700 Inference.BasicProof metaproof)
703 | Inference.BasicProof _ ->
704 print_endline "replacing a BasicProof";
706 | Inference.ProofGoalBlock (_, parent_eq) ->
707 print_endline "replacing another ProofGoalBlock";
708 Inference.ProofGoalBlock (pb, parent_eq)
711 (weight, target_proof, (eq_ty, left, right, ordering), [], [])
714 C.Appl [C.MutConstruct (* reflexivity *)
715 (HelmLibraryObjects.Logic.eq_URI, 0, 1, []);
716 eq_ty; if ordering = U.Gt then right else left]
719 Inference.ProofGoalBlock (Inference.BasicProof refl, target'))
722 if ordering = U.Gt then newgoal, right else left, newgoal in
723 let neworder = !Utils.compare_terms left right in
725 let time2 = Unix.gettimeofday () in
726 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
729 let w = Utils.compute_equality_weight eq_ty left right in
730 (w, newproof, (eq_ty, left, right, neworder), [], [])
734 !maxmeta, List.map build_new expansions
738 let sup_r_counter = ref 1;;
740 let superposition_right newmeta (metasenv, context, ugraph) table target =
741 let module C = Cic in
742 let module S = CicSubstitution in
743 let module M = CicMetaSubst in
744 let module HL = HelmLibraryObjects in
745 let module CR = CicReduction in
746 let module U = Utils in
747 let _, eqproof, (eq_ty, left, right, ordering), newmetas, args = target in
748 let metasenv' = metasenv @ newmetas in
749 let maxmeta = ref newmeta in
752 | U.Gt -> fst (betaexpand_term metasenv' context ugraph table 0 left), []
753 | U.Lt -> [], fst (betaexpand_term metasenv' context ugraph table 0 right)
757 (fun (_, subst, _, _, _) ->
758 let subst = (* M. *)apply_subst subst in
759 let o = !Utils.compare_terms (subst l) (subst r) in
760 o <> U.Lt && o <> U.Le)
761 (fst (betaexpand_term metasenv' context ugraph table 0 l))
763 (res left right), (res right left)
765 let build_new ordering (bo, s, m, ug, (eq_found, eq_URI)) =
767 let time1 = Unix.gettimeofday () in
769 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
770 let what, other = if pos = Utils.Left then what, other else other, what in
771 let newgoal, newproof =
772 let bo' = (* M. *)apply_subst s (S.subst other bo) in
774 let name = C.Name ("x_SupR_" ^ (string_of_int !sup_r_counter)) in
777 if ordering = U.Gt then bo, S.lift 1 right else S.lift 1 left, bo in
778 (name, ty, S.lift 1 eq_ty, l, r)
782 (* [C.MutInd (HL.Logic.eq_URI, 0, []); S.lift 1 eq_ty] @ *)
783 (* if ordering = U.Gt then [S.lift 1 bo'; S.lift 1 right] *)
784 (* else [S.lift 1 left; S.lift 1 bo']) *)
787 (* let name = C.Name ("x_SupR_" ^ (string_of_int !sup_r_counter)) in *)
788 (* incr sup_r_counter; *)
789 (* C.Lambda (name, ty, bo'') *)
792 Inference.ProofBlock (s, eq_URI, t', eq_found, eqproof(* target *))
793 (* (\* M. *\)apply_subst s *)
794 (* (C.Appl [C.Const (eq_URI, []); ty; what; t'; *)
795 (* eqproof; other; proof']) *)
797 let newmeta, newequality =
799 if ordering = U.Gt then newgoal, (* M. *)apply_subst s right
800 else (* M. *)apply_subst s left, newgoal in
801 let neworder = !Utils.compare_terms left right
802 and newmenv = newmetas @ menv'
803 and newargs = args @ args' in
805 let w = Utils.compute_equality_weight eq_ty left right in
806 (w, newproof, (eq_ty, left, right, neworder), newmenv, newargs)
807 and env = (metasenv, context, ugraph) in
808 let newm, eq' = Inference.fix_metas !maxmeta eq' in
813 let time2 = Unix.gettimeofday () in
814 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
819 (* let build_new = *)
820 (* let profile = CicUtil.profile "Indexing.superposition_right.build_new" in *)
821 (* (fun o e -> profile (build_new o) e) *)
824 let new1 = List.map (build_new U.Gt) res1
825 and new2 = List.map (build_new U.Lt) res2 in
827 | _, _, (_, left, right, _), _, _ ->
828 not (fst (CR.are_convertible context left right ugraph))
831 (List.filter ok (new1 @ new2)))