diff options
| -rw-r--r-- | intf/tacexpr.mli | 2 | ||||
| -rw-r--r-- | lib/future.ml | 7 | ||||
| -rw-r--r-- | lib/future.mli | 12 | ||||
| -rw-r--r-- | plugins/funind/functional_principles_proofs.ml | 2 | ||||
| -rw-r--r-- | plugins/funind/functional_principles_types.ml | 4 | ||||
| -rw-r--r-- | plugins/funind/indfun.ml | 2 | ||||
| -rw-r--r-- | plugins/funind/indfun_common.ml | 3 | ||||
| -rw-r--r-- | plugins/funind/indfun_common.mli | 2 | ||||
| -rw-r--r-- | plugins/funind/invfun.ml | 4 | ||||
| -rw-r--r-- | plugins/funind/recdef.ml | 8 | ||||
| -rw-r--r-- | stm/lemmas.ml | 11 | ||||
| -rw-r--r-- | stm/stm.ml | 3 | ||||
| -rw-r--r-- | tactics/rewrite.ml | 1 | ||||
| -rw-r--r-- | toplevel/class.ml | 4 | ||||
| -rw-r--r-- | toplevel/classes.ml | 4 | ||||
| -rw-r--r-- | toplevel/command.ml | 15 | ||||
| -rw-r--r-- | toplevel/obligations.ml | 13 | ||||
| -rw-r--r-- | toplevel/vernacentries.ml | 5 |
18 files changed, 68 insertions, 34 deletions
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli index 4b4a54a035..7895ddbf47 100644 --- a/intf/tacexpr.mli +++ b/intf/tacexpr.mli @@ -273,4 +273,4 @@ type raw_tactic_arg = type raw_red_expr = (r_trm, r_cst, r_pat) red_expr_gen type glob_red_expr = (g_trm, g_cst, g_pat) red_expr_gen -type 'a declaration_hook = locality -> global_reference -> 'a +type 'a declaration_hook = 'a Future.hook diff --git a/lib/future.ml b/lib/future.ml index 77386a1a9f..960363e252 100644 --- a/lib/future.ml +++ b/lib/future.ml @@ -91,6 +91,13 @@ let from_val ?(fix_exn=id) v = create fix_exn (Val (v, None)) let from_here ?(fix_exn=id) v = create fix_exn (Val (v, Some (!freeze ()))) let fix_exn_of ck = let _, fix_exn, _ = get ck in fix_exn +type 'a hook = Decl_kinds.locality -> Globnames.global_reference -> 'a +let mk_hook hook = hook +let call_hook fix_exn hook l c = + try hook l c + with e when Errors.noncritical e -> + let e = Errors.push e in + raise (fix_exn e) let default_force () = raise NotReady let assignement ck = fun v -> diff --git a/lib/future.mli b/lib/future.mli index b4eced06a9..41f5e185c9 100644 --- a/lib/future.mli +++ b/lib/future.mli @@ -84,8 +84,18 @@ val from_val : ?fix_exn:fix_exn -> 'a -> 'a computation the value is not just the 'a but also the global system state *) val from_here : ?fix_exn:fix_exn -> 'a -> 'a computation -(* To get the fix_exn of a computation *) +(* To get the fix_exn of a computation and build a Tacexpr.declaration_hook. + * When a future enters the environment a corresponding hook is run to perform + * some work. If this fails, then its failure has to be annotated with the + * same state id that corresponds to the future computation end. I.e. Qed + * is split into two parts, the lazy one (the future) and the eagher one + * (the hook), both performing some computations for the same state id. *) val fix_exn_of : 'a computation -> fix_exn +type 'a hook +val mk_hook : + (Decl_kinds.locality -> Globnames.global_reference -> 'a) -> 'a hook +val call_hook : + fix_exn -> 'a hook -> Decl_kinds.locality -> Globnames.global_reference -> 'a (* Run remotely, returns the function to assign. Optionally tekes a function that is called when forced. The default one is to raise NotReady. diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml index f0c7b5a7f7..714192f530 100644 --- a/plugins/funind/functional_principles_proofs.ml +++ b/plugins/funind/functional_principles_proofs.ml @@ -988,7 +988,7 @@ let generate_equation_lemma fnames f fun_num nb_params nb_args rec_args_num = (mk_equation_id f_id) (Decl_kinds.Global, false, (Decl_kinds.Proof Decl_kinds.Theorem)) (lemma_type, (*FIXME*) Univ.ContextSet.empty) - (fun _ _ -> ()); + (Future.mk_hook (fun _ _ -> ())); ignore (Pfedit.by (Proofview.V82.tactic prove_replacement)); Lemmas.save_proof (Vernacexpr.Proved(false,None)) diff --git a/plugins/funind/functional_principles_types.ml b/plugins/funind/functional_principles_types.ml index a8876c75b1..65a2627070 100644 --- a/plugins/funind/functional_principles_types.ml +++ b/plugins/funind/functional_principles_types.ml @@ -290,7 +290,7 @@ let build_functional_principle interactive_proof old_princ_type sorts funs i pro let new_princ_name = next_ident_away_in_goal (Id.of_string "___________princ_________") [] in - let hook = hook new_principle_type in + let hook = Future.mk_hook (hook new_principle_type) in begin Lemmas.start_proof new_princ_name @@ -305,7 +305,7 @@ let build_functional_principle interactive_proof old_princ_type sorts funs i pro (* let dur1 = System.time_difference tim1 tim2 in *) (* Pp.msgnl (str ("Time to compute proof: ") ++ str (string_of_float dur1)); *) (* end; *) - get_proof_clean true,Ephemeron.create hook + get_proof_clean true, Ephemeron.create hook end diff --git a/plugins/funind/indfun.ml b/plugins/funind/indfun.ml index 70a892a3bb..8c8d7a667e 100644 --- a/plugins/funind/indfun.ml +++ b/plugins/funind/indfun.ml @@ -352,7 +352,7 @@ let register_struct is_rec (fixpoint_exprl:(Vernacexpr.fixpoint_expr * Vernacexp | [((_,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) (fun _ _ -> ()) + bl None body (Some ret_type) (Future.mk_hook (fun _ _ -> ())) | _ -> Command.do_fixpoint Global false(*FIXME*) fixpoint_exprl diff --git a/plugins/funind/indfun_common.ml b/plugins/funind/indfun_common.ml index 0d1e600ee6..b923260c24 100644 --- a/plugins/funind/indfun_common.ml +++ b/plugins/funind/indfun_common.ml @@ -147,6 +147,7 @@ let get_locality = function | Global -> false let save with_clean id const (locality,_,kind) hook = + let fix_exn = Future.fix_exn_of const.Entries.const_entry_body in let l,r = match locality with | Discharge when Lib.sections_are_opened () -> let k = Kindops.logical_kind_of_goal_kind kind in @@ -160,7 +161,7 @@ let save with_clean id const (locality,_,kind) hook = (locality, ConstRef kn) in if with_clean then Pfedit.delete_current_proof (); - Ephemeron.iter_opt hook (fun f -> f l r); + Ephemeron.iter_opt hook (fun f -> Future.call_hook fix_exn f l r); definition_message id diff --git a/plugins/funind/indfun_common.mli b/plugins/funind/indfun_common.mli index 6e8b79a6be..3fafeadc1c 100644 --- a/plugins/funind/indfun_common.mli +++ b/plugins/funind/indfun_common.mli @@ -46,7 +46,7 @@ val const_of_id: Id.t -> constant val jmeq : unit -> Term.constr val jmeq_refl : unit -> Term.constr -val save : bool -> Id.t -> Entries.definition_entry -> Decl_kinds.goal_kind -> +val save : bool -> Id.t -> Entries.definition_entry -> Decl_kinds.goal_kind -> unit Tacexpr.declaration_hook Ephemeron.key -> unit (* [get_proof_clean do_reduce] : returns the proof name, definition, kind and hook and diff --git a/plugins/funind/invfun.ml b/plugins/funind/invfun.ml index d5640798e2..9558923f6b 100644 --- a/plugins/funind/invfun.ml +++ b/plugins/funind/invfun.ml @@ -1080,7 +1080,7 @@ let derive_correctness make_scheme functional_induction (funs: constant list) (g Lemmas.start_proof lem_id (Decl_kinds.Global,false(*FIXME*),(Decl_kinds.Proof Decl_kinds.Theorem)) (fst lemmas_types_infos.(i), (*FIXME*)Univ.ContextSet.empty) - (fun _ _ -> ()); + (Future.mk_hook (fun _ _ -> ())); ignore (Pfedit.by (Proofview.V82.tactic (observe_tac ("prove correctness ("^(Id.to_string f_id)^")") (proving_tac i)))); @@ -1133,7 +1133,7 @@ let derive_correctness make_scheme functional_induction (funs: constant list) (g Lemmas.start_proof lem_id (Decl_kinds.Global,false(*FIXME*),(Decl_kinds.Proof Decl_kinds.Theorem)) (fst lemmas_types_infos.(i), (*FIXME*)Univ.ContextSet.empty) - (fun _ _ -> ()); + (Future.mk_hook (fun _ _ -> ())); ignore (Pfedit.by (Proofview.V82.tactic (observe_tac ("prove completeness ("^(Id.to_string f_id)^")") (proving_tac i)))); diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml index 4390143619..08d8ca3914 100644 --- a/plugins/funind/recdef.ml +++ b/plugins/funind/recdef.ml @@ -1320,7 +1320,7 @@ let open_new_goal build_proof ctx using_lemmas ref_ goal_name (gls_type,decompos na (Decl_kinds.Global, false (* FIXME *), Decl_kinds.Proof Decl_kinds.Lemma) (gls_type, ctx) - hook; + (Future.mk_hook hook); if Indfun_common.is_strict_tcc () then ignore (by (Proofview.V82.tactic (tclIDTAC))) @@ -1415,7 +1415,9 @@ let (com_eqn : int -> Id.t -> let f_constr = constr_of_global f_ref in let equation_lemma_type = subst1 f_constr equation_lemma_type in (Lemmas.start_proof eq_name (Global, false, Proof Lemma) - ~sign:(Environ.named_context_val env) (equation_lemma_type, (*FIXME*)Univ.ContextSet.empty) (fun _ _ -> ()); + ~sign:(Environ.named_context_val env) + (equation_lemma_type, (*FIXME*)Univ.ContextSet.empty) + (Future.mk_hook (fun _ _ -> ())); ignore (by (Proofview.V82.tactic (start_equation f_ref terminate_ref (fun x -> @@ -1535,5 +1537,5 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num term_id using_lemmas (List.length res_vars) - ctx hook) + ctx (Future.mk_hook hook)) () diff --git a/stm/lemmas.ml b/stm/lemmas.ml index 0668af2c50..493b874aed 100644 --- a/stm/lemmas.ml +++ b/stm/lemmas.ml @@ -168,6 +168,7 @@ let look_for_possibly_mutual_statements = function (* Saving a goal *) let save id const cstrs do_guard (locality,poly,kind) hook = + let fix_exn = Future.fix_exn_of const.Entries.const_entry_body in let const = adjust_guardness_conditions const do_guard in let k = Kindops.logical_kind_of_goal_kind kind in let l,r = match locality with @@ -183,7 +184,7 @@ let save id const cstrs do_guard (locality,poly,kind) hook = let kn = declare_constant id ~local (DefinitionEntry const, k) in (locality, ConstRef kn) in definition_message id; - hook l r + Future.call_hook fix_exn hook l r let default_thm_id = Id.of_string "Unnamed_thm" @@ -224,7 +225,7 @@ let save_remaining_recthms (locality,p,kind) body opaq i (id,((t_i,ctx_i),(_,imp let body_i = match kind_of_term body with | Fix ((nv,0),decls) -> mkFix ((nv,i),decls) | CoFix (0,decls) -> mkCoFix (i,decls) - | _ -> anomaly (Pp.str "Not a proof by induction") in + | _ -> anomaly Pp.(str "Not a proof by induction: " ++ Printer.pr_constr body) in match locality with | Discharge -> let const = definition_entry ~types:t_i ~opaque:opaq ~poly:p @@ -285,7 +286,7 @@ let admit hook () = str "declared as an axiom.") in let () = assumption_message id in - hook Global (ConstRef kn) + Future.call_hook (fun exn -> exn) hook Global (ConstRef kn) (* Starting a goal *) @@ -400,8 +401,8 @@ let start_proof_with_initialization kind recguard thms snl hook = let thms_data = (strength,ref,imps)::other_thms_data in List.iter (fun (strength,ref,imps) -> maybe_declare_manual_implicits false ref imps; - hook strength ref) thms_data in - start_proof id kind t ?init_tac hook ~compute_guard:guard + Future.call_hook (fun exn -> exn) hook strength ref) thms_data in + start_proof id kind t ?init_tac (Future.mk_hook hook) ~compute_guard:guard let start_proof_com kind thms hook = let env0 = Global.env () in diff --git a/stm/stm.ml b/stm/stm.ml index b6143df528..c708389908 100644 --- a/stm/stm.ml +++ b/stm/stm.ml @@ -763,7 +763,8 @@ end = struct !reach_known_state ~cache:`No eop; (* The original terminator, a hook, has not been saved in the .vi*) Proof_global.set_terminator - (Lemmas.standard_proof_terminator [] (fun _ _ -> ())); + (Lemmas.standard_proof_terminator [] + (Future.mk_hook (fun _ _ -> ()))); let proof = Proof_global.close_proof (fun x -> x) in vernac_interp eop ~proof { verbose = false; loc; diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml index 1e88456f36..1c98ec21dd 100644 --- a/tactics/rewrite.ml +++ b/tactics/rewrite.ml @@ -1878,6 +1878,7 @@ let add_morphism_infer glob m n = declare_projection n instance_id (ConstRef cst) | _ -> assert false in + let hook = Future.mk_hook hook in Flags.silently (fun () -> Lemmas.start_proof instance_id kind (instance, ctx) hook; diff --git a/toplevel/class.ml b/toplevel/class.ml index 9ca75d1737..1d85290511 100644 --- a/toplevel/class.ml +++ b/toplevel/class.ml @@ -304,6 +304,8 @@ let add_coercion_hook poly local ref = let msg = pr_global_env Id.Set.empty ref ++ str " is now a coercion" in Flags.if_verbose msg_info msg +let add_coercion_hook poly = Future.mk_hook (add_coercion_hook poly) + let add_subclass_hook poly local ref = let stre = match local with | Local -> true @@ -312,3 +314,5 @@ let add_subclass_hook poly local ref = in let cl = class_of_global ref in try_add_new_coercion_subclass cl stre poly + +let add_subclass_hook poly = Future.mk_hook (add_subclass_hook poly) diff --git a/toplevel/classes.ml b/toplevel/classes.ml index b9c4a42943..5d1a0a43b6 100644 --- a/toplevel/classes.ml +++ b/toplevel/classes.ml @@ -294,6 +294,7 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro in obls, Some constr, typ | None -> [||], None, termtype in + let hook = Future.mk_hook hook in let ctx = Evd.universe_context_set evm in ignore (Obligations.add_definition id ?term:constr typ ctx ~kind:(Global,poly,Instance) ~hook obls); @@ -302,7 +303,8 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro (Flags.silently (fun () -> Lemmas.start_proof id kind (termtype, Evd.universe_context_set evm) - (fun _ -> instance_hook k pri global imps ?hook); + (Future.mk_hook + (fun _ -> instance_hook k pri global imps ?hook)); (* spiwack: I don't know what to do with the status here. *) if not (Option.is_empty term) then ignore (Pfedit.by (!refine_ref (evm, Option.get term))) diff --git a/toplevel/command.ml b/toplevel/command.ml index c1283fb1f4..b49fe40a09 100644 --- a/toplevel/command.ml +++ b/toplevel/command.ml @@ -163,7 +163,7 @@ let declare_definition ident (local, p, k) ce imps hook = VarRef ident | Discharge | Local | Global -> declare_global_definition ident ce local k imps in - hook local r + Future.call_hook (Future.fix_exn_of ce.Entries.const_entry_body) hook local r let _ = Obligations.declare_definition_ref := declare_definition @@ -183,10 +183,12 @@ let do_definition ident k bl red_option c ctypopt hook = Obligations.eterm_obligations env ident evd 0 c typ in let ctx = Evd.universe_context_set evd in - ignore(Obligations.add_definition ident ~term:c cty ctx ~implicits:imps ~kind:k ~hook obls) + ignore(Obligations.add_definition + ident ~term:c cty ctx ~implicits:imps ~kind:k ~hook obls) else let ce = check_definition def in ignore(declare_definition ident k ce imps - (fun l r -> hook l r;r)) + (Future.mk_hook + (fun l r -> Future.call_hook (fun exn -> exn) hook l r;r))) (* 2| Variable/Hypothesis/Parameter/Axiom declarations *) @@ -690,7 +692,7 @@ let build_fix_type (_,ctx) ccl = it_mkProd_or_LetIn ccl ctx let declare_fix (_,poly,_ as kind) ctx f ((def,_),eff) t imps = let ce = definition_entry ~types:t ~poly ~univs:ctx ~eff def in - declare_definition f kind ce imps (fun _ r -> r) + declare_definition f kind ce imps (Future.mk_hook (fun _ r -> r)) let _ = Obligations.declare_fix_ref := declare_fix @@ -898,6 +900,7 @@ let build_wellfounded (recname,n,bl,arityc,body) r measure notation = Impargs.declare_manual_implicits false gr [impls] in hook, recname, typ in + let hook = Future.mk_hook hook in let fullcoqc = Evarutil.nf_evar !evdref def in let fullctyp = Evarutil.nf_evar !evdref typ in Obligations.check_evars env !evdref; @@ -991,7 +994,7 @@ let declare_fixpoint local poly ((fixnames,fixdefs,fixtypes),ctx,fiximps) indexe Option.map (List.map Proofview.V82.tactic) init_tac in Lemmas.start_proof_with_initialization (Global,poly,DefinitionBody Fixpoint) - (Some(false,indexes,init_tac)) thms None (fun _ _ -> ()) + (Some(false,indexes,init_tac)) thms None (Future.mk_hook (fun _ _ -> ())) else begin (* We shortcut the proof process *) let fixdefs = List.map Option.get fixdefs in @@ -1025,7 +1028,7 @@ let declare_cofixpoint local poly ((fixnames,fixdefs,fixtypes),ctx,fiximps) ntns Option.map (List.map Proofview.V82.tactic) init_tac in Lemmas.start_proof_with_initialization (Global,poly, DefinitionBody CoFixpoint) - (Some(true,[],init_tac)) thms None (fun _ _ -> ()) + (Some(true,[],init_tac)) thms None (Future.mk_hook (fun _ _ -> ())) else begin (* We shortcut the proof process *) let fixdefs = List.map Option.get fixdefs in diff --git a/toplevel/obligations.ml b/toplevel/obligations.ml index f8247c4ed6..00fc3e0ce1 100644 --- a/toplevel/obligations.ml +++ b/toplevel/obligations.ml @@ -535,7 +535,8 @@ let declare_definition prg = progmap_remove prg; !declare_definition_ref prg.prg_name prg.prg_kind ce prg.prg_implicits - (fun l r -> prg.prg_hook l r; r) + (Future.mk_hook (fun l r -> + Future.call_hook (fun exn -> exn) prg.prg_hook l r; r)) open Pp @@ -606,7 +607,7 @@ let declare_mutual_definition l = Declare.recursive_message (fixkind != IsCoFixpoint) indexes fixnames; let gr = List.hd kns in let kn = match gr with ConstRef kn -> kn | _ -> assert false in - first.prg_hook local gr; + Future.call_hook (fun exn -> exn) first.prg_hook local gr; List.iter progmap_remove l; kn let shrink_body c = @@ -815,7 +816,7 @@ let rec solve_obligation prg num tac = let kind = kind_of_obligation (pi2 prg.prg_kind) obl.obl_status in Lemmas.start_proof_univs obl.obl_name kind (Universes.subst_opt_univs_constr prg.prg_subst obl.obl_type, ctx) - (fun (subst, ctx) strength gr -> + (fun (subst, ctx) -> Future.mk_hook (fun strength gr -> let cst = match gr with ConstRef cst -> cst | _ -> assert false in let obl = let transparent = evaluable_constant cst (Global.env ()) in @@ -851,7 +852,7 @@ let rec solve_obligation prg num tac = let deps = dependencies obls num in if not (Int.Set.is_empty deps) then ignore(auto_solve_obligations (Some prg.prg_name) None ~oblset:deps) - | _ -> ()); + | _ -> ())); trace (str "Started obligation " ++ int user_num ++ str " proof: " ++ Printer.pr_constr_env (Global.env ()) obl.obl_type); ignore (Pfedit.by (snd (get_default_tactic ()))); @@ -976,7 +977,7 @@ let show_term n = ++ Printer.pr_constr_env (Global.env ()) prg.prg_body) let add_definition n ?term t ctx ?(implicits=[]) ?(kind=Global,false,Definition) ?tactic - ?(reduce=reduce) ?(hook=fun _ _ -> ()) obls = + ?(reduce=reduce) ?(hook=Future.mk_hook (fun _ _ -> ())) obls = let info = str (Id.to_string n) ++ str " has type-checked" in let prg = init_prog_info n term t ctx [] None [] obls implicits kind reduce hook in let obls,_ = prg.prg_obligations in @@ -994,7 +995,7 @@ let add_definition n ?term t ctx ?(implicits=[]) ?(kind=Global,false,Definition) | _ -> res) let add_mutual_definitions l ctx ?tactic ?(kind=Global,false,Definition) ?(reduce=reduce) - ?(hook=fun _ _ -> ()) notations fixkind = + ?(hook=Future.mk_hook (fun _ _ -> ())) notations fixkind = let deps = List.map (fun (n, b, t, imps, obls) -> n) l in List.iter (fun (n, b, t, imps, obls) -> diff --git a/toplevel/vernacentries.ml b/toplevel/vernacentries.ml index 007ab52388..1fdf95c0f5 100644 --- a/toplevel/vernacentries.ml +++ b/toplevel/vernacentries.ml @@ -452,11 +452,12 @@ let start_proof_and_print k l hook = start_proof_com k l hook; print_subgoals () -let no_hook _ _ = () +let no_hook = Future.mk_hook (fun _ _ -> ()) let vernac_definition_hook p = function | Coercion -> Class.add_coercion_hook p -| CanonicalStructure -> fun _ -> Recordops.declare_canonical_structure +| CanonicalStructure -> + Future.mk_hook (fun _ -> Recordops.declare_canonical_structure) | SubClass -> Class.add_subclass_hook p | _ -> no_hook |
