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 _profiler = <:profiler<_profiler>>;; *)
30 module Index = Equality_indexing.DT (* discrimination tree based indexing *)
32 module Index = Equality_indexing.DT (* path tree based indexing *)
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)) ->
63 Printf.sprintf "Some: (%s, %s, %s)"
64 (Utils.string_of_pos p)
65 (Equality.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 (Equality.string_of_equality ?env e))
93 let apply_subst = Subst.apply_subst
95 let index = Index.index
96 let remove_index = Index.remove_index
97 let in_index = Index.in_index
98 let empty = Index.empty
99 let init_index = Index.init_index
101 let check_disjoint_invariant subst metasenv msg =
103 (fun (i,_,_) -> (Subst.is_in_subst i subst)) metasenv)
106 prerr_endline ("not disjoint: " ^ msg);
111 let check_for_duplicates metas msg =
112 if List.length metas <>
113 List.length (HExtlib.list_uniq (List.sort Pervasives.compare metas)) then
115 prerr_endline ("DUPLICATI " ^ msg);
116 prerr_endline (CicMetaSubst.ppmetasenv [] metas);
121 let check_res res msg =
123 Some (t, subst, menv, ug, eq_found) ->
124 let eqs = Equality.string_of_equality (snd eq_found) in
125 check_disjoint_invariant subst menv msg;
126 check_for_duplicates menv (msg ^ "\nchecking " ^ eqs);
130 let check_target context target msg =
131 let w, proof, (eq_ty, left, right, order), metas,_ =
132 Equality.open_equality target in
133 (* check that metas does not contains duplicates *)
134 let eqs = Equality.string_of_equality target in
135 let _ = check_for_duplicates metas (msg ^ "\nchecking " ^ eqs) in
136 let actual = (Utils.metas_of_term left)@(Utils.metas_of_term right)
137 @(Utils.metas_of_term eq_ty)@(Equality.metas_of_proof proof) in
138 let menv = List.filter (fun (i, _, _) -> List.mem i actual) metas in
139 let _ = if menv <> metas then
141 prerr_endline ("extra metas " ^ msg);
142 prerr_endline (CicMetaSubst.ppmetasenv [] metas);
143 prerr_endline "**********************";
144 prerr_endline (CicMetaSubst.ppmetasenv [] menv);
145 prerr_endline ("left: " ^ (CicPp.ppterm left));
146 prerr_endline ("right: " ^ (CicPp.ppterm right));
147 prerr_endline ("ty: " ^ (CicPp.ppterm eq_ty));
153 ignore(CicTypeChecker.type_of_aux'
154 metas context (Inference.build_proof_term proof) CicUniv.empty_ugraph)
157 prerr_endline (Inference.string_of_proof proof);
158 prerr_endline (CicPp.ppterm (Inference.build_proof_term proof));
159 prerr_endline ("+++++++++++++left: " ^ (CicPp.ppterm left));
160 prerr_endline ("+++++++++++++right: " ^ (CicPp.ppterm right));
165 (* returns a list of all the equalities in the tree that are in relation
166 "mode" with the given term, where mode can be either Matching or
169 Format of the return value: list of tuples in the form:
170 (position - Left or Right - of the term that matched the given one in this
174 Note that if equality is "left = right", if the ordering is left > right,
175 the position will always be Left, and if the ordering is left < right,
176 position will be Right.
179 let get_candidates ?env mode tree term =
183 Index.retrieve_generalizations tree term
185 Index.retrieve_unifiables tree term
188 Index.PosEqSet.elements s
192 finds the first equality in the index that matches "term", of type "termty"
193 termty can be Implicit if it is not needed. The result (one of the sides of
194 the equality, actually) should be not greater (wrt the term ordering) than
197 Format of the return value:
199 (term to substitute, [Cic.Rel 1 properly lifted - see the various
200 build_newtarget functions inside the various
201 demodulation_* functions]
202 substitution used for the matching,
204 ugraph, [substitution, metasenv and ugraph have the same meaning as those
205 returned by CicUnification.fo_unif]
206 (equality where the matching term was found, [i.e. the equality to use as
208 uri [either eq_ind_URI or eq_ind_r_URI, depending on the direction of
209 the equality: this is used to build the proof term, again see one of
210 the build_newtarget functions]
213 let rec find_matches metasenv context ugraph lift_amount term termty =
214 let module C = Cic in
215 let module U = Utils in
216 let module S = CicSubstitution in
217 let module M = CicMetaSubst in
218 let module HL = HelmLibraryObjects in
219 let cmp = !Utils.compare_terms in
220 let check = match termty with C.Implicit None -> false | _ -> true in
224 let pos, equality = candidate in
225 let (_, proof, (ty, left, right, o), metas,_) =
226 Equality.open_equality equality
228 if Utils.debug_metas then
229 ignore(check_target context (snd candidate) "find_matches");
230 if Utils.debug_res then
232 let c="eq = "^(Equality.string_of_equality (snd candidate)) ^ "\n"in
233 let t="t = " ^ (CicPp.ppterm term) ^ "\n" in
234 let m="metas = " ^ (CicMetaSubst.ppmetasenv [] metas) ^ "\n" in
237 (CicPp.ppterm(Equality.build_proof_term proof))^"\n"
240 check_for_duplicates metas "gia nella metas";
241 check_for_duplicates (metasenv@metas) ("not disjoint"^c^t^m(*^p*))
243 if check && not (fst (CicReduction.are_convertible
244 ~metasenv context termty ty ugraph)) then (
245 find_matches metasenv context ugraph lift_amount term termty tl
248 let subst', metasenv', ugraph' =
250 metasenv metas context term (S.lift lift_amount c) ugraph
252 Some (Cic.Rel(1+lift_amount),subst',metasenv',ugraph',candidate)
255 if pos = Utils.Left then left, right
258 if o <> U.Incomparable then
262 with Inference.MatchingFailure ->
263 find_matches metasenv context ugraph lift_amount term termty tl
265 if Utils.debug_res then ignore (check_res res "find1");
270 with Inference.MatchingFailure -> None
272 if Utils.debug_res then ignore (check_res res "find2");
274 | Some (_, s, _, _, _) ->
275 let c' = apply_subst s c in
277 let other' = U.guarded_simpl context (apply_subst s other) in *)
278 let other' = apply_subst s other in
279 let order = cmp c' other' in
284 metasenv context ugraph lift_amount term termty tl
286 find_matches metasenv context ugraph lift_amount term termty tl
289 let find_matches metasenv context ugraph lift_amount term termty =
290 find_matches metasenv context ugraph lift_amount term termty
294 as above, but finds all the matching equalities, and the matching condition
295 can be either Inference.matching or Inference.unification
297 let rec find_all_matches ?(unif_fun=Inference.unification)
298 metasenv context ugraph lift_amount term termty =
299 let module C = Cic in
300 let module U = Utils in
301 let module S = CicSubstitution in
302 let module M = CicMetaSubst in
303 let module HL = HelmLibraryObjects in
304 let cmp = !Utils.compare_terms in
308 let pos, equality = candidate in
309 let (_,_,(ty,left,right,o),metas,_)=Equality.open_equality equality in
311 let subst', metasenv', ugraph' =
312 unif_fun metasenv metas context term (S.lift lift_amount c) ugraph
314 (C.Rel (1+lift_amount),subst',metasenv',ugraph',candidate)
317 if pos = Utils.Left then left, right
320 if o <> U.Incomparable then
322 let res = do_match c in
323 res::(find_all_matches ~unif_fun metasenv context ugraph
324 lift_amount term termty tl)
326 | Inference.MatchingFailure
327 | CicUnification.UnificationFailure _
328 | CicUnification.Uncertain _ ->
329 find_all_matches ~unif_fun metasenv context ugraph
330 lift_amount term termty tl
333 let res = do_match c in
336 let c' = apply_subst s c
337 and other' = apply_subst s other in
338 let order = cmp c' other' in
339 if order <> U.Lt && order <> U.Le then
340 res::(find_all_matches ~unif_fun metasenv context ugraph
341 lift_amount term termty tl)
343 find_all_matches ~unif_fun metasenv context ugraph
344 lift_amount term termty tl
346 | Inference.MatchingFailure
347 | CicUnification.UnificationFailure _
348 | CicUnification.Uncertain _ ->
349 find_all_matches ~unif_fun metasenv context ugraph
350 lift_amount term termty tl
354 ?unif_fun metasenv context ugraph lift_amount term termty l
357 ?unif_fun metasenv context ugraph lift_amount term termty l
358 (*prerr_endline "CANDIDATES:";
359 List.iter (fun (_,x)->prerr_endline (Inference.string_of_equality x)) l;
360 prerr_endline ("MATCHING:" ^ CicPp.ppterm term ^ " are " ^ string_of_int
364 returns true if target is subsumed by some equality in table
367 prerr_endline (String.concat "\n" (List.map (fun (_, subst, menv, ug,
368 ((pos,equation),_)) -> Equality.string_of_equality equation)l))
371 let subsumption_aux use_unification env table target =
372 let _, _, (ty, left, right, _), tmetas, _ = Equality.open_equality target in
373 let metasenv, context, ugraph = env in
374 let metasenv = tmetas in
375 let predicate, unif_fun =
376 if use_unification then
377 Unification, Inference.unification
379 Matching, Inference.matching
383 | Cic.Meta _ when not use_unification -> []
385 let leftc = get_candidates predicate table left in
386 find_all_matches ~unif_fun
387 metasenv context ugraph 0 left ty leftc
389 let rec ok what leftorright = function
391 | (_, subst, menv, ug, (pos,equation))::tl ->
392 let _, _, (_, l, r, o), m,_ = Equality.open_equality equation in
394 let other = if pos = Utils.Left then r else l in
395 let what' = Subst.apply_subst subst what in
396 let other' = Subst.apply_subst subst other in
397 let subst', menv', ug' =
398 unif_fun metasenv m context what' other' ugraph
400 (match Subst.merge_subst_if_possible subst subst' with
401 | None -> ok what leftorright tl
402 | Some s -> Some (s, equation, leftorright <> pos ))
404 | Inference.MatchingFailure
405 | CicUnification.UnificationFailure _ -> ok what leftorright tl
407 match ok right Utils.Left leftr with
408 | Some _ as res -> res
412 | Cic.Meta _ when not use_unification -> []
414 let rightc = get_candidates predicate table right in
415 find_all_matches ~unif_fun
416 metasenv context ugraph 0 right ty rightc
418 ok left Utils.Right rightr
421 let subsumption x y z =
422 subsumption_aux false x y z
425 let unification x y z =
426 subsumption_aux true x y z
429 let rec demodulation_aux ?from ?(typecheck=false)
430 metasenv context ugraph table lift_amount term =
431 (* Printf.eprintf "term = %s\n" (CicPp.ppterm term);*)
432 let module C = Cic in
433 let module S = CicSubstitution in
434 let module M = CicMetaSubst in
435 let module HL = HelmLibraryObjects in
438 ~env:(metasenv,context,ugraph) (* Unification *) Matching table term
446 CicTypeChecker.type_of_aux' metasenv context term ugraph
448 C.Implicit None, ugraph
451 find_matches metasenv context ugraph lift_amount term termty candidates
453 if Utils.debug_res then ignore(check_res res "demod1");
463 (res, tl @ [S.lift 1 t])
466 demodulation_aux ~from:"1" metasenv context ugraph table
470 | None -> (None, tl @ [S.lift 1 t])
471 | Some (rel, _, _, _, _) -> (r, tl @ [rel]))
476 | Some (_, subst, menv, ug, eq_found) ->
477 Some (C.Appl ll, subst, menv, ug, eq_found)
479 | C.Prod (nn, s, t) ->
481 demodulation_aux ~from:"2"
482 metasenv context ugraph table lift_amount s in (
486 demodulation_aux metasenv
487 ((Some (nn, C.Decl s))::context) ugraph
488 table (lift_amount+1) t
492 | Some (t', subst, menv, ug, eq_found) ->
493 Some (C.Prod (nn, (S.lift 1 s), t'),
494 subst, menv, ug, eq_found)
496 | Some (s', subst, menv, ug, eq_found) ->
497 Some (C.Prod (nn, s', (S.lift 1 t)),
498 subst, menv, ug, eq_found)
500 | C.Lambda (nn, s, t) ->
503 metasenv context ugraph table lift_amount s in (
507 demodulation_aux metasenv
508 ((Some (nn, C.Decl s))::context) ugraph
509 table (lift_amount+1) t
513 | Some (t', subst, menv, ug, eq_found) ->
514 Some (C.Lambda (nn, (S.lift 1 s), t'),
515 subst, menv, ug, eq_found)
517 | Some (s', subst, menv, ug, eq_found) ->
518 Some (C.Lambda (nn, s', (S.lift 1 t)),
519 subst, menv, ug, eq_found)
524 if Utils.debug_res then ignore(check_res res "demod_aux output");
530 (** demodulation, when target is an equality *)
531 let rec demodulation_equality ?from eq_uri newmeta env table target =
532 let module C = Cic in
533 let module S = CicSubstitution in
534 let module M = CicMetaSubst in
535 let module HL = HelmLibraryObjects in
536 let module U = Utils in
537 let metasenv, context, ugraph = env in
538 let w, proof, (eq_ty, left, right, order), metas, id =
539 Equality.open_equality target
541 (* first, we simplify *)
542 (* let right = U.guarded_simpl context right in *)
543 (* let left = U.guarded_simpl context left in *)
544 (* let order = !Utils.compare_terms left right in *)
545 (* let stat = (eq_ty, left, right, order) in *)
546 (* let w = Utils.compute_equality_weight stat in*)
547 (* let target = Equality.mk_equality (w, proof, stat, metas) in *)
548 if Utils.debug_metas then
549 ignore(check_target context target "demod equalities input");
550 let metasenv' = (* metasenv @ *) metas in
551 let maxmeta = ref newmeta in
553 let build_newtarget is_left (t, subst, menv, ug, eq_found) =
555 if Utils.debug_metas then
557 ignore(check_for_duplicates menv "input1");
558 ignore(check_disjoint_invariant subst menv "input2");
559 let substs = Subst.ppsubst subst in
560 ignore(check_target context (snd eq_found) ("input3" ^ substs))
562 let pos, equality = eq_found in
564 (ty, what, other, _), menv',id') = Equality.open_equality equality in
566 try fst (CicTypeChecker.type_of_aux' metasenv context what ugraph)
567 with CicUtil.Meta_not_found _ -> ty
569 let what, other = if pos = Utils.Left then what, other else other, what in
570 let newterm, newproof =
572 Utils.guarded_simpl context (apply_subst subst (S.subst other t)) in
573 (* let name = C.Name ("x_Demod" ^ (string_of_int !demod_counter)) in*)
574 let name = C.Name "x" in
576 let l, r = if is_left then t, S.lift 1 right else S.lift 1 left, t in
577 C.Appl [C.MutInd (eq_uri, 0, []); S.lift 1 eq_ty; l; r]
579 (bo, (Equality.Step (subst,(Equality.Demodulation, id,(pos,id'),
580 (Cic.Lambda (name, ty, bo'))))))
582 let newmenv = menv in
583 let left, right = if is_left then newterm, right else left, newterm in
584 let ordering = !Utils.compare_terms left right in
585 let stat = (eq_ty, left, right, ordering) in
587 let w = Utils.compute_equality_weight stat in
588 (Equality.mk_equality (w, newproof, stat,newmenv))
590 if Utils.debug_metas then
591 ignore(check_target context res "buildnew_target output");
595 let res = demodulation_aux ~from:"3" metasenv' context ugraph table 0 left in
596 if Utils.debug_res then check_res res "demod result";
597 let newmeta, newtarget =
600 let newmeta, newtarget = build_newtarget true t in
601 assert (not (Equality.meta_convertibility_eq target newtarget));
602 if (Equality.is_weak_identity newtarget) ||
603 (Equality.meta_convertibility_eq target newtarget) then
606 demodulation_equality ?from eq_uri newmeta env table newtarget
608 let res = demodulation_aux metasenv' context ugraph table 0 right in
609 if Utils.debug_res then check_res res "demod result 1";
612 let newmeta, newtarget = build_newtarget false t in
613 if (Equality.is_weak_identity newtarget) ||
614 (Equality.meta_convertibility_eq target newtarget) then
617 demodulation_equality ?from eq_uri newmeta env table newtarget
621 (* newmeta, newtarget *)
626 Performs the beta expansion of the term "term" w.r.t. "table",
627 i.e. returns the list of all the terms t s.t. "(t term) = t2", for some t2
630 let rec betaexpand_term
631 ?(subterms_only=false) metasenv context ugraph table lift_amount term
633 let module C = Cic in
634 let module S = CicSubstitution in
635 let module M = CicMetaSubst in
636 let module HL = HelmLibraryObjects in
638 let res, lifted_term =
644 (fun arg (res, lifted_tl) ->
647 let arg_res, lifted_arg =
648 betaexpand_term metasenv context ugraph table
652 (fun (t, s, m, ug, eq_found) ->
653 (Some t)::lifted_tl, s, m, ug, eq_found)
658 (fun (l, s, m, ug, eq_found) ->
659 (Some lifted_arg)::l, s, m, ug, eq_found)
661 (Some lifted_arg)::lifted_tl)
664 (fun (r, s, m, ug, eq_found) ->
665 None::r, s, m, ug, eq_found) res,
671 (fun (l, s, m, ug, eq_found) ->
672 (C.Meta (i, l), s, m, ug, eq_found)) l'
674 e, C.Meta (i, lifted_l)
677 [], if m <= lift_amount then C.Rel m else C.Rel (m+1)
679 | C.Prod (nn, s, t) ->
681 betaexpand_term metasenv context ugraph table lift_amount s in
683 betaexpand_term metasenv ((Some (nn, C.Decl s))::context) ugraph
684 table (lift_amount+1) t in
687 (fun (t, s, m, ug, eq_found) ->
688 C.Prod (nn, t, lifted_t), s, m, ug, eq_found) l1
691 (fun (t, s, m, ug, eq_found) ->
692 C.Prod (nn, lifted_s, t), s, m, ug, eq_found) l2 in
693 l1' @ l2', C.Prod (nn, lifted_s, lifted_t)
695 | C.Lambda (nn, s, t) ->
697 betaexpand_term metasenv context ugraph table lift_amount s in
699 betaexpand_term metasenv ((Some (nn, C.Decl s))::context) ugraph
700 table (lift_amount+1) t in
703 (fun (t, s, m, ug, eq_found) ->
704 C.Lambda (nn, t, lifted_t), s, m, ug, eq_found) l1
707 (fun (t, s, m, ug, eq_found) ->
708 C.Lambda (nn, lifted_s, t), s, m, ug, eq_found) l2 in
709 l1' @ l2', C.Lambda (nn, lifted_s, lifted_t)
714 (fun (res, lifted_tl) arg ->
715 let arg_res, lifted_arg =
716 betaexpand_term metasenv context ugraph table lift_amount arg
720 (fun (a, s, m, ug, eq_found) ->
721 a::lifted_tl, s, m, ug, eq_found)
726 (fun (r, s, m, ug, eq_found) ->
727 lifted_arg::r, s, m, ug, eq_found)
729 lifted_arg::lifted_tl)
730 ) ([], []) (List.rev l)
733 (fun (l, s, m, ug, eq_found) -> (C.Appl l, s, m, ug, eq_found)) l',
736 | t -> [], (S.lift lift_amount t)
739 | C.Meta (i, l) -> res, lifted_term
742 C.Implicit None, ugraph
743 (* CicTypeChecker.type_of_aux' metasenv context term ugraph *)
745 let candidates = get_candidates Unification table term in
747 if subterms_only then
751 metasenv context ugraph lift_amount term termty candidates
758 returns a list of new clauses inferred with a right superposition step
759 between the positive equation "target" and one in the "table" "newmeta" is
760 the first free meta index, i.e. the first number above the highest meta
761 index: its updated value is also returned
763 let superposition_right
764 ?(subterms_only=false) eq_uri newmeta (metasenv, context, ugraph) table target=
765 let module C = Cic in
766 let module S = CicSubstitution in
767 let module M = CicMetaSubst in
768 let module HL = HelmLibraryObjects in
769 let module CR = CicReduction in
770 let module U = Utils in
771 let w, eqproof, (eq_ty, left, right, ordering), newmetas,id =
772 Equality.open_equality target
774 if Utils.debug_metas then
775 ignore (check_target context target "superpositionright");
776 let metasenv' = newmetas in
777 let maxmeta = ref newmeta in
781 fst (betaexpand_term ~subterms_only metasenv' context ugraph table 0 left), []
783 [], fst (betaexpand_term ~subterms_only metasenv' context ugraph table 0 right)
787 (fun (_, subst, _, _, _) ->
788 let subst = apply_subst subst in
789 let o = !Utils.compare_terms (subst l) (subst r) in
790 o <> U.Lt && o <> U.Le)
791 (fst (betaexpand_term ~subterms_only metasenv' context ugraph table 0 l))
793 (res left right), (res right left)
795 let build_new ordering (bo, s, m, ug, eq_found) =
796 if Utils.debug_metas then
797 ignore (check_target context (snd eq_found) "buildnew1" );
799 let pos, equality = eq_found in
800 let (_, proof', (ty, what, other, _), menv',id') =
801 Equality.open_equality equality in
802 let what, other = if pos = Utils.Left then what, other else other, what in
804 let newgoal, newproof =
807 Utils.guarded_simpl context (apply_subst s (S.subst other bo))
809 let name = C.Name "x" in
812 if ordering = U.Gt then bo, S.lift 1 right else S.lift 1 left, bo in
813 C.Appl [C.MutInd (eq_uri, 0, []); S.lift 1 eq_ty; l; r]
817 (s,(Equality.SuperpositionRight,
818 id,(pos,id'),(Cic.Lambda(name,ty,bo''))))
820 let newmeta, newequality =
822 if ordering = U.Gt then newgoal, apply_subst s right
823 else apply_subst s left, newgoal in
824 let neworder = !Utils.compare_terms left right in
825 let newmenv = (* Inference.filter s *) m in
826 let stat = (eq_ty, left, right, neworder) in
828 let w = Utils.compute_equality_weight stat in
829 Equality.mk_equality (w, newproof, stat, newmenv) in
830 if Utils.debug_metas then
831 ignore (check_target context eq' "buildnew3");
832 let newm, eq' = Equality.fix_metas !maxmeta eq' in
833 if Utils.debug_metas then
834 ignore (check_target context eq' "buildnew4");
838 if Utils.debug_metas then
839 ignore(check_target context newequality "buildnew2");
842 let new1 = List.map (build_new U.Gt) res1
843 and new2 = List.map (build_new U.Lt) res2 in
844 let ok e = not (Equality.is_identity (metasenv', context, ugraph) e) in
846 (List.filter ok (new1 @ new2)))
849 (** demodulation, when the target is a theorem *)
850 let rec demodulation_theorem newmeta env table theorem =
851 let module C = Cic in
852 let module S = CicSubstitution in
853 let module M = CicMetaSubst in
854 let module HL = HelmLibraryObjects in
855 let metasenv, context, ugraph = env in
856 let maxmeta = ref newmeta in
857 let term, termty, metas = theorem in
858 let metasenv' = metas in
860 let build_newtheorem (t, subst, menv, ug, eq_found) =
861 let pos, equality = eq_found in
862 let (_, proof', (ty, what, other, _), menv',id) =
863 Equality.open_equality equality in
864 let what, other = if pos = Utils.Left then what, other else other, what in
866 let bo = Utils.guarded_simpl context (apply_subst subst (S.subst other t)) in
867 (* let bo' = apply_subst subst t in *)
868 (* let name = C.Name ("x_DemodThm_" ^ (string_of_int !demod_counter)) in*)
871 Equality.ProofBlock (subst, eq_URI, (name, ty), bo', eq_found,
872 Equality.BasicProof (Equality.empty_subst,term))
874 (Equality.build_proof_term_old newproofold, bo)
876 (* TODO, not ported to the new proofs *)
877 if true then assert false; term, bo
879 !maxmeta, (newterm, newty, menv)
882 demodulation_aux (* ~typecheck:true *) metasenv' context ugraph table 0 termty
886 let newmeta, newthm = build_newtheorem t in
887 let newt, newty, _ = newthm in
888 if Equality.meta_convertibility termty newty then
891 demodulation_theorem newmeta env table newthm
896 (*****************************************************************************)
897 (** OPERATIONS ON GOALS **)
899 (** DEMODULATION_GOAL & SUPERPOSITION_LEFT **)
900 (*****************************************************************************)
904 | (proof,menv,Cic.Appl[(Cic.MutInd(uri,0,_)) as eq;ty;l;r]) ->
905 assert (LibraryObjects.is_eq_URI uri);
910 let ty_of_goal (_,_,ty) = ty ;;
912 (* checks if two goals are metaconvertible *)
913 let goal_metaconvertibility_eq g1 g2 =
914 Equality.meta_convertibility (ty_of_goal g1) (ty_of_goal g2)
917 (* when the betaexpand_term function is called on the left/right side of the
918 * goal, the predicate has to be fixed
919 * C[x] ---> (eq ty unchanged C[x])
920 * [posu] is the side of the [unchanged] term in the original goal
922 let fix_expansion goal posu (t, subst, menv, ug, eq_f) =
923 let _,_,eq,ty,l,r = open_goal goal in
924 let unchanged = if posu = Utils.Left then l else r in
925 let unchanged = CicSubstitution.lift 1 unchanged in
926 let ty = CicSubstitution.lift 1 ty in
929 | Utils.Left -> Cic.Appl [eq;ty;unchanged;t]
930 | Utils.Right -> Cic.Appl [eq;ty;t;unchanged]
932 (pred, subst, menv, ug, eq_f)
935 (* ginve the old [goal], the side that has not changed [posu] and the
936 * expansion builds a new goal *)
937 let build_newgoal context goal posu rule expansion =
938 let goalproof,_,_,_,_,_ = open_goal goal in
939 let (t,subst,menv,ug,eq_found) = fix_expansion goal posu expansion in
940 let pos, equality = eq_found in
941 let (_, proof', (ty, what, other, _), menv',id) =
942 Equality.open_equality equality in
943 let what, other = if pos = Utils.Left then what, other else other, what in
944 let newterm, newgoalproof =
946 Utils.guarded_simpl context
947 (apply_subst subst (CicSubstitution.subst other t))
949 let bo' = (*apply_subst subst*) t in
950 let name = Cic.Name "x" in
951 let newgoalproofstep = (rule,pos,id,subst,Cic.Lambda (name,ty,bo')) in
952 bo, (newgoalproofstep::goalproof)
954 let newmetasenv = (* Inference.filter subst *) menv in
955 (newgoalproof, newmetasenv, newterm)
960 returns a list of new clauses inferred with a left superposition step
961 the negative equation "target" and one of the positive equations in "table"
963 let superposition_left (metasenv, context, ugraph) table goal maxmeta =
964 let names = Utils.names_of_context context in
965 let proof,menv,eq,ty,l,r = open_goal goal in
966 let c = !Utils.compare_terms l r in
968 if c = Utils.Incomparable then
970 let expansionsl, _ = betaexpand_term menv context ugraph table 0 l in
971 let expansionsr, _ = betaexpand_term menv context ugraph table 0 r in
972 (* prerr_endline "incomparable";
973 prerr_endline (string_of_int (List.length expansionsl));
974 prerr_endline (string_of_int (List.length expansionsr));
976 List.map (build_newgoal context goal Utils.Right Equality.SuperpositionLeft) expansionsl
978 List.map (build_newgoal context goal Utils.Left Equality.SuperpositionLeft) expansionsr
982 | Utils.Gt -> (* prerr_endline "GT"; *)
983 let big,small,possmall = l,r,Utils.Right in
984 let expansions, _ = betaexpand_term menv context ugraph table 0 big in
986 (build_newgoal context goal possmall Equality.SuperpositionLeft)
988 | Utils.Lt -> (* prerr_endline "LT"; *)
989 let big,small,possmall = r,l,Utils.Left in
990 let expansions, _ = betaexpand_term menv context ugraph table 0 big in
992 (build_newgoal context goal possmall Equality.SuperpositionLeft)
997 ("NOT GT, LT NOR EQ : "^CicPp.pp l names^" - "^CicPp.pp r names);
1000 (* rinfresco le meta *)
1003 let max,g = Equality.fix_metas_goal max g in max,g::acc)
1004 newgoals (maxmeta,[])
1007 (** demodulation, when the target is a goal *)
1008 let rec demodulation_goal env table goal =
1009 let goalproof,menv,_,_,left,right = open_goal goal in
1010 let _, context, ugraph = env in
1011 (* let term = Utils.guarded_simpl (~debug:true) context term in*)
1013 let resright = demodulation_aux menv context ugraph table 0 right in
1017 build_newgoal context goal Utils.Left Equality.Demodulation t
1019 if goal_metaconvertibility_eq goal newg then
1022 true, snd (demodulation_goal env table newg)
1023 | None -> false, goal
1025 let resleft = demodulation_aux menv context ugraph table 0 left in
1028 let newg = build_newgoal context goal Utils.Right Equality.Demodulation t in
1029 if goal_metaconvertibility_eq goal newg then
1032 true, snd (demodulation_goal env table newg)
1033 | None -> do_right ()
1036 let get_stats () = "" ;;