]> matita.cs.unibo.it Git - helm.git/blob - helm/software/components/ng_paramodulation/paramod.ml
Extended is_identity test
[helm.git] / helm / software / components / ng_paramodulation / paramod.ml
1 let debug s =
2    prerr_endline s
3 ;;
4
5 let nparamod rdb metasenv subst context t table =
6   let max_nb_iter = 999999999 in
7   let amount_of_time = 300.0 in
8   let module C = struct
9     let metasenv = metasenv
10     let subst = subst
11     let context = context
12   end
13   in
14   let nb_iter = ref 0 in
15   let module B = NCicBlob.NCicBlob(C) in
16   let module Pp = Pp.Pp (B) in
17   let module FU = FoUnif.Founif(B) in
18   let module IDX = Index.Index(B) in
19   let module Sup = Superposition.Superposition(B) in
20   let module Utils = FoUtils.Utils(B) in
21     
22   let module WeightOrderedPassives =
23       struct
24         type t = B.t Terms.passive_clause
25             
26         let compare = Utils.compare_passive_clauses_weight
27       end
28   in
29   let module AgeOrderedPassives =
30       struct
31         type t = B.t Terms.passive_clause
32             
33         let compare = Utils.compare_passive_clauses_age
34       end
35   in
36   let module WeightPassiveSet = Set.Make(WeightOrderedPassives) in
37   let module AgePassiveSet = Set.Make(AgeOrderedPassives) in
38   let add_passive_clause (passives_w,passives_a) cl =
39     let cl = Utils.mk_passive_clause cl in
40     WeightPassiveSet.add cl passives_w, AgePassiveSet.add cl passives_a
41   in
42   let remove_passive_clause (passives_w,passives_a) cl =
43     let passives_w = WeightPassiveSet.remove cl passives_w in
44     let passives_a = AgePassiveSet.remove cl passives_a in
45       passives_w,passives_a
46   in
47   let add_passive_clauses (passives_w,passives_a) new_clauses =
48     let new_clauses_w,new_clauses_a = List.fold_left add_passive_clause
49       (WeightPassiveSet.empty,AgePassiveSet.empty) new_clauses
50     in
51       (WeightPassiveSet.union new_clauses_w passives_w,
52        AgePassiveSet.union new_clauses_a passives_a)
53   in
54   let is_passive_set_empty (passives_w,passives_a) =
55     if (WeightPassiveSet.is_empty passives_w) then begin
56       assert (AgePassiveSet.is_empty passives_a); true
57     end else begin
58       assert (not (AgePassiveSet.is_empty passives_a)); false
59     end
60   in
61   let passive_set_cardinal (passives_w,_) =
62     WeightPassiveSet.cardinal passives_w
63   in
64   let passive_singleton cl =
65     (WeightPassiveSet.singleton cl,AgePassiveSet.singleton cl)
66   in
67   let passive_empty_set =
68     (WeightPassiveSet.empty,AgePassiveSet.empty)
69   in
70   let pick_min_passive use_age (passives_w,passives_a) =
71     if use_age then AgePassiveSet.min_elt passives_a
72     else WeightPassiveSet.min_elt passives_w
73   in
74   let timeout = Unix.gettimeofday () +. amount_of_time in 
75
76     (* TODO : global age over facts and goals (without comparing weights) *)
77   let select passives g_passives =
78     if is_passive_set_empty passives then begin
79       assert (not (is_passive_set_empty g_passives));
80       let g_cl = pick_min_passive false g_passives in
81         (true,snd g_cl,passives,remove_passive_clause g_passives g_cl)
82     end
83     else let cl = pick_min_passive false passives in
84       if is_passive_set_empty g_passives then
85         (false,snd cl,remove_passive_clause passives cl,g_passives)
86       else
87         let g_cl = pick_min_passive false g_passives in
88           if (fst cl <= fst g_cl) then
89             (false,snd cl,remove_passive_clause passives cl,g_passives)
90           else
91             (true,snd g_cl,passives,remove_passive_clause g_passives g_cl)
92   in
93
94   let backward_infer_step bag maxvar actives passives
95                           g_actives g_passives g_current =
96     (* superposition left, simplifications on goals *)
97       debug "infer_left step...";
98       let bag, maxvar, new_goals = 
99         Sup.infer_left bag maxvar g_current actives 
100       in
101         debug "Performed infer_left step";
102         bag, maxvar, actives, passives, g_current::g_actives,
103     (add_passive_clauses g_passives new_goals)
104   in
105
106   let forward_infer_step bag maxvar actives passives g_actives
107                          g_passives current =
108     (* forward step *)
109     
110     (* e = select P           *
111      * e' = demod A e         *
112      * A' = demod [e'] A      *
113      * A'' = A' + e'          *
114      * e'' = fresh e'         *
115      * new = supright e'' A'' *
116      * new'= demod A'' new    *
117      * P' = P + new'          *)
118     debug "Forward infer step...";
119     debug "Selected and simplified";
120     (* debug ("Fact after simplification :"
121        ^ Pp.pp_unit_clause current); *)
122     let bag, maxvar, actives, new_clauses = 
123       Sup.infer_right bag maxvar current actives 
124     in
125       debug "Demodulating goals with actives...";
126       (* keep goals demodulated w.r.t. actives and check if solved *)
127       let bag, g_actives = 
128         List.fold_left 
129           (fun (bag,acc) c -> 
130              match Sup.simplify_goal maxvar (snd actives) bag acc c with
131                | None -> bag, acc
132                | Some (bag,c) -> bag,c::acc)
133           (bag,[]) g_actives 
134       in
135       let ctable = IDX.index_unit_clause IDX.DT.empty current in
136       let bag, maxvar, new_goals = 
137         List.fold_left 
138           (fun (bag,m,acc) g -> 
139              let bag, m, ng = Sup.infer_left bag m g
140                ([current],ctable) in
141                bag,m,ng@acc) 
142           (bag,maxvar,[]) g_actives 
143       in
144         bag, maxvar, actives,
145     add_passive_clauses passives new_clauses, g_actives,
146     add_passive_clauses g_passives new_goals
147   in
148
149   let rec given_clause bag maxvar actives passives g_actives g_passives =
150     (* prerr_endline "Bag :"; prerr_endline (Pp.pp_bag bag);
151       prerr_endline "Active table :"; 
152        (List.iter (fun x -> prerr_endline (Pp.pp_unit_clause x))
153           (fst actives)); *)
154     incr nb_iter; if !nb_iter = max_nb_iter then       
155       raise (Failure "No iterations left !");
156     if Unix.gettimeofday () > timeout then
157       raise (Failure "Timeout !");
158
159
160     let rec aux_select passives g_passives =
161       let backward,current,passives,g_passives = select passives g_passives in
162         if backward then
163          match Sup.simplify_goal maxvar (snd actives) bag g_actives current with
164             | None -> aux_select passives g_passives
165             | Some x -> let bag,g_current = x in
166                 backward_infer_step bag maxvar actives passives
167                   g_actives g_passives g_current
168         else
169           (* debug ("Selected fact : " ^ Pp.pp_unit_clause current); *)
170           match Sup.keep_simplified current actives bag maxvar with
171         (*  match Sup.one_pass_simplification current actives bag maxvar with*)
172               | None -> aux_select passives g_passives
173               | Some x -> let (current, bag, actives) = x in
174                   forward_infer_step bag maxvar actives passives
175                                      g_actives g_passives current
176     in
177
178     let bag,maxvar,actives,passives,g_actives,g_passives =      
179       aux_select passives g_passives
180     in
181       debug
182         (Printf.sprintf "Number of active goals : %d"
183            (List.length g_actives));
184       debug
185         (Printf.sprintf "Number of passive goals : %d"
186            (passive_set_cardinal g_passives));
187       debug
188         (Printf.sprintf "Number of actives : %d" (List.length (fst actives)));
189       debug
190         (Printf.sprintf "Number of passives : %d"
191            (passive_set_cardinal passives));
192       given_clause bag maxvar actives passives g_actives g_passives
193   in
194
195   let mk_clause bag maxvar (t,ty) =
196     let (proof,ty) = B.saturate t ty in
197     let c, maxvar = Utils.mk_unit_clause maxvar ty proof in
198     let bag, c = Utils.add_to_bag bag c in
199     bag, maxvar, c
200   in
201   let bag, maxvar, goal = mk_clause Terms.M.empty 0 t in
202   let g_actives = [] in
203   let g_passives =
204     passive_singleton (Utils.mk_passive_clause goal)
205   in
206   let passives, bag, maxvar = 
207     List.fold_left
208       (fun (cl, bag, maxvar) t -> 
209          let bag, maxvar, c = mk_clause bag maxvar t in
210          (add_passive_clause cl c), bag, maxvar)
211       (passive_empty_set, bag, maxvar) table 
212   in
213   let actives = [], IDX.DT.empty in
214   try given_clause bag maxvar actives passives g_actives g_passives
215   with 
216   | Sup.Success (bag, _, (i,_,_,_)) ->
217       let l =
218         let rec traverse ongoal (accg,acce) i =
219           match Terms.M.find i bag with
220             | (id,_,_,Terms.Exact _) ->
221                 if ongoal then [i],acce else
222                   if (List.mem i acce) then accg,acce else accg,acce@[i]
223             | (_,_,_,Terms.Step (_,i1,i2,_,_,_)) ->
224                 if (not ongoal) && (List.mem i acce) then accg,acce
225                 else
226                   let accg,acce = 
227                     traverse false (traverse ongoal (accg,acce) i1) i2
228                   in
229                     if ongoal then i::accg,acce else accg,i::acce
230         in
231         let gsteps,esteps = traverse true ([],[]) i in
232           (List.rev esteps)@gsteps
233       in
234         prerr_endline (Printf.sprintf "Found proof in %d iterations, %fs"
235                          !nb_iter
236                          (Unix.gettimeofday() -. timeout +. amount_of_time));
237       (* prerr_endline "Proof:"; 
238       List.iter (fun x -> prerr_endline (string_of_int x);
239               prerr_endline (Pp.pp_unit_clause (Terms.M.find x bag))) l;*)
240       let proofterm = B.mk_proof bag i l in
241         prerr_endline (Printf.sprintf "Got proof term, %fs"
242                          (Unix.gettimeofday() -. timeout +. amount_of_time));
243       let metasenv, proofterm = 
244         let rec aux k metasenv = function
245           | NCic.Meta _ as t -> metasenv, t
246           | NCic.Implicit _ -> 
247               let metasenv,i,_,_=NCicMetaSubst.mk_meta metasenv context `Term in
248               metasenv, NCic.Meta (i,(k,NCic.Irl (List.length context)))
249           | t -> NCicUntrusted.map_term_fold_a 
250                   (fun _ k -> k+1) k aux metasenv t
251         in
252          aux 0 metasenv proofterm
253       in
254       let metasenv, subst, proofterm, _prooftype = 
255         NCicRefiner.typeof 
256           (rdb#set_coerc_db NCicCoercion.empty_db) 
257           metasenv subst context proofterm None
258       in
259       proofterm, metasenv, subst
260   | Failure s -> 
261       prerr_endline s;
262       prerr_endline
263       (Printf.sprintf "FAILURE in %d iterations" !nb_iter); assert false
264 ;;