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 beta_expand_time = ref 0.;;
35 let debug_print = Utils.debug_print;;
39 let check_equation env equation msg =
40 let w, proof, (eq_ty, left, right, order), metas, args = equation in
41 let metasenv, context, ugraph = env
42 let metasenv' = metasenv @ metas in
44 CicTypeChecker.type_of_aux' metasenv' context left ugraph;
45 CicTypeChecker.type_of_aux' metasenv' context right ugraph;
48 CicUtil.Meta_not_found _ as exn ->
51 prerr_endline (CicPp.ppterm left);
52 prerr_endline (CicPp.ppterm right);
57 type retrieval_mode = Matching | Unification;;
59 let string_of_res ?env =
62 | Some (t, s, m, u, ((p,e), eq_URI)) ->
63 Printf.sprintf "Some: (%s, %s, %s)"
64 (Utils.string_of_pos p)
65 (Inference.string_of_equality ?env e)
69 let print_res ?env res =
72 (List.map (string_of_res ?env) res))
75 let print_candidates ?env mode term res =
79 prerr_endline ("| candidates Matching " ^ (CicPp.ppterm term))
81 prerr_endline ("| candidates Unification " ^ (CicPp.ppterm term))
87 Printf.sprintf "| (%s, %s)" (Utils.string_of_pos p)
88 (Inference.string_of_equality ?env e))
93 let indexing_retrieval_time = ref 0.;;
96 let apply_subst = CicMetaSubst.apply_subst
98 let index = Index.index
99 let remove_index = Index.remove_index
100 let in_index = Index.in_index
101 let empty = Index.empty
102 let init_index = Index.init_index
104 let check_disjoint_invariant subst metasenv msg =
106 (fun (i,_,_) -> (List.exists (fun (j,_) -> i=j) subst)) metasenv)
109 prerr_endline ("not disjoint: " ^ msg);
114 let check_for_duplicates metas msg =
117 ignore(CicUtil.lookup_meta 190 metas);
118 prerr_endline ("eccoci in " ^ msg);
120 CicUtil.Meta_not_found _ -> () in
121 if List.length metas <>
122 List.length (HExtlib.list_uniq (List.sort Pervasives.compare metas)) then
124 prerr_endline ("DUPLICATI " ^ msg);
125 prerr_endline (CicMetaSubst.ppmetasenv [] metas);
130 let check_res res msg =
132 Some (t, subst, menv, ug, (eq_found, eq_URI)) ->
133 let eqs = Inference.string_of_equality (snd eq_found) in
134 check_disjoint_invariant subst menv msg;
135 check_for_duplicates menv (msg ^ "\nchecking " ^ eqs);
139 let check_target context target msg =
140 let w, proof, (eq_ty, left, right, order), metas, args = target in
141 (* check that metas does not contains duplicates *)
142 let eqs = Inference.string_of_equality target in
143 let _ = check_for_duplicates metas (msg ^ "\nchecking " ^ eqs) in
144 let actual = (Inference.metas_of_term left)@(Inference.metas_of_term right)
145 @(Inference.metas_of_term eq_ty)@(Inference.metas_of_proof proof) in
146 let menv = List.filter (fun (i, _, _) -> List.mem i actual) metas in
147 let _ = if menv <> metas then
149 prerr_endline ("extra metas " ^ msg);
150 prerr_endline (CicMetaSubst.ppmetasenv [] metas);
151 prerr_endline "**********************";
152 prerr_endline (CicMetaSubst.ppmetasenv [] menv);
153 prerr_endline ("left: " ^ (CicPp.ppterm left));
154 prerr_endline ("right: " ^ (CicPp.ppterm right));
155 prerr_endline ("ty: " ^ (CicPp.ppterm eq_ty));
160 CicTypeChecker.type_of_aux'
161 metas context (Inference.build_proof_term proof) CicUniv.empty_ugraph
164 prerr_endline (Inference.string_of_proof proof);
165 prerr_endline (CicPp.ppterm (Inference.build_proof_term proof));
166 prerr_endline ("+++++++++++++left: " ^ (CicPp.ppterm left));
167 prerr_endline ("+++++++++++++right: " ^ (CicPp.ppterm right));
172 (* returns a list of all the equalities in the tree that are in relation
173 "mode" with the given term, where mode can be either Matching or
176 Format of the return value: list of tuples in the form:
177 (position - Left or Right - of the term that matched the given one in this
181 Note that if equality is "left = right", if the ordering is left > right,
182 the position will always be Left, and if the ordering is left < right,
183 position will be Right.
185 let local_max = ref 100;;
187 let make_variant (p,eq) =
188 let maxmeta, eq = Inference.fix_metas !local_max eq in
189 local_max := maxmeta;
193 let get_candidates ?env mode tree term =
194 let t1 = Unix.gettimeofday () in
198 | Matching -> Index.retrieve_generalizations tree term
199 | Unification -> Index.retrieve_unifiables tree term
201 Index.PosEqSet.elements s
203 (* print_endline (Discrimination_tree.string_of_discrimination_tree tree); *)
204 (* print_newline (); *)
205 let t2 = Unix.gettimeofday () in
206 indexing_retrieval_time := !indexing_retrieval_time +. (t2 -. t1);
207 (* make fresh instances *)
212 let match_unif_time_ok = ref 0.;;
213 let match_unif_time_no = ref 0.;;
217 finds the first equality in the index that matches "term", of type "termty"
218 termty can be Implicit if it is not needed. The result (one of the sides of
219 the equality, actually) should be not greater (wrt the term ordering) than
222 Format of the return value:
224 (term to substitute, [Cic.Rel 1 properly lifted - see the various
225 build_newtarget functions inside the various
226 demodulation_* functions]
227 substitution used for the matching,
229 ugraph, [substitution, metasenv and ugraph have the same meaning as those
230 returned by CicUnification.fo_unif]
231 (equality where the matching term was found, [i.e. the equality to use as
233 uri [either eq_ind_URI or eq_ind_r_URI, depending on the direction of
234 the equality: this is used to build the proof term, again see one of
235 the build_newtarget functions]
238 let rec find_matches metasenv context ugraph lift_amount term termty =
239 let module C = Cic in
240 let module U = Utils in
241 let module S = CicSubstitution in
242 let module M = CicMetaSubst in
243 let module HL = HelmLibraryObjects in
244 let cmp = !Utils.compare_terms in
245 let check = match termty with C.Implicit None -> false | _ -> true in
249 let pos, (_, proof, (ty, left, right, o), metas, args) = candidate in
250 if Utils.debug_metas then
251 ignore(check_target context (snd candidate) "find_matches");
252 if Utils.debug_res then
254 let c = "eq = " ^ (Inference.string_of_equality (snd candidate)) ^ "\n"in
255 let t = "t = " ^ (CicPp.ppterm term) ^ "\n" in
256 let m = "metas = " ^ (CicMetaSubst.ppmetasenv [] metas) ^ "\n" in
257 let p = "proof = " ^ (CicPp.ppterm (Inference.build_proof_term proof)) ^ "\n" in
258 check_for_duplicates metas "gia nella metas";
259 check_for_duplicates (metasenv @ metas) ("not disjoint" ^ c ^ t ^ m ^ p)
261 if check && not (fst (CicReduction.are_convertible
262 ~metasenv context termty ty ugraph)) then (
263 find_matches metasenv context ugraph lift_amount term termty tl
265 let do_match c eq_URI =
266 let subst', metasenv', ugraph' =
267 let t1 = Unix.gettimeofday () in
270 ( Inference.matching metasenv metas context
271 term (S.lift lift_amount c)) ugraph
273 let t2 = Unix.gettimeofday () in
274 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
277 | Inference.MatchingFailure as e ->
278 let t2 = Unix.gettimeofday () in
279 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
281 | CicUtil.Meta_not_found _ as exn -> raise exn
283 Some (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
286 let c, other, eq_URI =
287 if pos = Utils.Left then left, right, Utils.eq_ind_URI ()
288 else right, left, Utils.eq_ind_r_URI ()
290 if o <> U.Incomparable then
294 with Inference.MatchingFailure ->
295 find_matches metasenv context ugraph lift_amount term termty tl
297 if Utils.debug_res then ignore (check_res res "find1");
301 try do_match c eq_URI
302 with Inference.MatchingFailure -> None
304 if Utils.debug_res then ignore (check_res res "find2");
306 | Some (_, s, _, _, _) ->
307 let c' = apply_subst s c in
309 let other' = U.guarded_simpl context (apply_subst s other) in *)
310 let other' = apply_subst s other in
311 let order = cmp c' other' in
316 metasenv context ugraph lift_amount term termty tl
318 find_matches metasenv context ugraph lift_amount term termty tl
323 as above, but finds all the matching equalities, and the matching condition
324 can be either Inference.matching or Inference.unification
326 let rec find_all_matches ?(unif_fun=Inference.unification)
327 metasenv context ugraph lift_amount term termty =
328 let module C = Cic in
329 let module U = Utils in
330 let module S = CicSubstitution in
331 let module M = CicMetaSubst in
332 let module HL = HelmLibraryObjects in
333 let cmp = !Utils.compare_terms in
337 let pos, (_, _, (ty, left, right, o), metas, args) = candidate in
338 let do_match c eq_URI =
339 let subst', metasenv', ugraph' =
340 let t1 = Unix.gettimeofday () in
343 unif_fun metasenv metas context
344 term (S.lift lift_amount c) ugraph in
345 let t2 = Unix.gettimeofday () in
346 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
349 | Inference.MatchingFailure
350 | CicUnification.UnificationFailure _
351 | CicUnification.Uncertain _ as e ->
352 let t2 = Unix.gettimeofday () in
353 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
356 (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
359 let c, other, eq_URI =
360 if pos = Utils.Left then left, right, Utils.eq_ind_URI ()
361 else right, left, Utils.eq_ind_r_URI ()
363 if o <> U.Incomparable then
365 let res = do_match c eq_URI in
366 res::(find_all_matches ~unif_fun metasenv context ugraph
367 lift_amount term termty tl)
369 | Inference.MatchingFailure
370 | CicUnification.UnificationFailure _
371 | CicUnification.Uncertain _ ->
372 find_all_matches ~unif_fun metasenv context ugraph
373 lift_amount term termty tl
376 let res = do_match c eq_URI in
379 let c' = apply_subst s c
380 and other' = apply_subst s other in
381 let order = cmp c' other' in
382 if order <> U.Lt && order <> U.Le then
383 res::(find_all_matches ~unif_fun metasenv context ugraph
384 lift_amount term termty tl)
386 find_all_matches ~unif_fun metasenv context ugraph
387 lift_amount term termty tl
389 | Inference.MatchingFailure
390 | CicUnification.UnificationFailure _
391 | CicUnification.Uncertain _ ->
392 find_all_matches ~unif_fun metasenv context ugraph
393 lift_amount term termty tl
398 returns true if target is subsumed by some equality in table
400 let subsumption env table target =
401 let _, _, (ty, left, right, _), tmetas, _ = target in
402 let metasenv, context, ugraph = env in
403 let metasenv = metasenv @ tmetas in
404 let samesubst subst subst' =
405 let tbl = Hashtbl.create (List.length subst) in
406 List.iter (fun (m, (c, t1, t2)) -> Hashtbl.add tbl m (c, t1, t2)) subst;
408 (fun (m, (c, t1, t2)) ->
410 let c', t1', t2' = Hashtbl.find tbl m in
411 if (c = c') && (t1 = t1') && (t2 = t2') then true
421 let leftc = get_candidates Matching table left in
422 find_all_matches ~unif_fun:Inference.matching
423 metasenv context ugraph 0 left ty leftc
425 let rec ok what = function
427 | (_, subst, menv, ug, ((pos, (_, _, (_, l, r, o), m, _)), _))::tl ->
429 let other = if pos = Utils.Left then r else l in
430 let subst', menv', ug' =
431 let t1 = Unix.gettimeofday () in
434 Inference.matching menv m context what other ugraph
436 let t2 = Unix.gettimeofday () in
437 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
439 with Inference.MatchingFailure as e ->
440 let t2 = Unix.gettimeofday () in
441 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
444 if samesubst subst subst' then
448 with Inference.MatchingFailure ->
451 let r, subst = ok right leftr in
460 let rightc = get_candidates Matching table right in
461 find_all_matches ~unif_fun:Inference.matching
462 metasenv context ugraph 0 right ty rightc
469 (* (Printf.sprintf "SUBSUMPTION! %s\n%s\n" *)
470 (* (Inference.string_of_equality target) (Utils.print_subst s)))); *)
474 let rec demodulation_aux ?from ?(typecheck=false)
475 metasenv context ugraph table lift_amount term =
476 (* Printf.eprintf "term = %s\n" (CicPp.ppterm term); *)
477 let module C = Cic in
478 let module S = CicSubstitution in
479 let module M = CicMetaSubst in
480 let module HL = HelmLibraryObjects in
482 get_candidates ~env:(metasenv,context,ugraph) Matching table term in
483 (* let candidates = List.map make_variant candidates in *)
490 CicTypeChecker.type_of_aux' metasenv context term ugraph
492 C.Implicit None, ugraph
495 find_matches metasenv context ugraph lift_amount term termty candidates
497 if Utils.debug_res then ignore(check_res res "demod1");
507 (res, tl @ [S.lift 1 t])
510 demodulation_aux ~from:"1" metasenv context ugraph table
514 | None -> (None, tl @ [S.lift 1 t])
515 | Some (rel, _, _, _, _) -> (r, tl @ [rel]))
520 | Some (_, subst, menv, ug, eq_found) ->
521 Some (C.Appl ll, subst, menv, ug, eq_found)
523 | C.Prod (nn, s, t) ->
525 demodulation_aux ~from:"2"
526 metasenv context ugraph table lift_amount s in (
530 demodulation_aux metasenv
531 ((Some (nn, C.Decl s))::context) ugraph
532 table (lift_amount+1) t
536 | Some (t', subst, menv, ug, eq_found) ->
537 Some (C.Prod (nn, (S.lift 1 s), t'),
538 subst, menv, ug, eq_found)
540 | Some (s', subst, menv, ug, eq_found) ->
541 Some (C.Prod (nn, s', (S.lift 1 t)),
542 subst, menv, ug, eq_found)
544 | C.Lambda (nn, s, t) ->
547 metasenv context ugraph table lift_amount s in (
551 demodulation_aux metasenv
552 ((Some (nn, C.Decl s))::context) ugraph
553 table (lift_amount+1) t
557 | Some (t', subst, menv, ug, eq_found) ->
558 Some (C.Lambda (nn, (S.lift 1 s), t'),
559 subst, menv, ug, eq_found)
561 | Some (s', subst, menv, ug, eq_found) ->
562 Some (C.Lambda (nn, s', (S.lift 1 t)),
563 subst, menv, ug, eq_found)
568 if Utils.debug_res then ignore(check_res res "demod_aux output");
573 let build_newtarget_time = ref 0.;;
576 let demod_counter = ref 1;;
580 (** demodulation, when target is an equality *)
581 let rec demodulation_equality ?from newmeta env table sign target =
582 let module C = Cic in
583 let module S = CicSubstitution in
584 let module M = CicMetaSubst in
585 let module HL = HelmLibraryObjects in
586 let module U = Utils in
587 let metasenv, context, ugraph = env in
588 let w, proof, (eq_ty, left, right, order), metas, args = target in
589 (* first, we simplify *)
590 let right = U.guarded_simpl context right in
591 let left = U.guarded_simpl context left in
592 let order = !Utils.compare_terms left right in
593 let stat = (eq_ty, left, right, order) in
594 let w = Utils.compute_equality_weight stat in
595 let target = w, proof, stat, metas, args in
596 if Utils.debug_metas then
597 ignore(check_target context target "demod equalities input");
598 let metasenv' = (* metasenv @ *) metas in
599 let maxmeta = ref newmeta in
601 let build_newtarget is_left (t, subst, menv, ug, (eq_found, eq_URI)) =
602 let time1 = Unix.gettimeofday () in
604 if Utils.debug_metas then
606 ignore(check_for_duplicates menv "input1");
607 ignore(check_disjoint_invariant subst menv "input2");
608 let substs = CicMetaSubst.ppsubst subst in
609 ignore(check_target context (snd eq_found) ("input3" ^ substs))
611 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
613 try fst (CicTypeChecker.type_of_aux' metasenv context what ugraph)
614 with CicUtil.Meta_not_found _ -> ty
616 let what, other = if pos = Utils.Left then what, other else other, what in
617 let newterm, newproof =
618 let bo = Utils.guarded_simpl context (apply_subst subst (S.subst other t)) in
619 let name = C.Name ("x_Demod" ^ (string_of_int !demod_counter)) in
622 let l, r = if is_left then t, S.lift 1 right else S.lift 1 left, t in
623 C.Appl [C.MutInd (LibraryObjects.eq_URI (), 0, []);
624 S.lift 1 eq_ty; l; r]
626 if sign = Utils.Positive then
628 Inference.ProofBlock (
629 subst, eq_URI, (name, ty), bo'(* t' *), eq_found, proof))
634 CicMkImplicit.identity_relocation_list_for_metavariable context in
635 (* debug_print (lazy (Printf.sprintf "\nADDING META: %d\n" !maxmeta)); *)
636 (* print_newline (); *)
637 C.Meta (!maxmeta, irl)
642 if pos = Utils.Left then [ty; what; other]
643 else [ty; other; what]
645 Inference.ProofSymBlock (termlist, proof')
648 if pos = Utils.Left then what, other else other, what
650 pos, (0, proof', (ty, other, what, Utils.Incomparable),
655 Inference.ProofBlock (subst, eq_URI, (name, ty), bo',
656 eq_found, Inference.BasicProof metaproof)
659 | Inference.BasicProof _ ->
660 (* print_endline "replacing a BasicProof"; *)
662 | Inference.ProofGoalBlock (_, parent_proof) ->
664 (* print_endline "replacing another ProofGoalBlock"; *)
665 Inference.ProofGoalBlock (pb, parent_proof)
669 C.Appl [C.MutConstruct (* reflexivity *)
670 (LibraryObjects.eq_URI (), 0, 1, []);
671 eq_ty; if is_left then right else left]
674 Inference.ProofGoalBlock (Inference.BasicProof refl, target_proof))
676 let newmenv = (* Inference.filter subst *) menv in
678 if Utils.debug_metas then
679 try ignore(CicTypeChecker.type_of_aux'
680 newmenv context (Inference.build_proof_term newproof) ugraph);
683 prerr_endline "sempre lui";
684 prerr_endline (CicMetaSubst.ppsubst subst);
685 prerr_endline (CicPp.ppterm (Inference.build_proof_term newproof));
686 prerr_endline ("+++++++++++++termine: " ^ (CicPp.ppterm t));
687 prerr_endline ("+++++++++++++what: " ^ (CicPp.ppterm what));
688 prerr_endline ("+++++++++++++other: " ^ (CicPp.ppterm other));
689 prerr_endline ("+++++++++++++subst: " ^ (CicMetaSubst.ppsubst subst));
693 let left, right = if is_left then newterm, right else left, newterm in
694 let ordering = !Utils.compare_terms left right in
695 let stat = (eq_ty, left, right, ordering) in
696 let time2 = Unix.gettimeofday () in
697 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
699 let w = Utils.compute_equality_weight stat in
700 (w, newproof, stat,newmenv,args) in
701 if Utils.debug_metas then
702 ignore(check_target context res "buildnew_target output");
706 let res = demodulation_aux ~from:"3" metasenv' context ugraph table 0 left in
707 if Utils.debug_res then check_res res "demod result";
708 let newmeta, newtarget =
711 let newmeta, newtarget = build_newtarget true t in
712 if (Inference.is_weak_identity (metasenv', context, ugraph) newtarget) ||
713 (Inference.meta_convertibility_eq target newtarget) then
716 demodulation_equality newmeta env table sign newtarget
718 let res = demodulation_aux metasenv' context ugraph table 0 right in
719 if Utils.debug_res then check_res res "demod result 1";
722 let newmeta, newtarget = build_newtarget false t in
723 if (Inference.is_weak_identity (metasenv', context, ugraph) newtarget) ||
724 (Inference.meta_convertibility_eq target newtarget) then
727 demodulation_equality newmeta env table sign newtarget
731 (* newmeta, newtarget *)
737 Performs the beta expansion of the term "term" w.r.t. "table",
738 i.e. returns the list of all the terms t s.t. "(t term) = t2", for some t2
741 let rec betaexpand_term metasenv context ugraph table lift_amount term =
742 let module C = Cic in
743 let module S = CicSubstitution in
744 let module M = CicMetaSubst in
745 let module HL = HelmLibraryObjects in
746 let candidates = get_candidates Unification table term in
748 let res, lifted_term =
753 (fun arg (res, lifted_tl) ->
756 let arg_res, lifted_arg =
757 betaexpand_term metasenv context ugraph table
761 (fun (t, s, m, ug, eq_found) ->
762 (Some t)::lifted_tl, s, m, ug, eq_found)
767 (fun (l, s, m, ug, eq_found) ->
768 (Some lifted_arg)::l, s, m, ug, eq_found)
770 (Some lifted_arg)::lifted_tl)
773 (fun (r, s, m, ug, eq_found) ->
774 None::r, s, m, ug, eq_found) res,
780 (fun (l, s, m, ug, eq_found) ->
781 (C.Meta (i, l), s, m, ug, eq_found)) l'
783 e, C.Meta (i, lifted_l)
786 [], if m <= lift_amount then C.Rel m else C.Rel (m+1)
788 | C.Prod (nn, s, t) ->
790 betaexpand_term metasenv context ugraph table lift_amount s in
792 betaexpand_term metasenv ((Some (nn, C.Decl s))::context) ugraph
793 table (lift_amount+1) t in
796 (fun (t, s, m, ug, eq_found) ->
797 C.Prod (nn, t, lifted_t), s, m, ug, eq_found) l1
800 (fun (t, s, m, ug, eq_found) ->
801 C.Prod (nn, lifted_s, t), s, m, ug, eq_found) l2 in
802 l1' @ l2', C.Prod (nn, lifted_s, lifted_t)
804 | C.Lambda (nn, s, t) ->
806 betaexpand_term metasenv context ugraph table lift_amount s in
808 betaexpand_term metasenv ((Some (nn, C.Decl s))::context) ugraph
809 table (lift_amount+1) t in
812 (fun (t, s, m, ug, eq_found) ->
813 C.Lambda (nn, t, lifted_t), s, m, ug, eq_found) l1
816 (fun (t, s, m, ug, eq_found) ->
817 C.Lambda (nn, lifted_s, t), s, m, ug, eq_found) l2 in
818 l1' @ l2', C.Lambda (nn, lifted_s, lifted_t)
823 (fun arg (res, lifted_tl) ->
824 let arg_res, lifted_arg =
825 betaexpand_term metasenv context ugraph table lift_amount arg
829 (fun (a, s, m, ug, eq_found) ->
830 a::lifted_tl, s, m, ug, eq_found)
835 (fun (r, s, m, ug, eq_found) ->
836 lifted_arg::r, s, m, ug, eq_found)
838 lifted_arg::lifted_tl)
842 (fun (l, s, m, ug, eq_found) -> (C.Appl l, s, m, ug, eq_found)) l',
845 | t -> [], (S.lift lift_amount t)
848 | C.Meta (i, l) -> res, lifted_term
851 C.Implicit None, ugraph
852 (* CicTypeChecker.type_of_aux' metasenv context term ugraph *)
856 metasenv context ugraph lift_amount term termty candidates
862 let sup_l_counter = ref 1;;
866 returns a list of new clauses inferred with a left superposition step
867 the negative equation "target" and one of the positive equations in "table"
869 let superposition_left newmeta (metasenv, context, ugraph) table target =
870 let module C = Cic in
871 let module S = CicSubstitution in
872 let module M = CicMetaSubst in
873 let module HL = HelmLibraryObjects in
874 let module CR = CicReduction in
875 let module U = Utils in
876 let weight, proof, (eq_ty, left, right, ordering), menv, _ = target in
877 if Utils.debug_metas then
878 ignore(check_target context target "superpositionleft");
880 let term = if ordering = U.Gt then left else right in
882 let t1 = Unix.gettimeofday () in
883 let res = betaexpand_term metasenv context ugraph table 0 term in
884 let t2 = Unix.gettimeofday () in
885 beta_expand_time := !beta_expand_time +. (t2 -. t1);
889 let maxmeta = ref newmeta in
890 let build_new (bo, s, m, ug, (eq_found, eq_URI)) =
891 (* debug_print (lazy "\nSUPERPOSITION LEFT\n"); *)
892 let time1 = Unix.gettimeofday () in
894 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
895 let what, other = if pos = Utils.Left then what, other else other, what in
896 let newgoal, newproof =
897 let bo' = U.guarded_simpl context (apply_subst s (S.subst other bo)) in
898 let name = C.Name ("x_SupL_" ^ (string_of_int !sup_l_counter)) in
902 if ordering = U.Gt then bo, S.lift 1 right else S.lift 1 left, bo in
903 C.Appl [C.MutInd (LibraryObjects.eq_URI (), 0, []);
904 S.lift 1 eq_ty; l; r]
909 CicMkImplicit.identity_relocation_list_for_metavariable context in
910 C.Meta (!maxmeta, irl)
915 if pos = Utils.Left then [ty; what; other]
916 else [ty; other; what]
918 Inference.ProofSymBlock (termlist, proof')
921 if pos = Utils.Left then what, other else other, what
923 pos, (0, proof', (ty, other, what, Utils.Incomparable), menv', args')
927 Inference.ProofBlock (s, eq_URI, (name, ty), bo'', eq_found,
928 Inference.BasicProof metaproof)
931 | Inference.BasicProof _ ->
932 (* debug_print (lazy "replacing a BasicProof"); *)
934 | Inference.ProofGoalBlock (_, parent_proof) ->
935 (* debug_print (lazy "replacing another ProofGoalBlock"); *)
936 Inference.ProofGoalBlock (pb, parent_proof)
940 C.Appl [C.MutConstruct (* reflexivity *)
941 (LibraryObjects.eq_URI (), 0, 1, []);
942 eq_ty; if ordering = U.Gt then right else left]
945 Inference.ProofGoalBlock (Inference.BasicProof refl, target_proof))
948 if ordering = U.Gt then newgoal, right else left, newgoal in
949 let neworder = !Utils.compare_terms left right in
950 let stat = (eq_ty, left, right, neworder) in
951 let newmenv = (* Inference.filter s *) menv in
952 let time2 = Unix.gettimeofday () in
953 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
955 let w = Utils.compute_equality_weight stat in
956 (w, newproof, stat, newmenv, [])
959 !maxmeta, List.map build_new expansions
963 let sup_r_counter = ref 1;;
967 returns a list of new clauses inferred with a right superposition step
968 between the positive equation "target" and one in the "table" "newmeta" is
969 the first free meta index, i.e. the first number above the highest meta
970 index: its updated value is also returned
972 let superposition_right newmeta (metasenv, context, ugraph) table target =
973 let module C = Cic in
974 let module S = CicSubstitution in
975 let module M = CicMetaSubst in
976 let module HL = HelmLibraryObjects in
977 let module CR = CicReduction in
978 let module U = Utils in
979 let w, eqproof, (eq_ty, left, right, ordering), newmetas, args = target in
980 if Utils.debug_metas then
981 ignore (check_target context target "superpositionright");
982 let metasenv' = newmetas in
983 let maxmeta = ref newmeta in
985 let betaexpand_term metasenv context ugraph table d term =
986 let t1 = Unix.gettimeofday () in
987 let res = betaexpand_term metasenv context ugraph table d term in
988 let t2 = Unix.gettimeofday () in
989 beta_expand_time := !beta_expand_time +. (t2 -. t1);
993 | U.Gt -> fst (betaexpand_term metasenv' context ugraph table 0 left), []
994 | U.Lt -> [], fst (betaexpand_term metasenv' context ugraph table 0 right)
998 (fun (_, subst, _, _, _) ->
999 let subst = apply_subst subst in
1000 let o = !Utils.compare_terms (subst l) (subst r) in
1001 o <> U.Lt && o <> U.Le)
1002 (fst (betaexpand_term metasenv' context ugraph table 0 l))
1004 (res left right), (res right left)
1006 let build_new ordering ((bo, s, m, ug, (eq_found, eq_URI)) as input) =
1007 if Utils.debug_metas then
1008 ignore (check_target context (snd eq_found) "buildnew1" );
1009 let time1 = Unix.gettimeofday () in
1011 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
1012 let what, other = if pos = Utils.Left then what, other else other, what in
1013 let newgoal, newproof =
1015 let bo' = Utils.guarded_simpl context (apply_subst s (S.subst other bo)) in
1016 let name = C.Name ("x_SupR_" ^ (string_of_int !sup_r_counter)) in
1020 if ordering = U.Gt then bo, S.lift 1 right else S.lift 1 left, bo in
1021 C.Appl [C.MutInd (LibraryObjects.eq_URI (), 0, []);
1022 S.lift 1 eq_ty; l; r]
1025 Inference.ProofBlock (s, eq_URI, (name, ty), bo'', eq_found, eqproof)
1027 let newmeta, newequality =
1029 if ordering = U.Gt then newgoal, apply_subst s right
1030 else apply_subst s left, newgoal in
1031 let neworder = !Utils.compare_terms left right in
1032 let newmenv = (* Inference.filter s *) m in
1033 let newargs = args @ args' in
1034 let stat = (eq_ty, left, right, neworder) in
1036 let w = Utils.compute_equality_weight stat in
1037 (w, newproof, stat, newmenv, newargs) in
1038 if Utils.debug_metas then
1039 ignore (check_target context eq' "buildnew3");
1040 let newm, eq' = Inference.fix_metas !maxmeta eq' in
1041 if Utils.debug_metas then
1042 ignore (check_target context eq' "buildnew4");
1046 let time2 = Unix.gettimeofday () in
1047 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
1048 if Utils.debug_metas then
1049 ignore(check_target context newequality "buildnew2");
1052 let new1 = List.map (build_new U.Gt) res1
1053 and new2 = List.map (build_new U.Lt) res2 in
1054 let ok e = not (Inference.is_identity (metasenv', context, ugraph) e) in
1056 (List.filter ok (new1 @ new2)))
1060 (** demodulation, when the target is a goal *)
1061 let rec demodulation_goal newmeta env table goal =
1062 let module C = Cic in
1063 let module S = CicSubstitution in
1064 let module M = CicMetaSubst in
1065 let module HL = HelmLibraryObjects in
1066 let metasenv, context, ugraph = env in
1067 let maxmeta = ref newmeta in
1068 let proof, metas, term = goal in
1069 let term = Utils.guarded_simpl (~debug:true) context term in
1070 let goal = proof, metas, term in
1071 let metasenv' = metas in
1073 let build_newgoal (t, subst, menv, ug, (eq_found, eq_URI)) =
1074 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
1075 let what, other = if pos = Utils.Left then what, other else other, what in
1077 try fst (CicTypeChecker.type_of_aux' metasenv context what ugraph)
1078 with CicUtil.Meta_not_found _ -> ty
1080 let newterm, newproof =
1081 let bo = Utils.guarded_simpl context (apply_subst subst (S.subst other t)) in
1082 let bo' = apply_subst subst t in
1083 let name = C.Name ("x_DemodGoal_" ^ (string_of_int !demod_counter)) in
1088 CicMkImplicit.identity_relocation_list_for_metavariable context in
1089 (* debug_print (lazy (Printf.sprintf "\nADDING META: %d\n" !maxmeta)); *)
1090 C.Meta (!maxmeta, irl)
1095 if pos = Utils.Left then [ty; what; other]
1096 else [ty; other; what]
1098 Inference.ProofSymBlock (termlist, proof')
1101 if pos = Utils.Left then what, other else other, what
1103 pos, (0, proof', (ty, other, what, Utils.Incomparable), menv', args')
1107 Inference.ProofBlock (subst, eq_URI, (name, ty), bo',
1108 eq_found, Inference.BasicProof metaproof)
1110 let rec repl = function
1111 | Inference.NoProof ->
1112 (* debug_print (lazy "replacing a NoProof"); *)
1114 | Inference.BasicProof _ ->
1115 (* debug_print (lazy "replacing a BasicProof"); *)
1117 | Inference.ProofGoalBlock (_, parent_proof) ->
1118 (* debug_print (lazy "replacing another ProofGoalBlock"); *)
1119 Inference.ProofGoalBlock (pb, parent_proof)
1120 | Inference.SubProof (term, meta_index, p) ->
1121 Inference.SubProof (term, meta_index, repl p)
1125 bo, Inference.ProofGoalBlock (Inference.NoProof, goal_proof)
1127 let newmetasenv = (* Inference.filter subst *) menv in
1128 !maxmeta, (newproof, newmetasenv, newterm)
1131 demodulation_aux (* ~typecheck:true *) metasenv' context ugraph table 0 term
1135 let newmeta, newgoal = build_newgoal t in
1136 let _, _, newg = newgoal in
1137 if Inference.meta_convertibility term newg then
1140 demodulation_goal newmeta env table newgoal
1146 (** demodulation, when the target is a theorem *)
1147 let rec demodulation_theorem newmeta env table theorem =
1148 let module C = Cic in
1149 let module S = CicSubstitution in
1150 let module M = CicMetaSubst in
1151 let module HL = HelmLibraryObjects in
1152 let metasenv, context, ugraph = env in
1153 let maxmeta = ref newmeta in
1154 let term, termty, metas = theorem in
1155 let metasenv' = metas in
1157 let build_newtheorem (t, subst, menv, ug, (eq_found, eq_URI)) =
1158 let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
1159 let what, other = if pos = Utils.Left then what, other else other, what in
1160 let newterm, newty =
1161 let bo = Utils.guarded_simpl context (apply_subst subst (S.subst other t)) in
1162 let bo' = apply_subst subst t in
1163 let name = C.Name ("x_DemodThm_" ^ (string_of_int !demod_counter)) in
1166 Inference.ProofBlock (subst, eq_URI, (name, ty), bo', eq_found,
1167 Inference.BasicProof term)
1169 (Inference.build_proof_term newproof, bo)
1172 let m = Inference.metas_of_term newterm in
1173 !maxmeta, (newterm, newty, menv)
1176 demodulation_aux (* ~typecheck:true *) metasenv' context ugraph table 0 termty
1180 let newmeta, newthm = build_newtheorem t in
1181 let newt, newty, _ = newthm in
1182 if Inference.meta_convertibility termty newty then
1185 demodulation_theorem newmeta env table newthm