diff options
author | Enrico Tassi <gareuselesinge@debian.org> | 2015-07-15 10:36:12 +0200 |
---|---|---|
committer | Enrico Tassi <gareuselesinge@debian.org> | 2015-07-15 10:36:12 +0200 |
commit | 0aa2544d04dbd4b6ee665b551ed165e4fb02d2fa (patch) | |
tree | 12e8931a4a56da1a1bdfb89d670f4ba38fe08e1f /plugins/funind/indfun.ml | |
parent | cec4741afacd2e80894232850eaf9f9c0e45d6d7 (diff) |
Imported Upstream version 8.5~beta2+dfsgupstream/8.5_beta2+dfsg
Diffstat (limited to 'plugins/funind/indfun.ml')
-rw-r--r-- | plugins/funind/indfun.ml | 221 |
1 files changed, 143 insertions, 78 deletions
diff --git a/plugins/funind/indfun.ml b/plugins/funind/indfun.ml index 6dbd61cf..e211b688 100644 --- a/plugins/funind/indfun.ml +++ b/plugins/funind/indfun.ml @@ -8,7 +8,6 @@ open Libnames open Globnames open Glob_term open Declarations -open Declareops open Misctypes open Decl_kinds @@ -29,48 +28,55 @@ let choose_dest_or_ind scheme_info = let functional_induction with_clean c princl pat = Dumpglob.pause (); - let res = let f,args = decompose_app c in - fun g -> - let princ,bindings, princ_type = - match princl with - | None -> (* No principle is given let's find the good one *) - begin - match kind_of_term f with - | Const (c',u) -> - let princ_option = - let finfo = (* we first try to find out a graph on f *) - try find_Function_infos c' - with Not_found -> - errorlabstrm "" (str "Cannot find induction information on "++ - Printer.pr_lconstr (mkConst c') ) - in - match Tacticals.elimination_sort_of_goal g with - | InProp -> finfo.prop_lemma - | InSet -> finfo.rec_lemma - | InType -> finfo.rect_lemma - in - let princ = (* then we get the principle *) - try mkConst (Option.get princ_option ) - with Option.IsNone -> - (*i If there is not default lemma defined then, + let res = + let f,args = decompose_app c in + fun g -> + let princ,bindings, princ_type,g' = + match princl with + | None -> (* No principle is given let's find the good one *) + begin + match kind_of_term f with + | Const (c',u) -> + let princ_option = + let finfo = (* we first try to find out a graph on f *) + try find_Function_infos c' + with Not_found -> + errorlabstrm "" (str "Cannot find induction information on "++ + Printer.pr_lconstr (mkConst c') ) + in + match Tacticals.elimination_sort_of_goal g with + | InProp -> finfo.prop_lemma + | InSet -> finfo.rec_lemma + | InType -> finfo.rect_lemma + in + let princ,g' = (* then we get the principle *) + try + let g',princ = + Tacmach.pf_eapply (Evd.fresh_global) g (Globnames.ConstRef (Option.get princ_option )) in + princ,g' + with Option.IsNone -> + (*i If there is not default lemma defined then, we cross our finger and try to find a lemma named f_ind (or f_rec, f_rect) i*) - let princ_name = - Indrec.make_elimination_ident - (Label.to_id (con_label c')) - (Tacticals.elimination_sort_of_goal g) - in - try - mkConst(const_of_id princ_name ) - with Not_found -> (* This one is neither defined ! *) - errorlabstrm "" (str "Cannot find induction principle for " - ++Printer.pr_lconstr (mkConst c') ) - in - (princ,NoBindings, Tacmach.pf_type_of g princ) - | _ -> raise (UserError("",str "functional induction must be used with a function" )) - end - | Some ((princ,binding)) -> - princ,binding,Tacmach.pf_type_of g princ + let princ_name = + Indrec.make_elimination_ident + (Label.to_id (con_label c')) + (Tacticals.elimination_sort_of_goal g) + in + try + let princ_ref = const_of_id princ_name in + let (a,b) = Tacmach.pf_eapply (Evd.fresh_global) g princ_ref in + (b,a) + (* mkConst(const_of_id princ_name ),g (\* FIXME *\) *) + with Not_found -> (* This one is neither defined ! *) + errorlabstrm "" (str "Cannot find induction principle for " + ++Printer.pr_lconstr (mkConst c') ) + in + (princ,NoBindings, Tacmach.pf_type_of g' princ,g') + | _ -> raise (UserError("",str "functional induction must be used with a function" )) + end + | Some ((princ,binding)) -> + princ,binding,Tacmach.pf_type_of g princ,g in let princ_infos = Tactics.compute_elim_sig princ_type in let args_as_induction_constr = @@ -116,7 +122,7 @@ let functional_induction with_clean c princl pat = princ_infos (args_as_induction_constr,princ'))) subst_and_reduce - g + g' in Dumpglob.continue (); res @@ -222,34 +228,54 @@ let process_vernac_interp_error e = let derive_inversion fix_names = try + let evd' = Evd.empty in (* we first transform the fix_names identifier into their corresponding constant *) - let fix_names_as_constant = - List.map (fun id -> fst (destConst (Constrintern.global_reference id))) fix_names + let evd',fix_names_as_constant = + List.fold_right + (fun id (evd,l) -> + let evd,c = + Evd.fresh_global + (Global.env ()) evd (Constrintern.locate_reference (Libnames.qualid_of_ident id)) in + evd, destConst c::l + ) + fix_names + (evd',[]) in (* Then we check that the graphs have been defined If one of the graphs haven't been defined we do nothing *) - List.iter (fun c -> ignore (find_Function_infos c)) fix_names_as_constant ; + List.iter (fun c -> ignore (find_Function_infos (fst c))) fix_names_as_constant ; try + let evd', lind = + List.fold_right + (fun id (evd,l) -> + let evd,id = + Evd.fresh_global + (Global.env ()) evd + (Constrintern.locate_reference (Libnames.qualid_of_ident (mk_rel_id id))) + in + evd,(fst (destInd id))::l + ) + fix_names + (evd',[]) + in Invfun.derive_correctness Functional_principles_types.make_scheme functional_induction fix_names_as_constant - (*i The next call to mk_rel_id is valid since we have just construct the graph - Ensures by : register_built - i*) - (List.map - (fun id -> fst (destInd (Constrintern.global_reference (mk_rel_id id)))) - fix_names - ) - with e when Errors.noncritical e -> + lind; + with e when Errors.noncritical e -> let e' = process_vernac_interp_error e in msg_warning (str "Cannot build inversion information" ++ if do_observe () then (fnl() ++ Errors.print e') else mt ()) - with e when Errors.noncritical e -> () + with e when Errors.noncritical e -> + let e' = process_vernac_interp_error e in + msg_warning + (str "Cannot build inversion information (early)" ++ + if do_observe () then (fnl() ++ Errors.print e') else mt ()) let warning_error names e = let e = process_vernac_interp_error e in @@ -293,7 +319,7 @@ let error_error names e = e_explain e) | _ -> raise e -let generate_principle mp_dp on_error +let generate_principle (evd:Evd.evar_map ref) pconstants on_error is_general do_built (fix_rec_l:(Vernacexpr.fixpoint_expr * Vernacexpr.decl_notation list) list) recdefs interactive_proof (continue_proof : int -> Names.constant array -> Term.constr array -> int -> Tacmach.tactic) : unit = @@ -303,7 +329,7 @@ let generate_principle mp_dp on_error let funs_types = List.map (function ((_,_,_,types,_),_) -> types) fix_rec_l in try (* We then register the Inductive graphs of the functions *) - Glob_term_to_relation.build_inductive mp_dp names funs_args funs_types recdefs; + Glob_term_to_relation.build_inductive !evd pconstants funs_args funs_types recdefs; if do_built then begin @@ -328,14 +354,18 @@ let generate_principle mp_dp on_error let _ = List.map_i (fun i x -> - let princ = Indrec.lookup_eliminator (ind_kn,i) (InProp) in - let princ_type = Global.type_of_global_unsafe princ in - Functional_principles_types.generate_functional_principle + let princ = Indrec.lookup_eliminator (ind_kn,i) (InProp) in + let evd',uprinc = Evd.fresh_global (Global.env ()) !evd princ in + let evd',princ_type = Typing.e_type_of ~refresh:true (Global.env ()) evd' uprinc in + let _ = evd := evd' in + Functional_principles_types.generate_functional_principle + evd interactive_proof princ_type None None - funs_kn + (Array.of_list pconstants) + (* funs_kn *) i (continue_proof 0 [|funs_kn.(i)|]) ) @@ -352,10 +382,37 @@ let register_struct is_rec (fixpoint_exprl:(Vernacexpr.fixpoint_expr * Vernacexp match fixpoint_exprl with | [((_,fname),_,bl,ret_type,body),_] when not is_rec -> let body = match body with | Some body -> body | None -> user_err_loc (Loc.ghost,"Function",str "Body of Function must be given") in - Command.do_definition fname (Decl_kinds.Global,(*FIXME*)false,Decl_kinds.Definition) - bl None body (Some ret_type) (Lemmas.mk_hook (fun _ _ -> ())) + Command.do_definition + fname + (Decl_kinds.Global,(Flags.is_universe_polymorphism ()),Decl_kinds.Definition) + bl None body (Some ret_type) (Lemmas.mk_hook (fun _ _ -> ())); + let evd,rev_pconstants = + List.fold_left + (fun (evd,l) (((_,fname),_,_,_,_),_) -> + let evd,c = + Evd.fresh_global + (Global.env ()) evd (Constrintern.locate_reference (Libnames.qualid_of_ident fname)) in + evd,((destConst c)::l) + ) + (Evd.empty,[]) + fixpoint_exprl + in + evd,List.rev rev_pconstants | _ -> - Command.do_fixpoint Global false(*FIXME*) fixpoint_exprl + Command.do_fixpoint Global (Flags.is_universe_polymorphism ()) fixpoint_exprl; + let evd,rev_pconstants = + List.fold_left + (fun (evd,l) (((_,fname),_,_,_,_),_) -> + let evd,c = + Evd.fresh_global + (Global.env ()) evd (Constrintern.locate_reference (Libnames.qualid_of_ident fname)) in + evd,((destConst c)::l) + ) + (Evd.empty,[]) + fixpoint_exprl + in + evd,List.rev rev_pconstants + let generate_correction_proof_wf f_ref tcc_lemma_ref is_mes functional_ref eq_ref rec_arg_num rec_arg_type nb_args relation @@ -400,10 +457,10 @@ let register_wf ?(is_mes=false) fname rec_impls wf_rel_expr wf_arg using_lemmas [(f_app_args,None);(body,None)]) in let eq = Constrexpr_ops.prod_constr_expr unbounded_eq args in - let hook (f_ref,_) tcc_lemma_ref (functional_ref,_) (eq_ref,_) rec_arg_num rec_arg_type + let hook ((f_ref,_) as fconst) tcc_lemma_ref (functional_ref,_) (eq_ref,_) rec_arg_num rec_arg_type nb_args relation = try - pre_hook + pre_hook [fconst] (generate_correction_proof_wf f_ref tcc_lemma_ref is_mes functional_ref eq_ref rec_arg_num rec_arg_type nb_args relation ); @@ -551,7 +608,7 @@ let recompute_binder_list (fixpoint_exprl : (Vernacexpr.fixpoint_expr * Vernacex fixpoint_exprl_with_new_bl -let do_generate_principle mp_dp on_error register_built interactive_proof +let do_generate_principle pconstants on_error register_built interactive_proof (fixpoint_exprl:(Vernacexpr.fixpoint_expr * Vernacexpr.decl_notation list) list) :unit = List.iter (fun (_,l) -> if not (List.is_empty l) then error "Function does not support notations for now") fixpoint_exprl; let _is_struct = @@ -566,9 +623,10 @@ let do_generate_principle mp_dp on_error register_built interactive_proof let body = match body with | Some body -> body | None -> user_err_loc (Loc.ghost,"Function",str "Body of Function must be given") in let recdefs,rec_impls = build_newrecursive fixpoint_exprl in let using_lemmas = [] in - let pre_hook = + let pre_hook pconstants = generate_principle - mp_dp + (ref (Evd.empty)) + pconstants on_error true register_built @@ -589,9 +647,10 @@ let do_generate_principle mp_dp on_error register_built interactive_proof let recdefs,rec_impls = build_newrecursive fixpoint_exprl in let using_lemmas = [] in let body = match body with | Some body -> body | None -> user_err_loc (Loc.ghost,"Function",str "Body of Function must be given") in - let pre_hook = + let pre_hook pconstants = generate_principle - mp_dp + (ref Evd.empty) + pconstants on_error true register_built @@ -615,20 +674,26 @@ let do_generate_principle mp_dp on_error register_built interactive_proof let fix_names = List.map (function (((_,name),_,_,_,_),_) -> name) fixpoint_exprl in - (* ok all the expressions are structural *) + (* ok all the expressions are structural *) let recdefs,rec_impls = build_newrecursive fixpoint_exprl in let is_rec = List.exists (is_rec fix_names) recdefs in - if register_built then register_struct is_rec fixpoint_exprl; + let evd,pconstants = + if register_built + then register_struct is_rec fixpoint_exprl + else (Evd.empty,pconstants) + in + let evd = ref evd in generate_principle - mp_dp + (ref !evd) + pconstants on_error false register_built fixpoint_exprl recdefs interactive_proof - (Functional_principles_proofs.prove_princ_for_struct interactive_proof); - if register_built then derive_inversion fix_names; + (Functional_principles_proofs.prove_princ_for_struct evd interactive_proof); + if register_built then begin derive_inversion fix_names; end; true; in () @@ -774,7 +839,7 @@ let make_graph (f_ref:global_reference) = with_full_print (fun () -> (Constrextern.extern_constr false env Evd.empty body, Constrextern.extern_type false env Evd.empty - ((*FIXNE*) Typeops.type_of_constant_type env c_body.const_type) + ((*FIXME*) Typeops.type_of_constant_type env c_body.const_type) ) ) () @@ -812,13 +877,13 @@ let make_graph (f_ref:global_reference) = [((Loc.ghost,id),(None,Constrexpr.CStructRec),nal_tas,t,Some b),[]] in let mp,dp,_ = repr_con c in - do_generate_principle (Some (mp,dp)) error_error false false expr_list; + do_generate_principle [c,Univ.Instance.empty] error_error false false expr_list; (* We register the infos *) List.iter (fun (((_,id),_,_,_,_),_) -> add_Function false (make_con mp dp (Label.of_id id))) expr_list); Dumpglob.continue () -let do_generate_principle = do_generate_principle None warning_error true +let do_generate_principle = do_generate_principle [] warning_error true |