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/.
28 module Index = Equality_indexing.DT (* discrimination tree based indexing *)
30 module Index = Equality_indexing.DT (* path tree based indexing *)
33 let debug_print = Utils.debug_print;;
36 type retrieval_mode = Matching | Unification;;
38 let print_candidates mode term res =
42 Printf.printf "| candidates Matching %s\n" (CicPp.ppterm term)
44 Printf.printf "| candidates Unification %s\n" (CicPp.ppterm term)
50 Printf.sprintf "| (%s, %s)" (Utils.string_of_pos p)
51 (Inference.string_of_equality e))
57 let indexing_retrieval_time = ref 0.;;
60 let apply_subst = CicMetaSubst.apply_subst
62 let index = Index.index
63 let remove_index = Index.remove_index
64 let in_index = Index.in_index
65 let empty = Index.empty
66 let init_index = Index.init_index
68 (* returns a list of all the equalities in the tree that are in relation
69 "mode" with the given term, where mode can be either Matching or
72 Format of the return value: list of tuples in the form:
73 (position - Left or Right - of the term that matched the given one in this
77 Note that if equality is "left = right", if the ordering is left > right,
78 the position will always be Left, and if the ordering is left < right,
79 position will be Right.
81 let get_candidates mode tree term =
82 let t1 = Unix.gettimeofday () in
86 | Matching -> Index.retrieve_generalizations tree term
87 | Unification -> Index.retrieve_unifiables tree term
89 Index.PosEqSet.elements s
91 (* print_candidates mode term res; *)
92 (* print_endline (Discrimination_tree.string_of_discrimination_tree tree); *)
93 (* print_newline (); *)
94 let t2 = Unix.gettimeofday () in
95 indexing_retrieval_time := !indexing_retrieval_time +. (t2 -. t1);
100 let match_unif_time_ok = ref 0.;;
101 let match_unif_time_no = ref 0.;;
105 finds the first equality in the index that matches "term", of type "termty"
106 termty can be Implicit if it is not needed. The result (one of the sides of
107 the equality, actually) should be not greater (wrt the term ordering) than
110 Format of the return value:
112 (term to substitute, [Cic.Rel 1 properly lifted - see the various
113 build_newtarget functions inside the various
114 demodulation_* functions]
115 substitution used for the matching,
117 ugraph, [substitution, metasenv and ugraph have the same meaning as those
118 returned by CicUnification.fo_unif]
119 (equality where the matching term was found, [i.e. the equality to use as
121 uri [either eq_ind_URI or eq_ind_r_URI, depending on the direction of
122 the equality: this is used to build the proof term, again see one of
123 the build_newtarget functions]
126 let rec find_matches metasenv context ugraph lift_amount term termty =
127 let module C = Cic in
128 let module U = Utils in
129 let module S = CicSubstitution in
130 let module M = CicMetaSubst in
131 let module HL = HelmLibraryObjects in
132 let cmp = !Utils.compare_terms in
133 let check = match termty with C.Implicit None -> false | _ -> true in
137 let pos, (_, proof, (ty, left, right, o), metas, args) = candidate in
138 if check && not (fst (CicReduction.are_convertible
139 ~metasenv context termty ty ugraph)) then (
140 find_matches metasenv context ugraph lift_amount term termty tl
142 let do_match c eq_URI =
143 let subst', metasenv', ugraph' =
144 let t1 = Unix.gettimeofday () in
147 Inference.matching (metasenv @ metas) context
148 term (S.lift lift_amount c) ugraph in
149 let t2 = Unix.gettimeofday () in
150 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
152 with Inference.MatchingFailure as e ->
153 let t2 = Unix.gettimeofday () in
154 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
157 Some (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
160 let c, other, eq_URI =
161 if pos = Utils.Left then left, right, Utils.eq_ind_URI ()
162 else right, left, Utils.eq_ind_r_URI ()
164 if o <> U.Incomparable then
167 with Inference.MatchingFailure ->
168 find_matches metasenv context ugraph lift_amount term termty tl
171 try do_match c eq_URI
172 with Inference.MatchingFailure -> None
175 | Some (_, s, _, _, _) ->
176 let c' = apply_subst s c in
177 let other' = U.guarded_simpl context (apply_subst s other) in
178 let order = cmp c' other' in
179 let names = U.names_of_context context in
184 metasenv context ugraph lift_amount term termty tl
186 find_matches metasenv context ugraph lift_amount term termty tl
191 as above, but finds all the matching equalities, and the matching condition
192 can be either Inference.matching or Inference.unification
194 let rec find_all_matches ?(unif_fun=Inference.unification)
195 metasenv context ugraph lift_amount term termty =
196 let module C = Cic in
197 let module U = Utils in
198 let module S = CicSubstitution in
199 let module M = CicMetaSubst in
200 let module HL = HelmLibraryObjects in
201 let cmp = !Utils.compare_terms in
205 let pos, (_, _, (ty, left, right, o), metas, args) = candidate in
206 let do_match c 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 | Inference.MatchingFailure
218 | CicUnification.UnificationFailure _
219 | CicUnification.Uncertain _ as e ->
220 let t2 = Unix.gettimeofday () in
221 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
224 (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
227 let c, other, eq_URI =
228 if pos = Utils.Left then left, right, Utils.eq_ind_URI ()
229 else right, left, Utils.eq_ind_r_URI ()
231 if o <> U.Incomparable then
233 let res = do_match c eq_URI in
234 res::(find_all_matches ~unif_fun metasenv context ugraph
235 lift_amount term termty tl)
237 | Inference.MatchingFailure
238 | CicUnification.UnificationFailure _
239 | CicUnification.Uncertain _ ->
240 find_all_matches ~unif_fun metasenv context ugraph
241 lift_amount term termty tl
244 let res = do_match c eq_URI in
247 let c' = apply_subst s c
248 and other' = apply_subst s other in
249 let order = cmp c' other' in
250 let names = U.names_of_context context in
251 if order <> U.Lt && order <> U.Le then
252 res::(find_all_matches ~unif_fun metasenv context ugraph
253 lift_amount term termty tl)
255 find_all_matches ~unif_fun metasenv context ugraph
256 lift_amount term termty tl
258 | Inference.MatchingFailure
259 | CicUnification.UnificationFailure _
260 | CicUnification.Uncertain _ ->
261 find_all_matches ~unif_fun metasenv context ugraph
262 lift_amount term termty tl
267 returns true if target is subsumed by some equality in table
269 let subsumption env table target =
270 let _, _, (ty, left, right, _), tmetas, _ = target in
271 let metasenv, context, ugraph = env in
272 let metasenv = metasenv @ tmetas in
273 let samesubst subst subst' =
274 let tbl = Hashtbl.create (List.length subst) in
275 List.iter (fun (m, (c, t1, t2)) -> Hashtbl.add tbl m (c, t1, t2)) subst;
277 (fun (m, (c, t1, t2)) ->
279 let c', t1', t2' = Hashtbl.find tbl m in
280 if (c = c') && (t1 = t1') && (t2 = t2') then true
290 let leftc = get_candidates Matching table left in
291 find_all_matches ~unif_fun:Inference.matching
292 metasenv context ugraph 0 left ty leftc
294 let rec ok what = function
296 | (_, subst, menv, ug, ((pos, (_, _, (_, l, r, o), m, _)), _))::tl ->
298 let other = if pos = Utils.Left then r else l in
299 let subst', menv', ug' =
300 let t1 = Unix.gettimeofday () in
303 Inference.matching (metasenv @ menv @ m) context what other ugraph
305 let t2 = Unix.gettimeofday () in
306 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
308 with Inference.MatchingFailure as e ->
309 let t2 = Unix.gettimeofday () in
310 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
313 if samesubst subst subst' then
317 with Inference.MatchingFailure ->
320 let r, subst = ok right leftr in
329 let rightc = get_candidates Matching table right in
330 find_all_matches ~unif_fun:Inference.matching
331 metasenv context ugraph 0 right ty rightc
338 (* (Printf.sprintf "SUBSUMPTION! %s\n%s\n" *)
339 (* (Inference.string_of_equality target) (Utils.print_subst s)))); *)
344 let rec demodulation_aux ?(typecheck=false)
345 metasenv context ugraph table lift_amount term =
346 let module C = Cic in
347 let module S = CicSubstitution in
348 let module M = CicMetaSubst in
349 let module HL = HelmLibraryObjects in
350 let candidates = get_candidates Matching table term in
356 CicTypeChecker.type_of_aux' metasenv context term ugraph
358 C.Implicit None, ugraph
361 find_matches metasenv context ugraph lift_amount term termty candidates
372 (res, tl @ [S.lift 1 t])
375 demodulation_aux metasenv context ugraph table
379 | None -> (None, tl @ [S.lift 1 t])
380 | Some (rel, _, _, _, _) -> (r, tl @ [rel]))
385 | Some (_, subst, menv, ug, eq_found) ->
386 Some (C.Appl ll, subst, menv, ug, eq_found)
388 | C.Prod (nn, s, t) ->
390 demodulation_aux metasenv context ugraph table lift_amount s in (
394 demodulation_aux metasenv
395 ((Some (nn, C.Decl s))::context) ugraph
396 table (lift_amount+1) t
400 | Some (t', subst, menv, ug, eq_found) ->
401 Some (C.Prod (nn, (S.lift 1 s), t'),
402 subst, menv, ug, eq_found)
404 | Some (s', subst, menv, ug, eq_found) ->
405 Some (C.Prod (nn, s', (S.lift 1 t)),
406 subst, menv, ug, eq_found)
408 | C.Lambda (nn, s, t) ->
410 demodulation_aux metasenv context ugraph table lift_amount s in (
414 demodulation_aux metasenv
415 ((Some (nn, C.Decl s))::context) ugraph
416 table (lift_amount+1) t
420 | Some (t', subst, menv, ug, eq_found) ->
421 Some (C.Lambda (nn, (S.lift 1 s), t'),
422 subst, menv, ug, eq_found)
424 | Some (s', subst, menv, ug, eq_found) ->
425 Some (C.Lambda (nn, s', (S.lift 1 t)),
426 subst, menv, ug, eq_found)
433 let build_newtarget_time = ref 0.;;
436 let demod_counter = ref 1;;
438 (** demodulation, when target is an equality *)
439 let rec demodulation_equality newmeta env table sign target =
440 let module C = Cic in
441 let module S = CicSubstitution in
442 let module M = CicMetaSubst in
443 let module HL = HelmLibraryObjects in
444 let module U = Utils in
445 let metasenv, context, ugraph = env in
446 let _, proof, (eq_ty, left, right, order), metas, args = target in
447 let metasenv' = metasenv @ metas in
449 let maxmeta = ref newmeta in
451 let build_newtarget is_left (t, subst, menv, ug, (eq_found, eq_URI)) =
452 let time1 = Unix.gettimeofday () in
454 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
456 try fst (CicTypeChecker.type_of_aux' metasenv context what ugraph)
457 with CicUtil.Meta_not_found _ -> ty
459 let what, other = if pos = Utils.Left then what, other else other, what in
460 let newterm, newproof =
461 let bo = U.guarded_simpl context (apply_subst subst (S.subst other t)) in
462 let name = C.Name ("x_Demod_" ^ (string_of_int !demod_counter)) in
465 let l, r = if is_left then t, S.lift 1 right else S.lift 1 left, t in
466 C.Appl [C.MutInd (LibraryObjects.eq_URI (), 0, []);
467 S.lift 1 eq_ty; l; r]
469 if sign = Utils.Positive then
471 Inference.ProofBlock (
472 subst, eq_URI, (name, ty), bo'(* t' *), eq_found, proof))
477 CicMkImplicit.identity_relocation_list_for_metavariable context in
478 (* debug_print (lazy (Printf.sprintf "\nADDING META: %d\n" !maxmeta)); *)
479 (* print_newline (); *)
480 C.Meta (!maxmeta, irl)
485 if pos = Utils.Left then [ty; what; other]
486 else [ty; other; what]
488 Inference.ProofSymBlock (termlist, proof')
491 if pos = Utils.Left then what, other else other, what
493 pos, (0, proof', (ty, other, what, Utils.Incomparable),
498 Inference.ProofBlock (subst, eq_URI, (name, ty), bo',
499 eq_found, Inference.BasicProof metaproof)
502 | Inference.BasicProof _ ->
503 print_endline "replacing a BasicProof";
505 | Inference.ProofGoalBlock (_, parent_proof) ->
506 print_endline "replacing another ProofGoalBlock";
507 Inference.ProofGoalBlock (pb, parent_proof)
511 C.Appl [C.MutConstruct (* reflexivity *)
512 (LibraryObjects.eq_URI (), 0, 1, []);
513 eq_ty; if is_left then right else left]
516 Inference.ProofGoalBlock (Inference.BasicProof refl, target_proof))
518 let left, right = if is_left then newterm, right else left, newterm in
519 let m = (Inference.metas_of_term left) @ (Inference.metas_of_term right) in
520 let newmetasenv = List.filter (fun (i, _, _) -> List.mem i m) metas
523 let ordering = !Utils.compare_terms left right in
525 let time2 = Unix.gettimeofday () in
526 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
529 let w = Utils.compute_equality_weight eq_ty left right in
530 (w, newproof, (eq_ty, left, right, ordering), newmetasenv, newargs)
534 let res = demodulation_aux metasenv' context ugraph table 0 left in
535 let newmeta, newtarget =
538 let newmeta, newtarget = build_newtarget true t in
539 if (Inference.is_identity (metasenv', context, ugraph) newtarget) ||
540 (Inference.meta_convertibility_eq target newtarget) then
543 demodulation_equality newmeta env table sign newtarget
545 let res = demodulation_aux metasenv' context ugraph table 0 right in
548 let newmeta, newtarget = build_newtarget false t in
549 if (Inference.is_identity (metasenv', context, ugraph) newtarget) ||
550 (Inference.meta_convertibility_eq target newtarget) then
553 demodulation_equality newmeta env table sign newtarget
557 (* newmeta, newtarget *)
558 (* tentiamo di ridurre usando CicReduction.normalize *)
559 let w, p, (ty, left, right, o), m, a = newtarget in
560 let left' = ProofEngineReduction.simpl context left in
561 let right' = ProofEngineReduction.simpl context right in
563 if !Utils.compare_terms left' left = Utils.Lt then left' else left in
565 if !Utils.compare_terms right' right = Utils.Lt then right' else right in
566 (* if newleft != left || newright != right then ( *)
569 (* (Printf.sprintf "left: %s, left': %s\nright: %s, right': %s\n" *)
570 (* (CicPp.ppterm left) (CicPp.ppterm left') (CicPp.ppterm right) *)
571 (* (CicPp.ppterm right'))) *)
573 let w' = Utils.compute_equality_weight ty newleft newright in
574 let o' = !Utils.compare_terms newleft newright in
575 newmeta, (w', p, (ty, newleft, newright, o'), m, a)
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' = U.guarded_simpl context (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