summaryrefslogtreecommitdiff
path: root/toplevel/vernacentries.ml
diff options
context:
space:
mode:
Diffstat (limited to 'toplevel/vernacentries.ml')
-rw-r--r--toplevel/vernacentries.ml1240
1 files changed, 1240 insertions, 0 deletions
diff --git a/toplevel/vernacentries.ml b/toplevel/vernacentries.ml
new file mode 100644
index 00000000..1c6ad9a6
--- /dev/null
+++ b/toplevel/vernacentries.ml
@@ -0,0 +1,1240 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(*i $Id: vernacentries.ml,v 1.195.2.1 2004/07/16 19:31:50 herbelin Exp $ i*)
+
+(* Concrete syntax of the mathematical vernacular MV V2.6 *)
+
+open Pp
+open Util
+open Options
+open Names
+open Entries
+open Nameops
+open Term
+open Pfedit
+open Tacmach
+open Proof_trees
+open Constrintern
+open Prettyp
+open Printer
+open Tacinterp
+open Command
+open Goptions
+open Libnames
+open Nametab
+open Vernacexpr
+open Decl_kinds
+open Topconstr
+open Pretyping
+
+(* Pcoq hooks *)
+
+type pcoq_hook = {
+ start_proof : unit -> unit;
+ solve : int -> unit;
+ abort : string -> unit;
+ search : searchable -> dir_path list * bool -> unit;
+ print_name : reference -> unit;
+ print_check : Environ.unsafe_judgment -> unit;
+ print_eval : (constr -> constr) -> Environ.env -> constr_expr ->
+ Environ.unsafe_judgment -> unit;
+ show_goal : int option -> unit
+}
+
+let pcoq = ref None
+let set_pcoq_hook f = pcoq := Some f
+
+(* Misc *)
+
+let cl_of_qualid = function
+ | FunClass -> Classops.CL_FUN
+ | SortClass -> Classops.CL_SORT
+ | RefClass r -> Class.class_of_ref (Nametab.global r)
+
+(*******************)
+(* "Show" commands *)
+
+let show_proof () =
+ let pts = get_pftreestate () in
+ let pf = proof_of_pftreestate pts in
+ let cursor = cursor_of_pftreestate pts in
+ let evc = evc_of_pftreestate pts in
+ let (pfterm,meta_types) = extract_open_pftreestate pts in
+ msgnl (str"LOC: " ++
+ prlist_with_sep pr_spc pr_int (List.rev cursor) ++ fnl () ++
+ str"Subgoals" ++ fnl () ++
+ prlist (fun (mv,ty) -> Nameops.pr_meta mv ++ str" -> " ++
+ prtype ty ++ fnl ())
+ meta_types
+ ++ str"Proof: " ++ prterm (Evarutil.nf_evar evc pfterm))
+
+let show_node () =
+ let pts = get_pftreestate () in
+ let pf = proof_of_pftreestate pts
+ and cursor = cursor_of_pftreestate pts in
+ msgnl (prlist_with_sep pr_spc pr_int (List.rev cursor) ++ fnl () ++
+ prgl (goal_of_proof pf) ++ fnl () ++
+ (match pf.Proof_type.ref with
+ | None -> (str"BY <rule>")
+ | Some(r,spfl) ->
+ (str"BY " ++ Refiner.pr_rule r ++ fnl () ++
+ str" " ++
+ hov 0 (prlist_with_sep pr_fnl prgl
+ (List.map goal_of_proof spfl)))))
+
+let show_script () =
+ let pts = get_pftreestate () in
+ let pf = proof_of_pftreestate pts
+ and evc = evc_of_pftreestate pts in
+ msgnl (Refiner.print_treescript true evc (Global.named_context()) pf)
+
+let show_top_evars () =
+ let pfts = get_pftreestate () in
+ let gls = top_goal_of_pftreestate pfts in
+ let sigma = project gls in
+ msg (pr_evars_int 1 (Evd.non_instantiated sigma))
+
+let show_prooftree () =
+ let pts = get_pftreestate () in
+ let pf = proof_of_pftreestate pts
+ and evc = evc_of_pftreestate pts in
+ msg (Refiner.print_proof evc (Global.named_context()) pf)
+
+let print_subgoals () = if_verbose (fun () -> msg (pr_open_subgoals ())) ()
+
+ (* Simulate the Intro(s) tactic *)
+
+let fresh_id_of_name avoid gl = function
+ Anonymous -> Tactics.fresh_id avoid (id_of_string "H") gl
+ | Name id -> id
+
+let rec do_renum avoid gl = function
+ [] -> mt ()
+ | [n] -> pr_id (fresh_id_of_name avoid gl n)
+ | n :: l ->
+ let id = fresh_id_of_name avoid gl n in
+ pr_id id ++ spc () ++ do_renum (id :: avoid) gl l
+
+let show_intro all =
+ let pf = get_pftreestate() in
+ let gl = nth_goal_of_pftreestate 1 pf in
+ let l,_= decompose_prod (strip_outer_cast (pf_concl gl)) in
+ let nl = List.rev_map fst l in
+ if all then
+ msgnl (do_renum [] gl nl)
+ else
+ try
+ let n = List.hd nl in
+ msgnl (pr_id (fresh_id_of_name [] gl n))
+ with Failure "hd" -> message ""
+
+(********************)
+(* "Print" commands *)
+
+let print_path_entry (s,l) =
+ (str s ++ str " " ++ tbrk (0,2) ++ str (string_of_dirpath l))
+
+let print_loadpath () =
+ let l = Library.get_full_load_path () in
+ msgnl (Pp.t (str "Physical path: " ++
+ tab () ++ str "Logical Path:" ++ fnl () ++
+ prlist_with_sep pr_fnl print_path_entry l))
+
+let print_modules () =
+ let opened = Library.opened_libraries ()
+ and loaded = Library.loaded_libraries () in
+ let loaded_opened = list_intersect loaded opened
+ and only_loaded = list_subtract loaded opened in
+ str"Loaded and imported library files: " ++
+ pr_vertical_list pr_dirpath loaded_opened ++ fnl () ++
+ str"Loaded and not imported library files: " ++
+ pr_vertical_list pr_dirpath only_loaded
+
+
+let print_module r =
+ let (loc,qid) = qualid_of_reference r in
+ try
+ let globdir = Nametab.locate_dir qid in
+ match globdir with
+ DirModule (dirpath,(mp,_)) ->
+ msgnl (Printmod.print_module (Printmod.printable_body dirpath) mp)
+ | _ -> raise Not_found
+ with
+ Not_found -> msgnl (str"Unknown Module " ++ pr_qualid qid)
+
+let print_modtype r =
+ let (loc,qid) = qualid_of_reference r in
+ try
+ let kn = Nametab.locate_modtype qid in
+ msgnl (Printmod.print_modtype kn)
+ with
+ Not_found -> msgnl (str"Unknown Module Type " ++ pr_qualid qid)
+
+let dump_universes s =
+ let output = open_out s in
+ try
+ Univ.dump_universes output (Global.universes ());
+ close_out output;
+ msgnl (str ("Universes written to file \""^s^"\"."))
+ with
+ e -> close_out output; raise e
+
+(*********************)
+(* "Locate" commands *)
+
+let locate_file f =
+ try
+ let _,file =
+ System.where_in_path (Library.get_load_path()) f in
+ msgnl (str file)
+ with Not_found ->
+ msgnl (hov 0 (str"Can't find file" ++ spc () ++ str f ++ spc () ++
+ str"on loadpath"))
+
+let msg_found_library = function
+ | Library.LibLoaded, fulldir, file ->
+ msgnl(pr_dirpath fulldir ++ str " has been loaded from file" ++ fnl () ++
+ str file)
+ | Library.LibInPath, fulldir, file ->
+ msgnl(pr_dirpath fulldir ++ str " is bound to file " ++ str file)
+let msg_notfound_library loc qid = function
+ | Library.LibUnmappedDir ->
+ let dir = fst (repr_qualid qid) in
+ user_err_loc (loc,"locate_library",
+ str "Cannot find a physical path bound to logical path " ++
+ pr_dirpath dir ++ fnl ())
+ | Library.LibNotFound ->
+ msgnl (hov 0
+ (str"Unable to locate library" ++ spc () ++ pr_qualid qid))
+ | e -> assert false
+
+let print_located_library r =
+ let (loc,qid) = qualid_of_reference r in
+ try msg_found_library (Library.locate_qualified_library qid)
+ with e -> msg_notfound_library loc qid e
+
+(**********)
+(* Syntax *)
+
+let vernac_syntax = Metasyntax.add_syntax_obj
+
+let vernac_grammar = Metasyntax.add_grammar_obj
+
+let vernac_syntax_extension = Metasyntax.add_syntax_extension
+
+let vernac_delimiters = Metasyntax.add_delimiters
+
+let vernac_bind_scope sc cll =
+ List.iter (fun cl -> Metasyntax.add_class_scope sc (cl_of_qualid cl)) cll
+
+let vernac_open_close_scope = Symbols.open_close_scope
+
+let vernac_arguments_scope qid scl =
+ Symbols.declare_arguments_scope (global qid) scl
+
+let vernac_infix = Metasyntax.add_infix
+
+let vernac_distfix = Metasyntax.add_distfix
+
+let vernac_notation = Metasyntax.add_notation
+
+(***********)
+(* Gallina *)
+
+let start_proof_and_print idopt k t hook =
+ start_proof_com idopt k t hook;
+ print_subgoals ();
+ if !pcoq <> None then (out_some !pcoq).start_proof ()
+
+let vernac_definition (local,_ as k) id def hook =
+ match def with
+ | ProveBody (bl,t) -> (* local binders, typ *)
+ if Lib.is_modtype () then
+ errorlabstrm "Vernacentries.VernacDefinition"
+ (str "Proof editing mode not supported in module types")
+ else
+ let hook _ _ = () in
+ let kind = if local=Local then IsLocal else IsGlobal DefinitionBody in
+ start_proof_and_print (Some id) kind (bl,t) hook
+ | DefineBody (bl,red_option,c,typ_opt) ->
+ let red_option = match red_option with
+ | None -> None
+ | Some r ->
+ let (evc,env)= Command.get_current_context () in
+ Some (interp_redexp env evc r) in
+ declare_definition id k bl red_option c typ_opt hook
+
+let vernac_start_proof kind sopt (bl,t) lettop hook =
+ if not(refining ()) then
+ if lettop then
+ errorlabstrm "Vernacentries.StartProof"
+ (str "Let declarations can only be used in proof editing mode");
+ if Lib.is_modtype () then
+ errorlabstrm "Vernacentries.StartProof"
+ (str "Proof editing mode not supported in module types");
+ start_proof_and_print sopt (IsGlobal (Proof kind)) (bl,t) hook
+
+let vernac_end_proof = function
+ | Admitted -> admit ()
+ | Proved (is_opaque,idopt) ->
+ if_verbose show_script ();
+ match idopt with
+ | None -> save_named is_opaque
+ | Some ((_,id),None) -> save_anonymous is_opaque id
+ | Some ((_,id),Some kind) -> save_anonymous_with_strength kind is_opaque id
+
+ (* A stupid macro that should be replaced by ``Exact c. Save.'' all along
+ the theories [??] *)
+
+let vernac_exact_proof c =
+ by (Tactics.exact_proof c);
+ save_named true
+
+let vernac_assumption kind l =
+ List.iter (fun (is_coe,(idl,c)) -> declare_assumption idl is_coe kind [] c) l
+
+let vernac_inductive f indl = build_mutual indl f
+
+let vernac_fixpoint = build_recursive
+
+let vernac_cofixpoint = build_corecursive
+
+let vernac_scheme = build_scheme
+
+(**********************)
+(* Modules *)
+
+let vernac_declare_module id binders_ast mty_ast_o mexpr_ast_o =
+ (* We check the state of the system (in section, in module type)
+ and what module information is supplied *)
+ if Lib.sections_are_opened () then
+ error "Modules and Module Types are not allowed inside sections";
+
+ if not (Lib.is_modtype ()) then
+ error "Declare Module allowed in module types only";
+
+ let constrain_mty = match mty_ast_o with
+ Some (_,true) -> true
+ | _ -> false
+ in
+
+ match mty_ast_o, constrain_mty, mexpr_ast_o with
+ | _, false, None -> (* no ident, no/soft type *)
+ Declaremods.start_module Modintern.interp_modtype
+ id binders_ast mty_ast_o;
+ if_verbose message
+ ("Interactive Declaration of Module "^ string_of_id id ^" started")
+
+ | Some _, true, None (* no ident, hard type *)
+ | _, false, Some (CMEident _) -> (* ident, no/soft type *)
+ Declaremods.declare_module
+ Modintern.interp_modtype Modintern.interp_modexpr
+ id binders_ast mty_ast_o mexpr_ast_o;
+ if_verbose message
+ ("Module "^ string_of_id id ^" is declared")
+
+ | _, true, Some (CMEident _) -> (* ident, hard type *)
+ error "You cannot declare an equality and a type in module declaration"
+
+ | _, _, Some _ -> (* not ident *)
+ error "Only simple modules allowed in module declarations"
+
+ | None,true,None -> assert false (* 1st None ==> false *)
+
+let vernac_define_module id binders_ast mty_ast_o mexpr_ast_o =
+ (* We check the state of the system (in section, in module type)
+ and what module information is supplied *)
+ if Lib.sections_are_opened () then
+ error "Modules and Module Types are not allowed inside sections";
+
+ if Lib.is_modtype () then
+ error "Module definitions not allowed in module types. Use Declare Module instead";
+
+ match mexpr_ast_o with
+ | None ->
+ Declaremods.start_module Modintern.interp_modtype
+ id binders_ast mty_ast_o;
+ if_verbose message
+ ("Interactive Module "^ string_of_id id ^" started")
+
+ | Some _ ->
+ Declaremods.declare_module
+ Modintern.interp_modtype Modintern.interp_modexpr
+ id binders_ast mty_ast_o mexpr_ast_o;
+ if_verbose message
+ ("Module "^ string_of_id id ^" is defined")
+
+(* let vernac_declare_module id binders_ast mty_ast_o mexpr_ast_o = *)
+(* (\* We check the state of the system (in section, in module type) *)
+(* and what module information is supplied *\) *)
+(* if Lib.sections_are_opened () then *)
+(* error "Modules and Module Types are not allowed inside sections"; *)
+
+(* let constrain_mty = match mty_ast_o with *)
+(* Some (_,true) -> true *)
+(* | _ -> false *)
+(* in *)
+
+(* match Lib.is_modtype (), mty_ast_o, constrain_mty, mexpr_ast_o with *)
+(* | _, None, _, None *)
+(* | true, Some _, false, None *)
+(* | false, _, _, None -> *)
+(* Declaremods.start_module Modintern.interp_modtype *)
+(* id binders_ast mty_ast_o; *)
+(* if_verbose message *)
+(* ("Interactive Module "^ string_of_id id ^" started") *)
+
+(* | true, Some _, true, None *)
+(* | true, _, false, Some (CMEident _) *)
+(* | false, _, _, Some _ -> *)
+(* Declaremods.declare_module *)
+(* Modintern.interp_modtype Modintern.interp_modexpr *)
+(* id binders_ast mty_ast_o mexpr_ast_o; *)
+(* if_verbose message *)
+(* ("Module "^ string_of_id id ^" is defined") *)
+
+(* | true, _, _, _ -> *)
+(* error "Module definition not allowed in a Module Type" *)
+
+let vernac_end_module id =
+ Declaremods.end_module id;
+ if_verbose message
+ (if Lib.is_modtype () then
+ "Module "^ string_of_id id ^" is declared"
+ else
+ "Module "^ string_of_id id ^" is defined")
+
+
+
+
+let vernac_declare_module_type id binders_ast mty_ast_o =
+ if Lib.sections_are_opened () then
+ error "Modules and Module Types are not allowed inside sections";
+
+ match mty_ast_o with
+ | None ->
+ Declaremods.start_modtype Modintern.interp_modtype id binders_ast;
+ if_verbose message
+ ("Interactive Module Type "^ string_of_id id ^" started")
+
+ | Some base_mty ->
+ Declaremods.declare_modtype Modintern.interp_modtype
+ id binders_ast base_mty;
+ if_verbose message
+ ("Module Type "^ string_of_id id ^" is defined")
+
+
+let vernac_end_modtype id =
+ Declaremods.end_modtype id;
+ if_verbose message
+ ("Module Type "^ string_of_id id ^" is defined")
+
+
+(**********************)
+(* Gallina extensions *)
+
+let vernac_record struc binders sort nameopt cfs =
+ let const = match nameopt with
+ | None -> add_prefix "Build_" (snd (snd struc))
+ | Some (_,id) -> id in
+ let sigma = Evd.empty in
+ let env = Global.env() in
+ let s = interp_constr sigma env sort in
+ let s = Reductionops.whd_betadeltaiota env sigma s in
+ let s = match kind_of_term s with
+ | Sort s -> s
+ | _ -> user_err_loc
+ (constr_loc sort,"definition_structure", str "Sort expected") in
+ Record.definition_structure (struc,binders,cfs,const,s)
+
+ (* Sections *)
+
+let vernac_begin_section id = let _ = Lib.open_section id in ()
+
+let vernac_end_section id =
+ Discharge.close_section (is_verbose ()) id
+
+
+let vernac_end_segment id =
+ check_no_pending_proofs ();
+ try
+ match Lib.what_is_opened () with
+ | _,Lib.OpenedModule _ -> vernac_end_module id
+ | _,Lib.OpenedModtype _ -> vernac_end_modtype id
+ | _,Lib.OpenedSection _ -> vernac_end_section id
+ | _ -> anomaly "No more opened things"
+ with
+ Not_found -> error "There is nothing to end."
+
+let is_obsolete_module (_,qid) =
+ match repr_qualid qid with
+ | dir, id when dir = empty_dirpath ->
+ (match string_of_id id with
+ | ("Refine" | "Inv" | "Equality" | "EAuto" | "AutoRewrite"
+ | "EqDecide" | "Xml" | "Extraction" | "Tauto" | "Setoid_replace"
+ | "Elimdep"
+ | "DatatypesSyntax" | "LogicSyntax" | "Logic_TypeSyntax"
+ | "SpecifSyntax" | "PeanoSyntax" | "TypeSyntax" | "PolyListSyntax")
+ -> true
+ | _ -> false)
+ | _ -> false
+
+let test_renamed_module (_,qid) =
+ match repr_qualid qid with
+ | dir, id when dir = empty_dirpath ->
+ (match string_of_id id with
+ | "List" -> warning "List has been renamed into MonoList"
+ | "PolyList" -> warning "PolyList has been renamed into List and old List into MonoList"
+ | _ -> ())
+ | _ -> ()
+
+let vernac_require import _ qidl =
+ let qidl = List.map qualid_of_reference qidl in
+ try
+ match import with
+ | None -> List.iter Library.read_library qidl
+ | Some b -> Library.require_library None qidl b
+ with e ->
+ (* Compatibility message *)
+ let qidl' = List.filter is_obsolete_module qidl in
+ if qidl' = qidl then
+ List.iter
+ (fun (_,qid) ->
+ warning ("Module "^(string_of_qualid qid)^
+ " is now built-in and shouldn't be required")) qidl
+ else
+ (if not !Options.v7 then List.iter test_renamed_module qidl;
+ raise e)
+
+let vernac_import export refl =
+ let import_one ref =
+ let qid = qualid_of_reference ref in
+ Library.import_library export qid
+ in
+ List.iter import_one refl;
+ Lib.add_frozen_state ()
+
+(* else
+ let import (loc,qid) =
+ try
+ let mp = Nametab.locate_module qid in
+ Declaremods.import_module mp
+ with Not_found ->
+ user_err_loc
+ (loc,"vernac_import",
+ str ((string_of_qualid qid)^" is not a module"))
+ in
+ List.iter import qidl;
+*)
+
+let vernac_canonical locqid =
+ Recordobj.objdef_declare (Nametab.global locqid)
+
+let locate_reference ref =
+ let (loc,qid) = qualid_of_reference ref in
+ try match Nametab.extended_locate qid with
+ | TrueGlobal ref -> ref
+ | SyntacticDef kn ->
+ match Syntax_def.search_syntactic_definition loc kn with
+ | Rawterm.RRef (_,ref) -> ref
+ | _ -> raise Not_found
+ with Not_found ->
+ error_global_not_found_loc loc qid
+
+let vernac_coercion stre ref qids qidt =
+ let target = cl_of_qualid qidt in
+ let source = cl_of_qualid qids in
+ let ref' = locate_reference ref in
+ Class.try_add_new_coercion_with_target ref' stre source target;
+ if_verbose message ((string_of_reference ref) ^ " is now a coercion")
+
+let vernac_identity_coercion stre id qids qidt =
+ let target = cl_of_qualid qidt in
+ let source = cl_of_qualid qids in
+ Class.try_add_new_identity_coercion id stre source target
+
+
+(***********)
+(* Solving *)
+let vernac_solve n tcom b =
+ if not (refining ()) then
+ error "Unknown command of the non proof-editing mode";
+ begin
+ if b then
+ solve_nth n (Tacinterp.hide_interp tcom (get_end_tac ()))
+ else solve_nth n (Tacinterp.hide_interp tcom None)
+ end;
+ (* in case a strict subtree was completed,
+ go back to the top of the prooftree *)
+ if subtree_solved () then begin
+ Options.if_verbose msgnl (str "Subgoal proved");
+ make_focus 0;
+ reset_top_of_tree ()
+ end;
+ print_subgoals();
+ if !pcoq <> None then (out_some !pcoq).solve n
+
+ (* A command which should be a tactic. It has been
+ added by Christine to patch an error in the design of the proof
+ machine, and enables to instantiate existential variables when
+ there are no more goals to solve. It cannot be a tactic since
+ all tactics fail if there are no further goals to prove. *)
+
+let vernac_solve_existential = instantiate_nth_evar_com
+
+let vernac_set_end_tac tac =
+ if not (refining ()) then
+ error "Unknown command of the non proof-editing mode";
+ if tac <> (Tacexpr.TacId "") then set_end_tac (Tacinterp.interp tac)
+(* TO DO verifier s'il faut pas mettre exist s | TacId s ici*)
+
+
+(*****************************)
+(* Auxiliary file management *)
+
+let vernac_require_from export spec filename =
+ match export with
+ Some exp ->
+ Library.require_library_from_file spec None filename exp
+ | None -> Library.read_library_from_file filename
+
+let vernac_add_loadpath isrec pdir ldiropt =
+ let alias = match ldiropt with
+ | None -> Nameops.default_root_prefix
+ | Some ldir -> ldir in
+ (if isrec then Mltop.add_rec_path else Mltop.add_path) pdir alias
+
+let vernac_remove_loadpath = Library.remove_path
+
+ (* Coq syntax for ML or system commands *)
+
+let vernac_add_ml_path isrec s =
+ (if isrec then Mltop.add_rec_ml_dir else Mltop.add_ml_dir) (System.glob s)
+
+let vernac_declare_ml_module l = Mltop.declare_ml_modules l
+
+let vernac_chdir = function
+ | None -> message (Sys.getcwd())
+ | Some s ->
+ begin
+ try Sys.chdir (System.glob s)
+ with Sys_error str -> warning ("Cd failed: " ^ str)
+ end;
+ if_verbose message (Sys.getcwd())
+
+
+(********************)
+(* State management *)
+
+let abort_refine f x =
+ if Pfedit.refining() then delete_all_proofs ();
+ f x
+ (* used to be: error "Must save or abort current goal first" *)
+
+let vernac_write_state file = abort_refine States.extern_state file
+
+let vernac_restore_state file = abort_refine States.intern_state file
+
+
+(*************)
+(* Resetting *)
+
+let vernac_reset_name id = abort_refine Lib.reset_name id
+
+let vernac_reset_initial () = abort_refine Lib.reset_initial ()
+
+let vernac_back n = Lib.back n
+
+
+(************)
+(* Commands *)
+
+let vernac_declare_tactic_definition = Tacinterp.add_tacdef
+
+let vernac_hints = Auto.add_hints
+
+let vernac_syntactic_definition = Command.syntax_definition
+
+let vernac_declare_implicits locqid = function
+ | Some imps -> Impargs.declare_manual_implicits (Nametab.global locqid) imps
+ | None -> Impargs.declare_implicits (Nametab.global locqid)
+
+let vernac_reserve idl c =
+ let t = Constrintern.interp_type Evd.empty (Global.env()) c in
+ let t = Detyping.detype (false,Global.env()) [] [] t in
+ List.iter (fun id -> Reserve.declare_reserved_type id t) idl
+
+let make_silent_if_not_pcoq b =
+ if !pcoq <> None then
+ error "Turning on/off silent flag is not supported in Centaur mode"
+ else make_silent b
+
+let _ =
+ declare_bool_option
+ { optsync = false;
+ optname = "silent";
+ optkey = (PrimaryTable "Silent");
+ optread = is_silent;
+ optwrite = make_silent_if_not_pcoq }
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optname = "implicit arguments";
+ optkey = (SecondaryTable ("Implicit","Arguments"));
+ optread = Impargs.is_implicit_args;
+ optwrite = Impargs.make_implicit_args }
+
+let impargs = if !Options.v7 then "Implicits" else "Implicit"
+
+let _ =
+ declare_bool_option
+ { optsync = false; (* synchronisation is in Impargs *)
+ optname = "strict implicit arguments";
+ optkey = (SecondaryTable ("Strict",impargs));
+ optread = Impargs.is_strict_implicit_args;
+ optwrite = Impargs.make_strict_implicit_args }
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optname = "contextual implicit arguments";
+ optkey = (SecondaryTable ("Contextual",impargs));
+ optread = Impargs.is_contextual_implicit_args;
+ optwrite = Impargs.make_contextual_implicit_args }
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optname = "coercion printing";
+ optkey = (SecondaryTable ("Printing","Coercions"));
+ optread = (fun () -> !Constrextern.print_coercions);
+ optwrite = (fun b -> Constrextern.print_coercions := b) }
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optname = "implicit arguments printing";
+ optkey = (SecondaryTable ("Printing",impargs));
+ optread = (fun () -> !Constrextern.print_implicits);
+ optwrite = (fun b -> Constrextern.print_implicits := b) }
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optname = "projection printing using dot notation";
+ optkey = (SecondaryTable ("Printing","Projections"));
+ optread = (fun () -> !Constrextern.print_projections);
+ optwrite = (fun b -> Constrextern.print_projections := b) }
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optname = "notations printing";
+ optkey = (SecondaryTable ("Printing",if !Options.v7 then "Symbols" else "Notations"));
+ optread = (fun () -> not !Constrextern.print_no_symbol);
+ optwrite = (fun b -> Constrextern.print_no_symbol := not b) }
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optname = "raw printing";
+ optkey = (SecondaryTable ("Printing","All"));
+ optread = (fun () -> !Options.raw_print);
+ optwrite = (fun b -> Options.raw_print := b) }
+
+let _ =
+ declare_int_option
+ { optsync=false;
+ optkey=PrimaryTable("Undo");
+ optname="the undo limit";
+ optread=Pfedit.get_undo;
+ optwrite=Pfedit.set_undo }
+
+let _ =
+ declare_int_option
+ { optsync=false;
+ optkey=SecondaryTable("Hyps","Limit");
+ optname="the hypotheses limit";
+ optread=Options.print_hyps_limit;
+ optwrite=Options.set_print_hyps_limit }
+
+let _ =
+ declare_int_option
+ { optsync=true;
+ optkey=SecondaryTable("Printing","Depth");
+ optname="the printing depth";
+ optread=Pp_control.get_depth_boxes;
+ optwrite=Pp_control.set_depth_boxes }
+
+let _ =
+ declare_int_option
+ { optsync=true;
+ optkey=SecondaryTable("Printing","Width");
+ optname="the printing width";
+ optread=Pp_control.get_margin;
+ optwrite=Pp_control.set_margin }
+
+let vernac_set_opacity opaq locqid =
+ match Nametab.global locqid with
+ | ConstRef sp ->
+ if opaq then Tacred.set_opaque_const sp
+ else Tacred.set_transparent_const sp
+ | VarRef id ->
+ if opaq then Tacred.set_opaque_var id
+ else Tacred.set_transparent_var id
+ | _ -> error "cannot set an inductive type or a constructor as transparent"
+
+let vernac_set_option key = function
+ | StringValue s -> set_string_option_value key s
+ | IntValue n -> set_int_option_value key (Some n)
+ | BoolValue b -> set_bool_option_value key b
+
+let vernac_unset_option key =
+ try set_bool_option_value key false
+ with _ ->
+ set_int_option_value key None
+
+let vernac_add_option key lv =
+ let f = function
+ | StringRefValue s -> (get_string_table key)#add s
+ | QualidRefValue locqid -> (get_ref_table key)#add locqid
+ in
+ try List.iter f lv with Not_found -> error_undeclared_key key
+
+let vernac_remove_option key lv =
+ let f = function
+ | StringRefValue s -> (get_string_table key)#remove s
+ | QualidRefValue locqid -> (get_ref_table key)#remove locqid
+ in
+ try List.iter f lv with Not_found -> error_undeclared_key key
+
+let vernac_mem_option key lv =
+ let f = function
+ | StringRefValue s -> (get_string_table key)#mem s
+ | QualidRefValue locqid -> (get_ref_table key)#mem locqid
+ in
+ try List.iter f lv with Not_found -> error_undeclared_key key
+
+let vernac_print_option key =
+ try (get_ref_table key)#print
+ with Not_found ->
+ try (get_string_table key)#print
+ with Not_found ->
+ try print_option_value key
+ with Not_found -> error_undeclared_key key
+
+let get_current_context_of_args = function
+ | Some n -> get_goal_context n
+ | None -> get_current_context ()
+
+let vernac_check_may_eval redexp glopt rc =
+ let (evmap,env) = get_current_context_of_args glopt in
+ let c = interp_constr evmap env rc in
+ let j = Typeops.typing env c in
+ match redexp with
+ | None ->
+ if !pcoq <> None then (out_some !pcoq).print_check j
+ else msg (print_judgment env j)
+ | Some r ->
+ let redfun = Tacred.reduction_of_redexp (interp_redexp env evmap r) in
+ if !pcoq <> None
+ then (out_some !pcoq).print_eval (redfun env evmap) env rc j
+ else msg (print_eval redfun env j)
+
+ (* The same but avoiding the current goal context if any *)
+let vernac_global_check c =
+ let evmap = Evd.empty in
+ let env = Global.env() in
+ let c = interp_constr evmap env c in
+ let senv = Global.safe_env() in
+ let j = Safe_typing.typing senv c in
+ msg (print_safe_judgment env j)
+
+let vernac_print = function
+ | PrintTables -> print_tables ()
+ | PrintLocalContext -> msg (print_local_context ())
+ | PrintFullContext -> msg (print_full_context_typ ())
+ | PrintSectionContext qid -> msg (print_sec_context_typ qid)
+ | PrintInspect n -> msg (inspect n)
+ | PrintGrammar (uni,ent) -> Metasyntax.print_grammar uni ent
+ | PrintLoadPath -> (* For compatibility ? *) print_loadpath ()
+ | PrintModules -> msg (print_modules ())
+ | PrintModule qid -> print_module qid
+ | PrintModuleType qid -> print_modtype qid
+ | PrintMLLoadPath -> Mltop.print_ml_path ()
+ | PrintMLModules -> Mltop.print_ml_modules ()
+ | PrintName qid ->
+ if !pcoq <> None then (out_some !pcoq).print_name qid
+ else msg (print_name qid)
+ | PrintOpaqueName qid -> msg (print_opaque_name qid)
+ | PrintGraph -> ppnl (Prettyp.print_graph())
+ | PrintClasses -> ppnl (Prettyp.print_classes())
+ | PrintCoercions -> ppnl (Prettyp.print_coercions())
+ | PrintCoercionPaths (cls,clt) ->
+ ppnl (Prettyp.print_path_between (cl_of_qualid cls) (cl_of_qualid clt))
+ | PrintUniverses None -> pp (Univ.pr_universes (Global.universes ()))
+ | PrintUniverses (Some s) -> dump_universes s
+ | PrintHint qid -> Auto.print_hint_ref (Nametab.global qid)
+ | PrintHintGoal -> Auto.print_applicable_hint ()
+ | PrintHintDbName s -> Auto.print_hint_db_by_name s
+ | PrintHintDb -> Auto.print_searchtable ()
+ | PrintScopes ->
+ pp (Symbols.pr_scopes (Constrextern.without_symbols pr_rawterm))
+ | PrintScope s ->
+ pp (Symbols.pr_scope (Constrextern.without_symbols pr_rawterm) s)
+ | PrintVisibility s ->
+ pp (Symbols.pr_visibility (Constrextern.without_symbols pr_rawterm) s)
+ | PrintAbout qid -> msgnl (print_about qid)
+ | PrintImplicit qid -> msg (print_impargs qid)
+
+let global_module r =
+ let (loc,qid) = qualid_of_reference r in
+ try Nametab.full_name_module qid
+ with Not_found ->
+ user_err_loc (loc, "global_module",
+ str "Module/section " ++ pr_qualid qid ++ str " not found")
+
+let interp_search_restriction = function
+ | SearchOutside l -> (List.map global_module l, true)
+ | SearchInside l -> (List.map global_module l, false)
+
+open Search
+
+let interp_search_about_item = function
+ | SearchRef qid -> GlobSearchRef (Nametab.global qid)
+ | SearchString s -> GlobSearchString s
+
+let vernac_search s r =
+ let r = interp_search_restriction r in
+ if !pcoq <> None then (out_some !pcoq).search s r else
+ match s with
+ | SearchPattern c ->
+ let _,pat = interp_constrpattern Evd.empty (Global.env()) c in
+ Search.search_pattern pat r
+ | SearchRewrite c ->
+ let _,pat = interp_constrpattern Evd.empty (Global.env()) c in
+ Search.search_rewrite pat r
+ | SearchHead locqid ->
+ Search.search_by_head (Nametab.global locqid) r
+ | SearchAbout sl ->
+ Search.search_about (List.map interp_search_about_item sl) r
+
+let vernac_locate = function
+ | LocateTerm qid -> msgnl (print_located_qualid qid)
+ | LocateLibrary qid -> print_located_library qid
+ | LocateFile f -> locate_file f
+ | LocateNotation ntn ->
+ ppnl (Symbols.locate_notation (Constrextern.without_symbols pr_rawterm)
+ (Metasyntax.standardise_locatable_notation ntn))
+
+(********************)
+(* Proof management *)
+
+let vernac_goal = function
+ | None -> ()
+ | Some c ->
+ if not (refining()) then begin
+ let unnamed_kind = Lemma (* Arbitrary *) in
+ start_proof_com None (IsGlobal (Proof unnamed_kind)) c (fun _ _ ->());
+ print_subgoals ()
+ end else
+ error "repeated Goal not permitted in refining mode"
+
+let vernac_abort = function
+ | None ->
+ delete_current_proof ();
+ if_verbose message "Current goal aborted";
+ if !pcoq <> None then (out_some !pcoq).abort ""
+ | Some id ->
+ delete_proof id;
+ let s = string_of_id (snd id) in
+ if_verbose message ("Goal "^s^" aborted");
+ if !pcoq <> None then (out_some !pcoq).abort s
+
+let vernac_abort_all () =
+ if refining() then begin
+ delete_all_proofs ();
+ message "Current goals aborted"
+ end else
+ error "No proof-editing in progress"
+
+let vernac_restart () = restart_proof(); print_subgoals ()
+
+ (* Proof switching *)
+
+let vernac_suspend = suspend_proof
+
+let vernac_resume = function
+ | None -> resume_last_proof ()
+ | Some id -> resume_proof id
+
+let vernac_undo n =
+ undo n;
+ print_subgoals ()
+
+ (* Est-ce normal que "Focus" ne semble pas se comporter comme "Focus 1" ? *)
+let vernac_focus = function
+ | None -> traverse_nth_goal 1; print_subgoals ()
+ | Some n -> traverse_nth_goal n; print_subgoals ()
+
+ (* Reset the focus to the top of the tree *)
+let vernac_unfocus () =
+ make_focus 0; reset_top_of_tree (); print_subgoals ()
+
+let vernac_go = function
+ | GoTo n -> Pfedit.traverse n;show_node()
+ | GoTop -> Pfedit.reset_top_of_tree ();show_node()
+ | GoNext -> Pfedit.traverse_next_unproven ();show_node()
+ | GoPrev -> Pfedit.traverse_prev_unproven ();show_node()
+
+let apply_subproof f occ =
+ let pts = get_pftreestate() in
+ let evc = evc_of_pftreestate pts in
+ let rec aux pts = function
+ | [] -> pts
+ | (n::l) -> aux (Tacmach.traverse n pts) occ in
+ let pts = aux pts (occ@[-1]) in
+ let pf = proof_of_pftreestate pts in
+ f evc (Global.named_context()) pf
+
+let explain_proof occ =
+ msg (apply_subproof (Refiner.print_treescript true) occ)
+
+let explain_tree occ =
+ msg (apply_subproof Refiner.print_proof occ)
+
+let vernac_show = function
+ | ShowGoal nopt ->
+ if !pcoq <> None then (out_some !pcoq).show_goal nopt
+ else msg (match nopt with
+ | None -> pr_open_subgoals ()
+ | Some n -> pr_nth_open_subgoal n)
+ | ShowGoalImplicitly None ->
+ Constrextern.with_implicits msg (pr_open_subgoals ())
+ | ShowGoalImplicitly (Some n) ->
+ Constrextern.with_implicits msg (pr_nth_open_subgoal n)
+ | ShowProof -> show_proof ()
+ | ShowNode -> show_node ()
+ | ShowScript -> show_script ()
+ | ShowExistentials -> show_top_evars ()
+ | ShowTree -> show_prooftree ()
+ | ShowProofNames ->
+ msgnl (prlist_with_sep pr_spc pr_id (Pfedit.get_all_proof_names()))
+ | ShowIntros all -> show_intro all
+ | ExplainProof occ -> explain_proof occ
+ | ExplainTree occ -> explain_tree occ
+
+let vernac_check_guard () =
+ let pts = get_pftreestate () in
+ let pf = proof_of_pftreestate pts
+ and cursor = cursor_of_pftreestate pts in
+ let (pfterm,_) = extract_open_pftreestate pts in
+ let message =
+ try
+ Inductiveops.control_only_guard (Evarutil.evar_env (goal_of_proof pf))
+ pfterm;
+ (str "The condition holds up to here")
+ with UserError(_,s) ->
+ (str ("Condition violated : ") ++s)
+ in
+ msgnl message
+
+let vernac_debug b =
+ set_debug (if b then Tactic_debug.DebugOn 0 else Tactic_debug.DebugOff)
+
+
+(**************************)
+(* Not supported commands *)
+(***
+let _ =
+ add "ResetSection"
+ (function
+ | [VARG_IDENTIFIER id] ->
+ (fun () -> reset_section (string_of_id id))
+ | _ -> bad_vernac_args "ResetSection")
+
+(* Modules *)
+
+let _ =
+ vinterp_add "BeginModule"
+ (function
+ | [VARG_IDENTIFIER id] ->
+ let s = string_of_id id in
+ let lpe,_ = System.find_file_in_path (Library.get_load_path ()) (s^".v") in
+ let dir = extend_dirpath (Library.find_logical_path lpe) id in
+ fun () ->
+ Lib.start_module dir
+ | _ -> bad_vernac_args "BeginModule")
+
+let _ =
+ vinterp_add "WriteModule"
+ (function
+ | [VARG_IDENTIFIER id] ->
+ let mid = Lib.end_module id in
+ fun () -> let m = string_of_id id in Library.save_module_to mid m
+ | [VARG_IDENTIFIER id; VARG_STRING f] ->
+ let mid = Lib.end_module id in
+ fun () -> Library.save_module_to mid f
+ | _ -> bad_vernac_args "WriteModule")
+
+let _ =
+ vinterp_add "CLASS"
+ (function
+ | [VARG_STRING kind; VARG_QUALID qid] ->
+ let stre =
+ if kind = "LOCAL" then
+ make_strength_0()
+ else
+ Nametab.NeverDischarge
+ in
+ fun () ->
+ let ref = Nametab.global (dummy_loc, qid) in
+ Class.try_add_new_class ref stre;
+ if_verbose message
+ ((string_of_qualid qid) ^ " is now a class")
+ | _ -> bad_vernac_args "CLASS")
+
+(* Meta-syntax commands *)
+let _ =
+ add "TOKEN"
+ (function
+ | [VARG_STRING s] -> (fun () -> Metasyntax.add_token_obj s)
+ | _ -> bad_vernac_args "TOKEN")
+***)
+
+(* Search commands *)
+
+(***
+let _ =
+ add "Searchisos"
+ (function
+ | [VARG_CONSTR com] ->
+ (fun () ->
+ let env = Global.env() in
+ let c = constr_of_com Evd.empty env com in
+ let cc = nf_betaiota env Evd.empty c in
+ Searchisos.type_search cc)
+ | _ -> bad_vernac_args "Searchisos")
+***)
+
+let interp c = match c with
+ (* Control (done in vernac) *)
+ | (VernacTime _ | VernacVar _ | VernacList _ | VernacLoad _) -> assert false
+ | (VernacV7only _ | VernacV8only _) -> assert false
+
+ (* Syntax *)
+ | VernacSyntax (whatfor,sel) -> vernac_syntax whatfor sel
+ | VernacTacticGrammar al -> Metasyntax.add_tactic_grammar al
+ | VernacGrammar (univ,al) -> vernac_grammar univ al
+ | VernacSyntaxExtension (lcl,sl,l8) -> vernac_syntax_extension lcl sl l8
+ | VernacDelimiters (sc,lr) -> vernac_delimiters sc lr
+ | VernacBindScope (sc,rl) -> vernac_bind_scope sc rl
+ | VernacOpenCloseScope sc -> vernac_open_close_scope sc
+ | VernacArgumentsScope (qid,scl) -> vernac_arguments_scope qid scl
+ | VernacInfix (local,mv,qid,mv8,sc) -> vernac_infix local mv qid mv8 sc
+ | VernacDistfix (local,assoc,n,inf,qid,sc) ->
+ vernac_distfix local assoc n inf qid sc
+ | VernacNotation (local,c,infpl,mv8,sc) ->
+ vernac_notation local c infpl mv8 sc
+
+ (* Gallina *)
+ | VernacDefinition (k,(_,id),d,f) -> vernac_definition k id d f
+ | VernacStartTheoremProof (k,(_,id),t,top,f) ->
+ vernac_start_proof k (Some id) t top f
+ | VernacEndProof e -> vernac_end_proof e
+ | VernacExactProof c -> vernac_exact_proof c
+ | VernacAssumption (stre,l) -> vernac_assumption stre l
+ | VernacInductive (finite,l) -> vernac_inductive finite l
+ | VernacFixpoint l -> vernac_fixpoint l
+ | VernacCoFixpoint l -> vernac_cofixpoint l
+ | VernacScheme l -> vernac_scheme l
+
+ (* Modules *)
+ | VernacDeclareModule ((_,id),bl,mtyo,mexpro) ->
+ vernac_declare_module id bl mtyo mexpro
+ | VernacDefineModule ((_,id),bl,mtyo,mexpro) ->
+ vernac_define_module id bl mtyo mexpro
+ | VernacDeclareModuleType ((_,id),bl,mtyo) ->
+ vernac_declare_module_type id bl mtyo
+
+ (* Gallina extensions *)
+ | VernacBeginSection (_,id) -> vernac_begin_section id
+
+ | VernacEndSegment (_,id) -> vernac_end_segment id
+
+ | VernacRecord (_,id,bl,s,idopt,fs) -> vernac_record id bl s idopt fs
+ | VernacRequire (export,spec,qidl) -> vernac_require export spec qidl
+ | VernacImport (export,qidl) -> vernac_import export qidl
+ | VernacCanonical qid -> vernac_canonical qid
+ | VernacCoercion (str,r,s,t) -> vernac_coercion str r s t
+ | VernacIdentityCoercion (str,(_,id),s,t) -> vernac_identity_coercion str id s t
+
+ (* Solving *)
+ | VernacSolve (n,tac,b) -> vernac_solve n tac b
+ | VernacSolveExistential (n,c) -> vernac_solve_existential n c
+
+ (* Auxiliary file and library management *)
+ | VernacRequireFrom (exp,spec,f) -> vernac_require_from exp spec f
+ | VernacAddLoadPath (isrec,s,alias) -> vernac_add_loadpath isrec s alias
+ | VernacRemoveLoadPath s -> vernac_remove_loadpath s
+ | VernacAddMLPath (isrec,s) -> vernac_add_ml_path isrec s
+ | VernacDeclareMLModule l -> vernac_declare_ml_module l
+ | VernacChdir s -> vernac_chdir s
+
+ (* State management *)
+ | VernacWriteState s -> vernac_write_state s
+ | VernacRestoreState s -> vernac_restore_state s
+
+ (* Resetting *)
+ | VernacResetName id -> vernac_reset_name id
+ | VernacResetInitial -> vernac_reset_initial ()
+ | VernacBack n -> vernac_back n
+
+ (* Commands *)
+ | VernacDeclareTacticDefinition (x,l) -> vernac_declare_tactic_definition x l
+ | VernacHints (local,dbnames,hints) -> vernac_hints local dbnames hints
+ | VernacSyntacticDefinition (id,c,l,b) ->vernac_syntactic_definition id c l b
+ | VernacDeclareImplicits (qid,l) -> vernac_declare_implicits qid l
+ | VernacReserve (idl,c) -> vernac_reserve idl c
+ | VernacSetOpacity (opaq, qidl) -> List.iter (vernac_set_opacity opaq) qidl
+ | VernacSetOption (key,v) -> vernac_set_option key v
+ | VernacUnsetOption key -> vernac_unset_option key
+ | VernacRemoveOption (key,v) -> vernac_remove_option key v
+ | VernacAddOption (key,v) -> vernac_add_option key v
+ | VernacMemOption (key,v) -> vernac_mem_option key v
+ | VernacPrintOption key -> vernac_print_option key
+ | VernacCheckMayEval (r,g,c) -> vernac_check_may_eval r g c
+ | VernacGlobalCheck c -> vernac_global_check c
+ | VernacPrint p -> vernac_print p
+ | VernacSearch (s,r) -> vernac_search s r
+ | VernacLocate l -> vernac_locate l
+ | VernacComments l -> if_verbose message ("Comments ok\n")
+ | VernacNop -> ()
+
+ (* Proof management *)
+ | VernacGoal t -> vernac_start_proof Theorem None ([],t) false (fun _ _ ->())
+ | VernacAbort id -> vernac_abort id
+ | VernacAbortAll -> vernac_abort_all ()
+ | VernacRestart -> vernac_restart ()
+ | VernacSuspend -> vernac_suspend ()
+ | VernacResume id -> vernac_resume id
+ | VernacUndo n -> vernac_undo n
+ | VernacFocus n -> vernac_focus n
+ | VernacUnfocus -> vernac_unfocus ()
+ | VernacGo g -> vernac_go g
+ | VernacShow s -> vernac_show s
+ | VernacCheckGuard -> vernac_check_guard ()
+ | VernacDebug b -> vernac_debug b
+ | VernacProof tac -> vernac_set_end_tac tac
+ (* Toplevel control *)
+ | VernacToplevelControl e -> raise e
+
+ (* Extensions *)
+ | VernacExtend (opn,args) -> Vernacinterp.call (opn,args)