]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/paramodulation/saturation.ml
new paramodulation
[helm.git] / helm / ocaml / paramodulation / saturation.ml
index e8afa80329fd9572a2a70ef8e25d0bc3d3396563..bc935d7f730c518d97ed9c3a7dba09ba03c64714 100644 (file)
@@ -38,10 +38,14 @@ let kept_clauses = ref 0;;
 (* index of the greatest Cic.Meta created - TODO: find a better way! *)
 let maxmeta = ref 0;;
 
+(* varbiables controlling the search-space *)
+let maxdepth = ref 3;;
+let maxwidth = ref 3;;
+
 
 type result =
   | ParamodulationFailure
-  | ParamodulationSuccess of Inference.equality option * environment
+  | ParamodulationSuccess of Inference.proof option * environment
 ;;
 
 
@@ -103,8 +107,12 @@ end
 module EqualitySet = Set.Make(OrderedEquality);;
 
 
-let select env passive (active, _) =
+let select env goals passive (active, _) =
   processed_clauses := !processed_clauses + 1;
+
+  let goal =
+    match (List.rev goals) with (_, goal::_)::_ -> goal | _ -> assert false
+  in
   
   let (neg_list, neg_set), (pos_list, pos_set), passive_table = passive in
   let remove eq l =
@@ -135,9 +143,13 @@ let select env passive (active, _) =
       let cardinality map =
         TermMap.fold (fun k v res -> res + v) map 0
       in
-      match active with
-      | (Negative, e)::_ ->
-          let symbols = symbols_of_equality e in
+(*       match active with *)
+(*       | (Negative, e)::_ -> *)
+(*           let symbols = symbols_of_equality e in *)
+      let symbols =
+        let _, _, term = goal in
+        symbols_of_term term
+      in
           let card = cardinality symbols in
           let foldfun k v (r1, r2) = 
             if TermMap.mem k symbols then
@@ -179,19 +191,19 @@ let select env passive (active, _) =
           (([], neg_set),
            (remove current pos_list, EqualitySet.remove current pos_set),
            passive_table)
-      | _ ->
-          let current = EqualitySet.min_elt pos_set in
-          let passive_table =
-            Indexing.remove_index passive_table current
-(*             if !use_fullred then Indexing.remove_index passive_table current *)
-(*             else passive_table *)
-          in
-          let passive =
-            (neg_list, neg_set),
-            (remove current pos_list, EqualitySet.remove current pos_set),
-            passive_table
-          in
-          (Positive, current), passive
+(*       | _ -> *)
+(*           let current = EqualitySet.min_elt pos_set in *)
+(*           let passive_table = *)
+(*             Indexing.remove_index passive_table current *)
+(* (\*             if !use_fullred then Indexing.remove_index passive_table current *\) *)
+(* (\*             else passive_table *\) *)
+(*           in *)
+(*           let passive = *)
+(*             (neg_list, neg_set), *)
+(*             (remove current pos_list, EqualitySet.remove current pos_set), *)
+(*             passive_table *)
+(*           in *)
+(*           (Positive, current), passive *)
     )
   | _ ->
       symbols_counter := !symbols_ratio;
@@ -288,7 +300,8 @@ let prune_passive howmany (active, _) passive =
   in
   let in_weight = round (howmany *. ratio /. (ratio +. 1.))
   and in_age = round (howmany /. (ratio +. 1.)) in 
-  debug_print (lazy (Printf.sprintf "in_weight: %d, in_age: %d\n" in_weight in_age));
+  debug_print
+    (lazy (Printf.sprintf "in_weight: %d, in_age: %d\n" in_weight in_age));
   let symbols, card =
     match active with
     | (Negative, e)::_ ->
@@ -512,7 +525,7 @@ let forward_simplify env (sign, current) ?passive (active_list, active_table) =
   
   let demodulate table current = 
     let newmeta, newcurrent =
-      Indexing.demodulation !maxmeta env table sign current in
+      Indexing.demodulation_equality !maxmeta env table sign current in
     maxmeta := newmeta;
     if is_identity env newcurrent then
       if sign = Negative then Some (sign, newcurrent)
@@ -601,7 +614,7 @@ let forward_simplify_new env (new_neg, new_pos) ?passive active =
   
   let demodulate sign table target =
     let newmeta, newtarget =
-      Indexing.demodulation !maxmeta env table sign target in
+      Indexing.demodulation_equality !maxmeta env table sign target in
     maxmeta := newmeta;
     newtarget
   in
@@ -639,10 +652,10 @@ let forward_simplify_new env (new_neg, new_pos) ?passive active =
   let subs =
     match passive_table with
     | None ->
-        (fun e -> not (Indexing.subsumption env active_table e))
+        (fun e -> not (fst (Indexing.subsumption env active_table e)))
     | Some passive_table ->
-        (fun e -> not ((Indexing.subsumption env active_table e) ||
-                         (Indexing.subsumption env passive_table e)))
+        (fun e -> not ((fst (Indexing.subsumption env active_table e)) ||
+                         (fst (Indexing.subsumption env passive_table e))))
   in
 
   let t1 = Unix.gettimeofday () in
@@ -787,7 +800,545 @@ let get_selection_estimate () =
 ;;
 
   
-let rec given_clause env passive active =
+let simplify_goal env goal ?passive (active_list, active_table) =
+  let pl, passive_table =
+    match passive with
+    | None -> [], None
+    | Some ((pn, _), (pp, _), pt) ->
+        let pn = List.map (fun e -> (Negative, e)) pn
+        and pp = List.map (fun e -> (Positive, e)) pp in
+        pn @ pp, Some pt
+  in
+  let all = if pl = [] then active_list else active_list @ pl in
+
+  let demodulate table goal = 
+    let newmeta, newgoal =
+      Indexing.demodulation_goal !maxmeta env table goal in
+    maxmeta := newmeta;
+    newgoal
+  in
+  let goal =
+    match passive_table with
+    | None -> demodulate active_table goal
+    | Some passive_table ->
+        let goal = demodulate active_table goal in
+        demodulate passive_table goal
+  in
+  let _ =
+    let p, _, t = goal in
+    debug_print
+      (lazy
+         (Printf.sprintf "Goal after demodulation: %s, %s"
+            (string_of_proof p) (CicPp.ppterm t)))
+  in
+  goal
+;;
+
+
+let simplify_goals env goals ?passive active =
+  List.map
+    (fun (d, gl) ->
+       let gl = List.map (fun g -> simplify_goal env g ?passive active) gl in
+       d, gl)
+    goals
+;;
+
+
+let simplify_theorems env theorems ?passive (active_list, active_table) =
+  let pl, passive_table =
+    match passive with
+    | None -> [], None
+    | Some ((pn, _), (pp, _), pt) ->
+        let pn = List.map (fun e -> (Negative, e)) pn
+        and pp = List.map (fun e -> (Positive, e)) pp in
+        pn @ pp, Some pt
+  in
+  let all = if pl = [] then active_list else active_list @ pl in
+
+  let demodulate table theorem =
+    let newmeta, newthm =
+      Indexing.demodulation_theorem !maxmeta env table theorem in
+    maxmeta := newmeta;
+    newthm
+  in
+  match passive_table with
+  | None -> List.map (demodulate active_table) theorems
+  | Some passive_table ->
+      let theorems = List.map (demodulate active_table) theorems in
+      List.map (demodulate passive_table) theorems
+;;
+
+
+let apply_equality_to_goal env equality goal =
+  let module C = Cic in
+  let module HL = HelmLibraryObjects in
+  let module I = Inference in
+  let metasenv, context, ugraph = env in
+  let _, proof, (ty, left, right, _), metas, args = equality in
+  let eqterm = C.Appl [C.MutInd (HL.Logic.eq_URI, 0, []); ty; left; right] in
+  let gproof, gmetas, gterm = goal in
+  try
+    let subst, metasenv', _ =
+      let menv = metasenv @ metas @ gmetas in
+      Inference.unification menv context eqterm gterm ugraph
+    in
+    let newproof =
+      match proof with
+      | I.BasicProof t -> I.BasicProof (CicMetaSubst.apply_subst subst t)
+      | I.ProofBlock (s, uri, nt, t, pe, p) ->
+          I.ProofBlock (subst @ s, uri, nt, t, pe, p)
+      | _ -> assert false
+    in
+    let newgproof =
+      let rec repl = function
+        | I.ProofGoalBlock (_, gp) -> I.ProofGoalBlock (newproof, gp)
+        | I.NoProof -> newproof
+        | I.BasicProof p -> newproof
+        | I.SubProof (t, i, p) -> I.SubProof (t, i, repl p)
+        | _ -> assert false
+      in
+      repl gproof
+    in
+    true, subst, newgproof
+  with CicUnification.UnificationFailure _ ->
+    false, [], I.NoProof
+;;
+
+
+(*
+let apply_to_goal env theorems active (depth, goals) =
+  let _ =
+    debug_print ("apply_to_goal: " ^ (string_of_int (List.length goals)))
+  in
+  let metasenv, context, ugraph = env in
+  let goal = List.hd goals in
+  let proof, metas, term = goal in
+(*   debug_print *)
+(*     (Printf.sprintf "apply_to_goal with goal: %s" (CicPp.ppterm term)); *)
+  let newmeta = CicMkImplicit.new_meta metasenv [] in
+  let metasenv = (newmeta, context, term)::metasenv @ metas in
+  let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
+  let status =
+    ((None, metasenv, Cic.Meta (newmeta, irl), term), newmeta)
+  in
+  let rec aux = function
+    | [] -> false, [] (* goals *) (* None *)
+    | (theorem, thmty, _)::tl ->
+        try
+          let subst_in, (newproof, newgoals) =
+            PrimitiveTactics.apply_tac_verbose ~term:theorem status
+          in
+          if newgoals = [] then
+            let _, _, p, _ = newproof in
+            let newp =
+              let rec repl = function
+                | Inference.ProofGoalBlock (_, gp) ->
+                    Inference.ProofGoalBlock (Inference.BasicProof p, gp)
+                | Inference.NoProof -> Inference.BasicProof p
+                | Inference.BasicProof _ -> Inference.BasicProof p
+                | Inference.SubProof (t, i, p2) ->
+                    Inference.SubProof (t, i, repl p2)
+                | _ -> assert false
+              in
+              repl proof
+            in
+            true, [[newp, metas, term]] (* Some newp *)
+          else if List.length newgoals = 1 then
+            let _, menv, p, _ = newproof in
+            let irl =
+              CicMkImplicit.identity_relocation_list_for_metavariable context
+            in
+            let goals =
+              List.map
+                (fun i ->
+                   let _, _, ty = CicUtil.lookup_meta i menv in
+                   let proof =
+                     Inference.SubProof
+                       (p, i, Inference.BasicProof (Cic.Meta (i, irl)))
+                   in (proof, menv, ty))
+                newgoals
+            in
+            let res, others = aux tl in
+            if res then (true, others) else (false, goals::others)
+          else
+            aux tl
+        with ProofEngineTypes.Fail msg ->
+          (*     debug_print ("FAIL!!:" ^ msg); *)
+          aux tl
+  in
+  let r, l =
+    if Inference.term_is_equality term then
+      let rec appleq = function
+        | [] -> false, []
+        | (Positive, equality)::tl ->
+            let ok, _, newproof = apply_equality_to_goal env equality goal in
+            if ok then true, [(depth, [newproof, metas, term])] else appleq tl
+        | _::tl -> appleq tl
+      in
+      let al, _ = active in
+      appleq al
+    else
+      false, []
+  in
+  if r = true then r, l else
+    let r, l = aux theorems in
+    if r = true then
+      r, List.map (fun l -> (depth+1, l)) l
+    else
+      r, (depth, goals)::(List.map (fun l -> (depth+1, l)) l)
+;;
+*)
+
+
+let new_meta () =
+  incr maxmeta; !maxmeta
+;;
+
+
+let apply_to_goal env theorems active goal =
+  let metasenv, context, ugraph = env in
+  let proof, metas, term = goal in
+  debug_print
+    (lazy
+       (Printf.sprintf "apply_to_goal with goal: %s, %s"
+          (string_of_proof proof) (CicPp.ppterm term)));
+  let status =
+    let irl =
+      CicMkImplicit.identity_relocation_list_for_metavariable context in
+    let proof', newmeta =
+      let rec get_meta = function
+        | SubProof (t, i, _) -> t, i
+        | ProofGoalBlock (_, p) -> get_meta p
+        | _ ->
+            let n = new_meta () in (* CicMkImplicit.new_meta metasenv [] in *)
+            Cic.Meta (n, irl), n
+      in
+      get_meta proof
+    in
+(*     let newmeta = CicMkImplicit.new_meta metasenv [] in *)
+    let metasenv = (newmeta, context, term)::metasenv @ metas in
+    ((None, metasenv, Cic.Meta (newmeta, irl), term), newmeta)
+(*     ((None, metasenv, proof', term), newmeta) *)
+  in
+  let rec aux = function
+    | [] -> `No (* , [], [] *)
+    | (theorem, thmty, _)::tl ->
+        try
+          let subst, (newproof, newgoals) =
+            PrimitiveTactics.apply_tac_verbose_with_subst ~term:theorem status
+          in
+          if newgoals = [] then
+            let _, _, p, _ = newproof in
+            let newp =
+              let rec repl = function
+                | Inference.ProofGoalBlock (_, gp) ->
+                    Inference.ProofGoalBlock (Inference.BasicProof p, gp)
+                | Inference.NoProof -> Inference.BasicProof p
+                | Inference.BasicProof _ -> Inference.BasicProof p
+                | Inference.SubProof (t, i, p2) ->
+                    Inference.SubProof (t, i, repl p2)
+                | _ -> assert false
+              in
+              repl proof
+            in
+            let _, m = status in
+            let subst = List.filter (fun (i, _) -> i = m) subst in
+(*             debug_print *)
+(*               (lazy *)
+(*                  (Printf.sprintf "m = %d\nsubst = %s\n" *)
+(*                     m (print_subst subst))); *)
+            `Ok (subst, [newp, metas, term])
+          else
+            let _, menv, p, _ = newproof in
+            let irl =
+              CicMkImplicit.identity_relocation_list_for_metavariable context
+            in
+            let goals =
+              List.map
+                (fun i ->
+                   let _, _, ty = CicUtil.lookup_meta i menv in
+                   let p' =
+                     let rec gp = function
+                       | SubProof (t, i, p) ->
+                           SubProof (t, i, gp p)
+                       | ProofGoalBlock (sp1, sp2) ->
+(*                            SubProof (p, i, sp) *)
+                           ProofGoalBlock (sp1, gp sp2)
+(*                            gp sp *)
+                       | BasicProof _
+                       | NoProof ->
+                           SubProof (p, i, BasicProof (Cic.Meta (i, irl)))
+                       | ProofSymBlock (s, sp) ->
+                           ProofSymBlock (s, gp sp)
+                       | ProofBlock (s, u, nt, t, pe, sp) ->
+                           ProofBlock (s, u, nt, t, pe, gp sp)
+(*                        | _ -> assert false *)
+                     in gp proof
+                   in
+                   debug_print
+                     (lazy
+                        (Printf.sprintf "new sub goal: %s, %s"
+                           (string_of_proof p') (CicPp.ppterm ty)));
+                   (p', menv, ty))
+                newgoals
+            in
+(*             debug_print *)
+(*               (lazy *)
+(*                  (Printf.sprintf "\nGoOn with subst: %s" (print_subst subst))); *)
+            let best = aux tl in
+            match best with
+            | `Ok (_, _) -> best
+            | `No -> `GoOn ([subst, goals])
+            | `GoOn sl(* , subst', goals' *) ->
+(*                 if (List.length goals') < (List.length goals) then best *)
+(*                 else `GoOn, subst, goals *)
+                `GoOn ((subst, goals)::sl)
+        with ProofEngineTypes.Fail msg ->
+          aux tl
+  in
+  let r, s, l =
+    if Inference.term_is_equality term then
+      let rec appleq = function
+        | [] -> false, [], []
+        | (Positive, equality)::tl ->
+            let ok, s, newproof = apply_equality_to_goal env equality goal in
+            if ok then true, s, [newproof, metas, term] else appleq tl
+        | _::tl -> appleq tl
+      in
+      let al, _ = active in
+      appleq al
+    else
+      false, [], []
+  in
+  if r = true then `Ok (s, l) else aux theorems
+;;
+
+
+let apply_to_goal_conj env theorems active (depth, goals) =
+  let rec aux = function
+    | goal::tl ->
+        let propagate_subst subst (proof, metas, term) =
+          debug_print
+            (lazy
+               (Printf.sprintf "\npropagate_subst:\n%s\n%s, %s\n"
+                  (print_subst subst) (string_of_proof proof)
+                  (CicPp.ppterm term)));
+          let rec repl = function
+            | NoProof -> NoProof
+            | BasicProof t ->
+                BasicProof (CicMetaSubst.apply_subst subst t)
+            | ProofGoalBlock (p, pb) ->
+                debug_print (lazy "HERE");
+                let pb' = repl pb in
+                ProofGoalBlock (p, pb')
+            | SubProof (t, i, p) ->
+                let t' = CicMetaSubst.apply_subst subst t in
+                debug_print
+                  (lazy
+                     (Printf.sprintf
+                        "SubProof %d\nt = %s\nsubst = %s\nt' = %s\n"
+                        i (CicPp.ppterm t) (print_subst subst)
+                        (CicPp.ppterm t')));
+                let p = repl p in
+                SubProof (t', i, p)
+            | ProofSymBlock (ens, p) -> ProofSymBlock (ens, repl p)
+            | ProofBlock (s, u, nty, t, pe, p) ->
+                ProofBlock (subst @ s, u, nty, t, pe, p)
+          in (repl proof, metas, term)
+        in
+        let r = apply_to_goal env theorems active goal in (
+          match r with
+          | `No -> `No (depth, goals)
+          | `GoOn sl (* (subst, gl) *) ->
+(*               let tl = List.map (propagate_subst subst) tl in *)
+              debug_print (lazy "GO ON!!!");
+              let l =
+                List.map
+                  (fun (s, gl) ->
+                     (depth+1, gl @ (List.map (propagate_subst s) tl))) sl
+              in
+              debug_print
+                (lazy
+                   (Printf.sprintf "%s\n"
+                      (String.concat "; "
+                         (List.map
+                            (fun (s, gl) ->
+                               (Printf.sprintf "[%s]"
+                                  (String.concat "; "
+                                     (List.map
+                                        (fun (p, _, g) ->
+                                           (Printf.sprintf "<%s, %s>"
+                                              (string_of_proof p)
+                                              (CicPp.ppterm g))) gl)))) l))));
+              `GoOn l (* (depth+1, gl @ tl) *)
+          | `Ok (subst, gl) ->
+              if tl = [] then
+(*                 let _ = *)
+(*                   let p, _, t = List.hd gl in *)
+(*                   debug_print *)
+(*                     (lazy *)
+(*                        (Printf.sprintf "OK: %s, %s\n" *)
+(*                           (string_of_proof p) (CicPp.ppterm t))) *)
+(*                 in *)
+                `Ok (depth, gl)
+              else
+                let p, _, _ = List.hd gl in
+                let subproof =
+                  let rec repl = function
+                    | SubProof (_, _, p) -> repl p
+                    | ProofGoalBlock (p1, p2) ->
+                        ProofGoalBlock (repl p1, repl p2)
+                    | p -> p
+                  in
+                  build_proof_term (repl p)
+                in
+                let i = 
+                  let rec get_meta = function
+                    | SubProof (_, i, p) -> max i (get_meta p)
+                    | ProofGoalBlock (_, p) -> get_meta p
+                    | _ -> -1 (* assert false *)
+                  in
+                  get_meta p
+                in
+                let subst =
+                  let _, (context, _, _) = List.hd subst in
+                  [i, (context, subproof, Cic.Implicit None)]
+                in
+                let tl = List.map (propagate_subst subst) tl in
+                `GoOn ([depth+1, tl])
+        )
+    | _ -> assert false
+  in
+  debug_print
+    (lazy
+       (Printf.sprintf "apply_to_goal_conj (%d, [%s])"
+          depth
+          (String.concat "; "
+             (List.map (fun (_, _, t) -> CicPp.ppterm t) goals))));
+  if depth > !maxdepth || (List.length goals) > !maxwidth then (
+    debug_print
+      (lazy (Printf.sprintf "Pruning because depth = %d, width = %d"
+               depth (List.length goals)));
+    `No (depth, goals)
+  ) else
+    aux goals
+;;
+
+
+module OrderedGoals = struct
+  type t = int * (Inference.proof * Cic.metasenv * Cic.term) list
+
+  let compare g1 g2 =
+    let d1, l1 = g1
+    and d2, l2 = g2 in
+    let r = d2 - d1 in
+    if r <> 0 then r
+    else let r = (List.length l1) - (List.length l2) in
+    if r <> 0 then r
+    else
+      let res = ref 0 in
+      let _ = 
+        List.exists2
+          (fun (_, _, t1) (_, _, t2) ->
+             let r = Pervasives.compare t1 t2 in
+             if r <> 0 then (
+               res := r;
+               true
+             ) else
+               false) l1 l2
+      in !res
+(*       let res = Pervasives.compare g1 g2 in *)
+(*       let _ = *)
+(*         let print_goals (d, gl) =  *)
+(*           let gl' = List.map (fun (_, _, t) -> CicPp.ppterm t) gl in *)
+(*           Printf.sprintf "%d, [%s]" d (String.concat "; " gl') *)
+(*         in *)
+(*         debug_print *)
+(*           (lazy *)
+(*              (Printf.sprintf "comparing g1:%s and g2:%s, res: %d\n" *)
+(*                 (print_goals g1) (print_goals g2) res)) *)
+(*       in *)
+(*       res *)
+end
+
+module GoalsSet = Set.Make(OrderedGoals);;
+
+
+exception SearchSpaceOver;;
+
+
+let apply_to_goals env is_passive_empty theorems active goals =
+  debug_print (lazy "\n\n\tapply_to_goals\n\n");
+  let add_to set goals =
+    List.fold_left (fun s g -> GoalsSet.add g s) set goals 
+  in
+  let rec aux set = function
+    | [] ->
+        debug_print (lazy "HERE!!!");
+        if is_passive_empty then raise SearchSpaceOver else false, set
+    | goals::tl ->
+        let res = apply_to_goal_conj env theorems active goals in
+        match res with
+        | `Ok newgoals ->
+            let _ =
+              let d, p, t =
+                match newgoals with
+                | (d, (p, _, t)::_) -> d, p, t
+                | _ -> assert false
+              in
+              debug_print
+                (lazy
+                   (Printf.sprintf "\nOK!!!!\ndepth: %d\nProof: %s\ngoal: %s\n"
+                      d (string_of_proof p) (CicPp.ppterm t)))
+            in
+            true, GoalsSet.singleton newgoals
+        | `GoOn newgoals ->
+            let print_set set msg = 
+              debug_print
+                (lazy
+                   (Printf.sprintf "%s:\n%s" msg
+                      (String.concat "\n"
+                         (GoalsSet.fold
+                            (fun (d, gl) l ->
+                               let gl' =
+                                 List.map (fun (_, _, t) -> CicPp.ppterm t) gl
+                               in
+                               let s =
+                                 Printf.sprintf "%d, [%s]" d
+                                   (String.concat "; " gl')
+                               in
+                               s::l) set []))))
+            in
+            let set = add_to set (goals::tl) in
+(*             print_set set "SET BEFORE"; *)
+            let n = GoalsSet.cardinal set in
+            let set = add_to set newgoals in
+(*             print_set set "SET AFTER"; *)
+            let m = GoalsSet.cardinal set in
+(*             if n < m then *)
+            false, set
+(*             else *)
+(*               let _ = print_set set "SET didn't change" in *)
+(*               aux set tl *)
+        | `No newgoals ->
+            aux set tl
+(*             let set = add_to set (newgoals::goals::tl) in *)
+(*             let res, set = aux set tl in *)
+(*             res, set *)
+  in
+  let n = List.length goals in
+  let res, goals = aux (add_to GoalsSet.empty goals) goals in
+  let goals = GoalsSet.elements goals in
+  debug_print (lazy "\n\tapply_to_goals end\n");
+  let m = List.length goals in
+  if m = n && is_passive_empty then
+    raise SearchSpaceOver
+  else
+    res, goals
+;;
+
+
+let rec given_clause env goals theorems passive active =
   let time1 = Unix.gettimeofday () in
 
   let selection_estimate = get_selection_estimate () in
@@ -797,12 +1348,13 @@ let rec given_clause env passive active =
       passive
     else if !elapsed_time > !time_limit then (
       debug_print (lazy (Printf.sprintf "Time limit (%.2f) reached: %.2f\n"
-                     !time_limit !elapsed_time));
+                           !time_limit !elapsed_time));
       make_passive [] []
     ) else if kept > selection_estimate then (
-      debug_print (lazy (Printf.sprintf ("Too many passive equalities: pruning..." ^^
-                                     "(kept: %d, selection_estimate: %d)\n")
-                     kept selection_estimate));
+      debug_print
+        (lazy (Printf.sprintf ("Too many passive equalities: pruning..." ^^
+                                 "(kept: %d, selection_estimate: %d)\n")
+                 kept selection_estimate));
       prune_passive selection_estimate active passive
     ) else
       passive
@@ -813,67 +1365,95 @@ let rec given_clause env passive active =
 
   kept_clauses := (size_of_passive passive) + (size_of_active active);
     
-  match passive_is_empty passive with
-  | true -> ParamodulationFailure
-  | false ->
-      let (sign, current), passive = select env passive active in
-      let time1 = Unix.gettimeofday () in
-      let res = forward_simplify env (sign, current) ~passive active in
-      let time2 = Unix.gettimeofday () in
-      forward_simpl_time := !forward_simpl_time +. (time2 -. time1);
-      match res with
-      | None ->
-          given_clause env passive active
-      | Some (sign, current) ->
-          if (sign = Negative) && (is_identity env current) then (
-            debug_print (lazy (Printf.sprintf "OK!!! %s %s" (string_of_sign sign)
-                           (string_of_equality ~env current)));
-            ParamodulationSuccess (Some current, env)
-          ) else (            
-            debug_print (lazy "\n================================================");
-            debug_print (lazy (Printf.sprintf "selected: %s %s"
-                           (string_of_sign sign)
+(*   let refl_equal = *)
+(*     CicUtil.term_of_uri *)
+(*       (UriManager.uri_of_string "cic:/Coq/Init/Logic/eq.ind#xpointer(1/1/1)") *)
+(*   in *)
+  let goals = simplify_goals env goals active in
+  let theorems = simplify_theorems env theorems active in 
+  let is_passive_empty = passive_is_empty passive in
+  try
+    let ok, goals = apply_to_goals env is_passive_empty theorems active goals in
+    if ok then
+      let proof =
+        match goals with
+        | (_, [proof, _, _])::_ -> Some proof
+        | _ -> assert false
+      in
+      ParamodulationSuccess (proof, env)
+    else
+      match is_passive_empty (* passive_is_empty passive *) with
+      | true -> (* ParamodulationFailure *)
+          given_clause env goals theorems passive active
+      | false ->
+          let (sign, current), passive = select env goals passive active in
+          let time1 = Unix.gettimeofday () in
+          let res = forward_simplify env (sign, current) ~passive active in
+          let time2 = Unix.gettimeofday () in
+          forward_simpl_time := !forward_simpl_time +. (time2 -. time1);
+          match res with
+          | None ->
+              given_clause env goals theorems passive active
+          | Some (sign, current) ->
+              if (sign = Negative) && (is_identity env current) then (
+                debug_print
+                  (lazy (Printf.sprintf "OK!!! %s %s" (string_of_sign sign)
                            (string_of_equality ~env current)));
-
-            let t1 = Unix.gettimeofday () in
-            let new' = infer env sign current active in
-            let t2 = Unix.gettimeofday () in
-            infer_time := !infer_time +. (t2 -. t1);
-            
-            let res, goal = contains_empty env new' in
-            if res then
-              ParamodulationSuccess (goal, env)
-            else 
-              let t1 = Unix.gettimeofday () in
-              let new' = forward_simplify_new env new' (* ~passive *) active in
-              let t2 = Unix.gettimeofday () in
-              let _ =
-                forward_simpl_new_time := !forward_simpl_new_time +. (t2 -. t1)
-              in
-              let active =
-                match sign with
-                | Negative -> active
-                | Positive ->
-                    let t1 = Unix.gettimeofday () in
-                    let active, _, newa, _ =
-                      backward_simplify env ([], [current]) active
-                    in
-                    let t2 = Unix.gettimeofday () in
-                    backward_simpl_time := !backward_simpl_time +. (t2 -. t1);
-                    match newa with
-                    | None -> active
-                    | Some (n, p) ->
-                        let al, tbl = active in
-                        let nn = List.map (fun e -> Negative, e) n in
-                        let pp, tbl =
-                          List.fold_right
-                            (fun e (l, t) ->
-                               (Positive, e)::l,
-                               Indexing.index tbl e)
-                            p ([], tbl)
+                let _, proof, _, _, _  = current in
+                ParamodulationSuccess (Some proof (* current *), env)
+              ) else (            
+                debug_print
+                  (lazy "\n================================================");
+                debug_print (lazy (Printf.sprintf "selected: %s %s"
+                                     (string_of_sign sign)
+                                     (string_of_equality ~env current)));
+
+                let t1 = Unix.gettimeofday () in
+                let new' = infer env sign current active in
+                let t2 = Unix.gettimeofday () in
+                infer_time := !infer_time +. (t2 -. t1);
+                
+                let res, goal' = contains_empty env new' in
+                if res then
+                  let proof =
+                    match goal' with
+                    | Some goal -> let _, proof, _, _, _ = goal in Some proof
+                    | None -> None
+                  in
+                  ParamodulationSuccess (proof (* goal *), env)
+                else 
+                  let t1 = Unix.gettimeofday () in
+                  let new' = forward_simplify_new env new' active in
+                  let t2 = Unix.gettimeofday () in
+                  let _ =
+                    forward_simpl_new_time :=
+                      !forward_simpl_new_time +. (t2 -. t1)
+                  in
+                  let active =
+                    match sign with
+                    | Negative -> active
+                    | Positive ->
+                        let t1 = Unix.gettimeofday () in
+                        let active, _, newa, _ =
+                          backward_simplify env ([], [current]) active
                         in
-                        nn @ al @ pp, tbl
-              in
+                        let t2 = Unix.gettimeofday () in
+                        backward_simpl_time :=
+                          !backward_simpl_time +. (t2 -. t1);
+                        match newa with
+                        | None -> active
+                        | Some (n, p) ->
+                            let al, tbl = active in
+                            let nn = List.map (fun e -> Negative, e) n in
+                            let pp, tbl =
+                              List.fold_right
+                                (fun e (l, t) ->
+                                   (Positive, e)::l,
+                                   Indexing.index tbl e)
+                                p ([], tbl)
+                            in
+                            nn @ al @ pp, tbl
+                  in
 (*               let _ = *)
 (*                 Printf.printf "active:\n%s\n" *)
 (*                   (String.concat "\n" *)
@@ -895,17 +1475,17 @@ let rec given_clause env passive active =
 (*                                   (string_of_equality ~env e)) pos))); *)
 (*                     print_newline (); *)
 (*               in *)
-              match contains_empty env new' with
-              | false, _ -> 
-                  let active =
-                    let al, tbl = active in
-                    match sign with
-                    | Negative -> (sign, current)::al, tbl
-                    | Positive ->
-                        al @ [(sign, current)], Indexing.index tbl current
-                  in
-                  let passive = add_to_passive passive new' in
-                  let (_, ns), (_, ps), _ = passive in
+                  match contains_empty env new' with
+                  | false, _ -> 
+                      let active =
+                        let al, tbl = active in
+                        match sign with
+                        | Negative -> (sign, current)::al, tbl
+                        | Positive ->
+                            al @ [(sign, current)], Indexing.index tbl current
+                      in
+                      let passive = add_to_passive passive new' in
+                      let (_, ns), (_, ps), _ = passive in
 (*                   Printf.printf "passive:\n%s\n" *)
 (*                     (String.concat "\n" *)
 (*                        ((List.map (fun e -> "Negative " ^ *)
@@ -915,14 +1495,22 @@ let rec given_clause env passive active =
 (*                                        (string_of_equality ~env e)) *)
 (*                              (EqualitySet.elements ps)))); *)
 (*                   print_newline (); *)
-                  given_clause env passive active
-              | true, goal ->
-                  ParamodulationSuccess (goal, env)
-          )
+                      given_clause env goals theorems passive active
+                  | true, goal ->
+                      let proof =
+                        match goal with
+                        | Some goal ->
+                            let _, proof, _, _, _ = goal in Some proof
+                        | None -> None
+                      in
+                      ParamodulationSuccess (proof (* goal *), env)
+              )
+  with SearchSpaceOver ->
+    ParamodulationFailure
 ;;
 
 
-let rec given_clause_fullred env passive active =
+let rec given_clause_fullred env goals theorems passive active =
   let time1 = Unix.gettimeofday () in
   
   let selection_estimate = get_selection_estimate () in
@@ -932,12 +1520,13 @@ let rec given_clause_fullred env passive active =
       passive
     else if !elapsed_time > !time_limit then (
       debug_print (lazy (Printf.sprintf "Time limit (%.2f) reached: %.2f\n"
-                     !time_limit !elapsed_time));
+                           !time_limit !elapsed_time));
       make_passive [] []
     ) else if kept > selection_estimate then (
-      debug_print (lazy (Printf.sprintf ("Too many passive equalities: pruning..." ^^
-                                     "(kept: %d, selection_estimate: %d)\n")
-                     kept selection_estimate));
+      debug_print
+        (lazy (Printf.sprintf ("Too many passive equalities: pruning..." ^^
+                                 "(kept: %d, selection_estimate: %d)\n")
+                 kept selection_estimate));
       prune_passive selection_estimate active passive
     ) else
       passive
@@ -948,91 +1537,133 @@ let rec given_clause_fullred env passive active =
     
   kept_clauses := (size_of_passive passive) + (size_of_active active);
 
-  match passive_is_empty passive with
-  | true -> ParamodulationFailure
-  | false ->
-      let (sign, current), passive = select env passive active in
-      let time1 = Unix.gettimeofday () in
-      let res = forward_simplify env (sign, current) ~passive active in
-      let time2 = Unix.gettimeofday () in
-      forward_simpl_time := !forward_simpl_time +. (time2 -. time1);
-      match res with
-      | None ->
-          given_clause_fullred env passive active
-      | Some (sign, current) ->
-          if (sign = Negative) && (is_identity env current) then (
-            debug_print (lazy (Printf.sprintf "OK!!! %s %s" (string_of_sign sign)
-                           (string_of_equality ~env current)));
-            ParamodulationSuccess (Some current, env)
-          ) else (
-            debug_print (lazy "\n================================================");
-            debug_print (lazy (Printf.sprintf "selected: %s %s"
-                           (string_of_sign sign)
+(*   let refl_equal = *)
+(*     CicUtil.term_of_uri *)
+(*       (UriManager.uri_of_string "cic:/Coq/Init/Logic/eq.ind#xpointer(1/1/1)") *)
+(*   in *)
+  let goals = simplify_goals env goals ~passive active in
+  let theorems = simplify_theorems env theorems ~passive active in
+  let is_passive_empty = passive_is_empty passive in
+  try
+    let ok, goals = apply_to_goals env is_passive_empty theorems active goals in
+    if ok then
+      let proof =
+        match goals with
+        | (_, [proof, _, _])::_ -> Some proof
+        | _ -> assert false
+      in
+      ParamodulationSuccess (proof, env)
+    else
+      let _ =
+        debug_print
+          (lazy ("new_goals: " ^ (string_of_int (List.length goals))));
+        debug_print
+          (lazy
+             (String.concat "\n"
+                (List.map
+                   (fun (d, gl) ->
+                      let gl' =
+                        List.map
+                          (fun (p, _, t) ->
+                             (string_of_proof p) ^ ", " ^ (CicPp.ppterm t)) gl
+                      in
+                      Printf.sprintf "%d: %s" d (String.concat "; " gl'))
+                   goals)));
+      in
+      match is_passive_empty (* passive_is_empty passive *) with
+      | true -> (* ParamodulationFailure *)
+          given_clause_fullred env goals theorems passive active        
+      | false ->
+          let (sign, current), passive = select env goals passive active in
+          let time1 = Unix.gettimeofday () in
+          let res = forward_simplify env (sign, current) ~passive active in
+          let time2 = Unix.gettimeofday () in
+          forward_simpl_time := !forward_simpl_time +. (time2 -. time1);
+          match res with
+          | None ->
+              given_clause_fullred env goals theorems passive active
+          | Some (sign, current) ->
+              if (sign = Negative) && (is_identity env current) then (
+                debug_print
+                  (lazy (Printf.sprintf "OK!!! %s %s" (string_of_sign sign)
                            (string_of_equality ~env current)));
+                let _, proof, _, _, _ = current in 
+                ParamodulationSuccess (Some proof (* current *), env)
+              ) else (
+                debug_print
+                  (lazy "\n================================================");
+                debug_print (lazy (Printf.sprintf "selected: %s %s"
+                                     (string_of_sign sign)
+                                     (string_of_equality ~env current)));
+
+                let t1 = Unix.gettimeofday () in
+                let new' = infer env sign current active in
+                let t2 = Unix.gettimeofday () in
+                infer_time := !infer_time +. (t2 -. t1);
+
+                let active =
+                  if is_identity env current then active
+                  else
+                    let al, tbl = active in
+                    match sign with
+                    | Negative -> (sign, current)::al, tbl
+                    | Positive ->
+                        al @ [(sign, current)], Indexing.index tbl current
+                in
+                let rec simplify new' active passive =
+                  let t1 = Unix.gettimeofday () in
+                  let new' = forward_simplify_new env new' ~passive active in
+                  let t2 = Unix.gettimeofday () in
+                  forward_simpl_new_time :=
+                    !forward_simpl_new_time +. (t2 -. t1);
+                  let t1 = Unix.gettimeofday () in
+                  let active, passive, newa, retained =
+                    backward_simplify env new' ~passive active in
+                  let t2 = Unix.gettimeofday () in
+                  backward_simpl_time := !backward_simpl_time +. (t2 -. t1);
+                  match newa, retained with
+                  | None, None -> active, passive, new'
+                  | Some (n, p), None
+                  | None, Some (n, p) ->
+                      let nn, np = new' in
+                      simplify (nn @ n, np @ p) active passive
+                  | Some (n, p), Some (rn, rp) ->
+                      let nn, np = new' in
+                      simplify (nn @ n @ rn, np @ p @ rp) active passive
+                in
+                let active, passive, new' = simplify new' active passive in
 
-            let t1 = Unix.gettimeofday () in
-            let new' = infer env sign current active in
-            let t2 = Unix.gettimeofday () in
-            infer_time := !infer_time +. (t2 -. t1);
-
-            let active =
-              if is_identity env current then active
-              else
-                let al, tbl = active in
-                match sign with
-                | Negative -> (sign, current)::al, tbl
-                | Positive -> al @ [(sign, current)], Indexing.index tbl current
-            in
-            let rec simplify new' active passive =
-              let t1 = Unix.gettimeofday () in
-              let new' = forward_simplify_new env new' ~passive active in
-              let t2 = Unix.gettimeofday () in
-              forward_simpl_new_time := !forward_simpl_new_time +. (t2 -. t1);
-              let t1 = Unix.gettimeofday () in
-              let active, passive, newa, retained =
-                backward_simplify env new' ~passive active in
-              let t2 = Unix.gettimeofday () in
-              backward_simpl_time := !backward_simpl_time +. (t2 -. t1);
-              match newa, retained with
-              | None, None -> active, passive, new'
-              | Some (n, p), None
-              | None, Some (n, p) ->
-                  let nn, np = new' in
-                  simplify (nn @ n, np @ p) active passive
-              | Some (n, p), Some (rn, rp) ->
-                  let nn, np = new' in
-                  simplify (nn @ n @ rn, np @ p @ rp) active passive
-            in
-            let active, passive, new' = simplify new' active passive in
-
-            let k = size_of_passive passive in
-            if k < (kept - 1) then
-              processed_clauses := !processed_clauses + (kept - 1 - k);
-            
-            let _ =
-              debug_print (lazy (
-                Printf.sprintf "active:\n%s\n"
-                  (String.concat "\n"
-                     ((List.map
-                         (fun (s, e) -> (string_of_sign s) ^ " " ^
-                            (string_of_equality ~env e)) (fst active))))))
-            in
-            let _ =
-              match new' with
-              | neg, pos ->
-                  debug_print (lazy (
-                    Printf.sprintf "new':\n%s\n"
-                      (String.concat "\n"
-                         ((List.map
-                             (fun e -> "Negative " ^
-                                (string_of_equality ~env e)) neg) @
-                            (List.map
-                               (fun e -> "Positive " ^
-                                  (string_of_equality ~env e)) pos)))))
-            in
-            match contains_empty env new' with
-            | false, _ -> 
-                let passive = add_to_passive passive new' in
+                let k = size_of_passive passive in
+                if k < (kept - 1) then
+                  processed_clauses := !processed_clauses + (kept - 1 - k);
+                
+                let _ =
+                  debug_print
+                    (lazy
+                       (Printf.sprintf "active:\n%s\n"
+                          (String.concat "\n"
+                             ((List.map
+                                 (fun (s, e) -> (string_of_sign s) ^ " " ^
+                                    (string_of_equality ~env e))
+                                 (fst active))))))
+                in
+                let _ =
+                  match new' with
+                  | neg, pos ->
+                      debug_print
+                        (lazy
+                           (Printf.sprintf "new':\n%s\n"
+                              (String.concat "\n"
+                                 ((List.map
+                                     (fun e -> "Negative " ^
+                                        (string_of_equality ~env e)) neg) @
+                                    (List.map
+                                       (fun e -> "Positive " ^
+                                          (string_of_equality ~env e)) pos)))))
+                in
+                match contains_empty env new' with
+                | false, _ -> 
+                    let passive = add_to_passive passive new' in
 (*                 let (_, ns), (_, ps), _ = passive in *)
 (*                 Printf.printf "passive:\n%s\n" *)
 (*                   (String.concat "\n" *)
@@ -1043,15 +1674,21 @@ let rec given_clause_fullred env passive active =
 (*                                      (string_of_equality ~env e)) *)
 (*                            (EqualitySet.elements ps)))); *)
 (*                 print_newline (); *)
-                given_clause_fullred env passive active
-            | true, goal ->
-                ParamodulationSuccess (goal, env)
-          )
+                    given_clause_fullred env goals theorems passive active
+                | true, goal ->
+                    let proof =
+                      match goal with
+                      | Some goal -> let _, proof, _, _, _ = goal in Some proof
+                      | None -> None
+                    in
+                    ParamodulationSuccess (proof (* goal *), env)
+              )
+  with SearchSpaceOver ->
+    ParamodulationFailure
 ;;
 
 
-let given_clause_ref = ref given_clause;;
-
+(* let given_clause_ref = ref given_clause;; *)
 
 let main dbd term metasenv ugraph =
   let module C = Cic in
@@ -1064,9 +1701,9 @@ let main dbd term metasenv ugraph =
   let goal' = List.nth goals 0 in
   let _, metasenv, meta_proof, _ = proof in
   let _, context, goal = CicUtil.lookup_meta goal' metasenv in
-  let equalities, maxm = find_equalities context proof in
-  let library_equalities, maxm =
-    find_library_equalities ~dbd context (proof, goal') (maxm+2)
+  let eq_indexes, equalities, maxm = find_equalities context proof in
+  let lib_eq_uris, library_equalities, maxm =
+    find_library_equalities dbd context (proof, goal') (maxm+2)
   in
   maxmeta := maxm+2; (* TODO ugly!! *)
   let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
@@ -1080,28 +1717,45 @@ let main dbd term metasenv ugraph =
   in
 (*   let new_meta_goal = Cic.Meta (goal', irl) in *)
   let env = (metasenv, context, ugraph) in
+  let theorems = find_library_theorems dbd env (proof, goal') lib_eq_uris in
+  let context_hyp = find_context_hypotheses env eq_indexes in
+  let theorems = context_hyp @ theorems in
+  let _ =
+    debug_print
+      (lazy
+         (Printf.sprintf
+            "Theorems:\n-------------------------------------\n%s\n"
+            (String.concat "\n"
+               (List.map
+                  (fun (t, ty, _) ->
+                     Printf.sprintf
+                       "Term: %s, type: %s" (CicPp.ppterm t) (CicPp.ppterm ty))
+                  theorems))))
+  in
   try
-    let term_equality = equality_of_term new_meta_goal goal in
-    let _, meta_proof, (eq_ty, left, right, ordering), _, _ = term_equality in
-    if is_identity env term_equality then
-      let proof =
-        Cic.Appl [Cic.MutConstruct (* reflexivity *)
-                    (HelmLibraryObjects.Logic.eq_URI, 0, 1, []);
-                  eq_ty; left]
-      in
-      let _ = 
-        Printf.printf "OK, found a proof!\n";
-        let names = names_of_context context in
-        print_endline (PP.pp proof names)
-      in
-      ()
-    else
+    let goal = Inference.BasicProof new_meta_goal, [], goal in
+(*     let term_equality = equality_of_term new_meta_goal goal in *)
+(*     let _, meta_proof, (eq_ty, left, right, ordering), _, _ = term_equality in *)
+(*     if is_identity env term_equality then *)
+(*       let proof = *)
+(*         Cic.Appl [Cic.MutConstruct (\* reflexivity *\) *)
+(*                     (HelmLibraryObjects.Logic.eq_URI, 0, 1, []); *)
+(*                   eq_ty; left] *)
+(*       in *)
+(*       let _ =  *)
+(*         Printf.printf "OK, found a proof!\n"; *)
+(*         let names = names_of_context context in *)
+(*         print_endline (PP.pp proof names) *)
+(*       in *)
+(*       () *)
+(*     else *)
       let equalities =
         let equalities = equalities @ library_equalities in
-        debug_print (lazy (
-          Printf.sprintf "equalities:\n%s\n"
-            (String.concat "\n"
-               (List.map string_of_equality equalities))));
+        debug_print
+          (lazy 
+             (Printf.sprintf "equalities:\n%s\n"
+                (String.concat "\n"
+                   (List.map string_of_equality equalities))));
         debug_print (lazy "SIMPLYFYING EQUALITIES...");
         let rec simpl e others others_simpl =
           let active = others @ others_simpl in
@@ -1130,16 +1784,18 @@ let main dbd term metasenv ugraph =
             let res =
               List.rev (List.map snd (simpl (Positive, hd) others []))
             in
-            debug_print (lazy (
-              Printf.sprintf "equalities AFTER:\n%s\n"
-                (String.concat "\n"
-                   (List.map string_of_equality res))));
+            debug_print
+              (lazy
+                 (Printf.sprintf "equalities AFTER:\n%s\n"
+                    (String.concat "\n"
+                       (List.map string_of_equality res))));
             res
       in
       let active = make_active () in
-      let passive = make_passive [term_equality] equalities in
+      let passive = make_passive [] (* [term_equality] *) equalities in
       Printf.printf "\ncurrent goal: %s\n"
-        (string_of_equality ~env term_equality);
+        (let _, _, g = goal in CicPp.ppterm g);
+(*         (string_of_equality ~env term_equality); *)
       Printf.printf "\ncontext:\n%s\n" (PP.ppcontext context);
       Printf.printf "\nmetasenv:\n%s\n" (print_metasenv metasenv);
       Printf.printf "\nequalities:\n%s\n"
@@ -1153,28 +1809,22 @@ let main dbd term metasenv ugraph =
       start_time := Unix.gettimeofday ();
       let res =
         (if !use_fullred then given_clause_fullred else given_clause)
-          env passive active
+          env [0, [goal]] theorems passive active
       in
       let finish = Unix.gettimeofday () in
       let _ =
         match res with
         | ParamodulationFailure ->
             Printf.printf "NO proof found! :-(\n\n"
-        | ParamodulationSuccess (Some goal, env) ->
-            let proof = Inference.build_proof_term goal in
-(*             let proof = *)
-(* (\*               let p = CicSubstitution.lift 1 proof in *\) *)
-(*               let rec repl i = function *)
-(*                 | C.Meta _ -> C.Rel i *)
-(*                 | C.Appl l -> C.Appl (List.map (repl i) l) *)
-(*                 | C.Prod (n, s, t) -> C.Prod (n, s, repl (i+1) t) *)
-(*                 | C.Lambda (n, s, t) -> C.Lambda (n, s, repl (i+1) t) *)
-(*                 | t -> t *)
-(*               in *)
-(*               let p = repl 1 proof in *)
-(*               p *)
-(* (\*               C.Lambda (C.Anonymous, C.Rel 9, p) *\) *)
-(*             in *)
+        | ParamodulationSuccess (Some proof (* goal *), env) ->
+(*             let proof = Inference.build_proof_term goal in          *)
+            let proof = Inference.build_proof_term proof in
+            Printf.printf "OK, found a proof!\n";
+            (* REMEMBER: we have to instantiate meta_proof, we should use
+               apply  the "apply" tactic to proof and status 
+            *)
+            let names = names_of_context context in
+            print_endline (PP.pp proof names);
             let newmetasenv =
               List.fold_left
                 (fun m (_, _, _, menv, _) -> m @ menv) metasenv equalities
@@ -1238,108 +1888,124 @@ let main dbd term metasenv ugraph =
 ;;
 
 
-let saturate dbd ?(full=false) ?(depth=0) ?(width=0) (proof, goal) =
+let default_depth = !maxdepth
+and default_width = !maxwidth;;
+
+let saturate
+    dbd ?(full=false) ?(depth=default_depth) ?(width=default_width) status = 
   let module C = Cic in
   maxmeta := 0;
+  maxdepth := depth;
+  maxwidth := width;
+  let proof, goal = status in
   let goal' = goal in
   let uri, metasenv, meta_proof, term_to_prove = proof in
   let _, context, goal = CicUtil.lookup_meta goal' metasenv in
-  let equalities, maxm = find_equalities context proof in
+  let eq_indexes, equalities, maxm = find_equalities context proof in
   let new_meta_goal, metasenv, type_of_goal =
     let irl =
       CicMkImplicit.identity_relocation_list_for_metavariable context in
     let _, context, ty = CicUtil.lookup_meta goal' metasenv in
-    debug_print (lazy (Printf.sprintf "\n\nTIPO DEL GOAL: %s\n" (CicPp.ppterm ty)));
+    debug_print
+      (lazy (Printf.sprintf "\n\nTIPO DEL GOAL: %s\n" (CicPp.ppterm ty)));
     Cic.Meta (maxm+1, irl),
     (maxm+1, context, ty)::metasenv,
     ty
   in
   let ugraph = CicUniv.empty_ugraph in
   let env = (metasenv, context, ugraph) in
-(*   try *)
-  let term_equality = equality_of_term new_meta_goal goal in
+  let goal = Inference.BasicProof new_meta_goal, [], goal in
   let res, time = 
-    if is_identity env term_equality then
-      let w, _, (eq_ty, left, right, o), m, a = term_equality in
-      let proof =
-        Cic.Appl [Cic.MutConstruct (* reflexivity *)
-                    (HelmLibraryObjects.Logic.eq_URI, 0, 1, []);
-                  eq_ty; left]
-      in
-      (ParamodulationSuccess
-         (Some (0, Inference.BasicProof proof,
-                (eq_ty, left, right, o), m, a), env), 0.)
-    else
-      let library_equalities, maxm =
-        find_library_equalities ~dbd context (proof, goal') (maxm+2)
+    let lib_eq_uris, library_equalities, maxm =
+      find_library_equalities dbd context (proof, goal') (maxm+2)
+    in
+    maxmeta := maxm+2;
+    let equalities =
+      let equalities = equalities @ library_equalities in
+      debug_print
+        (lazy
+           (Printf.sprintf "equalities:\n%s\n"
+              (String.concat "\n"
+                 (List.map string_of_equality equalities))));
+      debug_print (lazy "SIMPLYFYING EQUALITIES...");
+      let rec simpl e others others_simpl =
+        let active = others @ others_simpl in
+        let tbl =
+          List.fold_left
+            (fun t (_, e) -> Indexing.index t e)
+            (Indexing.empty_table ()) active
+        in
+        let res = forward_simplify env e (active, tbl) in
+        match others with
+        | hd::tl -> (
+            match res with
+            | None -> simpl hd tl others_simpl
+            | Some e -> simpl hd tl (e::others_simpl)
+          )
+        | [] -> (
+            match res with
+            | None -> others_simpl
+            | Some e -> e::others_simpl
+          )
       in
-      maxmeta := maxm+2;
-      let equalities =
-        let equalities = equalities @ library_equalities in
-        debug_print (lazy (
-          Printf.sprintf "equalities:\n%s\n"
-            (String.concat "\n"
-               (List.map string_of_equality equalities))));
-        debug_print (lazy "SIMPLYFYING EQUALITIES...");
-        let rec simpl e others others_simpl =
-          let active = others @ others_simpl in
-          let tbl =
-            List.fold_left
-              (fun t (_, e) -> Indexing.index t e)
-              (Indexing.empty_table ()) active
+      match equalities with
+      | [] -> []
+      | hd::tl ->
+          let others = List.map (fun e -> (Positive, e)) tl in
+          let res =
+            List.rev (List.map snd (simpl (Positive, hd) others []))
           in
-          let res = forward_simplify env e (active, tbl) in
-          match others with
-          | hd::tl -> (
-              match res with
-              | None -> simpl hd tl others_simpl
-              | Some e -> simpl hd tl (e::others_simpl)
-            )
-          | [] -> (
-              match res with
-              | None -> others_simpl
-              | Some e -> e::others_simpl
-            )
+          debug_print
+            (lazy
+               (Printf.sprintf "equalities AFTER:\n%s\n"
+                  (String.concat "\n"
+                     (List.map string_of_equality res))));
+          res
+    in
+    let theorems =
+      if full then
+        let thms = find_library_theorems dbd env (proof, goal') lib_eq_uris in
+        let context_hyp = find_context_hypotheses env eq_indexes in
+        context_hyp @ thms
+      else
+        let refl_equal =
+          UriManager.uri_of_string "cic:/Coq/Init/Logic/eq.ind#xpointer(1/1/1)"
         in
-        match equalities with
-        | [] -> []
-        | hd::tl ->
-            let others = List.map (fun e -> (Positive, e)) tl in
-            let res =
-              List.rev (List.map snd (simpl (Positive, hd) others []))
-            in
-            debug_print (lazy (
-              Printf.sprintf "equalities AFTER:\n%s\n"
-                (String.concat "\n"
-                   (List.map string_of_equality res))));
-            res
-      in      
-      let active = make_active () in
-      let passive = make_passive [term_equality] equalities in
-      let start = Unix.gettimeofday () in
-      let res = given_clause_fullred env passive active in
-      let finish = Unix.gettimeofday () in
-      (res, finish -. start)
+        let t = CicUtil.term_of_uri refl_equal in
+        let ty, _ = CicTypeChecker.type_of_aux' [] [] t CicUniv.empty_ugraph in
+        [(t, ty, [])]
+    in
+    let _ =
+      debug_print
+        (lazy
+           (Printf.sprintf
+              "Theorems:\n-------------------------------------\n%s\n"
+              (String.concat "\n"
+                 (List.map
+                    (fun (t, ty, _) ->
+                       Printf.sprintf
+                         "Term: %s, type: %s"
+                         (CicPp.ppterm t) (CicPp.ppterm ty))
+                    theorems))))
+    in
+    let active = make_active () in
+    let passive = make_passive [(* term_equality *)] equalities in
+    let start = Unix.gettimeofday () in
+    let res = given_clause_fullred env [0, [goal]] theorems passive active in
+    let finish = Unix.gettimeofday () in
+    (res, finish -. start)
   in
   match res with
-  | ParamodulationSuccess (Some goal, env) ->
+  | ParamodulationSuccess (Some proof (* goal *), env) ->
       debug_print (lazy "OK, found a proof!");
-      let proof = Inference.build_proof_term goal in         
+(*       let proof = Inference.build_proof_term goal in          *)
+      let proof = Inference.build_proof_term proof in
       let names = names_of_context context in
       let newmetasenv =
         let i1 =
           match new_meta_goal with
           | C.Meta (i, _) -> i | _ -> assert false
         in
-(*           let i2 = *)
-(*             match meta_proof with *)
-(*             | C.Meta (i, _) -> i *)
-(*             | t -> *)
-(*                 Printf.printf "\nHMMM!!! meta_proof: %s\ngoal': %s" *)
-(*                   (CicPp.pp meta_proof names) (string_of_int goal'); *)
-(*                 print_newline (); *)
-(*                 assert false *)
-(*           in *)
         List.filter (fun (i, _, _) -> i <> i1 && i <> goal') metasenv
       in
       let newstatus =
@@ -1348,13 +2014,14 @@ let saturate dbd ?(full=false) ?(depth=0) ?(width=0) (proof, goal) =
             CicTypeChecker.type_of_aux' newmetasenv context proof ugraph
           in
           debug_print (lazy (CicPp.pp proof [](* names *)));
-          debug_print (lazy
-            (Printf.sprintf
-               "\nGOAL was: %s\nPROOF has type: %s\nconvertible?: %s\n"
-               (CicPp.pp type_of_goal names) (CicPp.pp ty names)
-               (string_of_bool
-                  (fst (CicReduction.are_convertible
-                          context type_of_goal ty ug)))));
+          debug_print
+            (lazy
+               (Printf.sprintf
+                  "\nGOAL was: %s\nPROOF has type: %s\nconvertible?: %s\n"
+                  (CicPp.pp type_of_goal names) (CicPp.pp ty names)
+                  (string_of_bool
+                     (fst (CicReduction.are_convertible
+                             context type_of_goal ty ug)))));
           let equality_for_replace i t1 =
             match t1 with
             | C.Meta (n, _) -> n = i
@@ -1366,13 +2033,14 @@ let saturate dbd ?(full=false) ?(depth=0) ?(width=0) (proof, goal) =
               ~what:[goal'] ~with_what:[proof]
               ~where:meta_proof
           in
-          debug_print (lazy (
-            Printf.sprintf "status:\n%s\n%s\n%s\n%s\n"
-              (match uri with Some uri -> UriManager.string_of_uri uri
-               | None -> "")
-              (print_metasenv newmetasenv)
-              (CicPp.pp real_proof [](* names *))
-              (CicPp.pp term_to_prove names)));
+          debug_print
+            (lazy
+               (Printf.sprintf "status:\n%s\n%s\n%s\n%s\n"
+                  (match uri with Some uri -> UriManager.string_of_uri uri
+                   | None -> "")
+                  (print_metasenv newmetasenv)
+                  (CicPp.pp real_proof [](* names *))
+                  (CicPp.pp term_to_prove names)));
           ((uri, newmetasenv, real_proof, term_to_prove), [])
         with CicTypeChecker.TypeCheckerFailure _ ->
           debug_print (lazy "THE PROOF DOESN'T TYPECHECK!!!");
@@ -1384,11 +2052,8 @@ let saturate dbd ?(full=false) ?(depth=0) ?(width=0) (proof, goal) =
       newstatus          
   | _ ->
       raise (ProofEngineTypes.Fail "NO proof found")
-(*   with e -> *)
-(*     raise (Failure "saturation failed") *)
 ;;
 
-
 (* dummy function called within matita to trigger linkage *)
 let init () = ();;
 
@@ -1398,3 +2063,4 @@ if connect_to_auto then (
   AutoTactic.paramodulation_tactic := saturate;
   AutoTactic.term_is_equality := Inference.term_is_equality;
 );;
+