]> matita.cs.unibo.it Git - helm.git/blob - helm/software/components/ng_paramodulation/superposition.ml
Fixed conflicts due to problem when merging with UEQ implementation
[helm.git] / helm / software / components / ng_paramodulation / superposition.ml
1 (*
2     ||M||  This file is part of HELM, an Hypertextual, Electronic        
3     ||A||  Library of Mathematics, developed at the Computer Science     
4     ||T||  Department, University of Bologna, Italy.                     
5     ||I||                                                                
6     ||T||  HELM is free software; you can redistribute it and/or         
7     ||A||  modify it under the terms of the GNU General Public License   
8     \   /  version 2 or (at your option) any later version.      
9      \ /   This software is distributed as is, NO WARRANTY.     
10       V_______________________________________________________________ *)
11
12 (* $Id: index.mli 9822 2009-06-03 15:37:06Z tassi $ *)
13
14 module Superposition (B : Orderings.Blob) = 
15   struct
16     module IDX = Index.Index(B)
17     module Unif = FoUnif.Founif(B)
18     module Subst = FoSubst 
19     module Order = B
20     module Utils = FoUtils.Utils(B)
21     module Pp = Pp.Pp(B)
22     
23     exception Success of B.t Terms.bag * int * B.t Terms.clause
24
25     let debug s = prerr_endline s;;
26     let debug _ = ();;
27     let enable = true;;
28
29     let rec list_first f = function
30       | [] -> None
31       | x::tl -> match f x with Some _ as x -> x | _ -> list_first f tl
32     ;;
33
34     let first_position pos ctx t f =
35       let inject_pos pos ctx = function
36         | None -> None
37         | Some (a,b,c,d) -> Some(ctx a,b,c,d,pos)
38       in
39       let rec aux pos ctx = function
40       | Terms.Leaf _ as t -> inject_pos pos ctx (f t)
41       | Terms.Var _ -> None
42       | Terms.Node l as t->
43           match f t with
44           | Some _ as x -> inject_pos pos ctx x
45           | None ->
46               let rec first pre post = function
47                 | [] -> None
48                 | t :: tl -> 
49                      let newctx = fun x -> ctx (Terms.Node (pre@[x]@post)) in
50                      match aux (List.length pre :: pos) newctx t with
51                      | Some _ as x -> x
52                      | None -> 
53                          if post = [] then None (* tl is also empty *)
54                          else first (pre @ [t]) (List.tl post) tl
55               in
56                 first [] (List.tl l) l 
57       in
58         aux pos ctx t
59     ;;
60                                      
61     let all_positions pos ctx t f =
62       let rec aux pos ctx = function
63       | Terms.Leaf _ as t -> f t pos ctx 
64       | Terms.Var _ -> []
65       | Terms.Node l as t-> 
66           let acc, _, _ = 
67             List.fold_left
68             (fun (acc,pre,post) t -> (* Invariant: pre @ [t] @ post = l *)
69                 let newctx = fun x -> ctx (Terms.Node (pre@[x]@post)) in
70                 let acc = aux (List.length pre :: pos) newctx t @ acc in
71                 if post = [] then acc, l, []
72                 else acc, pre @ [t], List.tl post)
73              (f t pos ctx, [], List.tl l) l
74           in
75            acc
76       in
77         aux pos ctx t
78     ;;
79
80     let parallel_positions bag pos ctx id t f =
81       let rec aux bag pos ctx id = function
82       | Terms.Leaf _ as t -> f bag t pos ctx id
83       | Terms.Var _ as t -> bag,t,id
84       | Terms.Node (hd::l) as t->
85           let bag,t,id1 = f bag t pos ctx id in
86             if id = id1 then
87               let bag, l, _, id = 
88                 List.fold_left
89                   (fun (bag,pre,post,id) t ->
90                      let newctx = fun x -> ctx (Terms.Node (pre@[x]@post)) in
91                      let newpos = (List.length pre)::pos in
92                      let bag,newt,id = aux bag newpos newctx id t in
93                        if post = [] then bag, pre@[newt], [], id
94                        else bag, pre @ [newt], List.tl post, id)
95                   (bag, [hd], List.tl l, id) l
96               in
97                 bag, Terms.Node l, id
98             else bag,t,id1
99       | _ -> assert false
100       in
101         aux bag pos ctx id t
102     ;;
103     
104     let build_clause bag filter rule t subst id id2 pos dir =
105       let proof = Terms.Step(rule,id,id2,dir,pos,subst) in
106       let t = Subst.apply_subst subst t in
107       if filter subst then
108         let literal = 
109           match t with
110           | Terms.Node [ Terms.Leaf eq ; ty; l; r ] when B.eq B.eqP eq ->
111                let o = Order.compare_terms l r in
112                Terms.Equation (l, r, ty, o)
113           | t -> Terms.Predicate t
114         in
115         let bag, uc = 
116           Terms.add_to_bag (0, literal, Terms.vars_of_term t, proof) bag
117         in
118         Some (bag, uc)
119       else
120         ((*prerr_endline ("Filtering: " ^ Pp.pp_foterm t);*)None)
121     ;;
122     let prof_build_clause = HExtlib.profile ~enable "build_clause";;
123     let build_clause bag filter rule t subst id id2 pos x =
124       prof_build_clause.HExtlib.profile (build_clause bag filter rule t subst id id2 pos) x
125     ;;
126       
127     
128     (* ============ simplification ================= *)
129     let prof_demod_u = HExtlib.profile ~enable "demod.unify";;
130     let prof_demod_r = HExtlib.profile ~enable "demod.retrieve_generalizations";;
131     let prof_demod_o = HExtlib.profile ~enable "demod.compare_terms";;
132     let prof_demod_s = HExtlib.profile ~enable "demod.apply_subst";;
133
134     let demod table varlist subterm =
135       let cands = 
136         prof_demod_r.HExtlib.profile 
137          (IDX.DT.retrieve_generalizations table) subterm 
138       in
139       list_first
140         (fun (dir, is_pos, pos, (id,nlit,plit,vl,_)) ->
141            match lit with
142            | Terms.Predicate _ -> assert false
143            | Terms.Equation (l,r,_,o) ->
144                let side, newside = if dir=Terms.Left2Right then l,r else r,l in
145                try 
146                  let subst =
147                    prof_demod_u.HExtlib.profile 
148                      (Unif.unification (* (varlist@vl) *) varlist subterm) side 
149                  in 
150                  let side = 
151                    prof_demod_s.HExtlib.profile 
152                      (Subst.apply_subst subst) side 
153                  in
154                  let newside = 
155                    prof_demod_s.HExtlib.profile 
156                      (Subst.apply_subst subst) newside 
157                  in
158                  if o = Terms.Incomparable || o = Terms.Invertible then
159                    let o = 
160                      prof_demod_o.HExtlib.profile 
161                       (Order.compare_terms newside) side in
162                    (* Riazanov, pp. 45 (ii) *)
163                    if o = Terms.Lt then
164                      Some (newside, subst, id, dir)
165                    else 
166                      ((*prerr_endline ("Filtering: " ^ 
167                         Pp.pp_foterm side ^ " =(< || =)" ^ 
168                         Pp.pp_foterm newside ^ " coming from " ^ 
169                         Pp.pp_clause uc );*)None)
170                  else
171                    Some (newside, subst, id, dir)
172                with FoUnif.UnificationFailure _ -> None)
173         (IDX.ClauseSet.elements cands)
174     ;;
175     let prof_demod = HExtlib.profile ~enable "demod";;
176     let demod table varlist x =
177       prof_demod.HExtlib.profile (demod table varlist) x
178     ;;
179
180     let demodulate_once_old ~jump_to_right bag (id, literal, vl, pr) table =
181       match literal with
182       | Terms.Predicate t -> assert false
183       | Terms.Equation (l,r,ty,_) ->
184         let left_position = if jump_to_right then None else
185           first_position [2]
186             (fun x -> Terms.Node [ Terms.Leaf B.eqP; ty; x; r ]) l
187             (demod table vl)
188         in
189         match left_position with
190           | Some (newt, subst, id2, dir, pos) ->
191               begin
192                 match build_clause bag (fun _ -> true) Terms.Demodulation 
193                   newt subst id id2 pos dir
194                 with
195                   | None -> assert false
196                   | Some x -> Some (x,false)
197               end
198           | None ->
199               match first_position
200                 [3] (fun x -> Terms.Node [ Terms.Leaf B.eqP; ty; l; x ]) r
201                 (demod table vl)
202               with
203                 | None -> None
204                 | Some (newt, subst, id2, dir, pos) ->
205                     match build_clause bag (fun _ -> true)
206                       Terms.Demodulation newt subst id id2 pos dir
207                     with
208                         | None -> assert false
209                         | Some x -> Some (x,true)
210     ;;
211
212     let parallel_demod table vl bag t pos ctx id =
213       match demod table vl t with
214         | None -> (bag,t,id)
215         | Some (newside, subst, id2, dir) ->
216             match build_clause bag (fun _ -> true)
217               Terms.Demodulation (ctx newside) subst id id2 pos dir
218             with
219               | None -> assert false
220               | Some (bag,(id,_,_,_)) ->
221                     (bag,newside,id)
222     ;;
223
224     let demodulate_once ~jump_to_right bag (id, literal, vl, pr) table =
225       match literal with
226       | Terms.Predicate t -> assert false
227       | Terms.Equation (l,r,ty,_) ->
228           let bag,l,id1 = if jump_to_right then (bag,l,id) else
229             parallel_positions bag [2]
230               (fun x -> Terms.Node [ Terms.Leaf B.eqP; ty; x; r ]) id l
231               (parallel_demod table vl)
232           in
233           let jump_to_right = id1 = id in
234           let bag,r,id2 =
235             parallel_positions bag [3]
236               (fun x -> Terms.Node [ Terms.Leaf B.eqP; ty; l; x ]) id1 r
237               (parallel_demod table vl)
238           in
239             if id = id2 then None
240             else
241               let cl,_,_ = Terms.get_from_bag id2 bag in
242                 Some ((bag,cl),jump_to_right)
243     ;;
244
245     let rec demodulate ~jump_to_right bag clause table =
246       match demodulate_once ~jump_to_right bag clause table with
247       | None -> bag, clause
248       | Some ((bag, clause),r) -> demodulate ~jump_to_right:r
249           bag clause table
250     ;;
251
252     let rec demodulate_old ~jump_to_right bag clause table =
253       match demodulate_once_old ~jump_to_right bag clause table with
254         | None -> bag, clause
255         | Some ((bag, clause),r) -> demodulate_old ~jump_to_right:r
256           bag clause table
257     ;;
258
259     let are_alpha_eq cl1 cl2 =
260       let get_term (_,lit,_,_) =
261         match lit with
262           | Terms.Predicate _ -> assert false
263           | Terms.Equation (l,r,ty,_) ->
264               Terms.Node [Terms.Leaf B.eqP; ty; l ; r]
265       in
266         try ignore(Unif.alpha_eq (get_term cl1) (get_term cl2)) ; true
267         with FoUnif.UnificationFailure _ -> false
268     ;;
269
270     let demodulate bag clause table =
271 (*      let (bag1,c1), (_,c2) =*)
272          demodulate ~jump_to_right:false bag clause table 
273 (*         demodulate_old ~jump_to_right:false bag clause table *)
274 (*      in
275         if are_alpha_eq c1 c2 then bag1,c1
276         else begin
277           prerr_endline (Pp.pp_clause c1);
278           prerr_endline (Pp.pp_clause c2);
279           prerr_endline "Bag :";
280           prerr_endline (Pp.pp_bag bag1);
281           assert false
282         end*)
283     ;;
284     let prof_demodulate = HExtlib.profile ~enable "demodulate";;
285     let demodulate bag clause x =
286       prof_demodulate.HExtlib.profile (demodulate bag clause) x
287     ;;
288
289     (* move away *)
290     let is_identity_clause ~unify = function
291       | _, Terms.Equation (_,_,_,Terms.Eq), _, _ -> true
292       | _, Terms.Equation (l,r,_,_), vl, proof when unify ->
293           (try ignore(Unif.unification (* vl *) [] l r); true
294           with FoUnif.UnificationFailure _ -> false)
295       | _, Terms.Equation (_,_,_,_), _, _ -> false
296       | _, Terms.Predicate _, _, _ -> assert false          
297     ;;
298
299     let build_new_clause bag maxvar filter rule t subst id id2 pos dir =
300       let maxvar, _vl, subst = Utils.relocate maxvar (Terms.vars_of_term
301       (Subst.apply_subst subst t)) subst in
302       match build_clause bag filter rule t subst id id2 pos dir with
303       | Some (bag, c) -> Some ((bag, maxvar), c)
304       | None -> None
305     ;;
306     let prof_build_new_clause = HExtlib.profile ~enable "build_new_clause";;
307     let build_new_clause bag maxvar filter rule t subst id id2 pos x =
308       prof_build_new_clause.HExtlib.profile (build_new_clause bag maxvar filter
309       rule t subst id id2 pos) x
310     ;;
311
312     let fold_build_new_clause bag maxvar id rule filter res =
313       let (bag, maxvar), res =
314        HExtlib.filter_map_acc 
315          (fun (bag, maxvar) (t,subst,id2,pos,dir) ->
316             build_new_clause bag maxvar filter rule t subst id id2 pos dir)
317          (bag, maxvar) res
318       in
319        bag, maxvar, res
320     ;;
321
322     
323     let rewrite_eq ~unify l r ty vl table =
324       let retrieve = if unify then IDX.DT.retrieve_unifiables
325       else IDX.DT.retrieve_generalizations in
326       let lcands = retrieve table l in
327       let rcands = retrieve table r in
328       let f b c = 
329         let id, dir, l, r, vl = 
330           match c with
331             | (d, (id,Terms.Equation (l,r,ty,_),vl,_))-> id, d, l, r, vl
332             |_ -> assert false 
333         in 
334         let reverse = (dir = Terms.Left2Right) = b in
335         let l, r, proof_rewrite_dir = if reverse then l,r,Terms.Left2Right
336         else r,l, Terms.Right2Left in
337           (id,proof_rewrite_dir,Terms.Node [ Terms.Leaf B.eqP; ty; l; r ], vl)
338       in
339       let cands1 = List.map (f true) (IDX.ClauseSet.elements lcands) in
340       let cands2 = List.map (f false) (IDX.ClauseSet.elements rcands) in
341       let t = Terms.Node [ Terms.Leaf B.eqP; ty; l; r ] in
342       let locked_vars = if unify then [] else vl in
343       let rec aux = function
344         | [] -> None
345         | (id2,dir,c,vl1)::tl ->
346             try
347               let subst = Unif.unification (* (vl@vl1) *) locked_vars c t in
348               Some (id2, dir, subst)
349             with FoUnif.UnificationFailure _ -> aux tl
350       in
351         aux (cands1 @ cands2)
352     ;;
353
354     let is_subsumed ~unify bag maxvar (id, lit, vl, _) table =
355       match lit with
356       | Terms.Predicate _ -> assert false
357       | Terms.Equation (l,r,ty,_) -> 
358           match rewrite_eq ~unify l r ty vl table with
359             | None -> None
360             | Some (id2, dir, subst) ->
361                 let id_t = Terms.Node [ Terms.Leaf B.eqP; ty; r; r ] in
362                   build_new_clause bag maxvar (fun _ -> true)
363                   Terms.Superposition id_t subst id id2 [2] dir 
364     ;;
365     let prof_is_subsumed = HExtlib.profile ~enable "is_subsumed";;
366     let is_subsumed ~unify bag maxvar c x =
367       prof_is_subsumed.HExtlib.profile (is_subsumed ~unify bag maxvar c) x
368     ;;
369     (* id refers to a clause proving contextl l = contextr r *)
370
371     let rec deep_eq ~unify l r ty pos contextl contextr table acc =
372       match acc with 
373       | None -> None
374       | Some(bag,maxvar,(id,lit,vl,p),subst) -> 
375           let l = Subst.apply_subst subst l in 
376           let r = Subst.apply_subst subst r in 
377             try 
378               let subst1 = Unif.unification (* vl *) [] l r in
379               let lit = 
380                 match lit with Terms.Predicate _ -> assert false
381                   | Terms.Equation (l,r,ty,o) -> 
382                      Terms.Equation (FoSubst.apply_subst subst1 l,
383                        FoSubst.apply_subst subst1 r, ty, o)
384               in
385                 Some(bag,maxvar,(id,lit,vl,p),Subst.concat subst1 subst)
386             with FoUnif.UnificationFailure _ -> 
387               match rewrite_eq ~unify l r ty vl table with
388               | Some (id2, dir, subst1) ->
389                   let newsubst = Subst.concat subst1 subst in
390                   let id_t = 
391                     FoSubst.apply_subst newsubst
392                       (Terms.Node[Terms.Leaf B.eqP;ty;contextl r;contextr r]) 
393                   in
394                     (match 
395                       build_new_clause bag maxvar (fun _ -> true)
396                         Terms.Superposition id_t 
397                         subst1 id id2 (pos@[2]) dir 
398                     with
399                     | Some ((bag, maxvar), c) -> 
400                         Some(bag,maxvar,c,newsubst)
401                     | None -> assert false)
402               | None ->
403                   match l,r with 
404                   | Terms.Node (a::la), Terms.Node (b::lb) when 
405                       a = b && List.length la = List.length lb ->
406                       let acc,_,_,_ =
407                         List.fold_left2 
408                           (fun (acc,pre,postl,postr) a b -> 
409                              let newcl = 
410                               fun x -> contextl(Terms.Node (pre@(x::postl))) in
411                              let newcr = 
412                               fun x -> contextr(Terms.Node (pre@(x::postr))) in
413                              let newpos = List.length pre::pos in
414                              let footail l =
415                                if l = [] then [] else List.tl l in
416                                (deep_eq ~unify a b ty 
417                                  newpos newcl newcr table acc,pre@[b],
418                                  footail postl, footail postr))
419                           (acc,[a],List.tl la,List.tl lb) la lb
420                       in acc
421                   | _,_ -> None
422     ;;
423     let prof_deep_eq = HExtlib.profile ~enable "deep_eq";;
424     let deep_eq ~unify l r ty pos contextl contextr table x =
425       prof_deep_eq.HExtlib.profile (deep_eq ~unify l r ty pos contextl contextr table) x
426     ;;
427
428     let rec orphan_murder bag acc i =
429       match Terms.get_from_bag i bag with
430         | (_,_,_,Terms.Exact _),discarded,_ -> (discarded,acc)
431         | (_,_,_,Terms.Step (_,i1,i2,_,_,_)),true,_ -> (true,acc)
432         | (_,_,_,Terms.Step (_,i1,i2,_,_,_)),false,_ ->
433             if (List.mem i acc) then (false,acc)
434             else match orphan_murder bag acc i1 with
435               | (true,acc) -> (true,acc)
436               | (false,acc) ->
437                   let (res,acc) = orphan_murder bag acc i2 in
438                   if res then res,acc else res,i::acc
439     ;;
440
441     let orphan_murder bag actives cl =
442       let (id,_,_,_) = cl in
443       let actives = List.map (fun (i,_,_,_) -> i) actives in
444       let (res,_) = orphan_murder bag actives id in
445         if res then debug "Orphan murdered"; res
446     ;;
447     let prof_orphan_murder = HExtlib.profile ~enable "orphan_murder";;
448     let orphan_murder bag actives x =
449       prof_orphan_murder.HExtlib.profile (orphan_murder bag actives) x
450     ;;
451
452     (* demodulate and check for subsumption *)
453     let simplify table maxvar bag clause = 
454       if is_identity_clause ~unify:false clause then bag,None
455       (* else if orphan_murder bag actives clause then bag,None *)
456       else let bag, clause = demodulate bag clause table in
457       if is_identity_clause ~unify:false clause then bag,None
458       else
459         match is_subsumed ~unify:false bag maxvar clause table with
460           | None -> bag, Some clause
461           | Some _ -> bag, None
462     ;;
463
464     let simplify table maxvar bag clause =
465       match simplify table maxvar bag clause with
466         | bag, None ->
467             let (id,_,_,_) = clause in
468             let (_,_,iter) = Terms.get_from_bag id bag in
469             Terms.replace_in_bag (clause,true,iter) bag, None
470         | bag, Some clause -> bag, Some clause
471     (*let (id,_,_,_) = clause in
472             if orphan_murder bag clause then
473               Terms.M.add id (clause,true) bag, Some clause
474             else bag, Some clause*)
475     ;;
476     let prof_simplify = HExtlib.profile ~enable "simplify";;
477     let simplify table maxvar bag x =
478       prof_simplify.HExtlib.profile (simplify table maxvar bag ) x
479     ;;
480
481     let one_pass_simplification new_clause (alist,atable) bag maxvar =
482       match simplify atable maxvar bag new_clause with
483         | bag,None -> bag,None (* new_clause has been discarded *)
484         | bag,(Some clause) ->
485             let ctable = IDX.index_clause IDX.DT.empty clause in
486             let bag, alist, atable = 
487               List.fold_left 
488                 (fun (bag, alist, atable) c ->
489                    match simplify ctable maxvar bag c with
490                      |bag,None -> (bag,alist,atable)
491                         (* an active clause as been discarded *)
492                      |bag,Some c1 ->
493                         bag, c :: alist, IDX.index_clause atable c)
494                 (bag,[],IDX.DT.empty) alist
495             in
496               bag, Some (clause, (alist,atable))
497     ;;
498     let prof_one_pass_simplification = HExtlib.profile ~enable "one_pass_simplification";;
499     let one_pass_simplification new_clause t bag x =
500       prof_one_pass_simplification.HExtlib.profile (one_pass_simplification new_clause t bag ) x
501     ;;
502
503     let simplification_step ~new_cl cl (alist,atable) bag maxvar new_clause =
504       let atable1 =
505         if new_cl then atable else
506         IDX.index_clause atable cl
507       in
508         (* Simplification of new_clause with :      *
509          * - actives and cl if new_clause is not cl *
510          * - only actives otherwise                 *)
511         match
512           simplify atable1 maxvar bag new_clause with
513           | bag,None -> bag,(Some cl, None) (* new_clause has been discarded *)
514           | bag,Some clause ->
515               (* Simplification of each active clause with clause *
516                * which is the simplified form of new_clause       *)
517               let ctable = IDX.index_clause IDX.DT.empty clause in
518               let bag, newa, alist, atable = 
519                 List.fold_left 
520                   (fun (bag, newa, alist, atable) c ->
521                      match simplify ctable maxvar bag c with
522                        |bag,None -> (bag, newa, alist, atable)
523                           (* an active clause as been discarded *)
524                        |bag,Some c1 ->
525                             if (c1 == c) then 
526                               bag, newa, c :: alist,
527                             IDX.index_clause atable c
528                             else
529                               bag, c1 :: newa, alist, atable)                  
530                   (bag,[],[],IDX.DT.empty) alist
531               in
532                 if new_cl then
533                   bag, (Some cl, Some (clause, (alist,atable), newa))
534                 else
535                   (* if new_clause is not cl, we simplify cl with clause *)
536                   match simplify ctable maxvar bag cl with
537                     | bag,None ->
538                         (* cl has been discarded *)
539                         bag,(None, Some (clause, (alist,atable), newa))
540                     | bag,Some cl1 ->
541                         bag,(Some cl1, Some (clause, (alist,atable), newa))
542     ;;
543     let prof_simplification_step = HExtlib.profile ~enable "simplification_step";;
544     let simplification_step ~new_cl cl (alist,atable) bag maxvar x =
545       prof_simplification_step.HExtlib.profile (simplification_step ~new_cl cl (alist,atable) bag maxvar) x
546     ;;
547
548     let keep_simplified cl (alist,atable) bag maxvar =
549       let rec keep_simplified_aux ~new_cl cl (alist,atable) bag newc =
550         if new_cl then
551           match simplification_step ~new_cl cl (alist,atable) bag maxvar cl with
552             | _,(None, _) -> assert false
553             | bag,(Some _, None) -> bag,None
554             | bag,(Some _, Some (clause, (alist,atable), newa)) ->
555                 keep_simplified_aux ~new_cl:(cl!=clause) clause (alist,atable)
556                   bag (newa@newc)
557         else
558           match newc with
559             | [] -> bag, Some (cl, (alist,atable))
560             | hd::tl ->
561                 match simplification_step ~new_cl cl
562                   (alist,atable) bag maxvar hd with
563                   | _,(None,None) -> assert false
564                   | bag,(Some _,None) ->
565                       keep_simplified_aux ~new_cl cl (alist,atable) bag tl
566                   | bag,(None, Some _) -> bag,None
567                   | bag,(Some cl1, Some (clause, (alist,atable), newa)) ->
568                       let alist,atable =
569                         (clause::alist, IDX.index_clause atable clause)
570                       in
571                         keep_simplified_aux ~new_cl:(cl!=cl1) cl1 (alist,atable)
572                           bag (newa@tl)
573       in
574         keep_simplified_aux ~new_cl:true cl (alist,atable) bag []
575     ;;
576     let prof_keep_simplified = HExtlib.profile ~enable "keep_simplified";;
577     let keep_simplified cl t bag x =
578       prof_keep_simplified.HExtlib.profile (keep_simplified cl t bag) x
579     ;;
580
581     (* this is like simplify but raises Success *)
582     let simplify_goal ~no_demod maxvar table bag g_actives clause = 
583       let bag, clause = 
584         if no_demod then bag, clause else demodulate bag clause table 
585       in
586       if List.exists (are_alpha_eq clause) g_actives then None else
587       if (is_identity_clause ~unify:true clause)
588       then raise (Success (bag, maxvar, clause))
589       else   
590         let (id,lit,vl,_) = clause in 
591         if vl = [] then Some (bag,clause)
592         else
593          let l,r,ty = 
594            match lit with
595              | Terms.Equation(l,r,ty,_) -> l,r,ty
596              | _ -> assert false 
597          in
598          match deep_eq ~unify:true l r ty [] (fun x -> x) (fun x -> x) 
599            table (Some(bag,maxvar,clause,Subst.id_subst)) with
600          | None -> Some (bag,clause)
601          | Some (bag,maxvar,cl,subst) -> 
602              prerr_endline "Goal subsumed";
603              raise (Success (bag,maxvar,cl))
604 (*
605       else match is_subsumed ~unify:true bag maxvar clause table with
606         | None -> Some (bag, clause)
607         | Some ((bag,maxvar),c) -> 
608             prerr_endline "Goal subsumed";
609             raise (Success (bag,maxvar,c))
610 *) 
611     ;;
612
613     let prof_simplify_goal = HExtlib.profile ~enable "simplify_goal";;
614     let  simplify_goal ~no_demod maxvar table bag g_actives x =
615       prof_simplify_goal.HExtlib.profile ( simplify_goal ~no_demod maxvar table bag g_actives) x
616     ;;
617
618     (* =================== inference ===================== *)
619
620     (* this is OK for both the sup_left and sup_right inference steps *)
621     let superposition table varlist subterm pos context =
622       let cands = IDX.DT.retrieve_unifiables table subterm in
623       HExtlib.filter_map
624         (fun (dir, (id,lit,vl,_ (*as uc*))) ->
625            match lit with
626            | Terms.Predicate _ -> assert false
627            | Terms.Equation (l,r,_,o) ->
628                let side, newside = if dir=Terms.Left2Right then l,r else r,l in
629                try 
630                  let subst = 
631                    Unif.unification (* (varlist@vl)*)  [] subterm side 
632                  in 
633                  if o = Terms.Incomparable || o = Terms.Invertible then
634                    let side = Subst.apply_subst subst side in
635                    let newside = Subst.apply_subst subst newside in
636                    let o = Order.compare_terms side newside in
637                    (* XXX: check Riazanov p. 33 (iii) *)
638                    if o <> Terms.Lt && o <> Terms.Eq then  
639                      Some (context newside, subst, id, pos, dir)
640                    else 
641                      ((*prerr_endline ("Filtering: " ^ 
642                         Pp.pp_foterm side ^ " =(< || =)" ^ 
643                         Pp.pp_foterm newside);*)None)
644                  else
645                    Some (context newside, subst, id, pos, dir)
646                with FoUnif.UnificationFailure _ -> None)
647         (IDX.ClauseSet.elements cands)
648     ;;
649
650     (* Superposes selected equation with equalities in table *)
651     let superposition_with_table bag maxvar (id,selected,vl,_) table =
652       match selected with 
653       | Terms.Predicate _ -> assert false
654       | Terms.Equation (l,r,ty,Terms.Lt) ->
655           fold_build_new_clause bag maxvar id Terms.Superposition
656             (fun _ -> true)
657             (all_positions [3] 
658               (fun x -> Terms.Node [ Terms.Leaf B.eqP; ty; l; x ])
659               r (superposition table vl))
660       | Terms.Equation (l,r,ty,Terms.Invertible)
661       | Terms.Equation (l,r,ty,Terms.Gt) ->
662           fold_build_new_clause bag maxvar id Terms.Superposition
663             (fun _ -> true)
664             (all_positions [2] 
665               (fun x -> Terms.Node [ Terms.Leaf B.eqP; ty; x; r ])
666               l (superposition table vl))
667       | Terms.Equation (l,r,ty,Terms.Incomparable) ->
668           let filtering avoid subst = (* Riazanov: p.33 condition (iv) *)
669             let l = Subst.apply_subst subst l in
670             let r = Subst.apply_subst subst r in
671             let o = Order.compare_terms l r in
672             o <> avoid && o <> Terms.Eq
673           in
674           let bag, maxvar,r_terms =
675             fold_build_new_clause bag maxvar id Terms.Superposition
676               (filtering Terms.Gt)
677               (all_positions [3] 
678                  (fun x -> Terms.Node [ Terms.Leaf B.eqP; ty; l; x ])
679                  r (superposition table vl))
680           in
681           let bag, maxvar, l_terms =
682             fold_build_new_clause bag maxvar id Terms.Superposition
683               (filtering Terms.Lt)
684               (all_positions [2] 
685                  (fun x -> Terms.Node [ Terms.Leaf B.eqP; ty; x; r ])
686                  l (superposition table vl))
687           in
688             bag, maxvar, r_terms @ l_terms
689       | _ -> assert false
690     ;;
691
692     (* the current equation is normal w.r.t. demodulation with atable
693      * (and is not the identity) *)
694     let infer_right bag maxvar current (alist,atable) = 
695       (* We demodulate actives clause with current until all *
696        * active clauses are reduced w.r.t each other         *)
697       (* let bag, (alist,atable) = keep_simplified (alist,atable) bag [current] in *)
698       let ctable = IDX.index_clause IDX.DT.empty current in
699       (* let bag, (alist, atable) = 
700         let bag, alist = 
701           HExtlib.filter_map_acc (simplify ctable) bag alist
702         in
703         bag, (alist, List.fold_left IDX.index_clause IDX.DT.empty alist)
704       in*)
705         debug "Simplified active clauses with fact";
706       (* We superpose active clauses with current *)
707       let bag, maxvar, new_clauses =
708         List.fold_left 
709           (fun (bag, maxvar, acc) active ->
710              let bag, maxvar, newc = 
711                superposition_with_table bag maxvar active ctable 
712              in
713              bag, maxvar, newc @ acc)
714           (bag, maxvar, []) alist
715       in
716         debug "First superpositions";
717         (* We add current to active clauses so that it can be *
718          * superposed with itself                             *)
719       let alist, atable = 
720         current :: alist, IDX.index_clause atable current
721       in
722         debug "Indexed";
723       let fresh_current, maxvar = Utils.fresh_clause maxvar current in
724         (* We need to put fresh_current into the bag so that all *
725          * variables clauses refer to are known.                 *)
726       let bag, fresh_current = Terms.add_to_bag fresh_current bag in
727         (* We superpose current with active clauses *)
728       let bag, maxvar, additional_new_clauses =
729         superposition_with_table bag maxvar fresh_current atable 
730       in
731         debug "Another superposition";
732       let new_clauses = new_clauses @ additional_new_clauses in
733         debug (Printf.sprintf "Demodulating %d clauses"
734                  (List.length new_clauses));
735       let bag, new_clauses = 
736         HExtlib.filter_map_monad (simplify atable maxvar) bag new_clauses
737       in
738         debug "Demodulated new clauses";
739       bag, maxvar, (alist, atable), new_clauses
740     ;;
741
742     let prof_ir = HExtlib.profile ~enable "infer_right";;
743     let infer_right bag maxvar current t = 
744       prof_ir.HExtlib.profile (infer_right bag maxvar current) t
745     ;;
746
747     let infer_left bag maxvar goal (_alist, atable) =
748         (* We superpose the goal with active clauses *)
749      if (match goal with (_,_,[],_) -> true | _ -> false) then bag, maxvar, []
750      else
751       let bag, maxvar, new_goals =        
752         superposition_with_table bag maxvar goal atable 
753       in
754         debug "Superposed goal with active clauses";
755         (* We simplify the new goals with active clauses *)
756       let bag, new_goals = 
757         List.fold_left
758          (fun (bag, acc) g -> 
759             match simplify_goal ~no_demod:false maxvar atable bag [] g with
760               | None -> assert false
761               | Some (bag,g) -> bag,g::acc)
762          (bag, []) new_goals
763       in
764         debug "Simplified new goals with active clauses";
765       bag, maxvar, List.rev new_goals
766     ;;
767
768     let prof_il = HExtlib.profile ~enable "infer_left";;
769     let infer_left bag maxvar goal t = 
770       prof_il.HExtlib.profile (infer_left bag maxvar goal) t
771     ;;
772
773   end