]> matita.cs.unibo.it Git - helm.git/blob - helm/software/components/tactics/paramodulation/saturation.ml
new version of auto that is able to prove the irrationality of sqrt(2)
[helm.git] / helm / software / 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 (* let _profiler = <:profiler<_profiler>>;; *)
27
28 (* $Id$ *)
29
30 (* set to false to disable paramodulation inside auto_tac *)
31
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 theorem = Cic.term * Cic.term * Cic.metasenv;;
74
75 let symbols_of_equality equality = 
76   let (_, _, (_, left, right, _), _,_) = Equality.open_equality equality in
77   let m1 = Utils.symbols_of_term left in
78   let m = 
79     Utils.TermMap.fold
80       (fun k v res ->
81          try
82            let c = Utils.TermMap.find k res in
83            Utils.TermMap.add k (c+v) res
84          with Not_found ->
85            Utils.TermMap.add k v res)
86       (Utils.symbols_of_term right) m1
87   in
88   m
89 ;;
90
91 (* griggio *)
92 module OrderedEquality = struct 
93   type t = Equality.equality
94
95   let compare eq1 eq2 =
96     match Equality.meta_convertibility_eq eq1 eq2 with
97     | true -> 0
98     | false -> 
99         let w1, _, (ty,left, right, _), m1,_ = Equality.open_equality eq1 in
100         let w2, _, (ty',left', right', _), m2,_ = Equality.open_equality eq2 in
101         match Pervasives.compare w1 w2 with
102         | 0 -> 
103             let res = (List.length m1) - (List.length m2) in 
104             if res <> 0 then res else 
105               Equality.compare eq1 eq2
106         | res -> res 
107 end 
108
109 module EqualitySet = Set.Make(OrderedEquality);;
110
111 type passive_table = Equality.equality list * EqualitySet.t
112 type active_table = Equality.equality list * Indexing.Index.t
113 type new_proof = 
114   Equality.goal_proof * Equality.proof * int * Subst.substitution * Cic.metasenv
115 type result =
116   | ParamodulationFailure of string * active_table * passive_table
117   | ParamodulationSuccess of new_proof * active_table * passive_table
118 ;;
119 let make_passive eq_list =
120   let set =
121     List.fold_left (fun s e -> EqualitySet.add e s) EqualitySet.empty eq_list
122   in
123   (*EqualitySet.elements set*) eq_list, set
124 ;;
125 let make_empty_active () = [], Indexing.empty ;;
126 let make_active eq_list = 
127   eq_list, List.fold_left Indexing.index Indexing.empty eq_list
128 ;;
129
130 let size_of_passive (passive_list, _) = List.length passive_list;;
131 let size_of_active (active_list, _) = List.length active_list;;
132 let passive_is_empty = function
133   | [], s when EqualitySet.is_empty s -> true
134   | [], s -> assert false (* the set and the list should be in sync *)
135   | _ -> false
136 ;;
137
138 type goals = Equality.goal list * Equality.goal list
139
140 let no_more_passive_goals g = match g with | _,[] -> true | _ -> false;;
141   
142
143 let age_factor = 0.01;;
144
145 (**
146    selects one equality from passive. The selection strategy is a combination
147    of weight, age and goal-similarity
148 *)
149
150 let rec select env g passive =
151   processed_clauses := !processed_clauses + 1;
152 (*
153   let goal =
154     match (List.rev goals) with goal::_ -> goal | _ -> assert false
155   in
156 *)
157   let pos_list, pos_set = passive in
158   let remove eq l = List.filter (fun e -> Equality.compare e eq <> 0) l in
159   if !weight_age_ratio > 0 then
160     weight_age_counter := !weight_age_counter - 1;
161   match !weight_age_counter with
162   | 0 -> (
163       weight_age_counter := !weight_age_ratio;
164       let skip_giant pos_list pos_set =
165         match pos_list with
166           | (hd:EqualitySet.elt)::tl ->
167               let w,_,_,_,_ = Equality.open_equality hd in
168                 if w < 30 then
169                   hd, (tl, EqualitySet.remove hd pos_set)
170                 else
171 (*
172                   (prerr_endline 
173                     ("+++ skipping giant of size "^string_of_int w^" +++");
174 *)
175                   select env g (tl@[hd],pos_set)
176           | _ -> assert false
177                    in
178                     skip_giant pos_list pos_set)
179
180 (*
181       let rec skip_giant pos_list pos_set =
182         match pos_list with
183           | (hd:EqualitySet.elt)::tl ->
184               let w,_,_,_,_ = Equality.open_equality hd in
185               let pos_set = EqualitySet.remove hd pos_set in
186                 if w < 30 then
187                   hd, (tl, pos_set)
188                 else
189                   (prerr_endline 
190                     ("+++ skipping giant of size "^string_of_int w^" +++");
191                   skip_giant tl pos_set)
192           | _ -> assert false
193       in        
194   skip_giant pos_list pos_set)
195
196 *)
197 (*
198   | _ when (!symbols_counter > 0) -> 
199      (symbols_counter := !symbols_counter - 1;
200       let cardinality map =
201         Utils.TermMap.fold (fun k v res -> res + v) map 0
202       in
203       let symbols =
204         let _, _, term = goal in
205         Utils.symbols_of_term term
206       in
207       let card = cardinality symbols in
208       let foldfun k v (r1, r2) = 
209         if Utils.TermMap.mem k symbols then
210           let c = Utils.TermMap.find k symbols in
211           let c1 = abs (c - v) in
212           let c2 = v - c1 in
213           r1 + c2, r2 + c1
214         else
215           r1, r2 + v
216       in
217       let f equality (i, e) =
218         let common, others =
219           Utils.TermMap.fold foldfun (symbols_of_equality equality) (0, 0)
220         in
221         let c = others + (abs (common - card)) in
222         if c < i then (c, equality)
223         else (i, e)
224       in
225       let e1 = EqualitySet.min_elt pos_set in
226       let initial =
227         let common, others = 
228           Utils.TermMap.fold foldfun (symbols_of_equality e1) (0, 0)
229         in
230         (others + (abs (common - card))), e1
231       in
232       let _, current = EqualitySet.fold f pos_set initial in
233         current,
234       (remove current pos_list, EqualitySet.remove current pos_set))
235 *)
236   | _ ->
237       symbols_counter := !symbols_ratio;
238       let my_min e1 e2 =
239         let w1,_,_,_,_ = Equality.open_equality e1 in
240         let w2,_,_,_,_ = Equality.open_equality e2 in
241         if w1 < w2 then e1 else e2
242       in
243       let rec my_min_elt min = function
244         | [] -> min
245         | hd::tl -> my_min_elt (my_min hd min) tl
246       in
247 (*     let current = EqualitySet.min_elt pos_set in  *)
248        let current = my_min_elt (List.hd pos_list) (List.tl pos_list) in 
249        current,(remove current pos_list, EqualitySet.remove current pos_set)
250 ;;
251
252
253 let filter_dependent bag passive id =
254   let pos_list, pos_set = passive in
255   let passive,no_pruned =
256     List.fold_right
257       (fun eq ((list,set),no) ->
258          if Equality.depend bag eq id then
259            (list, EqualitySet.remove eq set), no + 1
260          else 
261            (eq::list, set), no)
262       pos_list (([],pos_set),0)
263   in
264 (*
265   if no_pruned > 0 then
266     prerr_endline ("+++ pruning "^ string_of_int no_pruned ^" passives +++");  
267 *)
268   passive
269 ;;
270
271
272 (* adds to passive a list of equalities new_pos *)
273 let add_to_passive passive new_pos preferred =
274   let pos_list, pos_set = passive in
275   let ok set equality = not (EqualitySet.mem equality set) in
276   let pos = List.filter (ok pos_set) new_pos in
277   let add set equalities =
278     List.fold_left (fun s e -> EqualitySet.add e s) set equalities
279   in
280   let pos_head, pos_tail =
281     List.partition 
282       (fun e -> List.exists (fun x -> Equality.compare x e = 0) preferred)  
283       pos 
284   in
285   pos_head @ pos_list @ pos_tail, add pos_set pos
286 ;;
287
288 (* TODO *)
289 (* removes from passive equalities that are estimated impossible to activate
290    within the current time limit *)
291 let prune_passive howmany (active, _) passive =
292   let (pl, ps), tbl = passive in
293   let howmany = float_of_int howmany
294   and ratio = float_of_int !weight_age_ratio in
295   let round v =
296     let t = ceil v in 
297     int_of_float (if t -. v < 0.5 then t else v)
298   in
299   let in_weight = round (howmany *. ratio /. (ratio +. 1.))
300   and in_age = round (howmany /. (ratio +. 1.)) in 
301   Utils.debug_print
302     (lazy (Printf.sprintf "in_weight: %d, in_age: %d\n" in_weight in_age));
303   let counter = ref !symbols_ratio in
304   let rec pickw w ps =
305     if w > 0 then
306       if !counter > 0 then
307         let _ =
308           counter := !counter - 1;
309           if !counter = 0 then counter := !symbols_ratio in
310         let e = EqualitySet.min_elt ps in
311         let ps' = pickw (w-1) (EqualitySet.remove e ps) in
312           EqualitySet.add e ps'
313       else
314         let e = EqualitySet.min_elt ps in
315         let ps' = pickw (w-1) (EqualitySet.remove e ps) in
316         EqualitySet.add e ps'        
317     else
318       EqualitySet.empty
319   in
320   let ps = pickw in_weight ps in
321   let rec picka w s l =
322     if w > 0 then
323       match l with
324       | [] -> w, s, []
325       | hd::tl when not (EqualitySet.mem hd s) ->
326           let w, s, l = picka (w-1) s tl in
327           w, EqualitySet.add hd s, hd::l
328       | hd::tl ->
329           let w, s, l = picka w s tl in
330           w, s, hd::l
331     else
332       0, s, l
333   in
334   let _, ps, pl = picka in_age ps pl in
335   if not (EqualitySet.is_empty ps) then
336     maximal_retained_equality := Some (EqualitySet.max_elt ps); 
337   let tbl =
338     EqualitySet.fold
339       (fun e tbl -> Indexing.index tbl e) ps Indexing.empty
340   in
341   (pl, ps), tbl  
342 ;;
343
344
345 (** inference of new equalities between current and some in active *)
346 let infer bag eq_uri env current (active_list, active_table) =
347   let (_,c,_) = env in 
348   if Utils.debug_metas then
349     (ignore(Indexing.check_target bag c current "infer1");
350      ignore(List.map (function current -> Indexing.check_target bag c current "infer2") active_list)); 
351   let new_pos = 
352       let maxm, copy_of_current = Equality.fix_metas bag !maxmeta current in
353         maxmeta := maxm;
354       let active_table =  Indexing.index active_table copy_of_current in
355 (*       let _ = <:start<current contro active>> in *)
356       let maxm, res =
357         Indexing.superposition_right bag eq_uri !maxmeta env active_table current 
358       in
359 (*       let _ = <:stop<current contro active>> in *)
360       if Utils.debug_metas then
361         ignore(List.map 
362                  (function current -> 
363                     Indexing.check_target bag c current "sup0") res);
364       maxmeta := maxm;
365       let rec infer_positive table = function
366         | [] -> []
367         | equality::tl ->
368             let maxm, res =
369               Indexing.superposition_right bag 
370                 ~subterms_only:true eq_uri !maxmeta env table equality 
371             in
372               maxmeta := maxm;
373               if Utils.debug_metas then
374                 ignore
375                   (List.map 
376                      (function current -> 
377                         Indexing.check_target bag c current "sup2") res);
378               let pos = infer_positive table tl in
379               res @ pos
380       in
381 (*
382       let maxm, copy_of_current = Equality.fix_metas !maxmeta current in
383         maxmeta := maxm;
384 *)
385       let curr_table = Indexing.index Indexing.empty current in
386 (*       let _ = <:start<active contro current>> in *)
387       let pos = infer_positive curr_table ((*copy_of_current::*)active_list) in
388 (*       let _ = <:stop<active contro current>> in *)
389       if Utils.debug_metas then 
390         ignore(List.map 
391                  (function current -> 
392                     Indexing.check_target bag c current "sup3") pos);
393       res @ pos
394   in
395   derived_clauses := !derived_clauses + (List.length new_pos);
396   match !maximal_retained_equality with
397     | None -> new_pos
398     | Some eq ->
399       ignore(assert false);
400       (* if we have a maximal_retained_equality, we can discard all equalities
401          "greater" than it, as they will never be reached...  An equality is
402          greater than maximal_retained_equality if it is bigger
403          wrt. OrderedEquality.compare and it is less similar than
404          maximal_retained_equality to the current goal *)
405         List.filter (fun e -> OrderedEquality.compare e eq <= 0) new_pos
406 ;;
407
408 let check_for_deep_subsumption env active_table eq =
409   let _,_,(eq_ty, left, right, order),metas,id = Equality.open_equality eq in
410   let check_subsumed deep l r = 
411     let eqtmp = 
412       Equality.mk_tmp_equality(0,(eq_ty,l,r,Utils.Incomparable),metas)in
413     match Indexing.subsumption env active_table eqtmp with
414     | None -> false
415     | Some _ -> true        
416   in 
417   let rec aux b (ok_so_far, subsumption_used) t1 t2  = 
418     match t1,t2 with
419       | t1, t2 when not ok_so_far -> ok_so_far, subsumption_used
420       | t1, t2 when subsumption_used -> t1 = t2, subsumption_used
421       | Cic.Appl (h1::l),Cic.Appl (h2::l') ->
422           let rc = check_subsumed b t1 t2 in 
423             if rc then 
424               true, true
425             else if h1 = h2 then
426               (try 
427                  List.fold_left2 
428                    (fun (ok_so_far, subsumption_used) t t' -> 
429                       aux true (ok_so_far, subsumption_used) t t')
430                    (ok_so_far, subsumption_used) l l'
431                with Invalid_argument _ -> false,subsumption_used)
432             else
433               false, subsumption_used
434     | _ -> false, subsumption_used 
435   in
436   fst (aux false (true,false) left right)
437 ;;
438
439 (** simplifies current using active and passive *)
440 let forward_simplify bag eq_uri env current (active_list, active_table) =
441   let _, context, _ = env in
442   let demodulate table current = 
443     let newmeta, newcurrent =
444       Indexing.demodulation_equality bag eq_uri !maxmeta env table current
445     in
446     maxmeta := newmeta;
447     if Equality.is_identity env newcurrent then None else Some newcurrent
448   in
449   let rec demod current =
450     if Utils.debug_metas then
451       ignore (Indexing.check_target bag context current "demod0");
452     let res = demodulate active_table current in
453       if Utils.debug_metas then
454         ignore ((function None -> () | Some x -> 
455                    ignore (Indexing.check_target bag context x "demod1");()) res);
456     res
457   in 
458   let res = demod current in
459   match res with
460   | None -> None
461   | Some c ->
462       if Indexing.in_index active_table c ||
463          check_for_deep_subsumption env active_table c 
464       then
465         None
466       else 
467         res
468 ;;
469
470 (** simplifies new using active and passive *)
471 let forward_simplify_new bag eq_uri env new_pos active =
472   if Utils.debug_metas then
473     begin
474       let m,c,u = env in
475         ignore(List.map 
476         (fun current -> Indexing.check_target bag c current "forward new pos") 
477       new_pos;)
478     end;
479   let active_list, active_table = active in
480   let demodulate table target =
481     let newmeta, newtarget =
482       Indexing.demodulation_equality bag eq_uri !maxmeta env table target 
483     in
484     maxmeta := newmeta;
485     newtarget
486   in
487   (* we could also demodulate using passive. Currently we don't *)
488   let new_pos = List.map (demodulate active_table) new_pos in
489   let new_pos_set =
490     List.fold_left
491       (fun s e ->
492          if not (Equality.is_identity env e) then
493            EqualitySet.add e s
494          else s)
495       EqualitySet.empty new_pos
496   in
497   let new_pos = EqualitySet.elements new_pos_set in
498
499   let subs e = Indexing.subsumption env active_table e = None in
500   let is_duplicate e = not (Indexing.in_index active_table e) in
501   List.filter subs (List.filter is_duplicate new_pos)
502 ;;
503
504
505 (** simplifies a goal with equalities in active and passive *)  
506 let rec simplify_goal bag env goal (active_list, active_table) =
507   let demodulate table goal = Indexing.demodulation_goal bag env table goal in
508   let changed, goal = demodulate active_table goal in
509   changed,
510   if not changed then 
511     goal 
512   else 
513     snd (simplify_goal bag env goal (active_list, active_table)) 
514 ;;
515
516
517 let simplify_goals bag env goals active =
518   let a_goals, p_goals = goals in
519   let p_goals = List.map (fun g -> snd (simplify_goal bag env g active)) p_goals in
520   let a_goals = List.map (fun g -> snd (simplify_goal bag env g active)) a_goals in
521   a_goals, p_goals
522 ;;
523
524
525 (** simplifies active usign new *)
526 let backward_simplify_active 
527   bag eq_uri env new_pos new_table min_weight active 
528 =
529   let active_list, active_table = active in
530   let active_list, newa, pruned = 
531     List.fold_right
532       (fun equality (res, newn,pruned) ->
533          let ew, _, _, _,id = Equality.open_equality equality in
534          if ew < min_weight then
535            equality::res, newn,pruned
536          else
537            match 
538              forward_simplify bag eq_uri env equality (new_pos, new_table) 
539            with
540            | None -> res, newn, id::pruned
541            | Some e ->
542                if Equality.compare equality e = 0 then
543                  e::res, newn, pruned
544                else 
545                  res, e::newn, pruned)
546       active_list ([], [],[])
547   in
548   let find eq1 where =
549     List.exists (Equality.meta_convertibility_eq eq1) where
550   in
551   let id_of_eq eq = 
552     let _, _, _, _,id = Equality.open_equality eq in id
553   in
554   let ((active1,pruned),tbl), newa =
555     List.fold_right
556       (fun eq ((res,pruned), tbl) ->
557          if List.mem eq res then
558            (res, (id_of_eq eq)::pruned),tbl 
559          else if (Equality.is_identity env eq) || (find eq res) then (
560            (res, (id_of_eq eq)::pruned),tbl
561          ) 
562          else
563            (eq::res,pruned), Indexing.index tbl eq)
564       active_list (([],pruned), Indexing.empty),
565     List.fold_right
566       (fun eq p ->
567          if (Equality.is_identity env eq) then p
568          else eq::p)
569       newa []
570   in
571   match newa with
572   | [] -> (active1,tbl), None, pruned 
573   | _ -> (active1,tbl), Some newa, pruned
574 ;;
575
576
577 (** simplifies passive using new *)
578 let backward_simplify_passive 
579   bag eq_uri env new_pos new_table min_weight passive 
580 =
581   let (pl, ps), passive_table = passive in
582   let f equality (resl, ress, newn) =
583     let ew, _, _, _ , _ = Equality.open_equality equality in
584     if ew < min_weight then
585       equality::resl, ress, newn
586     else
587       match 
588         forward_simplify bag eq_uri env equality (new_pos, new_table) 
589       with
590       | None -> resl, EqualitySet.remove equality ress, newn
591       | Some e ->
592           if equality = e then
593             equality::resl, ress, newn
594           else
595             let ress = EqualitySet.remove equality ress in
596               resl, ress, e::newn
597   in
598   let pl, ps, newp = List.fold_right f pl ([], ps, []) in
599   let passive_table =
600     List.fold_left
601       (fun tbl e -> Indexing.index tbl e) Indexing.empty pl
602   in
603   match newp with
604   | [] -> ((pl, ps), passive_table), None
605   |  _ -> ((pl, ps), passive_table), Some (newp)
606 ;;
607
608 let build_table equations =
609     List.fold_left
610       (fun (l, t, w) e ->
611          let ew, _, _, _ , _ = Equality.open_equality e in
612          e::l, Indexing.index t e, min ew w)
613       ([], Indexing.empty, 1000000) equations
614 ;;
615   
616
617 let backward_simplify bag eq_uri env new' active =
618   let new_pos, new_table, min_weight = build_table new' in
619   let active, newa, pruned =
620     backward_simplify_active bag eq_uri env new_pos new_table min_weight active 
621   in
622   active, newa, pruned
623 ;;
624
625 let close bag eq_uri env new' given =
626   let new_pos, new_table, min_weight =
627     List.fold_left
628       (fun (l, t, w) e ->
629          let ew, _, _, _ , _ = Equality.open_equality e in
630          e::l, Indexing.index t e, min ew w)
631       ([], Indexing.empty, 1000000) (snd new')
632   in
633   List.fold_left
634     (fun p c ->
635        let pos = infer bag eq_uri env c (new_pos,new_table) in
636          pos@p)
637     [] given 
638 ;;
639
640 let is_commutative_law eq =
641   let w, proof, (eq_ty, left, right, order), metas , _ = 
642     Equality.open_equality eq 
643   in
644     match left,right with
645         Cic.Appl[f1;Cic.Meta _ as a1;Cic.Meta _ as b1], 
646         Cic.Appl[f2;Cic.Meta _ as a2;Cic.Meta _ as b2] ->
647           f1 = f2 && a1 = b2 && a2 = b1
648       | _ -> false
649 ;;
650
651 let prova bag eq_uri env new' active = 
652   let given = List.filter is_commutative_law (fst active) in
653   let _ =
654     Utils.debug_print
655       (lazy
656          (Printf.sprintf "symmetric:\n%s\n"
657             (String.concat "\n"
658                (List.map
659                   (fun e -> Equality.string_of_equality ~env e)
660                    given)))) in
661     close bag eq_uri env new' given
662 ;;
663
664 (* returns an estimation of how many equalities in passive can be activated
665    within the current time limit *)
666 let get_selection_estimate () =
667   elapsed_time := (Unix.gettimeofday ()) -. !start_time;
668   (*   !processed_clauses * (int_of_float (!time_limit /. !elapsed_time)) *)
669   int_of_float (
670     ceil ((float_of_int !processed_clauses) *.
671             ((!time_limit (* *. 2. *)) /. !elapsed_time -. 1.)))
672 ;;
673
674
675 (** initializes the set of goals *)
676 let make_goals goal =
677   let active = []
678   and passive = [0, [goal]] in
679   active, passive
680 ;;
681
682 let make_goal_set goal = 
683   ([],[goal]) 
684 ;;
685
686 (** initializes the set of theorems *)
687 let make_theorems theorems =
688   theorems, []
689 ;;
690
691
692 let activate_goal (active, passive) =
693   if active = [] then
694     match passive with
695     | goal_conj::tl -> true, (goal_conj::active, tl)
696     | [] -> false, (active, passive)
697   else  
698     true, (active,passive)
699 ;;
700
701
702 let activate_theorem (active, passive) =
703   match passive with
704   | theorem::tl -> true, (theorem::active, tl)
705   | [] -> false, (active, passive)
706 ;;
707
708
709
710 let simplify_theorems bag env theorems ?passive (active_list, active_table) =
711   let pl, passive_table =
712     match passive with
713     | None -> [], None
714     | Some ((pn, _), (pp, _), pt) -> pn @ pp, Some pt
715   in
716   let a_theorems, p_theorems = theorems in
717   let demodulate table theorem =
718     let newmeta, newthm =
719       Indexing.demodulation_theorem bag !maxmeta env table theorem in
720     maxmeta := newmeta;
721     theorem != newthm, newthm
722   in
723   let foldfun table (a, p) theorem =
724     let changed, theorem = demodulate table theorem in
725     if changed then (a, theorem::p) else (theorem::a, p)
726   in
727   let mapfun table theorem = snd (demodulate table theorem) in
728   match passive_table with
729   | None ->
730       let p_theorems = List.map (mapfun active_table) p_theorems in
731       List.fold_left (foldfun active_table) ([], p_theorems) a_theorems
732   | Some passive_table ->
733       let p_theorems = List.map (mapfun active_table) p_theorems in
734       let p_theorems, a_theorems =
735         List.fold_left (foldfun active_table) ([], p_theorems) a_theorems in
736       let p_theorems = List.map (mapfun passive_table) p_theorems in
737       List.fold_left (foldfun passive_table) ([], p_theorems) a_theorems
738 ;;
739
740
741 let rec simpl bag eq_uri env e others others_simpl =
742   let active = others @ others_simpl in
743   let tbl =
744     List.fold_left
745       (fun t e -> 
746          if Equality.is_weak_identity e then t else Indexing.index t e) 
747       Indexing.empty active
748   in
749   let res = forward_simplify bag eq_uri env e (active, tbl) in
750     match others with
751       | hd::tl -> (
752           match res with
753             | None -> simpl bag eq_uri env hd tl others_simpl
754             | Some e -> simpl bag eq_uri env hd tl (e::others_simpl)
755         )
756       | [] -> (
757           match res with
758             | None -> others_simpl
759             | Some e -> e::others_simpl
760         )
761 ;;
762
763 let simplify_equalities bag eq_uri env equalities =
764   Utils.debug_print
765     (lazy 
766        (Printf.sprintf "equalities:\n%s\n"
767           (String.concat "\n"
768              (List.map Equality.string_of_equality equalities))));
769   Utils.debug_print (lazy "SIMPLYFYING EQUALITIES...");
770   match equalities with
771     | [] -> []
772     | hd::tl ->
773         let res =
774           List.rev (simpl bag eq_uri env hd tl [])
775         in
776           Utils.debug_print
777             (lazy
778                (Printf.sprintf "equalities AFTER:\n%s\n"
779                   (String.concat "\n"
780                      (List.map Equality.string_of_equality res))));
781           res
782 ;;
783
784 let print_goals goals = 
785   (String.concat "\n"
786      (List.map
787         (fun (d, gl) ->
788            let gl' =
789              List.map
790                (fun (p, _, t) ->
791                   (* (string_of_proof p) ^ ", " ^ *) (CicPp.ppterm t)) gl
792            in
793            Printf.sprintf "%d: %s" d (String.concat "; " gl')) goals))
794 ;;
795               
796 let pp_goal_set msg goals names = 
797   let active_goals, passive_goals = goals in
798   prerr_endline ("////" ^ msg);
799   prerr_endline ("ACTIVE G: " ^
800     (String.concat "\n " (List.map (fun (_,_,g) -> CicPp.pp g names)
801     active_goals)));
802   prerr_endline ("PASSIVE G: " ^
803     (String.concat "\n " (List.map (fun (_,_,g) -> CicPp.pp g names)
804     passive_goals)))
805 ;;
806
807 let check_if_goal_is_subsumed bag ((_,ctx,_) as env) table (goalproof,menv,ty) =
808 (*   let names = Utils.names_of_context ctx in *)
809   match ty with
810   | Cic.Appl[Cic.MutInd(uri,_,_);eq_ty;left;right] 
811     when LibraryObjects.is_eq_URI uri ->
812       (let goal_equation = 
813          Equality.mk_equality bag
814            (0,Equality.Exact (Cic.Implicit None),(eq_ty,left,right,Utils.Eq),menv) 
815       in
816 (*      match Indexing.subsumption env table goal_equation with*)
817        match Indexing.unification env table goal_equation with 
818         | Some (subst, equality, swapped ) ->
819 (*
820             prerr_endline 
821              ("GOAL SUBSUMED IS: "^Equality.string_of_equality goal_equation ~env);
822             prerr_endline 
823              ("GOAL IS SUBSUMED BY: "^Equality.string_of_equality equality ~env);
824             prerr_endline ("SUBST:"^Subst.ppsubst ~names subst);
825 *)
826             let (_,p,(ty,l,r,_),m,id) = Equality.open_equality equality in
827             let cicmenv = Subst.apply_subst_metasenv subst (m @ menv) in
828             let p =
829               if swapped then
830                 Equality.symmetric bag eq_ty l id uri m
831               else
832                 p
833             in
834             Some (goalproof, p, id, subst, cicmenv)
835         | None -> None)
836   | _ -> None
837 ;;
838
839 let check_if_goal_is_identity env = function
840   | (goalproof,m,Cic.Appl[Cic.MutInd(uri,_,ens);eq_ty;left;right]) 
841     when left = right && LibraryObjects.is_eq_URI uri ->
842       let reflproof = Equality.Exact (Equality.refl_proof uri eq_ty left) in
843       Some (goalproof, reflproof, 0, Subst.empty_subst,m)
844   | (goalproof,m,Cic.Appl[Cic.MutInd(uri,_,ens);eq_ty;left;right]) 
845     when LibraryObjects.is_eq_URI uri ->
846     (let _,context,_ = env in
847     try 
848      let s,m,_ = 
849        Inference.unification m m context left right CicUniv.empty_ugraph 
850      in
851       let reflproof = Equality.Exact (Equality.refl_proof uri eq_ty left) in
852       let m = Subst.apply_subst_metasenv s m in
853       Some (goalproof, reflproof, 0, s,m)
854     with _ -> None)
855   | _ -> None
856 ;;                              
857     
858 let rec check goal = function
859   | [] -> None
860   | f::tl ->
861       match f goal with
862       | None -> check goal tl
863       | (Some p) as ok  -> ok
864 ;;
865   
866 let simplify_goal_set bag env goals active = 
867   let active_goals, passive_goals = goals in 
868   let find (_,_,g) where =
869     List.exists (fun (_,_,g1) -> Equality.meta_convertibility g g1) where
870   in
871     (* prova:tengo le passive semplificate 
872   let passive_goals = 
873     List.map (fun g -> snd (simplify_goal env g active)) passive_goals 
874   in *)
875     List.fold_left
876       (fun (acc_a,acc_p) goal -> 
877         match simplify_goal bag env goal active with 
878         | changed, g -> 
879             if changed then 
880               if find g acc_p then acc_a,acc_p else acc_a,g::acc_p
881             else
882               if find g acc_a then acc_a,acc_p else g::acc_a,acc_p)
883       ([],passive_goals) active_goals
884 ;;
885
886 let check_if_goals_set_is_solved bag env active goals =
887   let active_goals, passive_goals = goals in
888   List.fold_left 
889     (fun proof goal ->
890       match proof with
891       | Some p -> proof
892       | None -> 
893           check goal [
894             check_if_goal_is_identity env;
895             check_if_goal_is_subsumed bag env (snd active)])
896 (* provare active and passive?*)
897     None active_goals
898 ;;
899
900 let infer_goal_set bag env active goals = 
901   let active_goals, passive_goals = goals in
902   let rec aux = function
903     | [] -> active_goals, []
904     | hd::tl ->
905         let changed,selected = simplify_goal bag env hd active in
906 (*
907         if changed then
908           prerr_endline ("--------------- goal semplificato");
909 *)
910         let (_,_,t1) = selected in
911         let already_in = 
912           List.exists (fun (_,_,t) -> Equality.meta_convertibility t t1) 
913               active_goals
914         in
915         if already_in then 
916              aux tl
917           else
918             let passive_goals = tl in
919             let new_passive_goals =
920               if Utils.metas_of_term t1 = [] then passive_goals
921               else 
922                 let newmaxmeta,new' = 
923                    Indexing.superposition_left bag env (snd active) selected
924                    !maxmeta 
925                 in
926                 maxmeta := newmaxmeta;
927                 passive_goals @ new'
928             in
929             selected::active_goals, new_passive_goals
930   in 
931   aux passive_goals
932 ;;
933
934 let infer_goal_set_with_current bag env current goals active = 
935   let active_goals, passive_goals = simplify_goal_set bag env goals active in
936   let l,table,_  = build_table [current] in
937   active_goals, 
938   List.fold_left 
939     (fun acc g ->
940       let newmaxmeta, new' = Indexing.superposition_left bag env table g !maxmeta in
941       maxmeta := newmaxmeta;
942       acc @ new')
943     passive_goals active_goals
944 ;;
945
946 let ids_of_goal g = 
947   let p,_,_ = g in
948   let ids = List.map (fun _,_,i,_,_ -> i) p in
949   ids
950 ;;
951
952 let ids_of_goal_set (ga,gp) =
953   List.flatten (List.map ids_of_goal ga) @
954   List.flatten (List.map ids_of_goal gp)
955 ;;
956
957 let size_of_goal_set_a (l,_) = List.length l;;
958 let size_of_goal_set_p (_,l) = List.length l;;
959       
960 let pp_goals label goals context = 
961   let names = Utils.names_of_context context in
962   List.iter                 
963     (fun _,_,g -> 
964       prerr_endline 
965         (Printf.sprintf  "Current goal: %s = %s\n" label (CicPp.pp g names))) 
966     (fst goals);
967   List.iter                 
968     (fun _,_,g -> 
969       prerr_endline 
970         (Printf.sprintf  "PASSIVE goal: %s = %s\n" label (CicPp.pp g names))) 
971       (snd goals);
972 ;;
973
974 let print_status iterno goals active passive =
975   prerr_endline 
976     (Printf.sprintf "\n%d #ACTIVES: %d #PASSIVES: %d #GOALSET: %d(%d)"
977       iterno (size_of_active active) (size_of_passive passive)
978       (size_of_goal_set_a goals) (size_of_goal_set_p goals)) 
979 ;;
980
981 (** given-clause algorithm with full reduction strategy: NEW implementation *)
982 (* here goals is a set of goals in OR *)
983 let given_clause 
984   bag eq_uri ((_,context,_) as env) goals passive active 
985   goal_steps saturation_steps max_time
986
987   let initial_time = Unix.gettimeofday () in
988   let iterations_left iterno = 
989     let now = Unix.gettimeofday () in
990     let time_left = max_time -. now in
991     let time_spent_until_now = now -. initial_time in
992     let iteration_medium_cost = 
993       time_spent_until_now /. (float_of_int iterno)
994     in
995     let iterations_left = time_left /. iteration_medium_cost in
996     int_of_float iterations_left 
997   in
998   let rec step goals passive active g_iterno s_iterno =
999     if g_iterno > goal_steps && s_iterno > saturation_steps then
1000       (ParamodulationFailure ("No more iterations to spend",active,passive))
1001     else if Unix.gettimeofday () > max_time then
1002       (ParamodulationFailure ("No more time to spend",active,passive))
1003     else
1004       let _ = 
1005          print_status (max g_iterno s_iterno) goals active passive  
1006 (*         Printf.eprintf ".%!"; *)
1007       in
1008       (* PRUNING OF PASSIVE THAT WILL NEVER BE PROCESSED *) 
1009       let passive =
1010         let selection_estimate = iterations_left (max g_iterno s_iterno) in
1011         let kept = size_of_passive passive in
1012         if kept > selection_estimate then 
1013           begin
1014             (*Printf.eprintf "Too many passive equalities: pruning...";
1015             prune_passive selection_estimate active*) passive
1016           end
1017         else
1018           passive
1019       in
1020       kept_clauses := (size_of_passive passive) + (size_of_active active);
1021       let goals = 
1022         if g_iterno < goal_steps then
1023           infer_goal_set bag env active goals 
1024         else
1025           goals
1026       in
1027       match check_if_goals_set_is_solved bag env active goals with
1028       | Some p -> 
1029           prerr_endline 
1030             (Printf.sprintf "\nFound a proof in: %f\n" 
1031               (Unix.gettimeofday() -. initial_time));
1032           ParamodulationSuccess (p,active,passive)
1033       | None -> 
1034           (* SELECTION *)
1035           if passive_is_empty passive then
1036             if no_more_passive_goals goals then 
1037               ParamodulationFailure 
1038                 ("No more passive equations/goals",active,passive)
1039               (*maybe this is a success! *)
1040             else
1041               step goals passive active (g_iterno+1) (s_iterno+1)
1042           else
1043             begin
1044               (* COLLECTION OF GARBAGED EQUALITIES *)
1045               if max g_iterno s_iterno mod 40 = 0 then
1046                 begin
1047                   print_status (max g_iterno s_iterno) goals active passive;
1048                   let active = List.map Equality.id_of (fst active) in
1049                   let passive = List.map Equality.id_of (fst passive) in
1050                   let goal = ids_of_goal_set goals in
1051                   Equality.collect bag active passive goal
1052                 end;
1053               let res, passive = 
1054                 if s_iterno < saturation_steps then
1055                   let current, passive = select env goals passive in
1056                   (* SIMPLIFICATION OF CURRENT *)
1057                   prerr_endline
1058                         ("Selected : " ^ 
1059                           Equality.string_of_equality ~env  current);
1060                   forward_simplify bag eq_uri env current active, passive
1061                 else
1062                   None, passive
1063               in
1064               match res with
1065               | None -> step goals passive active (g_iterno+1) (s_iterno+1)
1066               | Some current ->
1067                   (* GENERATION OF NEW EQUATIONS *)
1068 (*                   prerr_endline "infer"; *)
1069                   let new' = infer bag eq_uri env current active in
1070 (*                   prerr_endline "infer goal"; *)
1071 (*
1072       match check_if_goals_set_is_solved env active goals with
1073       | Some p -> 
1074           prerr_endline 
1075             (Printf.sprintf "Found a proof in: %f\n" 
1076               (Unix.gettimeofday() -. initial_time));
1077           ParamodulationSuccess p
1078       | None -> 
1079 *)
1080                   let active = 
1081                       let al, tbl = active in
1082                       al @ [current], Indexing.index tbl current
1083                   in
1084                   let goals = 
1085                     infer_goal_set_with_current bag env current goals active 
1086                   in
1087                   (* FORWARD AND BACKWARD SIMPLIFICATION *)
1088 (*                   prerr_endline "fwd/back simpl"; *)
1089                   let rec simplify new' active passive =
1090                     let new' = 
1091                       forward_simplify_new bag eq_uri env new' active 
1092                     in
1093                     let active, newa, pruned =
1094                       backward_simplify bag eq_uri env new' active 
1095                     in
1096                     let passive = 
1097                       List.fold_left (filter_dependent bag) passive pruned 
1098                     in
1099                     match newa with
1100                     | None -> active, passive, new'
1101                     | Some p -> simplify (new' @ p) active passive 
1102                   in
1103                   let active, passive, new' = 
1104                     simplify new' active passive
1105                   in
1106 (*                   prerr_endline "simpl goal with new"; *)
1107                   let goals = 
1108                     let a,b,_ = build_table new' in
1109 (*                     let _ = <:start<simplify_goal_set new>> in *)
1110                     let rc = simplify_goal_set bag env goals (a,b) in
1111 (*                     let _ = <:stop<simplify_goal_set new>> in *)
1112                     rc
1113                   in
1114                   let passive = add_to_passive passive new' [] in
1115                   step goals passive active (g_iterno+1) (s_iterno+1)
1116             end
1117   in
1118     step goals passive active 1 1
1119 ;;
1120
1121 let rec saturate_equations bag eq_uri env goal accept_fun passive active =
1122   elapsed_time := Unix.gettimeofday () -. !start_time;
1123   if !elapsed_time > !time_limit then
1124     (active, passive)
1125   else
1126     let current, passive = select env ([goal],[]) passive in
1127     let res = forward_simplify bag eq_uri env current active in
1128     match res with
1129     | None ->
1130         saturate_equations bag eq_uri env goal accept_fun passive active
1131     | Some current ->
1132         Utils.debug_print (lazy (Printf.sprintf "selected: %s"
1133                              (Equality.string_of_equality ~env current)));
1134         let new' = infer bag eq_uri env current active in
1135         let active =
1136           if Equality.is_identity env current then active
1137           else
1138             let al, tbl = active in
1139             al @ [current], Indexing.index tbl current
1140         in
1141         (* alla fine new' contiene anche le attive semplificate!
1142          * quindi le aggiungo alle passive insieme alle new *)
1143         let rec simplify new' active passive =
1144           let new' = forward_simplify_new bag eq_uri env new' active in
1145           let active, newa, pruned =
1146             backward_simplify bag eq_uri env new' active in
1147           let passive = 
1148             List.fold_left (filter_dependent bag) passive pruned in
1149           match newa with
1150           | None -> active, passive, new'
1151           | Some p -> simplify (new' @ p) active passive
1152         in
1153         let active, passive, new' = simplify new' active passive in
1154         let _ =
1155           Utils.debug_print
1156             (lazy
1157                (Printf.sprintf "active:\n%s\n"
1158                   (String.concat "\n"
1159                      (List.map
1160                          (fun e -> Equality.string_of_equality ~env e)
1161                          (fst active)))))
1162         in
1163         let _ =
1164           Utils.debug_print
1165             (lazy
1166                (Printf.sprintf "new':\n%s\n"
1167                   (String.concat "\n"
1168                      (List.map
1169                          (fun e -> "Negative " ^
1170                             (Equality.string_of_equality ~env e)) new'))))
1171         in
1172         let new' = List.filter accept_fun new' in
1173         let passive = add_to_passive passive new' [] in
1174         saturate_equations bag eq_uri env goal accept_fun passive active
1175 ;;
1176   
1177 let default_depth = !maxdepth
1178 and default_width = !maxwidth;;
1179
1180 let reset_refs () =
1181   maxmeta := 0;
1182   symbols_counter := 0;
1183   weight_age_counter := !weight_age_ratio;
1184   processed_clauses := 0;
1185   start_time := 0.;
1186   elapsed_time := 0.;
1187   maximal_retained_equality := None;
1188   infer_time := 0.;
1189   forward_simpl_time := 0.;
1190   forward_simpl_new_time := 0.;
1191   backward_simpl_time := 0.;
1192   passive_maintainance_time := 0.;
1193   derived_clauses := 0;
1194   kept_clauses := 0;
1195 ;;
1196
1197 let eq_of_goal = function
1198   | Cic.Appl [Cic.MutInd(uri,0,_);_;_;_] when LibraryObjects.is_eq_URI uri ->
1199       uri
1200   | _ -> raise (ProofEngineTypes.Fail (lazy ("The goal is not an equality ")))
1201 ;;
1202
1203 let eq_and_ty_of_goal = function
1204   | Cic.Appl [Cic.MutInd(uri,0,_);t;_;_] when LibraryObjects.is_eq_URI uri ->
1205       uri,t
1206   | _ -> raise (ProofEngineTypes.Fail (lazy ("The goal is not an equality ")))
1207 ;;
1208
1209 (* status: input proof status
1210  * goalproof: forward steps on goal
1211  * newproof: backward steps
1212  * subsumption_id: the equation used if goal is closed by subsumption
1213  *   (0 if not closed by subsumption) (DEBUGGING: can be safely removed)
1214  * subsumption_subst: subst to make newproof and goalproof match
1215  * proof_menv: final metasenv
1216  *)
1217 let build_proof 
1218   bag status  
1219   goalproof newproof subsumption_id subsumption_subst proof_menv
1220 =
1221   let proof, goalno = status in
1222   let uri, metasenv, meta_proof, term_to_prove = proof in
1223   let _, context, type_of_goal = CicUtil.lookup_meta goalno metasenv in
1224   let eq_uri = eq_of_goal type_of_goal in 
1225       let names = Utils.names_of_context context in
1226       prerr_endline "Proof:";
1227       prerr_endline 
1228         (Equality.pp_proof bag names goalproof newproof subsumption_subst
1229           subsumption_id type_of_goal);
1230 (*       prerr_endline "ENDOFPROOFS"; *)
1231 (*
1232       prerr_endline ("max weight: " ^ 
1233         (string_of_int (Equality.max_weight goalproof newproof)));
1234 *)
1235       (* generation of the CIC proof *)
1236       let side_effects = 
1237         List.filter (fun i -> i <> goalno)
1238           (ProofEngineHelpers.compare_metasenvs 
1239             ~newmetasenv:metasenv ~oldmetasenv:proof_menv)
1240       in
1241       let goal_proof, side_effects_t = 
1242         let initial = Equality.add_subst subsumption_subst newproof in
1243         Equality.build_goal_proof bag
1244           eq_uri goalproof initial type_of_goal side_effects
1245           context proof_menv
1246       in
1247 (*       prerr_endline ("PROOF: " ^ CicPp.pp goal_proof names); *)
1248       let goal_proof = Subst.apply_subst subsumption_subst goal_proof in
1249       let metas_still_open_in_proof = Utils.metas_of_term goal_proof in
1250 (*prerr_endline (CicPp.pp goal_proof names);*)
1251       (* ?? *)
1252       let goal_proof = (* Subst.apply_subst subsumption_subst *) goal_proof in
1253       let side_effects_t = 
1254         List.map (Subst.apply_subst subsumption_subst) side_effects_t
1255       in
1256       (* replacing fake mets with real ones *)
1257 (*       prerr_endline "replacing metas..."; *)
1258       let irl=CicMkImplicit.identity_relocation_list_for_metavariable context in
1259       let goal_proof_menv, what, with_what,free_meta = 
1260         List.fold_left 
1261           (fun (acc1,acc2,acc3,uniq) (i,_,ty) -> 
1262              match uniq with
1263                | Some m -> 
1264 (*                    acc1, (Cic.Meta(i,[]))::acc2, m::acc3, uniq *)
1265                    (i,context,ty)::acc1, (Cic.Meta(i,[]))::acc2, (Cic.Meta(i,irl))::acc3, uniq
1266                | None ->
1267                    [i,context,ty], (Cic.Meta(i,[]))::acc2, 
1268                    (Cic.Meta(i,irl)) ::acc3,Some (Cic.Meta(i,irl))) 
1269           ([],[],[],None) 
1270           (List.filter 
1271            (fun (i,_,_) -> List.mem i metas_still_open_in_proof) 
1272            proof_menv)
1273       in
1274       let replace where = 
1275         (* we need this fake equality since the metas of the hypothesis may be
1276          * with a real local context *)
1277         ProofEngineReduction.replace_lifting 
1278           ~equality:(fun x y -> 
1279             match x,y with Cic.Meta(i,_),Cic.Meta(j,_) -> i=j | _-> false)
1280           ~what ~with_what ~where
1281       in
1282       let goal_proof = replace goal_proof in
1283         (* ok per le meta libere... ma per quelle che c'erano e sono rimaste? 
1284          * what mi pare buono, sostituisce solo le meta farlocche *)
1285       let side_effects_t = List.map replace side_effects_t in
1286       let free_metas = 
1287         List.filter (fun i -> i <> goalno)
1288           (ProofEngineHelpers.compare_metasenvs 
1289             ~oldmetasenv:metasenv ~newmetasenv:goal_proof_menv)
1290       in
1291 (* prerr_endline ("freemetas: " ^ String.concat "," (List.map string_of_int
1292  * free_metas) ); *)
1293       (* check/refine/... build the new proof *)
1294       let replaced_goal = 
1295         ProofEngineReduction.replace
1296           ~what:side_effects ~with_what:side_effects_t
1297           ~equality:(fun i t -> match t with Cic.Meta(j,_)->j=i|_->false)
1298           ~where:type_of_goal
1299       in
1300       let subst_side_effects,real_menv,_ = 
1301         let fail t s = raise (ProofEngineTypes.Fail (lazy (t^Lazy.force s))) in
1302         let free_metas_menv = 
1303           List.map (fun i -> CicUtil.lookup_meta i goal_proof_menv) free_metas
1304         in
1305 (*
1306         prerr_endline ("XX type_of_goal  " ^ CicPp.ppterm type_of_goal);
1307         prerr_endline ("XX replaced_goal " ^ CicPp.ppterm replaced_goal);
1308         prerr_endline ("XX metasenv      " ^ 
1309         CicMetaSubst.ppmetasenv [] (metasenv @ free_metas_menv));
1310 *)
1311         try
1312           CicUnification.fo_unif_subst [] context (metasenv @ free_metas_menv)
1313            replaced_goal type_of_goal CicUniv.empty_ugraph
1314         with
1315         | CicUnification.UnificationFailure s
1316         | CicUnification.Uncertain s 
1317         | CicUnification.AssertFailure s -> 
1318             fail "Maybe the local context of metas in the goal was not an IRL" s
1319       in
1320       let final_subst = 
1321         (goalno,(context,goal_proof,type_of_goal))::subst_side_effects
1322       in
1323 (* prerr_endline ("MENVreal_menv: " ^ CicMetaSubst.ppmetasenv [] real_menv); *)
1324       let _ = 
1325         try
1326           CicTypeChecker.type_of_aux' real_menv context goal_proof
1327             CicUniv.empty_ugraph
1328         with 
1329         | CicUtil.Meta_not_found _ 
1330         | CicTypeChecker.TypeCheckerFailure _ 
1331         | CicTypeChecker.AssertFailure _ 
1332         | Invalid_argument "list_fold_left2" as exn ->
1333             prerr_endline "THE PROOF DOES NOT TYPECHECK!";
1334             prerr_endline (CicPp.pp goal_proof names); 
1335             prerr_endline "THE PROOF DOES NOT TYPECHECK!";
1336             raise exn
1337       in
1338       let proof, real_metasenv = 
1339         ProofEngineHelpers.subst_meta_and_metasenv_in_proof
1340           proof goalno (CicMetaSubst.apply_subst final_subst) real_menv
1341       in
1342       let open_goals = 
1343         match free_meta with Some(Cic.Meta(m,_)) when m<>goalno ->[m] | _ ->[] 
1344       in
1345 (*
1346       Printf.eprintf 
1347         "GOALS APERTI: %s\nMETASENV PRIMA:\n%s\nMETASENV DOPO:\n%s\n" 
1348           (String.concat ", " (List.map string_of_int open_goals))
1349           (CicMetaSubst.ppmetasenv [] metasenv)
1350           (CicMetaSubst.ppmetasenv [] real_metasenv);
1351 *)
1352       final_subst, proof, open_goals
1353 ;;
1354
1355 let find_equalities dbd status smart_flag ?auto cache =
1356   let proof, goalno = status in
1357   let _, metasenv,_,_ = proof in
1358   let _, context, type_of_goal = CicUtil.lookup_meta goalno metasenv in
1359   let eq_uri = eq_of_goal type_of_goal in 
1360   let env = (metasenv, context, CicUniv.empty_ugraph) in 
1361   let bag = Equality.mk_equality_bag () in
1362   let eq_indexes, equalities, maxm, cache = 
1363     Equality_retrieval.find_context_equalities 0 bag ?auto context proof cache
1364   in
1365   prerr_endline ">>>>>>>>>> gained from the context >>>>>>>>>>>>";
1366   List.iter (fun e -> prerr_endline (Equality.string_of_equality e)) equalities;
1367   prerr_endline ">>>>>>>>>>>>>>>>>>>>>>";
1368   let lib_eq_uris, library_equalities, maxm, cache =
1369     Equality_retrieval.find_library_equalities bag
1370       ?auto smart_flag dbd context (proof, goalno) (maxm+2)
1371       cache
1372   in
1373   prerr_endline (">>>>>>>>>>  gained from the library >>>>>>>>>>>>" ^
1374     string_of_int maxm);
1375   List.iter
1376     (fun (_,e) -> prerr_endline (Equality.string_of_equality e)) 
1377     library_equalities;
1378   prerr_endline ">>>>>>>>>>>>>>>>>>>>>>";
1379   let equalities = List.map snd library_equalities @ equalities in
1380   let equalities = 
1381     simplify_equalities bag eq_uri env equalities
1382   in 
1383   prerr_endline ">>>>>>>>>> after simplify >>>>>>>>>>>>";
1384   List.iter
1385     (fun e -> prerr_endline (Equality.string_of_equality e)) equalities;
1386   prerr_endline (">>>>>>>>>>>>>>>>>>>>>>" ^ string_of_int maxm);
1387   bag, equalities, cache, maxm
1388 ;;
1389
1390 let saturate_more bag active maxmeta status smart_flag ?auto cache =
1391   let proof, goalno = status in
1392   let _, metasenv,_,_ = proof in
1393   let _, context, type_of_goal = CicUtil.lookup_meta goalno metasenv in
1394   let eq_uri = eq_of_goal type_of_goal in 
1395   let env = (metasenv, context, CicUniv.empty_ugraph) in 
1396   let eq_indexes, equalities, maxm, cache = 
1397     Equality_retrieval.find_context_equalities maxmeta bag ?auto context proof cache
1398   in
1399   prerr_endline (">>>>>>> gained from a new context saturation >>>>>>>>>" ^
1400     string_of_int maxm);
1401   List.iter
1402     (fun e -> prerr_endline (Equality.string_of_equality ~env e)) 
1403     equalities;
1404   prerr_endline ">>>>>>>>>>>>>>>>>>>>>>";
1405   let equalities = 
1406     HExtlib.filter_map 
1407       (fun e -> forward_simplify bag eq_uri env e active)
1408     equalities
1409   in
1410   prerr_endline ">>>>>>>>>> after simplify >>>>>>>>>>>>";
1411   List.iter
1412     (fun e -> prerr_endline (Equality.string_of_equality ~env e)) equalities;
1413   prerr_endline (">>>>>>>>>>>>>>>>>>>>>>" ^ string_of_int maxm);
1414   bag, equalities, cache, maxm
1415
1416 let saturate 
1417     smart_flag 
1418     dbd ?(full=false) ?(depth=default_depth) ?(width=default_width) 
1419     ?(timeout=600.) ?auto status = 
1420   let module C = Cic in
1421   reset_refs ();
1422   maxdepth := depth;
1423   maxwidth := width;
1424 (*  CicUnification.unif_ty := false;*)
1425   let proof, goalno = status in
1426   let uri, metasenv, meta_proof, term_to_prove = proof in
1427   let _, context, type_of_goal = CicUtil.lookup_meta goalno metasenv in
1428   let eq_uri = eq_of_goal type_of_goal in 
1429   let cleaned_goal = Utils.remove_local_context type_of_goal in
1430   Utils.set_goal_symbols cleaned_goal; (* DISACTIVATED *)
1431   let ugraph = CicUniv.empty_ugraph in
1432   let env = (metasenv, context, ugraph) in 
1433   let goal = [], List.filter (fun (i,_,_)->i<>goalno) metasenv, cleaned_goal in
1434   let bag, equalities, cache, maxm = 
1435     find_equalities dbd status smart_flag ?auto AutoCache.cache_empty 
1436   in
1437   let res, time =
1438     maxmeta := maxm+2;
1439     let t1 = Unix.gettimeofday () in
1440     let theorems =
1441       let refl_equal = LibraryObjects.eq_refl_URI ~eq:eq_uri in
1442       let t = CicUtil.term_of_uri refl_equal in
1443       let ty, _ = CicTypeChecker.type_of_aux' [] [] t CicUniv.empty_ugraph in
1444       [(t, ty, [])], []
1445     in
1446     let t2 = Unix.gettimeofday () in
1447     let _ =
1448       Utils.debug_print
1449         (lazy
1450            (Printf.sprintf
1451               "Theorems:\n-------------------------------------\n%s\n"
1452               (String.concat "\n"
1453                  (List.map
1454                     (fun (t, ty, _) ->
1455                        Printf.sprintf
1456                          "Term: %s, type: %s"
1457                          (CicPp.ppterm t) (CicPp.ppterm ty))
1458                     (fst theorems)))));
1459       Utils.debug_print
1460         (lazy
1461            (Printf.sprintf "Time to retrieve theorems: %.9f\n" (t2 -. t1)));
1462     in
1463     let active = make_empty_active () in
1464     let passive = make_passive equalities in
1465     let start = Unix.gettimeofday () in
1466     let res =
1467 (*
1468       let goals = make_goals goal in
1469       given_clause_fullred dbd env goals theorems passive active
1470 *)
1471       let goals = make_goal_set goal in
1472       let max_iterations = 10000 in
1473       let max_time = Unix.gettimeofday () +.  timeout (* minutes *) in
1474       given_clause bag
1475         eq_uri env goals passive active max_iterations max_iterations max_time 
1476     in
1477     let finish = Unix.gettimeofday () in
1478     (res, finish -. start)
1479   in
1480   match res with
1481   | ParamodulationFailure (s,_,_) ->
1482       raise (ProofEngineTypes.Fail (lazy ("NO proof found: " ^ s)))
1483   | ParamodulationSuccess 
1484     ((goalproof,newproof,subsumption_id,subsumption_subst, proof_menv),_,_) ->
1485       prerr_endline (Printf.sprintf "\nTIME NEEDED: %8.2f" time);
1486     let _,p,gl = 
1487       build_proof bag
1488         status goalproof newproof subsumption_id subsumption_subst proof_menv
1489     in
1490     p,gl
1491 ;;
1492 (* **************** HERE ENDS THE PARAMODULATION STUFF ******************** *)
1493
1494 (* exported version of given_clause *)
1495 let given_clause 
1496   bag maxm status active passive goal_steps saturation_steps max_time 
1497 =
1498   reset_refs();
1499   maxmeta := maxm;
1500   let max_l l = 
1501     List.fold_left 
1502      (fun acc e -> let _,_,_,menv,_ = Equality.open_equality e in
1503       List.fold_left (fun acc (i,_,_) -> max i acc) acc menv)
1504      0 l
1505   in
1506   let active_l = fst active in
1507   let passive_l = fst passive in
1508   let ma = max_l active_l in
1509   let mp = max_l passive_l in
1510   assert (maxm > max ma mp);
1511   let proof, goalno = status in
1512   let uri, metasenv, meta_proof, term_to_prove = proof in
1513   let _, context, type_of_goal = CicUtil.lookup_meta goalno metasenv in
1514   let eq_uri = eq_of_goal type_of_goal in 
1515   let cleaned_goal = Utils.remove_local_context type_of_goal in
1516   Utils.set_goal_symbols cleaned_goal; (* DISACTIVATED *)
1517   let goal = [], List.filter (fun (i,_,_)->i<>goalno) metasenv, cleaned_goal in
1518   let env = metasenv,context,CicUniv.empty_ugraph in
1519   prerr_endline ">>>>>> ACTIVES >>>>>>>>"; 
1520   List.iter (fun e -> prerr_endline (Equality.string_of_equality ~env e))
1521   active_l;
1522   prerr_endline ">>>>>>>>>>>>>>"; 
1523   let goals = make_goal_set goal in
1524   match 
1525     given_clause bag eq_uri env goals passive active 
1526       goal_steps saturation_steps max_time
1527   with
1528   | ParamodulationFailure (_,a,p) ->
1529       None, a, p, !maxmeta
1530   | ParamodulationSuccess 
1531     ((goalproof,newproof,subsumption_id,subsumption_subst, proof_menv),a,p) ->
1532     let subst, proof, gl =
1533       build_proof bag
1534         status goalproof newproof subsumption_id subsumption_subst proof_menv
1535     in
1536     Some (subst, proof,gl),a,p, !maxmeta
1537 ;;
1538
1539 let demodulate_tac ~dbd ((proof,goal)(*s initialstatus*)) = 
1540   let curi,metasenv,pbo,pty = proof in
1541   let metano,context,ty = CicUtil.lookup_meta goal metasenv in
1542   let eq_uri = eq_of_goal ty in
1543   let bag = Equality.mk_equality_bag () in
1544   let eq_indexes, equalities, maxm, cache = 
1545     Equality_retrieval.find_context_equalities 0 bag context proof AutoCache.cache_empty
1546   in
1547   let lib_eq_uris, library_equalities, maxm, cache =
1548     Equality_retrieval.find_library_equalities bag 
1549       false dbd context (proof, goal) (maxm+2)  cache 
1550   in
1551   if library_equalities = [] then prerr_endline "VUOTA!!!";
1552   let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
1553   let library_equalities = List.map snd library_equalities in
1554   let initgoal = [], [], ty in
1555   let env = (metasenv, context, CicUniv.empty_ugraph) in
1556   let equalities = 
1557     simplify_equalities bag eq_uri env (equalities@library_equalities) 
1558   in   
1559   let table = 
1560     List.fold_left 
1561       (fun tbl eq -> Indexing.index tbl eq) 
1562       Indexing.empty equalities 
1563   in
1564   let changed,(newproof,newmetasenv, newty) = 
1565     Indexing.demodulation_goal bag
1566       (metasenv,context,CicUniv.empty_ugraph) table initgoal 
1567   in
1568   if changed then
1569     begin
1570       let opengoal = Equality.Exact (Cic.Meta(maxm,irl)) in
1571       let proofterm,_ = 
1572         Equality.build_goal_proof bag
1573           eq_uri newproof opengoal ty [] context metasenv
1574       in
1575         let extended_metasenv = (maxm,context,newty)::metasenv in
1576         let extended_status = 
1577           (curi,extended_metasenv,pbo,pty),goal in
1578         let (status,newgoals) = 
1579           ProofEngineTypes.apply_tactic 
1580             (PrimitiveTactics.apply_tac ~term:proofterm)
1581             extended_status in
1582         (status,maxm::newgoals)
1583     end
1584   else (* if newty = ty then *)
1585     raise (ProofEngineTypes.Fail (lazy "no progress"))
1586   (*else ProofEngineTypes.apply_tactic 
1587     (ReductionTactics.simpl_tac
1588       ~pattern:(ProofEngineTypes.conclusion_pattern None)) initialstatus*)
1589 ;;
1590
1591 let demodulate_tac ~dbd = ProofEngineTypes.mk_tactic (demodulate_tac ~dbd);;
1592
1593 let rec find_in_ctx i name = function
1594   | [] -> raise (ProofEngineTypes.Fail (lazy ("Hypothesis not found: " ^ name)))
1595   | Some (Cic.Name name', _)::tl when name = name' -> i
1596   | _::tl -> find_in_ctx (i+1) name tl
1597 ;;
1598
1599 let rec position_of i x = function
1600   | [] -> assert false
1601   | j::tl when j <> x -> position_of (i+1) x tl
1602   | _ -> i
1603 ;;
1604
1605 (* Syntax: 
1606  *   auto superposition target = NAME 
1607  *     [table = NAME_LIST] [demod_table = NAME_LIST] [subterms_only]
1608  *
1609  *  - if table is omitted no superposition will be performed
1610  *  - if demod_table is omitted no demodulation will be prformed
1611  *  - subterms_only is passed to Indexing.superposition_right
1612  *
1613  *  lists are coded using _ (example: H_H1_H2)
1614  *)
1615
1616 let superposition_tac ~target ~table ~subterms_only ~demod_table status = 
1617   reset_refs();
1618   let proof,goalno = status in 
1619   let curi,metasenv,pbo,pty = proof in
1620   let metano,context,ty = CicUtil.lookup_meta goalno metasenv in
1621   let eq_uri,tty = eq_and_ty_of_goal ty in
1622   let env = (metasenv, context, CicUniv.empty_ugraph) in
1623   let names = Utils.names_of_context context in
1624   let bag = Equality.mk_equality_bag () in
1625   let eq_index, equalities, maxm,cache  = 
1626     Equality_retrieval.find_context_equalities 0 bag context proof AutoCache.cache_empty 
1627   in
1628   let eq_what = 
1629     let what = find_in_ctx 1 target context in
1630     List.nth equalities (position_of 0 what eq_index)
1631   in
1632   let eq_other = 
1633     if table <> "" then
1634       let other = 
1635         let others = Str.split (Str.regexp "_") table in 
1636         List.map (fun other -> find_in_ctx 1 other context) others 
1637       in
1638       List.map 
1639         (fun other -> List.nth equalities (position_of 0 other eq_index)) 
1640         other 
1641     else
1642       []
1643   in
1644   let index = List.fold_left Indexing.index Indexing.empty eq_other in
1645   let maxm, eql = 
1646     if table = "" then maxm,[eq_what] else 
1647     Indexing.superposition_right bag
1648       ~subterms_only eq_uri maxm env index eq_what
1649   in
1650   prerr_endline ("Superposition right:");
1651   prerr_endline ("\n eq: " ^ Equality.string_of_equality eq_what ~env);
1652   prerr_endline ("\n table: ");
1653   List.iter (fun e -> prerr_endline ("  " ^ Equality.string_of_equality e ~env)) eq_other;
1654   prerr_endline ("\n result: ");
1655   List.iter (fun e -> prerr_endline (Equality.string_of_equality e ~env)) eql;
1656   prerr_endline ("\n result (cut&paste): ");
1657   List.iter 
1658     (fun e -> 
1659       let t = Equality.term_of_equality eq_uri e in
1660       prerr_endline (CicPp.pp t names)) 
1661   eql;
1662   prerr_endline ("\n result proofs: ");
1663   List.iter (fun e -> 
1664     prerr_endline (let _,p,_,_,_ = Equality.open_equality e in
1665     let s = match p with Equality.Exact _ -> Subst.empty_subst | Equality.Step (s,_) -> s in
1666     Subst.ppsubst s ^ "\n" ^ 
1667     CicPp.pp (Equality.build_proof_term bag eq_uri [] 0 p) names)) eql;
1668   if demod_table <> "" then
1669     begin
1670       let eql = 
1671         if eql = [] then [eq_what] else eql
1672       in
1673       let demod = 
1674         let demod = Str.split (Str.regexp "_") demod_table in 
1675         List.map (fun other -> find_in_ctx 1 other context) demod 
1676       in
1677       let eq_demod = 
1678         List.map 
1679           (fun demod -> List.nth equalities (position_of 0 demod eq_index)) 
1680           demod 
1681       in
1682       let table = List.fold_left Indexing.index Indexing.empty eq_demod in
1683       let maxm,eql = 
1684         List.fold_left 
1685           (fun (maxm,acc) e -> 
1686             let maxm,eq = 
1687               Indexing.demodulation_equality bag eq_uri maxm env table e
1688             in
1689             maxm,eq::acc) 
1690           (maxm,[]) eql
1691       in
1692       let eql = List.rev eql in
1693       prerr_endline ("\n result [demod]: ");
1694       List.iter 
1695         (fun e -> prerr_endline (Equality.string_of_equality e ~env)) eql;
1696       prerr_endline ("\n result [demod] (cut&paste): ");
1697       List.iter 
1698         (fun e -> 
1699           let t = Equality.term_of_equality eq_uri e in
1700           prerr_endline (CicPp.pp t names)) 
1701       eql;
1702     end;
1703   proof,[goalno]
1704 ;;
1705
1706 let get_stats () = "" 
1707 (*
1708   <:show<Saturation.>> ^ Indexing.get_stats () ^ Inference.get_stats () ^
1709   Equality.get_stats ()
1710 ;;
1711 *)
1712
1713 (* THINGS USED ONLY BY saturate_main.ml *)
1714
1715 let main _ _ _ _ _ = () ;;
1716
1717 let retrieve_and_print dbd term metasenv ugraph = 
1718   let module C = Cic in
1719   let module T = CicTypeChecker in
1720   let module PET = ProofEngineTypes in
1721   let module PP = CicPp in
1722   let proof = None, (1, [], term)::metasenv, C.Meta (1, []), term in
1723   let status = PET.apply_tactic (PrimitiveTactics.intros_tac ()) (proof, 1) in
1724   let proof, goals = status in
1725   let goal' = List.nth goals 0 in
1726   let uri, metasenv, meta_proof, term_to_prove = proof in
1727   let _, context, type_of_goal = CicUtil.lookup_meta goal' metasenv in
1728   let eq_uri = eq_of_goal type_of_goal in
1729   let bag = Equality.mk_equality_bag () in
1730   let eq_indexes, equalities, maxm,cache = 
1731     Equality_retrieval.find_context_equalities 0 bag context proof AutoCache.cache_empty in
1732   let ugraph = CicUniv.empty_ugraph in
1733   let env = (metasenv, context, ugraph) in
1734   let t1 = Unix.gettimeofday () in
1735   let lib_eq_uris, library_equalities, maxm, cache =
1736     Equality_retrieval.find_library_equalities bag
1737       false dbd context (proof, goal') (maxm+2)  cache
1738   in 
1739   let t2 = Unix.gettimeofday () in
1740   maxmeta := maxm+2;
1741   let equalities = (* equalities @ *) library_equalities in
1742   Utils.debug_print
1743      (lazy
1744         (Printf.sprintf "\n\nequalities:\n%s\n"
1745            (String.concat "\n"
1746               (List.map 
1747           (fun (u, e) ->
1748 (*                  Printf.sprintf "%s: %s" *)
1749                    (UriManager.string_of_uri u)
1750 (*                    (string_of_equality e) *)
1751                      )
1752           equalities))));
1753   Utils.debug_print (lazy "RETR: SIMPLYFYING EQUALITIES...");
1754   let rec simpl e others others_simpl =
1755     let (u, e) = e in
1756     let active = (others @ others_simpl) in
1757     let tbl =
1758       List.fold_left
1759         (fun t (_, e) -> Indexing.index t e)
1760         Indexing.empty active
1761     in
1762     let res = forward_simplify bag eq_uri env e (active, tbl) in
1763     match others with
1764         | hd::tl -> (
1765             match res with
1766               | None -> simpl hd tl others_simpl
1767               | Some e -> simpl hd tl ((u, e)::others_simpl)
1768           )
1769         | [] -> (
1770             match res with
1771               | None -> others_simpl
1772               | Some e -> (u, e)::others_simpl
1773           ) 
1774   in
1775   let _equalities =
1776     match equalities with
1777       | [] -> []
1778       | hd::tl ->
1779           let others = tl in (* List.map (fun e -> (Utils.Positive, e)) tl in *)
1780           let res =
1781             List.rev (simpl (*(Positive,*) hd others [])
1782           in
1783             Utils.debug_print
1784               (lazy
1785                  (Printf.sprintf "\nequalities AFTER:\n%s\n"
1786                     (String.concat "\n"
1787                        (List.map
1788                           (fun (u, e) ->
1789                              Printf.sprintf "%s: %s"
1790                                (UriManager.string_of_uri u)
1791                                (Equality.string_of_equality e)
1792                           )
1793                           res))));
1794             res in
1795     Utils.debug_print
1796       (lazy
1797          (Printf.sprintf "Time to retrieve equalities: %.9f\n" (t2 -. t1)))
1798 ;;
1799
1800
1801 let main_demod_equalities dbd term metasenv ugraph =
1802   let module C = Cic in
1803   let module T = CicTypeChecker in
1804   let module PET = ProofEngineTypes in
1805   let module PP = CicPp in
1806   let proof = None, (1, [], term)::metasenv, C.Meta (1, []), term in
1807   let status = PET.apply_tactic (PrimitiveTactics.intros_tac ()) (proof, 1) in
1808   let proof, goals = status in
1809   let goal' = List.nth goals 0 in
1810   let _, metasenv, meta_proof, _ = proof in
1811   let _, context, goal = CicUtil.lookup_meta goal' metasenv in
1812   let eq_uri = eq_of_goal goal in 
1813   let bag = Equality.mk_equality_bag () in
1814   let eq_indexes, equalities, maxm,  cache = 
1815     Equality_retrieval.find_context_equalities 0 bag context proof AutoCache.cache_empty in
1816   let lib_eq_uris, library_equalities, maxm,cache =
1817     Equality_retrieval.find_library_equalities bag
1818       false dbd context (proof, goal') (maxm+2)  cache
1819   in
1820   let library_equalities = List.map snd library_equalities in
1821   maxmeta := maxm+2; (* TODO ugly!! *)
1822   let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
1823   let new_meta_goal, metasenv, type_of_goal =
1824     let _, context, ty = CicUtil.lookup_meta goal' metasenv in
1825     Utils.debug_print
1826       (lazy
1827          (Printf.sprintf "\n\nTRYING TO INFER EQUALITIES MATCHING: %s\n\n"
1828             (CicPp.ppterm ty)));
1829     Cic.Meta (maxm+1, irl),
1830     (maxm+1, context, ty)::metasenv,
1831     ty
1832   in
1833   let env = (metasenv, context, ugraph) in
1834   (*try*)
1835     let goal = [], [], goal 
1836     in
1837     let equalities = 
1838       simplify_equalities bag eq_uri env (equalities@library_equalities) 
1839     in
1840     let active = make_empty_active () in
1841     let passive = make_passive equalities in
1842     Printf.eprintf "\ncontext:\n%s\n" (PP.ppcontext context);
1843     Printf.eprintf "\nmetasenv:\n%s\n" (Utils.print_metasenv metasenv);
1844     Printf.eprintf "\nequalities:\n%s\n"
1845       (String.concat "\n"
1846          (List.map
1847             (Equality.string_of_equality ~env) equalities));
1848     prerr_endline "--------------------------------------------------";
1849     prerr_endline "GO!";
1850     start_time := Unix.gettimeofday ();
1851     if !time_limit < 1. then time_limit := 60.;    
1852     let ra, rp =
1853       saturate_equations bag eq_uri env goal (fun e -> true) passive active
1854     in
1855
1856     let initial =
1857       List.fold_left (fun s e -> EqualitySet.add e s)
1858         EqualitySet.empty equalities
1859     in
1860     let addfun s e = 
1861       if not (EqualitySet.mem e initial) then EqualitySet.add e s else s
1862     in
1863
1864     let passive =
1865       match rp with
1866       | p, _ ->
1867           EqualitySet.elements (List.fold_left addfun EqualitySet.empty p)
1868     in
1869     let active =
1870       let l = fst ra in
1871       EqualitySet.elements (List.fold_left addfun EqualitySet.empty l)
1872     in
1873     Printf.eprintf "\n\nRESULTS:\nActive:\n%s\n\nPassive:\n%s\n"
1874        (String.concat "\n" (List.map (Equality.string_of_equality ~env) active)) 
1875      (*  (String.concat "\n"
1876          (List.map (fun e -> CicPp.ppterm (term_of_equality e)) active)) *)
1877 (*       (String.concat "\n" (List.map (string_of_equality ~env) passive)); *)
1878       (String.concat "\n"
1879          (List.map 
1880            (fun e -> CicPp.ppterm (Equality.term_of_equality eq_uri e)) 
1881           passive));
1882     print_newline ();
1883 (*
1884   with e ->
1885     Utils.debug_print (lazy ("EXCEPTION: " ^ (Printexc.to_string e)))
1886 *)
1887 ;;
1888 let saturate_equations eq_uri env goal accept_fun passive active =
1889   let bag = Equality.mk_equality_bag () in
1890   saturate_equations bag eq_uri env goal accept_fun passive active
1891 ;;
1892
1893 let add_to_passive eql passives = 
1894   add_to_passive passives eql eql
1895 ;;