]> matita.cs.unibo.it Git - helm.git/blob - components/tactics/paramodulation/saturation.ml
Changed auto from implicit to option and renamed a few functions.
[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 (* 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 (* see applys.ma *)
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 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_identity env e then t else Indexing.index t e) 
747       Indexing.empty active
748   in
749   let res = 
750       forward_simplify bag eq_uri env e (active, tbl) 
751   in
752     match others with
753       | hd::tl -> (
754           match res with
755             | None -> simpl bag eq_uri env hd tl others_simpl
756             | Some e -> simpl bag eq_uri env hd tl (e::others_simpl)
757         )
758       | [] -> (
759           match res with
760             | None -> others_simpl
761             | Some e -> e::others_simpl
762         )
763 ;;
764
765 let simplify_equalities bag eq_uri env equalities =
766   Utils.debug_print
767     (lazy 
768        (Printf.sprintf "equalities:\n%s\n"
769           (String.concat "\n"
770              (List.map Equality.string_of_equality equalities))));
771   Utils.debug_print (lazy "SIMPLYFYING EQUALITIES...");
772   match equalities with
773     | [] -> []
774     | hd::tl ->
775         let res =
776           List.rev (simpl bag eq_uri env hd tl [])
777         in
778           Utils.debug_print
779             (lazy
780                (Printf.sprintf "equalities AFTER:\n%s\n"
781                   (String.concat "\n"
782                      (List.map Equality.string_of_equality res))));
783           res
784 ;;
785
786 let print_goals goals = 
787   (String.concat "\n"
788      (List.map
789         (fun (d, gl) ->
790            let gl' =
791              List.map
792                (fun (p, _, t) ->
793                   (* (string_of_proof p) ^ ", " ^ *) (CicPp.ppterm t)) gl
794            in
795            Printf.sprintf "%d: %s" d (String.concat "; " gl')) goals))
796 ;;
797               
798 let pp_goal_set msg goals names = 
799   let active_goals, passive_goals = goals in
800   prerr_endline ("////" ^ msg);
801   prerr_endline ("ACTIVE G: " ^
802     (String.concat "\n " (List.map (fun (_,_,g) -> CicPp.pp g names)
803     active_goals)));
804   prerr_endline ("PASSIVE G: " ^
805     (String.concat "\n " (List.map (fun (_,_,g) -> CicPp.pp g names)
806     passive_goals)))
807 ;;
808
809 let check_if_goal_is_subsumed bag ((_,ctx,_) as env) table (goalproof,menv,ty) =
810 (*   let names = Utils.names_of_context ctx in *)
811   match ty with
812   | Cic.Appl[Cic.MutInd(uri,_,_);eq_ty;left;right] 
813     when LibraryObjects.is_eq_URI uri ->
814       (let goal_equation = 
815          Equality.mk_equality bag
816            (0,Equality.Exact (Cic.Implicit None),(eq_ty,left,right,Utils.Eq),menv) 
817       in
818 (*      match Indexing.subsumption env table goal_equation with*)
819        match Indexing.unification env table goal_equation with 
820         | Some (subst, equality, swapped ) ->
821 (*
822             prerr_endline 
823              ("GOAL SUBSUMED IS: "^Equality.string_of_equality goal_equation ~env);
824             prerr_endline 
825              ("GOAL IS SUBSUMED BY: "^Equality.string_of_equality equality ~env);
826             prerr_endline ("SUBST:"^Subst.ppsubst ~names subst);
827 *)
828             let (_,p,(ty,l,r,_),m,id) = Equality.open_equality equality in
829             let cicmenv = Subst.apply_subst_metasenv subst (m @ menv) in
830             let p =
831               if swapped then
832                 Equality.symmetric bag eq_ty l id uri m
833               else
834                 p
835             in
836             Some (goalproof, p, id, subst, cicmenv)
837         | None -> None)
838   | _ -> None
839 ;;
840
841 let check_if_goal_is_identity env = function
842   | (goalproof,m,Cic.Appl[Cic.MutInd(uri,_,ens);eq_ty;left;right]) 
843     when left = right && LibraryObjects.is_eq_URI uri ->
844       let reflproof = Equality.Exact (Equality.refl_proof uri eq_ty left) in
845       Some (goalproof, reflproof, 0, Subst.empty_subst,m)
846   | (goalproof,m,Cic.Appl[Cic.MutInd(uri,_,ens);eq_ty;left;right]) 
847     when LibraryObjects.is_eq_URI uri ->
848     (let _,context,_ = env in
849     try 
850      let s,m,_ = 
851        Founif.unification m m context left right CicUniv.empty_ugraph 
852      in
853       let reflproof = Equality.Exact (Equality.refl_proof uri eq_ty left) in
854       let m = Subst.apply_subst_metasenv s m in
855       Some (goalproof, reflproof, 0, s,m)
856     with _ -> None)
857   | _ -> None
858 ;;                              
859     
860 let rec check goal = function
861   | [] -> None
862   | f::tl ->
863       match f goal with
864       | None -> check goal tl
865       | (Some p) as ok  -> ok
866 ;;
867   
868 let simplify_goal_set bag env goals active = 
869   let active_goals, passive_goals = goals in 
870   let find (_,_,g) where =
871     List.exists (fun (_,_,g1) -> Equality.meta_convertibility g g1) where
872   in
873     (* prova:tengo le passive semplificate 
874   let passive_goals = 
875     List.map (fun g -> snd (simplify_goal env g active)) passive_goals 
876   in *)
877     List.fold_left
878       (fun (acc_a,acc_p) goal -> 
879         match simplify_goal bag env goal active with 
880         | changed, g -> 
881             if changed then 
882               if find g acc_p then acc_a,acc_p else acc_a,g::acc_p
883             else
884               if find g acc_a then acc_a,acc_p else g::acc_a,acc_p)
885       ([],passive_goals) active_goals
886 ;;
887
888 let check_if_goals_set_is_solved bag env active goals =
889   let active_goals, passive_goals = goals in
890   List.fold_left 
891     (fun proof goal ->
892       match proof with
893       | Some p -> proof
894       | None -> 
895           check goal [
896             check_if_goal_is_identity env;
897             check_if_goal_is_subsumed bag env (snd active)])
898 (* provare active and passive?*)
899     None active_goals
900 ;;
901
902 let infer_goal_set bag env active goals = 
903   let active_goals, passive_goals = goals in
904   let rec aux = function
905     | [] -> active_goals, []
906     | hd::tl ->
907         let changed,selected = simplify_goal bag env hd active in
908 (*
909         if changed then
910           prerr_endline ("--------------- goal semplificato");
911 *)
912         let (_,_,t1) = selected in
913         let already_in = 
914           List.exists (fun (_,_,t) -> Equality.meta_convertibility t t1) 
915               active_goals
916         in
917         if already_in then 
918              aux tl
919           else
920             let passive_goals = tl in
921             let new_passive_goals =
922               if Utils.metas_of_term t1 = [] then passive_goals
923               else 
924                 let newmaxmeta,new' = 
925                    Indexing.superposition_left bag env (snd active) selected
926                    !maxmeta 
927                 in
928                 maxmeta := newmaxmeta;
929                 passive_goals @ new'
930             in
931             selected::active_goals, new_passive_goals
932   in 
933   aux passive_goals
934 ;;
935
936 let infer_goal_set_with_current bag env current goals active = 
937   let active_goals, passive_goals = simplify_goal_set bag env goals active in
938   let l,table,_  = build_table [current] in
939   active_goals, 
940   List.fold_left 
941     (fun acc g ->
942       let newmaxmeta, new' = Indexing.superposition_left bag env table g !maxmeta in
943       maxmeta := newmaxmeta;
944       acc @ new')
945     passive_goals active_goals
946 ;;
947
948 let ids_of_goal g = 
949   let p,_,_ = g in
950   let ids = List.map (fun _,_,i,_,_ -> i) p in
951   ids
952 ;;
953
954 let ids_of_goal_set (ga,gp) =
955   List.flatten (List.map ids_of_goal ga) @
956   List.flatten (List.map ids_of_goal gp)
957 ;;
958
959 let size_of_goal_set_a (l,_) = List.length l;;
960 let size_of_goal_set_p (_,l) = List.length l;;
961       
962 let pp_goals label goals context = 
963   let names = Utils.names_of_context context in
964   List.iter                 
965     (fun _,_,g -> 
966       prerr_endline 
967         (Printf.sprintf  "Current goal: %s = %s\n" label (CicPp.pp g names))) 
968     (fst goals);
969   List.iter                 
970     (fun _,_,g -> 
971       prerr_endline 
972         (Printf.sprintf  "PASSIVE goal: %s = %s\n" label (CicPp.pp g names))) 
973       (snd goals);
974 ;;
975
976 let print_status iterno goals active passive =
977   prerr_endline 
978     (Printf.sprintf "\n%d #ACTIVES: %d #PASSIVES: %d #GOALSET: %d(%d)"
979       iterno (size_of_active active) (size_of_passive passive)
980       (size_of_goal_set_a goals) (size_of_goal_set_p goals)) 
981 ;;
982
983 (** given-clause algorithm with full reduction strategy: NEW implementation *)
984 (* here goals is a set of goals in OR *)
985 let given_clause 
986   bag eq_uri ((_,context,_) as env) goals passive active 
987   goal_steps saturation_steps max_time
988
989   let initial_time = Unix.gettimeofday () in
990   let iterations_left iterno = 
991     let now = Unix.gettimeofday () in
992     let time_left = max_time -. now in
993     let time_spent_until_now = now -. initial_time in
994     let iteration_medium_cost = 
995       time_spent_until_now /. (float_of_int iterno)
996     in
997     let iterations_left = time_left /. iteration_medium_cost in
998     int_of_float iterations_left 
999   in
1000   let rec step goals passive active g_iterno s_iterno =
1001     if g_iterno > goal_steps && s_iterno > saturation_steps then
1002       (ParamodulationFailure ("No more iterations to spend",active,passive))
1003     else if Unix.gettimeofday () > max_time then
1004       (ParamodulationFailure ("No more time to spend",active,passive))
1005     else
1006       let _ = 
1007          print_status (max g_iterno s_iterno) goals active passive  
1008 (*         Printf.eprintf ".%!"; *)
1009       in
1010       (* PRUNING OF PASSIVE THAT WILL NEVER BE PROCESSED *) 
1011       let passive =
1012         let selection_estimate = iterations_left (max g_iterno s_iterno) in
1013         let kept = size_of_passive passive in
1014         if kept > selection_estimate then 
1015           begin
1016             (*Printf.eprintf "Too many passive equalities: pruning...";
1017             prune_passive selection_estimate active*) passive
1018           end
1019         else
1020           passive
1021       in
1022       kept_clauses := (size_of_passive passive) + (size_of_active active);
1023       let goals = 
1024         if g_iterno < goal_steps then
1025           infer_goal_set bag env active goals 
1026         else
1027           goals
1028       in
1029       match check_if_goals_set_is_solved bag env active goals with
1030       | Some p -> 
1031           prerr_endline 
1032             (Printf.sprintf "\nFound a proof in: %f\n" 
1033               (Unix.gettimeofday() -. initial_time));
1034           ParamodulationSuccess (p,active,passive)
1035       | None -> 
1036           (* SELECTION *)
1037           if passive_is_empty passive then
1038             if no_more_passive_goals goals then 
1039               ParamodulationFailure 
1040                 ("No more passive equations/goals",active,passive)
1041               (*maybe this is a success! *)
1042             else
1043               step goals passive active (g_iterno+1) (s_iterno+1)
1044           else
1045             begin
1046               (* COLLECTION OF GARBAGED EQUALITIES *)
1047               if max g_iterno s_iterno mod 40 = 0 then
1048                 begin
1049                   print_status (max g_iterno s_iterno) goals active passive;
1050                   let active = List.map Equality.id_of (fst active) in
1051                   let passive = List.map Equality.id_of (fst passive) in
1052                   let goal = ids_of_goal_set goals in
1053                   Equality.collect bag active passive goal
1054                 end;
1055               let res, passive = 
1056                 if s_iterno < saturation_steps then
1057                   let current, passive = select env goals passive in
1058                   (* SIMPLIFICATION OF CURRENT *)
1059                   prerr_endline
1060                         ("Selected : " ^ 
1061                           Equality.string_of_equality ~env  current);
1062                   forward_simplify bag eq_uri env current active, passive
1063                 else
1064                   None, passive
1065               in
1066               match res with
1067               | None -> step goals passive active (g_iterno+1) (s_iterno+1)
1068               | Some current ->
1069                   (* GENERATION OF NEW EQUATIONS *)
1070 (*                   prerr_endline "infer"; *)
1071                   let new' = infer bag eq_uri env current active in
1072 (*                   prerr_endline "infer goal"; *)
1073 (*
1074       match check_if_goals_set_is_solved env active goals with
1075       | Some p -> 
1076           prerr_endline 
1077             (Printf.sprintf "Found a proof in: %f\n" 
1078               (Unix.gettimeofday() -. initial_time));
1079           ParamodulationSuccess p
1080       | None -> 
1081 *)
1082
1083                   let active = 
1084                       let al, tbl = active in
1085                       al @ [current], Indexing.index tbl current
1086                   in
1087                   let goals = 
1088                     infer_goal_set_with_current bag env current goals active 
1089                   in
1090
1091                   (* FORWARD AND BACKWARD SIMPLIFICATION *)
1092 (*                   prerr_endline "fwd/back simpl"; *)
1093                   let rec simplify new' active passive =
1094                     let new' = 
1095                       forward_simplify_new bag eq_uri env new' active 
1096                     in
1097                     let active, newa, pruned =
1098                       backward_simplify bag eq_uri env new' active 
1099                     in
1100                     let passive = 
1101                       List.fold_left (filter_dependent bag) passive pruned 
1102                     in
1103                     match newa with
1104                     | None -> active, passive, new'
1105                     | Some p -> simplify (new' @ p) active passive 
1106                   in
1107                   let active, passive, new' = 
1108                     simplify new' active passive
1109                   in
1110
1111 (*                   prerr_endline "simpl goal with new"; *)
1112                   let goals = 
1113                     let a,b,_ = build_table new' in
1114 (*                     let _ = <:start<simplify_goal_set new>> in *)
1115                     let rc = simplify_goal_set bag env goals (a,b) in
1116 (*                     let _ = <:stop<simplify_goal_set new>> in *)
1117                     rc
1118                   in
1119                   let passive = add_to_passive passive new' [] in
1120                   step goals passive active (g_iterno+1) (s_iterno+1)
1121             end
1122   in
1123     step goals passive active 1 1
1124 ;;
1125
1126 let rec saturate_equations bag eq_uri env goal accept_fun passive active =
1127   elapsed_time := Unix.gettimeofday () -. !start_time;
1128   if !elapsed_time > !time_limit then
1129     (active, passive)
1130   else
1131     let current, passive = select env ([goal],[]) passive in
1132     let res = forward_simplify bag eq_uri env current active in
1133     match res with
1134     | None ->
1135         saturate_equations bag eq_uri env goal accept_fun passive active
1136     | Some current ->
1137         Utils.debug_print (lazy (Printf.sprintf "selected: %s"
1138                              (Equality.string_of_equality ~env current)));
1139         let new' = infer bag eq_uri env current active in
1140         let active =
1141           if Equality.is_identity env current then active
1142           else
1143             let al, tbl = active in
1144             al @ [current], Indexing.index tbl current
1145         in
1146         (* alla fine new' contiene anche le attive semplificate!
1147          * quindi le aggiungo alle passive insieme alle new *)
1148         let rec simplify new' active passive =
1149           let new' = forward_simplify_new bag eq_uri env new' active in
1150           let active, newa, pruned =
1151             backward_simplify bag eq_uri env new' active in
1152           let passive = 
1153             List.fold_left (filter_dependent bag) passive pruned in
1154           match newa with
1155           | None -> active, passive, new'
1156           | Some p -> simplify (new' @ p) active passive
1157         in
1158         let active, passive, new' = simplify new' active passive in
1159         let _ =
1160           Utils.debug_print
1161             (lazy
1162                (Printf.sprintf "active:\n%s\n"
1163                   (String.concat "\n"
1164                      (List.map
1165                          (fun e -> Equality.string_of_equality ~env e)
1166                          (fst active)))))
1167         in
1168         let _ =
1169           Utils.debug_print
1170             (lazy
1171                (Printf.sprintf "new':\n%s\n"
1172                   (String.concat "\n"
1173                      (List.map
1174                          (fun e -> "Negative " ^
1175                             (Equality.string_of_equality ~env e)) new'))))
1176         in
1177         let new' = List.filter accept_fun new' in
1178         let passive = add_to_passive passive new' [] in
1179         saturate_equations bag eq_uri env goal accept_fun passive active
1180 ;;
1181   
1182 let default_depth = !maxdepth
1183 and default_width = !maxwidth;;
1184
1185 let reset_refs () =
1186   maxmeta := 0;
1187   symbols_counter := 0;
1188   weight_age_counter := !weight_age_ratio;
1189   processed_clauses := 0;
1190   start_time := 0.;
1191   elapsed_time := 0.;
1192   maximal_retained_equality := None;
1193   infer_time := 0.;
1194   forward_simpl_time := 0.;
1195   forward_simpl_new_time := 0.;
1196   backward_simpl_time := 0.;
1197   passive_maintainance_time := 0.;
1198   derived_clauses := 0;
1199   kept_clauses := 0;
1200 ;;
1201
1202 let eq_of_goal = function
1203   | Cic.Appl [Cic.MutInd(uri,0,_);_;_;_] when LibraryObjects.is_eq_URI uri ->
1204       uri
1205   | _ -> raise (ProofEngineTypes.Fail (lazy ("The goal is not an equality ")))
1206 ;;
1207
1208 let eq_and_ty_of_goal = function
1209   | Cic.Appl [Cic.MutInd(uri,0,_);t;_;_] when LibraryObjects.is_eq_URI uri ->
1210       uri,t
1211   | _ -> raise (ProofEngineTypes.Fail (lazy ("The goal is not an equality ")))
1212 ;;
1213
1214 (* status: input proof status
1215  * goalproof: forward steps on goal
1216  * newproof: backward steps
1217  * subsumption_id: the equation used if goal is closed by subsumption
1218  *   (0 if not closed by subsumption) (DEBUGGING: can be safely removed)
1219  * subsumption_subst: subst to make newproof and goalproof match
1220  * proof_menv: final metasenv
1221  *)
1222 let build_proof 
1223   bag status  
1224   goalproof newproof subsumption_id subsumption_subst proof_menv
1225 =
1226   let proof, goalno = status in
1227   let uri, metasenv, meta_proof, term_to_prove = proof in
1228   let _, context, type_of_goal = CicUtil.lookup_meta goalno metasenv in
1229   let eq_uri = eq_of_goal type_of_goal in 
1230       let names = Utils.names_of_context context in
1231       prerr_endline "Proof:";
1232       prerr_endline 
1233         (Equality.pp_proof bag names goalproof newproof subsumption_subst
1234           subsumption_id type_of_goal);
1235 (*       prerr_endline "ENDOFPROOFS"; *)
1236 (*
1237       prerr_endline ("max weight: " ^ 
1238         (string_of_int (Equality.max_weight goalproof newproof)));
1239 *)
1240       (* generation of the CIC proof *)
1241       let side_effects = 
1242         List.filter (fun i -> i <> goalno)
1243           (ProofEngineHelpers.compare_metasenvs 
1244             ~newmetasenv:metasenv ~oldmetasenv:proof_menv)
1245       in
1246       let goal_proof, side_effects_t = 
1247         let initial = Equality.add_subst subsumption_subst newproof in
1248         Equality.build_goal_proof bag
1249           eq_uri goalproof initial type_of_goal side_effects
1250           context proof_menv
1251       in
1252       (* prerr_endline ("PROOF: " ^ CicPp.pp goal_proof names); *)
1253       let goal_proof = Subst.apply_subst subsumption_subst goal_proof in
1254       let metas_still_open_in_proof = Utils.metas_of_term goal_proof in
1255       (* prerr_endline (CicPp.pp goal_proof names); *)
1256       let goal_proof = (* Subst.apply_subst subsumption_subst *) goal_proof in
1257       let side_effects_t = 
1258         List.map (Subst.apply_subst subsumption_subst) side_effects_t
1259       in
1260       (* replacing fake mets with real ones *)
1261       (* prerr_endline "replacing metas..."; *)
1262       let irl=CicMkImplicit.identity_relocation_list_for_metavariable context in
1263       let goal_proof_menv, what, with_what,free_meta = 
1264         List.fold_left 
1265           (fun (acc1,acc2,acc3,uniq) (i,_,ty) -> 
1266              match uniq with
1267                | Some m -> 
1268 (*                     acc1, (Cic.Meta(i,[]))::acc2, m::acc3, uniq  *)
1269                    (i,context,ty)::acc1, (Cic.Meta(i,[]))::acc2,
1270                      (Cic.Meta(i,irl))::acc3, uniq
1271                | None ->
1272                    [i,context,ty], (Cic.Meta(i,[]))::acc2, 
1273                    (Cic.Meta(i,irl)) ::acc3,Some (Cic.Meta(i,irl))) 
1274           ([],[],[],None) 
1275           (List.filter 
1276            (fun (i,_,_) -> 
1277              List.mem i metas_still_open_in_proof
1278              (*&& not(List.mem i metas_still_open_in_goal)*)) 
1279            proof_menv)
1280       in
1281       let replace where = 
1282         (* we need this fake equality since the metas of the hypothesis may be
1283          * with a real local context *)
1284         ProofEngineReduction.replace_lifting 
1285           ~equality:(fun x y -> 
1286             match x,y with Cic.Meta(i,_),Cic.Meta(j,_) -> i=j | _-> false)
1287           ~what ~with_what ~where
1288       in
1289       let goal_proof = replace goal_proof in
1290         (* ok per le meta libere... ma per quelle che c'erano e sono rimaste? 
1291          * what mi pare buono, sostituisce solo le meta farlocche *)
1292       let side_effects_t = List.map replace side_effects_t in
1293       let free_metas = 
1294         List.filter (fun i -> i <> goalno)
1295           (ProofEngineHelpers.compare_metasenvs 
1296             ~oldmetasenv:metasenv ~newmetasenv:goal_proof_menv)
1297       in
1298       (* prerr_endline 
1299        *   ("freemetas: " ^ 
1300        *   String.concat "," (List.map string_of_int free_metas) ); *)
1301       (* check/refine/... build the new proof *)
1302       let replaced_goal = 
1303         ProofEngineReduction.replace
1304           ~what:side_effects ~with_what:side_effects_t
1305           ~equality:(fun i t -> match t with Cic.Meta(j,_)->j=i|_->false)
1306           ~where:type_of_goal
1307       in
1308       let subst_side_effects,real_menv,_ = 
1309         let fail t s = raise (ProofEngineTypes.Fail (lazy (t^Lazy.force s))) in
1310         let free_metas_menv = 
1311           List.map (fun i -> CicUtil.lookup_meta i goal_proof_menv) free_metas
1312         in
1313 (*
1314         prerr_endline ("XX type_of_goal  " ^ CicPp.ppterm type_of_goal);
1315         prerr_endline ("XX replaced_goal " ^ CicPp.ppterm replaced_goal);
1316         prerr_endline ("XX metasenv      " ^ 
1317         CicMetaSubst.ppmetasenv [] (metasenv @ free_metas_menv));
1318 *)
1319         try
1320           CicUnification.fo_unif_subst [] context (metasenv @ free_metas_menv)
1321            replaced_goal type_of_goal CicUniv.empty_ugraph
1322         with
1323         | CicUnification.UnificationFailure s
1324         | CicUnification.Uncertain s 
1325         | CicUnification.AssertFailure s -> 
1326             fail "Maybe the local context of metas in the goal was not an IRL" s
1327       in
1328       let final_subst = 
1329         (goalno,(context,goal_proof,type_of_goal))::subst_side_effects
1330       in
1331 (* prerr_endline ("MENVreal_menv: " ^ CicMetaSubst.ppmetasenv [] real_menv); *)
1332       let _ = 
1333         try
1334           CicTypeChecker.type_of_aux' real_menv context goal_proof
1335             CicUniv.empty_ugraph
1336         with 
1337         | CicUtil.Meta_not_found _ 
1338         | CicTypeChecker.TypeCheckerFailure _ 
1339         | CicTypeChecker.AssertFailure _ 
1340         | Invalid_argument "list_fold_left2" as exn ->
1341             prerr_endline "THE PROOF DOES NOT TYPECHECK!";
1342             prerr_endline (CicPp.pp goal_proof names); 
1343             prerr_endline "THE PROOF DOES NOT TYPECHECK!";
1344             raise exn
1345       in
1346
1347       let metas_of_proof = Utils.metas_of_term goal_proof in
1348
1349       let proof, real_metasenv = 
1350         ProofEngineHelpers.subst_meta_and_metasenv_in_proof
1351           proof goalno (CicMetaSubst.apply_subst final_subst) real_menv
1352       in
1353       let open_goals = 
1354         HExtlib.list_uniq (List.sort Pervasives.compare metas_of_proof) 
1355       in
1356 (*
1357         match free_meta with Some(Cic.Meta(m,_)) when m<>goalno ->[m] | _ ->[] 
1358       in
1359 *)
1360 (*
1361       Printf.eprintf 
1362         "GOALS APERTI: %s\nMETASENV PRIMA:\n%s\nMETASENV DOPO:\n%s\n" 
1363           (String.concat ", " (List.map string_of_int open_goals))
1364           (CicMetaSubst.ppmetasenv [] metasenv)
1365           (CicMetaSubst.ppmetasenv [] real_metasenv);
1366 *)
1367       final_subst, proof, open_goals
1368 ;;
1369
1370 let find_equalities dbd status smart_flag auto cache =
1371   let proof, goalno = status in
1372   let _, metasenv,_,_ = proof in
1373   let _, context, type_of_goal = CicUtil.lookup_meta goalno metasenv in
1374   let eq_uri = eq_of_goal type_of_goal in 
1375   let env = (metasenv, context, CicUniv.empty_ugraph) in 
1376   let bag = Equality.mk_equality_bag () in
1377   let eq_indexes, equalities, maxm, cache = 
1378     Equality_retrieval.find_context_equalities 0 bag auto context proof cache
1379   in
1380   prerr_endline ">>>>>>>>>> gained from the context >>>>>>>>>>>>";
1381   List.iter (fun e -> prerr_endline (Equality.string_of_equality e)) equalities;
1382   prerr_endline ">>>>>>>>>>>>>>>>>>>>>>";
1383   let lib_eq_uris, library_equalities, maxm, cache =
1384     Equality_retrieval.find_library_equalities bag
1385       auto smart_flag dbd context (proof, goalno) (maxm+2)
1386       cache
1387   in
1388   prerr_endline (">>>>>>>>>>  gained from the library >>>>>>>>>>>>" ^
1389     string_of_int maxm);
1390   List.iter
1391     (fun (_,e) -> prerr_endline (Equality.string_of_equality e)) 
1392     library_equalities;
1393   prerr_endline ">>>>>>>>>>>>>>>>>>>>>>";
1394   let equalities = List.map snd library_equalities @ equalities in
1395   let equalities = 
1396     simplify_equalities bag eq_uri env equalities
1397   in 
1398   prerr_endline ">>>>>>>>>> after simplify >>>>>>>>>>>>";
1399   List.iter
1400     (fun e -> prerr_endline (Equality.string_of_equality e)) equalities;
1401   prerr_endline (">>>>>>>>>>>>>>>>>>>>>>" ^ string_of_int maxm);
1402   bag, equalities, cache, maxm
1403 ;;
1404
1405 let close_more bag active maxmeta status smart_flag auto cache =
1406   let proof, goalno = status in
1407   let _, metasenv,_,_ = proof in
1408   let _, context, type_of_goal = CicUtil.lookup_meta goalno metasenv in
1409   let eq_uri = eq_of_goal type_of_goal in 
1410   let env = (metasenv, context, CicUniv.empty_ugraph) in 
1411   let eq_indexes, equalities, maxm, cache = 
1412     Equality_retrieval.find_context_equalities maxmeta bag auto context proof cache
1413   in
1414   prerr_endline (">>>>>>> gained from a new context saturation >>>>>>>>>" ^
1415     string_of_int maxm);
1416   List.iter
1417     (fun e -> prerr_endline (Equality.string_of_equality ~env e)) 
1418     equalities;
1419   prerr_endline ">>>>>>>>>>>>>>>>>>>>>>";
1420   let equalities = 
1421     HExtlib.filter_map 
1422       (fun e -> forward_simplify bag eq_uri env e active)
1423     equalities
1424   in
1425   prerr_endline ">>>>>>>>>> after simplify >>>>>>>>>>>>";
1426   List.iter
1427     (fun e -> prerr_endline (Equality.string_of_equality ~env e)) equalities;
1428   prerr_endline (">>>>>>>>>>>>>>>>>>>>>>" ^ string_of_int maxm);
1429   bag, equalities, cache, maxm
1430
1431 let saturate 
1432     smart_flag 
1433     dbd ?(full=false) ?(depth=default_depth) ?(width=default_width) 
1434     ?(timeout=600.) auto status = 
1435   let module C = Cic in
1436   reset_refs ();
1437   maxdepth := depth;
1438   maxwidth := width;
1439 (*  CicUnification.unif_ty := false;*)
1440   let proof, goalno = status in
1441   let uri, metasenv, meta_proof, term_to_prove = proof in
1442   let _, context, type_of_goal = CicUtil.lookup_meta goalno metasenv in
1443   let eq_uri = eq_of_goal type_of_goal in 
1444   let cleaned_goal = Utils.remove_local_context type_of_goal in
1445   Utils.set_goal_symbols cleaned_goal; (* DISACTIVATED *)
1446   let ugraph = CicUniv.empty_ugraph in
1447   let env = (metasenv, context, ugraph) in 
1448   let goal = [], List.filter (fun (i,_,_)->i<>goalno) metasenv, cleaned_goal in
1449   let bag, equalities, cache, maxm = 
1450     find_equalities dbd status smart_flag auto AutoCache.cache_empty 
1451   in
1452   let res, time =
1453     maxmeta := maxm+2;
1454     let t1 = Unix.gettimeofday () in
1455     let theorems =
1456       let refl_equal = LibraryObjects.eq_refl_URI ~eq:eq_uri in
1457       let t = CicUtil.term_of_uri refl_equal in
1458       let ty, _ = CicTypeChecker.type_of_aux' [] [] t CicUniv.empty_ugraph in
1459       [(t, ty, [])], []
1460     in
1461     let t2 = Unix.gettimeofday () in
1462     let _ =
1463       Utils.debug_print
1464         (lazy
1465            (Printf.sprintf
1466               "Theorems:\n-------------------------------------\n%s\n"
1467               (String.concat "\n"
1468                  (List.map
1469                     (fun (t, ty, _) ->
1470                        Printf.sprintf
1471                          "Term: %s, type: %s"
1472                          (CicPp.ppterm t) (CicPp.ppterm ty))
1473                     (fst theorems)))));
1474       Utils.debug_print
1475         (lazy
1476            (Printf.sprintf "Time to retrieve theorems: %.9f\n" (t2 -. t1)));
1477     in
1478     let active = make_empty_active () in
1479     let passive = make_passive equalities in
1480     let start = Unix.gettimeofday () in
1481     let res =
1482 (*
1483       let goals = make_goals goal in
1484       given_clause_fullred dbd env goals theorems passive active
1485 *)
1486       let goals = make_goal_set goal in
1487       let max_iterations = 10000 in
1488       let max_time = Unix.gettimeofday () +.  timeout (* minutes *) in
1489       given_clause bag
1490         eq_uri env goals passive active max_iterations max_iterations max_time 
1491     in
1492     let finish = Unix.gettimeofday () in
1493     (res, finish -. start)
1494   in
1495   match res with
1496   | ParamodulationFailure (s,_,_) ->
1497       raise (ProofEngineTypes.Fail (lazy ("NO proof found: " ^ s)))
1498   | ParamodulationSuccess 
1499     ((goalproof,newproof,subsumption_id,subsumption_subst, proof_menv),_,_) ->
1500       prerr_endline (Printf.sprintf "\nTIME NEEDED: %8.2f" time);
1501     let _,p,gl = 
1502       build_proof bag
1503         status goalproof newproof subsumption_id subsumption_subst proof_menv
1504     in
1505     p,gl
1506 ;;
1507 (* **************** HERE ENDS THE PARAMODULATION STUFF ******************** *)
1508
1509 (* exported version of given_clause *)
1510 let given_clause 
1511   bag maxm status active passive goal_steps saturation_steps max_time 
1512 =
1513   reset_refs();
1514   maxmeta := maxm;
1515   let max_l l = 
1516     List.fold_left 
1517      (fun acc e -> let _,_,_,menv,_ = Equality.open_equality e in
1518       List.fold_left (fun acc (i,_,_) -> max i acc) acc menv)
1519      0 l
1520   in
1521   let active_l = fst active in
1522   let passive_l = fst passive in
1523   let ma = max_l active_l in
1524   let mp = max_l passive_l in
1525   assert (maxm > max ma mp);
1526   let proof, goalno = status in
1527   let uri, metasenv, meta_proof, term_to_prove = proof in
1528   let _, context, type_of_goal = CicUtil.lookup_meta goalno metasenv in
1529   let eq_uri = eq_of_goal type_of_goal in 
1530   let cleaned_goal = Utils.remove_local_context type_of_goal in
1531   Utils.set_goal_symbols cleaned_goal; (* DISACTIVATED *)
1532   let goal = [], List.filter (fun (i,_,_)->i<>goalno) metasenv, cleaned_goal in
1533   let env = metasenv,context,CicUniv.empty_ugraph in
1534   prerr_endline ">>>>>> ACTIVES >>>>>>>>"; 
1535   List.iter (fun e -> prerr_endline (Equality.string_of_equality ~env e))
1536   active_l;
1537   prerr_endline ">>>>>>>>>>>>>>"; 
1538   let goals = make_goal_set goal in
1539   match 
1540     given_clause bag eq_uri env goals passive active 
1541       goal_steps saturation_steps max_time
1542   with
1543   | ParamodulationFailure (_,a,p) ->
1544       None, a, p, !maxmeta
1545   | ParamodulationSuccess 
1546     ((goalproof,newproof,subsumption_id,subsumption_subst, proof_menv),a,p) ->
1547     let subst, proof, gl =
1548       build_proof bag
1549         status goalproof newproof subsumption_id subsumption_subst proof_menv
1550     in
1551     Some (subst, proof,gl),a,p, !maxmeta
1552 ;;
1553
1554 let demodulate_tac ~dbd ((proof,goal)(*s initialstatus*)) = 
1555   let curi,metasenv,pbo,pty = proof in
1556   let metano,context,ty = CicUtil.lookup_meta goal metasenv in
1557   let eq_uri = eq_of_goal ty in
1558   let bag = Equality.mk_equality_bag () in
1559   let eq_indexes, equalities, maxm, cache = 
1560     Equality_retrieval.find_context_equalities 0 bag None context proof AutoCache.cache_empty
1561   in
1562   let lib_eq_uris, library_equalities, maxm, cache =
1563     Equality_retrieval.find_library_equalities bag None
1564       false dbd context (proof, goal) (maxm+2)  cache 
1565   in
1566   if library_equalities = [] then prerr_endline "VUOTA!!!";
1567   let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
1568   let library_equalities = List.map snd library_equalities in
1569   let initgoal = [], [], ty in
1570   let env = (metasenv, context, CicUniv.empty_ugraph) in
1571   let equalities = 
1572     simplify_equalities bag eq_uri env (equalities@library_equalities) 
1573   in   
1574   let table = 
1575     List.fold_left 
1576       (fun tbl eq -> Indexing.index tbl eq) 
1577       Indexing.empty equalities 
1578   in
1579   let changed,(newproof,newmetasenv, newty) = 
1580     Indexing.demodulation_goal bag
1581       (metasenv,context,CicUniv.empty_ugraph) table initgoal 
1582   in
1583   if changed then
1584     begin
1585       let opengoal = Equality.Exact (Cic.Meta(maxm,irl)) in
1586       let proofterm,_ = 
1587         Equality.build_goal_proof bag
1588           eq_uri newproof opengoal ty [] context metasenv
1589       in
1590         let extended_metasenv = (maxm,context,newty)::metasenv in
1591         let extended_status = 
1592           (curi,extended_metasenv,pbo,pty),goal in
1593         let (status,newgoals) = 
1594           ProofEngineTypes.apply_tactic 
1595             (PrimitiveTactics.apply_tac ~term:proofterm)
1596             extended_status in
1597         (status,maxm::newgoals)
1598     end
1599   else (* if newty = ty then *)
1600     raise (ProofEngineTypes.Fail (lazy "no progress"))
1601   (*else ProofEngineTypes.apply_tactic 
1602     (ReductionTactics.simpl_tac
1603       ~pattern:(ProofEngineTypes.conclusion_pattern None)) initialstatus*)
1604 ;;
1605
1606 let demodulate_tac ~dbd = ProofEngineTypes.mk_tactic (demodulate_tac ~dbd);;
1607
1608 let rec find_in_ctx i name = function
1609   | [] -> raise (ProofEngineTypes.Fail (lazy ("Hypothesis not found: " ^ name)))
1610   | Some (Cic.Name name', _)::tl when name = name' -> i
1611   | _::tl -> find_in_ctx (i+1) name tl
1612 ;;
1613
1614 let rec position_of i x = function
1615   | [] -> assert false
1616   | j::tl when j <> x -> position_of (i+1) x tl
1617   | _ -> i
1618 ;;
1619
1620 (* Syntax: 
1621  *   auto superposition target = NAME 
1622  *     [table = NAME_LIST] [demod_table = NAME_LIST] [subterms_only]
1623  *
1624  *  - if table is omitted no superposition will be performed
1625  *  - if demod_table is omitted no demodulation will be prformed
1626  *  - subterms_only is passed to Indexing.superposition_right
1627  *
1628  *  lists are coded using _ (example: H_H1_H2)
1629  *)
1630
1631 let superposition_tac ~target ~table ~subterms_only ~demod_table status = 
1632   reset_refs();
1633   let proof,goalno = status in 
1634   let curi,metasenv,pbo,pty = proof in
1635   let metano,context,ty = CicUtil.lookup_meta goalno metasenv in
1636   let eq_uri,tty = eq_and_ty_of_goal ty in
1637   let env = (metasenv, context, CicUniv.empty_ugraph) in
1638   let names = Utils.names_of_context context in
1639   let bag = Equality.mk_equality_bag () in
1640   let eq_index, equalities, maxm,cache  = 
1641     Equality_retrieval.find_context_equalities 0 bag None context proof AutoCache.cache_empty 
1642   in
1643   let eq_what = 
1644     let what = find_in_ctx 1 target context in
1645     List.nth equalities (position_of 0 what eq_index)
1646   in
1647   let eq_other = 
1648     if table <> "" then
1649       let other = 
1650         let others = Str.split (Str.regexp "_") table in 
1651         List.map (fun other -> find_in_ctx 1 other context) others 
1652       in
1653       List.map 
1654         (fun other -> List.nth equalities (position_of 0 other eq_index)) 
1655         other 
1656     else
1657       []
1658   in
1659   let index = List.fold_left Indexing.index Indexing.empty eq_other in
1660   let maxm, eql = 
1661     if table = "" then maxm,[eq_what] else 
1662     Indexing.superposition_right bag
1663       ~subterms_only eq_uri maxm env index eq_what
1664   in
1665   prerr_endline ("Superposition right:");
1666   prerr_endline ("\n eq: " ^ Equality.string_of_equality eq_what ~env);
1667   prerr_endline ("\n table: ");
1668   List.iter (fun e -> prerr_endline ("  " ^ Equality.string_of_equality e ~env)) eq_other;
1669   prerr_endline ("\n result: ");
1670   List.iter (fun e -> prerr_endline (Equality.string_of_equality e ~env)) eql;
1671   prerr_endline ("\n result (cut&paste): ");
1672   List.iter 
1673     (fun e -> 
1674       let t = Equality.term_of_equality eq_uri e in
1675       prerr_endline (CicPp.pp t names)) 
1676   eql;
1677   prerr_endline ("\n result proofs: ");
1678   List.iter (fun e -> 
1679     prerr_endline (let _,p,_,_,_ = Equality.open_equality e in
1680     let s = match p with Equality.Exact _ -> Subst.empty_subst | Equality.Step (s,_) -> s in
1681     Subst.ppsubst s ^ "\n" ^ 
1682     CicPp.pp (Equality.build_proof_term bag eq_uri [] 0 p) names)) eql;
1683   if demod_table <> "" then
1684     begin
1685       let eql = 
1686         if eql = [] then [eq_what] else eql
1687       in
1688       let demod = 
1689         let demod = Str.split (Str.regexp "_") demod_table in 
1690         List.map (fun other -> find_in_ctx 1 other context) demod 
1691       in
1692       let eq_demod = 
1693         List.map 
1694           (fun demod -> List.nth equalities (position_of 0 demod eq_index)) 
1695           demod 
1696       in
1697       let table = List.fold_left Indexing.index Indexing.empty eq_demod in
1698       let maxm,eql = 
1699         List.fold_left 
1700           (fun (maxm,acc) e -> 
1701             let maxm,eq = 
1702               Indexing.demodulation_equality bag eq_uri maxm env table e
1703             in
1704             maxm,eq::acc) 
1705           (maxm,[]) eql
1706       in
1707       let eql = List.rev eql in
1708       prerr_endline ("\n result [demod]: ");
1709       List.iter 
1710         (fun e -> prerr_endline (Equality.string_of_equality e ~env)) eql;
1711       prerr_endline ("\n result [demod] (cut&paste): ");
1712       List.iter 
1713         (fun e -> 
1714           let t = Equality.term_of_equality eq_uri e in
1715           prerr_endline (CicPp.pp t names)) 
1716       eql;
1717     end;
1718   proof,[goalno]
1719 ;;
1720
1721 let get_stats () = "" 
1722 (*
1723   <:show<Saturation.>> ^ Indexing.get_stats () ^ Founif.get_stats () ^
1724   Equality.get_stats ()
1725 ;;
1726 *)
1727
1728 (* THINGS USED ONLY BY saturate_main.ml *)
1729
1730 let main _ _ _ _ _ = () ;;
1731
1732 let retrieve_and_print dbd term metasenv ugraph = 
1733   let module C = Cic in
1734   let module T = CicTypeChecker in
1735   let module PET = ProofEngineTypes in
1736   let module PP = CicPp in
1737   let proof = None, (1, [], term)::metasenv, C.Meta (1, []), term in
1738   let status = PET.apply_tactic (PrimitiveTactics.intros_tac ()) (proof, 1) in
1739   let proof, goals = status in
1740   let goal' = List.nth goals 0 in
1741   let uri, metasenv, meta_proof, term_to_prove = proof in
1742   let _, context, type_of_goal = CicUtil.lookup_meta goal' metasenv in
1743   let eq_uri = eq_of_goal type_of_goal in
1744   let bag = Equality.mk_equality_bag () in
1745   let eq_indexes, equalities, maxm,cache = 
1746     Equality_retrieval.find_context_equalities 0 bag None context proof AutoCache.cache_empty in
1747   let ugraph = CicUniv.empty_ugraph in
1748   let env = (metasenv, context, ugraph) in
1749   let t1 = Unix.gettimeofday () in
1750   let lib_eq_uris, library_equalities, maxm, cache =
1751     Equality_retrieval.find_library_equalities bag None
1752       false dbd context (proof, goal') (maxm+2)  cache
1753   in 
1754   let t2 = Unix.gettimeofday () in
1755   maxmeta := maxm+2;
1756   let equalities = (* equalities @ *) library_equalities in
1757   Utils.debug_print
1758      (lazy
1759         (Printf.sprintf "\n\nequalities:\n%s\n"
1760            (String.concat "\n"
1761               (List.map 
1762           (fun (u, e) ->
1763 (*                  Printf.sprintf "%s: %s" *)
1764                    (UriManager.string_of_uri u)
1765 (*                    (string_of_equality e) *)
1766                      )
1767           equalities))));
1768   Utils.debug_print (lazy "RETR: SIMPLYFYING EQUALITIES...");
1769   let rec simpl e others others_simpl =
1770     let (u, e) = e in
1771     let active = (others @ others_simpl) in
1772     let tbl =
1773       List.fold_left
1774         (fun t (_, e) -> Indexing.index t e)
1775         Indexing.empty active
1776     in
1777     let res = forward_simplify bag eq_uri env e (active, tbl) in
1778     match others with
1779         | hd::tl -> (
1780             match res with
1781               | None -> simpl hd tl others_simpl
1782               | Some e -> simpl hd tl ((u, e)::others_simpl)
1783           )
1784         | [] -> (
1785             match res with
1786               | None -> others_simpl
1787               | Some e -> (u, e)::others_simpl
1788           ) 
1789   in
1790   let _equalities =
1791     match equalities with
1792       | [] -> []
1793       | hd::tl ->
1794           let others = tl in (* List.map (fun e -> (Utils.Positive, e)) tl in *)
1795           let res =
1796             List.rev (simpl (*(Positive,*) hd others [])
1797           in
1798             Utils.debug_print
1799               (lazy
1800                  (Printf.sprintf "\nequalities AFTER:\n%s\n"
1801                     (String.concat "\n"
1802                        (List.map
1803                           (fun (u, e) ->
1804                              Printf.sprintf "%s: %s"
1805                                (UriManager.string_of_uri u)
1806                                (Equality.string_of_equality e)
1807                           )
1808                           res))));
1809             res in
1810     Utils.debug_print
1811       (lazy
1812          (Printf.sprintf "Time to retrieve equalities: %.9f\n" (t2 -. t1)))
1813 ;;
1814
1815
1816 let main_demod_equalities dbd term metasenv ugraph =
1817   let module C = Cic in
1818   let module T = CicTypeChecker in
1819   let module PET = ProofEngineTypes in
1820   let module PP = CicPp in
1821   let proof = None, (1, [], term)::metasenv, C.Meta (1, []), term in
1822   let status = PET.apply_tactic (PrimitiveTactics.intros_tac ()) (proof, 1) in
1823   let proof, goals = status in
1824   let goal' = List.nth goals 0 in
1825   let _, metasenv, meta_proof, _ = proof in
1826   let _, context, goal = CicUtil.lookup_meta goal' metasenv in
1827   let eq_uri = eq_of_goal goal in 
1828   let bag = Equality.mk_equality_bag () in
1829   let eq_indexes, equalities, maxm,  cache = 
1830     Equality_retrieval.find_context_equalities 0 bag None context proof AutoCache.cache_empty in
1831   let lib_eq_uris, library_equalities, maxm,cache =
1832     Equality_retrieval.find_library_equalities bag None
1833       false dbd context (proof, goal') (maxm+2)  cache
1834   in
1835   let library_equalities = List.map snd library_equalities in
1836   maxmeta := maxm+2; (* TODO ugly!! *)
1837   let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
1838   let new_meta_goal, metasenv, type_of_goal =
1839     let _, context, ty = CicUtil.lookup_meta goal' metasenv in
1840     Utils.debug_print
1841       (lazy
1842          (Printf.sprintf "\n\nTRYING TO INFER EQUALITIES MATCHING: %s\n\n"
1843             (CicPp.ppterm ty)));
1844     Cic.Meta (maxm+1, irl),
1845     (maxm+1, context, ty)::metasenv,
1846     ty
1847   in
1848   let env = (metasenv, context, ugraph) in
1849   (*try*)
1850     let goal = [], [], goal 
1851     in
1852     let equalities = 
1853       simplify_equalities bag eq_uri env (equalities@library_equalities) 
1854     in
1855     let active = make_empty_active () in
1856     let passive = make_passive equalities in
1857     Printf.eprintf "\ncontext:\n%s\n" (PP.ppcontext context);
1858     Printf.eprintf "\nmetasenv:\n%s\n" (Utils.print_metasenv metasenv);
1859     Printf.eprintf "\nequalities:\n%s\n"
1860       (String.concat "\n"
1861          (List.map
1862             (Equality.string_of_equality ~env) equalities));
1863     prerr_endline "--------------------------------------------------";
1864     prerr_endline "GO!";
1865     start_time := Unix.gettimeofday ();
1866     if !time_limit < 1. then time_limit := 60.;    
1867     let ra, rp =
1868       saturate_equations bag eq_uri env goal (fun e -> true) passive active
1869     in
1870
1871     let initial =
1872       List.fold_left (fun s e -> EqualitySet.add e s)
1873         EqualitySet.empty equalities
1874     in
1875     let addfun s e = 
1876       if not (EqualitySet.mem e initial) then EqualitySet.add e s else s
1877     in
1878
1879     let passive =
1880       match rp with
1881       | p, _ ->
1882           EqualitySet.elements (List.fold_left addfun EqualitySet.empty p)
1883     in
1884     let active =
1885       let l = fst ra in
1886       EqualitySet.elements (List.fold_left addfun EqualitySet.empty l)
1887     in
1888     Printf.eprintf "\n\nRESULTS:\nActive:\n%s\n\nPassive:\n%s\n"
1889        (String.concat "\n" (List.map (Equality.string_of_equality ~env) active)) 
1890      (*  (String.concat "\n"
1891          (List.map (fun e -> CicPp.ppterm (term_of_equality e)) active)) *)
1892 (*       (String.concat "\n" (List.map (string_of_equality ~env) passive)); *)
1893       (String.concat "\n"
1894          (List.map 
1895            (fun e -> CicPp.ppterm (Equality.term_of_equality eq_uri e)) 
1896           passive));
1897     print_newline ();
1898 (*
1899   with e ->
1900     Utils.debug_print (lazy ("EXCEPTION: " ^ (Printexc.to_string e)))
1901 *)
1902 ;;
1903 let saturate_equations eq_uri env goal accept_fun passive active =
1904   let bag = Equality.mk_equality_bag () in
1905   saturate_equations bag eq_uri env goal accept_fun passive active
1906 ;;
1907
1908 let add_to_passive eql passives = 
1909   add_to_passive passives eql eql
1910 ;;