aboutsummaryrefslogtreecommitdiff
path: root/vernac
diff options
context:
space:
mode:
Diffstat (limited to 'vernac')
-rw-r--r--vernac/himsg.ml22
-rw-r--r--vernac/lemmas.ml32
-rw-r--r--vernac/lemmas.mli2
-rw-r--r--vernac/mltop.ml34
-rw-r--r--vernac/mltop.mli24
-rw-r--r--vernac/vernacentries.ml39
6 files changed, 98 insertions, 55 deletions
diff --git a/vernac/himsg.ml b/vernac/himsg.ml
index e8c5aeedd1..f00c1e6046 100644
--- a/vernac/himsg.ml
+++ b/vernac/himsg.ml
@@ -83,12 +83,12 @@ let rec contract3' env sigma a b c = function
(** Ad-hoc reductions *)
-let j_nf_betaiotaevar sigma j =
+let j_nf_betaiotaevar env sigma j =
{ uj_val = j.uj_val;
- uj_type = Reductionops.nf_betaiota sigma j.uj_type }
+ uj_type = Reductionops.nf_betaiota env sigma j.uj_type }
-let jv_nf_betaiotaevar sigma jl =
- Array.map (fun j -> j_nf_betaiotaevar sigma j) jl
+let jv_nf_betaiotaevar env sigma jl =
+ Array.map (fun j -> j_nf_betaiotaevar env sigma j) jl
(** Printers *)
@@ -258,7 +258,7 @@ let explain_number_branches env sigma cj expn =
str "expects " ++ int expn ++ str " branches."
let explain_ill_formed_branch env sigma c ci actty expty =
- let simp t = Reductionops.nf_betaiota sigma t in
+ let simp t = Reductionops.nf_betaiota env sigma t in
let env = make_all_name_different env sigma in
let pc = pr_leconstr_env env sigma c in
let pa, pe = pr_explicit env sigma (simp actty) (simp expty) in
@@ -295,8 +295,8 @@ let explain_unification_error env sigma p1 p2 = function
| NotSameArgSize | NotSameHead | NoCanonicalStructure ->
(* Error speaks from itself *) []
| ConversionFailed (env,t1,t2) ->
- let t1 = Reductionops.nf_betaiota sigma t1 in
- let t2 = Reductionops.nf_betaiota sigma t2 in
+ let t1 = Reductionops.nf_betaiota env sigma t1 in
+ let t2 = Reductionops.nf_betaiota env sigma t2 in
if EConstr.eq_constr sigma t1 p1 && EConstr.eq_constr sigma t2 p2 then [] else
let env = make_all_name_different env sigma in
if not (EConstr.eq_constr sigma t1 p1) || not (EConstr.eq_constr sigma t2 p2) then
@@ -336,8 +336,8 @@ let explain_unification_error env sigma p1 p2 = function
let explain_actual_type env sigma j t reason =
let env = make_all_name_different env sigma in
- let j = j_nf_betaiotaevar sigma j in
- let t = Reductionops.nf_betaiota sigma t in
+ let j = j_nf_betaiotaevar env sigma j in
+ let t = Reductionops.nf_betaiota env sigma t in
(** Actually print *)
let pe = pr_ne_context_of (str "In environment") env sigma in
let pc = pr_leconstr_env env sigma (Environ.j_val j) in
@@ -351,8 +351,8 @@ let explain_actual_type env sigma j t reason =
ppreason ++ str ".")
let explain_cant_apply_bad_type env sigma (n,exptyp,actualtyp) rator randl =
- let randl = jv_nf_betaiotaevar sigma randl in
- let actualtyp = Reductionops.nf_betaiota sigma actualtyp in
+ let randl = jv_nf_betaiotaevar env sigma randl in
+ let actualtyp = Reductionops.nf_betaiota env sigma actualtyp in
let env = make_all_name_different env sigma in
let actualtyp, exptyp = pr_explicit env sigma actualtyp exptyp in
let nargs = Array.length randl in
diff --git a/vernac/lemmas.ml b/vernac/lemmas.ml
index 6ef310837c..57436784b8 100644
--- a/vernac/lemmas.ml
+++ b/vernac/lemmas.ml
@@ -210,17 +210,16 @@ let save ?export_seff id const uctx do_guard (locality,poly,kind) hook =
let default_thm_id = Id.of_string "Unnamed_thm"
-let compute_proof_name locality = function
- | Some ((loc,id),pl) ->
- (* We check existence here: it's a bit late at Qed time *)
- if Nametab.exists_cci (Lib.make_path id) || is_section_variable id ||
- locality == Global && Nametab.exists_cci (Lib.make_path_except_section id)
- then
- user_err ?loc (Id.print id ++ str " already exists.");
- id
- | None ->
- let avoid = Id.Set.of_list (Proof_global.get_all_proof_names ()) in
- next_global_ident_away default_thm_id avoid
+let fresh_name_for_anonymous_theorem () =
+ let avoid = Id.Set.of_list (Proof_global.get_all_proof_names ()) in
+ next_global_ident_away default_thm_id avoid
+
+let check_name_freshness locality (loc,id) : unit =
+ (* We check existence here: it's a bit late at Qed time *)
+ if Nametab.exists_cci (Lib.make_path id) || is_section_variable id ||
+ locality == Global && Nametab.exists_cci (Lib.make_path_except_section id)
+ then
+ user_err ?loc (Id.print id ++ str " already exists.")
let save_remaining_recthms (locality,p,kind) norm univs body opaq i (id,(t_i,(_,imps))) =
let t_i = norm t_i in
@@ -435,20 +434,17 @@ let start_proof_with_initialization kind sigma decl recguard thms snl hook =
let start_proof_com ?inference_hook kind thms hook =
let env0 = Global.env () in
let decl = fst (List.hd thms) in
- let evd, decl =
- match decl with
- | None -> Evd.from_env env0, Univdecls.default_univ_decl
- | Some decl ->
- Univdecls.interp_univ_decl_opt env0 (snd decl) in
- let evd, thms = List.fold_left_map (fun evd (sopt,(bl,t)) ->
+ let evd, decl = Univdecls.interp_univ_decl_opt env0 (snd decl) in
+ let evd, thms = List.fold_left_map (fun evd ((id, _), (bl, t)) ->
let evd, (impls, ((env, ctx), imps)) = interp_context_evars env0 evd bl in
let evd, (t', imps') = interp_type_evars_impls ~impls env evd t in
let flags = all_and_fail_flags in
let flags = { flags with use_hook = inference_hook } in
let evd = solve_remaining_evars flags env evd Evd.empty in
let ids = List.map RelDecl.get_name ctx in
+ check_name_freshness (pi1 kind) id;
(* XXX: The nf_evar is critical !! *)
- evd, (compute_proof_name (pi1 kind) sopt,
+ evd, (snd id,
(Evarutil.nf_evar evd (EConstr.it_mkProd_or_LetIn t' ctx),
(ids, imps @ lift_implicits (Context.Rel.nhyps ctx) imps'))))
evd thms in
diff --git a/vernac/lemmas.mli b/vernac/lemmas.mli
index ca92e856bc..126dcd8b07 100644
--- a/vernac/lemmas.mli
+++ b/vernac/lemmas.mli
@@ -52,6 +52,8 @@ val standard_proof_terminator :
Proof_global.lemma_possible_guards -> unit declaration_hook ->
Proof_global.proof_terminator
+val fresh_name_for_anonymous_theorem : unit -> Id.t
+
(** {6 ... } *)
(** A hook the next three functions pass to cook_proof *)
diff --git a/vernac/mltop.ml b/vernac/mltop.ml
index 00554e3bae..053b9d0705 100644
--- a/vernac/mltop.ml
+++ b/vernac/mltop.ml
@@ -184,10 +184,28 @@ let warn_cannot_open_path =
type add_ml = AddNoML | AddTopML | AddRecML
-let add_rec_path add_ml ~unix_path ~coq_root ~implicit =
+type vo_path_spec = {
+ unix_path : string;
+ coq_path : Names.DirPath.t;
+ implicit : bool;
+ has_ml : add_ml;
+}
+
+type coq_path_spec =
+ | VoPath of vo_path_spec
+ | MlPath of string
+
+type coq_path = {
+ path_spec: coq_path_spec;
+ recursive: bool;
+}
+
+let add_vo_path ~recursive lp =
+ let unix_path = lp.unix_path in
+ let implicit = lp.implicit in
if exists_dir unix_path then
- let dirs = all_subdirs ~unix_path in
- let prefix = Names.DirPath.repr coq_root in
+ let dirs = if recursive then all_subdirs ~unix_path else [] in
+ let prefix = Names.DirPath.repr lp.coq_path in
let convert_dirs (lp, cp) =
try
let path = List.rev_map convert_string cp @ prefix in
@@ -195,17 +213,23 @@ let add_rec_path add_ml ~unix_path ~coq_root ~implicit =
with Exit -> None
in
let dirs = List.map_filter convert_dirs dirs in
- let () = match add_ml with
+ let () = match lp.has_ml with
| AddNoML -> ()
| AddTopML -> add_ml_dir unix_path
| AddRecML -> List.iter (fun (lp,_) -> add_ml_dir lp) dirs in
let add (path, dir) =
Loadpath.add_load_path path ~implicit dir in
let () = List.iter add dirs in
- Loadpath.add_load_path unix_path ~implicit coq_root
+ Loadpath.add_load_path unix_path ~implicit lp.coq_path
else
warn_cannot_open_path unix_path
+let add_coq_path { recursive; path_spec } = match path_spec with
+ | VoPath lp ->
+ add_vo_path ~recursive lp
+ | MlPath dir ->
+ if recursive then add_rec_ml_dir dir else add_ml_dir dir
+
(* convertit un nom quelconque en nom de fichier ou de module *)
let mod_of_name name =
if Filename.check_suffix name ".cmo" then
diff --git a/vernac/mltop.mli b/vernac/mltop.mli
index 324a66d382..e44a7c2438 100644
--- a/vernac/mltop.mli
+++ b/vernac/mltop.mli
@@ -42,14 +42,26 @@ val dir_ml_load : string -> unit
(** Dynamic interpretation of .ml *)
val dir_ml_use : string -> unit
-(** Adds a path to the ML paths *)
-val add_ml_dir : string -> unit
-val add_rec_ml_dir : string -> unit
-
+(** Adds a path to the Coq and ML paths *)
type add_ml = AddNoML | AddTopML | AddRecML
-(** Adds a path to the Coq and ML paths *)
-val add_rec_path : add_ml -> unix_path:string -> coq_root:Names.DirPath.t -> implicit:bool -> unit
+type vo_path_spec = {
+ unix_path : string; (* Filesystem path contaning vo/ml files *)
+ coq_path : Names.DirPath.t; (* Coq prefix for the path *)
+ implicit : bool; (* [implicit = true] avoids having to qualify with [coq_path] *)
+ has_ml : add_ml; (* If [has_ml] is true, the directory will also be search for plugins *)
+}
+
+type coq_path_spec =
+ | VoPath of vo_path_spec
+ | MlPath of string
+
+type coq_path = {
+ path_spec: coq_path_spec;
+ recursive: bool;
+}
+
+val add_coq_path : coq_path -> unit
(** List of modules linked to the toplevel *)
val add_known_module : string -> unit
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index 3358951f4c..be09696d1b 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -471,33 +471,40 @@ let vernac_definition_hook p = function
| SubClass -> Class.add_subclass_hook p
| _ -> no_hook
-let vernac_definition ~atts discharge kind ((loc,id as lid),pl) def =
+let vernac_definition ~atts discharge kind ((loc, id), pl) def =
let local = enforce_locality_exp atts.locality discharge in
let hook = vernac_definition_hook atts.polymorphic kind in
- let () = match local with
- | Discharge -> Dumpglob.dump_definition lid true "var"
- | Local | Global -> Dumpglob.dump_definition lid false "def"
+ let () =
+ match id with
+ | Anonymous -> ()
+ | Name n -> let lid = (loc, n) in
+ match local with
+ | Discharge -> Dumpglob.dump_definition lid true "var"
+ | Local | Global -> Dumpglob.dump_definition lid false "def"
in
let program_mode = Flags.is_program_mode () in
+ let name =
+ match id with
+ | Anonymous -> fresh_name_for_anonymous_theorem ()
+ | Name n -> n
+ in
(match def with
| ProveBody (bl,t) -> (* local binders, typ *)
- start_proof_and_print (local, atts.polymorphic, DefinitionBody kind)
- [Some (lid,pl), (bl,t)] hook
+ start_proof_and_print (local, atts.polymorphic, DefinitionBody kind)
+ [((loc, name), pl), (bl, t)] hook
| DefineBody (bl,red_option,c,typ_opt) ->
let red_option = match red_option with
| None -> None
| Some r ->
let sigma, env = Pfedit.get_current_context () in
Some (snd (Hook.get f_interp_redexp env sigma r)) in
- ComDefinition.do_definition ~program_mode id (local, atts.polymorphic, kind) pl bl red_option c typ_opt hook)
+ ComDefinition.do_definition ~program_mode name
+ (local, atts.polymorphic, kind) pl bl red_option c typ_opt hook)
let vernac_start_proof ~atts kind l =
let local = enforce_locality_exp atts.locality NoDischarge in
if Dumpglob.dump () then
- List.iter (fun (id, _) ->
- match id with
- | Some (lid,_) -> Dumpglob.dump_definition lid false "prf"
- | None -> ()) l;
+ List.iter (fun ((id, _), _) -> Dumpglob.dump_definition id false "prf") l;
start_proof_and_print (local, atts.polymorphic, Proof kind) l no_hook
let vernac_end_proof ?proof = function
@@ -905,9 +912,11 @@ let expand filename =
Envars.expand_path_macros ~warn:(fun x -> Feedback.msg_warning (str x)) filename
let vernac_add_loadpath implicit pdir ldiropt =
+ let open Mltop in
let pdir = expand pdir in
let alias = Option.default Libnames.default_root_prefix ldiropt in
- Mltop.add_rec_path Mltop.AddTopML ~unix_path:pdir ~coq_root:alias ~implicit
+ add_coq_path { recursive = true;
+ path_spec = VoPath { unix_path = pdir; coq_path = alias; has_ml = AddTopML; implicit } }
let vernac_remove_loadpath path =
Loadpath.remove_load_path (expand path)
@@ -915,7 +924,8 @@ let vernac_remove_loadpath path =
(* Coq syntax for ML or system commands *)
let vernac_add_ml_path isrec path =
- (if isrec then Mltop.add_rec_ml_dir else Mltop.add_ml_dir) (expand path)
+ let open Mltop in
+ add_coq_path { recursive = isrec; path_spec = MlPath (expand path) }
let vernac_declare_ml_module ~atts l =
let local = make_locality atts.locality in
@@ -1584,7 +1594,7 @@ let vernac_check_may_eval ~atts redexp glopt rc =
| None ->
let evars_of_term c = Evarutil.undefined_evars_of_term sigma' c in
let l = Evar.Set.union (evars_of_term j.Environ.uj_val) (evars_of_term j.Environ.uj_type) in
- let j = { j with Environ.uj_type = Reductionops.nf_betaiota sigma' j.Environ.uj_type } in
+ let j = { j with Environ.uj_type = Reductionops.nf_betaiota env sigma' j.Environ.uj_type } in
Feedback.msg_notice (print_judgment env sigma' j ++
pr_ne_evar_set (fnl () ++ str "where" ++ fnl ()) (mt ()) sigma' l ++
Printer.pr_universe_ctx_set sigma uctx)
@@ -2065,7 +2075,6 @@ let interp ?proof ~atts ~st c =
| VernacComments l -> Flags.if_verbose Feedback.msg_info (str "Comments ok\n")
(* Proof management *)
- | VernacGoal t -> vernac_start_proof ~atts Theorem [None,([],t)]
| VernacFocus n -> vernac_focus n
| VernacUnfocus -> vernac_unfocus ()
| VernacUnfocused -> vernac_unfocused ()