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 type goal = Equality.goal_proof * Cic.metasenv * Cic.term
30 module Index = Equality_indexing.DT (* discrimination tree based indexing *)
32 module Index = Equality_indexing.DT (* path tree based indexing *)
35 let beta_expand_time = ref 0.;;
37 let debug_print = Utils.debug_print;;
41 let check_equation env equation msg =
42 let w, proof, (eq_ty, left, right, order), metas, args = equation in
43 let metasenv, context, ugraph = env
44 let metasenv' = metasenv @ metas in
46 CicTypeChecker.type_of_aux' metasenv' context left ugraph;
47 CicTypeChecker.type_of_aux' metasenv' context right ugraph;
50 CicUtil.Meta_not_found _ as exn ->
53 prerr_endline (CicPp.ppterm left);
54 prerr_endline (CicPp.ppterm right);
59 type retrieval_mode = Matching | Unification;;
61 let string_of_res ?env =
64 | Some (t, s, m, u, ((p,e), eq_URI)) ->
65 Printf.sprintf "Some: (%s, %s, %s)"
66 (Utils.string_of_pos p)
67 (Equality.string_of_equality ?env e)
71 let print_res ?env res =
74 (List.map (string_of_res ?env) res))
77 let print_candidates ?env mode term res =
81 prerr_endline ("| candidates Matching " ^ (CicPp.ppterm term))
83 prerr_endline ("| candidates Unification " ^ (CicPp.ppterm term))
89 Printf.sprintf "| (%s, %s)" (Utils.string_of_pos p)
90 (Equality.string_of_equality ?env e))
95 let indexing_retrieval_time = ref 0.;;
98 let apply_subst = Subst.apply_subst
100 let index = Index.index
101 let remove_index = Index.remove_index
102 let in_index = Index.in_index
103 let empty = Index.empty
104 let init_index = Index.init_index
106 let check_disjoint_invariant subst metasenv msg =
108 (fun (i,_,_) -> (Subst.is_in_subst i subst)) metasenv)
111 prerr_endline ("not disjoint: " ^ msg);
116 let check_for_duplicates metas msg =
117 if List.length metas <>
118 List.length (HExtlib.list_uniq (List.sort Pervasives.compare metas)) then
120 prerr_endline ("DUPLICATI " ^ msg);
121 prerr_endline (CicMetaSubst.ppmetasenv [] metas);
126 let check_res res msg =
128 Some (t, subst, menv, ug, (eq_found, eq_URI)) ->
129 let eqs = Equality.string_of_equality (snd eq_found) in
130 check_disjoint_invariant subst menv msg;
131 check_for_duplicates menv (msg ^ "\nchecking " ^ eqs);
135 let check_target context target msg =
136 let w, proof, (eq_ty, left, right, order), metas,_ =
137 Equality.open_equality target in
138 (* check that metas does not contains duplicates *)
139 let eqs = Equality.string_of_equality target in
140 let _ = check_for_duplicates metas (msg ^ "\nchecking " ^ eqs) in
141 let actual = (Utils.metas_of_term left)@(Utils.metas_of_term right)
142 @(Utils.metas_of_term eq_ty)@(Equality.metas_of_proof proof) in
143 let menv = List.filter (fun (i, _, _) -> List.mem i actual) metas in
144 let _ = if menv <> metas then
146 prerr_endline ("extra metas " ^ msg);
147 prerr_endline (CicMetaSubst.ppmetasenv [] metas);
148 prerr_endline "**********************";
149 prerr_endline (CicMetaSubst.ppmetasenv [] menv);
150 prerr_endline ("left: " ^ (CicPp.ppterm left));
151 prerr_endline ("right: " ^ (CicPp.ppterm right));
152 prerr_endline ("ty: " ^ (CicPp.ppterm eq_ty));
158 ignore(CicTypeChecker.type_of_aux'
159 metas context (Inference.build_proof_term proof) CicUniv.empty_ugraph)
162 prerr_endline (Inference.string_of_proof proof);
163 prerr_endline (CicPp.ppterm (Inference.build_proof_term proof));
164 prerr_endline ("+++++++++++++left: " ^ (CicPp.ppterm left));
165 prerr_endline ("+++++++++++++right: " ^ (CicPp.ppterm right));
170 (* returns a list of all the equalities in the tree that are in relation
171 "mode" with the given term, where mode can be either Matching or
174 Format of the return value: list of tuples in the form:
175 (position - Left or Right - of the term that matched the given one in this
179 Note that if equality is "left = right", if the ordering is left > right,
180 the position will always be Left, and if the ordering is left < right,
181 position will be Right.
184 let get_candidates ?env mode tree term =
185 let t1 = Unix.gettimeofday () in
189 | Matching -> Index.retrieve_generalizations tree term
190 | Unification -> Index.retrieve_unifiables tree term
192 Index.PosEqSet.elements s
194 (* print_endline (Discrimination_tree.string_of_discrimination_tree tree); *)
195 (* print_newline (); *)
196 let t2 = Unix.gettimeofday () in
197 indexing_retrieval_time := !indexing_retrieval_time +. (t2 -. t1);
198 (* make fresh instances *)
202 let profiler = HExtlib.profile "P/Indexing.get_candidates"
204 let get_candidates ?env mode tree term =
205 profiler.HExtlib.profile (get_candidates ?env mode tree) term
207 let match_unif_time_ok = ref 0.;;
208 let match_unif_time_no = ref 0.;;
212 finds the first equality in the index that matches "term", of type "termty"
213 termty can be Implicit if it is not needed. The result (one of the sides of
214 the equality, actually) should be not greater (wrt the term ordering) than
217 Format of the return value:
219 (term to substitute, [Cic.Rel 1 properly lifted - see the various
220 build_newtarget functions inside the various
221 demodulation_* functions]
222 substitution used for the matching,
224 ugraph, [substitution, metasenv and ugraph have the same meaning as those
225 returned by CicUnification.fo_unif]
226 (equality where the matching term was found, [i.e. the equality to use as
228 uri [either eq_ind_URI or eq_ind_r_URI, depending on the direction of
229 the equality: this is used to build the proof term, again see one of
230 the build_newtarget functions]
233 let rec find_matches metasenv context ugraph lift_amount term termty =
234 let module C = Cic in
235 let module U = Utils in
236 let module S = CicSubstitution in
237 let module M = CicMetaSubst in
238 let module HL = HelmLibraryObjects in
239 let cmp = !Utils.compare_terms in
240 let check = match termty with C.Implicit None -> false | _ -> true in
244 let pos, equality = candidate in
245 let (_, proof, (ty, left, right, o), metas,_) =
246 Equality.open_equality equality in
247 if Utils.debug_metas then
248 ignore(check_target context (snd candidate) "find_matches");
249 if Utils.debug_res then
251 let c="eq = "^(Equality.string_of_equality (snd candidate)) ^ "\n"in
252 let t="t = " ^ (CicPp.ppterm term) ^ "\n" in
253 let m="metas = " ^ (CicMetaSubst.ppmetasenv [] metas) ^ "\n" in
255 (CicPp.ppterm(Equality.build_proof_term proof))^"\n"
257 check_for_duplicates metas "gia nella metas";
258 check_for_duplicates (metasenv@metas) ("not disjoint"^c^t^m^p)
260 if check && not (fst (CicReduction.are_convertible
261 ~metasenv context termty ty ugraph)) then (
262 find_matches metasenv context ugraph lift_amount term termty tl
264 let do_match c eq_URI =
265 let subst', metasenv', ugraph' =
266 let t1 = Unix.gettimeofday () in
269 ( Inference.matching metasenv metas context
270 term (S.lift lift_amount c)) ugraph
272 let t2 = Unix.gettimeofday () in
273 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
276 | Inference.MatchingFailure as e ->
277 let t2 = Unix.gettimeofday () in
278 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
280 | CicUtil.Meta_not_found _ as exn -> raise exn
282 Some (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
285 let c, other, eq_URI =
286 if pos = Utils.Left then left, right, Utils.eq_ind_URI ()
287 else right, left, Utils.eq_ind_r_URI ()
289 if o <> U.Incomparable then
293 with Inference.MatchingFailure ->
294 find_matches metasenv context ugraph lift_amount term termty tl
296 if Utils.debug_res then ignore (check_res res "find1");
300 try do_match c eq_URI
301 with Inference.MatchingFailure -> None
303 if Utils.debug_res then ignore (check_res res "find2");
305 | Some (_, s, _, _, _) ->
306 let c' = apply_subst s c in
308 let other' = U.guarded_simpl context (apply_subst s other) in *)
309 let other' = apply_subst s other in
310 let order = cmp c' other' in
315 metasenv context ugraph lift_amount term termty tl
317 find_matches metasenv context ugraph lift_amount term termty tl
321 as above, but finds all the matching equalities, and the matching condition
322 can be either Inference.matching or Inference.unification
324 let rec find_all_matches ?(unif_fun=Inference.unification)
325 metasenv context ugraph lift_amount term termty =
326 let module C = Cic in
327 let module U = Utils in
328 let module S = CicSubstitution in
329 let module M = CicMetaSubst in
330 let module HL = HelmLibraryObjects in
331 let cmp = !Utils.compare_terms in
335 let pos, equality = candidate in
336 let (_,_,(ty,left,right,o),metas,_)=Equality.open_equality equality in
337 let do_match c eq_URI =
338 let subst', metasenv', ugraph' =
339 let t1 = Unix.gettimeofday () in
342 unif_fun metasenv metas context
343 term (S.lift lift_amount c) ugraph in
344 let t2 = Unix.gettimeofday () in
345 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
348 | Inference.MatchingFailure
349 | CicUnification.UnificationFailure _
350 | CicUnification.Uncertain _ as e ->
351 let t2 = Unix.gettimeofday () in
352 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
355 (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
358 let c, other, eq_URI =
359 if pos = Utils.Left then left, right, Utils.eq_ind_URI ()
360 else right, left, Utils.eq_ind_r_URI ()
362 if o <> U.Incomparable then
364 let res = do_match c eq_URI in
365 res::(find_all_matches ~unif_fun metasenv context ugraph
366 lift_amount term termty tl)
368 | Inference.MatchingFailure
369 | CicUnification.UnificationFailure _
370 | CicUnification.Uncertain _ ->
371 find_all_matches ~unif_fun metasenv context ugraph
372 lift_amount term termty tl
375 let res = do_match c eq_URI in
378 let c' = apply_subst s c
379 and other' = apply_subst s other in
380 let order = cmp c' other' in
381 if order <> U.Lt && order <> U.Le then
382 res::(find_all_matches ~unif_fun metasenv context ugraph
383 lift_amount term termty tl)
385 find_all_matches ~unif_fun metasenv context ugraph
386 lift_amount term termty tl
388 | Inference.MatchingFailure
389 | CicUnification.UnificationFailure _
390 | CicUnification.Uncertain _ ->
391 find_all_matches ~unif_fun metasenv context ugraph
392 lift_amount term termty tl
396 ?unif_fun metasenv context ugraph lift_amount term termty l
400 ?unif_fun metasenv context ugraph lift_amount term termty l
402 (*prerr_endline "CANDIDATES:";
403 List.iter (fun (_,x)->prerr_endline (Inference.string_of_equality x)) l;
404 prerr_endline ("MATCHING:" ^ CicPp.ppterm term ^ " are " ^ string_of_int
409 returns true if target is subsumed by some equality in table
411 let subsumption_aux use_unification env table target =
412 (* let print_res l =*)
413 (* prerr_endline (String.concat "\n" (List.map (fun (_, subst, menv, ug,*)
414 (* ((pos,equation),_)) -> Equality.string_of_equality equation)l))*)
416 let _, _, (ty, left, right, _), tmetas, _ = Equality.open_equality target in
417 let metasenv, context, ugraph = env in
418 let metasenv = tmetas in
419 let predicate, unif_fun =
420 if use_unification then
421 Unification, Inference.unification
423 Matching, Inference.matching
427 | Cic.Meta _ when not use_unification -> []
429 let leftc = get_candidates predicate table left in
430 find_all_matches ~unif_fun
431 metasenv context ugraph 0 left ty leftc
433 (* print_res leftr;*)
434 let rec ok what = function
436 | (_, subst, menv, ug, ((pos,equation),_))::tl ->
437 let _, _, (_, l, r, o), m,_ = Equality.open_equality equation in
439 let other = if pos = Utils.Left then r else l in
440 let subst', menv', ug' =
441 let t1 = Unix.gettimeofday () in
443 let other = Subst.apply_subst subst other in
444 let r = unif_fun metasenv m context what other ugraph in
445 let t2 = Unix.gettimeofday () in
446 match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
449 | Inference.MatchingFailure
450 | CicUnification.UnificationFailure _ as e ->
451 let t2 = Unix.gettimeofday () in
452 match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
455 (match Subst.merge_subst_if_possible subst subst' with
457 | Some s -> Some (s, equation))
459 | Inference.MatchingFailure
460 | CicUnification.UnificationFailure _ -> ok what tl
462 match ok right leftr with
463 | Some _ as res -> res
467 | Cic.Meta _ when not use_unification -> []
469 let rightc = get_candidates predicate table right in
470 find_all_matches ~unif_fun
471 metasenv context ugraph 0 right ty rightc
473 (* print_res rightr;*)
478 (* (Printf.sprintf "SUBSUMPTION! %s\n%s\n" *)
479 (* (Inference.string_of_equality target) (Utils.print_subst s)))); *)
482 let subsumption = subsumption_aux false;;
483 let unification = subsumption_aux true;;
485 let rec demodulation_aux ?from ?(typecheck=false)
486 metasenv context ugraph table lift_amount term =
487 (* Printf.eprintf "term = %s\n" (CicPp.ppterm term); *)
488 let module C = Cic in
489 let module S = CicSubstitution in
490 let module M = CicMetaSubst in
491 let module HL = HelmLibraryObjects in
493 get_candidates ~env:(metasenv,context,ugraph) (* Unification *) Matching table term in
494 if List.exists (fun (i,_,_) -> i = 2840) metasenv
496 (prerr_endline ("term: " ^(CicPp.ppterm term));
497 List.iter (fun (_,x) -> prerr_endline (Equality.string_of_equality x))
499 prerr_endline ("-------");
500 prerr_endline ("+++++++"));
507 CicTypeChecker.type_of_aux' metasenv context term ugraph
509 C.Implicit None, ugraph
512 find_matches metasenv context ugraph lift_amount term termty candidates
514 if Utils.debug_res then ignore(check_res res "demod1");
524 (res, tl @ [S.lift 1 t])
527 demodulation_aux ~from:"1" metasenv context ugraph table
531 | None -> (None, tl @ [S.lift 1 t])
532 | Some (rel, _, _, _, _) -> (r, tl @ [rel]))
537 | Some (_, subst, menv, ug, eq_found) ->
538 Some (C.Appl ll, subst, menv, ug, eq_found)
540 | C.Prod (nn, s, t) ->
542 demodulation_aux ~from:"2"
543 metasenv context ugraph table lift_amount s in (
547 demodulation_aux metasenv
548 ((Some (nn, C.Decl s))::context) ugraph
549 table (lift_amount+1) t
553 | Some (t', subst, menv, ug, eq_found) ->
554 Some (C.Prod (nn, (S.lift 1 s), t'),
555 subst, menv, ug, eq_found)
557 | Some (s', subst, menv, ug, eq_found) ->
558 Some (C.Prod (nn, s', (S.lift 1 t)),
559 subst, menv, ug, eq_found)
561 | C.Lambda (nn, s, t) ->
564 metasenv context ugraph table lift_amount s in (
568 demodulation_aux metasenv
569 ((Some (nn, C.Decl s))::context) ugraph
570 table (lift_amount+1) t
574 | Some (t', subst, menv, ug, eq_found) ->
575 Some (C.Lambda (nn, (S.lift 1 s), t'),
576 subst, menv, ug, eq_found)
578 | Some (s', subst, menv, ug, eq_found) ->
579 Some (C.Lambda (nn, s', (S.lift 1 t)),
580 subst, menv, ug, eq_found)
585 if Utils.debug_res then ignore(check_res res "demod_aux output");
590 let build_newtarget_time = ref 0.;;
593 let demod_counter = ref 1;;
597 let profiler = HExtlib.profile "P/Indexing.demod_eq[build_new_target]"
599 (** demodulation, when target is an equality *)
600 let rec demodulation_equality ?from newmeta env table sign target =
601 let module C = Cic in
602 let module S = CicSubstitution in
603 let module M = CicMetaSubst in
604 let module HL = HelmLibraryObjects in
605 let module U = Utils in
606 let metasenv, context, ugraph = env in
607 let w, proof, (eq_ty, left, right, order), metas, id =
608 Equality.open_equality target
610 (* first, we simplify *)
611 (* let right = U.guarded_simpl context right in *)
612 (* let left = U.guarded_simpl context left in *)
613 (* let order = !Utils.compare_terms left right in *)
614 (* let stat = (eq_ty, left, right, order) in *)
615 (* let w = Utils.compute_equality_weight stat in*)
616 (* let target = Equality.mk_equality (w, proof, stat, metas) in *)
617 if Utils.debug_metas then
618 ignore(check_target context target "demod equalities input");
619 let metasenv' = (* metasenv @ *) metas in
620 let maxmeta = ref newmeta in
622 let build_newtarget is_left (t, subst, menv, ug, (eq_found, eq_URI)) =
623 let time1 = Unix.gettimeofday () in
625 if Utils.debug_metas then
627 ignore(check_for_duplicates menv "input1");
628 ignore(check_disjoint_invariant subst menv "input2");
629 let substs = Subst.ppsubst subst in
630 ignore(check_target context (snd eq_found) ("input3" ^ substs))
632 let pos, equality = eq_found in
634 (ty, what, other, _), menv',id') = Equality.open_equality equality in
636 try fst (CicTypeChecker.type_of_aux' metasenv context what ugraph)
637 with CicUtil.Meta_not_found _ -> ty
639 let what, other = if pos = Utils.Left then what, other else other, what in
640 let newterm, newproof =
642 Utils.guarded_simpl context (apply_subst subst (S.subst other t)) in
643 (* let name = C.Name ("x_Demod" ^ (string_of_int !demod_counter)) in*)
644 let name = C.Name "x" in
647 let l, r = if is_left then t, S.lift 1 right else S.lift 1 left, t in
648 C.Appl [C.MutInd (LibraryObjects.eq_URI (), 0, []);
649 S.lift 1 eq_ty; l; r]
651 if sign = Utils.Positive then
652 (bo, (Equality.Step (subst,(Equality.Demodulation, id,(pos,id'),
653 (Cic.Lambda (name, ty, bo'))))))
658 prerr_endline "***************************************negative";
662 CicMkImplicit.identity_relocation_list_for_metavariable context in
663 (* debug_print (lazy (Printf.sprintf "\nADDING META: %d\n" !maxmeta)); *)
664 (* print_newline (); *)
665 C.Meta (!maxmeta, irl)
670 if pos = Utils.Left then [ty; what; other]
671 else [ty; other; what]
673 Equality.ProofSymBlock (termlist, proof'_old)
675 let proof'_new' = assert false (* not implemented *) in
677 if pos = Utils.Left then what, other else other, what
681 (0, (proof'_new',proof'_old'),
682 (ty, other, what, Utils.Incomparable),menv')
687 (subst, eq_URI, (name, ty), bo',
688 eq_found, Equality.BasicProof (Equality.empty_subst,metaproof))
690 assert false, (* not implemented *)
691 (match snd proof with
692 | Equality.BasicProof _ ->
693 (* print_endline "replacing a BasicProof"; *)
695 | Equality.ProofGoalBlock (_, parent_proof) ->
696 (* print_endline "replacing another ProofGoalBlock"; *)
697 Equality.ProofGoalBlock (pb, parent_proof)
701 C.Appl [C.MutConstruct (* reflexivity *)
702 (LibraryObjects.eq_URI (), 0, 1, []);
703 eq_ty; if is_left then right else left]
706 (assert false, (* not implemented *)
707 Equality.ProofGoalBlock
708 (Equality.BasicProof (Equality.empty_subst,refl), snd target_proof)))
712 let newmenv = (* Inference.filter subst *) menv in
714 if Utils.debug_metas then
715 try ignore(CicTypeChecker.type_of_aux'
717 (Equality.build_proof_term newproof) ugraph);
720 prerr_endline "sempre lui";
721 prerr_endline (Subst.ppsubst subst);
722 prerr_endline (CicPp.ppterm
723 (Equality.build_proof_term newproof));
724 prerr_endline ("+++++++++++++termine: " ^ (CicPp.ppterm t));
725 prerr_endline ("+++++++++++++what: " ^ (CicPp.ppterm what));
726 prerr_endline ("+++++++++++++other: " ^ (CicPp.ppterm other));
727 prerr_endline ("+++++++++++++subst: " ^ (Subst.ppsubst subst));
728 prerr_endline ("+++++++++++++newmenv: " ^ (CicMetaSubst.ppmetasenv []
733 let left, right = if is_left then newterm, right else left, newterm in
734 let ordering = !Utils.compare_terms left right in
735 let stat = (eq_ty, left, right, ordering) in
736 let time2 = Unix.gettimeofday () in
737 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
739 let w = Utils.compute_equality_weight stat in
740 Equality.mk_equality (w, newproof, stat,newmenv)
742 if Utils.debug_metas then
743 ignore(check_target context res "buildnew_target output");
746 let build_newtarget is_left x =
747 profiler.HExtlib.profile (build_newtarget is_left) x
750 let res = demodulation_aux ~from:"3" metasenv' context ugraph table 0 left in
751 if Utils.debug_res then check_res res "demod result";
752 let newmeta, newtarget =
755 let newmeta, newtarget = build_newtarget true t in
756 assert (not (Equality.meta_convertibility_eq target newtarget));
757 if (Equality.is_weak_identity newtarget) ||
758 (Equality.meta_convertibility_eq target newtarget) then
761 demodulation_equality ?from newmeta env table sign newtarget
763 let res = demodulation_aux metasenv' context ugraph table 0 right in
764 if Utils.debug_res then check_res res "demod result 1";
767 let newmeta, newtarget = build_newtarget false t in
768 if (Equality.is_weak_identity newtarget) ||
769 (Equality.meta_convertibility_eq target newtarget) then
772 demodulation_equality ?from newmeta env table sign newtarget
776 (* newmeta, newtarget *)
781 Performs the beta expansion of the term "term" w.r.t. "table",
782 i.e. returns the list of all the terms t s.t. "(t term) = t2", for some t2
785 let rec betaexpand_term metasenv context ugraph table lift_amount term =
786 let module C = Cic in
787 let module S = CicSubstitution in
788 let module M = CicMetaSubst in
789 let module HL = HelmLibraryObjects in
790 let candidates = get_candidates Unification table term in
792 let res, lifted_term =
797 (fun arg (res, lifted_tl) ->
800 let arg_res, lifted_arg =
801 betaexpand_term metasenv context ugraph table
805 (fun (t, s, m, ug, eq_found) ->
806 (Some t)::lifted_tl, s, m, ug, eq_found)
811 (fun (l, s, m, ug, eq_found) ->
812 (Some lifted_arg)::l, s, m, ug, eq_found)
814 (Some lifted_arg)::lifted_tl)
817 (fun (r, s, m, ug, eq_found) ->
818 None::r, s, m, ug, eq_found) res,
824 (fun (l, s, m, ug, eq_found) ->
825 (C.Meta (i, l), s, m, ug, eq_found)) l'
827 e, C.Meta (i, lifted_l)
830 [], if m <= lift_amount then C.Rel m else C.Rel (m+1)
832 | C.Prod (nn, s, t) ->
834 betaexpand_term metasenv context ugraph table lift_amount s in
836 betaexpand_term metasenv ((Some (nn, C.Decl s))::context) ugraph
837 table (lift_amount+1) t in
840 (fun (t, s, m, ug, eq_found) ->
841 C.Prod (nn, t, lifted_t), s, m, ug, eq_found) l1
844 (fun (t, s, m, ug, eq_found) ->
845 C.Prod (nn, lifted_s, t), s, m, ug, eq_found) l2 in
846 l1' @ l2', C.Prod (nn, lifted_s, lifted_t)
848 | C.Lambda (nn, s, t) ->
850 betaexpand_term metasenv context ugraph table lift_amount s in
852 betaexpand_term metasenv ((Some (nn, C.Decl s))::context) ugraph
853 table (lift_amount+1) t in
856 (fun (t, s, m, ug, eq_found) ->
857 C.Lambda (nn, t, lifted_t), s, m, ug, eq_found) l1
860 (fun (t, s, m, ug, eq_found) ->
861 C.Lambda (nn, lifted_s, t), s, m, ug, eq_found) l2 in
862 l1' @ l2', C.Lambda (nn, lifted_s, lifted_t)
867 (fun arg (res, lifted_tl) ->
868 let arg_res, lifted_arg =
869 betaexpand_term metasenv context ugraph table lift_amount arg
873 (fun (a, s, m, ug, eq_found) ->
874 a::lifted_tl, s, m, ug, eq_found)
879 (fun (r, s, m, ug, eq_found) ->
880 lifted_arg::r, s, m, ug, eq_found)
882 lifted_arg::lifted_tl)
886 (fun (l, s, m, ug, eq_found) -> (C.Appl l, s, m, ug, eq_found)) l',
889 | t -> [], (S.lift lift_amount t)
892 | C.Meta (i, l) -> res, lifted_term
895 C.Implicit None, ugraph
896 (* CicTypeChecker.type_of_aux' metasenv context term ugraph *)
900 metasenv context ugraph lift_amount term termty candidates
905 let profiler = HExtlib.profile "P/Indexing.betaexpand_term"
907 let betaexpand_term metasenv context ugraph table lift_amount term =
908 profiler.HExtlib.profile
909 (betaexpand_term metasenv context ugraph table lift_amount) term
912 let sup_l_counter = ref 1;;
916 returns a list of new clauses inferred with a left superposition step
917 the negative equation "target" and one of the positive equations in "table"
920 let build_newgoal context goalproof (t, subst, menv, ug, (eq_found, eq_URI)) =
921 let pos, equality = eq_found in
922 let (_, proof', (ty, what, other, _), menv',id) =
923 Equality.open_equality equality in
924 let what, other = if pos = Utils.Left then what, other else other, what in
925 let newterm, newgoalproof =
927 Utils.guarded_simpl context
928 (apply_subst subst (CicSubstitution.subst other t))
930 let bo' = (*apply_subst subst*) t in
931 let name = Cic.Name "x" in
932 let newgoalproofstep = (pos,id,subst,Cic.Lambda (name,ty,bo')) in
933 bo, (newgoalproofstep::goalproof)
935 let newmetasenv = (* Inference.filter subst *) menv in
936 (newgoalproof, newmetasenv, newterm)
939 let superposition_left
940 (metasenv, context, ugraph) table (proof,menv,ty)
942 let module C = Cic in
943 let module S = CicSubstitution in
944 let module M = CicMetaSubst in
945 let module HL = HelmLibraryObjects in
946 let module CR = CicReduction in
947 let module U = Utils in
948 let big,small,pos,eq,ty =
950 | Cic.Appl [eq;ty;l;r] ->
952 Utils.compare_weights ~normalize:true
953 (Utils.weight_of_term l) (Utils.weight_of_term r)
956 | Utils.Gt -> l,r,Utils.Right,eq,ty
957 | _ -> r,l,Utils.Left,eq,ty)
960 let small = CicSubstitution.lift 1 small in
961 let ty = CicSubstitution.lift 1 ty in
962 let expansions, _ = betaexpand_term menv context ugraph table 0 big in
963 let fix_preds (t, subst, menv, ug, (eq_found, eq_URI)) =
967 Cic.Appl [eq;ty;small;t]
969 Cic.Appl [eq;ty;t;small]
971 (pred, subst, menv, ug, (eq_found, eq_URI))
973 List.map (build_newgoal context proof)
974 (List.map fix_preds expansions)
977 let sup_r_counter = ref 1;;
981 returns a list of new clauses inferred with a right superposition step
982 between the positive equation "target" and one in the "table" "newmeta" is
983 the first free meta index, i.e. the first number above the highest meta
984 index: its updated value is also returned
986 let superposition_right newmeta (metasenv, context, ugraph) table target =
987 let module C = Cic in
988 let module S = CicSubstitution in
989 let module M = CicMetaSubst in
990 let module HL = HelmLibraryObjects in
991 let module CR = CicReduction in
992 let module U = Utils in
993 let w, eqproof, (eq_ty, left, right, ordering), newmetas,id =
994 Equality.open_equality target
996 if Utils.debug_metas then
997 ignore (check_target context target "superpositionright");
998 let metasenv' = newmetas in
999 let maxmeta = ref newmeta in
1001 let betaexpand_term metasenv context ugraph table d term =
1002 let t1 = Unix.gettimeofday () in
1003 let res = betaexpand_term metasenv context ugraph table d term in
1004 let t2 = Unix.gettimeofday () in
1005 beta_expand_time := !beta_expand_time +. (t2 -. t1);
1009 | U.Gt -> fst (betaexpand_term metasenv' context ugraph table 0 left), []
1010 | U.Lt -> [], fst (betaexpand_term metasenv' context ugraph table 0 right)
1014 (fun (_, subst, _, _, _) ->
1015 let subst = apply_subst subst in
1016 let o = !Utils.compare_terms (subst l) (subst r) in
1017 o <> U.Lt && o <> U.Le)
1018 (fst (betaexpand_term metasenv' context ugraph table 0 l))
1020 (res left right), (res right left)
1022 let build_new ordering (bo, s, m, ug, (eq_found, eq_URI)) =
1023 if Utils.debug_metas then
1024 ignore (check_target context (snd eq_found) "buildnew1" );
1025 let time1 = Unix.gettimeofday () in
1027 let pos, equality = eq_found in
1028 let (_, proof', (ty, what, other, _), menv',id') =
1029 Equality.open_equality equality in
1030 let what, other = if pos = Utils.Left then what, other else other, what in
1031 let newgoal, newproof =
1034 Utils.guarded_simpl context (apply_subst s (S.subst other bo))
1036 let name = C.Name "x" in
1040 if ordering = U.Gt then bo, S.lift 1 right else S.lift 1 left, bo in
1041 C.Appl [C.MutInd (LibraryObjects.eq_URI (), 0, []);
1042 S.lift 1 eq_ty; l; r]
1046 (s,(Equality.SuperpositionRight,
1047 id,(pos,id'),(Cic.Lambda(name,ty,bo''))))
1049 let newmeta, newequality =
1051 if ordering = U.Gt then newgoal, apply_subst s right
1052 else apply_subst s left, newgoal in
1053 let neworder = !Utils.compare_terms left right in
1054 let newmenv = (* Inference.filter s *) m in
1055 let stat = (eq_ty, left, right, neworder) in
1057 let w = Utils.compute_equality_weight stat in
1058 Equality.mk_equality (w, newproof, stat, newmenv) in
1059 if Utils.debug_metas then
1060 ignore (check_target context eq' "buildnew3");
1061 let newm, eq' = Equality.fix_metas !maxmeta eq' in
1062 if Utils.debug_metas then
1063 ignore (check_target context eq' "buildnew4");
1067 let time2 = Unix.gettimeofday () in
1068 build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
1069 if Utils.debug_metas then
1070 ignore(check_target context newequality "buildnew2");
1073 let new1 = List.map (build_new U.Gt) res1
1074 and new2 = List.map (build_new U.Lt) res2 in
1075 let ok e = not (Equality.is_identity (metasenv', context, ugraph) e) in
1077 (List.filter ok (new1 @ new2)))
1081 (** demodulation, when the target is a goal *)
1082 let rec demodulation_goal newmeta env table goal =
1083 let module C = Cic in
1084 let module S = CicSubstitution in
1085 let module M = CicMetaSubst in
1086 let module HL = HelmLibraryObjects in
1087 let metasenv, context, ugraph = env in
1088 let maxmeta = ref newmeta in
1089 let goalproof, metas, term = goal in
1090 let term = Utils.guarded_simpl (~debug:true) context term in
1091 let goal = goalproof, metas, term in
1092 let metasenv' = metas in
1094 let build_newgoal (t, subst, menv, ug, (eq_found, eq_URI)) =
1095 let pos, equality = eq_found in
1096 let (_, proof', (ty, what, other, _), menv',id) =
1097 Equality.open_equality equality in
1098 let what, other = if pos = Utils.Left then what, other else other, what in
1100 try fst (CicTypeChecker.type_of_aux' menv' context what ugraph)
1102 | CicUtil.Meta_not_found _
1103 | Invalid_argument("List.fold_left2") -> ty
1105 let newterm, newgoalproof =
1107 Utils.guarded_simpl context (apply_subst subst(S.subst other t))
1109 let bo' = (*apply_subst subst*) t in
1110 let name = C.Name "x" in
1112 let newgoalproofstep = (pos,id,subst,Cic.Lambda (name,ty,bo')) in
1113 bo, (newgoalproofstep::goalproof)
1115 let newmetasenv = (* Inference.filter subst *) menv in
1116 !maxmeta, (newgoalproof, newmetasenv, newterm)
1119 demodulation_aux (* ~typecheck:true *) metasenv' context ugraph table 0 term
1123 let newmeta, newgoal = build_newgoal t in
1124 let _, _, newg = newgoal in
1125 if Equality.meta_convertibility term newg then
1126 false, newmeta, newgoal
1128 let changed, newmeta, newgoal =
1129 demodulation_goal newmeta env table newgoal
1131 true, newmeta, newgoal
1133 false, newmeta, goal
1136 (** demodulation, when the target is a theorem *)
1137 let rec demodulation_theorem newmeta env table theorem =
1138 let module C = Cic in
1139 let module S = CicSubstitution in
1140 let module M = CicMetaSubst in
1141 let module HL = HelmLibraryObjects in
1142 let metasenv, context, ugraph = env in
1143 let maxmeta = ref newmeta in
1144 let term, termty, metas = theorem in
1145 let metasenv' = metas in
1147 let build_newtheorem (t, subst, menv, ug, (eq_found, eq_URI)) =
1148 let pos, equality = eq_found in
1149 let (_, proof', (ty, what, other, _), menv',id) =
1150 Equality.open_equality equality in
1151 let what, other = if pos = Utils.Left then what, other else other, what in
1152 let newterm, newty =
1153 let bo = Utils.guarded_simpl context (apply_subst subst (S.subst other t)) in
1154 (* let bo' = apply_subst subst t in *)
1155 (* let name = C.Name ("x_DemodThm_" ^ (string_of_int !demod_counter)) in*)
1159 Equality.ProofBlock (subst, eq_URI, (name, ty), bo', eq_found,
1160 Equality.BasicProof (Equality.empty_subst,term))
1162 (Equality.build_proof_term_old newproofold, bo)
1164 (* TODO, not ported to the new proofs *)
1165 if true then assert false; term, bo
1167 !maxmeta, (newterm, newty, menv)
1170 demodulation_aux (* ~typecheck:true *) metasenv' context ugraph table 0 termty
1174 let newmeta, newthm = build_newtheorem t in
1175 let newt, newty, _ = newthm in
1176 if Equality.meta_convertibility termty newty then
1179 demodulation_theorem newmeta env table newthm