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 let t2 = Unix.gettimeofday () in
120 indexing_retrieval_time := !indexing_retrieval_time +. (t2 -. t1);
125 (* let get_candidates = *)
126 (* let profile = CicUtil.profile "Indexing.get_candidates" in *)
127 (* (fun mode tree term -> profile (get_candidates mode tree) term) *)
131 let match_unif_time_ok = ref 0.;;
132 let match_unif_time_no = ref 0.;;
135 let rec find_matches metasenv context ugraph lift_amount term =
136 let module C = Cic in
137 let module U = Utils in
138 let module S = CicSubstitution in
139 let module M = CicMetaSubst in
140 let module HL = HelmLibraryObjects in
141 let cmp = !Utils.compare_terms in
142 let names = Utils.names_of_context context in
146 let pos, (_, proof, (ty, left, right, o), metas, args) = candidate in
147 let do_match c other eq_URI =
148 let subst', metasenv', ugraph' =
149 let t1 = Unix.gettimeofday () in
152 Inference.matching (metasenv @ metas) context
153 term (S.lift lift_amount c) ugraph in
154 let t2 = Unix.gettimeofday () in
155 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
158 let t2 = Unix.gettimeofday () in
159 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
162 Some (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
165 let c, other, eq_URI =
166 if pos = Utils.Left then left, right, HL.Logic.eq_ind_URI
167 else right, left, HL.Logic.eq_ind_r_URI
169 if o <> U.Incomparable then
171 do_match c other eq_URI
173 find_matches metasenv context ugraph lift_amount term tl
175 let res = try do_match c other eq_URI with e -> None in
177 | Some (_, s, _, _, _) ->
178 let c' = (* M. *)apply_subst s c
179 and other' = (* M. *)apply_subst s other in
180 let order = cmp c' other' in
181 let names = U.names_of_context context in
185 find_matches metasenv context ugraph lift_amount term tl
187 find_matches metasenv context ugraph lift_amount term tl
191 let rec find_all_matches ?(unif_fun=Inference.unification)
192 metasenv context ugraph lift_amount term =
193 let module C = Cic in
194 let module U = Utils in
195 let module S = CicSubstitution in
196 let module M = CicMetaSubst in
197 let module HL = HelmLibraryObjects in
198 let cmp = !Utils.compare_terms in
199 let names = Utils.names_of_context context in
203 let pos, (_, _, (ty, left, right, o), metas, args) = candidate in
204 let do_match c other eq_URI =
205 let subst', metasenv', ugraph' =
206 let t1 = Unix.gettimeofday () in
209 unif_fun (metasenv @ metas) context
210 term (S.lift lift_amount c) ugraph in
211 let t2 = Unix.gettimeofday () in
212 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
215 let t2 = Unix.gettimeofday () in
216 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
219 (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
222 let c, other, eq_URI =
223 if pos = Utils.Left then left, right, HL.Logic.eq_ind_URI
224 else right, left, HL.Logic.eq_ind_r_URI
226 if o <> U.Incomparable then
228 let res = do_match c other eq_URI in
229 res::(find_all_matches ~unif_fun metasenv context ugraph
232 find_all_matches ~unif_fun metasenv context ugraph
236 let res = do_match c other eq_URI in
239 let c' = (* M. *)apply_subst s c
240 and other' = (* M. *)apply_subst s other in
241 let order = cmp c' other' in
242 let names = U.names_of_context context in
243 if order <> U.Lt && order <> U.Le then
244 res::(find_all_matches ~unif_fun metasenv context ugraph
247 find_all_matches ~unif_fun metasenv context ugraph
250 find_all_matches ~unif_fun metasenv context ugraph
255 let subsumption env table target =
256 let _, (ty, left, right, _), tmetas, _ = target in
257 let metasenv, context, ugraph = env in
258 let metasenv = metasenv @ tmetas in
259 let samesubst subst subst' =
260 let tbl = Hashtbl.create (List.length subst) in
261 List.iter (fun (m, (c, t1, t2)) -> Hashtbl.add tbl m (c, t1, t2)) subst;
263 (fun (m, (c, t1, t2)) ->
265 let c', t1', t2' = Hashtbl.find tbl m in
266 if (c = c') && (t1 = t1') && (t2 = t2') then true
276 let leftc = get_candidates Matching table left in
277 find_all_matches ~unif_fun:Inference.matching
278 metasenv context ugraph 0 left leftc
280 let ok what (_, subst, menv, ug, ((pos, (_, _, (_, l, r, o), _, _)), _)) =
282 let other = if pos = Utils.Left then r else l in
283 let subst', menv', ug' =
284 let t1 = Unix.gettimeofday () in
287 Inference.matching metasenv context what other ugraph in
288 let t2 = Unix.gettimeofday () in
289 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
292 let t2 = Unix.gettimeofday () in
293 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
296 samesubst subst subst'
300 let r = List.exists (ok right) leftr in
308 let rightc = get_candidates Matching table right in
309 find_all_matches ~unif_fun:Inference.matching
310 metasenv context ugraph 0 right rightc
312 List.exists (ok left) rightr
316 let rec demodulate_term metasenv context ugraph table lift_amount term =
317 let module C = Cic in
318 let module S = CicSubstitution in
319 let module M = CicMetaSubst in
320 let module HL = HelmLibraryObjects in
321 let candidates = get_candidates Matching table term in
326 find_matches metasenv context ugraph lift_amount term candidates
337 (res, tl @ [S.lift 1 t])
340 demodulate_term metasenv context ugraph table
344 | None -> (None, tl @ [S.lift 1 t])
345 | Some (rel, _, _, _, _) -> (r, tl @ [rel]))
350 | Some (_, subst, menv, ug, eq_found) ->
351 Some (C.Appl ll, subst, menv, ug, eq_found)
353 | C.Prod (nn, s, t) ->
355 demodulate_term metasenv context ugraph table lift_amount s in (
359 demodulate_term metasenv
360 ((Some (nn, C.Decl s))::context) ugraph
361 table (lift_amount+1) t
365 | Some (t', subst, menv, ug, eq_found) ->
366 Some (C.Prod (nn, (S.lift 1 s), t'),
367 subst, menv, ug, eq_found)
369 | Some (s', subst, menv, ug, eq_found) ->
370 Some (C.Prod (nn, s', (S.lift 1 t)),
371 subst, menv, ug, eq_found)
378 let build_ens_for_sym_eq ty x y =
379 [(UriManager.uri_of_string
380 "cic:/Coq/Init/Logic/Logic_lemmas/equality/A.var", ty);
381 (UriManager.uri_of_string
382 "cic:/Coq/Init/Logic/Logic_lemmas/equality/x.var", x);
383 (UriManager.uri_of_string
384 "cic:/Coq/Init/Logic/Logic_lemmas/equality/y.var", y)]
388 let build_newtarget_time = ref 0.;;
391 let demod_counter = ref 1;;
393 let rec demodulation newmeta env table sign target =
394 let module C = Cic in
395 let module S = CicSubstitution in
396 let module M = CicMetaSubst in
397 let module HL = HelmLibraryObjects in
398 let metasenv, context, ugraph = env in
399 let _, proof, (eq_ty, left, right, order), metas, args = target in
400 let metasenv' = metasenv @ metas in
402 let maxmeta = ref newmeta in
404 let build_newtarget is_left (t, subst, menv, ug, (eq_found, eq_URI)) =
405 let time1 = Unix.gettimeofday () in
407 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
408 let what, other = if pos = Utils.Left then what, other else other, what in
409 let newterm, newproof =
410 let bo = (* M. *)apply_subst subst (S.subst other t) in
412 let name = C.Name ("x_Demod_" ^ (string_of_int !demod_counter)) in
415 if is_left then t, S.lift 1 right else S.lift 1 left, t in
416 (name, ty, S.lift 1 eq_ty, l, r)
418 if sign = Utils.Positive then
420 Inference.ProofBlock (subst, eq_URI, t', eq_found, proof))
425 CicMkImplicit.identity_relocation_list_for_metavariable context in
426 Printf.printf "\nADDING META: %d\n" !maxmeta;
428 C.Meta (!maxmeta, irl)
434 if pos = Utils.Left then
435 build_ens_for_sym_eq ty what other
437 build_ens_for_sym_eq ty other what
439 Inference.ProofSymBlock (ens, proof')
442 if pos = Utils.Left then what, other else other, what
444 pos, (0, proof', (ty, other, what, Utils.Incomparable),
449 Inference.ProofBlock (subst, eq_URI, t', eq_found,
450 Inference.BasicProof metaproof)
453 | Inference.BasicProof _ ->
454 print_endline "replacing a BasicProof";
456 | Inference.ProofGoalBlock (_, parent_eq) ->
457 print_endline "replacing another ProofGoalBlock";
458 Inference.ProofGoalBlock (pb, parent_eq)
461 (0, target_proof, (eq_ty, left, right, order), metas, args)
464 C.Appl [C.MutConstruct (* reflexivity *)
465 (HelmLibraryObjects.Logic.eq_URI, 0, 1, []);
466 eq_ty; if is_left then right else left]
469 Inference.ProofGoalBlock (Inference.BasicProof refl, target'))
471 let left, right = if is_left then newterm, right else left, newterm in
472 let m = (Inference.metas_of_term left) @ (Inference.metas_of_term right) in
473 let newmetasenv = List.filter (fun (i, _, _) -> List.mem i m) metas
476 (function C.Meta (i, _) -> List.mem i m | _ -> assert false)
479 let ordering = !Utils.compare_terms left right in
481 let time2 = Unix.gettimeofday () in
482 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
485 let w = Utils.compute_equality_weight eq_ty left right in
486 (w, newproof, (eq_ty, left, right, ordering), newmetasenv, newargs)
488 (* if sign = Utils.Positive then ( *)
489 (* let newm, res = Inference.fix_metas !maxmeta res in *)
490 (* maxmeta := newm; *)
493 !maxmeta(* newmeta *), res
495 let res = demodulate_term metasenv' context ugraph table 0 left in
496 (* let build_identity (w, p, (t, l, r, o), m, a) = *)
498 (* | Utils.Gt -> (w, p, (t, r, r, Utils.Eq), m, a) *)
499 (* | _ -> (w, p, (t, l, l, Utils.Eq), m, a) *)
503 let newmeta, newtarget = build_newtarget true t in
504 if (Inference.is_identity (metasenv', context, ugraph) newtarget) ||
505 (Inference.meta_convertibility_eq target newtarget) then
508 (* if subsumption env table newtarget then *)
509 (* newmeta, build_identity newtarget *)
511 demodulation newmeta env table sign newtarget
513 let res = demodulate_term metasenv' context ugraph table 0 right in
516 let newmeta, newtarget = build_newtarget false t in
517 if (Inference.is_identity (metasenv', context, ugraph) newtarget) ||
518 (Inference.meta_convertibility_eq target newtarget) then
521 (* if subsumption env table newtarget then *)
522 (* newmeta, build_identity newtarget *)
524 demodulation newmeta env table sign newtarget
530 let rec betaexpand_term metasenv context ugraph table lift_amount term =
531 let module C = Cic in
532 let module S = CicSubstitution in
533 let module M = CicMetaSubst in
534 let module HL = HelmLibraryObjects in
535 let candidates = get_candidates Unification table term in
536 let res, lifted_term =
541 (fun arg (res, lifted_tl) ->
544 let arg_res, lifted_arg =
545 betaexpand_term metasenv context ugraph table
549 (fun (t, s, m, ug, eq_found) ->
550 (Some t)::lifted_tl, s, m, ug, eq_found)
555 (fun (l, s, m, ug, eq_found) ->
556 (Some lifted_arg)::l, s, m, ug, eq_found)
558 (Some lifted_arg)::lifted_tl)
561 (fun (r, s, m, ug, eq_found) ->
562 None::r, s, m, ug, eq_found) res,
568 (fun (l, s, m, ug, eq_found) ->
569 (C.Meta (i, l), s, m, ug, eq_found)) l'
571 e, C.Meta (i, lifted_l)
574 [], if m <= lift_amount then C.Rel m else C.Rel (m+1)
576 | C.Prod (nn, s, t) ->
578 betaexpand_term metasenv context ugraph table lift_amount s in
580 betaexpand_term metasenv ((Some (nn, C.Decl s))::context) ugraph
581 table (lift_amount+1) t in
584 (fun (t, s, m, ug, eq_found) ->
585 C.Prod (nn, t, lifted_t), s, m, ug, eq_found) l1
588 (fun (t, s, m, ug, eq_found) ->
589 C.Prod (nn, lifted_s, t), s, m, ug, eq_found) l2 in
590 l1' @ l2', C.Prod (nn, lifted_s, lifted_t)
595 (fun arg (res, lifted_tl) ->
596 let arg_res, lifted_arg =
597 betaexpand_term metasenv context ugraph table lift_amount arg
601 (fun (a, s, m, ug, eq_found) ->
602 a::lifted_tl, s, m, ug, eq_found)
607 (fun (r, s, m, ug, eq_found) ->
608 lifted_arg::r, s, m, ug, eq_found)
610 lifted_arg::lifted_tl)
614 (fun (l, s, m, ug, eq_found) -> (C.Appl l, s, m, ug, eq_found)) l',
617 | t -> [], (S.lift lift_amount t)
620 | C.Meta _ -> res, lifted_term
623 find_all_matches metasenv context ugraph lift_amount term candidates
629 let sup_l_counter = ref 1;;
631 let superposition_left newmeta (metasenv, context, ugraph) table target =
632 let module C = Cic in
633 let module S = CicSubstitution in
634 let module M = CicMetaSubst in
635 let module HL = HelmLibraryObjects in
636 let module CR = CicReduction in
637 let module U = Utils in
638 let weight, proof, (eq_ty, left, right, ordering), _, _ = target in
640 let term = if ordering = U.Gt then left else right in
641 betaexpand_term metasenv context ugraph table 0 term
643 let maxmeta = ref newmeta in
644 let build_new (bo, s, m, ug, (eq_found, eq_URI)) =
646 print_endline "\nSUPERPOSITION LEFT\n";
648 let time1 = Unix.gettimeofday () in
650 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
651 let what, other = if pos = Utils.Left then what, other else other, what in
652 let newgoal, newproof =
653 let bo' = (* M. *)apply_subst s (S.subst other bo) in
655 let name = C.Name ("x_SupL_" ^ (string_of_int !sup_l_counter)) in
658 if ordering = U.Gt then bo, S.lift 1 right else S.lift 1 left, bo in
659 (name, ty, S.lift 1 eq_ty, l, r)
663 (* [C.MutInd (HL.Logic.eq_URI, 0, []); *)
664 (* S.lift 1 eq_ty] @ *)
665 (* if ordering = U.Gt then [S.lift 1 bo'; S.lift 1 right] *)
666 (* else [S.lift 1 left; S.lift 1 bo']) *)
669 (* let name = C.Name ("x_SupL_" ^ (string_of_int !sup_l_counter)) in *)
670 (* incr sup_l_counter; *)
671 (* C.Lambda (name, ty, bo'') *)
676 CicMkImplicit.identity_relocation_list_for_metavariable context in
677 C.Meta (!maxmeta, irl)
683 if pos = Utils.Left then
684 build_ens_for_sym_eq ty what other
686 build_ens_for_sym_eq ty other what
688 Inference.ProofSymBlock (ens, proof')
691 if pos = Utils.Left then what, other else other, what
693 pos, (0, proof', (ty, other, what, Utils.Incomparable), menv', args')
697 Inference.ProofBlock (s, eq_URI, t', eq_found,
698 Inference.BasicProof metaproof)
701 | Inference.BasicProof _ ->
702 print_endline "replacing a BasicProof";
704 | Inference.ProofGoalBlock (_, parent_eq) ->
705 print_endline "replacing another ProofGoalBlock";
706 Inference.ProofGoalBlock (pb, parent_eq)
709 (weight, target_proof, (eq_ty, left, right, ordering), [], [])
712 C.Appl [C.MutConstruct (* reflexivity *)
713 (HelmLibraryObjects.Logic.eq_URI, 0, 1, []);
714 eq_ty; if ordering = U.Gt then right else left]
717 Inference.ProofGoalBlock (Inference.BasicProof refl, target'))
720 if ordering = U.Gt then newgoal, right else left, newgoal in
721 let neworder = !Utils.compare_terms left right in
723 let time2 = Unix.gettimeofday () in
724 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
727 let w = Utils.compute_equality_weight eq_ty left right in
728 (w, newproof, (eq_ty, left, right, neworder), [], [])
732 !maxmeta, List.map build_new expansions
736 let sup_r_counter = ref 1;;
738 let superposition_right newmeta (metasenv, context, ugraph) table target =
739 let module C = Cic in
740 let module S = CicSubstitution in
741 let module M = CicMetaSubst in
742 let module HL = HelmLibraryObjects in
743 let module CR = CicReduction in
744 let module U = Utils in
745 let _, eqproof, (eq_ty, left, right, ordering), newmetas, args = target in
746 let metasenv' = metasenv @ newmetas in
747 let maxmeta = ref newmeta in
750 | U.Gt -> fst (betaexpand_term metasenv' context ugraph table 0 left), []
751 | U.Lt -> [], fst (betaexpand_term metasenv' context ugraph table 0 right)
755 (fun (_, subst, _, _, _) ->
756 let subst = (* M. *)apply_subst subst in
757 let o = !Utils.compare_terms (subst l) (subst r) in
758 o <> U.Lt && o <> U.Le)
759 (fst (betaexpand_term metasenv' context ugraph table 0 l))
761 (res left right), (res right left)
763 let build_new ordering (bo, s, m, ug, (eq_found, eq_URI)) =
765 let time1 = Unix.gettimeofday () in
767 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
768 let what, other = if pos = Utils.Left then what, other else other, what in
769 let newgoal, newproof =
770 let bo' = (* M. *)apply_subst s (S.subst other bo) in
772 let name = C.Name ("x_SupR_" ^ (string_of_int !sup_r_counter)) in
775 if ordering = U.Gt then bo, S.lift 1 right else S.lift 1 left, bo in
776 (name, ty, S.lift 1 eq_ty, l, r)
780 (* [C.MutInd (HL.Logic.eq_URI, 0, []); S.lift 1 eq_ty] @ *)
781 (* if ordering = U.Gt then [S.lift 1 bo'; S.lift 1 right] *)
782 (* else [S.lift 1 left; S.lift 1 bo']) *)
785 (* let name = C.Name ("x_SupR_" ^ (string_of_int !sup_r_counter)) in *)
786 (* incr sup_r_counter; *)
787 (* C.Lambda (name, ty, bo'') *)
790 Inference.ProofBlock (s, eq_URI, t', eq_found, eqproof(* target *))
791 (* (\* M. *\)apply_subst s *)
792 (* (C.Appl [C.Const (eq_URI, []); ty; what; t'; *)
793 (* eqproof; other; proof']) *)
795 let newmeta, newequality =
797 if ordering = U.Gt then newgoal, (* M. *)apply_subst s right
798 else (* M. *)apply_subst s left, newgoal in
799 let neworder = !Utils.compare_terms left right
800 and newmenv = newmetas @ menv'
801 and newargs = args @ args' in
803 let w = Utils.compute_equality_weight eq_ty left right in
804 (w, newproof, (eq_ty, left, right, neworder), newmenv, newargs)
805 and env = (metasenv, context, ugraph) in
806 let newm, eq' = Inference.fix_metas !maxmeta eq' in
811 let time2 = Unix.gettimeofday () in
812 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
817 (* let build_new = *)
818 (* let profile = CicUtil.profile "Indexing.superposition_right.build_new" in *)
819 (* (fun o e -> profile (build_new o) e) *)
822 let new1 = List.map (build_new U.Gt) res1
823 and new2 = List.map (build_new U.Lt) res2 in
825 | _, _, (_, left, right, _), _, _ ->
826 not (fst (CR.are_convertible context left right ugraph))
829 (List.filter ok (new1 @ new2)))