5 let nparamod rdb metasenv subst context t table =
6 let max_nb_iter = 999999999 in
7 let amount_of_time = 300.0 in
9 let metasenv = metasenv
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
22 let module WeightOrderedPassives =
24 type t = B.t Terms.passive_clause
26 let compare = Utils.compare_passive_clauses_weight
29 let module AgeOrderedPassives =
31 type t = B.t Terms.passive_clause
33 let compare = Utils.compare_passive_clauses_age
36 let module WeightPassiveSet = Set.Make(WeightOrderedPassives) in
37 let module AgePassiveSet = Set.Make(AgeOrderedPassives) in
38 let add_passive_clause ?(no_weight=true) (passives_w,passives_a) cl =
39 let cl = if no_weight then (0,cl)
40 else Utils.mk_passive_clause cl in
41 WeightPassiveSet.add cl passives_w, AgePassiveSet.add cl passives_a
43 let remove_passive_clause (passives_w,passives_a) cl =
44 let passives_w = WeightPassiveSet.remove cl passives_w in
45 let passives_a = AgePassiveSet.remove cl passives_a in
48 let add_passive_clauses (passives_w,passives_a) new_clauses =
49 let new_clauses_w,new_clauses_a = List.fold_left add_passive_clause
50 (WeightPassiveSet.empty,AgePassiveSet.empty) new_clauses
52 (WeightPassiveSet.union new_clauses_w passives_w,
53 AgePassiveSet.union new_clauses_a passives_a)
55 let is_passive_set_empty (passives_w,passives_a) =
56 if (WeightPassiveSet.is_empty passives_w) then begin
57 assert (AgePassiveSet.is_empty passives_a); true
59 assert (not (AgePassiveSet.is_empty passives_a)); false
62 let passive_set_cardinal (passives_w,_) =
63 WeightPassiveSet.cardinal passives_w
65 let passive_singleton cl =
66 (WeightPassiveSet.singleton cl,AgePassiveSet.singleton cl)
68 let passive_empty_set =
69 (WeightPassiveSet.empty,AgePassiveSet.empty)
71 let pick_min_passive use_age (passives_w,passives_a) =
72 if use_age then AgePassiveSet.min_elt passives_a
73 else WeightPassiveSet.min_elt passives_w
75 let timeout = Unix.gettimeofday () +. amount_of_time in
77 (* TODO : global age over facts and goals (without comparing weights) *)
78 let select passives g_passives =
79 if is_passive_set_empty passives then begin
80 assert (not (is_passive_set_empty g_passives));
81 let g_cl = pick_min_passive false g_passives in
82 (true,snd g_cl,passives,remove_passive_clause g_passives g_cl)
84 else let cl = pick_min_passive false passives in
85 if is_passive_set_empty g_passives then
86 (false,snd cl,remove_passive_clause passives cl,g_passives)
88 let g_cl = pick_min_passive false g_passives in
89 if (fst cl <= fst g_cl) then
90 (false,snd cl,remove_passive_clause passives cl,g_passives)
92 (true,snd g_cl,passives,remove_passive_clause g_passives g_cl)
95 let backward_infer_step bag maxvar actives passives
96 g_actives g_passives g_current =
97 (* superposition left, simplifications on goals *)
98 debug "infer_left step...";
99 let bag, maxvar, new_goals =
100 Sup.infer_left bag maxvar g_current actives
102 debug "Performed infer_left step";
103 bag, maxvar, actives, passives, g_current::g_actives,
104 (add_passive_clauses g_passives new_goals)
107 let forward_infer_step bag maxvar actives passives g_actives
113 * A' = demod [e'] A *
116 * new = supright e'' A'' *
117 * new'= demod A'' new *
119 debug "Forward infer step...";
120 debug "Selected and simplified";
121 (* debug ("Fact after simplification :"
122 ^ Pp.pp_unit_clause current); *)
123 let bag, maxvar, actives, new_clauses =
124 Sup.infer_right bag maxvar current actives
126 debug "Demodulating goals with actives...";
127 (* keep goals demodulated w.r.t. actives and check if solved *)
131 match Sup.simplify_goal maxvar (snd actives) bag acc c with
133 | Some (bag,c) -> bag,c::acc)
136 let ctable = IDX.index_unit_clause IDX.DT.empty current in
137 let bag, maxvar, new_goals =
139 (fun (bag,m,acc) g ->
140 let bag, m, ng = Sup.infer_left bag m g
141 ([current],ctable) in
143 (bag,maxvar,[]) g_actives
145 bag, maxvar, actives,
146 add_passive_clauses passives new_clauses, g_actives,
147 add_passive_clauses g_passives new_goals
150 let rec given_clause bag maxvar actives passives g_actives g_passives =
151 (* prerr_endline "Bag :"; prerr_endline (Pp.pp_bag bag);
152 prerr_endline "Active table :";
153 (List.iter (fun x -> prerr_endline (Pp.pp_unit_clause x))
155 incr nb_iter; if !nb_iter = max_nb_iter then
156 raise (Failure "No iterations left !");
157 if Unix.gettimeofday () > timeout then
158 raise (Failure "Timeout !");
161 let rec aux_select passives g_passives =
162 let backward,current,passives,g_passives = select passives g_passives in
164 match Sup.simplify_goal maxvar (snd actives) bag g_actives current with
165 | None -> aux_select passives g_passives
166 | Some x -> let bag,g_current = x in
167 backward_infer_step bag maxvar actives passives
168 g_actives g_passives g_current
170 (* debug ("Selected fact : " ^ Pp.pp_unit_clause current); *)
171 match Sup.keep_simplified current actives bag maxvar with
172 (* match Sup.one_pass_simplification current actives bag maxvar with*)
173 | None -> aux_select passives g_passives
174 | Some x -> let (current, bag, actives) = x in
175 forward_infer_step bag maxvar actives passives
176 g_actives g_passives current
179 let bag,maxvar,actives,passives,g_actives,g_passives =
180 aux_select passives g_passives
183 (Printf.sprintf "Number of active goals : %d"
184 (List.length g_actives));
186 (Printf.sprintf "Number of passive goals : %d"
187 (passive_set_cardinal g_passives));
189 (Printf.sprintf "Number of actives : %d" (List.length (fst actives)));
191 (Printf.sprintf "Number of passives : %d"
192 (passive_set_cardinal passives));
193 given_clause bag maxvar actives passives g_actives g_passives
196 let mk_clause ?(no_weight=false) bag maxvar (t,ty) =
197 let (proof,ty) = B.saturate t ty in
198 let c, maxvar = Utils.mk_unit_clause maxvar ty proof in
199 let bag, c = Utils.add_to_bag bag c in
202 let bag, maxvar, goal = mk_clause Terms.M.empty 0 t in
203 let g_actives = [] in
205 passive_singleton (0,goal)
207 let passives, bag, maxvar =
209 (fun (cl, bag, maxvar) t ->
210 let bag, maxvar, c = mk_clause bag maxvar t in
211 (add_passive_clause cl c), bag, maxvar)
212 (passive_empty_set, bag, maxvar) table
214 let actives = [], IDX.DT.empty in
215 try given_clause bag maxvar actives passives g_actives g_passives
217 | Sup.Success (bag, _, (i,_,_,_)) ->
219 let rec traverse ongoal (accg,acce) i =
220 match Terms.M.find i bag with
221 | (id,_,_,Terms.Exact _) ->
222 if ongoal then [i],acce else
223 if (List.mem i acce) then accg,acce else accg,acce@[i]
224 | (_,_,_,Terms.Step (_,i1,i2,_,_,_)) ->
225 if (not ongoal) && (List.mem i acce) then accg,acce
228 traverse false (traverse ongoal (accg,acce) i1) i2
230 if ongoal then i::accg,acce else accg,i::acce
232 let gsteps,esteps = traverse true ([],[]) i in
233 (List.rev esteps)@gsteps
235 prerr_endline (Printf.sprintf "Found proof in %d iterations, %fs"
237 (Unix.gettimeofday() -. timeout +. amount_of_time));
238 (* prerr_endline "Proof:";
239 List.iter (fun x -> prerr_endline (string_of_int x);
240 prerr_endline (Pp.pp_unit_clause (Terms.M.find x bag))) l;*)
241 let proofterm = B.mk_proof bag i l in
242 prerr_endline (Printf.sprintf "Got proof term, %fs"
243 (Unix.gettimeofday() -. timeout +. amount_of_time));
244 let metasenv, proofterm =
245 let rec aux k metasenv = function
246 | NCic.Meta _ as t -> metasenv, t
248 let metasenv,i,_,_=NCicMetaSubst.mk_meta metasenv context `Term in
249 metasenv, NCic.Meta (i,(k,NCic.Irl (List.length context)))
250 | t -> NCicUntrusted.map_term_fold_a
251 (fun _ k -> k+1) k aux metasenv t
253 aux 0 metasenv proofterm
255 let metasenv, subst, proofterm, _prooftype =
257 (rdb#set_coerc_db NCicCoercion.empty_db)
258 metasenv subst context proofterm None
260 proofterm, metasenv, subst
264 (Printf.sprintf "FAILURE in %d iterations" !nb_iter); assert false