X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Fsoftware%2Fcomponents%2Fng_tactics%2FnnAuto.ml;h=fdf2d2ea3138130ca23aa7ecabeac40b0fc1fdb0;hb=ced2abc1e3fe84d5bbfa9ccb2ebf46f253279ebe;hp=e00bb2ade0d99768c11fe7330500d2487323a86a;hpb=c32e87198e3434dc89009b954223e825da34c1ac;p=helm.git diff --git a/helm/software/components/ng_tactics/nnAuto.ml b/helm/software/components/ng_tactics/nnAuto.ml index e00bb2ade..fdf2d2ea3 100644 --- a/helm/software/components/ng_tactics/nnAuto.ml +++ b/helm/software/components/ng_tactics/nnAuto.ml @@ -56,7 +56,8 @@ let menv_closure status gl = (* we call a "fact" an object whose hypothesis occur in the goal or in types of goal-variables *) let is_a_fact status ty = - let status, ty, _ = saturate ~delta:max_int status ty in + let status, ty, _ = saturate ~delta:0 status ty in + debug_print (lazy (ppterm status ty)); let g_metas = metas_of_term status ty in let clos = menv_closure status g_metas in let _,_,metasenv,_,_ = status#obj in @@ -84,66 +85,55 @@ let current_goal status = (* =============================== paramod =========================== *) -let auto_paramod ~params:(l,_) status goal = - let gty = get_goalty status goal in - let n,h,metasenv,subst,o = status#obj in - let status,t = term_of_cic_term status gty (ctx_of gty) in - let status, l = - List.fold_left - (fun (status, l) t -> - let status, t = disambiguate status (ctx_of gty) t None in - let status, ty = typeof status (ctx_of t) t in - let status, t = term_of_cic_term status t (ctx_of gty) in - let status, ty = term_of_cic_term status ty (ctx_of ty) in - (status, (t,ty) :: l)) - (status,[]) l - in - match - NCicParamod.nparamod status metasenv subst (ctx_of gty) (NCic.Rel ~-1,t) l - with - | [] -> raise (Error (lazy "no proof found",None)) - | (pt, _, metasenv, subst)::_ -> - let status = status#set_obj (n,h,metasenv,subst,o) in - instantiate status goal (mk_cic_term (ctx_of gty) pt) -;; - -let auto_paramod_tac ~params status = - NTactics.distribute_tac (auto_paramod ~params) status -;; - -let fast_eq_check_all status eq_cache goal = +let solve fast status eq_cache goal = + let f = + if fast then NCicParamod.fast_eq_check + else NCicParamod.paramod in let n,h,metasenv,subst,o = status#obj in let gname, ctx, gty = List.assoc goal metasenv in let gty = NCicUntrusted.apply_subst subst ctx gty in let build_status (pt, _, metasenv, subst) = - let stamp = Unix.gettimeofday () in - let metasenv, subst, pt, pty = - NCicRefiner.typeof - (status#set_coerc_db NCicCoercion.empty_db) - metasenv subst ctx pt None in - let metasenv, subst = - NCicUnification.unify status metasenv subst ctx gty pty -(* the previous code is much less expensive than directly refining - pt with expected type pty - in - NCicRefiner.typeof - (status#set_coerc_db NCicCoercion.empty_db) - metasenv subst ctx pt (Some gty) *) - in - print (lazy (Printf.sprintf "Refined in %fs" + try + debug_print (lazy ("refining: "^(NCicPp.ppterm ctx subst metasenv pt))); + let stamp = Unix.gettimeofday () in + let metasenv, subst, pt, pty = + NCicRefiner.typeof status + (* (status#set_coerc_db NCicCoercion.empty_db) *) + metasenv subst ctx pt None in + debug_print (lazy ("refined: "^(NCicPp.ppterm ctx subst metasenv pt))); + debug_print (lazy ("synt: "^(NCicPp.ppterm ctx subst metasenv pty))); + let metasenv, subst = + NCicUnification.unify status metasenv subst ctx gty pty + (* the previous code is much less expensive than directly refining + pt with expected type pty + in + prerr_endline ("exp: "^(NCicPp.ppterm ctx subst metasenv gty)); + NCicRefiner.typeof + (status#set_coerc_db NCicCoercion.empty_db) + metasenv subst ctx pt (Some gty) *) + in + print (lazy (Printf.sprintf "Refined in %fs" (Unix.gettimeofday() -. stamp))); - let status = status#set_obj (n,h,metasenv,subst,o) in - let metasenv = List.filter (fun j,_ -> j <> goal) metasenv in - let subst = (goal,(gname,ctx,pt,pty)) :: subst in - status#set_obj (n,h,metasenv,subst,o) + let status = status#set_obj (n,h,metasenv,subst,o) in + let metasenv = List.filter (fun j,_ -> j <> goal) metasenv in + let subst = (goal,(gname,ctx,pt,pty)) :: subst in + Some (status#set_obj (n,h,metasenv,subst,o)) + with + NCicRefiner.RefineFailure msg + | NCicRefiner.Uncertain msg -> + debug_print (lazy ("WARNING: refining in fast_eq_check failed" ^ + snd (Lazy.force msg))); None + | NCicRefiner.AssertFailure msg -> + debug_print (lazy ("WARNING: refining in fast_eq_check failed" ^ + Lazy.force msg)); None + | _ -> None in - List.map build_status - (NCicParamod.fast_eq_check status metasenv subst ctx - eq_cache (NCic.Rel ~-1,gty)) + HExtlib.filter_map build_status + (f status metasenv subst ctx eq_cache (NCic.Rel ~-1,gty)) ;; let fast_eq_check eq_cache status goal = - match fast_eq_check_all status eq_cache goal with + match solve true status eq_cache goal with | [] -> raise (Error (lazy "no proof found",None)) | s::_ -> s ;; @@ -186,6 +176,17 @@ let fast_eq_check_tac ~params s = dist_fast_eq_check unit_eq s ;; +let paramod eq_cache status goal = + match solve false status eq_cache goal with + | [] -> raise (Error (lazy "no proof found",None)) + | s::_ -> s +;; + +let paramod_tac ~params s = + let unit_eq = index_local_equations s#eq_cache s in + NTactics.distribute_tac (paramod unit_eq) s +;; + (* let fast_eq_check_tac_all ~params eq_cache status = let g,_,_ = current_goal status in @@ -198,6 +199,17 @@ let fast_eq_check_tac_all ~params eq_cache status = ;; *) +(* +let demod status eq_cache goal = + let n,h,metasenv,subst,o = status#obj in + let gname, ctx, gty = List.assoc goal metasenv in + let gty = NCicUntrusted.apply_subst subst ctx gty in + +let demod_tac ~params s = + let unit_eq = index_local_equations s#eq_cache s in + dist_fast_eq_check unit_eq s +*) + (*************** subsumption ****************) let close_wrt_context = @@ -1344,7 +1356,7 @@ let pp_th status = let search_in_th gty th = let c = ctx_of gty in let rec aux acc = function - | [] -> Ncic_termSet.elements acc + | [] -> (* Ncic_termSet.elements *) acc | (_::tl) as k -> try let idx = List.assq k th in @@ -1403,55 +1415,107 @@ let openg_no status = List.length (head_goals status#stack) let sort_new_elems l = List.sort (fun (_,s1) (_,s2) -> openg_no s1 - openg_no s2) l -let try_candidate flags depth status eq_cache t = +let try_candidate ?(smart=0) flags depth status eq_cache t = try - debug_print ~depth (lazy ("try " ^ CicNotationPp.pp_term t)); + print ~depth (lazy ("------------ try " ^ CicNotationPp.pp_term t)); let status = - smart_apply_auto ("",0,t) eq_cache status in - (* let status = NTactics.apply_tac ("",0,t) status in *) - let og_no = openg_no status in - if og_no > flags.maxwidth || + if smart= 0 then NTactics.apply_tac ("",0,t) status + else if smart = 1 then smart_apply_auto ("",0,t) eq_cache status + else (* smart = 2: both *) + try NTactics.apply_tac ("",0,t) status + with Error _ -> + smart_apply_auto ("",0,t) eq_cache status in + let og_no = openg_no status in + if (* og_no > flags.maxwidth || *) (depth = flags.maxdepth && og_no <> 0) then - (debug_print ~depth (lazy "pruned immediately"); None) + (print ~depth (lazy "pruned immediately"); None) else (incr candidate_no; Some ((!candidate_no,t),status)) with Error (msg,exn) -> debug_print ~depth (lazy "failed"); None ;; -let get_candidates status cache signature gty = +let get_candidates ?(smart=true) status cache signature gty = let universe = status#auto_cache in let context = ctx_of gty in + let t_ast t = + let _status, t = term_of_cic_term status t context + in Ast.NCic t in + let c_ast = function + | NCic.Const r -> Ast.NRef r | _ -> assert false in let _, raw_gty = term_of_cic_term status gty context in let cands = NDiscriminationTree.DiscriminationTree.retrieve_unifiables - universe raw_gty - in - let cands = - List.filter (only signature context) - (NDiscriminationTree.TermSet.elements cands) + universe raw_gty in + let local_cands = search_in_th gty cache in + let together global local = + List.map c_ast + (List.filter (only signature context) + (NDiscriminationTree.TermSet.elements global)) @ + List.map t_ast (Ncic_termSet.elements local) in + let candidates = together cands local_cands in + let smart_candidates = + if smart then + match raw_gty with + | NCic.Appl (hd::tl) -> + let weak_gty = + NCic.Appl (hd:: HExtlib.mk_list(NCic.Meta (0,(0,NCic.Irl 0))) + (List.length tl)) in + let more_cands = + NDiscriminationTree.DiscriminationTree.retrieve_unifiables + universe weak_gty in + let smart_cands = + NDiscriminationTree.TermSet.diff more_cands cands in + let cic_weak_gty = mk_cic_term context weak_gty in + let more_local_cands = search_in_th cic_weak_gty cache in + let smart_local_cands = + Ncic_termSet.diff more_local_cands local_cands in + together smart_cands smart_local_cands + | _ -> [] + else [] in - List.map (fun t -> - let _status, t = term_of_cic_term status t context in Ast.NCic t) - (search_in_th gty cache) - @ - List.map (function NCic.Const r -> Ast.NRef r | _ -> assert false) cands + candidates, smart_candidates ;; let applicative_case depth signature status flags gty (cache:cache) = - let tcache = cache.facts in app_counter:= !app_counter+1; - let candidates = get_candidates status tcache signature gty in + let _,_,metasenv,subst,_ = status#obj in + let context = ctx_of gty in + let tcache = cache.facts in + let is_eq = + let status, t = term_of_cic_term status gty context in + NCicParamod.is_equation metasenv subst context t + in + debug_print(lazy (string_of_bool is_eq)); + let candidates, smart_candidates = + get_candidates ~smart:(not is_eq) status tcache signature gty in debug_print ~depth (lazy ("candidates: " ^ string_of_int (List.length candidates))); + debug_print ~depth + (lazy ("smart candidates: " ^ + string_of_int (List.length smart_candidates))); +(* + let sm = 0 in + let smart_candidates = [] in *) + let sm = if is_eq then 0 else 2 in let elems = List.fold_left (fun elems cand -> - match try_candidate flags depth status cache.unit_eq cand with + match try_candidate (~smart:sm) + flags depth status cache.unit_eq cand with | None -> elems | Some x -> x::elems) [] candidates in - elems + let more_elems = + List.fold_left + (fun elems cand -> + match try_candidate (~smart:1) + flags depth status cache.unit_eq cand with + | None -> elems + | Some x -> x::elems) + [] smart_candidates + in + elems@more_elems ;; exception Found @@ -1567,17 +1631,19 @@ let do_something signature flags status g depth gty cache = (* whd *) let l = reduce ~depth status g in (* backward aplications *) - let l1 = applicative_case depth signature status flags gty cache in - (* fast paramodulation *) - let l2 = + let l1 = List.map (fun s -> incr candidate_no; ((!candidate_no,Ast.Ident("__paramod",None)),s)) - (auto_eq_check cache.unit_eq status) + (auto_eq_check cache.unit_eq status) in + let l2 = + if (l1 <> []) then [] + else applicative_case depth signature status flags gty cache + (* fast paramodulation *) in - (* states in l2 have have an set of subgoals: no point to sort them *) - l2 @ (sort_new_elems (l@l1)), cache + (* states in l1 have have an empty set of subgoals: no point to sort them *) + l1 @ (sort_new_elems (l@l2)), cache ;; let pp_goal = function @@ -1660,7 +1726,7 @@ let focus_tac focus status = status#set_stack gstatus ;; -let rec auto_clusters +let rec auto_clusters ?(top=false) flags signature cache depth status : unit = debug_print ~depth (lazy "entering auto clusters"); (* ignore(Unix.select [] [] [] 0.01); *) @@ -1674,6 +1740,7 @@ let rec auto_clusters debug_print ~depth (lazy ("goals = " ^ String.concat "," (List.map string_of_int goals))); let classes = HExtlib.clusters (deps status) goals in + let classes = if top then List.rev classes else classes in debug_print ~depth (lazy (String.concat "\n" @@ -1681,17 +1748,20 @@ let rec auto_clusters (fun l -> ("cluster:" ^ String.concat "," (List.map string_of_int l))) classes))); - let status = + let status,b = List.fold_left - (fun status gl -> + (fun (status,b) gl -> let status = focus_tac gl status in try debug_print ~depth (lazy ("focusing on" ^ String.concat "," (List.map string_of_int gl))); - auto_main flags signature cache depth status; status - with Proved(status) -> NTactics.merge_tac status) - status classes - in raise (Proved status) + auto_main flags signature cache depth status; assert false + with + | Proved(status) -> (NTactics.merge_tac status,true) + | Gaveup _ when top -> (NTactics.merge_tac status,b) + ) + (status,false) classes + in if b then raise (Proved status) else raise (Gaveup IntSet.empty) and @@ -1706,7 +1776,10 @@ auto_main flags signature (cache:cache) depth status: unit = match goals with | [] -> raise (Proved status) | orig::_ -> - let branch = List.length(goals)>1 in + let ng = List.length goals in + if ng > flags.maxwidth then + (print (lazy "FAIL WIDTH"); raise (Gaveup IntSet.empty)) + else let branch = ng>1 in if depth = flags.maxdepth then raise (Gaveup IntSet.empty) else let status = @@ -1738,7 +1811,9 @@ auto_main flags signature (cache:cache) depth status: unit = else depth+1, loop_cache in debug_print (~depth:depth') (lazy ("Case: " ^ CicNotationPp.pp_term t)); - try auto_clusters flags signature loop_cache + let flags' = + {flags with maxwidth = flags.maxwidth - ng +1} in + try auto_clusters flags' signature loop_cache depth' status; unsat with | Proved status -> @@ -1793,7 +1868,7 @@ let auto_tac ~params:(_univ,flags) status = *) let depth = int "depth" flags 3 in let size = int "size" flags 10 in - let width = int "width" flags (3+List.length goals) in + let width = int "width" flags 4 (* (3+List.length goals)*) in (* XXX fix sort *) let goals = List.map (fun i -> (i,P)) goals in let signature = () in @@ -1817,7 +1892,7 @@ let auto_tac ~params:(_univ,flags) status = let _ = debug_print (lazy("\n\nRound "^string_of_int x^"\n")) in let flags = { flags with maxdepth = x } in - try auto_clusters flags signature cache 0 status;assert false + try auto_clusters (~top:true) flags signature cache 0 status;assert false with | Gaveup _ -> up_to (x+1) y | Proved s ->