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