]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/paramodulation/indexing.ml
now proofs have the correct type :-)
[helm.git] / helm / ocaml / paramodulation / indexing.ml
1
2 type retrieval_mode = Matching | Unification;;
3
4
5 let print_candidates mode term res =
6   let _ =
7     match mode with
8     | Matching ->
9         Printf.printf "| candidates Matching %s\n" (CicPp.ppterm term)
10     | Unification ->
11         Printf.printf "| candidates Unification %s\n" (CicPp.ppterm term)
12   in
13   print_endline
14     (String.concat "\n"
15        (List.map
16           (fun (p, e) ->
17              Printf.sprintf "| (%s, %s)" (Utils.string_of_pos p)
18                (Inference.string_of_equality e))
19           res));
20   print_endline "|";
21 ;;
22
23
24 let indexing_retrieval_time = ref 0.;;
25
26
27 (* let my_apply_subst subst term = *)
28 (*   let module C = Cic in *)
29 (*   let lookup lift_amount meta = *)
30 (*     match meta with *)
31 (*     | C.Meta (i, _) -> ( *)
32 (*         try *)
33 (*           let _, (_, t, _) = List.find (fun (m, _) -> m = i) subst in *)
34 (*           (\* CicSubstitution.lift lift_amount  *\)t *)
35 (*         with Not_found -> meta *)
36 (*       ) *)
37 (*     | _ -> assert false *)
38 (*   in *)
39 (*   let rec apply_aux lift_amount =  function *)
40 (*     | C.Meta (i, l) as t -> lookup lift_amount t *)
41 (*     | C.Appl l -> C.Appl (List.map (apply_aux lift_amount) l) *)
42 (*     | C.Prod (nn, s, t) -> *)
43 (*         C.Prod (nn, apply_aux lift_amount s, apply_aux (lift_amount+1) t) *)
44 (*     | C.Lambda (nn, s, t) -> *)
45 (*         C.Lambda (nn, apply_aux lift_amount s, apply_aux (lift_amount+1) t) *)
46 (*     | t -> t *)
47 (*   in *)
48 (*   apply_aux 0 term *)
49 (* ;; *)
50
51
52 (* let apply_subst subst term = *)
53 (*   Printf.printf "| apply_subst:\n| subst: %s\n| term: %s\n" *)
54 (*     (Utils.print_subst ~prefix:" ; " subst) (CicPp.ppterm term); *)
55 (*   let res = my_apply_subst subst term in *)
56 (* (\*   let res = CicMetaSubst.apply_subst subst term in *\) *)
57 (*   Printf.printf "| res: %s\n" (CicPp.ppterm res); *)
58 (*   print_endline "|"; *)
59 (*   res *)
60 (* ;; *)
61
62 (* let apply_subst = my_apply_subst *)
63 let apply_subst = CicMetaSubst.apply_subst
64
65
66 let apply_subst =
67   let profile = CicUtil.profile "apply_subst" in
68   (fun s a -> profile (apply_subst s) a)
69 ;;
70
71
72 (*
73 let empty_table () =
74   Path_indexing.PSTrie.empty
75 ;;
76
77 let index = Path_indexing.index
78 and remove_index = Path_indexing.remove_index
79 and in_index = Path_indexing.in_index;;
80   
81 let get_candidates mode trie term =
82   let t1 = Unix.gettimeofday () in
83   let res = 
84     let s = 
85       match mode with
86       | Matching -> Path_indexing.retrieve_generalizations trie term
87       | Unification -> Path_indexing.retrieve_unifiables trie term
88 (*       Path_indexing.retrieve_all trie term *)
89     in
90     Path_indexing.PosEqSet.elements s
91   in
92 (*   print_candidates mode term res; *)
93   let t2 = Unix.gettimeofday () in
94   indexing_retrieval_time := !indexing_retrieval_time +. (t2 -. t1);
95   res
96 ;;
97 *)
98
99
100 let empty_table () =
101   Discrimination_tree.DiscriminationTree.empty
102 ;;
103
104 let index = Discrimination_tree.index
105 and remove_index = Discrimination_tree.remove_index
106 and in_index = Discrimination_tree.in_index;;
107
108 let get_candidates mode tree term =
109   let t1 = Unix.gettimeofday () in
110   let res =
111     let s = 
112       match mode with
113       | Matching -> Discrimination_tree.retrieve_generalizations tree term
114       | Unification -> Discrimination_tree.retrieve_unifiables tree term
115     in
116     Discrimination_tree.PosEqSet.elements s
117   in
118 (*   print_candidates mode term res; *)
119   let t2 = Unix.gettimeofday () in
120   indexing_retrieval_time := !indexing_retrieval_time +. (t2 -. t1);
121   res
122 ;;
123
124
125 (* let get_candidates = *)
126 (*   let profile = CicUtil.profile "Indexing.get_candidates" in *)
127 (*   (fun mode tree term -> profile (get_candidates mode tree) term) *)
128 (* ;; *)
129
130
131 let match_unif_time_ok = ref 0.;;
132 let match_unif_time_no = ref 0.;;
133
134
135 let rec find_matches metasenv context ugraph lift_amount term =
136   let module C = Cic in
137   let module U = Utils in
138   let module S = CicSubstitution in
139   let module M = CicMetaSubst in
140   let module HL = HelmLibraryObjects in
141   let cmp = !Utils.compare_terms in
142   let names = Utils.names_of_context context in
143   function
144     | [] -> None
145     | candidate::tl ->
146         let pos, (_, proof, (ty, left, right, o), metas, args) = candidate in
147         let do_match c other eq_URI =
148           let subst', metasenv', ugraph' =
149             let t1 = Unix.gettimeofday () in
150             try
151               let r = 
152                 Inference.matching (metasenv @ metas) context
153                   term (S.lift lift_amount c) ugraph in
154               let t2 = Unix.gettimeofday () in
155               match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
156               r
157             with e ->
158               let t2 = Unix.gettimeofday () in
159               match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
160               raise e
161           in
162             Some (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
163                   (candidate, eq_URI))
164         in
165         let c, other, eq_URI =
166           if pos = Utils.Left then left, right, HL.Logic.eq_ind_URI
167           else right, left, HL.Logic.eq_ind_r_URI
168         in
169         if o <> U.Incomparable then
170           try
171             do_match c other eq_URI
172           with e ->
173             find_matches metasenv context ugraph lift_amount term tl
174         else
175           let res = try do_match c other eq_URI with e -> None in
176           match res with
177           | Some (_, s, _, _, _) ->
178               let c' = (* M. *)apply_subst s c
179               and other' = (* M. *)apply_subst s other in
180               let order = cmp c' other' in
181               let names = U.names_of_context context in
182               if order = U.Gt then
183                 res
184               else
185                 find_matches metasenv context ugraph lift_amount term tl
186           | None ->
187               find_matches metasenv context ugraph lift_amount term tl
188 ;;
189
190
191 let rec find_all_matches ?(unif_fun=Inference.unification)
192     metasenv context ugraph lift_amount term =
193   let module C = Cic in
194   let module U = Utils in
195   let module S = CicSubstitution in
196   let module M = CicMetaSubst in
197   let module HL = HelmLibraryObjects in
198   let cmp = !Utils.compare_terms in
199   let names = Utils.names_of_context context in
200   function
201     | [] -> []
202     | candidate::tl ->
203         let pos, (_, _, (ty, left, right, o), metas, args) = candidate in
204         let do_match c other eq_URI =
205           let subst', metasenv', ugraph' =
206             let t1 = Unix.gettimeofday () in
207             try
208               let r = 
209                 unif_fun (metasenv @ metas) context
210                   term (S.lift lift_amount c) ugraph in
211               let t2 = Unix.gettimeofday () in
212               match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
213               r
214             with e ->
215               let t2 = Unix.gettimeofday () in
216               match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
217               raise e
218           in
219           (C.Rel (1 + lift_amount), subst', metasenv', ugraph',
220            (candidate, eq_URI))
221         in
222         let c, other, eq_URI =
223           if pos = Utils.Left then left, right, HL.Logic.eq_ind_URI
224           else right, left, HL.Logic.eq_ind_r_URI
225         in
226         if o <> U.Incomparable then
227           try
228             let res = do_match c other eq_URI in
229             res::(find_all_matches ~unif_fun metasenv context ugraph
230                     lift_amount term tl)
231           with e ->
232             find_all_matches ~unif_fun metasenv context ugraph
233               lift_amount term tl
234         else
235           try
236             let res = do_match c other eq_URI in
237             match res with
238             | _, s, _, _, _ ->
239                 let c' = (* M. *)apply_subst s c
240                 and other' = (* M. *)apply_subst s other in
241                 let order = cmp c' other' in
242                 let names = U.names_of_context context in
243                 if order <> U.Lt && order <> U.Le then
244                   res::(find_all_matches ~unif_fun metasenv context ugraph
245                           lift_amount term tl)
246                 else
247                   find_all_matches ~unif_fun metasenv context ugraph
248                     lift_amount term tl
249           with e ->
250             find_all_matches ~unif_fun metasenv context ugraph
251               lift_amount term tl
252 ;;
253
254
255 let subsumption env table target =
256   let _, (ty, left, right, _), tmetas, _ = target in
257   let metasenv, context, ugraph = env in
258   let metasenv = metasenv @ tmetas in
259   let samesubst subst subst' =
260     let tbl = Hashtbl.create (List.length subst) in
261     List.iter (fun (m, (c, t1, t2)) -> Hashtbl.add tbl m (c, t1, t2)) subst;
262     List.for_all
263       (fun (m, (c, t1, t2)) ->
264          try
265            let c', t1', t2' = Hashtbl.find tbl m in
266            if (c = c') && (t1 = t1') && (t2 = t2') then true
267            else false
268          with Not_found ->
269            true)
270       subst'
271   in
272   let leftr =
273     match left with
274     | Cic.Meta _ -> []
275     | _ ->
276         let leftc = get_candidates Matching table left in
277         find_all_matches ~unif_fun:Inference.matching
278           metasenv context ugraph 0 left leftc
279   in
280   let ok what (_, subst, menv, ug, ((pos, (_, _, (_, l, r, o), _, _)), _)) =
281     try
282       let other = if pos = Utils.Left then r else l in
283       let subst', menv', ug' =
284         let t1 = Unix.gettimeofday () in
285         try
286           let r = 
287             Inference.matching metasenv context what other ugraph in
288           let t2 = Unix.gettimeofday () in
289           match_unif_time_ok := !match_unif_time_ok +. (t2 -. t1);
290           r
291         with e ->
292           let t2 = Unix.gettimeofday () in
293           match_unif_time_no := !match_unif_time_no +. (t2 -. t1);
294           raise e
295       in
296       samesubst subst subst'
297     with e ->
298       false
299   in
300   let r = List.exists (ok right) leftr in
301   if r then
302     true
303   else
304     let rightr =
305       match right with
306       | Cic.Meta _ -> []
307       | _ ->
308           let rightc = get_candidates Matching table right in
309           find_all_matches ~unif_fun:Inference.matching
310             metasenv context ugraph 0 right rightc
311     in
312     List.exists (ok left) rightr
313 ;;
314
315
316 let rec demodulate_term metasenv context ugraph table lift_amount term =
317   let module C = Cic in
318   let module S = CicSubstitution in
319   let module M = CicMetaSubst in
320   let module HL = HelmLibraryObjects in
321   let candidates = get_candidates Matching table term in
322   match term with
323   | C.Meta _ -> None
324   | term ->
325       let res =
326         find_matches metasenv context ugraph lift_amount term candidates
327       in
328       if res <> None then
329         res
330       else
331         match term with
332         | C.Appl l ->
333             let res, ll = 
334               List.fold_left
335                 (fun (res, tl) t ->
336                    if res <> None then
337                      (res, tl @ [S.lift 1 t])
338                    else 
339                      let r =
340                        demodulate_term metasenv context ugraph table
341                          lift_amount t
342                      in
343                      match r with
344                      | None -> (None, tl @ [S.lift 1 t])
345                      | Some (rel, _, _, _, _) -> (r, tl @ [rel]))
346                 (None, []) l
347             in (
348               match res with
349               | None -> None
350               | Some (_, subst, menv, ug, eq_found) ->
351                   Some (C.Appl ll, subst, menv, ug, eq_found)
352             )
353         | C.Prod (nn, s, t) ->
354             let r1 =
355               demodulate_term metasenv context ugraph table lift_amount s in (
356               match r1 with
357               | None ->
358                   let r2 =
359                     demodulate_term metasenv
360                       ((Some (nn, C.Decl s))::context) ugraph
361                       table (lift_amount+1) t
362                   in (
363                     match r2 with
364                     | None -> None
365                     | Some (t', subst, menv, ug, eq_found) ->
366                         Some (C.Prod (nn, (S.lift 1 s), t'),
367                               subst, menv, ug, eq_found)
368                   )
369               | Some (s', subst, menv, ug, eq_found) ->
370                   Some (C.Prod (nn, s', (S.lift 1 t)),
371                         subst, menv, ug, eq_found)
372             )
373         | t ->
374             None
375 ;;
376
377
378 let build_ens_for_sym_eq ty x y = 
379   [(UriManager.uri_of_string
380       "cic:/Coq/Init/Logic/Logic_lemmas/equality/A.var", ty);
381    (UriManager.uri_of_string
382       "cic:/Coq/Init/Logic/Logic_lemmas/equality/x.var", x);
383    (UriManager.uri_of_string
384       "cic:/Coq/Init/Logic/Logic_lemmas/equality/y.var", y)]
385 ;;
386
387
388 let build_newtarget_time = ref 0.;;
389
390
391 let demod_counter = ref 1;;
392
393 let rec demodulation newmeta env table sign target =
394   let module C = Cic in
395   let module S = CicSubstitution in
396   let module M = CicMetaSubst in
397   let module HL = HelmLibraryObjects in
398   let metasenv, context, ugraph = env in
399   let _, proof, (eq_ty, left, right, order), metas, args = target in
400   let metasenv' = metasenv @ metas in
401
402   let maxmeta = ref newmeta in
403   
404   let build_newtarget is_left (t, subst, menv, ug, (eq_found, eq_URI)) =
405     let time1 = Unix.gettimeofday () in
406     
407     let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
408     let what, other = if pos = Utils.Left then what, other else other, what in
409     let newterm, newproof =
410       let bo = (* M. *)apply_subst subst (S.subst other t) in
411       let t' =
412         let name = C.Name ("x_Demod_" ^ (string_of_int !demod_counter)) in
413         incr demod_counter;
414         let l, r =
415           if is_left then t, S.lift 1 right else S.lift 1 left, t in
416         (name, ty, S.lift 1 eq_ty, l, r)
417       in
418       if sign = Utils.Positive then
419         (bo,
420          Inference.ProofBlock (subst, eq_URI, t', eq_found, proof))
421       else
422         let metaproof = 
423           incr maxmeta;
424           let irl =
425             CicMkImplicit.identity_relocation_list_for_metavariable context in
426           Printf.printf "\nADDING META: %d\n" !maxmeta;
427           print_newline ();
428           C.Meta (!maxmeta, irl)
429         in
430         let target' =
431           let eq_found =
432             let proof' =
433               let ens =
434                 if pos = Utils.Left then
435                   build_ens_for_sym_eq ty what other
436                 else
437                   build_ens_for_sym_eq ty other what
438               in
439               Inference.ProofSymBlock (ens, proof')
440             in
441             let what, other =
442               if pos = Utils.Left then what, other else other, what
443             in
444             pos, (0, proof', (ty, other, what, Utils.Incomparable),
445                   menv', args')
446           in
447           let target_proof =
448             let pb =
449               Inference.ProofBlock (subst, eq_URI, t', eq_found,
450                                     Inference.BasicProof metaproof)
451             in
452             match proof with
453             | Inference.BasicProof _ ->
454                 print_endline "replacing a BasicProof";
455                 pb
456             | Inference.ProofGoalBlock (_, parent_eq) ->
457                 print_endline "replacing another ProofGoalBlock";
458                 Inference.ProofGoalBlock (pb, parent_eq)
459             | _ -> assert false
460           in
461           (0, target_proof, (eq_ty, left, right, order), metas, args)
462         in
463         let refl =
464           C.Appl [C.MutConstruct (* reflexivity *)
465                     (HelmLibraryObjects.Logic.eq_URI, 0, 1, []);
466                   eq_ty; if is_left then right else left]          
467         in
468         (bo,
469          Inference.ProofGoalBlock (Inference.BasicProof refl, target'))
470     in
471     let left, right = if is_left then newterm, right else left, newterm in
472     let m = (Inference.metas_of_term left) @ (Inference.metas_of_term right) in
473     let newmetasenv = List.filter (fun (i, _, _) -> List.mem i m) metas
474     and newargs =
475       List.filter
476         (function C.Meta (i, _) -> List.mem i m | _ -> assert false)
477         args
478     in
479     let ordering = !Utils.compare_terms left right in
480
481     let time2 = Unix.gettimeofday () in
482     build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
483
484     let res =
485       let w = Utils.compute_equality_weight eq_ty left right in
486       (w, newproof, (eq_ty, left, right, ordering), newmetasenv, newargs)
487     in
488 (*     if sign = Utils.Positive then ( *)
489 (*       let newm, res = Inference.fix_metas !maxmeta res in *)
490 (*       maxmeta := newm; *)
491 (*       !maxmeta, res *)
492 (*     ) else *)
493     !maxmeta(* newmeta *), res
494   in
495   let res = demodulate_term metasenv' context ugraph table 0 left in
496 (*   let build_identity (w, p, (t, l, r, o), m, a) = *)
497 (*     match o with *)
498 (*     | Utils.Gt -> (w, p, (t, r, r, Utils.Eq), m, a) *)
499 (*     | _ -> (w, p, (t, l, l, Utils.Eq), m, a) *)
500 (*   in *)
501   match res with
502   | Some t ->
503       let newmeta, newtarget = build_newtarget true t in
504       if (Inference.is_identity (metasenv', context, ugraph) newtarget) ||
505         (Inference.meta_convertibility_eq target newtarget) then
506           newmeta, newtarget
507       else
508 (*         if subsumption env table newtarget then *)
509 (*           newmeta, build_identity newtarget *)
510 (*         else *)
511         demodulation newmeta env table sign newtarget
512   | None ->
513       let res = demodulate_term metasenv' context ugraph table 0 right in
514       match res with
515       | Some t ->
516           let newmeta, newtarget = build_newtarget false t in
517           if (Inference.is_identity (metasenv', context, ugraph) newtarget) ||
518             (Inference.meta_convertibility_eq target newtarget) then
519               newmeta, newtarget
520           else
521 (*             if subsumption env table newtarget then *)
522 (*               newmeta, build_identity newtarget *)
523 (*             else *)
524               demodulation newmeta env table sign newtarget
525       | None ->
526           newmeta, target
527 ;;
528
529
530 let rec betaexpand_term metasenv context ugraph table lift_amount term =
531   let module C = Cic in
532   let module S = CicSubstitution in
533   let module M = CicMetaSubst in
534   let module HL = HelmLibraryObjects in
535   let candidates = get_candidates Unification table term in
536   let res, lifted_term = 
537     match term with
538     | C.Meta (i, l) ->
539         let l', lifted_l = 
540           List.fold_right
541             (fun arg (res, lifted_tl) ->
542                match arg with
543                | Some arg ->
544                    let arg_res, lifted_arg =
545                      betaexpand_term metasenv context ugraph table
546                        lift_amount arg in
547                    let l1 =
548                      List.map
549                        (fun (t, s, m, ug, eq_found) ->
550                           (Some t)::lifted_tl, s, m, ug, eq_found)
551                        arg_res
552                    in
553                    (l1 @
554                       (List.map
555                          (fun (l, s, m, ug, eq_found) ->
556                             (Some lifted_arg)::l, s, m, ug, eq_found)
557                          res),
558                     (Some lifted_arg)::lifted_tl)
559                | None ->
560                    (List.map
561                       (fun (r, s, m, ug, eq_found) ->
562                          None::r, s, m, ug, eq_found) res, 
563                     None::lifted_tl)
564             ) l ([], [])
565         in
566         let e = 
567           List.map
568             (fun (l, s, m, ug, eq_found) ->
569                (C.Meta (i, l), s, m, ug, eq_found)) l'
570         in
571         e, C.Meta (i, lifted_l)
572           
573     | C.Rel m ->
574         [], if m <= lift_amount then C.Rel m else C.Rel (m+1)
575           
576     | C.Prod (nn, s, t) ->
577         let l1, lifted_s =
578           betaexpand_term metasenv context ugraph table lift_amount s in
579         let l2, lifted_t =
580           betaexpand_term metasenv ((Some (nn, C.Decl s))::context) ugraph
581             table (lift_amount+1) t in
582         let l1' =
583           List.map
584             (fun (t, s, m, ug, eq_found) ->
585                C.Prod (nn, t, lifted_t), s, m, ug, eq_found) l1
586         and l2' =
587           List.map
588             (fun (t, s, m, ug, eq_found) ->
589                C.Prod (nn, lifted_s, t), s, m, ug, eq_found) l2 in
590         l1' @ l2', C.Prod (nn, lifted_s, lifted_t)
591           
592     | C.Appl l ->
593         let l', lifted_l =
594           List.fold_right
595             (fun arg (res, lifted_tl) ->
596                let arg_res, lifted_arg =
597                  betaexpand_term metasenv context ugraph table lift_amount arg
598                in
599                let l1 =
600                  List.map
601                    (fun (a, s, m, ug, eq_found) ->
602                       a::lifted_tl, s, m, ug, eq_found)
603                    arg_res
604                in
605                (l1 @
606                   (List.map
607                      (fun (r, s, m, ug, eq_found) ->
608                         lifted_arg::r, s, m, ug, eq_found)
609                      res),
610                 lifted_arg::lifted_tl)
611             ) l ([], [])
612         in
613         (List.map
614            (fun (l, s, m, ug, eq_found) -> (C.Appl l, s, m, ug, eq_found)) l',
615          C.Appl lifted_l)
616
617     | t -> [], (S.lift lift_amount t)
618   in
619   match term with
620   | C.Meta _ -> res, lifted_term
621   | term ->
622       let r = 
623         find_all_matches metasenv context ugraph lift_amount term candidates
624       in
625       r @ res, lifted_term
626 ;;
627
628
629 let sup_l_counter = ref 1;;
630
631 let superposition_left newmeta (metasenv, context, ugraph) table target =
632   let module C = Cic in
633   let module S = CicSubstitution in
634   let module M = CicMetaSubst in
635   let module HL = HelmLibraryObjects in
636   let module CR = CicReduction in
637   let module U = Utils in
638   let weight, proof, (eq_ty, left, right, ordering), _, _ = target in
639   let expansions, _ =
640     let term = if ordering = U.Gt then left else right in
641     betaexpand_term metasenv context ugraph table 0 term
642   in
643   let maxmeta = ref newmeta in
644   let build_new (bo, s, m, ug, (eq_found, eq_URI)) =
645
646     print_endline "\nSUPERPOSITION LEFT\n";
647     
648     let time1 = Unix.gettimeofday () in
649     
650     let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
651     let what, other = if pos = Utils.Left then what, other else other, what in
652     let newgoal, newproof =
653       let bo' = (* M. *)apply_subst s (S.subst other bo) in
654       let t' =
655         let name = C.Name ("x_SupL_" ^ (string_of_int !sup_l_counter)) in
656         incr sup_l_counter;
657         let l, r =
658           if ordering = U.Gt then bo, S.lift 1 right else S.lift 1 left, bo in
659         (name, ty, S.lift 1 eq_ty, l, r)
660       in
661 (*       let bo'' = *)
662 (*         C.Appl ( *)
663 (*           [C.MutInd (HL.Logic.eq_URI, 0, []); *)
664 (*            S.lift 1 eq_ty] @ *)
665 (*             if ordering = U.Gt then [S.lift 1 bo'; S.lift 1 right] *)
666 (*             else [S.lift 1 left; S.lift 1 bo']) *)
667 (*       in *)
668 (*       let t' = *)
669 (*         let name = C.Name ("x_SupL_" ^ (string_of_int !sup_l_counter)) in *)
670 (*         incr sup_l_counter; *)
671 (*         C.Lambda (name, ty, bo'') *)
672 (*       in *)
673       incr maxmeta;
674       let metaproof =
675         let irl =
676           CicMkImplicit.identity_relocation_list_for_metavariable context in
677         C.Meta (!maxmeta, irl)
678       in
679       let target' =
680         let eq_found =
681           let proof' =
682             let ens =
683               if pos = Utils.Left then
684                 build_ens_for_sym_eq ty what other
685               else
686                 build_ens_for_sym_eq ty other what
687             in
688             Inference.ProofSymBlock (ens, proof')
689           in
690           let what, other =
691             if pos = Utils.Left then what, other else other, what
692           in
693           pos, (0, proof', (ty, other, what, Utils.Incomparable), menv', args')
694         in
695         let target_proof =
696           let pb =
697             Inference.ProofBlock (s, eq_URI, t', eq_found,
698                                   Inference.BasicProof metaproof)
699           in
700           match proof with
701           | Inference.BasicProof _ ->
702               print_endline "replacing a BasicProof";
703               pb
704           | Inference.ProofGoalBlock (_, parent_eq) ->
705               print_endline "replacing another ProofGoalBlock";
706               Inference.ProofGoalBlock (pb, parent_eq)
707           | _ -> assert false
708         in
709         (weight, target_proof, (eq_ty, left, right, ordering), [], [])
710       in
711       let refl =
712         C.Appl [C.MutConstruct (* reflexivity *)
713                   (HelmLibraryObjects.Logic.eq_URI, 0, 1, []);
714                 eq_ty; if ordering = U.Gt then right else left]
715       in
716       (bo',
717        Inference.ProofGoalBlock (Inference.BasicProof refl, target'))
718     in
719     let left, right =
720       if ordering = U.Gt then newgoal, right else left, newgoal in
721     let neworder = !Utils.compare_terms left right in
722
723     let time2 = Unix.gettimeofday () in
724     build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
725
726     let res =
727       let w = Utils.compute_equality_weight eq_ty left right in
728       (w, newproof, (eq_ty, left, right, neworder), [], [])
729     in
730     res
731   in
732   !maxmeta, List.map build_new expansions
733 ;;
734
735
736 let sup_r_counter = ref 1;;
737
738 let superposition_right newmeta (metasenv, context, ugraph) table target =
739   let module C = Cic in
740   let module S = CicSubstitution in
741   let module M = CicMetaSubst in
742   let module HL = HelmLibraryObjects in
743   let module CR = CicReduction in
744   let module U = Utils in
745   let _, eqproof, (eq_ty, left, right, ordering), newmetas, args = target in
746   let metasenv' = metasenv @ newmetas in
747   let maxmeta = ref newmeta in
748   let res1, res2 =
749     match ordering with
750     | U.Gt -> fst (betaexpand_term metasenv' context ugraph table 0 left), []
751     | U.Lt -> [], fst (betaexpand_term metasenv' context ugraph table 0 right)
752     | _ ->
753         let res l r =
754           List.filter
755             (fun (_, subst, _, _, _) ->
756                let subst = (* M. *)apply_subst subst in
757                let o = !Utils.compare_terms (subst l) (subst r) in
758                o <> U.Lt && o <> U.Le)
759             (fst (betaexpand_term metasenv' context ugraph table 0 l))
760         in
761         (res left right), (res right left)
762   in
763   let build_new ordering (bo, s, m, ug, (eq_found, eq_URI)) =
764
765     let time1 = Unix.gettimeofday () in
766     
767     let pos, (_, proof', (ty, what, other, _), menv', args') = eq_found in
768     let what, other = if pos = Utils.Left then what, other else other, what in
769     let newgoal, newproof =
770       let bo' = (* M. *)apply_subst s (S.subst other bo) in
771       let t' =
772         let name = C.Name ("x_SupR_" ^ (string_of_int !sup_r_counter)) in
773         incr sup_r_counter;
774         let l, r =
775           if ordering = U.Gt then bo, S.lift 1 right else S.lift 1 left, bo in
776         (name, ty, S.lift 1 eq_ty, l, r)
777       in
778 (*       let bo'' = *)
779 (*         C.Appl ( *)
780 (*           [C.MutInd (HL.Logic.eq_URI, 0, []); S.lift 1 eq_ty] @ *)
781 (*             if ordering = U.Gt then [S.lift 1 bo'; S.lift 1 right] *)
782 (*             else [S.lift 1 left; S.lift 1 bo']) *)
783 (*       in *)
784 (*       let t' = *)
785 (*         let name = C.Name ("x_SupR_" ^ (string_of_int !sup_r_counter)) in *)
786 (*         incr sup_r_counter; *)
787 (*         C.Lambda (name, ty, bo'') *)
788 (*       in *)
789       bo',
790       Inference.ProofBlock (s, eq_URI, t', eq_found, eqproof(* target *))
791 (*       (\* M. *\)apply_subst s *)
792 (*         (C.Appl [C.Const (eq_URI, []); ty; what; t'; *)
793 (*                  eqproof; other; proof']) *)
794     in
795     let newmeta, newequality = 
796       let left, right =
797         if ordering = U.Gt then newgoal, (* M. *)apply_subst s right
798         else (* M. *)apply_subst s left, newgoal in
799       let neworder = !Utils.compare_terms left right 
800       and newmenv = newmetas @ menv'
801       and newargs = args @ args' in
802       let eq' =
803         let w = Utils.compute_equality_weight eq_ty left right in
804         (w, newproof, (eq_ty, left, right, neworder), newmenv, newargs)
805       and env = (metasenv, context, ugraph) in
806       let newm, eq' = Inference.fix_metas !maxmeta eq' in
807       newm, eq'
808     in
809     maxmeta := newmeta;
810
811     let time2 = Unix.gettimeofday () in
812     build_newtarget_time := !build_newtarget_time +. (time2 -. time1);
813
814     newequality
815   in
816
817 (*   let build_new = *)
818 (*     let profile = CicUtil.profile "Indexing.superposition_right.build_new" in *)
819 (*     (fun o e -> profile (build_new o) e) *)
820 (*   in *)
821   
822   let new1 = List.map (build_new U.Gt) res1
823   and new2 = List.map (build_new U.Lt) res2 in
824   let ok = function
825     | _, _, (_, left, right, _), _, _ ->
826         not (fst (CR.are_convertible context left right ugraph))
827   in
828   (!maxmeta,
829    (List.filter ok (new1 @ new2)))
830 ;;