]> matita.cs.unibo.it Git - helm.git/blob - components/tactics/paramodulation/saturation.ml
f8c20d0e3b61250633e5dc4841fabe932b911470
[helm.git] / components / tactics / paramodulation / saturation.ml
1 (* Copyright (C) 2005, HELM Team.
2  * 
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.
6  * 
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.
11  * 
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.
16  *
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,
20  * MA  02111-1307, USA.
21  * 
22  * For details, see the HELM World-Wide-Web page,
23  * http://cs.unibo.it/helm/.
24  *)
25
26 (* $Id$ *)
27
28 open Inference;;
29 open Utils;;
30
31 (* set to false to disable paramodulation inside auto_tac *)
32 let connect_to_auto = true;;
33
34
35 (* profiling statistics... *)
36 let infer_time = ref 0.;;
37 let forward_simpl_time = ref 0.;;
38 let forward_simpl_new_time = ref 0.;;
39 let backward_simpl_time = ref 0.;;
40 let passive_maintainance_time = ref 0.;;
41
42 (* limited-resource-strategy related globals *)
43 let processed_clauses = ref 0;; (* number of equalities selected so far... *)
44 let time_limit = ref 0.;; (* in seconds, settable by the user... *)
45 let start_time = ref 0.;; (* time at which the execution started *)
46 let elapsed_time = ref 0.;;
47 (* let maximal_weight = ref None;; *)
48 let maximal_retained_equality = ref None;;
49
50 (* equality-selection related globals *)
51 let use_fullred = ref true;;
52 let weight_age_ratio = ref 6 (* 5 *);; (* settable by the user *)
53 let weight_age_counter = ref !weight_age_ratio ;;
54 let symbols_ratio = ref 0 (* 3 *);;
55 let symbols_counter = ref 0;;
56
57 (* non-recursive Knuth-Bendix term ordering by default *)
58 (* Utils.compare_terms := Utils.rpo;; *)
59 (* Utils.compare_terms := Utils.nonrec_kbo;; *)
60 (* Utils.compare_terms := Utils.ao;; *)
61
62 (* statistics... *)
63 let derived_clauses = ref 0;;
64 let kept_clauses = ref 0;;
65
66 (* index of the greatest Cic.Meta created - TODO: find a better way! *)
67 let maxmeta = ref 0;;
68
69 (* varbiables controlling the search-space *)
70 let maxdepth = ref 3;;
71 let maxwidth = ref 3;;
72
73 type new_proof = 
74   Equality.goal_proof * Equality.proof * Subst.substitution * Cic.metasenv
75 type result =
76   | ParamodulationFailure
77   | ParamodulationSuccess of new_proof option
78 ;;
79
80 type goal = Equality.goal_proof * Cic.metasenv * Cic.term;;
81
82 type theorem = Cic.term * Cic.term * Cic.metasenv;;
83
84 let symbols_of_equality equality = 
85   let (_, _, (_, left, right, _), _,_) = Equality.open_equality equality in
86   let m1 = symbols_of_term left in
87   let m = 
88     TermMap.fold
89       (fun k v res ->
90          try
91            let c = TermMap.find k res in
92            TermMap.add k (c+v) res
93          with Not_found ->
94            TermMap.add k v res)
95       (symbols_of_term right) m1
96   in
97   m
98 ;;
99
100 (* griggio *)
101 module OrderedEquality = struct 
102   type t = Equality.equality
103
104   let compare eq1 eq2 =
105     match Equality.meta_convertibility_eq eq1 eq2 with
106     | true -> 0
107     | false ->
108         let w1, _, (ty,left, right, _), m1,_ = Equality.open_equality eq1 in
109         let w2, _, (ty',left', right', _), m2,_ = Equality.open_equality eq2 in
110         match Pervasives.compare w1 w2 with
111         | 0 -> 
112             let res = (List.length m1) - (List.length m2) in 
113             if res <> 0 then res else 
114               Equality.compare eq1 eq2
115         | res -> res 
116 end 
117
118 module EqualitySet = Set.Make(OrderedEquality);;
119
120 exception Empty_list;;
121
122 let passive_is_empty = function
123   | ([], _), _ -> true
124   | _ -> false
125 ;;
126
127
128 let size_of_passive ((passive_list, ps), _) = List.length passive_list
129 (* EqualitySet.cardinal ps *)
130 ;;
131
132
133 let size_of_active (active_list, _) = List.length active_list
134 ;;
135
136 let age_factor = 0.01;;
137
138 (**
139    selects one equality from passive. The selection strategy is a combination
140    of weight, age and goal-similarity
141 *)
142
143 let rec select env goals passive =
144   processed_clauses := !processed_clauses + 1;
145   let goal =
146     match (List.rev goals) with (_, goal::_)::_ -> goal | _ -> assert false
147   in
148   let (pos_list, pos_set), passive_table = passive in
149   let remove eq l = List.filter (fun e -> Equality.compare e eq <> 0) l in
150   if !weight_age_ratio > 0 then
151     weight_age_counter := !weight_age_counter - 1;
152   match !weight_age_counter with
153   | 0 -> (
154       weight_age_counter := !weight_age_ratio;
155       let rec skip_giant pos_list pos_set passive_table =
156         match pos_list with
157           | (hd:EqualitySet.elt)::tl ->
158               let w,_,_,_,_ = Equality.open_equality hd in
159               let passive_table =
160                 Indexing.remove_index passive_table hd
161               in 
162               let pos_set = EqualitySet.remove hd pos_set in
163                 if w < 50 then
164                   hd, ((tl, pos_set), passive_table)
165                 else
166                   (prerr_endline ("\n\n\nGIANT SKIPPED: "^string_of_int w^"\n\n\n");
167                   skip_giant tl pos_set passive_table)
168           | _ -> assert false
169       in
170         skip_giant pos_list pos_set passive_table)
171   | _ when (!symbols_counter > 0) -> 
172      (symbols_counter := !symbols_counter - 1;
173       let cardinality map =
174         TermMap.fold (fun k v res -> res + v) map 0
175       in
176       let symbols =
177         let _, _, term = goal in
178         symbols_of_term term
179       in
180       let card = cardinality symbols in
181       let foldfun k v (r1, r2) = 
182         if TermMap.mem k symbols then
183           let c = TermMap.find k symbols in
184           let c1 = abs (c - v) in
185           let c2 = v - c1 in
186           r1 + c2, r2 + c1
187         else
188           r1, r2 + v
189       in
190       let f equality (i, e) =
191         let common, others =
192           TermMap.fold foldfun (symbols_of_equality equality) (0, 0)
193         in
194         let c = others + (abs (common - card)) in
195         if c < i then (c, equality)
196         else (i, e)
197       in
198       let e1 = EqualitySet.min_elt pos_set in
199       let initial =
200         let common, others = 
201           TermMap.fold foldfun (symbols_of_equality e1) (0, 0)
202         in
203         (others + (abs (common - card))), e1
204       in
205       let _, current = EqualitySet.fold f pos_set initial in
206       let passive_table =
207         Indexing.remove_index passive_table current
208       in
209         current,
210       ((remove current pos_list, EqualitySet.remove current pos_set),
211        passive_table))
212   | _ ->
213       symbols_counter := !symbols_ratio;
214       let current = EqualitySet.min_elt pos_set in
215       let passive_table =
216         Indexing.remove_index passive_table current
217       in
218         current, 
219       ((remove current pos_list, EqualitySet.remove current pos_set),
220       passive_table)
221 ;;
222
223 let filter_dependent passive id =
224   prerr_endline ("+++++++++++++++passives "^
225                    ( string_of_int (size_of_passive passive)));
226   let (pos_list, pos_set), passive_table = passive in
227   let passive =
228     List.fold_right
229       (fun eq ((list,set),table) ->
230          if Equality.depend eq id then
231            (let _,_,_,_,id_eq = Equality.open_equality eq in
232               if id_eq = 9228 then 
233                 prerr_endline ("\n\n--------filtering "^(string_of_int id_eq));
234            ((list, 
235              EqualitySet.remove eq set),
236             Indexing.remove_index table eq))
237          else ((eq::list, set),table))
238       pos_list (([],pos_set),passive_table) in
239   prerr_endline ("+++++++++++++++passives "^
240                    ( string_of_int (size_of_passive passive)));  
241   passive
242 ;;
243
244
245 (* initializes the passive set of equalities *)
246 let make_passive pos =
247   let set_of equalities =
248     List.fold_left (fun s e -> EqualitySet.add e s) EqualitySet.empty equalities
249   in
250   let table =
251       List.fold_left (fun tbl e -> Indexing.index tbl e) Indexing.empty pos
252   in
253   (pos, set_of pos),
254   table
255 ;;
256
257
258 let make_active () =
259   [], Indexing.empty
260 ;;
261
262
263 (* adds to passive a list of equalities new_pos *)
264 let add_to_passive passive new_pos =
265   let (pos_list, pos_set), table = passive in
266   let ok set equality = not (EqualitySet.mem equality set) in
267   let pos = List.filter (ok pos_set) new_pos in
268   let table = 
269      List.fold_left (fun tbl e -> Indexing.index tbl e) table pos 
270   in
271   let add set equalities =
272     List.fold_left (fun s e -> EqualitySet.add e s) set equalities
273   in
274   (pos_list @ pos, add pos_set pos),
275   table
276 ;;
277
278 (* TODO *)
279 (* removes from passive equalities that are estimated impossible to activate
280    within the current time limit *)
281 let prune_passive howmany (active, _) passive =
282   let (pl, ps), tbl = passive in
283   let howmany = float_of_int howmany
284   and ratio = float_of_int !weight_age_ratio in
285   let round v =
286     let t = ceil v in 
287     int_of_float (if t -. v < 0.5 then t else v)
288   in
289   let in_weight = round (howmany *. ratio /. (ratio +. 1.))
290   and in_age = round (howmany /. (ratio +. 1.)) in 
291   debug_print
292     (lazy (Printf.sprintf "in_weight: %d, in_age: %d\n" in_weight in_age));
293   let counter = ref !symbols_ratio in
294   let rec pickw w ps =
295     if w > 0 then
296       if !counter > 0 then
297         let _ =
298           counter := !counter - 1;
299           if !counter = 0 then counter := !symbols_ratio in
300         let e = EqualitySet.min_elt ps in
301         let ps' = pickw (w-1) (EqualitySet.remove e ps) in
302           EqualitySet.add e ps'
303       else
304         let e = EqualitySet.min_elt ps in
305         let ps' = pickw (w-1) (EqualitySet.remove e ps) in
306         EqualitySet.add e ps'        
307     else
308       EqualitySet.empty
309   in
310   let ps = pickw in_weight ps in
311   let rec picka w s l =
312     if w > 0 then
313       match l with
314       | [] -> w, s, []
315       | hd::tl when not (EqualitySet.mem hd s) ->
316           let w, s, l = picka (w-1) s tl in
317           w, EqualitySet.add hd s, hd::l
318       | hd::tl ->
319           let w, s, l = picka w s tl in
320           w, s, hd::l
321     else
322       0, s, l
323   in
324   let _, ps, pl = picka in_age ps pl in
325   if not (EqualitySet.is_empty ps) then
326     maximal_retained_equality := Some (EqualitySet.max_elt ps); 
327   let tbl =
328     EqualitySet.fold
329       (fun e tbl -> Indexing.index tbl e) ps Indexing.empty
330   in
331   (pl, ps), tbl  
332 ;;
333
334
335 (** inference of new equalities between current and some in active *)
336 let infer env current (active_list, active_table) =
337   let (_,c,_) = env in 
338   if Utils.debug_metas then
339     (ignore(Indexing.check_target c current "infer1");
340      ignore(List.map (function current -> Indexing.check_target c current "infer2") active_list)); 
341   let new_pos = 
342     let maxm, res =
343       Indexing.superposition_right !maxmeta env active_table current in
344       if Utils.debug_metas then
345         ignore(List.map 
346                  (function current -> 
347                     Indexing.check_target c current "sup0") res);
348       maxmeta := maxm;
349       let rec infer_positive table = function
350         | [] -> []
351         | equality::tl ->
352             let maxm, res =
353               Indexing.superposition_right !maxmeta env table equality in
354               maxmeta := maxm;
355               if Utils.debug_metas then
356                 ignore
357                   (List.map 
358                      (function current -> 
359                         Indexing.check_target c current "sup2") res);
360               let pos = infer_positive table tl in
361               res @ pos
362       in
363       let maxm, copy_of_current = Equality.fix_metas !maxmeta current in
364         maxmeta := maxm;
365       let curr_table = Indexing.index Indexing.empty current in
366       let pos = infer_positive curr_table (copy_of_current::active_list) 
367       in 
368       if Utils.debug_metas then 
369         ignore(List.map 
370                  (function current -> 
371                     Indexing.check_target c current "sup3") pos);
372         res @ pos
373   in
374   derived_clauses := !derived_clauses + (List.length new_pos);
375   match !maximal_retained_equality with
376     | None -> new_pos
377     | Some eq ->
378       ignore(assert false);
379       (* if we have a maximal_retained_equality, we can discard all equalities
380          "greater" than it, as they will never be reached...  An equality is
381          greater than maximal_retained_equality if it is bigger
382          wrt. OrderedEquality.compare and it is less similar than
383          maximal_retained_equality to the current goal *)
384         List.filter (fun e -> OrderedEquality.compare e eq <= 0) new_pos
385 ;;
386
387 let check_for_deep_subsumption env active_table eq =
388   let _,_,(eq_ty, left, right, order),metas,id = Equality.open_equality eq in
389   if id = 14242 then assert false;
390   
391   let check_subsumed deep l r = 
392     let eqtmp = 
393       Equality.mk_tmp_equality(0,(eq_ty,l,r,Utils.Incomparable),metas)in
394     match Indexing.subsumption env active_table eqtmp with
395     | None -> false
396     | Some (s,eq') -> 
397         prerr_endline 
398           ("\n\n " ^ Equality.string_of_equality ~env eq ^ 
399           "\nis"^(if deep then " CONTEXTUALLY " else " ")^"subsumed by \n " ^ 
400           Equality.string_of_equality ~env eq' ^ "\n\n");
401         true        
402   in 
403   let rec aux b (ok_so_far, subsumption_used) t1 t2  = 
404     match t1,t2 with
405       | t1, t2 when not ok_so_far -> ok_so_far, subsumption_used
406       | t1, t2 when subsumption_used -> t1 = t2, subsumption_used
407 (* VERSIONE ERRATA 
408       | Cic.Appl (h1::l),Cic.Appl (h2::l') when h1 = h2 ->
409           let rc = check_subsumed b t1 t1 in 
410             if rc then 
411               true, true
412             else if h1 = h2 then
413               (try 
414                  List.fold_left2 
415                    (fun (ok_so_far, subsumption_used) t t' -> 
416                       aux true (ok_so_far, subsumption_used) t t')
417                    (ok_so_far, subsumption_used) l l'
418                with Invalid_argument _ -> false,subsumption_used)
419             else
420               false, subsumption_used
421       | _ -> false, subsumption_used *)
422       | Cic.Appl (h1::l),Cic.Appl (h2::l') ->
423           let rc = check_subsumed b t1 t2 in 
424             if rc then 
425               true, true
426             else if h1 = h2 then
427               (try 
428                  List.fold_left2 
429                    (fun (ok_so_far, subsumption_used) t t' -> 
430                       aux true (ok_so_far, subsumption_used) t t')
431                    (ok_so_far, subsumption_used) l l'
432                with Invalid_argument _ -> false,subsumption_used)
433             else
434               false, subsumption_used
435     | _ -> false, subsumption_used 
436   in
437   fst (aux false (true,false) left right)
438 ;;
439
440 (*
441 let check_for_deep env active_table eq =
442   match Indexing.subsumption env active_table eq with
443   | None -> false
444   | Some _ -> true
445 ;;
446 *)
447
448 let profiler = HExtlib.profile "check_for_deep";;
449
450 let check_for_deep_subsumption env active_table eq = 
451   profiler.HExtlib.profile (check_for_deep_subsumption env active_table) eq
452 ;;
453
454 (* buttare via sign *)
455
456 (** simplifies current using active and passive *)
457 let forward_simplify env (sign,current) ?passive (active_list, active_table) =
458   let _, context, _ = env in
459   let passive_table =
460     match passive with
461     | None -> None
462     | Some ((_, _), pt) -> Some pt
463   in
464   let demodulate table current = 
465     let newmeta, newcurrent =
466       Indexing.demodulation_equality !maxmeta env table sign current in
467     maxmeta := newmeta;
468     if Equality.is_identity env newcurrent then
469 (*         debug_print  *)
470 (*           (lazy *)
471 (*              (Printf.sprintf "\ncurrent was: %s\nnewcurrent is: %s\n" *)
472 (*                 (string_of_equality current) *)
473 (*                 (string_of_equality newcurrent))); *)
474 (*         debug_print *)
475 (*           (lazy *)
476 (*              (Printf.sprintf "active is: %s" *)
477 (*                 (String.concat "\n"  *)
478 (*                    (List.map (fun (_, e) -> (string_of_equality e)) active_list)))); *)
479         None
480     else
481       Some newcurrent
482   in
483   let rec demod current =
484     if Utils.debug_metas then
485       ignore (Indexing.check_target context current "demod0");
486     let res = demodulate active_table current in
487       if Utils.debug_metas then
488         ignore ((function None -> () | Some x -> 
489                    ignore (Indexing.check_target context x "demod1");()) res);
490     match res with
491     | None -> None
492     | Some newcurrent ->
493         match passive_table with
494         | None -> res
495         | Some passive_table -> 
496             match demodulate passive_table newcurrent with
497               | None -> None
498               | Some newnewcurrent -> 
499                   if Equality.compare newcurrent newnewcurrent <> 0 then 
500                     demod newnewcurrent
501                   else Some newnewcurrent
502   in 
503   let res = demod current in
504   match res with
505   | None -> None
506   | Some c ->
507       if Indexing.in_index active_table c then
508         None
509       else
510         match passive_table with
511         | None -> 
512             if check_for_deep_subsumption env active_table c then
513               None
514             else 
515               res
516 (*
517             if Indexing.subsumption env active_table c = None then
518               res
519             else
520               None
521 *)
522         | Some passive_table ->
523             if Indexing.in_index passive_table c then None
524             else 
525               if check_for_deep_subsumption env active_table c then
526                 None
527               else 
528 (*              if Indexing.subsumption env active_table c = None then*)
529                 (match Indexing.subsumption env passive_table c with
530                 | None -> res
531                 | Some (_,c') -> 
532                     None
533                     (*prerr_endline "\n\nPESCO DALLE PASSIVE LA PIU' GENERALE\n\n";
534                     Some c'*))
535 (*
536               else
537                 None
538 *)
539 ;;
540
541 type fs_time_info_t = {
542   mutable build_all: float;
543   mutable demodulate: float;
544   mutable subsumption: float;
545 };;
546
547 let fs_time_info = { build_all = 0.; demodulate = 0.; subsumption = 0. };;
548
549
550 (** simplifies new using active and passive *)
551 let forward_simplify_new env new_pos ?passive active =
552   if Utils.debug_metas then
553     begin
554       let m,c,u = env in
555         ignore(List.map 
556         (fun current -> Indexing.check_target c current "forward new pos") 
557       new_pos;)
558     end;
559   let t1 = Unix.gettimeofday () in
560
561   let active_list, active_table = active in
562   let passive_table =
563     match passive with
564     | None -> None
565     | Some ((_, _), pt) -> Some pt
566   in
567   let t2 = Unix.gettimeofday () in
568   fs_time_info.build_all <- fs_time_info.build_all +. (t2 -. t1);
569   
570   let demodulate sign table target =
571     let newmeta, newtarget =
572       Indexing.demodulation_equality !maxmeta env table sign target in
573     maxmeta := newmeta;
574     newtarget
575   in
576   let t1 = Unix.gettimeofday () in
577   (* we could also demodulate using passive. Currently we don't *)
578   let new_pos =
579     List.map (demodulate Positive active_table) new_pos 
580   in
581   let t2 = Unix.gettimeofday () in
582   fs_time_info.demodulate <- fs_time_info.demodulate +. (t2 -. t1);
583
584   let new_pos_set =
585     List.fold_left
586       (fun s e ->
587          if not (Equality.is_identity env e) then
588            if EqualitySet.mem e s then s
589            else EqualitySet.add e s
590          else s)
591       EqualitySet.empty new_pos
592   in
593   let new_pos = EqualitySet.elements new_pos_set in
594
595   let subs =
596     match passive_table with
597     | None ->
598         (fun e -> (Indexing.subsumption env active_table e = None))
599     | Some passive_table ->
600         (fun e -> ((Indexing.subsumption env active_table e = None) &&
601                          (Indexing.subsumption env passive_table e = None)))
602   in
603 (*   let t1 = Unix.gettimeofday () in *)
604 (*   let t2 = Unix.gettimeofday () in *)
605 (*   fs_time_info.subsumption <- fs_time_info.subsumption +. (t2 -. t1); *)
606   let is_duplicate =
607     match passive_table with
608     | None ->
609         (fun e -> not (Indexing.in_index active_table e))
610     | Some passive_table ->
611         (fun e ->
612            not ((Indexing.in_index active_table e) ||
613                   (Indexing.in_index passive_table e)))
614   in
615   List.filter subs (List.filter is_duplicate new_pos)
616 ;;
617
618
619 (** simplifies a goal with equalities in active and passive *)  
620 let rec simplify_goal env goal ?passive (active_list, active_table) =
621   let passive_table =
622     match passive with
623     | None -> None
624     | Some ((_, _), pt) -> Some pt
625   in
626   let demodulate table goal = 
627     let changed, newmeta, newgoal =
628       Indexing.demodulation_goal !maxmeta env table goal in
629     maxmeta := newmeta;
630     changed, newgoal
631   in
632   let changed, goal =
633     match passive_table with
634     | None -> demodulate active_table goal
635     | Some passive_table ->
636         let changed, goal = demodulate active_table goal in
637 (*        let changed', goal = demodulate passive_table goal in*)
638         (changed (*|| changed'*)), goal
639   in
640   changed,
641   if not changed then 
642     goal 
643   else 
644     snd (simplify_goal env goal ?passive (active_list, active_table)) 
645 ;;
646
647
648 let simplify_goals env goals ?passive active =
649   let a_goals, p_goals = goals in
650   let p_goals = 
651     List.map
652       (fun (d, gl) ->
653          let gl =
654            List.map (fun g -> snd (simplify_goal env g ?passive active)) gl in
655          d, gl)
656       p_goals
657   in
658   let goals =
659     List.fold_left
660       (fun (a, p) (d, gl) ->
661          let changed = ref false in
662          let gl =
663            List.map
664              (fun g ->
665                 let c, g = simplify_goal env g ?passive active in
666                 changed := !changed || c; g) gl in
667          if !changed then (a, (d, gl)::p) else ((d, gl)::a, p))
668       ([], p_goals) a_goals
669   in
670   goals
671 ;;
672
673
674 (** simplifies active usign new *)
675 let backward_simplify_active env new_pos new_table min_weight active =
676   let active_list, active_table = active in
677   let active_list, newa, pruned = 
678     List.fold_right
679       (fun equality (res, newn,pruned) ->
680          let ew, _, _, _,id = Equality.open_equality equality in
681          if ew < min_weight then
682            equality::res, newn,pruned
683          else
684            match forward_simplify env (Utils.Positive, equality) (new_pos, new_table) with
685            | None -> res, newn, id::pruned
686            | Some e ->
687                if Equality.compare equality e = 0 then
688                  e::res, newn, pruned
689                else 
690                  res, e::newn, pruned)
691       active_list ([], [],[])
692   in
693   let find eq1 where =
694     List.exists (Equality.meta_convertibility_eq eq1) where
695   in
696   let id_of_eq eq = 
697     let _, _, _, _,id = Equality.open_equality eq in id
698   in
699   let ((active1,pruned),tbl), newa =
700     List.fold_right
701       (fun eq ((res,pruned), tbl) ->
702          if List.mem eq res then
703            (res, (id_of_eq eq)::pruned),tbl 
704          else if (Equality.is_identity env eq) || (find eq res) then (
705            (res, (id_of_eq eq)::pruned),tbl
706          ) 
707          else
708            (eq::res,pruned), Indexing.index tbl eq)
709       active_list (([],pruned), Indexing.empty),
710     List.fold_right
711       (fun eq p ->
712          if (Equality.is_identity env eq) then p
713          else eq::p)
714       newa []
715   in
716   if List.length active1 <> List.length (fst active) then
717     prerr_endline "\n\n\nMANCAVANO DELLE PRUNED!!!!\n\n\n";
718   match newa with
719   | [] -> (active1,tbl), None, pruned 
720   | _ -> (active1,tbl), Some newa, pruned
721 ;;
722
723
724 (** simplifies passive using new *)
725 let backward_simplify_passive env new_pos new_table min_weight passive =
726   let (pl, ps), passive_table = passive in
727   let f sign equality (resl, ress, newn) =
728     let ew, _, _, _ , _ = Equality.open_equality equality in
729     if ew < min_weight then
730       equality::resl, ress, newn
731     else
732       match forward_simplify env (sign, equality) (new_pos, new_table) with
733       | None -> resl, EqualitySet.remove equality ress, newn
734       | Some e ->
735           if equality = e then
736             equality::resl, ress, newn
737           else
738             let ress = EqualitySet.remove equality ress in
739               resl, ress, e::newn
740   in
741   let pl, ps, newp = List.fold_right (f Positive) pl ([], ps, []) in
742   let passive_table =
743     List.fold_left
744       (fun tbl e -> Indexing.index tbl e) Indexing.empty pl
745   in
746   match newp with
747   | [] -> ((pl, ps), passive_table), None
748   |  _ -> ((pl, ps), passive_table), Some (newp)
749 ;;
750
751 let build_table equations =
752     List.fold_left
753       (fun (l, t, w) e ->
754          let ew, _, _, _ , _ = Equality.open_equality e in
755          e::l, Indexing.index t e, min ew w)
756       ([], Indexing.empty, 1000000) equations
757 ;;
758   
759
760 let backward_simplify env new' ?passive active =
761   let new_pos, new_table, min_weight = build_table new' in
762 (*
763     List.fold_left
764       (fun (l, t, w) e ->
765          let ew, _, _, _ , _ = Equality.open_equality e in
766          e::l, Indexing.index t e, min ew w)
767       ([], Indexing.empty, 1000000) new'
768   in
769 *)
770   let active, newa, pruned =
771     backward_simplify_active env new_pos new_table min_weight active in
772   match passive with
773   | None ->
774       active, (make_passive []), newa, None, pruned
775   | Some passive ->
776      active, passive, newa, None, pruned
777 (* prova
778       let passive, newp =
779         backward_simplify_passive env new_pos new_table min_weight passive in
780       active, passive, newa, newp *)
781 ;;
782
783
784 let close env new' given =
785   let new_pos, new_table, min_weight =
786     List.fold_left
787       (fun (l, t, w) e ->
788          let ew, _, _, _ , _ = Equality.open_equality e in
789          e::l, Indexing.index t e, min ew w)
790       ([], Indexing.empty, 1000000) (snd new')
791   in
792   List.fold_left
793     (fun p c ->
794        let pos = infer env c (new_pos,new_table) in
795          pos@p)
796     [] given 
797 ;;
798
799 let is_commutative_law eq =
800   let w, proof, (eq_ty, left, right, order), metas , _ = 
801     Equality.open_equality eq 
802   in
803     match left,right with
804         Cic.Appl[f1;Cic.Meta _ as a1;Cic.Meta _ as b1], 
805         Cic.Appl[f2;Cic.Meta _ as a2;Cic.Meta _ as b2] ->
806           f1 = f2 && a1 = b2 && a2 = b1
807       | _ -> false
808 ;;
809
810 let prova env new' active = 
811   let given = List.filter is_commutative_law (fst active) in
812   let _ =
813     debug_print
814       (lazy
815          (Printf.sprintf "symmetric:\n%s\n"
816             (String.concat "\n"
817                (List.map
818                   (fun e -> Equality.string_of_equality ~env e)
819                    given)))) in
820     close env new' given
821 ;;
822
823 (* returns an estimation of how many equalities in passive can be activated
824    within the current time limit *)
825 let get_selection_estimate () =
826   elapsed_time := (Unix.gettimeofday ()) -. !start_time;
827   (*   !processed_clauses * (int_of_float (!time_limit /. !elapsed_time)) *)
828   int_of_float (
829     ceil ((float_of_int !processed_clauses) *.
830             ((!time_limit (* *. 2. *)) /. !elapsed_time -. 1.)))
831 ;;
832
833
834 (** initializes the set of goals *)
835 let make_goals goal =
836   let active = []
837   and passive = [0, [goal]] in
838   active, passive
839 ;;
840
841
842 (** initializes the set of theorems *)
843 let make_theorems theorems =
844   theorems, []
845 ;;
846
847
848 let activate_goal (active, passive) =
849   if active = [] then
850     match passive with
851     | goal_conj::tl -> true, (goal_conj::active, tl)
852     | [] -> false, (active, passive)
853   else  
854     true, (active,passive)
855 ;;
856
857
858 let activate_theorem (active, passive) =
859   match passive with
860   | theorem::tl -> true, (theorem::active, tl)
861   | [] -> false, (active, passive)
862 ;;
863
864
865
866 let simplify_theorems env theorems ?passive (active_list, active_table) =
867   let pl, passive_table =
868     match passive with
869     | None -> [], None
870     | Some ((pn, _), (pp, _), pt) ->
871         let pn = List.map (fun e -> (Negative, e)) pn
872         and pp = List.map (fun e -> (Positive, e)) pp in
873         pn @ pp, Some pt
874   in
875   let a_theorems, p_theorems = theorems in
876   let demodulate table theorem =
877     let newmeta, newthm =
878       Indexing.demodulation_theorem !maxmeta env table theorem in
879     maxmeta := newmeta;
880     theorem != newthm, newthm
881   in
882   let foldfun table (a, p) theorem =
883     let changed, theorem = demodulate table theorem in
884     if changed then (a, theorem::p) else (theorem::a, p)
885   in
886   let mapfun table theorem = snd (demodulate table theorem) in
887   match passive_table with
888   | None ->
889       let p_theorems = List.map (mapfun active_table) p_theorems in
890       List.fold_left (foldfun active_table) ([], p_theorems) a_theorems
891   | Some passive_table ->
892       let p_theorems = List.map (mapfun active_table) p_theorems in
893       let p_theorems, a_theorems =
894         List.fold_left (foldfun active_table) ([], p_theorems) a_theorems in
895       let p_theorems = List.map (mapfun passive_table) p_theorems in
896       List.fold_left (foldfun passive_table) ([], p_theorems) a_theorems
897 ;;
898
899
900 let rec simpl env e others others_simpl =
901   let active = others @ others_simpl in
902   let tbl =
903     List.fold_left
904       (fun t e -> Indexing.index t e)
905       Indexing.empty active
906   in
907   let res = forward_simplify env (Positive,e) (active, tbl) in
908     match others with
909       | hd::tl -> (
910           match res with
911             | None -> simpl env hd tl others_simpl
912             | Some e -> simpl env hd tl (e::others_simpl)
913         )
914       | [] -> (
915           match res with
916             | None -> others_simpl
917             | Some e -> e::others_simpl
918         )
919 ;;
920
921 let simplify_equalities env equalities =
922   debug_print
923     (lazy 
924        (Printf.sprintf "equalities:\n%s\n"
925           (String.concat "\n"
926              (List.map Equality.string_of_equality equalities))));
927   debug_print (lazy "SIMPLYFYING EQUALITIES...");
928   match equalities with
929     | [] -> []
930     | hd::tl ->
931         let res =
932           List.rev (simpl env hd tl [])
933         in
934           debug_print
935             (lazy
936                (Printf.sprintf "equalities AFTER:\n%s\n"
937                   (String.concat "\n"
938                      (List.map Equality.string_of_equality res))));
939           res
940 ;;
941
942 let print_goals goals = 
943   (String.concat "\n"
944      (List.map
945         (fun (d, gl) ->
946            let gl' =
947              List.map
948                (fun (p, _, t) ->
949                   (* (string_of_proof p) ^ ", " ^ *) (CicPp.ppterm t)) gl
950            in
951            Printf.sprintf "%d: %s" d (String.concat "; " gl')) goals))
952 ;;
953
954 let check_if_goal_is_subsumed env (goalproof,menv,ty) table =
955   prerr_endline "check_goal_subsumed";
956   match ty with
957   | Cic.Appl[Cic.MutInd(uri,_,_);eq_ty;left;right] 
958     when UriManager.eq uri (LibraryObjects.eq_URI ()) ->
959       (let goal_equation = 
960          Equality.mk_equality
961            (0,Equality.Exact (Cic.Implicit None),(eq_ty,left,right,Eq),menv) 
962       in
963       match Indexing.subsumption env table goal_equation with
964         | Some (subst, equality ) ->
965             let (_,p,(ty,l,r,_),m,id) = Equality.open_equality equality in
966             let cicmenv = Subst.apply_subst_metasenv subst (m @ menv) in
967             Some (goalproof, p, subst, cicmenv)
968         | None -> None)
969   | _ -> None
970 ;;
971
972 let counter = ref 0
973
974 (** given-clause algorithm with full reduction strategy *)
975 let rec given_clause_fullred dbd env goals theorems ~passive active =
976   let goals = simplify_goals env goals ~passive active in 
977   let _,context,_ = env in
978   let ok, goals = activate_goal goals in
979 (*   let theorems = simplify_theorems env theorems ~passive active in *)
980   if ok then
981     let names = List.map (HExtlib.map_option (fun (name,_) -> name)) context in 
982     let _, _, t = List.hd (snd (List.hd (fst goals))) in
983     let _ = prerr_endline ("goal activated = " ^ (CicPp.pp t names)) in
984 (*     let _ = *)
985 (*       debug_print *)
986 (*         (lazy *)
987 (*            (Printf.sprintf "\ngoals = \nactive\n%s\npassive\n%s\n" *)
988 (*               (print_goals (fst goals)) (print_goals (snd goals)))); *)
989 (*       let current = List.hd (fst goals) in *)
990 (*       let p, _, t = List.hd (snd current) in *)
991 (*       debug_print *)
992 (*         (lazy *)
993 (*            (Printf.sprintf "goal activated:\n%s\n%s\n" *)
994 (*               (CicPp.ppterm t) (string_of_proof p))); *)
995 (*     in *)
996     let ok, proof =
997       (* apply_goal_to_theorems dbd env theorems ~passive active goals in *)
998       let iseq uri = UriManager.eq uri (LibraryObjects.eq_URI ()) in
999       match (fst goals) with
1000         | (_,[goalproof,m,Cic.Appl[Cic.MutInd(uri,_,ens);eq_ty;left;right]])::_ 
1001             when left = right && iseq uri -> 
1002             let reflproof = Equality.Exact (Equality.refl_proof eq_ty left) in
1003             true, Some (goalproof, reflproof, Subst.empty_subst,m)
1004         | (_, [goal])::_ ->
1005             (match check_if_goal_is_subsumed env goal (snd active) with
1006             | None -> false,None
1007             | Some p ->
1008                 prerr_endline "Proof found by subsumption!";
1009                 true, Some p)
1010         | _ -> false, None
1011     in 
1012     if ok then
1013       ( prerr_endline "esco qui";
1014         (*
1015         let s = Printf.sprintf "actives:\n%s\n"
1016           (String.concat "\n"
1017              ((List.map
1018                  (fun (s, e) -> (string_of_sign s) ^ " " ^
1019                     (string_of_equality ~env e))
1020                  (fst active)))) in
1021         let sp = Printf.sprintf "passives:\n%s\n"
1022           (String.concat "\n"
1023              (List.map
1024                 (string_of_equality ~env)
1025                 (let x,y,_ = passive in (fst x)@(fst y)))) in
1026           prerr_endline s;
1027           prerr_endline sp; *)
1028       ParamodulationSuccess (proof))
1029     else
1030       given_clause_fullred_aux dbd env goals theorems passive active
1031   else
1032 (*     let ok', theorems = activate_theorem theorems in *)
1033 (*     if ok' then *)
1034 (*       let ok, goals = apply_theorem_to_goals env theorems active goals in *)
1035 (*       if ok then *)
1036 (*         let proof = *)
1037 (*           match (fst goals) with *)
1038 (*           | (_, [proof, _, _])::_ -> Some proof *)
1039 (*           | _ -> assert false *)
1040 (*         in *)
1041 (*         ParamodulationSuccess (proof, env) *)
1042 (*       else *)
1043 (*         given_clause_fullred_aux env goals theorems passive active *)
1044 (*     else *)
1045       if (passive_is_empty passive) then ParamodulationFailure
1046       else given_clause_fullred_aux dbd env goals theorems passive active
1047     
1048 and given_clause_fullred_aux dbd env goals theorems passive active =
1049   prerr_endline (string_of_int !counter ^ 
1050                  " MAXMETA: " ^ string_of_int !maxmeta ^ 
1051                  " #ACTIVES: " ^ string_of_int (size_of_active active) ^
1052                  " #PASSIVES: " ^ string_of_int (size_of_passive passive));
1053   incr counter;
1054 (*
1055     if !counter mod 10 = 0 then
1056     begin
1057       let size = HExtlib.estimate_size (passive,active) in
1058       let sizep = HExtlib.estimate_size (passive) in
1059       let sizea = HExtlib.estimate_size (active) in
1060       let (l1,s1),(l2,s2), t = passive in 
1061       let sizetbl = HExtlib.estimate_size t in
1062       let sizel = HExtlib.estimate_size (l1,l2) in
1063       let sizes = HExtlib.estimate_size (s1,s2) in
1064
1065       prerr_endline ("SIZE: " ^ string_of_int size);        
1066       prerr_endline ("SIZE P: " ^ string_of_int sizep);        
1067       prerr_endline ("SIZE A: " ^ string_of_int sizea);        
1068       prerr_endline ("SIZE TBL: " ^ string_of_int sizetbl ^ 
1069                        " SIZE L: " ^ string_of_int sizel ^ 
1070                        " SIZE S:" ^ string_of_int sizes);
1071     end;*)
1072 (*
1073   if (size_of_active active) mod 50 = 0 then
1074     (let s = Printf.sprintf "actives:\n%s\n"
1075       (String.concat "\n"
1076          ((List.map
1077              (fun (s, e) -> (string_of_sign s) ^ " " ^
1078                 (string_of_equality ~env e))
1079              (fst active)))) in
1080      let sp = Printf.sprintf "passives:\n%s\n"
1081       (String.concat "\n"
1082          (List.map
1083              (string_of_equality ~env)
1084              (let x,y,_ = passive in (fst x)@(fst y)))) in
1085       prerr_endline s;
1086       prerr_endline sp); *)
1087   let time1 = Unix.gettimeofday () in
1088   let (_,context,_) = env in
1089   let selection_estimate = get_selection_estimate () in
1090   let kept = size_of_passive passive in
1091   let passive =
1092     if !time_limit = 0. || !processed_clauses = 0 then
1093       passive
1094     else if !elapsed_time > !time_limit then (
1095       debug_print (lazy (Printf.sprintf "Time limit (%.2f) reached: %.2f\n"
1096                            !time_limit !elapsed_time));
1097       make_passive [] 
1098     ) else if kept > selection_estimate then (
1099       debug_print
1100         (lazy (Printf.sprintf ("Too many passive equalities: pruning..." ^^
1101                                  "(kept: %d, selection_estimate: %d)\n")
1102                  kept selection_estimate));
1103       prune_passive selection_estimate active passive
1104     ) else
1105       passive
1106   in
1107
1108   let time2 = Unix.gettimeofday () in
1109   passive_maintainance_time := !passive_maintainance_time +. (time2 -. time1);
1110   
1111   kept_clauses := (size_of_passive passive) + (size_of_active active);
1112   match passive_is_empty passive with
1113   | true -> ParamodulationFailure 
1114       (* given_clause_fullred dbd env goals theorems passive active  *)     
1115   | false ->
1116       let current, passive = select env (fst goals) passive in
1117       prerr_endline 
1118         ("Selected = " ^ Equality.string_of_equality ~env current);
1119 (* ^ 
1120            (let w,p,(t,l,r,o),m = current in
1121            " size w: " ^ string_of_int (HExtlib.estimate_size w)^
1122            " size p: " ^ string_of_int (HExtlib.estimate_size p)^
1123            " size t: " ^ string_of_int (HExtlib.estimate_size t)^
1124            " size l: " ^ string_of_int (HExtlib.estimate_size l)^
1125            " size r: " ^ string_of_int (HExtlib.estimate_size r)^
1126            " size o: " ^ string_of_int (HExtlib.estimate_size o)^
1127            " size m: " ^ string_of_int (HExtlib.estimate_size m)^
1128            " size m-c: " ^ string_of_int 
1129              (HExtlib.estimate_size (List.map (fun (x,_,_) -> x) m)))) *)
1130       let time1 = Unix.gettimeofday () in
1131       let res = forward_simplify env (Positive, current) ~passive active in
1132       let time2 = Unix.gettimeofday () in
1133       forward_simpl_time := !forward_simpl_time +. (time2 -. time1);
1134       match res with
1135       | None ->
1136           (* weight_age_counter := !weight_age_counter + 1; *)
1137           given_clause_fullred dbd env goals theorems passive active
1138       | Some current ->
1139 (*          prerr_endline (Printf.sprintf "selected simpl: %s"
1140                                (Equality.string_of_equality ~env current));*)
1141           let t1 = Unix.gettimeofday () in
1142           let new' = infer env current active in
1143           let _ =
1144             debug_print
1145               (lazy
1146                  (Printf.sprintf "new' (senza semplificare):\n%s\n"
1147                     (String.concat "\n"
1148                        (List.map
1149                           (fun e -> "Positive " ^
1150                              (Equality.string_of_equality ~env e)) new'))))
1151           in
1152           let t2 = Unix.gettimeofday () in
1153             infer_time := !infer_time +. (t2 -. t1);
1154             let active =
1155               if Equality.is_identity env current then active
1156               else
1157                 let al, tbl = active in
1158                   al @ [current], Indexing.index tbl current
1159             in
1160             let rec simplify new' active passive =
1161               let t1 = Unix.gettimeofday () in
1162               let new' = forward_simplify_new env new'~passive active in
1163               let t2 = Unix.gettimeofday () in
1164               forward_simpl_new_time :=
1165                 !forward_simpl_new_time +. (t2 -. t1);
1166               let t1 = Unix.gettimeofday () in
1167               let active, passive, newa, retained, pruned =
1168                 backward_simplify env new' ~passive  active in
1169               let passive = 
1170                 List.fold_left filter_dependent passive pruned in
1171               let t2 = Unix.gettimeofday () in
1172                 backward_simpl_time := !backward_simpl_time +. (t2 -. t1);
1173               match newa, retained with
1174               | None, None -> active, passive, new'
1175               | Some p, None
1176               | None, Some p ->
1177                   if Utils.debug_metas then
1178                     begin
1179                       List.iter 
1180                         (fun x->Indexing.check_target context x "simplify1")
1181                         p;
1182                     end;
1183                   simplify (new' @ p) active passive
1184               | Some p, Some rp ->
1185                   simplify (new' @ p @ rp) active passive
1186             in
1187             let active, passive, new' = simplify new' active passive in
1188             let goals = 
1189               let a,b,_ = build_table new' in
1190               simplify_goals env goals ~passive (a,b)
1191             in
1192               
1193 (* pessima prova 
1194             let new1 = prova env new' active in
1195             let new' = (fst new') @ (fst new1), (snd new') @ (snd new1) in
1196             let _ =
1197               match new1 with
1198               | neg, pos ->
1199                   debug_print
1200                     (lazy
1201                        (Printf.sprintf "new1:\n%s\n"
1202                           (String.concat "\n"
1203                              ((List.map
1204                                  (fun e -> "Negative " ^
1205                                     (string_of_equality ~env e)) neg) @
1206                                 (List.map
1207                                    (fun e -> "Positive " ^
1208                                       (string_of_equality ~env e)) pos)))))
1209             in
1210 end prova *)
1211             let k = size_of_passive passive in
1212             if k < (kept - 1) then
1213               processed_clauses := !processed_clauses + (kept - 1 - k);
1214             
1215             let _ =
1216               debug_print
1217                 (lazy
1218                    (Printf.sprintf "active:\n%s\n"
1219                       (String.concat "\n"
1220                          ((List.map
1221                              (fun e -> (Equality.string_of_equality ~env e))
1222                              (fst active))))))
1223             in
1224             let _ =
1225               debug_print
1226                 (lazy
1227                    (Printf.sprintf "new':\n%s\n"
1228                       (String.concat "\n"
1229                          ((List.map
1230                              (fun e -> "Negative " ^
1231                                 (Equality.string_of_equality ~env e)) new')))))
1232             in
1233             let passive = add_to_passive passive new' in
1234               given_clause_fullred dbd env goals theorems passive active
1235 ;;
1236
1237 (*
1238 let profiler0 = HExtlib.profile "P/Saturation.given_clause_fullred"
1239
1240 let given_clause_fullred dbd env goals theorems passive active =
1241   profiler0.HExtlib.profile 
1242     (given_clause_fullred dbd env goals theorems passive) active
1243 *)
1244
1245
1246 let rec saturate_equations env goal accept_fun passive active =
1247   elapsed_time := Unix.gettimeofday () -. !start_time;
1248   if !elapsed_time > !time_limit then
1249     (active, passive)
1250   else
1251     let current, passive = select env [1, [goal]] passive in
1252     let res = forward_simplify env (Positive, current) ~passive active in
1253     match res with
1254     | None ->
1255         saturate_equations env goal accept_fun passive active
1256     | Some current ->
1257         debug_print (lazy (Printf.sprintf "selected: %s"
1258                              (Equality.string_of_equality ~env current)));
1259         let new' = infer env current active in
1260         let active =
1261           if Equality.is_identity env current then active
1262           else
1263             let al, tbl = active in
1264             al @ [current], Indexing.index tbl current
1265         in
1266         let rec simplify new' active passive =
1267           let new' = forward_simplify_new env new' ~passive active in
1268           let active, passive, newa, retained, pruned =
1269             backward_simplify env new' ~passive active in
1270           let passive = 
1271             List.fold_left filter_dependent passive pruned in
1272           match newa, retained with
1273           | None, None -> active, passive, new'
1274           | Some p, None
1275           | None, Some p -> simplify (new' @ p) active passive
1276           | Some p, Some rp -> simplify (new' @ p @ rp) active passive
1277         in
1278         let active, passive, new' = simplify new' active passive in
1279         let _ =
1280           debug_print
1281             (lazy
1282                (Printf.sprintf "active:\n%s\n"
1283                   (String.concat "\n"
1284                      (List.map
1285                          (fun e -> Equality.string_of_equality ~env e)
1286                          (fst active)))))
1287         in
1288         let _ =
1289           debug_print
1290             (lazy
1291                (Printf.sprintf "new':\n%s\n"
1292                   (String.concat "\n"
1293                      (List.map
1294                          (fun e -> "Negative " ^
1295                             (Equality.string_of_equality ~env e)) new'))))
1296         in
1297         let new' = List.filter accept_fun new' in
1298         let passive = add_to_passive passive new' in
1299         saturate_equations env goal accept_fun passive active
1300 ;;
1301   
1302 let main dbd full term metasenv ugraph = ()
1303 (*
1304 let main dbd full term metasenv ugraph =
1305   let module C = Cic in
1306   let module T = CicTypeChecker in
1307   let module PET = ProofEngineTypes in
1308   let module PP = CicPp in
1309   let proof = None, (1, [], term)::metasenv, C.Meta (1, []), term in
1310   let status = PET.apply_tactic (PrimitiveTactics.intros_tac ()) (proof, 1) in
1311   let proof, goals = status in
1312   let goal' = List.nth goals 0 in
1313   let _, metasenv, meta_proof, _ = proof in
1314   let _, context, goal = CicUtil.lookup_meta goal' metasenv in
1315   let eq_indexes, equalities, maxm = find_equalities context proof in
1316   let lib_eq_uris, library_equalities, maxm =
1317
1318     find_library_equalities dbd context (proof, goal') (maxm+2)
1319   in
1320   let library_equalities = List.map snd library_equalities in
1321   maxmeta := maxm+2; (* TODO ugly!! *)
1322   let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
1323   let new_meta_goal, metasenv, type_of_goal =
1324     let _, context, ty = CicUtil.lookup_meta goal' metasenv in
1325     debug_print
1326       (lazy
1327          (Printf.sprintf "\n\nTIPO DEL GOAL: %s\n\n" (CicPp.ppterm ty)));
1328     Cic.Meta (maxm+1, irl),
1329     (maxm+1, context, ty)::metasenv,
1330     ty
1331   in
1332   let env = (metasenv, context, ugraph) in
1333   let t1 = Unix.gettimeofday () in
1334   let theorems =
1335     if full then
1336       let theorems = find_library_theorems dbd env (proof, goal') lib_eq_uris in
1337       let context_hyp = find_context_hypotheses env eq_indexes in
1338       context_hyp @ theorems, []
1339     else
1340       let refl_equal =
1341         let us = UriManager.string_of_uri (LibraryObjects.eq_URI ()) in
1342         UriManager.uri_of_string (us ^ "#xpointer(1/1/1)")
1343       in
1344       let t = CicUtil.term_of_uri refl_equal in
1345       let ty, _ = CicTypeChecker.type_of_aux' [] [] t CicUniv.empty_ugraph in
1346       [(t, ty, [])], []
1347   in
1348   let t2 = Unix.gettimeofday () in
1349   debug_print
1350     (lazy
1351        (Printf.sprintf "Time to retrieve theorems: %.9f\n" (t2 -. t1)));
1352   let _ =
1353     debug_print
1354       (lazy
1355          (Printf.sprintf
1356             "Theorems:\n-------------------------------------\n%s\n"
1357             (String.concat "\n"
1358                (List.map
1359                   (fun (t, ty, _) ->
1360                      Printf.sprintf
1361                        "Term: %s, type: %s" (CicPp.ppterm t) (CicPp.ppterm ty))
1362                   (fst theorems)))))
1363   in
1364   (*try*)
1365     let goal = 
1366       ([],Equality.BasicProof (Equality.empty_subst ,new_meta_goal)), [], goal 
1367     in
1368     let equalities = simplify_equalities env 
1369       (equalities@library_equalities) in 
1370     let active = make_active () in
1371     let passive = make_passive equalities in
1372     Printf.printf "\ncurrent goal: %s\n"
1373       (let _, _, g = goal in CicPp.ppterm g);
1374     Printf.printf "\ncontext:\n%s\n" (PP.ppcontext context);
1375     Printf.printf "\nmetasenv:\n%s\n" (print_metasenv metasenv);
1376     Printf.printf "\nequalities:\n%s\n"
1377       (String.concat "\n"
1378          (List.map
1379             (Equality.string_of_equality ~env) equalities));
1380 (*             (equalities @ library_equalities))); *)
1381       print_endline "--------------------------------------------------";
1382       let start = Unix.gettimeofday () in
1383       print_endline "GO!";
1384       start_time := Unix.gettimeofday ();
1385       let res =
1386         let goals = make_goals goal in
1387         (if !use_fullred then given_clause_fullred else given_clause_fullred)
1388           dbd env goals theorems passive active
1389       in
1390       let finish = Unix.gettimeofday () in
1391       let _ =
1392         match res with
1393         | ParamodulationFailure ->
1394             Printf.printf "NO proof found! :-(\n\n"
1395         | ParamodulationSuccess (Some ((cicproof,cicmenv),(proof, env))) ->
1396             Printf.printf "OK, found a proof!\n";
1397             let oldproof = Equation.build_proof_term proof in
1398             let newproof,_,newenv,_ = 
1399                 CicRefine.type_of_aux' 
1400                   cicmenv context cicproof CicUniv.empty_ugraph
1401             in
1402             (* REMEMBER: we have to instantiate meta_proof, we should use
1403                apply  the "apply" tactic to proof and status 
1404             *)
1405             let names = names_of_context context in
1406             prerr_endline "OLD PROOF";
1407             print_endline (PP.pp proof names);
1408             prerr_endline "NEW PROOF";
1409             print_endline (PP.pp newproof names);
1410             let newmetasenv =
1411               List.fold_left
1412                 (fun m eq -> 
1413                   let (_, _, _, menv,_) = Equality.open_equality eq in 
1414                   m @ menv) 
1415               metasenv equalities
1416             in
1417             let _ =
1418               (*try*)
1419                 let ty, ug =
1420                   CicTypeChecker.type_of_aux' newmetasenv context proof ugraph
1421                 in
1422                 print_endline (string_of_float (finish -. start));
1423                 Printf.printf
1424                   "\nGOAL was: %s\nPROOF has type: %s\nconvertible?: %s\n\n"
1425                   (CicPp.pp type_of_goal names) (CicPp.pp ty names)
1426                   (string_of_bool
1427                      (fst (CicReduction.are_convertible
1428                              context type_of_goal ty ug)));
1429               (*with e ->
1430                 Printf.printf "\nEXCEPTION!!! %s\n" (Printexc.to_string e);
1431                 Printf.printf "MAXMETA USED: %d\n" !maxmeta;
1432                 print_endline (string_of_float (finish -. start));*)
1433             in
1434             ()
1435               
1436         | ParamodulationSuccess None ->
1437             Printf.printf "Success, but no proof?!?\n\n"
1438       in
1439         if Utils.time then
1440           begin
1441             prerr_endline 
1442               ((Printf.sprintf ("infer_time: %.9f\nforward_simpl_time: %.9f\n" ^^
1443                        "forward_simpl_new_time: %.9f\n" ^^
1444                        "backward_simpl_time: %.9f\n")
1445               !infer_time !forward_simpl_time !forward_simpl_new_time
1446               !backward_simpl_time) ^
1447               (Printf.sprintf "passive_maintainance_time: %.9f\n"
1448                  !passive_maintainance_time) ^
1449               (Printf.sprintf "    successful unification/matching time: %.9f\n"
1450                  !Indexing.match_unif_time_ok) ^
1451               (Printf.sprintf "    failed unification/matching time: %.9f\n"
1452                  !Indexing.match_unif_time_no) ^
1453               (Printf.sprintf "    indexing retrieval time: %.9f\n"
1454                  !Indexing.indexing_retrieval_time) ^
1455               (Printf.sprintf "    demodulate_term.build_newtarget_time: %.9f\n"
1456                  !Indexing.build_newtarget_time) ^
1457               (Printf.sprintf "derived %d clauses, kept %d clauses.\n"
1458                  !derived_clauses !kept_clauses)) 
1459             end
1460 (*
1461   with exc ->
1462     print_endline ("EXCEPTION: " ^ (Printexc.to_string exc));
1463     raise exc
1464 *)
1465 ;;
1466 *)
1467
1468 let default_depth = !maxdepth
1469 and default_width = !maxwidth;;
1470
1471 let reset_refs () =
1472   maxmeta := 0;
1473   symbols_counter := 0;
1474   weight_age_counter := !weight_age_ratio;
1475   processed_clauses := 0;
1476   start_time := 0.;
1477   elapsed_time := 0.;
1478   maximal_retained_equality := None;
1479   infer_time := 0.;
1480   forward_simpl_time := 0.;
1481   forward_simpl_new_time := 0.;
1482   backward_simpl_time := 0.;
1483   passive_maintainance_time := 0.;
1484   derived_clauses := 0;
1485   kept_clauses := 0;
1486   Equality.reset ();
1487 ;;
1488
1489 let saturate 
1490     dbd ?(full=false) ?(depth=default_depth) ?(width=default_width) status = 
1491   let module C = Cic in
1492   reset_refs ();
1493   Indexing.init_index ();
1494   counter := 0;
1495   maxdepth := depth;
1496   maxwidth := width;
1497 (*  CicUnification.unif_ty := false;*)
1498   let proof, goal = status in
1499   let goal' = goal in
1500   let uri, metasenv, meta_proof, term_to_prove = proof in
1501   let _, context, goal = CicUtil.lookup_meta goal' metasenv in
1502   let names = names_of_context context in
1503   let eq_indexes, equalities, maxm = find_equalities context proof in
1504   let new_meta_goal, metasenv, type_of_goal =
1505     let irl =
1506       CicMkImplicit.identity_relocation_list_for_metavariable context in
1507     let _, context, ty = CicUtil.lookup_meta goal' metasenv in
1508     debug_print
1509       (lazy (Printf.sprintf "\n\nTIPO DEL GOAL: %s\n" (CicPp.ppterm ty)));
1510     Cic.Meta (maxm+1, irl),
1511     (maxm+1, context, ty)::metasenv,
1512     ty
1513   in
1514   let ugraph = CicUniv.empty_ugraph in
1515   let env = (metasenv, context, ugraph) in 
1516   let goal = [], [], goal in
1517   let res, time =
1518     let t1 = Unix.gettimeofday () in
1519     let lib_eq_uris, library_equalities, maxm =
1520       find_library_equalities dbd context (proof, goal') (maxm+2)
1521     in
1522     let library_equalities = List.map snd library_equalities in
1523     let t2 = Unix.gettimeofday () in
1524     maxmeta := maxm+2;
1525     let equalities = simplify_equalities env (equalities@library_equalities) in 
1526     debug_print
1527       (lazy
1528          (Printf.sprintf "Time to retrieve equalities: %.9f\n" (t2 -. t1)));
1529     let t1 = Unix.gettimeofday () in
1530     let theorems =
1531       if full then
1532         let thms = find_library_theorems dbd env (proof, goal') lib_eq_uris in
1533         let context_hyp = find_context_hypotheses env eq_indexes in
1534         context_hyp @ thms, []
1535       else
1536         let refl_equal =
1537           let us = UriManager.string_of_uri (LibraryObjects.eq_URI ()) in
1538           UriManager.uri_of_string (us ^ "#xpointer(1/1/1)")
1539         in
1540         let t = CicUtil.term_of_uri refl_equal in
1541         let ty, _ = CicTypeChecker.type_of_aux' [] [] t CicUniv.empty_ugraph in
1542         [(t, ty, [])], []
1543     in
1544     let t2 = Unix.gettimeofday () in
1545     let _ =
1546       debug_print
1547         (lazy
1548            (Printf.sprintf
1549               "Theorems:\n-------------------------------------\n%s\n"
1550               (String.concat "\n"
1551                  (List.map
1552                     (fun (t, ty, _) ->
1553                        Printf.sprintf
1554                          "Term: %s, type: %s"
1555                          (CicPp.ppterm t) (CicPp.ppterm ty))
1556                     (fst theorems)))));
1557       debug_print
1558         (lazy
1559            (Printf.sprintf "Time to retrieve theorems: %.9f\n" (t2 -. t1)));
1560     in
1561     let active = make_active () in
1562     let passive = make_passive equalities in
1563     let start = Unix.gettimeofday () in
1564     let res =
1565       let goals = make_goals goal in
1566       given_clause_fullred dbd env goals theorems passive active
1567     in
1568     let finish = Unix.gettimeofday () in
1569     (res, finish -. start)
1570   in
1571   match res with
1572   | ParamodulationSuccess 
1573       (Some (goalproof,newproof,subsumption_subst, proof_menv))
1574       ->
1575       prerr_endline "OK, found a proof!";
1576
1577       prerr_endline "NEWPROOF";
1578      (* prerr_endline (Equality.string_of_proof_new ~names newproof
1579       * goalproof);*)
1580       prerr_endline (Equality.pp_proof names goalproof newproof);
1581       
1582       (* generation of the proof *)
1583       let cic_proof_new = 
1584         Equality.build_goal_proof 
1585           goalproof (Equality.build_proof_term newproof) type_of_goal
1586       in
1587       let cic_proof_new = 
1588         Subst.apply_subst subsumption_subst cic_proof_new 
1589       in
1590       
1591       (* replacing fake mets with real ones *)
1592       let equality_for_replace i t1 =
1593         match t1 with
1594         | C.Meta (n, _) -> n = i
1595         | _ -> false
1596       in
1597       let mkirl = CicMkImplicit.identity_relocation_list_for_metavariable in
1598       prerr_endline "replacing metas (new)";
1599       let newproof_menv, what, with_what = 
1600         let irl = mkirl context in
1601         List.fold_left 
1602           (fun (acc1,acc2,acc3) (i,_,ty) -> 
1603             (i,context,ty)::acc1, 
1604             (Cic.Meta(i,[]))::acc2, 
1605             (Cic.Meta(i,irl)) ::acc3) 
1606           ([],[],[]) proof_menv 
1607       in
1608       let cic_proof_new = ProofEngineReduction.replace_lifting
1609               ~equality:(=)
1610               ~what ~with_what
1611               ~where:cic_proof_new
1612       in
1613
1614       (* pp new/old proof *)
1615 (*      prerr_endline "NEWPROOFCIC";*)
1616 (*      prerr_endline (CicPp.pp cic_proof_new names); *)
1617
1618       (* generation of proof metasenv *)
1619       let newmetasenv =
1620         let i1 =
1621           match new_meta_goal with
1622           | C.Meta (i, _) -> i | _ -> assert false
1623         in
1624         List.filter (fun (i, _, _) -> i <> i1 && i <> goal') metasenv
1625       in
1626       let newmetasenv_new = newmetasenv@newproof_menv in
1627       (* check/refine/... build the new proof *)
1628       let newstatus =
1629         let cic_proof,newmetasenv,proof_menv,ty, ug =
1630           let cic_proof_new,new_ty,newmetasenv_new,newug = 
1631             try
1632               (*
1633                prerr_endline "refining ... (new) ";
1634                CicRefine.type_of_aux' 
1635                 newmetasenv_new context cic_proof_new ugraph
1636               *)
1637               let ty,ug = 
1638                 prerr_endline "typechecking ... (new) ";
1639                 CicTypeChecker.type_of_aux' 
1640                   newmetasenv_new context cic_proof_new ugraph
1641               in
1642               cic_proof_new, ty, newmetasenv_new, ug
1643             with
1644             | CicTypeChecker.TypeCheckerFailure s ->
1645                 prerr_endline "THE PROOF DOESN'T TYPECHECK!!!";
1646                 prerr_endline (Lazy.force s);
1647                 assert false
1648             | CicRefine.RefineFailure s 
1649             | CicRefine.Uncertain s 
1650             | CicRefine.AssertFailure s -> 
1651                 prerr_endline "FAILURE IN REFINE";
1652                 prerr_endline (Lazy.force s);
1653                 assert false
1654           in
1655           if List.length newmetasenv_new <> 0 then
1656             prerr_endline 
1657               ("Some METAS are still open: "(* ^ CicMetaSubst.ppmetasenv
1658                [] newmetasenv_new*));
1659           cic_proof_new, newmetasenv_new, newmetasenv_new,new_ty, newug
1660           (* THE OLD PROOF: cic_proof,newmetasenv,proof_menv,oldty,oldug *)
1661         in
1662 (*        prerr_endline "FINAL PROOF";*)
1663 (*        prerr_endline (CicPp.pp cic_proof names);*)
1664         prerr_endline "ENDOFPROOFS";
1665         (*  
1666         debug_print
1667           (lazy
1668              (Printf.sprintf
1669                 "\nGOAL was: %s\nPROOF has type: %s\nconvertible?: %s\n"
1670                 (CicPp.pp type_of_goal names) (CicPp.pp ty names)
1671                 (string_of_bool
1672                    (fst (CicReduction.are_convertible
1673                            context type_of_goal ty ug)))));
1674         *)
1675         let real_proof =
1676           ProofEngineReduction.replace
1677             ~equality:equality_for_replace
1678             ~what:[goal'] ~with_what:[cic_proof]
1679             ~where:meta_proof
1680         in
1681         (*
1682         debug_print
1683           (lazy
1684              (Printf.sprintf "status:\n%s\n%s\n%s\n%s\n"
1685                 (match uri with Some uri -> UriManager.string_of_uri uri
1686                  | None -> "")
1687                 (print_metasenv newmetasenv)
1688                 (CicPp.pp real_proof [](* names *))
1689                 (CicPp.pp term_to_prove names)));
1690         *)
1691         let open_goals = List.map (fun (i,_,_) -> i) proof_menv in
1692         (uri, newmetasenv, real_proof, term_to_prove), open_goals
1693       in
1694       if Utils.time then
1695         begin
1696           let tall = fs_time_info.build_all in
1697           let tdemodulate = fs_time_info.demodulate in
1698           let tsubsumption = fs_time_info.subsumption in
1699           prerr_endline (
1700             (Printf.sprintf "\nTIME NEEDED: %.9f" time) ^
1701               (Printf.sprintf "\ntall: %.9f" tall) ^
1702               (Printf.sprintf "\ntdemod: %.9f" tdemodulate) ^
1703               (Printf.sprintf "\ntsubsumption: %.9f" tsubsumption) ^
1704               (Printf.sprintf "\ninfer_time: %.9f" !infer_time) ^
1705               (Printf.sprintf "\nforward_simpl_times: %.9f" 
1706                 !forward_simpl_time) ^
1707               (Printf.sprintf "\nforward_simpl_new_times: %.9f" 
1708                 !forward_simpl_new_time) ^
1709               (Printf.sprintf "\nbackward_simpl_times: %.9f" 
1710                 !backward_simpl_time) ^
1711               (Printf.sprintf "\npassive_maintainance_time: %.9f" 
1712                  !passive_maintainance_time))
1713         end;
1714       newstatus 
1715   | ParamodulationSuccess None -> assert false
1716   | ParamodulationFailure ->
1717       raise (ProofEngineTypes.Fail (lazy "NO proof found"))
1718 ;;
1719
1720 (* dummy function called within matita to trigger linkage *)
1721 let init () = ();;
1722
1723
1724 let retrieve_and_print dbd term metasenv ugraph = 
1725   let module C = Cic in
1726   let module T = CicTypeChecker in
1727   let module PET = ProofEngineTypes in
1728   let module PP = CicPp in
1729   let proof = None, (1, [], term)::metasenv, C.Meta (1, []), term in
1730   let status = PET.apply_tactic (PrimitiveTactics.intros_tac ()) (proof, 1) in
1731   let proof, goals = status in
1732   let goal' = List.nth goals 0 in
1733   let uri, metasenv, meta_proof, term_to_prove = proof in
1734   let _, context, goal = CicUtil.lookup_meta goal' metasenv in
1735   let eq_indexes, equalities, maxm = find_equalities context proof in
1736   let new_meta_goal, metasenv, type_of_goal =
1737     let irl =
1738       CicMkImplicit.identity_relocation_list_for_metavariable context in
1739     let _, context, ty = CicUtil.lookup_meta goal' metasenv in
1740     debug_print
1741       (lazy (Printf.sprintf "\n\nTIPO DEL GOAL: %s\n" (CicPp.ppterm ty)));
1742     Cic.Meta (maxm+1, irl),
1743     (maxm+1, context, ty)::metasenv,
1744     ty
1745   in
1746   let ugraph = CicUniv.empty_ugraph in
1747   let env = (metasenv, context, ugraph) in
1748   let t1 = Unix.gettimeofday () in
1749   let lib_eq_uris, library_equalities, maxm =
1750     find_library_equalities dbd context (proof, goal') (maxm+2) in
1751   let t2 = Unix.gettimeofday () in
1752   maxmeta := maxm+2;
1753   let equalities = (* equalities @ *) library_equalities in
1754   debug_print
1755      (lazy
1756         (Printf.sprintf "\n\nequalities:\n%s\n"
1757            (String.concat "\n"
1758               (List.map 
1759           (fun (u, e) ->
1760 (*                  Printf.sprintf "%s: %s" *)
1761                    (UriManager.string_of_uri u)
1762 (*                    (string_of_equality e) *)
1763                      )
1764           equalities))));
1765   debug_print (lazy "RETR: SIMPLYFYING EQUALITIES...");
1766   let rec simpl e others others_simpl =
1767     let (u, e) = e in
1768     let active = List.map (fun (u, e) -> (Positive, e))
1769       (others @ others_simpl) in
1770     let tbl =
1771       List.fold_left
1772         (fun t (_, e) -> Indexing.index t e)
1773         Indexing.empty active
1774     in
1775     let res = forward_simplify env (Positive, e) (active, tbl) in
1776     match others with
1777         | hd::tl -> (
1778             match res with
1779               | None -> simpl hd tl others_simpl
1780               | Some e -> simpl hd tl ((u, e)::others_simpl)
1781           )
1782         | [] -> (
1783             match res with
1784               | None -> others_simpl
1785               | Some e -> (u, e)::others_simpl
1786           ) 
1787   in
1788   let _equalities =
1789     match equalities with
1790       | [] -> []
1791       | hd::tl ->
1792           let others = tl in (* List.map (fun e -> (Positive, e)) tl in *)
1793           let res =
1794             List.rev (simpl (*(Positive,*) hd others [])
1795           in
1796             debug_print
1797               (lazy
1798                  (Printf.sprintf "\nequalities AFTER:\n%s\n"
1799                     (String.concat "\n"
1800                        (List.map
1801                           (fun (u, e) ->
1802                              Printf.sprintf "%s: %s"
1803                                (UriManager.string_of_uri u)
1804                                (Equality.string_of_equality e)
1805                           )
1806                           res))));
1807             res in
1808     debug_print
1809       (lazy
1810          (Printf.sprintf "Time to retrieve equalities: %.9f\n" (t2 -. t1)))
1811 ;;
1812
1813
1814 let main_demod_equalities dbd term metasenv ugraph =
1815   let module C = Cic in
1816   let module T = CicTypeChecker in
1817   let module PET = ProofEngineTypes in
1818   let module PP = CicPp in
1819   let proof = None, (1, [], term)::metasenv, C.Meta (1, []), term in
1820   let status = PET.apply_tactic (PrimitiveTactics.intros_tac ()) (proof, 1) in
1821   let proof, goals = status in
1822   let goal' = List.nth goals 0 in
1823   let _, metasenv, meta_proof, _ = proof in
1824   let _, context, goal = CicUtil.lookup_meta goal' metasenv in
1825   let eq_indexes, equalities, maxm = find_equalities context proof in
1826   let lib_eq_uris, library_equalities, maxm =
1827     find_library_equalities dbd context (proof, goal') (maxm+2)
1828   in
1829   let library_equalities = List.map snd library_equalities in
1830   maxmeta := maxm+2; (* TODO ugly!! *)
1831   let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
1832   let new_meta_goal, metasenv, type_of_goal =
1833     let _, context, ty = CicUtil.lookup_meta goal' metasenv in
1834     debug_print
1835       (lazy
1836          (Printf.sprintf "\n\nTRYING TO INFER EQUALITIES MATCHING: %s\n\n"
1837             (CicPp.ppterm ty)));
1838     Cic.Meta (maxm+1, irl),
1839     (maxm+1, context, ty)::metasenv,
1840     ty
1841   in
1842   let env = (metasenv, context, ugraph) in
1843   (*try*)
1844     let goal = [], [], goal 
1845     in
1846     let equalities = simplify_equalities env (equalities@library_equalities) in
1847     let active = make_active () in
1848     let passive = make_passive equalities in
1849     Printf.printf "\ncontext:\n%s\n" (PP.ppcontext context);
1850     Printf.printf "\nmetasenv:\n%s\n" (print_metasenv metasenv);
1851     Printf.printf "\nequalities:\n%s\n"
1852       (String.concat "\n"
1853          (List.map
1854             (Equality.string_of_equality ~env) equalities));
1855     print_endline "--------------------------------------------------";
1856     print_endline "GO!";
1857     start_time := Unix.gettimeofday ();
1858     if !time_limit < 1. then time_limit := 60.;    
1859     let ra, rp =
1860       saturate_equations env goal (fun e -> true) passive active
1861     in
1862
1863     let initial =
1864       List.fold_left (fun s e -> EqualitySet.add e s)
1865         EqualitySet.empty equalities
1866     in
1867     let addfun s e = 
1868       if not (EqualitySet.mem e initial) then EqualitySet.add e s else s
1869     in
1870
1871     let passive =
1872       match rp with
1873       | (p, _), _ ->
1874           EqualitySet.elements (List.fold_left addfun EqualitySet.empty p)
1875     in
1876     let active =
1877       let l = fst ra in
1878       EqualitySet.elements (List.fold_left addfun EqualitySet.empty l)
1879     in
1880     Printf.printf "\n\nRESULTS:\nActive:\n%s\n\nPassive:\n%s\n"
1881        (String.concat "\n" (List.map (Equality.string_of_equality ~env) active)) 
1882      (*  (String.concat "\n"
1883          (List.map (fun e -> CicPp.ppterm (term_of_equality e)) active)) *)
1884 (*       (String.concat "\n" (List.map (string_of_equality ~env) passive)); *)
1885       (String.concat "\n"
1886          (List.map (fun e -> CicPp.ppterm (Equality.term_of_equality e)) passive));
1887     print_newline ();
1888 (*
1889   with e ->
1890     debug_print (lazy ("EXCEPTION: " ^ (Printexc.to_string e)))
1891 *)
1892 ;;
1893
1894 let demodulate_tac ~dbd ~pattern ((proof,goal) as initialstatus) = 
1895   let module I = Inference in
1896   let curi,metasenv,pbo,pty = proof in
1897   let metano,context,ty = CicUtil.lookup_meta goal metasenv in
1898   let eq_indexes, equalities, maxm = I.find_equalities context proof in
1899   let lib_eq_uris, library_equalities, maxm =
1900     I.find_library_equalities dbd context (proof, goal) (maxm+2) in
1901   if library_equalities = [] then prerr_endline "VUOTA!!!";
1902   let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
1903   let library_equalities = List.map snd library_equalities in
1904   let initgoal = [], [], ty in
1905   let env = (metasenv, context, CicUniv.empty_ugraph) in
1906   let equalities = simplify_equalities env (equalities@library_equalities) in   
1907   let table = 
1908     List.fold_left 
1909       (fun tbl eq -> Indexing.index tbl eq) 
1910       Indexing.empty equalities 
1911   in
1912   let _, newmeta,(newproof,newmetasenv, newty) = 
1913     Indexing.demodulation_goal 
1914       maxm (metasenv,context,CicUniv.empty_ugraph) table initgoal 
1915   in
1916   if newmeta != maxm then
1917     begin
1918       let opengoal = Cic.Meta(maxm,irl) in
1919       let proofterm = 
1920         Equality.build_goal_proof newproof opengoal ty in
1921         let extended_metasenv = (maxm,context,newty)::metasenv in
1922         let extended_status = 
1923           (curi,extended_metasenv,pbo,pty),goal in
1924         let (status,newgoals) = 
1925           ProofEngineTypes.apply_tactic 
1926             (PrimitiveTactics.apply_tac ~term:proofterm)
1927             extended_status in
1928         (status,maxm::newgoals)
1929     end
1930   else if newty = ty then
1931     raise (ProofEngineTypes.Fail (lazy "no progress"))
1932   else ProofEngineTypes.apply_tactic 
1933     (ReductionTactics.simpl_tac ~pattern) 
1934     initialstatus
1935 ;;
1936
1937 let demodulate_tac ~dbd ~pattern = 
1938   ProofEngineTypes.mk_tactic (demodulate_tac ~dbd ~pattern)
1939 ;;