1 (* Copyright (C) 2005, 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 let debug_print = Utils.debug_print;;
29 type retrieval_mode = Matching | Unification;;
32 let print_candidates mode term res =
36 Printf.printf "| candidates Matching %s\n" (CicPp.ppterm term)
38 Printf.printf "| candidates Unification %s\n" (CicPp.ppterm term)
44 Printf.sprintf "| (%s, %s)" (Utils.string_of_pos p)
45 (Inference.string_of_equality e))
51 let indexing_retrieval_time = ref 0.;;
54 let apply_subst = CicMetaSubst.apply_subst
60 let init_index () = ()
62 let empty_table () = []
64 let index table equality =
65 let _, _, (_, l, r, ordering), _, _ = equality in
67 | Utils.Gt -> (Utils.Left, equality)::table
68 | Utils.Lt -> (Utils.Right, equality)::table
69 | _ -> (Utils.Left, equality)::(Utils.Right, equality)::table
72 let remove_index table equality =
73 List.filter (fun (p, e) -> e != equality) table
76 let in_index table equality =
77 List.exists (fun (p, e) -> e == equality) table
80 let get_candidates mode table term = table
86 let init_index () = ()
89 Path_indexing.PSTrie.empty
92 let index = Path_indexing.index
93 and remove_index = Path_indexing.remove_index
94 and in_index = Path_indexing.in_index;;
96 let get_candidates mode trie term =
97 let t1 = Unix.gettimeofday () in
101 | Matching -> Path_indexing.retrieve_generalizations trie term
102 | Unification -> Path_indexing.retrieve_unifiables trie term
103 (* Path_indexing.retrieve_all trie term *)
105 Path_indexing.PosEqSet.elements s
107 (* print_candidates mode term res; *)
108 let t2 = Unix.gettimeofday () in
109 indexing_retrieval_time := !indexing_retrieval_time +. (t2 -. t1);
115 (* DISCRIMINATION TREES *)
117 Hashtbl.clear Discrimination_tree.arities;
121 Discrimination_tree.DiscriminationTree.empty
124 let index = Discrimination_tree.index
125 and remove_index = Discrimination_tree.remove_index
126 and in_index = Discrimination_tree.in_index;;
128 let get_candidates mode tree term =
129 let t1 = Unix.gettimeofday () in
133 | Matching -> Discrimination_tree.retrieve_generalizations tree term
134 | Unification -> Discrimination_tree.retrieve_unifiables tree term
136 Discrimination_tree.PosEqSet.elements s
138 (* print_candidates mode term res; *)
139 (* print_endline (Discrimination_tree.string_of_discrimination_tree tree); *)
140 (* print_newline (); *)
141 let t2 = Unix.gettimeofday () in
142 indexing_retrieval_time := !indexing_retrieval_time +. (t2 -. t1);
147 let match_unif_time_ok = ref 0.;;
148 let match_unif_time_no = ref 0.;;
152 finds the first equality in the index that matches "term", of type "termty"
153 termty can be Implicit if it is not needed. The result (one of the sides of
154 the equality, actually) should be not greater (wrt the term ordering) than
157 let rec find_matches metasenv context ugraph lift_amount term termty =
158 let module C = Cic in
159 let module U = Utils in
160 let module S = CicSubstitution in
161 let module M = CicMetaSubst in
162 let module HL = HelmLibraryObjects in
163 let cmp = !Utils.compare_terms in
164 let check = match termty with C.Implicit None -> false | _ -> true in
168 let pos, (_, proof, (ty, left, right, o), metas, args) = candidate in
169 if check && not (fst (CicReduction.are_convertible
170 ~metasenv context termty ty ugraph)) then (
171 find_matches metasenv context ugraph lift_amount term termty tl
173 let do_match c eq_URI =
174 let subst', metasenv', ugraph' =
175 let t1 = Unix.gettimeofday () in
178 Inference.matching (metasenv @ metas) context
179 term (S.lift lift_amount c) ugraph in
180 let t2 = Unix.gettimeofday () in
181 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
183 with Inference.MatchingFailure as e ->
184 let t2 = Unix.gettimeofday () in
185 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
188 Some (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
191 let c, other, eq_URI =
192 if pos = Utils.Left then left, right, Utils.eq_ind_URI ()
193 else right, left, Utils.eq_ind_r_URI ()
195 if o <> U.Incomparable then
198 with Inference.MatchingFailure ->
199 find_matches metasenv context ugraph lift_amount term termty tl
202 try do_match c eq_URI
203 with Inference.MatchingFailure -> None
206 | Some (_, s, _, _, _) ->
207 let c' = apply_subst s c
208 and other' = apply_subst s other in
209 let order = cmp c' other' in
210 let names = U.names_of_context context in
215 metasenv context ugraph lift_amount term termty tl
217 find_matches metasenv context ugraph lift_amount term termty tl
222 as above, but finds all the matching equalities, and the matching condition
223 can be either Inference.matching or Inference.unification
225 let rec find_all_matches ?(unif_fun=Inference.unification)
226 metasenv context ugraph lift_amount term termty =
227 let module C = Cic in
228 let module U = Utils in
229 let module S = CicSubstitution in
230 let module M = CicMetaSubst in
231 let module HL = HelmLibraryObjects in
232 let cmp = !Utils.compare_terms in
236 let pos, (_, _, (ty, left, right, o), metas, args) = candidate in
237 let do_match c eq_URI =
238 let subst', metasenv', ugraph' =
239 let t1 = Unix.gettimeofday () in
242 unif_fun (metasenv @ metas) context
243 term (S.lift lift_amount c) ugraph in
244 let t2 = Unix.gettimeofday () in
245 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
248 | Inference.MatchingFailure
249 | CicUnification.UnificationFailure _
250 | CicUnification.Uncertain _ as e ->
251 let t2 = Unix.gettimeofday () in
252 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
255 (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
258 let c, other, eq_URI =
259 if pos = Utils.Left then left, right, Utils.eq_ind_URI ()
260 else right, left, Utils.eq_ind_r_URI ()
262 if o <> U.Incomparable then
264 let res = do_match c eq_URI in
265 res::(find_all_matches ~unif_fun metasenv context ugraph
266 lift_amount term termty tl)
268 | Inference.MatchingFailure
269 | CicUnification.UnificationFailure _
270 | CicUnification.Uncertain _ ->
271 find_all_matches ~unif_fun metasenv context ugraph
272 lift_amount term termty tl
275 let res = do_match c eq_URI in
278 let c' = apply_subst s c
279 and other' = apply_subst s other in
280 let order = cmp c' other' in
281 let names = U.names_of_context context in
282 if order <> U.Lt && order <> U.Le then
283 res::(find_all_matches ~unif_fun metasenv context ugraph
284 lift_amount term termty tl)
286 find_all_matches ~unif_fun metasenv context ugraph
287 lift_amount term termty tl
289 | Inference.MatchingFailure
290 | CicUnification.UnificationFailure _
291 | CicUnification.Uncertain _ ->
292 find_all_matches ~unif_fun metasenv context ugraph
293 lift_amount term termty tl
298 returns true if target is subsumed by some equality in table
300 let subsumption env table target =
301 let _, (ty, left, right, _), tmetas, _ = target in
302 let metasenv, context, ugraph = env in
303 let metasenv = metasenv @ tmetas in
304 let samesubst subst subst' =
305 let tbl = Hashtbl.create (List.length subst) in
306 List.iter (fun (m, (c, t1, t2)) -> Hashtbl.add tbl m (c, t1, t2)) subst;
308 (fun (m, (c, t1, t2)) ->
310 let c', t1', t2' = Hashtbl.find tbl m in
311 if (c = c') && (t1 = t1') && (t2 = t2') then true
321 let leftc = get_candidates Matching table left in
322 find_all_matches ~unif_fun:Inference.matching
323 metasenv context ugraph 0 left ty leftc
325 let rec ok what = function
327 | (_, subst, menv, ug, ((pos, (_, _, (_, l, r, o), _, _)), _))::tl ->
329 let other = if pos = Utils.Left then r else l in
330 let subst', menv', ug' =
331 let t1 = Unix.gettimeofday () in
334 Inference.matching metasenv context what other ugraph in
335 let t2 = Unix.gettimeofday () in
336 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
338 with Inference.MatchingFailure as e ->
339 let t2 = Unix.gettimeofday () in
340 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
343 if samesubst subst subst' then
347 with Inference.MatchingFailure ->
350 let r, subst = ok right leftr in
358 let rightc = get_candidates Matching table right in
359 find_all_matches ~unif_fun:Inference.matching
360 metasenv context ugraph 0 right ty rightc
366 let rec demodulation_aux ?(typecheck=false)
367 metasenv context ugraph table lift_amount term =
368 let module C = Cic in
369 let module S = CicSubstitution in
370 let module M = CicMetaSubst in
371 let module HL = HelmLibraryObjects in
372 let candidates = get_candidates Matching table term in
378 CicTypeChecker.type_of_aux' metasenv context term ugraph
380 C.Implicit None, ugraph
383 find_matches metasenv context ugraph lift_amount term termty candidates
394 (res, tl @ [S.lift 1 t])
397 demodulation_aux metasenv context ugraph table
401 | None -> (None, tl @ [S.lift 1 t])
402 | Some (rel, _, _, _, _) -> (r, tl @ [rel]))
407 | Some (_, subst, menv, ug, eq_found) ->
408 Some (C.Appl ll, subst, menv, ug, eq_found)
410 | C.Prod (nn, s, t) ->
412 demodulation_aux metasenv context ugraph table lift_amount s in (
416 demodulation_aux metasenv
417 ((Some (nn, C.Decl s))::context) ugraph
418 table (lift_amount+1) t
422 | Some (t', subst, menv, ug, eq_found) ->
423 Some (C.Prod (nn, (S.lift 1 s), t'),
424 subst, menv, ug, eq_found)
426 | Some (s', subst, menv, ug, eq_found) ->
427 Some (C.Prod (nn, s', (S.lift 1 t)),
428 subst, menv, ug, eq_found)
430 | C.Lambda (nn, s, t) ->
432 demodulation_aux metasenv context ugraph table lift_amount s in (
436 demodulation_aux metasenv
437 ((Some (nn, C.Decl s))::context) ugraph
438 table (lift_amount+1) t
442 | Some (t', subst, menv, ug, eq_found) ->
443 Some (C.Lambda (nn, (S.lift 1 s), t'),
444 subst, menv, ug, eq_found)
446 | Some (s', subst, menv, ug, eq_found) ->
447 Some (C.Lambda (nn, s', (S.lift 1 t)),
448 subst, menv, ug, eq_found)
455 let build_newtarget_time = ref 0.;;
458 let demod_counter = ref 1;;
460 (** demodulation, when target is an equality *)
461 let rec demodulation_equality newmeta env table sign target =
462 let module C = Cic in
463 let module S = CicSubstitution in
464 let module M = CicMetaSubst in
465 let module HL = HelmLibraryObjects in
466 let metasenv, context, ugraph = env in
467 let _, proof, (eq_ty, left, right, order), metas, args = target in
468 let metasenv' = metasenv @ metas in
470 let maxmeta = ref newmeta in
472 let build_newtarget is_left (t, subst, menv, ug, (eq_found, eq_URI)) =
473 let time1 = Unix.gettimeofday () in
475 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
477 try fst (CicTypeChecker.type_of_aux' metasenv context what ugraph)
478 with CicUtil.Meta_not_found _ -> ty
480 let what, other = if pos = Utils.Left then what, other else other, what in
481 let newterm, newproof =
482 let bo = apply_subst subst (S.subst other t) in
483 let name = C.Name ("x_Demod_" ^ (string_of_int !demod_counter)) in
486 let l, r = if is_left then t, S.lift 1 right else S.lift 1 left, t in
487 C.Appl [C.MutInd (LibraryObjects.eq_URI (), 0, []);
488 S.lift 1 eq_ty; l; r]
490 if sign = Utils.Positive then
492 Inference.ProofBlock (
493 subst, eq_URI, (name, ty), bo'(* t' *), eq_found, proof))
498 CicMkImplicit.identity_relocation_list_for_metavariable context in
499 debug_print (lazy (Printf.sprintf "\nADDING META: %d\n" !maxmeta));
501 C.Meta (!maxmeta, irl)
506 if pos = Utils.Left then [ty; what; other]
507 else [ty; other; what]
509 Inference.ProofSymBlock (termlist, proof')
512 if pos = Utils.Left then what, other else other, what
514 pos, (0, proof', (ty, other, what, Utils.Incomparable),
519 Inference.ProofBlock (subst, eq_URI, (name, ty), bo',
520 eq_found, Inference.BasicProof metaproof)
523 | Inference.BasicProof _ ->
524 print_endline "replacing a BasicProof";
526 | Inference.ProofGoalBlock (_, parent_proof) ->
527 print_endline "replacing another ProofGoalBlock";
528 Inference.ProofGoalBlock (pb, parent_proof)
532 C.Appl [C.MutConstruct (* reflexivity *)
533 (LibraryObjects.eq_URI (), 0, 1, []);
534 eq_ty; if is_left then right else left]
537 Inference.ProofGoalBlock (Inference.BasicProof refl, target_proof))
539 let left, right = if is_left then newterm, right else left, newterm in
540 let m = (Inference.metas_of_term left) @ (Inference.metas_of_term right) in
541 let newmetasenv = List.filter (fun (i, _, _) -> List.mem i m) metas
544 let ordering = !Utils.compare_terms left right in
546 let time2 = Unix.gettimeofday () in
547 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
550 let w = Utils.compute_equality_weight eq_ty left right in
551 (w, newproof, (eq_ty, left, right, ordering), newmetasenv, newargs)
555 let res = demodulation_aux metasenv' context ugraph table 0 left in
558 let newmeta, newtarget = build_newtarget true t in
559 if (Inference.is_identity (metasenv', context, ugraph) newtarget) ||
560 (Inference.meta_convertibility_eq target newtarget) then
563 demodulation_equality newmeta env table sign newtarget
565 let res = demodulation_aux metasenv' context ugraph table 0 right in
568 let newmeta, newtarget = build_newtarget false t in
569 if (Inference.is_identity (metasenv', context, ugraph) newtarget) ||
570 (Inference.meta_convertibility_eq target newtarget) then
573 demodulation_equality newmeta env table sign newtarget
580 Performs the beta expansion of the term "term" w.r.t. "table",
581 i.e. returns the list of all the terms t s.t. "(t term) = t2", for some t2
584 let rec betaexpand_term metasenv context ugraph table lift_amount term =
585 let module C = Cic in
586 let module S = CicSubstitution in
587 let module M = CicMetaSubst in
588 let module HL = HelmLibraryObjects in
589 let candidates = get_candidates Unification table term in
590 let res, lifted_term =
595 (fun arg (res, lifted_tl) ->
598 let arg_res, lifted_arg =
599 betaexpand_term metasenv context ugraph table
603 (fun (t, s, m, ug, eq_found) ->
604 (Some t)::lifted_tl, s, m, ug, eq_found)
609 (fun (l, s, m, ug, eq_found) ->
610 (Some lifted_arg)::l, s, m, ug, eq_found)
612 (Some lifted_arg)::lifted_tl)
615 (fun (r, s, m, ug, eq_found) ->
616 None::r, s, m, ug, eq_found) res,
622 (fun (l, s, m, ug, eq_found) ->
623 (C.Meta (i, l), s, m, ug, eq_found)) l'
625 e, C.Meta (i, lifted_l)
628 [], if m <= lift_amount then C.Rel m else C.Rel (m+1)
630 | C.Prod (nn, s, t) ->
632 betaexpand_term metasenv context ugraph table lift_amount s in
634 betaexpand_term metasenv ((Some (nn, C.Decl s))::context) ugraph
635 table (lift_amount+1) t in
638 (fun (t, s, m, ug, eq_found) ->
639 C.Prod (nn, t, lifted_t), s, m, ug, eq_found) l1
642 (fun (t, s, m, ug, eq_found) ->
643 C.Prod (nn, lifted_s, t), s, m, ug, eq_found) l2 in
644 l1' @ l2', C.Prod (nn, lifted_s, lifted_t)
646 | C.Lambda (nn, s, t) ->
648 betaexpand_term metasenv context ugraph table lift_amount s in
650 betaexpand_term metasenv ((Some (nn, C.Decl s))::context) ugraph
651 table (lift_amount+1) t in
654 (fun (t, s, m, ug, eq_found) ->
655 C.Lambda (nn, t, lifted_t), s, m, ug, eq_found) l1
658 (fun (t, s, m, ug, eq_found) ->
659 C.Lambda (nn, lifted_s, t), s, m, ug, eq_found) l2 in
660 l1' @ l2', C.Lambda (nn, lifted_s, lifted_t)
665 (fun arg (res, lifted_tl) ->
666 let arg_res, lifted_arg =
667 betaexpand_term metasenv context ugraph table lift_amount arg
671 (fun (a, s, m, ug, eq_found) ->
672 a::lifted_tl, s, m, ug, eq_found)
677 (fun (r, s, m, ug, eq_found) ->
678 lifted_arg::r, s, m, ug, eq_found)
680 lifted_arg::lifted_tl)
684 (fun (l, s, m, ug, eq_found) -> (C.Appl l, s, m, ug, eq_found)) l',
687 | t -> [], (S.lift lift_amount t)
690 | C.Meta (i, l) -> res, lifted_term
693 C.Implicit None, ugraph
694 (* CicTypeChecker.type_of_aux' metasenv context term ugraph *)
698 metasenv context ugraph lift_amount term termty candidates
704 let sup_l_counter = ref 1;;
708 returns a list of new clauses inferred with a left superposition step
709 the negative equation "target" and one of the positive equations in "table"
711 let superposition_left newmeta (metasenv, context, ugraph) table target =
712 let module C = Cic in
713 let module S = CicSubstitution in
714 let module M = CicMetaSubst in
715 let module HL = HelmLibraryObjects in
716 let module CR = CicReduction in
717 let module U = Utils in
718 let weight, proof, (eq_ty, left, right, ordering), _, _ = target in
720 let term = if ordering = U.Gt then left else right in
721 betaexpand_term metasenv context ugraph table 0 term
723 let maxmeta = ref newmeta in
724 let build_new (bo, s, m, ug, (eq_found, eq_URI)) =
726 debug_print (lazy "\nSUPERPOSITION LEFT\n");
728 let time1 = Unix.gettimeofday () in
730 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
731 let what, other = if pos = Utils.Left then what, other else other, what in
732 let newgoal, newproof =
733 let bo' = apply_subst s (S.subst other bo) in
734 let name = C.Name ("x_SupL_" ^ (string_of_int !sup_l_counter)) in
738 if ordering = U.Gt then bo, S.lift 1 right else S.lift 1 left, bo in
739 C.Appl [C.MutInd (LibraryObjects.eq_URI (), 0, []);
740 S.lift 1 eq_ty; l; r]
745 CicMkImplicit.identity_relocation_list_for_metavariable context in
746 C.Meta (!maxmeta, irl)
751 if pos = Utils.Left then [ty; what; other]
752 else [ty; other; what]
754 Inference.ProofSymBlock (termlist, proof')
757 if pos = Utils.Left then what, other else other, what
759 pos, (0, proof', (ty, other, what, Utils.Incomparable), menv', args')
763 Inference.ProofBlock (s, eq_URI, (name, ty), bo'', eq_found,
764 Inference.BasicProof metaproof)
767 | Inference.BasicProof _ ->
768 debug_print (lazy "replacing a BasicProof");
770 | Inference.ProofGoalBlock (_, parent_proof) ->
771 debug_print (lazy "replacing another ProofGoalBlock");
772 Inference.ProofGoalBlock (pb, parent_proof)
776 C.Appl [C.MutConstruct (* reflexivity *)
777 (LibraryObjects.eq_URI (), 0, 1, []);
778 eq_ty; if ordering = U.Gt then right else left]
781 Inference.ProofGoalBlock (Inference.BasicProof refl, target_proof))
784 if ordering = U.Gt then newgoal, right else left, newgoal in
785 let neworder = !Utils.compare_terms left right in
787 let time2 = Unix.gettimeofday () in
788 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
791 let w = Utils.compute_equality_weight eq_ty left right in
792 (w, newproof, (eq_ty, left, right, neworder), [], [])
796 !maxmeta, List.map build_new expansions
800 let sup_r_counter = ref 1;;
804 returns a list of new clauses inferred with a right superposition step
805 between the positive equation "target" and one in the "table" "newmeta" is
806 the first free meta index, i.e. the first number above the highest meta
807 index: its updated value is also returned
809 let superposition_right newmeta (metasenv, context, ugraph) table target =
810 let module C = Cic in
811 let module S = CicSubstitution in
812 let module M = CicMetaSubst in
813 let module HL = HelmLibraryObjects in
814 let module CR = CicReduction in
815 let module U = Utils in
816 let _, eqproof, (eq_ty, left, right, ordering), newmetas, args = target in
817 let metasenv' = metasenv @ newmetas in
818 let maxmeta = ref newmeta in
821 | U.Gt -> fst (betaexpand_term metasenv' context ugraph table 0 left), []
822 | U.Lt -> [], fst (betaexpand_term metasenv' context ugraph table 0 right)
826 (fun (_, subst, _, _, _) ->
827 let subst = apply_subst subst in
828 let o = !Utils.compare_terms (subst l) (subst r) in
829 o <> U.Lt && o <> U.Le)
830 (fst (betaexpand_term metasenv' context ugraph table 0 l))
832 (res left right), (res right left)
834 let build_new ordering (bo, s, m, ug, (eq_found, eq_URI)) =
836 let time1 = Unix.gettimeofday () in
838 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
839 let what, other = if pos = Utils.Left then what, other else other, what in
840 let newgoal, newproof =
841 let bo' = apply_subst s (S.subst other bo) in
843 let name = C.Name ("x_SupR_" ^ (string_of_int !sup_r_counter)) in
846 if ordering = U.Gt then bo, S.lift 1 right else S.lift 1 left, bo in
847 (name, ty, S.lift 1 eq_ty, l, r)
849 let name = C.Name ("x_SupR_" ^ (string_of_int !sup_r_counter)) in
853 if ordering = U.Gt then bo, S.lift 1 right else S.lift 1 left, bo in
854 C.Appl [C.MutInd (LibraryObjects.eq_URI (), 0, []);
855 S.lift 1 eq_ty; l; r]
858 Inference.ProofBlock (s, eq_URI, (name, ty), bo'', eq_found, eqproof)
860 let newmeta, newequality =
862 if ordering = U.Gt then newgoal, apply_subst s right
863 else apply_subst s left, newgoal in
864 let neworder = !Utils.compare_terms left right
865 and newmenv = newmetas @ menv'
866 and newargs = args @ args' in
868 let w = Utils.compute_equality_weight eq_ty left right in
869 (w, newproof, (eq_ty, left, right, neworder), newmenv, newargs)
870 and env = (metasenv, context, ugraph) in
871 let newm, eq' = Inference.fix_metas !maxmeta eq' in
876 let time2 = Unix.gettimeofday () in
877 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
881 let new1 = List.map (build_new U.Gt) res1
882 and new2 = List.map (build_new U.Lt) res2 in
883 let ok e = not (Inference.is_identity (metasenv, context, ugraph) e) in
885 (List.filter ok (new1 @ new2)))
889 (** demodulation, when the target is a goal *)
890 let rec demodulation_goal newmeta env table goal =
891 let module C = Cic in
892 let module S = CicSubstitution in
893 let module M = CicMetaSubst in
894 let module HL = HelmLibraryObjects in
895 let metasenv, context, ugraph = env in
896 let maxmeta = ref newmeta in
897 let proof, metas, term = goal in
898 let metasenv' = metasenv @ metas in
900 let build_newgoal (t, subst, menv, ug, (eq_found, eq_URI)) =
901 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
902 let what, other = if pos = Utils.Left then what, other else other, what in
904 try fst (CicTypeChecker.type_of_aux' metasenv context what ugraph)
905 with CicUtil.Meta_not_found _ -> ty
907 let newterm, newproof =
908 let bo = apply_subst subst (S.subst other t) in
909 let bo' = apply_subst subst t in
910 let name = C.Name ("x_DemodGoal_" ^ (string_of_int !demod_counter)) in
915 CicMkImplicit.identity_relocation_list_for_metavariable context in
916 debug_print (lazy (Printf.sprintf "\nADDING META: %d\n" !maxmeta));
917 C.Meta (!maxmeta, irl)
922 if pos = Utils.Left then [ty; what; other]
923 else [ty; other; what]
925 Inference.ProofSymBlock (termlist, proof')
928 if pos = Utils.Left then what, other else other, what
930 pos, (0, proof', (ty, other, what, Utils.Incomparable), menv', args')
934 Inference.ProofBlock (subst, eq_URI, (name, ty), bo',
935 eq_found, Inference.BasicProof metaproof)
937 let rec repl = function
938 | Inference.NoProof ->
939 debug_print (lazy "replacing a NoProof");
941 | Inference.BasicProof _ ->
942 debug_print (lazy "replacing a BasicProof");
944 | Inference.ProofGoalBlock (_, parent_proof) ->
945 debug_print (lazy "replacing another ProofGoalBlock");
946 Inference.ProofGoalBlock (pb, parent_proof)
947 | (Inference.SubProof (term, meta_index, p) as subproof) ->
950 (Printf.sprintf "replacing %s"
951 (Inference.string_of_proof subproof)));
952 Inference.SubProof (term, meta_index, repl p)
956 bo, Inference.ProofGoalBlock (Inference.NoProof, goal_proof)
958 let m = Inference.metas_of_term newterm in
959 let newmetasenv = List.filter (fun (i, _, _) -> List.mem i m) metas in
960 !maxmeta, (newproof, newmetasenv, newterm)
963 demodulation_aux ~typecheck:true metasenv' context ugraph table 0 term
967 let newmeta, newgoal = build_newgoal t in
968 let _, _, newg = newgoal in
969 if Inference.meta_convertibility term newg then
972 demodulation_goal newmeta env table newgoal
978 (** demodulation, when the target is a theorem *)
979 let rec demodulation_theorem newmeta env table theorem =
980 let module C = Cic in
981 let module S = CicSubstitution in
982 let module M = CicMetaSubst in
983 let module HL = HelmLibraryObjects in
984 let metasenv, context, ugraph = env in
985 let maxmeta = ref newmeta in
986 let proof, metas, term = theorem in
987 let term, termty, metas = theorem in
988 let metasenv' = metasenv @ metas in
990 let build_newtheorem (t, subst, menv, ug, (eq_found, eq_URI)) =
991 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
992 let what, other = if pos = Utils.Left then what, other else other, what in
994 let bo = apply_subst subst (S.subst other t) in
995 let bo' = apply_subst subst t in
996 let name = C.Name ("x_DemodThm_" ^ (string_of_int !demod_counter)) in
999 Inference.ProofBlock (subst, eq_URI, (name, ty), bo', eq_found,
1000 Inference.BasicProof term)
1002 (Inference.build_proof_term newproof, bo)
1004 let m = Inference.metas_of_term newterm in
1005 let newmetasenv = List.filter (fun (i, _, _) -> List.mem i m) metas in
1006 !maxmeta, (newterm, newty, newmetasenv)
1009 demodulation_aux ~typecheck:true metasenv' context ugraph table 0 termty
1013 let newmeta, newthm = build_newtheorem t in
1014 let newt, newty, _ = newthm in
1015 if Inference.meta_convertibility termty newty then
1018 demodulation_theorem newmeta env table newthm