aboutsummaryrefslogtreecommitdiff
path: root/vernac
diff options
context:
space:
mode:
Diffstat (limited to 'vernac')
-rw-r--r--vernac/.ocamlformat-enable1
-rw-r--r--vernac/auto_ind_decl.ml231
-rw-r--r--vernac/canonical.ml2
-rw-r--r--vernac/classes.ml53
-rw-r--r--vernac/classes.mli10
-rw-r--r--vernac/comArguments.ml6
-rw-r--r--vernac/comAssumption.ml28
-rw-r--r--vernac/comAssumption.mli2
-rw-r--r--vernac/comCoercion.ml14
-rw-r--r--vernac/comCoercion.mli4
-rw-r--r--vernac/comDefinition.ml99
-rw-r--r--vernac/comDefinition.mli22
-rw-r--r--vernac/comFixpoint.ml40
-rw-r--r--vernac/comFixpoint.mli22
-rw-r--r--vernac/comHints.ml157
-rw-r--r--vernac/comHints.mli11
-rw-r--r--vernac/comInductive.ml122
-rw-r--r--vernac/comInductive.mli6
-rw-r--r--vernac/comProgramFixpoint.ml25
-rw-r--r--vernac/comProgramFixpoint.mli4
-rw-r--r--vernac/declare.ml1055
-rw-r--r--vernac/declare.mli399
-rw-r--r--vernac/declareDef.ml174
-rw-r--r--vernac/declareDef.mli108
-rw-r--r--vernac/declareInd.ml41
-rw-r--r--vernac/declareInd.mli3
-rw-r--r--vernac/declareObl.ml70
-rw-r--r--vernac/declareObl.mli10
-rw-r--r--vernac/declareUniv.ml19
-rw-r--r--vernac/declareUniv.mli3
-rw-r--r--vernac/declaremods.ml229
-rw-r--r--vernac/declaremods.mli4
-rw-r--r--vernac/g_proofs.mlg9
-rw-r--r--vernac/g_vernac.mlg125
-rw-r--r--vernac/himsg.ml18
-rw-r--r--vernac/indschemes.ml7
-rw-r--r--vernac/lemmas.ml308
-rw-r--r--vernac/lemmas.mli37
-rw-r--r--vernac/library.ml115
-rw-r--r--vernac/locality.ml2
-rw-r--r--vernac/locality.mli2
-rw-r--r--vernac/metasyntax.ml11
-rw-r--r--vernac/obligations.ml261
-rw-r--r--vernac/obligations.mli156
-rw-r--r--vernac/pfedit.ml19
-rw-r--r--vernac/ppvernac.ml15
-rw-r--r--vernac/proof_global.ml12
-rw-r--r--vernac/pvernac.mli2
-rw-r--r--vernac/record.ml183
-rw-r--r--vernac/retrieveObl.ml296
-rw-r--r--vernac/retrieveObl.mli46
-rw-r--r--vernac/search.ml2
-rw-r--r--vernac/search.mli12
-rw-r--r--vernac/vernac.mllib7
-rw-r--r--vernac/vernacentries.ml216
-rw-r--r--vernac/vernacentries.mli3
-rw-r--r--vernac/vernacexpr.ml47
-rw-r--r--vernac/vernacextend.ml6
-rw-r--r--vernac/vernacextend.mli6
-rw-r--r--vernac/vernacinterp.ml29
-rw-r--r--vernac/vernacinterp.mli2
-rw-r--r--vernac/vernacstate.ml39
-rw-r--r--vernac/vernacstate.mli18
63 files changed, 3303 insertions, 1682 deletions
diff --git a/vernac/.ocamlformat-enable b/vernac/.ocamlformat-enable
new file mode 100644
index 0000000000..ffaa7e70f4
--- /dev/null
+++ b/vernac/.ocamlformat-enable
@@ -0,0 +1 @@
+comHints.ml
diff --git a/vernac/auto_ind_decl.ml b/vernac/auto_ind_decl.ml
index 0c9b9c7255..743d1d2026 100644
--- a/vernac/auto_ind_decl.ml
+++ b/vernac/auto_ind_decl.ml
@@ -113,8 +113,8 @@ let mkFullInd (ind,u) n =
else mkIndU (ind,u)
let check_bool_is_defined () =
- try let _ = Typeops.type_of_global_in_context (Global.env ()) Coqlib.(lib_ref "core.bool.type") in ()
- with e when CErrors.noncritical e -> raise (UndefinedCst "bool")
+ if not (Coqlib.has_ref "core.bool.type")
+ then raise (UndefinedCst "bool")
let check_no_indices mib =
if Array.exists (fun mip -> mip.mind_nrealargs <> 0) mib.mind_packets then
@@ -122,6 +122,53 @@ let check_no_indices mib =
let beq_scheme_kind_aux = ref (fun _ -> failwith "Undefined")
+let build_beq_scheme_deps kn =
+ (* fetching global env *)
+ let env = Global.env() in
+ (* fetching the mutual inductive body *)
+ let mib = Global.lookup_mind kn in
+ (* number of inductives in the mutual *)
+ let nb_ind = Array.length mib.mind_packets in
+ (* number of params in the type *)
+ let nparrec = mib.mind_nparams_rec in
+ check_no_indices mib;
+ let make_one_eq accu i =
+ (* This function is only trying to recursively compute the inductive types
+ appearing as arguments of the constructors. This is done to support
+ equality decision over hereditarily first-order types. It could be
+ perfomed in a much cleaner way, e.g. using the kernel normal form of
+ constructor types and kernel whd_all for the argument types. *)
+ let rec aux accu c =
+ let (c,a) = Reductionops.whd_betaiota_stack Evd.empty EConstr.(of_constr c) in
+ let (c,a) = EConstr.Unsafe.(to_constr c, List.map to_constr a) in
+ match Constr.kind c with
+ | Cast (x,_,_) -> aux accu (Term.applist (x,a))
+ | App _ -> assert false
+ | Ind ((kn', _), _) ->
+ if MutInd.equal kn kn' then accu
+ else
+ let eff = SchemeMutualDep (kn', !beq_scheme_kind_aux ()) in
+ List.fold_left aux (eff :: accu) a
+ | Const (kn, u) ->
+ (match Environ.constant_opt_value_in env (kn, u) with
+ | Some c -> aux accu (Term.applist (c,a))
+ | None -> accu)
+ | Rel _ | Var _ | Sort _ | Prod _ | Lambda _ | LetIn _ | Proj _
+ | Construct _ | Case _ | CoFix _ | Fix _ | Meta _ | Evar _ | Int _
+ | Float _ -> accu
+ in
+ let u = Univ.Instance.empty in
+ let constrs n = get_constructors env (make_ind_family (((kn, i), u),
+ Context.Rel.to_extended_list mkRel (n+nb_ind-1) mib.mind_params_ctxt)) in
+ let constrsi = constrs (3+nparrec) in
+ let fold i accu arg =
+ let fold accu c = aux accu (RelDecl.get_type c) in
+ List.fold_left fold accu arg.cs_args
+ in
+ Array.fold_left_i fold accu constrsi
+ in
+ Array.fold_left_i (fun i accu _ -> make_one_eq accu i) [] mib.mind_packets
+
let build_beq_scheme mode kn =
check_bool_is_defined ();
(* fetching global env *)
@@ -194,7 +241,7 @@ let build_beq_scheme mode kn =
let (c,a) = Reductionops.whd_betaiota_stack Evd.empty EConstr.(of_constr c) in
let (c,a) = EConstr.Unsafe.(to_constr c, List.map to_constr a) in
match Constr.kind c with
- | Rel x -> mkRel (x-nlist+ndx), Evd.empty_side_effects
+ | Rel x -> mkRel (x-nlist+ndx)
| Var x ->
(* Support for working in a context with "eq_x : x -> x -> bool" *)
let eid = Id.of_string ("eq_"^(Id.to_string x)) in
@@ -202,26 +249,23 @@ let build_beq_scheme mode kn =
try ignore (Environ.lookup_named eid env)
with Not_found -> raise (ParameterWithoutEquality (GlobRef.VarRef x))
in
- mkVar eid, Evd.empty_side_effects
+ mkVar eid
| Cast (x,_,_) -> aux (Term.applist (x,a))
| App _ -> assert false
| Ind ((kn',i as ind'),u) (*FIXME: universes *) ->
- if MutInd.equal kn kn' then mkRel(eqA-nlist-i+nb_ind-1), Evd.empty_side_effects
+ if MutInd.equal kn kn' then mkRel(eqA-nlist-i+nb_ind-1)
else begin
try
- let eq, eff =
- let c, eff = find_scheme ~mode (!beq_scheme_kind_aux()) (kn',i) in
- mkConst c, eff in
- let eqa, eff =
- let eqa, effs = List.split (List.map aux a) in
- Array.of_list eqa,
- List.fold_left Evd.concat_side_effects eff (List.rev effs)
- in
+ let eq = match lookup_scheme (!beq_scheme_kind_aux()) ind' with
+ | Some c -> mkConst c
+ | None -> assert false
+ in
+ let eqa = Array.of_list @@ List.map aux a in
let args =
Array.append
(Array.of_list (List.map (fun x -> lift lifti x) a)) eqa in
- if Int.equal (Array.length args) 0 then eq, eff
- else mkApp (eq, args), eff
+ if Int.equal (Array.length args) 0 then eq
+ else mkApp (eq, args)
with Not_found -> raise(EqNotFound (ind', fst ind))
end
| Sort _ -> raise InductiveWithSort
@@ -236,10 +280,10 @@ let build_beq_scheme mode kn =
(* Needs Hints, see test suite *)
let eq_lbl = Label.make ("eq_" ^ Label.to_string (Constant.label kn)) in
let kneq = Constant.change_label kn eq_lbl in
- try let _ = Environ.constant_opt_value_in env (kneq, u) in
- Term.applist (mkConst kneq,a),
- Evd.empty_side_effects
- with Not_found -> raise (ParameterWithoutEquality (GlobRef.ConstRef kn)))
+ if Environ.mem_constant kneq env then
+ let _ = Environ.constant_opt_value_in env (kneq, u) in
+ Term.applist (mkConst kneq,a)
+ else raise (ParameterWithoutEquality (GlobRef.ConstRef kn)))
| Proj _ -> raise (EqUnknown "projection")
| Construct _ -> raise (EqUnknown "constructor")
| Case _ -> raise (EqUnknown "match")
@@ -270,7 +314,6 @@ let build_beq_scheme mode kn =
let constrsi = constrs (3+nparrec) in
let n = Array.length constrsi in
let ar = Array.make n (ff ()) in
- let eff = ref Evd.empty_side_effects in
for i=0 to n-1 do
let nb_cstr_args = List.length constrsi.(i).cs_args in
let ar2 = Array.make n (ff ()) in
@@ -282,13 +325,12 @@ let build_beq_scheme mode kn =
| _ -> let eqs = Array.make nb_cstr_args (tt ()) in
for ndx = 0 to nb_cstr_args-1 do
let cc = RelDecl.get_type (List.nth constrsi.(i).cs_args ndx) in
- let eqA, eff' = compute_A_equality rel_list
+ let eqA = compute_A_equality rel_list
nparrec
(nparrec+3+2*nb_cstr_args)
(nb_cstr_args+ndx+1)
cc
in
- eff := Evd.concat_side_effects eff' !eff;
Array.set eqs ndx
(mkApp (eqA,
[|mkRel (ndx+1+nb_cstr_args);mkRel (ndx+1)|]
@@ -314,21 +356,18 @@ let build_beq_scheme mode kn =
done;
mkNamedLambda (make_annot (Id.of_string "X") Sorts.Relevant) (mkFullInd ind (nb_ind-1+1)) (
mkNamedLambda (make_annot (Id.of_string "Y") Sorts.Relevant) (mkFullInd ind (nb_ind-1+2)) (
- mkCase (ci, do_predicate rel_list 0,mkVar (Id.of_string "X"),ar))),
- !eff
+ mkCase (ci, do_predicate rel_list 0,mkVar (Id.of_string "X"),ar)))
in (* build_beq_scheme *)
let names = Array.make nb_ind (make_annot Anonymous Sorts.Relevant) and
types = Array.make nb_ind mkSet and
cores = Array.make nb_ind mkSet in
- let eff = ref Evd.empty_side_effects in
let u = Univ.Instance.empty in
for i=0 to (nb_ind-1) do
names.(i) <- make_annot (Name (Id.of_string (rec_name i))) Sorts.Relevant;
types.(i) <- mkArrow (mkFullInd ((kn,i),u) 0) Sorts.Relevant
(mkArrow (mkFullInd ((kn,i),u) 1) Sorts.Relevant (bb ()));
- let c, eff' = make_one_eq i in
+ let c = make_one_eq i in
cores.(i) <- c;
- eff := Evd.concat_side_effects eff' !eff
done;
(Array.init nb_ind (fun i ->
let kelim = Inductive.elim_sort (mib,mib.mind_packets.(i)) in
@@ -346,10 +385,12 @@ let build_beq_scheme mode kn =
Vars.substl subst cores.(i)
in
create_input fix),
- UState.make ~lbound:(Global.universes_lbound ()) (Global.universes ())),
- !eff
+ UState.make ~lbound:(Global.universes_lbound ()) (Global.universes ()))
-let beq_scheme_kind = declare_mutual_scheme_object "_beq" build_beq_scheme
+let beq_scheme_kind =
+ declare_mutual_scheme_object "_beq"
+ ~deps:build_beq_scheme_deps
+ build_beq_scheme
let _ = beq_scheme_kind_aux := fun () -> beq_scheme_kind
@@ -373,7 +414,7 @@ so from Ai we can find the correct eq_Ai bl_ai or lb_ai
let do_replace_lb mode lb_scheme_key aavoid narg p q =
let open EConstr in
let avoid = Array.of_list aavoid in
- let do_arg sigma hd v offset =
+ let do_arg env sigma hd v offset =
match kind sigma v with
| Var s ->
let x = narg*offset in
@@ -390,7 +431,9 @@ let do_replace_lb mode lb_scheme_key aavoid narg p q =
Parameter (see example "J" in test file SchemeEquality.v) *)
let lbl = Label.to_string (Constant.label cst) in
let newlbl = if Int.equal offset 1 then ("eq_" ^ lbl) else (lbl ^ "_lb") in
- mkConst (Constant.change_label cst (Label.make newlbl))
+ let newcst = Constant.change_label cst (Label.make newlbl) in
+ if Environ.mem_constant newcst env then mkConst newcst
+ else raise (ConstructorWithNonParametricInductiveType (fst hd))
| _ -> raise (ConstructorWithNonParametricInductiveType (fst hd))
in
@@ -398,34 +441,18 @@ let do_replace_lb mode lb_scheme_key aavoid narg p q =
let type_of_pq = Tacmach.New.pf_get_type_of gl p in
let sigma = Tacmach.New.project gl in
let env = Tacmach.New.pf_env gl in
- let u,v = destruct_ind env sigma type_of_pq
- in let lb_type_of_p =
- try
- let c, eff = find_scheme ~mode lb_scheme_key (fst u) (*FIXME*) in
- Proofview.tclUNIT (mkConst c, eff)
- with Not_found ->
- (* spiwack: the format of this error message should probably
- be improved. *)
- let err_msg =
- (str "Leibniz->boolean:" ++
- str "You have to declare the" ++
- str "decidability over " ++
- Printer.pr_econstr_env env sigma type_of_pq ++
- str " first.")
- in
- Tacticals.New.tclZEROMSG err_msg
- in
- lb_type_of_p >>= fun (lb_type_of_p,eff) ->
+ let u,v = destruct_ind env sigma type_of_pq in
+ find_scheme ~mode lb_scheme_key (fst u) (*FIXME*) >>= fun c ->
+ let lb_type_of_p = mkConst c in
Proofview.tclEVARMAP >>= fun sigma ->
let lb_args = Array.append (Array.append
v
- (Array.Smart.map (fun x -> do_arg sigma u x 1) v))
- (Array.Smart.map (fun x -> do_arg sigma u x 2) v)
+ (Array.Smart.map (fun x -> do_arg env sigma u x 1) v))
+ (Array.Smart.map (fun x -> do_arg env sigma u x 2) v)
in let app = if Array.is_empty lb_args
then lb_type_of_p else mkApp (lb_type_of_p,lb_args)
in
Tacticals.New.tclTHENLIST [
- Proofview.tclEFFECTS eff;
Equality.replace p q ; apply app ; Auto.default_auto]
end
@@ -433,7 +460,7 @@ let do_replace_lb mode lb_scheme_key aavoid narg p q =
let do_replace_bl bl_scheme_key (ind,u as indu) aavoid narg lft rgt =
let open EConstr in
let avoid = Array.of_list aavoid in
- let do_arg sigma hd v offset =
+ let do_arg env sigma hd v offset =
match kind sigma v with
| Var s ->
let x = narg*offset in
@@ -450,7 +477,9 @@ let do_replace_bl bl_scheme_key (ind,u as indu) aavoid narg lft rgt =
Parameter (see example "J" in test file SchemeEquality.v) *)
let lbl = Label.to_string (Constant.label cst) in
let newlbl = if Int.equal offset 1 then ("eq_" ^ lbl) else (lbl ^ "_bl") in
- mkConst (Constant.change_label cst (Label.make newlbl))
+ let newcst = Constant.change_label cst (Label.make newlbl) in
+ if Environ.mem_constant newcst env then mkConst newcst
+ else raise (ConstructorWithNonParametricInductiveType (fst hd))
| _ -> raise (ConstructorWithNonParametricInductiveType (fst hd))
in
@@ -469,32 +498,18 @@ let do_replace_bl bl_scheme_key (ind,u as indu) aavoid narg lft rgt =
in if eq_ind (fst u) ind
then Tacticals.New.tclTHENLIST [Equality.replace t1 t2; Auto.default_auto ; aux q1 q2 ]
else (
- let bl_t1, eff =
- try
- let c, eff = find_scheme bl_scheme_key (fst u) (*FIXME*) in
- mkConst c, eff
- with Not_found ->
- (* spiwack: the format of this error message should probably
- be improved. *)
- let err_msg =
- (str "boolean->Leibniz:" ++
- str "You have to declare the" ++
- str "decidability over " ++
- Printer.pr_econstr_env env sigma tt1 ++
- str " first.")
- in
- user_err err_msg
- in let bl_args =
+ find_scheme bl_scheme_key (fst u) (*FIXME*) >>= fun c ->
+ let bl_t1 = mkConst c in
+ let bl_args =
Array.append (Array.append
v
- (Array.Smart.map (fun x -> do_arg sigma u x 1) v))
- (Array.Smart.map (fun x -> do_arg sigma u x 2) v )
+ (Array.Smart.map (fun x -> do_arg env sigma u x 1) v))
+ (Array.Smart.map (fun x -> do_arg env sigma u x 2) v )
in
let app = if Array.is_empty bl_args
then bl_t1 else mkApp (bl_t1,bl_args)
in
Tacticals.New.tclTHENLIST [
- Proofview.tclEFFECTS eff;
Equality.replace_by t1 t2
(Tacticals.New.tclTHEN (apply app) (Auto.default_auto)) ;
aux q1 q2 ]
@@ -547,11 +562,12 @@ let eqI ind l =
let list_id = list_id l in
let eA = Array.of_list((List.map (fun (s,_,_,_) -> mkVar s) list_id)@
(List.map (fun (_,seq,_,_)-> mkVar seq) list_id ))
- and e, eff =
- try let c, eff = find_scheme beq_scheme_kind ind in mkConst c, eff
- with Not_found -> user_err ~hdr:"AutoIndDecl.eqI"
+ and e = match lookup_scheme beq_scheme_kind ind with
+ | Some c -> mkConst c
+ | None ->
+ user_err ~hdr:"AutoIndDecl.eqI"
(str "The boolean equality on " ++ Printer.pr_inductive (Global.env ()) ind ++ str " is needed.");
- in (if Array.equal Constr.equal eA [||] then e else mkApp(e,eA)), eff
+ in (if Array.equal Constr.equal eA [||] then e else mkApp(e,eA))
(**********************************************************************)
(* Boolean->Leibniz *)
@@ -559,7 +575,7 @@ let eqI ind l =
open Namegen
let compute_bl_goal ind lnamesparrec nparrec =
- let eqI, eff = eqI ind lnamesparrec in
+ let eqI = eqI ind lnamesparrec in
let list_id = list_id lnamesparrec in
let avoid = List.fold_right (Nameops.Name.fold_right (fun id l -> Id.Set.add id l)) (List.map RelDecl.get_name lnamesparrec) Id.Set.empty in
let create_input c =
@@ -600,7 +616,7 @@ let compute_bl_goal ind lnamesparrec nparrec =
(mkApp(eq (),[|bb ();mkApp(eqI,[|mkVar n;mkVar m|]);tt ()|]))
Sorts.Relevant
(mkApp(eq (),[|mkFullInd (ind,u) (nparrec+3);mkVar n;mkVar m|]))
- ))), eff
+ )))
let compute_bl_tact mode bl_scheme_key ind lnamesparrec nparrec =
let list_id = list_id lnamesparrec in
@@ -690,16 +706,19 @@ let make_bl_scheme mode mind =
let nparrec = mib.mind_nparams_rec in
let lnonparrec,lnamesparrec = (* TODO subst *)
context_chop (nparams-nparrec) mib.mind_params_ctxt in
- let bl_goal, eff = compute_bl_goal ind lnamesparrec nparrec in
+ let bl_goal = compute_bl_goal ind lnamesparrec nparrec in
let uctx = UState.make ~lbound:(Global.universes_lbound ()) (Global.universes ()) in
let side_eff = side_effect_of_mode mode in
let bl_goal = EConstr.of_constr bl_goal in
- let (ans, _, _, ctx) = Pfedit.build_by_tactic ~poly:false ~side_eff (Global.env()) ~uctx ~typ:bl_goal
+ let (ans, _, _, _, ctx) = Declare.build_by_tactic ~poly:false ~side_eff (Global.env()) ~uctx ~typ:bl_goal
(compute_bl_tact mode (!bl_scheme_kind_aux()) (ind, EConstr.EInstance.empty) lnamesparrec nparrec)
in
- ([|ans|], ctx), eff
+ ([|ans|], ctx)
-let bl_scheme_kind = declare_mutual_scheme_object "_dec_bl" make_bl_scheme
+let bl_scheme_kind =
+ declare_mutual_scheme_object "_dec_bl"
+ ~deps:(fun ind -> [SchemeMutualDep (ind, beq_scheme_kind)])
+ make_bl_scheme
let _ = bl_scheme_kind_aux := fun () -> bl_scheme_kind
@@ -710,7 +729,7 @@ let compute_lb_goal ind lnamesparrec nparrec =
let list_id = list_id lnamesparrec in
let eq = eq () and tt = tt () and bb = bb () in
let avoid = List.fold_right (Nameops.Name.fold_right (fun id l -> Id.Set.add id l)) (List.map RelDecl.get_name lnamesparrec) Id.Set.empty in
- let eqI, eff = eqI ind lnamesparrec in
+ let eqI = eqI ind lnamesparrec in
let create_input c =
let x = next_ident_away (Id.of_string "x") avoid and
y = next_ident_away (Id.of_string "y") avoid in
@@ -750,7 +769,7 @@ let compute_lb_goal ind lnamesparrec nparrec =
(mkApp(eq,[|mkFullInd (ind,u) (nparrec+2);mkVar n;mkVar m|]))
Sorts.Relevant
(mkApp(eq,[|bb;mkApp(eqI,[|mkVar n;mkVar m|]);tt|]))
- ))), eff
+ )))
let compute_lb_tact mode lb_scheme_key ind lnamesparrec nparrec =
let list_id = list_id lnamesparrec in
@@ -820,16 +839,19 @@ let make_lb_scheme mode mind =
let nparrec = mib.mind_nparams_rec in
let lnonparrec,lnamesparrec =
context_chop (nparams-nparrec) mib.mind_params_ctxt in
- let lb_goal, eff = compute_lb_goal ind lnamesparrec nparrec in
+ let lb_goal = compute_lb_goal ind lnamesparrec nparrec in
let uctx = UState.make ~lbound:(Global.universes_lbound ()) (Global.universes ()) in
let side_eff = side_effect_of_mode mode in
let lb_goal = EConstr.of_constr lb_goal in
- let (ans, _, _, ctx) = Pfedit.build_by_tactic ~poly:false ~side_eff (Global.env()) ~uctx ~typ:lb_goal
+ let (ans, _, _, _, ctx) = Declare.build_by_tactic ~poly:false ~side_eff (Global.env()) ~uctx ~typ:lb_goal
(compute_lb_tact mode (!lb_scheme_kind_aux()) ind lnamesparrec nparrec)
in
- ([|ans|], ctx), eff
+ ([|ans|], ctx)
-let lb_scheme_kind = declare_mutual_scheme_object "_dec_lb" make_lb_scheme
+let lb_scheme_kind =
+ declare_mutual_scheme_object "_dec_lb"
+ ~deps:(fun ind -> [SchemeMutualDep (ind, beq_scheme_kind)])
+ make_lb_scheme
let _ = lb_scheme_kind_aux := fun () -> lb_scheme_kind
@@ -837,8 +859,8 @@ let _ = lb_scheme_kind_aux := fun () -> lb_scheme_kind
(* Decidable equality *)
let check_not_is_defined () =
- try ignore (Coqlib.lib_ref "core.not.type")
- with Not_found -> raise (UndefinedCst "not")
+ if not (Coqlib.has_ref "core.not.type")
+ then raise (UndefinedCst "not")
(* {n=m}+{n<>m} part *)
let compute_dec_goal ind lnamesparrec nparrec =
@@ -904,7 +926,8 @@ let compute_dec_tact ind lnamesparrec nparrec =
let eq = eq () and tt = tt ()
and ff = ff () and bb = bb () in
let list_id = list_id lnamesparrec in
- let eqI, eff = eqI ind lnamesparrec in
+ find_scheme beq_scheme_kind ind >>= fun _ ->
+ let eqI = eqI ind lnamesparrec in
let avoid = ref [] in
let eqtrue x = mkApp(eq,[|bb;x;tt|]) in
let eqfalse x = mkApp(eq,[|bb;x;ff|]) in
@@ -926,21 +949,11 @@ let compute_dec_tact ind lnamesparrec nparrec =
let eqbnm = mkApp(eqI,[|mkVar freshn;mkVar freshm|]) in
let arfresh = Array.of_list fresh_first_intros in
let xargs = Array.sub arfresh 0 (2*nparrec) in
- begin try
- let c, eff = find_scheme bl_scheme_kind ind in
- Proofview.tclUNIT (mkConst c,eff) with
- Not_found ->
- Tacticals.New.tclZEROMSG (str "Error during the decidability part, boolean to leibniz equality is required.")
- end >>= fun (blI,eff') ->
- begin try
- let c, eff = find_scheme lb_scheme_kind ind in
- Proofview.tclUNIT (mkConst c,eff) with
- Not_found ->
- Tacticals.New.tclZEROMSG (str "Error during the decidability part, leibniz to boolean equality is required.")
- end >>= fun (lbI,eff'') ->
- let eff = (Evd.concat_side_effects eff'' (Evd.concat_side_effects eff' eff)) in
+ find_scheme bl_scheme_kind ind >>= fun c ->
+ let blI = mkConst c in
+ find_scheme lb_scheme_kind ind >>= fun c ->
+ let lbI = mkConst c in
Tacticals.New.tclTHENLIST [
- Proofview.tclEFFECTS eff;
intros_using fresh_first_intros;
intros_using [freshn;freshm];
(*we do this so we don't have to prove the same goal twice *)
@@ -1001,11 +1014,11 @@ let make_eq_decidability mode mind =
let lnonparrec,lnamesparrec =
context_chop (nparams-nparrec) mib.mind_params_ctxt in
let side_eff = side_effect_of_mode mode in
- let (ans, _, _, ctx) = Pfedit.build_by_tactic ~poly:false ~side_eff (Global.env()) ~uctx
+ let (ans, _, _, _, ctx) = Declare.build_by_tactic ~poly:false ~side_eff (Global.env()) ~uctx
~typ:(EConstr.of_constr (compute_dec_goal (ind,u) lnamesparrec nparrec))
(compute_dec_tact ind lnamesparrec nparrec)
in
- ([|ans|], ctx), Evd.empty_side_effects
+ ([|ans|], ctx)
let eq_dec_scheme_kind =
declare_mutual_scheme_object "_eq_dec" make_eq_decidability
diff --git a/vernac/canonical.ml b/vernac/canonical.ml
index 390ed62bee..eaa6c84791 100644
--- a/vernac/canonical.ml
+++ b/vernac/canonical.ml
@@ -28,7 +28,7 @@ let discharge_canonical_structure (_,((gref, _ as x), local)) =
let inCanonStruc : (GlobRef.t * inductive) * bool -> obj =
declare_object {(default_object "CANONICAL-STRUCTURE") with
- open_function = open_canonical_structure;
+ open_function = simple_open open_canonical_structure;
cache_function = cache_canonical_structure;
subst_function = (fun (subst,(c,local)) -> subst_canonical_structure subst c, local);
classify_function = (fun x -> Substitute x);
diff --git a/vernac/classes.ml b/vernac/classes.ml
index dafd1cc5e4..55af2e1a7d 100644
--- a/vernac/classes.ml
+++ b/vernac/classes.ml
@@ -116,7 +116,7 @@ let instance_input : instance -> obj =
{ (default_object "type classes instances state") with
cache_function = cache_instance;
load_function = (fun _ x -> cache_instance x);
- open_function = (fun _ x -> cache_instance x);
+ open_function = simple_open (fun _ x -> cache_instance x);
classify_function = classify_instance;
discharge_function = discharge_instance;
rebuild_function = rebuild_instance;
@@ -237,7 +237,7 @@ let class_input : typeclass -> obj =
{ (default_object "type classes state") with
cache_function = cache_class;
load_function = (fun _ -> cache_class);
- open_function = (fun _ -> cache_class);
+ open_function = simple_open (fun _ -> cache_class);
classify_function = (fun x -> Substitute x);
discharge_function = (fun a -> Some (discharge_class a));
rebuild_function = rebuild_class;
@@ -304,22 +304,19 @@ let id_of_class cl =
mip.(0).Declarations.mind_typename
| _ -> assert false
-let instance_hook info global imps ?hook cst =
- Impargs.maybe_declare_manual_implicits false cst imps;
+let instance_hook info global ?hook cst =
let info = intern_info info in
let env = Global.env () in
let sigma = Evd.from_env env in
declare_instance env sigma (Some info) (not global) cst;
(match hook with Some h -> h cst | None -> ())
-let declare_instance_constant info global imps ?hook name udecl poly sigma term termtype =
+let declare_instance_constant info global impargs ?hook name udecl poly sigma term termtype =
let kind = Decls.(IsDefinition Instance) in
- let sigma, entry = DeclareDef.prepare_definition
- ~allow_evars:false ~poly sigma ~udecl ~types:(Some termtype) ~body:term in
- let kn = Declare.declare_constant ~name ~kind (Declare.DefinitionEntry entry) in
- Declare.definition_message name;
- DeclareUniv.declare_univ_binders (GlobRef.ConstRef kn) (Evd.universe_binders sigma);
- instance_hook info global imps ?hook (GlobRef.ConstRef kn)
+ let scope = Declare.Global Declare.ImportDefaultBehavior in
+ let kn = Declare.declare_definition ~name ~kind ~scope ~impargs
+ ~opaque:false ~poly sigma ~udecl ~types:(Some termtype) ~body:term in
+ instance_hook info global ?hook kn
let do_declare_instance sigma ~global ~poly k u ctx ctx' pri udecl impargs subst name =
let subst = List.fold_left2
@@ -328,30 +325,31 @@ let do_declare_instance sigma ~global ~poly k u ctx ctx' pri udecl impargs subst
in
let (_, ty_constr) = instance_constructor (k,u) subst in
let termtype = it_mkProd_or_LetIn ty_constr (ctx' @ ctx) in
- let sigma, entry = DeclareDef.prepare_parameter ~allow_evars:false ~poly sigma ~udecl ~types:termtype in
+ let sigma, entry = Declare.prepare_parameter ~poly sigma ~udecl ~types:termtype in
let cst = Declare.declare_constant ~name
~kind:Decls.(IsAssumption Logical) (Declare.ParameterEntry entry) in
DeclareUniv.declare_univ_binders (GlobRef.ConstRef cst) (Evd.universe_binders sigma);
- instance_hook pri global impargs (GlobRef.ConstRef cst)
+ let cst = (GlobRef.ConstRef cst) in
+ Impargs.maybe_declare_manual_implicits false cst impargs;
+ instance_hook pri global cst
-let declare_instance_program env sigma ~global ~poly name pri imps udecl term termtype =
- let hook { DeclareDef.Hook.S.scope; dref; _ } =
+let declare_instance_program env sigma ~global ~poly name pri impargs udecl term termtype =
+ let hook { Declare.Hook.S.scope; dref; _ } =
let cst = match dref with GlobRef.ConstRef kn -> kn | _ -> assert false in
- Impargs.declare_manual_implicits false dref imps;
let pri = intern_info pri in
let env = Global.env () in
let sigma = Evd.from_env env in
declare_instance env sigma (Some pri) (not global) (GlobRef.ConstRef cst)
in
- let obls, _, term, typ = Obligations.eterm_obligations env name sigma 0 term termtype in
- let hook = DeclareDef.Hook.make hook in
+ let obls, _, term, typ = RetrieveObl.retrieve_obligations env name sigma 0 term termtype in
+ let hook = Declare.Hook.make hook in
let uctx = Evd.evar_universe_context sigma in
- let scope, kind = DeclareDef.Global Declare.ImportDefaultBehavior, Decls.Instance in
+ let scope, kind = Declare.Global Declare.ImportDefaultBehavior, Decls.Instance in
let _ : DeclareObl.progress =
- Obligations.add_definition ~name ~term ~udecl ~scope ~poly ~kind ~hook typ ~uctx obls
+ Obligations.add_definition ~name ~term ~udecl ~scope ~poly ~kind ~hook ~impargs ~uctx typ obls
in ()
-let declare_instance_open sigma ?hook ~tac ~global ~poly id pri imps udecl ids term termtype =
+let declare_instance_open sigma ?hook ~tac ~global ~poly id pri impargs udecl ids term termtype =
(* spiwack: it is hard to reorder the actions to do
the pretyping after the proof has opened. As a
consequence, we use the low-level primitives to code
@@ -359,12 +357,12 @@ let declare_instance_open sigma ?hook ~tac ~global ~poly id pri imps udecl ids t
let gls = List.rev (Evd.future_goals sigma) in
let sigma = Evd.reset_future_goals sigma in
let kind = Decls.(IsDefinition Instance) in
- let hook = DeclareDef.Hook.(make (fun { S.dref ; _ } -> instance_hook pri global imps ?hook dref)) in
+ let hook = Declare.Hook.(make (fun { S.dref ; _ } -> instance_hook pri global ?hook dref)) in
let info = Lemmas.Info.make ~hook ~kind () in
(* XXX: We need to normalize the type, otherwise Admitted / Qed will fails!
This is due to a bug in proof_global :( *)
let termtype = Evarutil.nf_evar sigma termtype in
- let lemma = Lemmas.start_lemma ~name:id ~poly ~udecl ~info sigma termtype in
+ let lemma = Lemmas.start_lemma ~name:id ~poly ~udecl ~info ~impargs sigma termtype in
(* spiwack: I don't know what to do with the status here. *)
let lemma =
match term with
@@ -487,10 +485,8 @@ let do_instance env env' sigma ?hook ~global ~poly cty k u ctx ctx' pri decl imp
interp_props ~program_mode:false env' cty k u ctx ctx' subst sigma props
in
let termtype, sigma = do_instance_resolve_TC termtype sigma env in
- if Evd.has_undefined sigma then
- CErrors.user_err Pp.(str "Unsolved obligations remaining.")
- else
- declare_instance_constant pri global imps ?hook id decl poly sigma term termtype
+ Pretyping.check_evars_are_solved ~program_mode:false env sigma;
+ declare_instance_constant pri global imps ?hook id decl poly sigma term termtype
let do_instance_program env env' sigma ?hook ~global ~poly cty k u ctx ctx' pri decl imps subst id opt_props =
let term, termtype, sigma =
@@ -516,7 +512,8 @@ let interp_instance_context ~program_mode env ctx ~generalize pl tclass =
else tclass
in
let sigma, (impls, ((env', ctx), imps)) = interp_context_evars ~program_mode env sigma ctx in
- let sigma, (c', imps') = interp_type_evars_impls ~program_mode ~impls env' sigma tclass in
+ let flags = Pretyping.{ all_no_fail_flags with program_mode } in
+ let sigma, (c', imps') = interp_type_evars_impls ~flags ~impls env' sigma tclass in
let imps = imps @ imps' in
let ctx', c = decompose_prod_assum sigma c' in
let ctx'' = ctx' @ ctx in
diff --git a/vernac/classes.mli b/vernac/classes.mli
index 9698c14452..1b6deb3b28 100644
--- a/vernac/classes.mli
+++ b/vernac/classes.mli
@@ -22,7 +22,7 @@ val declare_instance : ?warn:bool -> env -> Evd.evar_map ->
Does nothing — or emit a “not-a-class” warning if the [warn] argument is set —
when said type is not a registered type class. *)
-val existing_instance : bool -> qualid -> Hints.hint_info_expr option -> unit
+val existing_instance : bool -> qualid -> Vernacexpr.hint_info_expr option -> unit
(** globality, reference, optional priority and pattern information *)
val new_instance_interactive
@@ -34,7 +34,7 @@ val new_instance_interactive
-> ?generalize:bool
-> ?tac:unit Proofview.tactic
-> ?hook:(GlobRef.t -> unit)
- -> Hints.hint_info_expr
+ -> Vernacexpr.hint_info_expr
-> (bool * constr_expr) option
-> Id.t * Lemmas.t
@@ -47,7 +47,7 @@ val new_instance
-> (bool * constr_expr)
-> ?generalize:bool
-> ?hook:(GlobRef.t -> unit)
- -> Hints.hint_info_expr
+ -> Vernacexpr.hint_info_expr
-> Id.t
val new_instance_program
@@ -59,7 +59,7 @@ val new_instance_program
-> (bool * constr_expr) option
-> ?generalize:bool
-> ?hook:(GlobRef.t -> unit)
- -> Hints.hint_info_expr
+ -> Vernacexpr.hint_info_expr
-> Id.t
val declare_new_instance
@@ -69,7 +69,7 @@ val declare_new_instance
-> ident_decl
-> local_binder_expr list
-> constr_expr
- -> Hints.hint_info_expr
+ -> Vernacexpr.hint_info_expr
-> unit
(** {6 Low level interface used by Add Morphism, do not use } *)
diff --git a/vernac/comArguments.ml b/vernac/comArguments.ml
index 90791a0906..360e228bfc 100644
--- a/vernac/comArguments.ml
+++ b/vernac/comArguments.ml
@@ -52,10 +52,10 @@ let warn_arguments_assert =
CWarnings.create ~name:"arguments-assert" ~category:"vernacular"
Pp.(fun sr ->
strbrk "This command is just asserting the names of arguments of " ++
- Printer.pr_global sr ++ strbrk". If this is what you want add " ++
+ Printer.pr_global sr ++ strbrk". If this is what you want, add " ++
strbrk "': assert' to silence the warning. If you want " ++
- strbrk "to clear implicit arguments add ': clear implicits'. " ++
- strbrk "If you want to clear notation scopes add ': clear scopes'")
+ strbrk "to clear implicit arguments, add ': clear implicits'. " ++
+ strbrk "If you want to clear notation scopes, add ': clear scopes'")
(* [nargs_for_red] is the number of arguments required to trigger reduction,
[args] is the main list of arguments statuses,
diff --git a/vernac/comAssumption.ml b/vernac/comAssumption.ml
index dc9c8e2d3c..023d76ce3b 100644
--- a/vernac/comAssumption.ml
+++ b/vernac/comAssumption.ml
@@ -70,7 +70,8 @@ let declare_axiom is_coe ~poly ~local ~kind typ (univs, pl) imps nl {CAst.v=name
(gr,inst)
let interp_assumption ~program_mode sigma env impls c =
- let sigma, (ty, impls) = interp_type_evars_impls ~program_mode env sigma ~impls c in
+ let flags = { Pretyping.all_no_fail_flags with program_mode } in
+ let sigma, (ty, impls) = interp_type_evars_impls ~flags env sigma ~impls c in
sigma, (ty, impls)
(* When monomorphic the universe constraints and universe names are
@@ -86,11 +87,10 @@ let context_set_of_entry = function
| Monomorphic_entry uctx -> uctx
let declare_assumptions ~poly ~scope ~kind univs nl l =
- let open DeclareDef in
- let () = match scope with
+ let () = let open Declare in match scope with
| Discharge ->
(* declare universes separately for variables *)
- Declare.declare_universe_context ~poly (context_set_of_entry (fst univs))
+ DeclareUctx.declare_universe_context ~poly (context_set_of_entry (fst univs))
| Global _ -> ()
in
let _, _ = List.fold_left (fun (subst,univs) ((is_coe,idl),typ,imps) ->
@@ -99,10 +99,10 @@ let declare_assumptions ~poly ~scope ~kind univs nl l =
let univs,subst' =
List.fold_left_map (fun univs id ->
let refu = match scope with
- | Discharge ->
+ | Declare.Discharge ->
declare_variable is_coe ~kind typ imps Glob_term.Explicit id;
GlobRef.VarRef id.CAst.v, Univ.Instance.empty
- | Global local ->
+ | Declare.Global local ->
declare_axiom is_coe ~local ~poly ~kind typ univs imps nl id
in
next_univs univs, (id.CAst.v, Constr.mkRef refu))
@@ -129,7 +129,7 @@ let process_assumptions_udecls ~scope l =
udecl, id
| (_, ([], _))::_ | [] -> assert false
in
- let open DeclareDef in
+ let open Declare in
let () = match scope, udecl with
| Discharge, Some _ ->
let loc = first_id.CAst.loc in
@@ -160,7 +160,7 @@ let do_assumptions ~program_mode ~poly ~scope ~kind nl l =
let env =
EConstr.push_named_context (List.map (fun {CAst.v=id} -> LocalAssum (make_annot id r,t)) idl) env in
let ienv = List.fold_right (fun {CAst.v=id} ienv ->
- let impls = compute_internalization_data env sigma Variable t imps in
+ let impls = compute_internalization_data env sigma id Variable t imps in
Id.Map.add id impls ienv) idl ienv in
((sigma,env,ienv),((is_coe,idl),t,imps)))
(sigma,env,empty_internalization_env) l
@@ -190,7 +190,7 @@ let context_subst subst (name,b,t,impl) =
let context_insection sigma ~poly ctx =
let uctx = Evd.universe_context_set sigma in
- let () = Declare.declare_universe_context ~poly uctx in
+ let () = DeclareUctx.declare_universe_context ~poly uctx in
let fn subst (name,_,_,_ as d) =
let d = context_subst subst d in
let () = match d with
@@ -203,8 +203,12 @@ let context_insection sigma ~poly ctx =
else Monomorphic_entry Univ.ContextSet.empty
in
let entry = Declare.definition_entry ~univs ~types:t b in
- let _ : GlobRef.t = DeclareDef.declare_definition ~name ~scope:DeclareDef.Discharge
- ~kind:Decls.(IsDefinition Definition) ~ubind:UnivNames.empty_binders ~impargs:[] entry
+ (* XXX Fixme: Use DeclareDef.prepare_definition *)
+ let uctx = Evd.evar_universe_context sigma in
+ let kind = Decls.(IsDefinition Definition) in
+ let _ : GlobRef.t =
+ Declare.declare_entry ~name ~scope:Declare.Discharge
+ ~kind ~impargs:[] ~uctx entry
in
()
in
@@ -221,7 +225,7 @@ let context_nosection sigma ~poly ctx =
(* Multiple monomorphic axioms: declare universes separately to
avoid redeclaring them. *)
let uctx = Evd.universe_context_set sigma in
- let () = Declare.declare_universe_context ~poly uctx in
+ let () = DeclareUctx.declare_universe_context ~poly uctx in
Monomorphic_entry Univ.ContextSet.empty
in
let fn subst d =
diff --git a/vernac/comAssumption.mli b/vernac/comAssumption.mli
index 4b953c8869..989015a9f3 100644
--- a/vernac/comAssumption.mli
+++ b/vernac/comAssumption.mli
@@ -17,7 +17,7 @@ open Constrexpr
val do_assumptions
: program_mode:bool
-> poly:bool
- -> scope:DeclareDef.locality
+ -> scope:Declare.locality
-> kind:Decls.assumption_object_kind
-> Declaremods.inline
-> (ident_decl list * constr_expr) with_coercion list
diff --git a/vernac/comCoercion.ml b/vernac/comCoercion.ml
index c339c53a9b..d6be02245c 100644
--- a/vernac/comCoercion.ml
+++ b/vernac/comCoercion.ml
@@ -256,7 +256,7 @@ let classify_coercion obj =
let inCoercion : coercion -> obj =
declare_object {(default_object "COERCION") with
- open_function = open_coercion;
+ open_function = simple_open open_coercion;
cache_function = cache_coercion;
subst_function = (fun (subst,c) -> subst_coercion subst c);
classify_function = classify_coercion;
@@ -352,8 +352,8 @@ let try_add_new_identity_coercion id ~local ~poly ~source ~target =
let try_add_new_coercion_with_source ref ~local ~poly ~source =
try_add_new_coercion_core ref ~local poly (Some source) None false
-let add_coercion_hook poly { DeclareDef.Hook.S.scope; dref; _ } =
- let open DeclareDef in
+let add_coercion_hook poly { Declare.Hook.S.scope; dref; _ } =
+ let open Declare in
let local = match scope with
| Discharge -> assert false (* Local Coercion in section behaves like Local Definition *)
| Global ImportNeedQualified -> true
@@ -363,10 +363,10 @@ let add_coercion_hook poly { DeclareDef.Hook.S.scope; dref; _ } =
let msg = Nametab.pr_global_env Id.Set.empty dref ++ str " is now a coercion" in
Flags.if_verbose Feedback.msg_info msg
-let add_coercion_hook ~poly = DeclareDef.Hook.make (add_coercion_hook poly)
+let add_coercion_hook ~poly = Declare.Hook.make (add_coercion_hook poly)
-let add_subclass_hook ~poly { DeclareDef.Hook.S.scope; dref; _ } =
- let open DeclareDef in
+let add_subclass_hook ~poly { Declare.Hook.S.scope; dref; _ } =
+ let open Declare in
let stre = match scope with
| Discharge -> assert false (* Local Subclass in section behaves like Local Definition *)
| Global ImportNeedQualified -> true
@@ -375,4 +375,4 @@ let add_subclass_hook ~poly { DeclareDef.Hook.S.scope; dref; _ } =
let cl = class_of_global dref in
try_add_new_coercion_subclass cl ~local:stre ~poly
-let add_subclass_hook ~poly = DeclareDef.Hook.make (add_subclass_hook ~poly)
+let add_subclass_hook ~poly = Declare.Hook.make (add_subclass_hook ~poly)
diff --git a/vernac/comCoercion.mli b/vernac/comCoercion.mli
index 3b44bdaf8a..dee693232f 100644
--- a/vernac/comCoercion.mli
+++ b/vernac/comCoercion.mli
@@ -46,8 +46,8 @@ val try_add_new_identity_coercion
-> local:bool
-> poly:bool -> source:cl_typ -> target:cl_typ -> unit
-val add_coercion_hook : poly:bool -> DeclareDef.Hook.t
+val add_coercion_hook : poly:bool -> Declare.Hook.t
-val add_subclass_hook : poly:bool -> DeclareDef.Hook.t
+val add_subclass_hook : poly:bool -> Declare.Hook.t
val class_of_global : GlobRef.t -> cl_typ
diff --git a/vernac/comDefinition.ml b/vernac/comDefinition.ml
index ba2c1ac115..95f3955309 100644
--- a/vernac/comDefinition.ml
+++ b/vernac/comDefinition.ml
@@ -12,7 +12,6 @@ open Pp
open Util
open Redexpr
open Constrintern
-open Pretyping
(* Commands of the interface: Constant definitions *)
@@ -40,15 +39,56 @@ let check_imps ~impsty ~impsbody =
| [], [] -> () in
aux impsty impsbody
+let protect_pattern_in_binder bl c ctypopt =
+ (* We turn "Definition d binders := body : typ" into *)
+ (* "Definition d := fun binders => body:type" *)
+ (* This is a hack while waiting for LocalPattern in regular environments *)
+ if List.exists (function Constrexpr.CLocalPattern _ -> true | _ -> false) bl
+ then
+ let t = match ctypopt with
+ | None -> CAst.make ?loc:c.CAst.loc (Constrexpr.CHole (None,Namegen.IntroAnonymous,None))
+ | Some t -> t in
+ let loc = Loc.merge_opt c.CAst.loc t.CAst.loc in
+ let c = CAst.make ?loc @@ Constrexpr.CCast (c, Glob_term.CastConv t) in
+ let loc = match List.hd bl with
+ | Constrexpr.CLocalAssum (a::_,_,_) | Constrexpr.CLocalDef (a,_,_) -> a.CAst.loc
+ | Constrexpr.CLocalPattern {CAst.loc} -> loc
+ | Constrexpr.CLocalAssum ([],_,_) -> assert false in
+ let apply_under_binders f env evd c =
+ let rec aux env evd c =
+ let open Constr in
+ let open EConstr in
+ let open Context.Rel.Declaration in
+ match kind evd c with
+ | Lambda (x,t,c) ->
+ let evd,c = aux (push_rel (LocalAssum (x,t)) env) evd c in
+ evd, mkLambda (x,t,c)
+ | LetIn (x,b,t,c) ->
+ let evd,c = aux (push_rel (LocalDef (x,b,t)) env) evd c in
+ evd, mkLetIn (x,t,b,c)
+ | Case (ci,p,a,bl) ->
+ let evd,bl = Array.fold_left_map (aux env) evd bl in
+ evd, mkCase (ci,p,a,bl)
+ | Cast (c,_,_) -> f env evd c (* we remove the cast we had set *)
+ (* This last case may happen when reaching the proof of an
+ impossible case, as when pattern-matching on a vector of length 1 *)
+ | _ -> (evd,c) in
+ aux env evd c in
+ ([], Constrexpr_ops.mkLambdaCN ?loc:(Loc.merge_opt loc c.CAst.loc) bl c, None, apply_under_binders)
+ else
+ (bl, c, ctypopt, fun f env evd c -> f env evd c)
+
let interp_definition ~program_mode pl bl ~poly red_option c ctypopt =
+ let flags = Pretyping.{ all_no_fail_flags with program_mode } in
let env = Global.env() in
(* Explicitly bound universes and constraints *)
let evd, udecl = Constrexpr_ops.interp_univ_decl_opt env pl in
+ let (bl, c, ctypopt, apply_under_binders) = protect_pattern_in_binder bl c ctypopt in
(* Build the parameters *)
let evd, (impls, ((env_bl, ctx), imps1)) = interp_context_evars ~program_mode env evd bl in
(* Build the type *)
let evd, tyopt = Option.fold_left_map
- (interp_type_evars_impls ~program_mode ~impls env_bl)
+ (interp_type_evars_impls ~flags ~impls env_bl)
evd ctypopt
in
(* Build the body, and merge implicits from parameters and from type/body *)
@@ -63,46 +103,31 @@ let interp_definition ~program_mode pl bl ~poly red_option c ctypopt =
evd, c, imps1@impsty, Some ty
in
(* Do the reduction *)
- let evd, c = red_constant_body red_option env_bl evd c in
+ let evd, c = apply_under_binders (red_constant_body red_option) env_bl evd c in
(* Declare the definition *)
let c = EConstr.it_mkLambda_or_LetIn c ctx in
let tyopt = Option.map (fun ty -> EConstr.it_mkProd_or_LetIn ty ctx) tyopt in
+ (c, tyopt), evd, udecl, imps
- let evd, ce = DeclareDef.prepare_definition ~allow_evars:program_mode
- ~opaque:false ~poly evd ~udecl ~types:tyopt ~body:c in
-
- (ce, evd, udecl, imps)
-
-let check_definition ~program_mode (ce, evd, _, imps) =
- let env = Global.env () in
- check_evars_are_solved ~program_mode env evd;
- ce
+let do_definition ?hook ~name ~scope ~poly ~kind udecl bl red_option c ctypopt =
+ let program_mode = false in
+ let (body, types), evd, udecl, impargs =
+ interp_definition ~program_mode udecl bl ~poly red_option c ctypopt
+ in
+ let kind = Decls.IsDefinition kind in
+ let _ : Names.GlobRef.t =
+ Declare.declare_definition ~name ~scope ~kind ?hook ~impargs
+ ~opaque:false ~poly evd ~udecl ~types ~body
+ in ()
-let do_definition ~program_mode ?hook ~name ~scope ~poly ~kind udecl bl red_option c ctypopt =
- let (ce, evd, udecl, impargs as def) =
+let do_definition_program ?hook ~name ~scope ~poly ~kind udecl bl red_option c ctypopt =
+ let program_mode = true in
+ let (body, types), evd, udecl, impargs =
interp_definition ~program_mode udecl bl ~poly red_option c ctypopt
in
- if program_mode then
- let env = Global.env () in
- let (c,ctx), sideff = Future.force ce.Declare.proof_entry_body in
- assert(Safe_typing.empty_private_constants = sideff.Evd.seff_private);
- assert(Univ.ContextSet.is_empty ctx);
- Obligations.check_evars env evd;
- let c = EConstr.of_constr c in
- let typ = match ce.Declare.proof_entry_type with
- | Some t -> EConstr.of_constr t
- | None -> Retyping.get_type_of env evd c
- in
- let obls, _, c, cty =
- Obligations.eterm_obligations env name evd 0 c typ
- in
- let uctx = Evd.evar_universe_context evd in
- ignore(Obligations.add_definition
- ~name ~term:c cty ~uctx ~udecl ~impargs ~scope ~poly ~kind ?hook obls)
- else
- let ce = check_definition ~program_mode def in
- let uctx = Evd.evar_universe_context evd in
- let hook_data = Option.map (fun hook -> hook, uctx, []) hook in
- let kind = Decls.IsDefinition kind in
- ignore(DeclareDef.declare_definition ~name ~scope ~kind ?hook_data ~ubind:(Evd.universe_binders evd) ce ~impargs)
+ let term, ty, uctx, obls = Declare.prepare_obligation ~name ~poly ~body ~types ~udecl evd in
+ let _ : DeclareObl.progress =
+ Obligations.add_definition
+ ~name ~term ty ~uctx ~udecl ~impargs ~scope ~poly ~kind ?hook obls
+ in ()
diff --git a/vernac/comDefinition.mli b/vernac/comDefinition.mli
index 6c6da8952e..2e8fe16252 100644
--- a/vernac/comDefinition.mli
+++ b/vernac/comDefinition.mli
@@ -15,10 +15,9 @@ open Constrexpr
(** {6 Definitions/Let} *)
val do_definition
- : program_mode:bool
- -> ?hook:DeclareDef.Hook.t
+ : ?hook:Declare.Hook.t
-> name:Id.t
- -> scope:DeclareDef.locality
+ -> scope:Declare.locality
-> poly:bool
-> kind:Decls.definition_object_kind
-> universe_decl_expr option
@@ -28,18 +27,15 @@ val do_definition
-> constr_expr option
-> unit
-(************************************************************************)
-(** Internal API *)
-(************************************************************************)
-
-(** Not used anywhere. *)
-val interp_definition
- : program_mode:bool
+val do_definition_program
+ : ?hook:Declare.Hook.t
+ -> name:Id.t
+ -> scope:Declare.locality
+ -> poly:bool
+ -> kind:Decls.definition_object_kind
-> universe_decl_expr option
-> local_binder_expr list
- -> poly:bool
-> red_expr option
-> constr_expr
-> constr_expr option
- -> Evd.side_effects Declare.proof_entry *
- Evd.evar_map * UState.universe_decl * Impargs.manual_implicits
+ -> unit
diff --git a/vernac/comFixpoint.ml b/vernac/comFixpoint.ml
index 6580495295..80ca85e9a6 100644
--- a/vernac/comFixpoint.ml
+++ b/vernac/comFixpoint.ml
@@ -53,7 +53,7 @@ let rec partial_order cmp = function
(z, Inr (List.add_set cmp x (List.remove cmp y zge)))
else
(z, Inr zge)) res in
- browse ((y,Inl x)::res) xge' (List.union cmp xge (List.remove cmp x yge))
+ browse ((y,Inl x)::res) xge' (List.union cmp xge yge)
else
browse res (List.add_set cmp y (List.union cmp xge' yge)) xge
with Not_found -> browse res (List.add_set cmp y xge') xge
@@ -82,16 +82,25 @@ let warn_non_full_mutual =
(fun (x,xge,y,yge,isfix,rest) ->
non_full_mutual_message x xge y yge isfix rest)
-let check_mutuality env evd isfix fixl =
+let warn_non_recursive =
+ CWarnings.create ~name:"non-recursive" ~category:"fixpoints"
+ (fun (x,isfix) ->
+ let k = if isfix then "fixpoint" else "cofixpoint" in
+ strbrk "Not a truly recursive " ++ str k ++ str ".")
+
+let check_true_recursivity env evd isfix fixl =
let names = List.map fst fixl in
let preorder =
List.map (fun (id,def) ->
- (id, List.filter (fun id' -> not (Id.equal id id') && Termops.occur_var env evd id' def) names))
+ (id, List.filter (fun id' -> Termops.occur_var env evd id' def) names))
fixl in
let po = partial_order Id.equal preorder in
match List.filter (function (_,Inr _) -> true | _ -> false) po with
| (x,Inr xge)::(y,Inr yge)::rest ->
warn_non_full_mutual (x,xge,y,yge,isfix,rest)
+ | _ ->
+ match po with
+ | [x,Inr []] -> warn_non_recursive (x,isfix)
| _ -> ()
let interp_fix_context ~program_mode ~cofix env sigma fix =
@@ -107,7 +116,8 @@ let interp_fix_context ~program_mode ~cofix env sigma fix =
sigma, ((env'', ctx' @ ctx), (impl_env',imps @ imps'), annot)
let interp_fix_ccl ~program_mode sigma impls (env,_) fix =
- let sigma, (c, impl) = interp_type_evars_impls ~program_mode ~impls env sigma fix.Vernacexpr.rtype in
+ let flags = Pretyping.{ all_no_fail_flags with program_mode } in
+ let sigma, (c, impl) = interp_type_evars_impls ~flags ~impls env sigma fix.Vernacexpr.rtype in
let r = Retyping.relevance_of_type env sigma c in
sigma, (c, r, impl)
@@ -140,8 +150,8 @@ let compute_possible_guardness_evidences (ctx,_,recindex) =
fixpoints ?) *)
List.interval 0 (Context.Rel.nhyps ctx - 1)
-type recursive_preentry =
- Id.t list * Sorts.relevance list * Constr.t option list * Constr.types list
+type ('constr, 'types) recursive_preentry =
+ Id.t list * Sorts.relevance list * 'constr option list * 'types list
(* Wellfounded definition *)
@@ -221,7 +231,7 @@ let interp_recursive ~program_mode ~cofix (fixl : 'a Vernacexpr.fix_expr_gen lis
let check_recursive isfix env evd (fixnames,_,fixdefs,_) =
if List.for_all Option.has_some fixdefs then begin
let fixdefs = List.map Option.get fixdefs in
- check_mutuality env evd isfix (List.combine fixnames fixdefs)
+ check_true_recursivity env evd isfix (List.combine fixnames fixdefs)
end
let ground_fixpoint env evd (fixnames,fixrs,fixdefs,fixtypes) =
@@ -230,9 +240,13 @@ let ground_fixpoint env evd (fixnames,fixrs,fixdefs,fixtypes) =
let fixtypes = List.map EConstr.(to_constr evd) fixtypes in
Evd.evar_universe_context evd, (fixnames,fixrs,fixdefs,fixtypes)
-let interp_fixpoint ~cofix l =
+(* XXX: Unify with interp_recursive *)
+let interp_fixpoint ?(check_recursivity=true) ~cofix l :
+ ( (Constr.t, Constr.types) recursive_preentry *
+ UState.universe_decl * UState.t *
+ (EConstr.rel_context * Impargs.manual_implicits * int option) list) =
let (env,_,pl,evd),fix,info = interp_recursive ~program_mode:false ~cofix l in
- check_recursive true env evd fix;
+ if check_recursivity then check_recursive true env evd fix;
let uctx,fix = ground_fixpoint env evd fix in
(fix,pl,uctx,info)
@@ -243,8 +257,10 @@ let build_recthms ~indexes fixnames fixtypes fiximps =
in
let thms =
List.map3 (fun name typ (ctx,impargs,_) ->
- { DeclareDef.Recthm.name; typ
- ; args = List.map Context.Rel.Declaration.get_name ctx; impargs})
+ { Declare.Recthm.name
+ ; typ
+ ; args = List.map Context.Rel.Declaration.get_name ctx
+ ; impargs})
fixnames fixtypes fiximps
in
fix_kind, cofix, thms
@@ -268,7 +284,7 @@ let declare_fixpoint_generic ?indexes ~scope ~poly ((fixnames,fixrs,fixdefs,fixt
let rec_declaration = prepare_recursive_declaration fixnames fixrs fixtypes fixdefs in
let fix_kind = Decls.IsDefinition fix_kind in
let _ : GlobRef.t list =
- DeclareDef.declare_mutually_recursive ~scope ~opaque:false ~kind:fix_kind ~poly ~uctx
+ Declare.declare_mutually_recursive ~scope ~opaque:false ~kind:fix_kind ~poly ~uctx
~possible_indexes:indexes ~restrict_ucontext:true ~udecl ~ntns ~rec_declaration
fixitems
in
diff --git a/vernac/comFixpoint.mli b/vernac/comFixpoint.mli
index 2ad6c03bae..62a9d10bae 100644
--- a/vernac/comFixpoint.mli
+++ b/vernac/comFixpoint.mli
@@ -9,7 +9,6 @@
(************************************************************************)
open Names
-open Constr
open Vernacexpr
(** {6 Fixpoints and cofixpoints} *)
@@ -17,16 +16,16 @@ open Vernacexpr
(** Entry points for the vernacular commands Fixpoint and CoFixpoint *)
val do_fixpoint_interactive :
- scope:DeclareDef.locality -> poly:bool -> fixpoint_expr list -> Lemmas.t
+ scope:Declare.locality -> poly:bool -> fixpoint_expr list -> Lemmas.t
val do_fixpoint :
- scope:DeclareDef.locality -> poly:bool -> fixpoint_expr list -> unit
+ scope:Declare.locality -> poly:bool -> fixpoint_expr list -> unit
val do_cofixpoint_interactive :
- scope:DeclareDef.locality -> poly:bool -> cofixpoint_expr list -> Lemmas.t
+ scope:Declare.locality -> poly:bool -> cofixpoint_expr list -> Lemmas.t
val do_cofixpoint :
- scope:DeclareDef.locality -> poly:bool -> cofixpoint_expr list -> unit
+ scope:Declare.locality -> poly:bool -> cofixpoint_expr list -> unit
(************************************************************************)
(** Internal API *)
@@ -40,6 +39,9 @@ val adjust_rec_order
-> Constrexpr.recursion_order_expr option
-> lident option
+(** names / relevance / defs / types *)
+type ('constr, 'types) recursive_preentry = Id.t list * Sorts.relevance list * 'constr option list * 'types list
+
(** Exported for Program *)
val interp_recursive :
(* Misc arguments *)
@@ -49,18 +51,18 @@ val interp_recursive :
(* env / signature / univs / evar_map *)
(Environ.env * EConstr.named_context * UState.universe_decl * Evd.evar_map) *
(* names / defs / types *)
- (Id.t list * Sorts.relevance list * EConstr.constr option list * EConstr.types list) *
+ (EConstr.t, EConstr.types) recursive_preentry *
(* ctx per mutual def / implicits / struct annotations *)
(EConstr.rel_context * Impargs.manual_implicits * int option) list
(** Exported for Funind *)
-type recursive_preentry = Id.t list * Sorts.relevance list * constr option list * types list
-
val interp_fixpoint
- : cofix:bool
+ : ?check_recursivity:bool ->
+ cofix:bool
-> lident option fix_expr_gen list
- -> recursive_preentry * UState.universe_decl * UState.t *
+ -> (Constr.t, Constr.types) recursive_preentry *
+ UState.universe_decl * UState.t *
(EConstr.rel_context * Impargs.manual_implicits * int option) list
(** Very private function, do not use *)
diff --git a/vernac/comHints.ml b/vernac/comHints.ml
new file mode 100644
index 0000000000..2fd6fe2b29
--- /dev/null
+++ b/vernac/comHints.ml
@@ -0,0 +1,157 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * Copyright INRIA, CNRS and contributors *)
+(* <O___,, * (see version control and CREDITS file for authors & dates) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Util
+
+(** (Partial) implementation of the [Hint] command; some more
+ functionality still lives in tactics/hints.ml *)
+
+let project_hint ~poly pri l2r r =
+ let open EConstr in
+ let open Coqlib in
+ let gr = Smartlocate.global_with_alias r in
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ let sigma, c = Evd.fresh_global env sigma gr in
+ let t = Retyping.get_type_of env sigma c in
+ let t =
+ Tacred.reduce_to_quantified_ref env sigma (lib_ref "core.iff.type") t
+ in
+ let sign, ccl = decompose_prod_assum sigma t in
+ let a, b =
+ match snd (decompose_app sigma ccl) with
+ | [a; b] -> (a, b)
+ | _ -> assert false
+ in
+ let p = if l2r then lib_ref "core.iff.proj1" else lib_ref "core.iff.proj2" in
+ let sigma, p = Evd.fresh_global env sigma p in
+ let c =
+ Reductionops.whd_beta sigma
+ (mkApp (c, Context.Rel.to_extended_vect mkRel 0 sign))
+ in
+ let c =
+ it_mkLambda_or_LetIn
+ (mkApp
+ ( p
+ , [| mkArrow a Sorts.Relevant (Vars.lift 1 b)
+ ; mkArrow b Sorts.Relevant (Vars.lift 1 a)
+ ; c |] ))
+ sign
+ in
+ let name =
+ Nameops.add_suffix
+ (Nametab.basename_of_global gr)
+ ("_proj_" ^ if l2r then "l2r" else "r2l")
+ in
+ let ctx = Evd.univ_entry ~poly sigma in
+ let c = EConstr.to_constr sigma c in
+ let cb =
+ Declare.(DefinitionEntry (definition_entry ~univs:ctx ~opaque:false c))
+ in
+ let c =
+ Declare.declare_constant ~local:Declare.ImportDefaultBehavior ~name
+ ~kind:Decls.(IsDefinition Definition)
+ cb
+ in
+ let info = {Typeclasses.hint_priority = pri; hint_pattern = None} in
+ (info, false, true, Hints.PathAny, Hints.IsGlobRef (Names.GlobRef.ConstRef c))
+
+let warn_deprecated_hint_constr =
+ CWarnings.create ~name:"deprecated-hint-constr" ~category:"deprecated"
+ (fun () ->
+ Pp.strbrk
+ "Declaring arbitrary terms as hints is deprecated; declare a global \
+ reference instead")
+
+let interp_hints ~poly h =
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ let f poly c =
+ let evd, c = Constrintern.interp_open_constr env sigma c in
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ let c, diff = Hints.prepare_hint true env sigma (evd, c) in
+ if poly then (Hints.IsConstr (c, diff) [@ocaml.warning "-3"])
+ else
+ let () = DeclareUctx.declare_universe_context ~poly:false diff in
+ (Hints.IsConstr (c, Univ.ContextSet.empty) [@ocaml.warning "-3"])
+ in
+ let fref r =
+ let gr = Smartlocate.global_with_alias r in
+ Dumpglob.add_glob ?loc:r.CAst.loc gr;
+ gr
+ in
+ let fr r = Tacred.evaluable_of_global_reference env (fref r) in
+ let fi c =
+ let open Hints in
+ let open Vernacexpr in
+ match c with
+ | HintsReference c ->
+ let gr = Smartlocate.global_with_alias c in
+ (PathHints [gr], poly, IsGlobRef gr)
+ | HintsConstr c ->
+ let () = warn_deprecated_hint_constr () in
+ (PathAny, poly, f poly c)
+ in
+ let fp = Constrintern.intern_constr_pattern env sigma in
+ let fres (info, b, r) =
+ let path, poly, gr = fi r in
+ let info =
+ { info with
+ Typeclasses.hint_pattern = Option.map fp info.Typeclasses.hint_pattern
+ }
+ in
+ (info, poly, b, path, gr)
+ in
+ let open Hints in
+ let open Vernacexpr in
+ let ft = function
+ | HintsVariables -> HintsVariables
+ | HintsConstants -> HintsConstants
+ | HintsReferences lhints -> HintsReferences (List.map fr lhints)
+ in
+ let fp = Constrintern.intern_constr_pattern (Global.env ()) in
+ match h with
+ | HintsResolve lhints -> HintsResolveEntry (List.map fres lhints)
+ | HintsResolveIFF (l2r, lc, n) ->
+ HintsResolveEntry (List.map (project_hint ~poly n l2r) lc)
+ | HintsImmediate lhints -> HintsImmediateEntry (List.map fi lhints)
+ | HintsUnfold lhints -> HintsUnfoldEntry (List.map fr lhints)
+ | HintsTransparency (t, b) -> HintsTransparencyEntry (ft t, b)
+ | HintsMode (r, l) -> HintsModeEntry (fref r, l)
+ | HintsConstructors lqid ->
+ let constr_hints_of_ind qid =
+ let ind = Smartlocate.global_inductive_with_alias qid in
+ let mib, _ = Global.lookup_inductive ind in
+ Dumpglob.dump_reference ?loc:qid.CAst.loc "<>"
+ (Libnames.string_of_qualid qid)
+ "ind";
+ List.init (Inductiveops.nconstructors env ind) (fun i ->
+ let c = (ind, i + 1) in
+ let gr = Names.GlobRef.ConstructRef c in
+ ( empty_hint_info
+ , Declareops.inductive_is_polymorphic mib
+ , true
+ , PathHints [gr]
+ , IsGlobRef gr ))
+ in
+ HintsResolveEntry (List.flatten (List.map constr_hints_of_ind lqid))
+ | HintsExtern (pri, patcom, tacexp) ->
+ let pat = Option.map (fp sigma) patcom in
+ let l = match pat with None -> [] | Some (l, _) -> l in
+ let ltacvars =
+ List.fold_left
+ (fun accu x -> Names.Id.Set.add x accu)
+ Names.Id.Set.empty l
+ in
+ let env = Genintern.{(empty_glob_sign env) with ltacvars} in
+ let _, tacexp = Genintern.generic_intern env tacexp in
+ HintsExternEntry
+ ({Typeclasses.hint_priority = Some pri; hint_pattern = pat}, tacexp)
diff --git a/vernac/comHints.mli b/vernac/comHints.mli
new file mode 100644
index 0000000000..20894eecf1
--- /dev/null
+++ b/vernac/comHints.mli
@@ -0,0 +1,11 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * Copyright INRIA, CNRS and contributors *)
+(* <O___,, * (see version control and CREDITS file for authors & dates) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+val interp_hints : poly:bool -> Vernacexpr.hints_expr -> Hints.hints_entry
diff --git a/vernac/comInductive.ml b/vernac/comInductive.ml
index 1f1700b4d6..cc9b840bed 100644
--- a/vernac/comInductive.ml
+++ b/vernac/comInductive.ml
@@ -20,7 +20,6 @@ open Nameops
open Constrexpr
open Constrexpr_ops
open Constrintern
-open Reductionops
open Type_errors
open Pretyping
open Context.Rel.Declaration
@@ -51,20 +50,6 @@ let should_auto_template =
if b then warn_auto_template id;
b
-let rec complete_conclusion a cs = CAst.map_with_loc (fun ?loc -> function
- | CProdN (bl,c) -> CProdN (bl,complete_conclusion a cs c)
- | CLetIn (na,b,t,c) -> CLetIn (na,b,t,complete_conclusion a cs c)
- | CHole (k, _, _) ->
- let (has_no_args,name,params) = a in
- if not has_no_args then
- user_err ?loc
- (strbrk"Cannot infer the non constant arguments of the conclusion of "
- ++ Id.print cs ++ str ".");
- let args = List.map (fun id -> CAst.(make ?loc @@ CRef(qualid_of_ident ?loc id,None))) params in
- CAppExpl ((None,qualid_of_ident ?loc name,None),List.rev args)
- | c -> c
- )
-
let push_types env idl rl tl =
List.fold_left3 (fun env id r t -> EConstr.push_rel (LocalAssum (make_annot (Name id) r,t)) env)
env idl rl tl
@@ -93,10 +78,6 @@ let check_all_names_different indl =
| [] -> ()
| _ -> raise (InductiveError (SameNamesOverlap l))
-let mk_mltype_data sigma env assums arity indname =
- let is_ml_type = is_sort env sigma arity in
- (is_ml_type,indname,assums)
-
(** Make the arity conclusion flexible to avoid generating an upper bound universe now,
only if the universe does not appear anywhere else.
This is really a hack to stay compatible with the semantics of template polymorphic
@@ -145,16 +126,50 @@ let pretype_ind_arity env sigma (loc, c, impls, pseudo_poly) =
in
sigma, (t, Retyping.relevance_of_sort s, concl, impls)
-let interp_cstrs env sigma impls mldata arity ind =
+(* ind_rel is the Rel for this inductive in the context without params.
+ n is how many arguments there are in the constructor. *)
+let model_conclusion env sigma ind_rel params n arity_indices =
+ let model_head = EConstr.mkRel (n + Context.Rel.length params + ind_rel) in
+ let model_params = Context.Rel.to_extended_vect EConstr.mkRel n params in
+ let sigma,model_indices =
+ List.fold_right
+ (fun (_,t) (sigma, subst) ->
+ let t = EConstr.Vars.substl subst (EConstr.Vars.liftn n (List.length subst + 1) (EConstr.Vars.liftn 1 (List.length params + List.length subst + 1) t)) in
+ let sigma, c = Evarutil.new_evar env sigma t in
+ sigma, c::subst)
+ arity_indices (sigma, []) in
+ sigma, EConstr.mkApp (EConstr.mkApp (model_head, model_params), Array.of_list (List.rev model_indices))
+
+let interp_cstrs env (sigma, ind_rel) impls params ind arity =
let cnames,ctyps = List.split ind.ind_lc in
- (* Complete conclusions of constructor types if given in ML-style syntax *)
- let ctyps' = List.map2 (complete_conclusion mldata) cnames ctyps in
+ let arity_indices, cstr_sort = Reductionops.splay_arity env sigma arity in
(* Interpret the constructor types *)
- let sigma, (ctyps'', cimpls) =
+ let interp_cstr sigma ctyp =
+ let flags =
+ Pretyping.{ all_no_fail_flags with
+ use_typeclasses = UseTCForConv;
+ solve_unification_constraints = false }
+ in
+ let sigma, (ctyp, cimpl) = interp_type_evars_impls ~flags env sigma ~impls ctyp in
+ let ctx, concl = Reductionops.splay_prod_assum env sigma ctyp in
+ let concl_env = EConstr.push_rel_context ctx env in
+ let sigma_with_model_evars, model =
+ model_conclusion concl_env sigma ind_rel params (Context.Rel.length ctx) arity_indices
+ in
+ (* unify the expected with the provided conclusion *)
+ let sigma =
+ try Evarconv.unify concl_env sigma_with_model_evars Reduction.CONV concl model
+ with Evarconv.UnableToUnify (sigma,e) ->
+ user_err (Himsg.explain_pretype_error concl_env sigma
+ (Pretype_errors.CannotUnify (concl, model, (Some e))))
+ in
+ sigma, (ctyp, cimpl)
+ in
+ let sigma, (ctyps, cimpls) =
on_snd List.split @@
- List.fold_left_map (fun sigma l ->
- interp_type_evars_impls ~program_mode:false env sigma ~impls l) sigma ctyps' in
- sigma, (cnames, ctyps'', cimpls)
+ List.fold_left_map interp_cstr sigma ctyps
+ in
+ (sigma, pred ind_rel), (cnames, ctyps, cimpls)
let sign_level env evd sign =
fst (List.fold_right
@@ -427,6 +442,30 @@ let interp_params env udecl uparamsl paramsl =
sigma, env_params, (ctx_params, env_uparams, ctx_uparams,
List.map (RelDecl.get_name %> Name.get_id) assums, userimpls, useruimpls, impls, udecl)
+(* When a hole remains for a param, pretend the param is uniform and
+ do the unification.
+ [env_ar_par] is [uparams; inds; params]
+ *)
+let maybe_unify_params_in env_ar_par sigma ~ninds ~nparams c =
+ let is_ind sigma k c = match EConstr.kind sigma c with
+ | Constr.Rel n ->
+ (* env is [uparams; inds; params; k other things] *)
+ n > k + nparams && n <= k + nparams + ninds
+ | _ -> false
+ in
+ let rec aux (env,k as envk) sigma c = match EConstr.kind sigma c with
+ | Constr.App (h,args) when is_ind sigma k h ->
+ Array.fold_left_i (fun i sigma arg ->
+ if i >= nparams || not (EConstr.isEvar sigma arg) then sigma
+ else Evarconv.unify_delay env sigma arg (EConstr.mkRel (k+nparams-i)))
+ sigma args
+ | _ -> Termops.fold_constr_with_full_binders
+ sigma
+ (fun d (env,k) -> EConstr.push_rel d env, k+1)
+ aux envk sigma c
+ in
+ aux (env_ar_par,0) sigma c
+
let interp_mutual_inductive_gen env0 ~template udecl (uparamsl,paramsl,indl) notations ~cumulative ~poly ~private_ind finite =
check_all_names_different indl;
List.iter check_param paramsl;
@@ -464,20 +503,31 @@ let interp_mutual_inductive_gen env0 ~template udecl (uparamsl,paramsl,indl) not
(* Compute interpretation metadatas *)
let indimpls = List.map (fun impls -> userimpls @ impls) indimpls in
- let impls = compute_internalization_env env_uparams sigma ~impls (Inductive (params,true)) indnames fullarities indimpls in
- let ntn_impls = compute_internalization_env env_uparams sigma (Inductive (params,true)) indnames fullarities indimpls in
- let mldatas = List.map2 (mk_mltype_data sigma env_params params) arities indnames in
+ let impls = compute_internalization_env env_uparams sigma ~impls Inductive indnames fullarities indimpls in
+ let ntn_impls = compute_internalization_env env_uparams sigma Inductive indnames fullarities indimpls in
- let sigma, constructors =
+ let ninds = List.length indl in
+ let (sigma, _), constructors =
Metasyntax.with_syntax_protection (fun () ->
- (* Temporary declaration of notations and scopes *)
- List.iter (Metasyntax.set_notation_for_interpretation env_params ntn_impls) notations;
- (* Interpret the constructor types *)
- List.fold_left3_map (fun sigma -> interp_cstrs env_ar_params sigma impls) sigma mldatas arities indl)
- () in
+ (* Temporary declaration of notations and scopes *)
+ List.iter (Metasyntax.set_notation_for_interpretation env_params ntn_impls) notations;
+ (* Interpret the constructor types *)
+ List.fold_left2_map
+ (fun (sigma, ind_rel) -> interp_cstrs env_ar_params (sigma, ind_rel) impls ctx_params)
+ (sigma, ninds) indl arities)
+ ()
+ in
- (* generalize over the uniform parameters *)
let nparams = Context.Rel.length ctx_params in
+ let sigma =
+ List.fold_left (fun sigma (_,ctyps,_) ->
+ List.fold_left (fun sigma ctyp ->
+ maybe_unify_params_in env_ar_params sigma ~ninds ~nparams ctyp)
+ sigma ctyps)
+ sigma constructors
+ in
+
+ (* generalize over the uniform parameters *)
let nuparams = Context.Rel.length ctx_uparams in
let uargs = Context.Rel.to_extended_vect EConstr.mkRel 0 ctx_uparams in
let uparam_subst =
diff --git a/vernac/comInductive.mli b/vernac/comInductive.mli
index 2b9da1d4e5..984581152a 100644
--- a/vernac/comInductive.mli
+++ b/vernac/comInductive.mli
@@ -88,3 +88,9 @@ val template_polymorphism_candidate
polymorphic. It should have at least one universe in its
monomorphic universe context that can be made parametric in its
conclusion sort, if one is given. *)
+
+val maybe_unify_params_in : Environ.env -> Evd.evar_map -> ninds:int -> nparams:int
+ -> EConstr.t -> Evd.evar_map
+(** [nparams] is the number of parameters which aren't treated as
+ uniform, ie the length of params (including letins) where the env
+ is [uniform params, inductives, params]. *)
diff --git a/vernac/comProgramFixpoint.ml b/vernac/comProgramFixpoint.ml
index 3bac0419ef..4e9e24b119 100644
--- a/vernac/comProgramFixpoint.ml
+++ b/vernac/comProgramFixpoint.ml
@@ -195,13 +195,14 @@ let build_wellfounded (recname,pl,bl,arityc,body) poly r measure notation =
let lift_lets = lift_rel_context 1 letbinders in
let sigma, intern_body =
let ctx = LocalAssum (make_annot (Name recname) Sorts.Relevant, get_type curry_fun) :: binders_rel in
- let (r, l, impls, scopes) =
- Constrintern.compute_internalization_data env sigma
+ let interning_data =
+ Constrintern.compute_internalization_data env sigma recname
Constrintern.Recursive full_arity impls
in
let newimpls = Id.Map.singleton recname
- (r, l, impls @ [Some (ExplByName (Id.of_string "recproof"), Impargs.Manual, (true, false))],
- scopes @ [None]) in
+ (Constrintern.extend_internalization_data interning_data
+ (Some (ExplByName (Id.of_string "recproof"), Impargs.Manual, (true, false)))
+ None) in
interp_casted_constr_evars ~program_mode:true (push_rel_context ctx env) sigma
~impls:newimpls body (lift 1 top_arity)
in
@@ -229,7 +230,7 @@ let build_wellfounded (recname,pl,bl,arityc,body) poly r measure notation =
let name = add_suffix recname "_func" in
(* XXX: Mutating the evar_map in the hook! *)
(* XXX: Likely the sigma is out of date when the hook is called .... *)
- let hook sigma { DeclareDef.Hook.S.dref; _ } =
+ let hook sigma { Declare.Hook.S.dref; _ } =
let sigma, h_body = Evarutil.new_global sigma dref in
let body = it_mkLambda_or_LetIn (mkApp (h_body, [|make|])) binders_rel in
let ty = it_mkProd_or_LetIn top_arity binders_rel in
@@ -247,16 +248,16 @@ let build_wellfounded (recname,pl,bl,arityc,body) poly r measure notation =
hook, name, typ
else
let typ = it_mkProd_or_LetIn top_arity binders_rel in
- let hook sigma { DeclareDef.Hook.S.dref; _ } =
+ let hook sigma { Declare.Hook.S.dref; _ } =
if Impargs.is_implicit_args () || not (List.is_empty impls) then
Impargs.declare_manual_implicits false dref impls
in hook, recname, typ
in
(* XXX: Capturing sigma here... bad bad *)
- let hook = DeclareDef.Hook.make (hook sigma) in
- Obligations.check_evars env sigma;
+ let hook = Declare.Hook.make (hook sigma) in
+ RetrieveObl.check_evars env sigma;
let evars, _, evars_def, evars_typ =
- Obligations.eterm_obligations env recname sigma 0 def typ
+ RetrieveObl.retrieve_obligations env recname sigma 0 def typ
in
let uctx = Evd.evar_universe_context sigma in
ignore(Obligations.add_definition ~name:recname ~term:evars_def ~udecl
@@ -281,15 +282,15 @@ let do_program_recursive ~scope ~poly fixkind fixl =
let evd = Typeclasses.resolve_typeclasses ~filter:Typeclasses.no_goals ~fail:true env evd in
(* Solve remaining evars *)
let evd = nf_evar_map_undefined evd in
- let collect_evars id def typ imps =
+ let collect_evars name def typ impargs =
(* Generalize by the recursive prototypes *)
let def = nf_evar evd (Termops.it_mkNamedLambda_or_LetIn def rec_sign) in
let typ = nf_evar evd (Termops.it_mkNamedProd_or_LetIn typ rec_sign) in
let evm = collect_evars_of_term evd def typ in
let evars, _, def, typ =
- Obligations.eterm_obligations env id evm
+ RetrieveObl.retrieve_obligations env name evm
(List.length rec_sign) def typ in
- (id, def, typ, imps, evars)
+ ({ Declare.Recthm.name; typ; impargs; args = [] }, def, evars)
in
let (fixnames,fixrs,fixdefs,fixtypes) = fix in
let fiximps = List.map pi2 info in
diff --git a/vernac/comProgramFixpoint.mli b/vernac/comProgramFixpoint.mli
index 6851c9f69e..8b1fa6c202 100644
--- a/vernac/comProgramFixpoint.mli
+++ b/vernac/comProgramFixpoint.mli
@@ -14,8 +14,8 @@ open Vernacexpr
val do_fixpoint :
(* When [false], assume guarded. *)
- scope:DeclareDef.locality -> poly:bool -> fixpoint_expr list -> unit
+ scope:Declare.locality -> poly:bool -> fixpoint_expr list -> unit
val do_cofixpoint :
(* When [false], assume guarded. *)
- scope:DeclareDef.locality -> poly:bool -> cofixpoint_expr list -> unit
+ scope:Declare.locality -> poly:bool -> cofixpoint_expr list -> unit
diff --git a/vernac/declare.ml b/vernac/declare.ml
new file mode 100644
index 0000000000..c3f95c5297
--- /dev/null
+++ b/vernac/declare.ml
@@ -0,0 +1,1055 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * Copyright INRIA, CNRS and contributors *)
+(* <O___,, * (see version control and CREDITS file for authors & dates) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** This module is about the low-level declaration of logical objects *)
+
+open Pp
+open Util
+open Names
+open Safe_typing
+module NamedDecl = Context.Named.Declaration
+
+type opacity_flag = Vernacexpr.opacity_flag = Opaque | Transparent
+
+type t =
+ { endline_tactic : Genarg.glob_generic_argument option
+ ; section_vars : Id.Set.t option
+ ; proof : Proof.t
+ ; udecl: UState.universe_decl
+ (** Initial universe declarations *)
+ ; initial_euctx : UState.t
+ (** The initial universe context (for the statement) *)
+ }
+
+(*** Proof Global manipulation ***)
+
+let get_proof ps = ps.proof
+let get_proof_name ps = (Proof.data ps.proof).Proof.name
+
+let get_initial_euctx ps = ps.initial_euctx
+
+let map_proof f p = { p with proof = f p.proof }
+let map_fold_proof f p = let proof, res = f p.proof in { p with proof }, res
+
+let map_fold_proof_endline f ps =
+ let et =
+ match ps.endline_tactic with
+ | None -> Proofview.tclUNIT ()
+ | Some tac ->
+ let open Geninterp in
+ let {Proof.poly} = Proof.data ps.proof in
+ let ist = { lfun = Id.Map.empty; poly; extra = TacStore.empty } in
+ let Genarg.GenArg (Genarg.Glbwit tag, tac) = tac in
+ let tac = Geninterp.interp tag ist tac in
+ Ftactic.run tac (fun _ -> Proofview.tclUNIT ())
+ in
+ let (newpr,ret) = f et ps.proof in
+ let ps = { ps with proof = newpr } in
+ ps, ret
+
+let compact_the_proof pf = map_proof Proof.compact pf
+
+(* Sets the tactic to be used when a tactic line is closed with [...] *)
+let set_endline_tactic tac ps =
+ { ps with endline_tactic = Some tac }
+
+(** [start_proof ~name ~udecl ~poly sigma goals] starts a proof of
+ name [name] with goals [goals] (a list of pairs of environment and
+ conclusion). The proof is started in the evar map [sigma] (which
+ can typically contain universe constraints), and with universe
+ bindings [udecl]. *)
+let start_proof ~name ~udecl ~poly sigma goals =
+ let proof = Proof.start ~name ~poly sigma goals in
+ let initial_euctx = Evd.evar_universe_context Proof.((data proof).sigma) in
+ { proof
+ ; endline_tactic = None
+ ; section_vars = None
+ ; udecl
+ ; initial_euctx
+ }
+
+let start_dependent_proof ~name ~udecl ~poly goals =
+ let proof = Proof.dependent_start ~name ~poly goals in
+ let initial_euctx = Evd.evar_universe_context Proof.((data proof).sigma) in
+ { proof
+ ; endline_tactic = None
+ ; section_vars = None
+ ; udecl
+ ; initial_euctx
+ }
+
+let get_used_variables pf = pf.section_vars
+let get_universe_decl pf = pf.udecl
+
+let set_used_variables ps l =
+ let open Context.Named.Declaration in
+ let env = Global.env () in
+ let ids = List.fold_right Id.Set.add l Id.Set.empty in
+ let ctx = Environ.keep_hyps env ids in
+ let ctx_set =
+ List.fold_right Id.Set.add (List.map NamedDecl.get_id ctx) Id.Set.empty in
+ let vars_of = Environ.global_vars_set in
+ let aux env entry (ctx, all_safe as orig) =
+ match entry with
+ | LocalAssum ({Context.binder_name=x},_) ->
+ if Id.Set.mem x all_safe then orig
+ else (ctx, all_safe)
+ | LocalDef ({Context.binder_name=x},bo, ty) as decl ->
+ if Id.Set.mem x all_safe then orig else
+ let vars = Id.Set.union (vars_of env bo) (vars_of env ty) in
+ if Id.Set.subset vars all_safe
+ then (decl :: ctx, Id.Set.add x all_safe)
+ else (ctx, all_safe) in
+ let ctx, _ =
+ Environ.fold_named_context aux env ~init:(ctx,ctx_set) in
+ if not (Option.is_empty ps.section_vars) then
+ CErrors.user_err Pp.(str "Used section variables can be declared only once");
+ ctx, { ps with section_vars = Some (Context.Named.to_vars ctx) }
+
+let get_open_goals ps =
+ let Proof.{ goals; stack; shelf } = Proof.data ps.proof in
+ List.length goals +
+ List.fold_left (+) 0
+ (List.map (fun (l1,l2) -> List.length l1 + List.length l2) stack) +
+ List.length shelf
+
+type import_status = ImportDefaultBehavior | ImportNeedQualified
+
+(** Declaration of constants and parameters *)
+
+type 'a proof_entry = {
+ proof_entry_body : 'a Entries.const_entry_body;
+ (* List of section variables *)
+ proof_entry_secctx : Id.Set.t option;
+ (* State id on which the completion of type checking is reported *)
+ proof_entry_feedback : Stateid.t option;
+ proof_entry_type : Constr.types option;
+ proof_entry_universes : Entries.universes_entry;
+ proof_entry_opaque : bool;
+ proof_entry_inline_code : bool;
+}
+
+let default_univ_entry = Entries.Monomorphic_entry Univ.ContextSet.empty
+
+let definition_entry ?fix_exn ?(opaque=false) ?(inline=false) ?feedback_id ?section_vars ?types
+ ?(univs=default_univ_entry) ?(eff=Evd.empty_side_effects) ?(univsbody=Univ.ContextSet.empty) body =
+ { proof_entry_body = Future.from_val ?fix_exn ((body,univsbody), eff);
+ proof_entry_secctx = section_vars;
+ proof_entry_type = types;
+ proof_entry_universes = univs;
+ proof_entry_opaque = opaque;
+ proof_entry_feedback = feedback_id;
+ proof_entry_inline_code = inline}
+
+type proof_object =
+ { name : Names.Id.t
+ (* [name] only used in the STM *)
+ ; entries : Evd.side_effects proof_entry list
+ ; uctx: UState.t
+ }
+
+let private_poly_univs =
+ Goptions.declare_bool_option_and_ref
+ ~depr:false
+ ~key:["Private";"Polymorphic";"Universes"]
+ ~value:true
+
+(* XXX: This is still separate from close_proof below due to drop_pt in the STM *)
+(* XXX: Unsafe_typ:true is needed by vio files, see bf0499bc507d5a39c3d5e3bf1f69191339270729 *)
+let prepare_proof ~unsafe_typ { proof } =
+ let Proof.{name=pid;entry;poly} = Proof.data proof in
+ let initial_goals = Proofview.initial_goals entry in
+ let evd = Proof.return ~pid proof in
+ let eff = Evd.eval_side_effects evd in
+ let evd = Evd.minimize_universes evd in
+ let to_constr_body c =
+ match EConstr.to_constr_opt evd c with
+ | Some p -> p
+ | None -> CErrors.user_err Pp.(str "Some unresolved existential variables remain")
+ in
+ let to_constr_typ t =
+ if unsafe_typ then EConstr.Unsafe.to_constr t else to_constr_body t
+ in
+ (* ppedrot: FIXME, this is surely wrong. There is no reason to duplicate
+ side-effects... This may explain why one need to uniquize side-effects
+ thereafter... *)
+ (* EJGA: actually side-effects de-duplication and this codepath is
+ unrelated. Duplicated side-effects arise from incorrect scheme
+ generation code, the main bulk of it was mostly fixed by #9836
+ but duplication can still happen because of rewriting schemes I
+ think; however the code below is mostly untested, the only
+ code-paths that generate several proof entries are derive and
+ equations and so far there is no code in the CI that will
+ actually call those and do a side-effect, TTBOMK *)
+ (* EJGA: likely the right solution is to attach side effects to the first constant only? *)
+ let proofs = List.map (fun (body, typ) -> (to_constr_body body, eff), to_constr_typ typ) initial_goals in
+ proofs, Evd.evar_universe_context evd
+
+let close_proof ~opaque ~keep_body_ucst_separate ps =
+
+ let { section_vars; proof; udecl; initial_euctx } = ps in
+ let { Proof.name; poly } = Proof.data proof in
+ let unsafe_typ = keep_body_ucst_separate && not poly in
+ let elist, uctx = prepare_proof ~unsafe_typ ps in
+ let opaque = match opaque with Opaque -> true | Transparent -> false in
+
+ let make_entry ((body, eff), typ) =
+
+ let allow_deferred =
+ not poly &&
+ (keep_body_ucst_separate
+ || not (Safe_typing.is_empty_private_constants eff.Evd.seff_private))
+ in
+ let used_univs_body = Vars.universes_of_constr body in
+ let used_univs_typ = Vars.universes_of_constr typ in
+ let used_univs = Univ.LSet.union used_univs_body used_univs_typ in
+ let utyp, ubody =
+ if allow_deferred then
+ let utyp = UState.univ_entry ~poly initial_euctx in
+ let uctx = UState.constrain_variables (fst (UState.context_set initial_euctx)) uctx in
+ (* For vi2vo compilation proofs are computed now but we need to
+ complement the univ constraints of the typ with the ones of
+ the body. So we keep the two sets distinct. *)
+ let uctx_body = UState.restrict uctx used_univs in
+ let ubody = UState.check_mono_univ_decl uctx_body udecl in
+ utyp, ubody
+ else if poly && opaque && private_poly_univs () then
+ let universes = UState.restrict uctx used_univs in
+ let typus = UState.restrict universes used_univs_typ in
+ let utyp = UState.check_univ_decl ~poly typus udecl in
+ let ubody = Univ.ContextSet.diff
+ (UState.context_set universes)
+ (UState.context_set typus)
+ in
+ utyp, ubody
+ else
+ (* Since the proof is computed now, we can simply have 1 set of
+ constraints in which we merge the ones for the body and the ones
+ for the typ. We recheck the declaration after restricting with
+ the actually used universes.
+ TODO: check if restrict is really necessary now. *)
+ let ctx = UState.restrict uctx used_univs in
+ let utyp = UState.check_univ_decl ~poly ctx udecl in
+ utyp, Univ.ContextSet.empty
+ in
+ definition_entry ~opaque ?section_vars ~univs:utyp ~univsbody:ubody ~types:typ ~eff body
+ in
+ let entries = CList.map make_entry elist in
+ { name; entries; uctx }
+
+type 'a constant_entry =
+ | DefinitionEntry of 'a proof_entry
+ | ParameterEntry of Entries.parameter_entry
+ | PrimitiveEntry of Entries.primitive_entry
+
+type constant_obj = {
+ cst_kind : Decls.logical_kind;
+ cst_locl : import_status;
+}
+
+let load_constant i ((sp,kn), obj) =
+ if Nametab.exists_cci sp then
+ raise (DeclareUniv.AlreadyDeclared (None, Libnames.basename sp));
+ let con = Global.constant_of_delta_kn kn in
+ Nametab.push (Nametab.Until i) sp (GlobRef.ConstRef con);
+ Dumpglob.add_constant_kind con obj.cst_kind
+
+(* Opening means making the name without its module qualification available *)
+let open_constant f i ((sp,kn), obj) =
+ (* Never open a local definition *)
+ match obj.cst_locl with
+ | ImportNeedQualified -> ()
+ | ImportDefaultBehavior ->
+ let con = Global.constant_of_delta_kn kn in
+ if Libobject.in_filter_ref (GlobRef.ConstRef con) f then
+ Nametab.push (Nametab.Exactly i) sp (GlobRef.ConstRef con)
+
+let exists_name id =
+ Decls.variable_exists id || Global.exists_objlabel (Label.of_id id)
+
+let check_exists id =
+ if exists_name id then
+ raise (DeclareUniv.AlreadyDeclared (None, id))
+
+let cache_constant ((sp,kn), obj) =
+ (* Invariant: the constant must exist in the logical environment *)
+ let kn' =
+ if Global.exists_objlabel (Label.of_id (Libnames.basename sp))
+ then Constant.make1 kn
+ else CErrors.anomaly Pp.(str"Missing constant " ++ Id.print(Libnames.basename sp) ++ str".")
+ in
+ assert (Constant.equal kn' (Constant.make1 kn));
+ Nametab.push (Nametab.Until 1) sp (GlobRef.ConstRef (Constant.make1 kn));
+ Dumpglob.add_constant_kind (Constant.make1 kn) obj.cst_kind
+
+let discharge_constant ((sp, kn), obj) =
+ Some obj
+
+let classify_constant cst = Libobject.Substitute cst
+
+let (objConstant : constant_obj Libobject.Dyn.tag) =
+ let open Libobject in
+ declare_object_full { (default_object "CONSTANT") with
+ cache_function = cache_constant;
+ load_function = load_constant;
+ open_function = open_constant;
+ classify_function = classify_constant;
+ subst_function = ident_subst_function;
+ discharge_function = discharge_constant }
+
+let inConstant v = Libobject.Dyn.Easy.inj v objConstant
+
+let update_tables c =
+ Impargs.declare_constant_implicits c;
+ Notation.declare_ref_arguments_scope Evd.empty (GlobRef.ConstRef c)
+
+let register_constant kn kind local =
+ let o = inConstant {
+ cst_kind = kind;
+ cst_locl = local;
+ } in
+ let id = Label.to_id (Constant.label kn) in
+ let _ = Lib.add_leaf id o in
+ update_tables kn
+
+let register_side_effect (c, role) =
+ let () = register_constant c Decls.(IsProof Theorem) ImportDefaultBehavior in
+ match role with
+ | None -> ()
+ | Some (Evd.Schema (ind, kind)) -> DeclareScheme.declare_scheme kind [|ind,c|]
+
+let get_roles export eff =
+ let map c =
+ let role = try Some (Cmap.find c eff.Evd.seff_roles) with Not_found -> None in
+ (c, role)
+ in
+ List.map map export
+
+let export_side_effects eff =
+ let export = Global.export_private_constants eff.Evd.seff_private in
+ let export = get_roles export eff in
+ List.iter register_side_effect export
+
+let record_aux env s_ty s_bo =
+ let open Environ in
+ let in_ty = keep_hyps env s_ty in
+ let v =
+ String.concat " "
+ (CList.map_filter (fun decl ->
+ let id = NamedDecl.get_id decl in
+ if List.exists (NamedDecl.get_id %> Id.equal id) in_ty then None
+ else Some (Id.to_string id))
+ (keep_hyps env s_bo)) in
+ Aux_file.record_in_aux "context_used" v
+
+let pure_definition_entry ?fix_exn ?(opaque=false) ?(inline=false) ?types
+ ?(univs=default_univ_entry) body =
+ { proof_entry_body = Future.from_val ?fix_exn ((body,Univ.ContextSet.empty), ());
+ proof_entry_secctx = None;
+ proof_entry_type = types;
+ proof_entry_universes = univs;
+ proof_entry_opaque = opaque;
+ proof_entry_feedback = None;
+ proof_entry_inline_code = inline}
+
+let delayed_definition_entry ~opaque ?feedback_id ~section_vars ~univs ?types body =
+ { proof_entry_body = body
+ ; proof_entry_secctx = section_vars
+ ; proof_entry_type = types
+ ; proof_entry_universes = univs
+ ; proof_entry_opaque = opaque
+ ; proof_entry_feedback = feedback_id
+ ; proof_entry_inline_code = false
+ }
+
+let cast_proof_entry e =
+ let (body, ctx), () = Future.force e.proof_entry_body in
+ let univs =
+ if Univ.ContextSet.is_empty ctx then e.proof_entry_universes
+ else match e.proof_entry_universes with
+ | Entries.Monomorphic_entry ctx' ->
+ (* This can actually happen, try compiling EqdepFacts for instance *)
+ Entries.Monomorphic_entry (Univ.ContextSet.union ctx' ctx)
+ | Entries.Polymorphic_entry _ ->
+ CErrors.anomaly Pp.(str "Local universes in non-opaque polymorphic definition.");
+ in
+ { Entries.const_entry_body = body;
+ const_entry_secctx = e.proof_entry_secctx;
+ const_entry_feedback = e.proof_entry_feedback;
+ const_entry_type = e.proof_entry_type;
+ const_entry_universes = univs;
+ const_entry_inline_code = e.proof_entry_inline_code;
+ }
+
+type ('a, 'b) effect_entry =
+| EffectEntry : (private_constants, private_constants Entries.const_entry_body) effect_entry
+| PureEntry : (unit, Constr.constr) effect_entry
+
+let cast_opaque_proof_entry (type a b) (entry : (a, b) effect_entry) (e : a proof_entry) : b Entries.opaque_entry =
+ let typ = match e.proof_entry_type with
+ | None -> assert false
+ | Some typ -> typ
+ in
+ let secctx = match e.proof_entry_secctx with
+ | None ->
+ let open Environ in
+ let env = Global.env () in
+ let hyp_typ, hyp_def =
+ if List.is_empty (Environ.named_context env) then
+ Id.Set.empty, Id.Set.empty
+ else
+ let ids_typ = global_vars_set env typ in
+ let pf, env = match entry with
+ | PureEntry ->
+ let (pf, _), () = Future.force e.proof_entry_body in
+ pf, env
+ | EffectEntry ->
+ let (pf, _), eff = Future.force e.proof_entry_body in
+ let env = Safe_typing.push_private_constants env eff in
+ pf, env
+ in
+ let vars = global_vars_set env pf in
+ ids_typ, vars
+ in
+ let () = if Aux_file.recording () then record_aux env hyp_typ hyp_def in
+ Environ.really_needed env (Id.Set.union hyp_typ hyp_def)
+ | Some hyps -> hyps
+ in
+ let (body, univs : b * _) = match entry with
+ | PureEntry ->
+ let (body, uctx), () = Future.force e.proof_entry_body in
+ let univs = match e.proof_entry_universes with
+ | Entries.Monomorphic_entry uctx' ->
+ Entries.Monomorphic_entry (Univ.ContextSet.union uctx uctx')
+ | Entries.Polymorphic_entry _ ->
+ assert (Univ.ContextSet.is_empty uctx);
+ e.proof_entry_universes
+ in
+ body, univs
+ | EffectEntry -> e.proof_entry_body, e.proof_entry_universes
+ in
+ { Entries.opaque_entry_body = body;
+ opaque_entry_secctx = secctx;
+ opaque_entry_feedback = e.proof_entry_feedback;
+ opaque_entry_type = typ;
+ opaque_entry_universes = univs;
+ }
+
+let feedback_axiom () = Feedback.(feedback AddedAxiom)
+
+let is_unsafe_typing_flags () =
+ let open Declarations in
+ let flags = Environ.typing_flags (Global.env()) in
+ not (flags.check_universes && flags.check_guarded && flags.check_positive)
+
+let define_constant ~name cd =
+ (* Logically define the constant and its subproofs, no libobject tampering *)
+ let decl, unsafe = match cd with
+ | DefinitionEntry de ->
+ (* We deal with side effects *)
+ if not de.proof_entry_opaque then
+ let body, eff = Future.force de.proof_entry_body in
+ (* This globally defines the side-effects in the environment
+ and registers their libobjects. *)
+ let () = export_side_effects eff in
+ let de = { de with proof_entry_body = Future.from_val (body, ()) } in
+ let cd = Entries.DefinitionEntry (cast_proof_entry de) in
+ ConstantEntry cd, false
+ else
+ let map (body, eff) = body, eff.Evd.seff_private in
+ let body = Future.chain de.proof_entry_body map in
+ let de = { de with proof_entry_body = body } in
+ let de = cast_opaque_proof_entry EffectEntry de in
+ OpaqueEntry de, false
+ | ParameterEntry e ->
+ ConstantEntry (Entries.ParameterEntry e), not (Lib.is_modtype_strict())
+ | PrimitiveEntry e ->
+ ConstantEntry (Entries.PrimitiveEntry e), false
+ in
+ let kn = Global.add_constant name decl in
+ if unsafe || is_unsafe_typing_flags() then feedback_axiom();
+ kn
+
+let declare_constant ?(local = ImportDefaultBehavior) ~name ~kind cd =
+ let () = check_exists name in
+ let kn = define_constant ~name cd in
+ (* Register the libobjects attached to the constants *)
+ let () = register_constant kn kind local in
+ kn
+
+let get_cd_fix_exn = function
+ | DefinitionEntry de ->
+ Future.fix_exn_of de.proof_entry_body
+ | _ -> fun x -> x
+
+let declare_constant ?local ~name ~kind cd =
+ try declare_constant ?local ~name ~kind cd
+ with exn ->
+ let exn = Exninfo.capture exn in
+ Exninfo.iraise (get_cd_fix_exn cd exn)
+
+let declare_private_constant ?role ?(local = ImportDefaultBehavior) ~name ~kind de =
+ let kn, eff =
+ let de =
+ if not de.proof_entry_opaque then
+ DefinitionEff (cast_proof_entry de)
+ else
+ let de = cast_opaque_proof_entry PureEntry de in
+ OpaqueEff de
+ in
+ Global.add_private_constant name de
+ in
+ let () = register_constant kn kind local in
+ let seff_roles = match role with
+ | None -> Cmap.empty
+ | Some r -> Cmap.singleton kn r
+ in
+ let eff = { Evd.seff_private = eff; Evd.seff_roles; } in
+ kn, eff
+
+let inline_private_constants ~uctx env ce =
+ let body, eff = Future.force ce.proof_entry_body in
+ let cb, ctx = Safe_typing.inline_private_constants env (body, eff.Evd.seff_private) in
+ let uctx = UState.merge ~sideff:true Evd.univ_rigid uctx ctx in
+ cb, uctx
+
+(** Declaration of section variables and local definitions *)
+type variable_declaration =
+ | SectionLocalDef of Evd.side_effects proof_entry
+ | SectionLocalAssum of { typ:Constr.types; impl:Glob_term.binding_kind; }
+
+(* This object is only for things which iterate over objects to find
+ variables (only Prettyp.print_context AFAICT) *)
+let objVariable : unit Libobject.Dyn.tag =
+ let open Libobject in
+ declare_object_full { (default_object "VARIABLE") with
+ classify_function = (fun () -> Dispose)}
+
+let inVariable v = Libobject.Dyn.Easy.inj v objVariable
+
+let declare_variable ~name ~kind d =
+ (* Variables are distinguished by only short names *)
+ if Decls.variable_exists name then
+ raise (DeclareUniv.AlreadyDeclared (None, name));
+
+ let impl,opaque = match d with (* Fails if not well-typed *)
+ | SectionLocalAssum {typ;impl} ->
+ let () = Global.push_named_assum (name,typ) in
+ impl, true
+ | SectionLocalDef (de) ->
+ (* The body should already have been forced upstream because it is a
+ section-local definition, but it's not enforced by typing *)
+ let ((body, body_ui), eff) = Future.force de.proof_entry_body in
+ let () = export_side_effects eff in
+ let poly, entry_ui = match de.proof_entry_universes with
+ | Entries.Monomorphic_entry uctx -> false, uctx
+ | Entries.Polymorphic_entry (_, uctx) -> true, Univ.ContextSet.of_context uctx
+ in
+ let univs = Univ.ContextSet.union body_ui entry_ui in
+ (* We must declare the universe constraints before type-checking the
+ term. *)
+ let () = DeclareUctx.declare_universe_context ~poly univs in
+ let se = {
+ Entries.secdef_body = body;
+ secdef_secctx = de.proof_entry_secctx;
+ secdef_feedback = de.proof_entry_feedback;
+ secdef_type = de.proof_entry_type;
+ } in
+ let () = Global.push_named_def (name, se) in
+ Glob_term.Explicit, de.proof_entry_opaque
+ in
+ Nametab.push (Nametab.Until 1) (Libnames.make_path DirPath.empty name) (GlobRef.VarRef name);
+ Decls.(add_variable_data name {opaque;kind});
+ ignore(Lib.add_leaf name (inVariable ()) : Libobject.object_name);
+ Impargs.declare_var_implicits ~impl name;
+ Notation.declare_ref_arguments_scope Evd.empty (GlobRef.VarRef name)
+
+(* Declaration messages *)
+
+let pr_rank i = pr_nth (i+1)
+
+let fixpoint_message indexes l =
+ Flags.if_verbose Feedback.msg_info (match l with
+ | [] -> CErrors.anomaly (Pp.str "no recursive definition.")
+ | [id] -> Id.print id ++ str " is recursively defined" ++
+ (match indexes with
+ | Some [|i|] -> str " (guarded on "++pr_rank i++str " argument)"
+ | _ -> mt ())
+ | l -> hov 0 (prlist_with_sep pr_comma Id.print l ++
+ spc () ++ str "are recursively defined" ++
+ match indexes with
+ | Some a -> spc () ++ str "(guarded respectively on " ++
+ prvect_with_sep pr_comma pr_rank a ++
+ str " arguments)"
+ | None -> mt ()))
+
+let cofixpoint_message l =
+ Flags.if_verbose Feedback.msg_info (match l with
+ | [] -> CErrors.anomaly (Pp.str "No corecursive definition.")
+ | [id] -> Id.print id ++ str " is corecursively defined"
+ | l -> hov 0 (prlist_with_sep pr_comma Id.print l ++
+ spc () ++ str "are corecursively defined"))
+
+let recursive_message isfix i l =
+ (if isfix then fixpoint_message i else cofixpoint_message) l
+
+let definition_message id =
+ Flags.if_verbose Feedback.msg_info (Id.print id ++ str " is defined")
+
+let assumption_message id =
+ (* Changing "assumed" to "declared", "assuming" referring more to
+ the type of the object than to the name of the object (see
+ discussion on coqdev: "Chapter 4 of the Reference Manual", 8/10/2015) *)
+ Flags.if_verbose Feedback.msg_info (Id.print id ++ str " is declared")
+
+module Internal = struct
+
+ let map_entry_body ~f entry =
+ { entry with proof_entry_body = Future.chain entry.proof_entry_body f }
+
+ let map_entry_type ~f entry =
+ { entry with proof_entry_type = f entry.proof_entry_type }
+
+ let set_opacity ~opaque entry =
+ { entry with proof_entry_opaque = opaque }
+
+ let rec decompose len c t accu =
+ let open Constr in
+ let open Context.Rel.Declaration in
+ if len = 0 then (c, t, accu)
+ else match kind c, kind t with
+ | Lambda (na, u, c), Prod (_, _, t) ->
+ decompose (pred len) c t (LocalAssum (na, u) :: accu)
+ | LetIn (na, b, u, c), LetIn (_, _, _, t) ->
+ decompose (pred len) c t (LocalDef (na, b, u) :: accu)
+ | _ -> assert false
+
+ let rec shrink ctx sign c t accu =
+ let open Constr in
+ let open Vars in
+ match ctx, sign with
+ | [], [] -> (c, t, accu)
+ | p :: ctx, decl :: sign ->
+ if noccurn 1 c && noccurn 1 t then
+ let c = subst1 mkProp c in
+ let t = subst1 mkProp t in
+ shrink ctx sign c t accu
+ else
+ let c = Term.mkLambda_or_LetIn p c in
+ let t = Term.mkProd_or_LetIn p t in
+ let accu = if Context.Rel.Declaration.is_local_assum p
+ then mkVar (NamedDecl.get_id decl) :: accu
+ else accu
+ in
+ shrink ctx sign c t accu
+ | _ -> assert false
+
+ let shrink_entry sign const =
+ let typ = match const.proof_entry_type with
+ | None -> assert false
+ | Some t -> t
+ in
+ (* The body has been forced by the call to [build_constant_by_tactic] *)
+ let () = assert (Future.is_over const.proof_entry_body) in
+ let ((body, uctx), eff) = Future.force const.proof_entry_body in
+ let (body, typ, ctx) = decompose (List.length sign) body typ [] in
+ let (body, typ, args) = shrink ctx sign body typ [] in
+ { const with
+ proof_entry_body = Future.from_val ((body, uctx), eff)
+ ; proof_entry_type = Some typ
+ }, args
+
+ type nonrec constant_obj = constant_obj
+
+ let objVariable = objVariable
+ let objConstant = objConstant
+
+end
+(*** Proof Global Environment ***)
+
+type closed_proof_output = (Constr.t * Evd.side_effects) list * UState.t
+
+let close_proof_delayed ~feedback_id ps (fpl : closed_proof_output Future.computation) =
+ let { section_vars; proof; udecl; initial_euctx } = ps in
+ let { Proof.name; poly; entry; sigma } = Proof.data proof in
+
+ (* We don't allow poly = true in this path *)
+ if poly then
+ CErrors.anomaly (Pp.str "Cannot delay universe-polymorphic constants.");
+
+ let fpl, uctx = Future.split2 fpl in
+ (* Because of dependent subgoals at the beginning of proofs, we could
+ have existential variables in the initial types of goals, we need to
+ normalise them for the kernel. *)
+ let subst_evar k = Evd.existential_opt_value0 sigma k in
+ let nf = UnivSubst.nf_evars_and_universes_opt_subst subst_evar (UState.subst initial_euctx) in
+
+ (* We only support opaque proofs, this will be enforced by using
+ different entries soon *)
+ let opaque = true in
+ let make_entry p (_, types) =
+ (* Already checked the univ_decl for the type universes when starting the proof. *)
+ let univs = UState.univ_entry ~poly:false initial_euctx in
+ let types = nf (EConstr.Unsafe.to_constr types) in
+
+ Future.chain p (fun (pt,eff) ->
+ (* Deferred proof, we already checked the universe declaration with
+ the initial universes, ensure that the final universes respect
+ the declaration as well. If the declaration is non-extensible,
+ this will prevent the body from adding universes and constraints. *)
+ let uctx = Future.force uctx in
+ let uctx = UState.constrain_variables (fst (UState.context_set initial_euctx)) uctx in
+ let used_univs = Univ.LSet.union
+ (Vars.universes_of_constr types)
+ (Vars.universes_of_constr pt)
+ in
+ let univs = UState.restrict uctx used_univs in
+ let univs = UState.check_mono_univ_decl univs udecl in
+ (pt,univs),eff)
+ |> delayed_definition_entry ~opaque ~feedback_id ~section_vars ~univs ~types
+ in
+ let entries = Future.map2 make_entry fpl (Proofview.initial_goals entry) in
+ { name; entries; uctx = initial_euctx }
+
+let close_future_proof = close_proof_delayed
+
+let return_partial_proof { proof } =
+ let proofs = Proof.partial_proof proof in
+ let Proof.{sigma=evd} = Proof.data proof in
+ let eff = Evd.eval_side_effects evd in
+ (* ppedrot: FIXME, this is surely wrong. There is no reason to duplicate
+ side-effects... This may explain why one need to uniquize side-effects
+ thereafter... *)
+ let proofs = List.map (fun c -> EConstr.Unsafe.to_constr c, eff) proofs in
+ proofs, Evd.evar_universe_context evd
+
+let return_proof ps =
+ let p, uctx = prepare_proof ~unsafe_typ:false ps in
+ List.map fst p, uctx
+
+let update_global_env =
+ map_proof (fun p ->
+ let { Proof.sigma } = Proof.data p in
+ let tac = Proofview.Unsafe.tclEVARS (Evd.update_sigma_env sigma (Global.env ())) in
+ let p, (status,info), _ = Proof.run_tactic (Global.env ()) tac p in
+ p)
+
+let next = let n = ref 0 in fun () -> incr n; !n
+
+let by tac = map_fold_proof (Proof.solve (Goal_select.SelectNth 1) None tac)
+
+let build_constant_by_tactic ~name ?(opaque=Transparent) ~uctx ~sign ~poly typ tac =
+ let evd = Evd.from_ctx uctx in
+ let goals = [ (Global.env_of_context sign , typ) ] in
+ let pf = start_proof ~name ~poly ~udecl:UState.default_univ_decl evd goals in
+ let pf, status = by tac pf in
+ let { entries; uctx } = close_proof ~opaque ~keep_body_ucst_separate:false pf in
+ match entries with
+ | [entry] ->
+ entry, status, uctx
+ | _ ->
+ CErrors.anomaly Pp.(str "[build_constant_by_tactic] close_proof returned more than one proof term")
+
+let build_by_tactic ?(side_eff=true) env ~uctx ~poly ~typ tac =
+ let name = Id.of_string ("temporary_proof"^string_of_int (next())) in
+ let sign = Environ.(val_of_named_context (named_context env)) in
+ let ce, status, uctx = build_constant_by_tactic ~name ~uctx ~sign ~poly typ tac in
+ let cb, uctx =
+ if side_eff then inline_private_constants ~uctx env ce
+ else
+ (* GG: side effects won't get reset: no need to treat their universes specially *)
+ let (cb, ctx), _eff = Future.force ce.proof_entry_body in
+ cb, UState.merge ~sideff:false Evd.univ_rigid uctx ctx
+ in
+ cb, ce.proof_entry_type, ce.proof_entry_universes, status, uctx
+
+let declare_abstract ~name ~poly ~kind ~sign ~secsign ~opaque ~solve_tac sigma concl =
+ (* EJGA: flush_and_check_evars is only used in abstract, could we
+ use a different API? *)
+ let concl =
+ try Evarutil.flush_and_check_evars sigma concl
+ with Evarutil.Uninstantiated_evar _ ->
+ CErrors.user_err Pp.(str "\"abstract\" cannot handle existentials.")
+ in
+ let sigma, concl =
+ (* FIXME: should be done only if the tactic succeeds *)
+ let sigma = Evd.minimize_universes sigma in
+ sigma, Evarutil.nf_evars_universes sigma concl
+ in
+ let concl = EConstr.of_constr concl in
+ let uctx = Evd.evar_universe_context sigma in
+ let (const, safe, uctx) =
+ try build_constant_by_tactic ~name ~opaque:Transparent ~poly ~uctx ~sign:secsign concl solve_tac
+ with Logic_monad.TacticFailure e as src ->
+ (* if the tactic [tac] fails, it reports a [TacticFailure e],
+ which is an error irrelevant to the proof system (in fact it
+ means that [e] comes from [tac] failing to yield enough
+ success). Hence it reraises [e]. *)
+ let (_, info) = Exninfo.capture src in
+ Exninfo.iraise (e, info)
+ in
+ let sigma = Evd.set_universe_context sigma uctx in
+ let body, effs = Future.force const.proof_entry_body in
+ (* We drop the side-effects from the entry, they already exist in the ambient environment *)
+ let const = Internal.map_entry_body const ~f:(fun _ -> body, ()) in
+ (* EJGA: Hack related to the above call to
+ `build_constant_by_tactic` with `~opaque:Transparent`. Even if
+ the abstracted term is destined to be opaque, if we trigger the
+ `if poly && opaque && private_poly_univs ()` in `Proof_global`
+ kernel will boom. This deserves more investigation. *)
+ let const = Internal.set_opacity ~opaque const in
+ let const, args = Internal.shrink_entry sign const in
+ let cst () =
+ (* do not compute the implicit arguments, it may be costly *)
+ let () = Impargs.make_implicit_args false in
+ (* ppedrot: seems legit to have abstracted subproofs as local*)
+ declare_private_constant ~local:ImportNeedQualified ~name ~kind const
+ in
+ let cst, eff = Impargs.with_implicit_protection cst () in
+ let inst = match const.proof_entry_universes with
+ | Entries.Monomorphic_entry _ -> EConstr.EInstance.empty
+ | Entries.Polymorphic_entry (_, ctx) ->
+ (* We mimic what the kernel does, that is ensuring that no additional
+ constraints appear in the body of polymorphic constants. Ideally this
+ should be enforced statically. *)
+ let (_, body_uctx), _ = Future.force const.proof_entry_body in
+ let () = assert (Univ.ContextSet.is_empty body_uctx) in
+ EConstr.EInstance.make (Univ.UContext.instance ctx)
+ in
+ let args = List.map EConstr.of_constr args in
+ let lem = EConstr.mkConstU (cst, inst) in
+ let effs = Evd.concat_side_effects eff effs in
+ effs, sigma, lem, args, safe
+
+let get_goal_context pf i =
+ let p = get_proof pf in
+ Proof.get_goal_context_gen p i
+
+let get_current_goal_context pf =
+ let p = get_proof pf in
+ try Proof.get_goal_context_gen p 1
+ with
+ | Proof.NoSuchGoal _ ->
+ (* spiwack: returning empty evar_map, since if there is no goal,
+ under focus, there is no accessible evar either. EJGA: this
+ seems strange, as we have pf *)
+ let env = Global.env () in
+ Evd.from_env env, env
+
+let get_current_context pf =
+ let p = get_proof pf in
+ Proof.get_proof_context p
+
+module Proof = struct
+ type nonrec t = t
+ let get_proof = get_proof
+ let get_proof_name = get_proof_name
+ let get_used_variables = get_used_variables
+ let get_universe_decl = get_universe_decl
+ let get_initial_euctx = get_initial_euctx
+ let map_proof = map_proof
+ let map_fold_proof = map_fold_proof
+ let map_fold_proof_endline = map_fold_proof_endline
+ let set_endline_tactic = set_endline_tactic
+ let set_used_variables = set_used_variables
+ let compact = compact_the_proof
+ let update_global_env = update_global_env
+ let get_open_goals = get_open_goals
+end
+
+let declare_definition_scheme ~internal ~univs ~role ~name c =
+ let kind = Decls.(IsDefinition Scheme) in
+ let entry = pure_definition_entry ~univs c in
+ let kn, eff = declare_private_constant ~role ~kind ~name entry in
+ let () = if internal then () else definition_message name in
+ kn, eff
+
+let _ = Ind_tables.declare_definition_scheme := declare_definition_scheme
+let _ = Abstract.declare_abstract := declare_abstract
+
+let declare_universe_context = DeclareUctx.declare_universe_context
+
+type locality = Discharge | Global of import_status
+
+(* Hooks naturally belong here as they apply to both definitions and lemmas *)
+module Hook = struct
+ module S = struct
+ type t =
+ { uctx : UState.t
+ (** [ustate]: universe constraints obtained when the term was closed *)
+ ; obls : (Names.Id.t * Constr.t) list
+ (** [(n1,t1),...(nm,tm)]: association list between obligation
+ name and the corresponding defined term (might be a constant,
+ but also an arbitrary term in the Expand case of obligations) *)
+ ; scope : locality
+ (** [locality]: Locality of the original declaration *)
+ ; dref : Names.GlobRef.t
+ (** [ref]: identifier of the original declaration *)
+ }
+ end
+
+ type t = (S.t -> unit) CEphemeron.key
+
+ let make hook = CEphemeron.create hook
+
+ let call ?hook x = Option.iter (fun hook -> CEphemeron.get hook x) hook
+
+end
+
+(* Locality stuff *)
+let declare_entry ~name ~scope ~kind ?hook ?(obls=[]) ~impargs ~uctx entry =
+ let should_suggest = entry.proof_entry_opaque &&
+ Option.is_empty entry.proof_entry_secctx in
+ let ubind = UState.universe_binders uctx in
+ let dref = match scope with
+ | Discharge ->
+ let () = declare_variable ~name ~kind (SectionLocalDef entry) in
+ if should_suggest then Proof_using.suggest_variable (Global.env ()) name;
+ Names.GlobRef.VarRef name
+ | Global local ->
+ let kn = declare_constant ~name ~local ~kind (DefinitionEntry entry) in
+ let gr = Names.GlobRef.ConstRef kn in
+ if should_suggest then Proof_using.suggest_constant (Global.env ()) kn;
+ let () = DeclareUniv.declare_univ_binders gr ubind in
+ gr
+ in
+ let () = Impargs.maybe_declare_manual_implicits false dref impargs in
+ let () = definition_message name in
+ Option.iter (fun hook -> Hook.call ~hook { Hook.S.uctx; obls; scope; dref }) hook;
+ dref
+
+let mutual_make_bodies ~fixitems ~rec_declaration ~possible_indexes =
+ match possible_indexes with
+ | Some possible_indexes ->
+ let env = Global.env() in
+ let indexes = Pretyping.search_guard env possible_indexes rec_declaration in
+ let vars = Vars.universes_of_constr (Constr.mkFix ((indexes,0),rec_declaration)) in
+ let fixdecls = CList.map_i (fun i _ -> Constr.mkFix ((indexes,i),rec_declaration)) 0 fixitems in
+ vars, fixdecls, Some indexes
+ | None ->
+ let fixdecls = CList.map_i (fun i _ -> Constr.mkCoFix (i,rec_declaration)) 0 fixitems in
+ let vars = Vars.universes_of_constr (List.hd fixdecls) in
+ vars, fixdecls, None
+
+module Recthm = struct
+ type t =
+ { name : Names.Id.t
+ (** Name of theorem *)
+ ; typ : Constr.t
+ (** Type of theorem *)
+ ; args : Names.Name.t list
+ (** Names to pre-introduce *)
+ ; impargs : Impargs.manual_implicits
+ (** Explicitily declared implicit arguments *)
+ }
+end
+
+let declare_mutually_recursive ~opaque ~scope ~kind ~poly ~uctx ~udecl ~ntns ~rec_declaration ~possible_indexes ?(restrict_ucontext=true) fixitems =
+ let vars, fixdecls, indexes =
+ mutual_make_bodies ~fixitems ~rec_declaration ~possible_indexes in
+ let uctx, univs =
+ (* XXX: Obligations don't do this, this seems like a bug? *)
+ if restrict_ucontext
+ then
+ let uctx = UState.restrict uctx vars in
+ let univs = UState.check_univ_decl ~poly uctx udecl in
+ uctx, univs
+ else
+ let univs = UState.univ_entry ~poly uctx in
+ uctx, univs
+ in
+ let csts = CList.map2
+ (fun Recthm.{ name; typ; impargs } body ->
+ let entry = definition_entry ~opaque ~types:typ ~univs body in
+ declare_entry ~name ~scope ~kind ~impargs ~uctx entry)
+ fixitems fixdecls
+ in
+ let isfix = Option.has_some possible_indexes in
+ let fixnames = List.map (fun { Recthm.name } -> name) fixitems in
+ recursive_message isfix indexes fixnames;
+ List.iter (Metasyntax.add_notation_interpretation (Global.env())) ntns;
+ csts
+
+let warn_let_as_axiom =
+ CWarnings.create ~name:"let-as-axiom" ~category:"vernacular"
+ Pp.(fun id -> strbrk "Let definition" ++ spc () ++ Names.Id.print id ++
+ spc () ++ strbrk "declared as an axiom.")
+
+let declare_assumption ~name ~scope ~hook ~impargs ~uctx pe =
+ let local = match scope with
+ | Discharge -> warn_let_as_axiom name; ImportNeedQualified
+ | Global local -> local
+ in
+ let kind = Decls.(IsAssumption Conjectural) in
+ let decl = ParameterEntry pe in
+ let kn = declare_constant ~name ~local ~kind decl in
+ let dref = Names.GlobRef.ConstRef kn in
+ let () = Impargs.maybe_declare_manual_implicits false dref impargs in
+ let () = assumption_message name in
+ let () = DeclareUniv.declare_univ_binders dref (UState.universe_binders uctx) in
+ let () = Hook.(call ?hook { S.uctx; obls = []; scope; dref}) in
+ dref
+
+let declare_assumption ?fix_exn ~name ~scope ~hook ~impargs ~uctx pe =
+ try declare_assumption ~name ~scope ~hook ~impargs ~uctx pe
+ with exn ->
+ let exn = Exninfo.capture exn in
+ let exn = Option.cata (fun fix -> fix exn) exn fix_exn in
+ Exninfo.iraise exn
+
+(* Preparing proof entries *)
+
+let prepare_definition ?opaque ?inline ?fix_exn ~poly ~udecl ~types ~body sigma =
+ let env = Global.env () in
+ Pretyping.check_evars_are_solved ~program_mode:false env sigma;
+ let sigma, (body, types) = Evarutil.finalize ~abort_on_undefined_evars:true
+ sigma (fun nf -> nf body, Option.map nf types)
+ in
+ let univs = Evd.check_univ_decl ~poly sigma udecl in
+ let entry = definition_entry ?fix_exn ?opaque ?inline ?types ~univs body in
+ let uctx = Evd.evar_universe_context sigma in
+ entry, uctx
+
+let declare_definition ~name ~scope ~kind ~opaque ~impargs ~udecl ?hook
+ ?obls ~poly ?inline ~types ~body ?fix_exn sigma =
+ let entry, uctx = prepare_definition ?fix_exn ~opaque ~poly ~udecl ~types ~body ?inline sigma in
+ declare_entry ~name ~scope ~kind ~impargs ?obls ?hook ~uctx entry
+
+let prepare_obligation ?opaque ?inline ~name ~poly ~udecl ~types ~body sigma =
+ let sigma, (body, types) = Evarutil.finalize ~abort_on_undefined_evars:false
+ sigma (fun nf -> nf body, Option.map nf types)
+ in
+ let univs = Evd.check_univ_decl ~poly sigma udecl in
+ let ce = definition_entry ?opaque ?inline ?types ~univs body in
+ let env = Global.env () in
+ let (c,ctx), sideff = Future.force ce.proof_entry_body in
+ assert(Safe_typing.is_empty_private_constants sideff.Evd.seff_private);
+ assert(Univ.ContextSet.is_empty ctx);
+ RetrieveObl.check_evars env sigma;
+ let c = EConstr.of_constr c in
+ let typ = match ce.proof_entry_type with
+ | Some t -> EConstr.of_constr t
+ | None -> Retyping.get_type_of env sigma c
+ in
+ let obls, _, c, cty = RetrieveObl.retrieve_obligations env name sigma 0 c typ in
+ let uctx = Evd.evar_universe_context sigma in
+ c, cty, uctx, obls
+
+let prepare_parameter ~poly ~udecl ~types sigma =
+ let env = Global.env () in
+ Pretyping.check_evars_are_solved ~program_mode:false env sigma;
+ let sigma, typ = Evarutil.finalize ~abort_on_undefined_evars:true
+ sigma (fun nf -> nf types)
+ in
+ let univs = Evd.check_univ_decl ~poly sigma udecl in
+ sigma, (None(*proof using*), (typ, univs), None(*inline*))
+
+(* Compat: will remove *)
+exception AlreadyDeclared = DeclareUniv.AlreadyDeclared
diff --git a/vernac/declare.mli b/vernac/declare.mli
new file mode 100644
index 0000000000..340c035d1d
--- /dev/null
+++ b/vernac/declare.mli
@@ -0,0 +1,399 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * Copyright INRIA, CNRS and contributors *)
+(* <O___,, * (see version control and CREDITS file for authors & dates) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Names
+open Constr
+open Entries
+
+(** This module provides the official functions to declare new
+ variables, parameters, constants and inductive types in the global
+ environment. It also updates some accesory tables such as [Nametab]
+ (name resolution), [Impargs], and [Notations]. *)
+
+(** We provide two kind of fuctions:
+
+ - one go functions, that will register a constant in one go, suited
+ for non-interactive definitions where the term is given.
+
+ - two-phase [start/declare] functions which will create an
+ interactive proof, allow its modification, and saving when
+ complete.
+
+ Internally, these functions mainly differ in that usually, the first
+ case doesn't require setting up the tactic engine.
+
+ *)
+
+(** [Declare.Proof.t] Construction of constants using interactive proofs. *)
+module Proof : sig
+
+ type t
+
+ (** XXX: These are internal and will go away from publis API once
+ lemmas is merged here *)
+ val get_proof : t -> Proof.t
+ val get_proof_name : t -> Names.Id.t
+
+ (** XXX: These 3 are only used in lemmas *)
+ val get_used_variables : t -> Names.Id.Set.t option
+ val get_universe_decl : t -> UState.universe_decl
+ val get_initial_euctx : t -> UState.t
+
+ val map_proof : (Proof.t -> Proof.t) -> t -> t
+ val map_fold_proof : (Proof.t -> Proof.t * 'a) -> t -> t * 'a
+ val map_fold_proof_endline : (unit Proofview.tactic -> Proof.t -> Proof.t * 'a) -> t -> t * 'a
+
+ (** Sets the tactic to be used when a tactic line is closed with [...] *)
+ val set_endline_tactic : Genarg.glob_generic_argument -> t -> t
+
+ (** Sets the section variables assumed by the proof, returns its closure
+ * (w.r.t. type dependencies and let-ins covered by it) *)
+ val set_used_variables : t ->
+ Names.Id.t list -> Constr.named_context * t
+
+ val compact : t -> t
+
+ (** Update the proofs global environment after a side-effecting command
+ (e.g. a sublemma definition) has been run inside it. Assumes
+ there_are_pending_proofs. *)
+ val update_global_env : t -> t
+
+ val get_open_goals : t -> int
+
+end
+
+type opacity_flag = Vernacexpr.opacity_flag = Opaque | Transparent
+
+(** [start_proof ~name ~udecl ~poly sigma goals] starts a proof of
+ name [name] with goals [goals] (a list of pairs of environment and
+ conclusion); [poly] determines if the proof is universe
+ polymorphic. The proof is started in the evar map [sigma] (which
+ can typically contain universe constraints), and with universe
+ bindings [udecl]. *)
+val start_proof
+ : name:Names.Id.t
+ -> udecl:UState.universe_decl
+ -> poly:bool
+ -> Evd.evar_map
+ -> (Environ.env * EConstr.types) list
+ -> Proof.t
+
+(** Like [start_proof] except that there may be dependencies between
+ initial goals. *)
+val start_dependent_proof
+ : name:Names.Id.t
+ -> udecl:UState.universe_decl
+ -> poly:bool
+ -> Proofview.telescope
+ -> Proof.t
+
+(** Proof entries represent a proof that has been finished, but still
+ not registered with the kernel.
+
+ XXX: Scheduled for removal from public API, don't rely on it *)
+type 'a proof_entry = private {
+ proof_entry_body : 'a Entries.const_entry_body;
+ (* List of section variables *)
+ proof_entry_secctx : Id.Set.t option;
+ (* State id on which the completion of type checking is reported *)
+ proof_entry_feedback : Stateid.t option;
+ proof_entry_type : Constr.types option;
+ proof_entry_universes : Entries.universes_entry;
+ proof_entry_opaque : bool;
+ proof_entry_inline_code : bool;
+}
+
+(** XXX: Scheduled for removal from public API, don't rely on it *)
+type proof_object = private
+ { name : Names.Id.t
+ (** name of the proof *)
+ ; entries : Evd.side_effects proof_entry list
+ (** list of the proof terms (in a form suitable for definitions). *)
+ ; uctx: UState.t
+ (** universe state *)
+ }
+
+val close_proof : opaque:opacity_flag -> keep_body_ucst_separate:bool -> Proof.t -> proof_object
+
+(** Declaration of local constructions (Variable/Hypothesis/Local) *)
+
+(** XXX: Scheduled for removal from public API, don't rely on it *)
+type variable_declaration =
+ | SectionLocalDef of Evd.side_effects proof_entry
+ | SectionLocalAssum of { typ:types; impl:Glob_term.binding_kind; }
+
+(** XXX: Scheduled for removal from public API, don't rely on it *)
+type 'a constant_entry =
+ | DefinitionEntry of 'a proof_entry
+ | ParameterEntry of parameter_entry
+ | PrimitiveEntry of primitive_entry
+
+val declare_variable
+ : name:variable
+ -> kind:Decls.logical_kind
+ -> variable_declaration
+ -> unit
+
+(** Declaration of global constructions
+ i.e. Definition/Theorem/Axiom/Parameter/...
+
+ XXX: Scheduled for removal from public API, use `DeclareDef` instead *)
+val definition_entry
+ : ?fix_exn:Future.fix_exn
+ -> ?opaque:bool
+ -> ?inline:bool
+ -> ?feedback_id:Stateid.t
+ -> ?section_vars:Id.Set.t
+ -> ?types:types
+ -> ?univs:Entries.universes_entry
+ -> ?eff:Evd.side_effects
+ -> ?univsbody:Univ.ContextSet.t
+ (** Universe-constraints attached to the body-only, used in
+ vio-delayed opaque constants and private poly universes *)
+ -> constr
+ -> Evd.side_effects proof_entry
+
+type import_status = ImportDefaultBehavior | ImportNeedQualified
+
+(** [declare_constant id cd] declares a global declaration
+ (constant/parameter) with name [id] in the current section; it returns
+ the full path of the declaration
+
+ internal specify if the constant has been created by the kernel or by the
+ user, and in the former case, if its errors should be silent
+
+ XXX: Scheduled for removal from public API, use `DeclareDef` instead *)
+val declare_constant
+ : ?local:import_status
+ -> name:Id.t
+ -> kind:Decls.logical_kind
+ -> Evd.side_effects constant_entry
+ -> Constant.t
+
+(** [inline_private_constants ~sideff ~uctx env ce] will inline the
+ constants in [ce]'s body and return the body plus the updated
+ [UState.t].
+
+ XXX: Scheduled for removal from public API, don't rely on it *)
+val inline_private_constants
+ : uctx:UState.t
+ -> Environ.env
+ -> Evd.side_effects proof_entry
+ -> Constr.t * UState.t
+
+(** Declaration messages *)
+
+(** XXX: Scheduled for removal from public API, do not use *)
+val definition_message : Id.t -> unit
+val assumption_message : Id.t -> unit
+val fixpoint_message : int array option -> Id.t list -> unit
+
+val check_exists : Id.t -> unit
+
+(** {6 For legacy support, do not use} *)
+
+module Internal : sig
+
+ val map_entry_body : f:('a Entries.proof_output -> 'b Entries.proof_output) -> 'a proof_entry -> 'b proof_entry
+ val map_entry_type : f:(Constr.t option -> Constr.t option) -> 'a proof_entry -> 'a proof_entry
+ (* Overriding opacity is indeed really hacky *)
+ val set_opacity : opaque:bool -> 'a proof_entry -> 'a proof_entry
+
+ val shrink_entry : EConstr.named_context -> 'a proof_entry -> 'a proof_entry * Constr.constr list
+
+ type constant_obj
+
+ val objConstant : constant_obj Libobject.Dyn.tag
+ val objVariable : unit Libobject.Dyn.tag
+
+end
+
+(* Intermediate step necessary to delegate the future.
+ * Both access the current proof state. The former is supposed to be
+ * chained with a computation that completed the proof *)
+type closed_proof_output
+
+(** Requires a complete proof. *)
+val return_proof : Proof.t -> closed_proof_output
+
+(** An incomplete proof is allowed (no error), and a warn is given if
+ the proof is complete. *)
+val return_partial_proof : Proof.t -> closed_proof_output
+val close_future_proof : feedback_id:Stateid.t -> Proof.t -> closed_proof_output Future.computation -> proof_object
+
+(** [by tac] applies tactic [tac] to the 1st subgoal of the current
+ focused proof.
+ Returns [false] if an unsafe tactic has been used. *)
+val by : unit Proofview.tactic -> Proof.t -> Proof.t * bool
+
+val build_by_tactic
+ : ?side_eff:bool
+ -> Environ.env
+ -> uctx:UState.t
+ -> poly:bool
+ -> typ:EConstr.types
+ -> unit Proofview.tactic
+ -> Constr.constr * Constr.types option * Entries.universes_entry * bool * UState.t
+
+(** {6 Helpers to obtain proof state when in an interactive proof } *)
+
+(** [get_goal_context n] returns the context of the [n]th subgoal of
+ the current focused proof or raises a [UserError] if there is no
+ focused proof or if there is no more subgoals *)
+
+val get_goal_context : Proof.t -> int -> Evd.evar_map * Environ.env
+
+(** [get_current_goal_context ()] works as [get_goal_context 1] *)
+val get_current_goal_context : Proof.t -> Evd.evar_map * Environ.env
+
+(** [get_current_context ()] returns the context of the
+ current focused goal. If there is no focused goal but there
+ is a proof in progress, it returns the corresponding evar_map.
+ If there is no pending proof then it returns the current global
+ environment and empty evar_map. *)
+val get_current_context : Proof.t -> Evd.evar_map * Environ.env
+
+(** Temporarily re-exported for 3rd party code; don't use *)
+val build_constant_by_tactic :
+ name:Names.Id.t ->
+ ?opaque:opacity_flag ->
+ uctx:UState.t ->
+ sign:Environ.named_context_val ->
+ poly:bool ->
+ EConstr.types ->
+ unit Proofview.tactic ->
+ Evd.side_effects proof_entry * bool * UState.t
+
+val declare_universe_context : poly:bool -> Univ.ContextSet.t -> unit
+[@@ocaml.deprecated "Use DeclareUctx.declare_universe_context"]
+
+type locality = Discharge | Global of import_status
+
+(** Declaration hooks *)
+module Hook : sig
+ type t
+
+ (** Hooks allow users of the API to perform arbitrary actions at
+ proof/definition saving time. For example, to register a constant
+ as a Coercion, perform some cleanup, update the search database,
+ etc... *)
+ module S : sig
+ type t =
+ { uctx : UState.t
+ (** [ustate]: universe constraints obtained when the term was closed *)
+ ; obls : (Id.t * Constr.t) list
+ (** [(n1,t1),...(nm,tm)]: association list between obligation
+ name and the corresponding defined term (might be a constant,
+ but also an arbitrary term in the Expand case of obligations) *)
+ ; scope : locality
+ (** [scope]: Locality of the original declaration *)
+ ; dref : GlobRef.t
+ (** [dref]: identifier of the original declaration *)
+ }
+ end
+
+ val make : (S.t -> unit) -> t
+ val call : ?hook:t -> S.t -> unit
+end
+
+(** Declare an interactively-defined constant *)
+val declare_entry
+ : name:Id.t
+ -> scope:locality
+ -> kind:Decls.logical_kind
+ -> ?hook:Hook.t
+ -> ?obls:(Id.t * Constr.t) list
+ -> impargs:Impargs.manual_implicits
+ -> uctx:UState.t
+ -> Evd.side_effects proof_entry
+ -> GlobRef.t
+
+(** Declares a non-interactive constant; [body] and [types] will be
+ normalized w.r.t. the passed [evar_map] [sigma]. Universes should
+ be handled properly, including minimization and restriction. Note
+ that [sigma] is checked for unresolved evars, thus you should be
+ careful not to submit open terms or evar maps with stale,
+ unresolved existentials *)
+val declare_definition
+ : name:Id.t
+ -> scope:locality
+ -> kind:Decls.logical_kind
+ -> opaque:bool
+ -> impargs:Impargs.manual_implicits
+ -> udecl:UState.universe_decl
+ -> ?hook:Hook.t
+ -> ?obls:(Id.t * Constr.t) list
+ -> poly:bool
+ -> ?inline:bool
+ -> types:EConstr.t option
+ -> body:EConstr.t
+ -> ?fix_exn:(Exninfo.iexn -> Exninfo.iexn)
+ -> Evd.evar_map
+ -> GlobRef.t
+
+val declare_assumption
+ : ?fix_exn:(Exninfo.iexn -> Exninfo.iexn)
+ -> name:Id.t
+ -> scope:locality
+ -> hook:Hook.t option
+ -> impargs:Impargs.manual_implicits
+ -> uctx:UState.t
+ -> Entries.parameter_entry
+ -> GlobRef.t
+
+module Recthm : sig
+ type t =
+ { name : Id.t
+ (** Name of theorem *)
+ ; typ : Constr.t
+ (** Type of theorem *)
+ ; args : Name.t list
+ (** Names to pre-introduce *)
+ ; impargs : Impargs.manual_implicits
+ (** Explicitily declared implicit arguments *)
+ }
+end
+
+val declare_mutually_recursive
+ : opaque:bool
+ -> scope:locality
+ -> kind:Decls.logical_kind
+ -> poly:bool
+ -> uctx:UState.t
+ -> udecl:UState.universe_decl
+ -> ntns:Vernacexpr.decl_notation list
+ -> rec_declaration:Constr.rec_declaration
+ -> possible_indexes:int list list option
+ -> ?restrict_ucontext:bool
+ (** XXX: restrict_ucontext should be always true, this seems like a
+ bug in obligations, so this parameter should go away *)
+ -> Recthm.t list
+ -> Names.GlobRef.t list
+
+val prepare_obligation
+ : ?opaque:bool
+ -> ?inline:bool
+ -> name:Id.t
+ -> poly:bool
+ -> udecl:UState.universe_decl
+ -> types:EConstr.t option
+ -> body:EConstr.t
+ -> Evd.evar_map
+ -> Constr.constr * Constr.types * UState.t * RetrieveObl.obligation_info
+
+val prepare_parameter
+ : poly:bool
+ -> udecl:UState.universe_decl
+ -> types:EConstr.types
+ -> Evd.evar_map
+ -> Evd.evar_map * Entries.parameter_entry
+
+(* Compat: will remove *)
+exception AlreadyDeclared of (string option * Names.Id.t)
diff --git a/vernac/declareDef.ml b/vernac/declareDef.ml
index fc53abdcea..83bb1dae71 100644
--- a/vernac/declareDef.ml
+++ b/vernac/declareDef.ml
@@ -1,165 +1,9 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * Copyright INRIA, CNRS and contributors *)
-(* <O___,, * (see version control and CREDITS file for authors & dates) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Declare
-open Impargs
-
-type locality = Discharge | Global of Declare.import_status
-
-(* Hooks naturally belong here as they apply to both definitions and lemmas *)
-module Hook = struct
- module S = struct
- type t =
- { uctx : UState.t
- (** [ustate]: universe constraints obtained when the term was closed *)
- ; obls : (Names.Id.t * Constr.t) list
- (** [(n1,t1),...(nm,tm)]: association list between obligation
- name and the corresponding defined term (might be a constant,
- but also an arbitrary term in the Expand case of obligations) *)
- ; scope : locality
- (** [locality]: Locality of the original declaration *)
- ; dref : Names.GlobRef.t
- (** [ref]: identifier of the original declaration *)
- }
- end
-
- type t = (S.t -> unit) CEphemeron.key
-
- let make hook = CEphemeron.create hook
-
- let call ?hook ?fix_exn x =
- try Option.iter (fun hook -> CEphemeron.get hook x) hook
- with e when CErrors.noncritical e ->
- let e = Exninfo.capture e in
- let e = Option.cata (fun fix -> fix e) e fix_exn in
- Exninfo.iraise e
-end
-
-(* Locality stuff *)
-let declare_definition ~name ~scope ~kind ?hook_data ~ubind ~impargs ce =
- let fix_exn = Declare.Internal.get_fix_exn ce in
- let should_suggest = ce.Declare.proof_entry_opaque &&
- Option.is_empty ce.Declare.proof_entry_secctx in
- let dref = match scope with
- | Discharge ->
- let () = declare_variable ~name ~kind (SectionLocalDef ce) in
- if should_suggest then Proof_using.suggest_variable (Global.env ()) name;
- Names.GlobRef.VarRef name
- | Global local ->
- let kn = declare_constant ~name ~local ~kind (DefinitionEntry ce) in
- let gr = Names.GlobRef.ConstRef kn in
- if should_suggest then Proof_using.suggest_constant (Global.env ()) kn;
- let () = DeclareUniv.declare_univ_binders gr ubind in
- gr
- in
- let () = maybe_declare_manual_implicits false dref impargs in
- let () = definition_message name in
- begin
- match hook_data with
- | None -> ()
- | Some (hook, uctx, obls) ->
- Hook.call ~fix_exn ~hook { Hook.S.uctx; obls; scope; dref }
- end;
- dref
-
-let mutual_make_bodies ~fixitems ~rec_declaration ~possible_indexes =
- match possible_indexes with
- | Some possible_indexes ->
- let env = Global.env() in
- let indexes = Pretyping.search_guard env possible_indexes rec_declaration in
- let vars = Vars.universes_of_constr (Constr.mkFix ((indexes,0),rec_declaration)) in
- let fixdecls = CList.map_i (fun i _ -> Constr.mkFix ((indexes,i),rec_declaration)) 0 fixitems in
- vars, fixdecls, Some indexes
- | None ->
- let fixdecls = CList.map_i (fun i _ -> Constr.mkCoFix (i,rec_declaration)) 0 fixitems in
- let vars = Vars.universes_of_constr (List.hd fixdecls) in
- vars, fixdecls, None
-
-module Recthm = struct
- type t =
- { name : Names.Id.t
- (** Name of theorem *)
- ; typ : Constr.t
- (** Type of theorem *)
- ; args : Names.Name.t list
- (** Names to pre-introduce *)
- ; impargs : Impargs.manual_implicits
- (** Explicitily declared implicit arguments *)
- }
-end
-
-let declare_mutually_recursive ~opaque ~scope ~kind ~poly ~uctx ~udecl ~ntns ~rec_declaration ~possible_indexes ?(restrict_ucontext=true) fixitems =
- let vars, fixdecls, indexes =
- mutual_make_bodies ~fixitems ~rec_declaration ~possible_indexes in
- let ubind, univs =
- (* XXX: Obligations don't do this, this seems like a bug? *)
- if restrict_ucontext
- then
- let evd = Evd.from_ctx uctx in
- let evd = Evd.restrict_universe_context evd vars in
- let univs = Evd.check_univ_decl ~poly evd udecl in
- Evd.universe_binders evd, univs
- else
- let univs = UState.univ_entry ~poly uctx in
- UnivNames.empty_binders, univs
- in
- let csts = CList.map2
- (fun Recthm.{ name; typ; impargs } body ->
- let ce = Declare.definition_entry ~opaque ~types:typ ~univs body in
- declare_definition ~name ~scope ~kind ~ubind ~impargs ce)
- fixitems fixdecls
- in
- let isfix = Option.is_empty possible_indexes in
- let fixnames = List.map (fun { Recthm.name } -> name) fixitems in
- Declare.recursive_message isfix indexes fixnames;
- List.iter (Metasyntax.add_notation_interpretation (Global.env())) ntns;
- csts
-
-let warn_let_as_axiom =
- CWarnings.create ~name:"let-as-axiom" ~category:"vernacular"
- Pp.(fun id -> strbrk "Let definition" ++ spc () ++ Names.Id.print id ++
- spc () ++ strbrk "declared as an axiom.")
-
-let declare_assumption ?fix_exn ~name ~scope ~hook ~impargs ~uctx pe =
- let local = match scope with
- | Discharge -> warn_let_as_axiom name; Declare.ImportNeedQualified
- | Global local -> local
- in
- let kind = Decls.(IsAssumption Conjectural) in
- let decl = Declare.ParameterEntry pe in
- let kn = Declare.declare_constant ~name ~local ~kind decl in
- let dref = Names.GlobRef.ConstRef kn in
- let () = Impargs.maybe_declare_manual_implicits false dref impargs in
- let () = Declare.assumption_message name in
- let () = DeclareUniv.declare_univ_binders dref (UState.universe_binders uctx) in
- let () = Hook.(call ?fix_exn ?hook { S.uctx; obls = []; scope; dref}) in
- dref
-
-(* Preparing proof entries *)
-
-let check_definition_evars ~allow_evars sigma =
- let env = Global.env () in
- if not allow_evars then Pretyping.check_evars_are_solved ~program_mode:false env sigma
-
-let prepare_definition ~allow_evars ?opaque ?inline ~poly ~udecl ~types ~body sigma =
- check_definition_evars ~allow_evars sigma;
- let sigma, (body, types) = Evarutil.finalize ~abort_on_undefined_evars:(not allow_evars)
- sigma (fun nf -> nf body, Option.map nf types)
- in
- let univs = Evd.check_univ_decl ~poly sigma udecl in
- sigma, definition_entry ?opaque ?inline ?types ~univs body
-
-let prepare_parameter ~allow_evars ~poly ~udecl ~types sigma =
- check_definition_evars ~allow_evars sigma;
- let sigma, typ = Evarutil.finalize ~abort_on_undefined_evars:(not allow_evars)
- sigma (fun nf -> nf types)
- in
- let univs = Evd.check_univ_decl ~poly sigma udecl in
- sigma, (None(*proof using*), (typ, univs), None(*inline*))
+type locality = Declare.locality =
+ | Discharge [@ocaml.deprecated "Use [Declare.Discharge]"]
+ | Global of Declare.import_status [@ocaml.deprecated "Use [Declare.Global]"]
+[@@ocaml.deprecated "Use [Declare.locality]"]
+
+let declare_definition = Declare.declare_definition
+[@@ocaml.deprecated "Use [Declare.declare_definition]"]
+module Hook = Declare.Hook
+[@@ocaml.deprecated "Use [Declare.Hook]"]
diff --git a/vernac/declareDef.mli b/vernac/declareDef.mli
deleted file mode 100644
index 1d7fd3a3bf..0000000000
--- a/vernac/declareDef.mli
+++ /dev/null
@@ -1,108 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * Copyright INRIA, CNRS and contributors *)
-(* <O___,, * (see version control and CREDITS file for authors & dates) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Names
-
-type locality = Discharge | Global of Declare.import_status
-
-(** Declaration hooks *)
-module Hook : sig
- type t
-
- (** Hooks allow users of the API to perform arbitrary actions at
- proof/definition saving time. For example, to register a constant
- as a Coercion, perform some cleanup, update the search database,
- etc... *)
- module S : sig
- type t =
- { uctx : UState.t
- (** [ustate]: universe constraints obtained when the term was closed *)
- ; obls : (Id.t * Constr.t) list
- (** [(n1,t1),...(nm,tm)]: association list between obligation
- name and the corresponding defined term (might be a constant,
- but also an arbitrary term in the Expand case of obligations) *)
- ; scope : locality
- (** [scope]: Locality of the original declaration *)
- ; dref : GlobRef.t
- (** [dref]: identifier of the original declaration *)
- }
- end
-
- val make : (S.t -> unit) -> t
- val call : ?hook:t -> ?fix_exn:Future.fix_exn -> S.t -> unit
-end
-
-val declare_definition
- : name:Id.t
- -> scope:locality
- -> kind:Decls.logical_kind
- -> ?hook_data:(Hook.t * UState.t * (Id.t * Constr.t) list)
- -> ubind:UnivNames.universe_binders
- -> impargs:Impargs.manual_implicits
- -> Evd.side_effects Declare.proof_entry
- -> GlobRef.t
-
-val declare_assumption
- : ?fix_exn:(Exninfo.iexn -> Exninfo.iexn)
- -> name:Id.t
- -> scope:locality
- -> hook:Hook.t option
- -> impargs:Impargs.manual_implicits
- -> uctx:UState.t
- -> Entries.parameter_entry
- -> GlobRef.t
-
-module Recthm : sig
- type t =
- { name : Id.t
- (** Name of theorem *)
- ; typ : Constr.t
- (** Type of theorem *)
- ; args : Name.t list
- (** Names to pre-introduce *)
- ; impargs : Impargs.manual_implicits
- (** Explicitily declared implicit arguments *)
- }
-end
-
-val declare_mutually_recursive
- : opaque:bool
- -> scope:locality
- -> kind:Decls.logical_kind
- -> poly:bool
- -> uctx:UState.t
- -> udecl:UState.universe_decl
- -> ntns:Vernacexpr.decl_notation list
- -> rec_declaration:Constr.rec_declaration
- -> possible_indexes:int list list option
- -> ?restrict_ucontext:bool
- (** XXX: restrict_ucontext should be always true, this seems like a
- bug in obligations, so this parameter should go away *)
- -> Recthm.t list
- -> Names.GlobRef.t list
-
-val prepare_definition
- : allow_evars:bool
- -> ?opaque:bool
- -> ?inline:bool
- -> poly:bool
- -> udecl:UState.universe_decl
- -> types:EConstr.t option
- -> body:EConstr.t
- -> Evd.evar_map
- -> Evd.evar_map * Evd.side_effects Declare.proof_entry
-
-val prepare_parameter
- : allow_evars:bool
- -> poly:bool
- -> udecl:UState.universe_decl
- -> types:EConstr.types
- -> Evd.evar_map
- -> Evd.evar_map * Entries.parameter_entry
diff --git a/vernac/declareInd.ml b/vernac/declareInd.ml
index 2610f16d92..e22d63b811 100644
--- a/vernac/declareInd.ml
+++ b/vernac/declareInd.ml
@@ -49,9 +49,12 @@ let load_inductive i ((sp, kn), names) =
let names = inductive_names sp kn names in
List.iter (fun (sp, ref) -> Nametab.push (Nametab.Until i) sp ref ) names
-let open_inductive i ((sp, kn), names) =
+let open_inductive f i ((sp, kn), names) =
let names = inductive_names sp kn names in
- List.iter (fun (sp, ref) -> Nametab.push (Nametab.Exactly i) sp ref) names
+ List.iter (fun (sp, ref) ->
+ if Libobject.in_filter_ref ref f then
+ Nametab.push (Nametab.Exactly i) sp ref)
+ names
let cache_inductive ((sp, kn), names) =
let names = inductive_names sp kn names in
@@ -93,38 +96,6 @@ let inPrim : (Projection.Repr.t * Constant.t) -> Libobject.obj =
let declare_primitive_projection p c = Lib.add_anonymous_leaf (inPrim (p,c))
-let declare_one_projection univs (mind,_ as ind) ~proj_npars proj_arg label (term,types) =
- let name = Label.to_id label in
- let univs, u = match univs with
- | Monomorphic_entry _ ->
- (* Global constraints already defined through the inductive *)
- Monomorphic_entry Univ.ContextSet.empty, Univ.Instance.empty
- | Polymorphic_entry (nas, ctx) ->
- Polymorphic_entry (nas, ctx), Univ.UContext.instance ctx
- in
- let term = Vars.subst_instance_constr u term in
- let types = Vars.subst_instance_constr u types in
- let entry = Declare.definition_entry ~types ~univs term in
- let cst = Declare.declare_constant ~name ~kind:Decls.(IsDefinition StructureComponent) (Declare.DefinitionEntry entry) in
- let p = Projection.Repr.make ind ~proj_npars ~proj_arg label in
- declare_primitive_projection p cst
-
-let declare_projections univs mind =
- let env = Global.env () in
- let mib = Environ.lookup_mind mind env in
- let open Declarations in
- match mib.mind_record with
- | PrimRecord info ->
- let iter_ind i (_, labs, _, _) =
- let ind = (mind, i) in
- let projs = Inductiveops.compute_projections env ind in
- CArray.iter2_i (declare_one_projection univs ind ~proj_npars:mib.mind_nparams) labs projs
- in
- let () = Array.iteri iter_ind info in
- true
- | FakeRecord -> false
- | NotRecord -> false
-
let feedback_axiom () = Feedback.(feedback AddedAxiom)
let is_unsafe_typing_flags () =
@@ -146,7 +117,7 @@ let declare_mind mie =
let (sp,kn as oname) = Lib.add_leaf id (inInductive { ind_names = names }) in
if is_unsafe_typing_flags() then feedback_axiom ();
let mind = Global.mind_of_delta_kn kn in
- let isprim = declare_projections mie.mind_entry_universes mind in
+ let isprim = Inductive.is_primitive_record (Inductive.lookup_mind_specif (Global.env()) (mind,0)) in
Impargs.declare_mib_implicits mind;
declare_inductive_argument_scopes mind mie;
oname, isprim
diff --git a/vernac/declareInd.mli b/vernac/declareInd.mli
index ae649634a5..05a1617329 100644
--- a/vernac/declareInd.mli
+++ b/vernac/declareInd.mli
@@ -30,3 +30,6 @@ type inductive_obj
val objInductive : inductive_obj Libobject.Dyn.tag
end
+
+val declare_primitive_projection :
+ Names.Projection.Repr.t -> Names.Constant.t -> unit
diff --git a/vernac/declareObl.ml b/vernac/declareObl.ml
index 98a9e4b9c9..ab11472dec 100644
--- a/vernac/declareObl.ml
+++ b/vernac/declareObl.ml
@@ -55,10 +55,10 @@ module ProgramDecl = struct
; prg_implicits : Impargs.manual_implicits
; prg_notations : Vernacexpr.decl_notation list
; prg_poly : bool
- ; prg_scope : DeclareDef.locality
+ ; prg_scope : Declare.locality
; prg_kind : Decls.definition_object_kind
; prg_reduce : constr -> constr
- ; prg_hook : DeclareDef.Hook.t option
+ ; prg_hook : Declare.Hook.t option
; prg_opaque : bool
}
@@ -362,34 +362,21 @@ let get_fix_exn, stm_get_fix_exn = Hook.make ()
let declare_definition prg =
let varsubst = obligation_substitution true prg in
- let body, typ = subst_prog varsubst prg in
- let nf =
- UnivSubst.nf_evars_and_universes_opt_subst
- (fun x -> None)
- (UState.subst prg.prg_ctx)
- in
- let opaque = prg.prg_opaque in
+ let sigma = Evd.from_ctx prg.prg_ctx in
+ let body, types = subst_prog varsubst prg in
+ let body, types = EConstr.(of_constr body, Some (of_constr types)) in
+ (* All these should be grouped into a struct a some point *)
+ let opaque, poly, udecl, hook = prg.prg_opaque, prg.prg_poly, prg.prg_univdecl, prg.prg_hook in
+ let name, scope, kind, impargs = prg.prg_name, prg.prg_scope, Decls.(IsDefinition prg.prg_kind), prg.prg_implicits in
let fix_exn = Hook.get get_fix_exn () in
- let typ = nf typ in
- let body = nf body in
- let obls = List.map (fun (id, (_, c)) -> (id, nf c)) varsubst in
- let uvars =
- Univ.LSet.union
- (Vars.universes_of_constr typ)
- (Vars.universes_of_constr body)
- in
- let uctx = UState.restrict prg.prg_ctx uvars in
- let univs =
- UState.check_univ_decl ~poly:prg.prg_poly uctx prg.prg_univdecl
- in
- let ce = Declare.definition_entry ~fix_exn ~opaque ~types:typ ~univs body in
+ let obls = List.map (fun (id, (_, c)) -> (id, c)) varsubst in
+ (* XXX: This is doing normalization twice *)
let () = progmap_remove prg in
- let ubind = UState.universe_binders uctx in
- let hook_data = Option.map (fun hook -> hook, uctx, obls) prg.prg_hook in
- DeclareDef.declare_definition
- ~name:prg.prg_name ~scope:prg.prg_scope ~ubind
- ~kind:Decls.(IsDefinition prg.prg_kind) ce
- ~impargs:prg.prg_implicits ?hook_data
+ let kn =
+ Declare.declare_definition ~name ~scope ~kind ~impargs ?hook ~obls
+ ~fix_exn ~opaque ~poly ~udecl ~types ~body sigma
+ in
+ kn
let rec lam_index n t acc =
match Constr.kind t with
@@ -439,7 +426,7 @@ let declare_mutual_definition l =
let fixdefs, fixrs, fixtypes, fixitems =
List.fold_right2 (fun (d,r,typ,impargs) name (a1,a2,a3,a4) ->
d :: a1, r :: a2, typ :: a3,
- DeclareDef.Recthm.{ name; typ; impargs; args = [] } :: a4
+ Declare.Recthm.{ name; typ; impargs; args = [] } :: a4
) defs first.prg_deps ([],[],[],[])
in
let fixkind = Option.get first.prg_fixkind in
@@ -459,14 +446,13 @@ let declare_mutual_definition l =
(* Declare the recursive definitions *)
let udecl = UState.default_univ_decl in
let kns =
- DeclareDef.declare_mutually_recursive ~scope ~opaque ~kind
+ Declare.declare_mutually_recursive ~scope ~opaque ~kind
~udecl ~ntns ~uctx:first.prg_ctx ~rec_declaration ~possible_indexes ~poly
~restrict_ucontext:false fixitems
in
(* Only for the first constant *)
- let fix_exn = Hook.get get_fix_exn () in
let dref = List.hd kns in
- DeclareDef.Hook.(call ?hook:first.prg_hook ~fix_exn { S.uctx = first.prg_ctx; obls; scope; dref });
+ Declare.Hook.(call ?hook:first.prg_hook { S.uctx = first.prg_ctx; obls; scope; dref });
List.iter progmap_remove l;
dref
@@ -529,10 +515,6 @@ let obligation_terminator entries uctx { name; num; auto } =
Inductiveops.control_only_guard (Global.env ()) sigma (EConstr.of_constr body);
(* Declare the obligation ourselves and drop the hook *)
let prg = CEphemeron.get (ProgMap.find name !from_prg) in
- (* Ensure universes are substituted properly in body and type *)
- let body = EConstr.to_constr sigma (EConstr.of_constr body) in
- let ty = Option.map (fun x -> EConstr.to_constr sigma (EConstr.of_constr x)) ty in
- let ctx = Evd.evar_universe_context sigma in
let { obls; remaining=rem } = prg.prg_obligations in
let obl = obls.(num) in
let status =
@@ -545,24 +527,24 @@ let obligation_terminator entries uctx { name; num; auto } =
| (_, status), false -> status
in
let obl = { obl with obl_status = false, status } in
- let ctx =
- if prg.prg_poly then ctx
- else UState.union prg.prg_ctx ctx
+ let uctx =
+ if prg.prg_poly then uctx
+ else UState.union prg.prg_ctx uctx
in
- let uctx = UState.univ_entry ~poly:prg.prg_poly ctx in
- let (defined, obl) = declare_obligation prg obl body ty uctx in
+ let univs = UState.univ_entry ~poly:prg.prg_poly uctx in
+ let (defined, obl) = declare_obligation prg obl body ty univs in
let prg_ctx =
if prg.prg_poly then (* Polymorphic *)
(* We merge the new universes and constraints of the
polymorphic obligation with the existing ones *)
- UState.union prg.prg_ctx ctx
+ UState.union prg.prg_ctx uctx
else
(* The first obligation, if defined,
declares the univs of the constant,
each subsequent obligation declares its own additional
universes and constraints if any *)
if defined then UState.make ~lbound:(Global.universes_lbound ()) (Global.universes ())
- else ctx
+ else uctx
in
update_program_decl_on_defined prg obls num obl ~uctx:prg_ctx rem ~auto
| _ ->
@@ -574,7 +556,7 @@ let obligation_terminator entries uctx { name; num; auto } =
(* Similar to the terminator but for interactive paths, as the
terminator is only called in interactive proof mode *)
-let obligation_hook prg obl num auto { DeclareDef.Hook.S.uctx = ctx'; dref; _ } =
+let obligation_hook prg obl num auto { Declare.Hook.S.uctx = ctx'; dref; _ } =
let { obls; remaining=rem } = prg.prg_obligations in
let cst = match dref with GlobRef.ConstRef cst -> cst | _ -> assert false in
let transparent = evaluable_constant cst (Global.env ()) in
diff --git a/vernac/declareObl.mli b/vernac/declareObl.mli
index 16c0413caf..03f0a57bcb 100644
--- a/vernac/declareObl.mli
+++ b/vernac/declareObl.mli
@@ -52,22 +52,22 @@ module ProgramDecl : sig
; prg_implicits : Impargs.manual_implicits
; prg_notations : Vernacexpr.decl_notation list
; prg_poly : bool
- ; prg_scope : DeclareDef.locality
+ ; prg_scope : Declare.locality
; prg_kind : Decls.definition_object_kind
; prg_reduce : constr -> constr
- ; prg_hook : DeclareDef.Hook.t option
+ ; prg_hook : Declare.Hook.t option
; prg_opaque : bool
}
val make :
?opaque:bool
- -> ?hook:DeclareDef.Hook.t
+ -> ?hook:Declare.Hook.t
-> Names.Id.t
-> udecl:UState.universe_decl
-> uctx:UState.t
-> impargs:Impargs.manual_implicits
-> poly:bool
- -> scope:DeclareDef.locality
+ -> scope:Declare.locality
-> kind:Decls.definition_object_kind
-> Constr.constr option
-> Constr.types
@@ -126,7 +126,7 @@ val obligation_hook
-> Obligation.t
-> Int.t
-> (Names.Id.t option -> Int.Set.t -> 'a option -> 'b)
- -> DeclareDef.Hook.S.t
+ -> Declare.Hook.S.t
-> unit
(** [obligation_hook] part 2 of saving an obligation, non-interactive mode *)
diff --git a/vernac/declareUniv.ml b/vernac/declareUniv.ml
index 300dfe6c35..1705915e70 100644
--- a/vernac/declareUniv.ml
+++ b/vernac/declareUniv.ml
@@ -10,6 +10,17 @@
open Names
+(* object_kind , id *)
+exception AlreadyDeclared of (string option * Id.t)
+
+let _ = CErrors.register_handler (function
+ | AlreadyDeclared (kind, id) ->
+ Some
+ Pp.(seq [ Pp.pr_opt_no_spc (fun s -> str s ++ spc ()) kind
+ ; Id.print id; str " already exists."])
+ | _ ->
+ None)
+
type universe_source =
| BoundUniv (* polymorphic universe, bound in a function (this will go away someday) *)
| QualifiedUniv of Id.t (* global universe introduced by some global value *)
@@ -19,7 +30,7 @@ type universe_name_decl = universe_source * (Id.t * Univ.Level.UGlobal.t) list
let check_exists_universe sp =
if Nametab.exists_universe sp then
- raise (Declare.AlreadyDeclared (Some "Universe", Libnames.basename sp))
+ raise (AlreadyDeclared (Some "Universe", Libnames.basename sp))
else ()
let qualify_univ i dp src id =
@@ -56,7 +67,7 @@ let input_univ_names : universe_name_decl -> Libobject.obj =
{ (default_object "Global universe name state") with
cache_function = cache_univ_names;
load_function = load_univ_names;
- open_function = open_univ_names;
+ open_function = simple_open open_univ_names;
discharge_function = discharge_univ_names;
subst_function = (fun (subst, a) -> (* Actually the name is generated once and for all. *) a);
classify_function = (fun a -> Substitute a) }
@@ -94,7 +105,7 @@ let do_universe ~poly l =
in
let src = if poly then BoundUniv else UnqualifiedUniv in
let () = Lib.add_anonymous_leaf (input_univ_names (src, l)) in
- Declare.declare_universe_context ~poly ctx
+ DeclareUctx.declare_universe_context ~poly ctx
let do_constraint ~poly l =
let open Univ in
@@ -107,4 +118,4 @@ let do_constraint ~poly l =
Constraint.empty l
in
let uctx = ContextSet.add_constraints constraints ContextSet.empty in
- Declare.declare_universe_context ~poly uctx
+ DeclareUctx.declare_universe_context ~poly uctx
diff --git a/vernac/declareUniv.mli b/vernac/declareUniv.mli
index 51f3f5e0fb..e4d1d5dc65 100644
--- a/vernac/declareUniv.mli
+++ b/vernac/declareUniv.mli
@@ -10,6 +10,9 @@
open Names
+(* object_kind , id *)
+exception AlreadyDeclared of (string option * Id.t)
+
(** Global universe contexts, names and constraints *)
val declare_univ_binders : GlobRef.t -> UnivNames.universe_binders -> unit
diff --git a/vernac/declaremods.ml b/vernac/declaremods.ml
index 4f527b73d0..50fa6052f6 100644
--- a/vernac/declaremods.ml
+++ b/vernac/declaremods.ml
@@ -81,6 +81,19 @@ module ModSubstObjs :
let sobjs_no_functor (mbids,_) = List.is_empty mbids
+let subst_filtered sub (f,mp) =
+ let f = match f with
+ | Unfiltered -> Unfiltered
+ | Names ns ->
+ let module NSet = Globnames.ExtRefSet in
+ let ns =
+ NSet.fold (fun n ns -> NSet.add (Globnames.subst_extended_reference sub n) ns)
+ ns NSet.empty
+ in
+ Names ns
+ in
+ f, subst_mp sub mp
+
let rec subst_aobjs sub = function
| Objs o as objs ->
let o' = subst_objects sub o in
@@ -109,7 +122,7 @@ and subst_objects subst seg =
let aobjs' = subst_aobjs subst aobjs in
if aobjs' == aobjs then node else (id, IncludeObject aobjs')
| ExportObject { mpl } ->
- let mpl' = List.map (subst_mp subst) mpl in
+ let mpl' = List.Smart.map (subst_filtered subst) mpl in
if mpl'==mpl then node else (id, ExportObject { mpl = mpl' })
| KeepObject _ -> assert false
in
@@ -285,86 +298,103 @@ and load_keep i ((sp,kn),kobjs) =
(** {6 Implementation of Import and Export commands} *)
-let mark_object obj (exports,acc) =
- (exports, obj::acc)
+let mark_object f obj (exports,acc) =
+ (exports, (f,obj)::acc)
-let rec collect_module_objects mp acc =
+let rec collect_module_objects (f,mp) acc =
(* May raise Not_found for unknown module and for functors *)
let modobjs = ModObjs.get mp in
let prefix = modobjs.module_prefix in
- let acc = collect_objects 1 prefix modobjs.module_keep_objects acc in
- collect_objects 1 prefix modobjs.module_substituted_objects acc
+ let acc = collect_objects f 1 prefix modobjs.module_keep_objects acc in
+ collect_objects f 1 prefix modobjs.module_substituted_objects acc
-and collect_object i (name, obj as o) acc =
+and collect_object f i (name, obj as o) acc =
match obj with
- | ExportObject { mpl; _ } -> collect_export i mpl acc
+ | ExportObject { mpl } -> collect_export f i mpl acc
| AtomicObject _ | IncludeObject _ | KeepObject _
- | ModuleObject _ | ModuleTypeObject _ -> mark_object o acc
+ | ModuleObject _ | ModuleTypeObject _ -> mark_object f o acc
+
+and collect_objects f i prefix objs acc =
+ List.fold_right (fun (id, obj) acc -> collect_object f i (Lib.make_oname prefix id, obj) acc) objs acc
+
+and collect_one_export f (f',mp) (exports,objs as acc) =
+ match filter_and f f' with
+ | None -> acc
+ | Some f ->
+ let exports' = MPmap.update mp (function
+ | None -> Some f
+ | Some f0 -> Some (filter_or f f0))
+ exports
+ in
+ (* If the map doesn't change there is nothing new to export.
-and collect_objects i prefix objs acc =
- List.fold_right (fun (id, obj) acc -> collect_object i (Lib.make_oname prefix id, obj) acc) objs acc
+ It's possible that [filter_and] or [filter_or] mangled precise
+ filters such that we repeat uselessly, but the important
+ [Unfiltered] case is handled correctly.
+ *)
+ if exports == exports' then acc
+ else
+ collect_module_objects (f,mp) (exports', objs)
-and collect_one_export mp (exports,objs as acc) =
- if not (MPset.mem mp exports) then
- collect_module_objects mp (MPset.add mp exports, objs)
- else acc
-and collect_export i mpl acc =
+and collect_export f i mpl acc =
if Int.equal i 1 then
- List.fold_right collect_one_export mpl acc
+ List.fold_right (collect_one_export f) mpl acc
else acc
-let rec open_object i (name, obj) =
+let open_modtype i ((sp,kn),_) =
+ let mp = mp_of_kn kn in
+ let mp' =
+ try Nametab.locate_modtype (qualid_of_path sp)
+ with Not_found ->
+ anomaly (pr_path sp ++ str " should already exist!");
+ in
+ assert (ModPath.equal mp mp');
+ Nametab.push_modtype (Nametab.Exactly i) sp mp
+
+let rec open_object f i (name, obj) =
match obj with
- | AtomicObject o -> Libobject.open_object i (name, o)
+ | AtomicObject o -> Libobject.open_object f i (name, o)
| ModuleObject sobjs ->
let dir = dir_of_sp (fst name) in
let mp = mp_of_kn (snd name) in
- open_module i dir mp sobjs
+ open_module f i dir mp sobjs
| ModuleTypeObject sobjs -> open_modtype i (name, sobjs)
- | IncludeObject aobjs -> open_include i (name, aobjs)
- | ExportObject { mpl; _ } -> open_export i mpl
- | KeepObject objs -> open_keep i (name, objs)
+ | IncludeObject aobjs -> open_include f i (name, aobjs)
+ | ExportObject { mpl } -> open_export f i mpl
+ | KeepObject objs -> open_keep f i (name, objs)
-and open_module i obj_dir obj_mp sobjs =
+and open_module f i obj_dir obj_mp sobjs =
let prefix = Nametab.{ obj_dir ; obj_mp; } in
let dirinfo = Nametab.GlobDirRef.DirModule prefix in
consistency_checks true obj_dir dirinfo;
- Nametab.push_dir (Nametab.Exactly i) obj_dir dirinfo;
+ (match f with
+ | Unfiltered -> Nametab.push_dir (Nametab.Exactly i) obj_dir dirinfo
+ | Names _ -> ());
(* If we're not a functor, let's iter on the internal components *)
if sobjs_no_functor sobjs then begin
let modobjs = ModObjs.get obj_mp in
- open_objects (i+1) modobjs.module_prefix modobjs.module_substituted_objects
+ open_objects f (i+1) modobjs.module_prefix modobjs.module_substituted_objects
end
-and open_objects i prefix objs =
- List.iter (fun (id, obj) -> open_object i (Lib.make_oname prefix id, obj)) objs
-
-and open_modtype i ((sp,kn),_) =
- let mp = mp_of_kn kn in
- let mp' =
- try Nametab.locate_modtype (qualid_of_path sp)
- with Not_found ->
- anomaly (pr_path sp ++ str " should already exist!");
- in
- assert (ModPath.equal mp mp');
- Nametab.push_modtype (Nametab.Exactly i) sp mp
+and open_objects f i prefix objs =
+ List.iter (fun (id, obj) -> open_object f i (Lib.make_oname prefix id, obj)) objs
-and open_include i ((sp,kn), aobjs) =
+and open_include f i ((sp,kn), aobjs) =
let obj_dir = Libnames.dirpath sp in
let obj_mp = KerName.modpath kn in
let prefix = Nametab.{ obj_dir; obj_mp; } in
let o = expand_aobjs aobjs in
- open_objects i prefix o
+ open_objects f i prefix o
-and open_export i mpl =
- let _,objs = collect_export i mpl (MPset.empty, []) in
- List.iter (open_object 1) objs
+and open_export f i mpl =
+ let _,objs = collect_export f i mpl (MPmap.empty, []) in
+ List.iter (fun (f,o) -> open_object f 1 o) objs
-and open_keep i ((sp,kn),kobjs) =
+and open_keep f i ((sp,kn),kobjs) =
let obj_dir = dir_of_sp sp and obj_mp = mp_of_kn kn in
let prefix = Nametab.{ obj_dir; obj_mp; } in
- open_objects i prefix kobjs
+ open_objects f i prefix kobjs
let rec cache_object (name, obj) =
match obj with
@@ -383,7 +413,7 @@ and cache_include ((sp,kn), aobjs) =
let prefix = Nametab.{ obj_dir; obj_mp; } in
let o = expand_aobjs aobjs in
load_objects 1 prefix o;
- open_objects 1 prefix o
+ open_objects Unfiltered 1 prefix o
and cache_keep ((sp,kn),kobjs) =
anomaly (Pp.str "This module should not be cached!")
@@ -621,26 +651,28 @@ let mk_params_entry args =
let mk_funct_type env args seb0 =
List.fold_left
- (fun seb (arg_id,arg_t,arg_inl) ->
+ (fun (seb,cst) (arg_id,arg_t,arg_inl) ->
let mp = MPbound arg_id in
- let arg_t = Mod_typing.translate_modtype env mp arg_inl ([],arg_t) in
- MoreFunctor(arg_id,arg_t,seb))
+ let arg_t, cst' = Mod_typing.translate_modtype env mp arg_inl ([],arg_t) in
+ MoreFunctor(arg_id,arg_t,seb), Univ.Constraint.union cst cst')
seb0 args
(** Prepare the module type list for check of subtypes *)
let build_subtypes env mp args mtys =
- let (cst, ans) = List.fold_left_map
- (fun cst (m,ann) ->
+ let (ctx, ans) = List.fold_left_map
+ (fun ctx (m,ann) ->
let inl = inl2intopt ann in
- let mte, _, cst' = Modintern.interp_module_ast env Modintern.ModType m in
- let env = Environ.push_context_set ~strict:true cst' env in
- let cst = Univ.ContextSet.union cst cst' in
- let mtb = Mod_typing.translate_modtype env mp inl ([],mte) in
- cst, { mtb with mod_type = mk_funct_type env args mtb.mod_type })
+ let mte, _, ctx' = Modintern.interp_module_ast env Modintern.ModType m in
+ let env = Environ.push_context_set ~strict:true ctx' env in
+ let ctx = Univ.ContextSet.union ctx ctx' in
+ let mtb, cst = Mod_typing.translate_modtype env mp inl ([],mte) in
+ let mod_type, cst = mk_funct_type env args (mtb.mod_type,cst) in
+ let ctx = Univ.ContextSet.add_constraints cst ctx in
+ ctx, { mtb with mod_type })
Univ.ContextSet.empty mtys
in
- (ans, cst)
+ (ans, ctx)
(** {6 Current module information}
@@ -673,23 +705,23 @@ module RawModOps = struct
let start_module export id args res fs =
let mp = Global.start_module id in
- let arg_entries_r, cst = intern_args args in
- let () = Global.push_context_set ~strict:true cst in
+ let arg_entries_r, ctx = intern_args args in
+ let () = Global.push_context_set ~strict:true ctx in
let env = Global.env () in
- let res_entry_o, subtyps, cst = match res with
+ let res_entry_o, subtyps, ctx = match res with
| Enforce (res,ann) ->
let inl = inl2intopt ann in
- let (mte, _, cst) = Modintern.interp_module_ast env Modintern.ModType res in
- let env = Environ.push_context_set ~strict:true cst env in
+ let (mte, _, ctx) = Modintern.interp_module_ast env Modintern.ModType res in
+ let env = Environ.push_context_set ~strict:true ctx env in
(* We check immediately that mte is well-formed *)
- let _, _, _, cst' = Mod_typing.translate_mse env None inl mte in
- let cst = Univ.ContextSet.union cst cst' in
- Some (mte, inl), [], cst
+ let _, _, _, cst = Mod_typing.translate_mse env None inl mte in
+ let ctx = Univ.ContextSet.add_constraints cst ctx in
+ Some (mte, inl), [], ctx
| Check resl ->
- let typs, cst = build_subtypes env mp arg_entries_r resl in
- None, typs, cst
+ let typs, ctx = build_subtypes env mp arg_entries_r resl in
+ None, typs, ctx
in
- let () = Global.push_context_set ~strict:true cst in
+ let () = Global.push_context_set ~strict:true ctx in
openmod_info := { cur_typ = res_entry_o; cur_typs = subtyps };
let prefix = Lib.start_module export id mp fs in
Nametab.(push_dir (Until 1) (prefix.obj_dir) (GlobDirRef.DirOpenModule prefix));
@@ -733,37 +765,38 @@ let end_module () =
mp
+(* TODO cleanup push universes directly to global env *)
let declare_module id args res mexpr_o fs =
(* We simulate the beginning of an interactive module,
then we adds the module parameters to the global env. *)
let mp = Global.start_module id in
- let arg_entries_r, cst = intern_args args in
+ let arg_entries_r, ctx = intern_args args in
let params = mk_params_entry arg_entries_r in
let env = Global.env () in
- let env = Environ.push_context_set ~strict:true cst env in
- let mty_entry_o, subs, inl_res, cst' = match res with
+ let env = Environ.push_context_set ~strict:true ctx env in
+ let mty_entry_o, subs, inl_res, ctx' = match res with
| Enforce (mty,ann) ->
let inl = inl2intopt ann in
- let (mte, _, cst) = Modintern.interp_module_ast env Modintern.ModType mty in
- let env = Environ.push_context_set ~strict:true cst env in
+ let (mte, _, ctx) = Modintern.interp_module_ast env Modintern.ModType mty in
+ let env = Environ.push_context_set ~strict:true ctx env in
(* We check immediately that mte is well-formed *)
- let _, _, _, cst' = Mod_typing.translate_mse env None inl mte in
- let cst = Univ.ContextSet.union cst cst' in
- Some mte, [], inl, cst
+ let _, _, _, cst = Mod_typing.translate_mse env None inl mte in
+ let ctx = Univ.ContextSet.add_constraints cst ctx in
+ Some mte, [], inl, ctx
| Check mtys ->
- let typs, cst = build_subtypes env mp arg_entries_r mtys in
- None, typs, default_inline (), cst
+ let typs, ctx = build_subtypes env mp arg_entries_r mtys in
+ None, typs, default_inline (), ctx
in
- let env = Environ.push_context_set ~strict:true cst' env in
- let cst = Univ.ContextSet.union cst cst' in
- let mexpr_entry_o, inl_expr, cst' = match mexpr_o with
+ let env = Environ.push_context_set ~strict:true ctx' env in
+ let ctx = Univ.ContextSet.union ctx ctx' in
+ let mexpr_entry_o, inl_expr, ctx' = match mexpr_o with
| None -> None, default_inline (), Univ.ContextSet.empty
| Some (mexpr,ann) ->
- let (mte, _, cst) = Modintern.interp_module_ast env Modintern.Module mexpr in
- Some mte, inl2intopt ann, cst
+ let (mte, _, ctx) = Modintern.interp_module_ast env Modintern.Module mexpr in
+ Some mte, inl2intopt ann, ctx
in
- let env = Environ.push_context_set ~strict:true cst' env in
- let cst = Univ.ContextSet.union cst cst' in
+ let env = Environ.push_context_set ~strict:true ctx' env in
+ let ctx = Univ.ContextSet.union ctx ctx' in
let entry = match mexpr_entry_o, mty_entry_o with
| None, None -> assert false (* No body, no type ... *)
| None, Some typ -> MType (params, typ)
@@ -782,7 +815,7 @@ let declare_module id args res mexpr_o fs =
| None -> None
| _ -> inl_res
in
- let () = Global.push_context_set ~strict:true cst in
+ let () = Global.push_context_set ~strict:true ctx in
let mp_env,resolver = Global.add_module id entry inl in
(* Name consistency check : kernel vs. library *)
@@ -834,20 +867,20 @@ let declare_modtype id args mtys (mty,ann) fs =
(* We simulate the beginning of an interactive module,
then we adds the module parameters to the global env. *)
let mp = Global.start_modtype id in
- let arg_entries_r, cst = intern_args args in
- let () = Global.push_context_set ~strict:true cst in
+ let arg_entries_r, ctx = intern_args args in
+ let () = Global.push_context_set ~strict:true ctx in
let params = mk_params_entry arg_entries_r in
let env = Global.env () in
- let mte, _, cst = Modintern.interp_module_ast env Modintern.ModType mty in
- let () = Global.push_context_set ~strict:true cst in
+ let mte, _, ctx = Modintern.interp_module_ast env Modintern.ModType mty in
+ let () = Global.push_context_set ~strict:true ctx in
let env = Global.env () in
(* We check immediately that mte is well-formed *)
let _, _, _, cst = Mod_typing.translate_mse env None inl mte in
- let () = Global.push_context_set ~strict:true cst in
+ let () = Global.push_context_set ~strict:true (Univ.LSet.empty,cst) in
let env = Global.env () in
let entry = params, mte in
- let sub_mty_l, cst = build_subtypes env mp arg_entries_r mtys in
- let () = Global.push_context_set ~strict:true cst in
+ let sub_mty_l, ctx = build_subtypes env mp arg_entries_r mtys in
+ let () = Global.push_context_set ~strict:true ctx in
let env = Global.env () in
let sobjs = get_functor_sobjs false env inl entry in
let subst = map_mp (get_module_path (snd entry)) mp empty_delta_resolver in
@@ -1023,12 +1056,12 @@ let end_library ?except ~output_native_objects dir =
cenv,(substitute,keep),ast
let import_modules ~export mpl =
- let _,objs = List.fold_right collect_module_objects mpl (MPset.empty, []) in
- List.iter (open_object 1) objs;
+ let _,objs = List.fold_right collect_module_objects mpl (MPmap.empty, []) in
+ List.iter (fun (f,o) -> open_object f 1 o) objs;
if export then Lib.add_anonymous_entry (Lib.Leaf (ExportObject { mpl }))
-let import_module ~export mp =
- import_modules ~export [mp]
+let import_module f ~export mp =
+ import_modules ~export [f,mp]
(** {6 Iterators} *)
@@ -1073,6 +1106,6 @@ let debug_print_modtab _ =
let mod_ops = {
- Printmod.import_module = import_module;
+ Printmod.import_module = import_module Unfiltered;
process_module_binding = process_module_binding;
}
diff --git a/vernac/declaremods.mli b/vernac/declaremods.mli
index e37299aad6..5e45957e83 100644
--- a/vernac/declaremods.mli
+++ b/vernac/declaremods.mli
@@ -97,11 +97,11 @@ val append_end_library_hook : (unit -> unit) -> unit
or when [mp] corresponds to a functor. If [export] is [true], the module is also
opened every time the module containing it is. *)
-val import_module : export:bool -> ModPath.t -> unit
+val import_module : Libobject.open_filter -> export:bool -> ModPath.t -> unit
(** Same as [import_module] but for multiple modules, and more optimized than
iterating [import_module]. *)
-val import_modules : export:bool -> ModPath.t list -> unit
+val import_modules : export:bool -> (Libobject.open_filter * ModPath.t) list -> unit
(** Include *)
diff --git a/vernac/g_proofs.mlg b/vernac/g_proofs.mlg
index 247f80181a..058fa691ee 100644
--- a/vernac/g_proofs.mlg
+++ b/vernac/g_proofs.mlg
@@ -14,7 +14,6 @@ open Glob_term
open Constrexpr
open Vernacexpr
open Hints
-open Proof_global
open Pcoq
open Pcoq.Prim
@@ -65,12 +64,12 @@ GRAMMAR EXTEND Gram
| IDENT "Existential"; n = natural; c = constr_body ->
{ VernacSolveExistential (n,c) }
| IDENT "Admitted" -> { VernacEndProof Admitted }
- | IDENT "Qed" -> { VernacEndProof (Proved (Opaque,None)) }
+ | IDENT "Qed" -> { VernacEndProof (Proved (Declare.Opaque,None)) }
| IDENT "Save"; id = identref ->
- { VernacEndProof (Proved (Opaque, Some id)) }
- | IDENT "Defined" -> { VernacEndProof (Proved (Transparent,None)) }
+ { VernacEndProof (Proved (Declare.Opaque, Some id)) }
+ | IDENT "Defined" -> { VernacEndProof (Proved (Declare.Transparent,None)) }
| IDENT "Defined"; id=identref ->
- { VernacEndProof (Proved (Transparent,Some id)) }
+ { VernacEndProof (Proved (Declare.Transparent,Some id)) }
| IDENT "Restart" -> { VernacRestart }
| IDENT "Undo" -> { VernacUndo 1 }
| IDENT "Undo"; n = natural -> { VernacUndo n }
diff --git a/vernac/g_vernac.mlg b/vernac/g_vernac.mlg
index a8f1a49086..3cb10364b5 100644
--- a/vernac/g_vernac.mlg
+++ b/vernac/g_vernac.mlg
@@ -68,6 +68,11 @@ let make_bullet s =
let add_control_flag ~loc ~flag { CAst.v = cmd } =
CAst.make ~loc { cmd with control = flag :: cmd.control }
+let test_hash_ident =
+ let open Pcoq.Lookahead in
+ to_entry "test_hash_ident" begin
+ lk_kw "#" >> lk_ident >> check_no_space
+ end
}
GRAMMAR EXTEND Gram
@@ -199,8 +204,8 @@ GRAMMAR EXTEND Gram
VernacAssumption (stre, nl, bl) }
| d = def_token; id = ident_decl; b = def_body ->
{ VernacDefinition (d, name_of_ident_decl id, b) }
- | IDENT "Let"; id = identref; b = def_body ->
- { VernacDefinition ((DoDischarge, Let), (lname_of_lident id, None), b) }
+ | IDENT "Let"; id = ident_decl; b = def_body ->
+ { VernacDefinition ((DoDischarge, Let), name_of_ident_decl id, b) }
(* Gallina inductive declarations *)
| f = finite_token; indl = LIST1 inductive_definition SEP "with" ->
{ VernacInductive (f, indl) }
@@ -226,63 +231,9 @@ GRAMMAR EXTEND Gram
| IDENT "Constraint"; l = LIST1 univ_constraint SEP "," -> { VernacConstraint l }
] ]
;
-
- register_token:
- [ [ r = register_prim_token -> { CPrimitives.OT_op r }
- | r = register_type_token -> { CPrimitives.OT_type r } ] ]
- ;
-
- register_type_token:
- [ [ "#int63_type" -> { CPrimitives.PT_int63 }
- | "#float64_type" -> { CPrimitives.PT_float64 } ] ]
- ;
-
- register_prim_token:
- [ [ "#int63_head0" -> { CPrimitives.Int63head0 }
- | "#int63_tail0" -> { CPrimitives.Int63tail0 }
- | "#int63_add" -> { CPrimitives.Int63add }
- | "#int63_sub" -> { CPrimitives.Int63sub }
- | "#int63_mul" -> { CPrimitives.Int63mul }
- | "#int63_div" -> { CPrimitives.Int63div }
- | "#int63_mod" -> { CPrimitives.Int63mod }
- | "#int63_lsr" -> { CPrimitives.Int63lsr }
- | "#int63_lsl" -> { CPrimitives.Int63lsl }
- | "#int63_land" -> { CPrimitives.Int63land }
- | "#int63_lor" -> { CPrimitives.Int63lor }
- | "#int63_lxor" -> { CPrimitives.Int63lxor }
- | "#int63_addc" -> { CPrimitives.Int63addc }
- | "#int63_subc" -> { CPrimitives.Int63subc }
- | "#int63_addcarryc" -> { CPrimitives.Int63addCarryC }
- | "#int63_subcarryc" -> { CPrimitives.Int63subCarryC }
- | "#int63_mulc" -> { CPrimitives.Int63mulc }
- | "#int63_diveucl" -> { CPrimitives.Int63diveucl }
- | "#int63_div21" -> { CPrimitives.Int63div21 }
- | "#int63_addmuldiv" -> { CPrimitives.Int63addMulDiv }
- | "#int63_eq" -> { CPrimitives.Int63eq }
- | "#int63_lt" -> { CPrimitives.Int63lt }
- | "#int63_le" -> { CPrimitives.Int63le }
- | "#int63_compare" -> { CPrimitives.Int63compare }
- | "#float64_opp" -> { CPrimitives.Float64opp }
- | "#float64_abs" -> { CPrimitives.Float64abs }
- | "#float64_eq" -> { CPrimitives.Float64eq }
- | "#float64_lt" -> { CPrimitives.Float64lt }
- | "#float64_le" -> { CPrimitives.Float64le }
- | "#float64_compare" -> { CPrimitives.Float64compare }
- | "#float64_classify" -> { CPrimitives.Float64classify }
- | "#float64_add" -> { CPrimitives.Float64add }
- | "#float64_sub" -> { CPrimitives.Float64sub }
- | "#float64_mul" -> { CPrimitives.Float64mul }
- | "#float64_div" -> { CPrimitives.Float64div }
- | "#float64_sqrt" -> { CPrimitives.Float64sqrt }
- | "#float64_of_int63" -> { CPrimitives.Float64ofInt63 }
- | "#float64_normfr_mantissa" -> { CPrimitives.Float64normfr_mantissa }
- | "#float64_frshiftexp" -> { CPrimitives.Float64frshiftexp }
- | "#float64_ldshiftexp" -> { CPrimitives.Float64ldshiftexp }
- | "#float64_next_up" -> { CPrimitives.Float64next_up }
- | "#float64_next_down" -> { CPrimitives.Float64next_down }
- ] ]
- ;
-
+ register_token:
+ [ [ test_hash_ident; "#"; r = IDENT -> { CPrimitives.parse_op_or_type ~loc r } ] ]
+ ;
thm_token:
[ [ "Theorem" -> { Theorem }
| IDENT "Lemma" -> { Lemma }
@@ -348,25 +299,11 @@ GRAMMAR EXTEND Gram
(* Simple definitions *)
def_body:
[ [ bl = binders; ":="; red = reduce; c = lconstr ->
- { if List.exists (function CLocalPattern _ -> true | _ -> false) bl
- then
- (* FIXME: "red" will be applied to types in bl and Cast with remain *)
- let c = mkLambdaCN ~loc bl c in
- DefineBody ([], red, c, None)
- else
- (match c with
- | { CAst.v = CCast(c, CastConv t) } -> DefineBody (bl, red, c, Some t)
- | _ -> DefineBody (bl, red, c, None)) }
+ { match c.CAst.v with
+ | CCast(c, Glob_term.CastConv t) -> DefineBody (bl, red, c, Some t)
+ | _ -> DefineBody (bl, red, c, None) }
| bl = binders; ":"; t = lconstr; ":="; red = reduce; c = lconstr ->
- { let ((bl, c), tyo) =
- if List.exists (function CLocalPattern _ -> true | _ -> false) bl
- then
- (* FIXME: "red" will be applied to types in bl and Cast with remain *)
- let c = CAst.make ~loc @@ CCast (c, CastConv t) in
- (([],mkLambdaCN ~loc bl c), None)
- else ((bl, c), Some t)
- in
- DefineBody (bl, red, c, tyo) }
+ { DefineBody (bl, red, c, Some t) }
| bl = binders; ":"; t = lconstr ->
{ ProveBody (bl, t) } ] ]
;
@@ -566,7 +503,6 @@ GRAMMAR EXTEND Gram
{ VernacDeclareModule (export, id, bl, mty) }
(* Section beginning *)
| IDENT "Section"; id = identref -> { VernacBeginSection id }
- | IDENT "Chapter"; id = identref -> { VernacBeginSection id }
(* This end a Section a Module or a Module Type *)
| IDENT "End"; id = identref -> { VernacEndSegment id }
@@ -581,14 +517,21 @@ GRAMMAR EXTEND Gram
| IDENT "From" ; ns = global ; IDENT "Require"; export = export_token
; qidl = LIST1 global ->
{ VernacRequire (Some ns, export, qidl) }
- | IDENT "Import"; qidl = LIST1 global -> { VernacImport (false,qidl) }
- | IDENT "Export"; qidl = LIST1 global -> { VernacImport (true,qidl) }
+ | IDENT "Import"; qidl = LIST1 filtered_import -> { VernacImport (false,qidl) }
+ | IDENT "Export"; qidl = LIST1 filtered_import -> { VernacImport (true,qidl) }
| IDENT "Include"; e = module_type_inl; l = LIST0 ext_module_expr ->
{ VernacInclude(e::l) }
| IDENT "Include"; "Type"; e = module_type_inl; l = LIST0 ext_module_type ->
{ warn_deprecated_include_type ~loc ();
VernacInclude(e::l) } ] ]
;
+ filtered_import:
+ [ [ m = global -> { (m, ImportAll) }
+ | m = global; "("; ns = LIST1 one_import_filter_name SEP ","; ")" -> { (m, ImportNames ns) } ] ]
+ ;
+ one_import_filter_name:
+ [ [ n = global; etc = OPT [ "("; ".."; ")" -> { () } ] -> { n, Option.has_some etc } ] ]
+ ;
export_token:
[ [ IDENT "Import" -> { Some false }
| IDENT "Export" -> { Some true }
@@ -709,17 +652,17 @@ GRAMMAR EXTEND Gram
| IDENT "Canonical"; OPT [ IDENT "Structure" -> {()} ]; qid = global; ud = OPT [ u = OPT univ_decl; d = def_body -> { (u,d) } ] ->
{ match ud with
| None ->
- VernacCanonical CAst.(make ~loc @@ AN qid)
+ VernacCanonical CAst.(make ?loc:qid.CAst.loc @@ AN qid)
| Some (u,d) ->
let s = coerce_reference_to_id qid in
- VernacDefinition ((NoDischarge,CanonicalStructure),((CAst.make (Name s)),u),d) }
+ VernacDefinition ((NoDischarge,CanonicalStructure),((CAst.make ?loc:qid.CAst.loc (Name s)),u),d) }
| IDENT "Canonical"; OPT [ IDENT "Structure" -> {()} ]; ntn = by_notation ->
{ VernacCanonical CAst.(make ~loc @@ ByNotation ntn) }
(* Coercions *)
| IDENT "Coercion"; qid = global; u = OPT univ_decl; d = def_body ->
{ let s = coerce_reference_to_id qid in
- VernacDefinition ((NoDischarge,Coercion),((CAst.make (Name s)),u),d) }
+ VernacDefinition ((NoDischarge,Coercion),((CAst.make ?loc:qid.CAst.loc (Name s)),u),d) }
| IDENT "Identity"; IDENT "Coercion"; f = identref; ":";
s = class_rawexpr; ">->"; t = class_rawexpr ->
{ VernacIdentityCoercion (f, s, t) }
@@ -946,23 +889,23 @@ GRAMMAR EXTEND Gram
| IDENT "Print"; IDENT "Table"; table = option_table ->
{ VernacPrintOption table }
- | IDENT "Add"; table = IDENT; field = IDENT; v = LIST1 option_ref_value
+ | IDENT "Add"; table = IDENT; field = IDENT; v = LIST1 table_value
-> { VernacAddOption ([table;field], v) }
(* A global value below will be hidden by a field above! *)
(* In fact, we give priority to secondary tables *)
(* No syntax for tertiary tables due to conflict *)
(* (but they are unused anyway) *)
- | IDENT "Add"; table = IDENT; v = LIST1 option_ref_value ->
+ | IDENT "Add"; table = IDENT; v = LIST1 table_value ->
{ VernacAddOption ([table], v) }
- | IDENT "Test"; table = option_table; "for"; v = LIST1 option_ref_value
+ | IDENT "Test"; table = option_table; "for"; v = LIST1 table_value
-> { VernacMemOption (table, v) }
| IDENT "Test"; table = option_table ->
{ VernacPrintOption table }
- | IDENT "Remove"; table = IDENT; field = IDENT; v= LIST1 option_ref_value
+ | IDENT "Remove"; table = IDENT; field = IDENT; v= LIST1 table_value
-> { VernacRemoveOption ([table;field], v) }
- | IDENT "Remove"; table = IDENT; v = LIST1 option_ref_value ->
+ | IDENT "Remove"; table = IDENT; v = LIST1 table_value ->
{ VernacRemoveOption ([table], v) } ]]
;
query_command: (* TODO: rapprocher Eval et Check *)
@@ -1055,9 +998,9 @@ GRAMMAR EXTEND Gram
| n = integer -> { OptionSetInt n }
| s = STRING -> { OptionSetString s } ] ]
;
- option_ref_value:
- [ [ id = global -> { QualidRefValue id }
- | s = STRING -> { StringRefValue s } ] ]
+ table_value:
+ [ [ id = global -> { Goptions.QualidRefValue id }
+ | s = STRING -> { Goptions.StringRefValue s } ] ]
;
option_table:
[ [ fl = LIST1 [ x = IDENT -> { x } ] -> { fl } ]]
diff --git a/vernac/himsg.ml b/vernac/himsg.ml
index 5555a2c68e..41f2ab9c63 100644
--- a/vernac/himsg.ml
+++ b/vernac/himsg.ml
@@ -57,16 +57,16 @@ let contract3 env sigma a b c = match contract env sigma [a;b;c] with
let contract4 env sigma a b c d = match contract env sigma [a;b;c;d] with
| env, [a;b;c;d] -> (env,a,b,c),d | _ -> assert false
-let contract1_vect env sigma a v =
- match contract env sigma (a :: Array.to_list v) with
- | env, a::l -> env,a,Array.of_list l
+let contract1 env sigma a v =
+ match contract env sigma (a :: v) with
+ | env, a::l -> env,a,l
| _ -> assert false
let rec contract3' env sigma a b c = function
| OccurCheck (evk,d) ->
let x,d = contract4 env sigma a b c d in x,OccurCheck(evk, d)
| NotClean ((evk,args),env',d) ->
- let env',d,args = contract1_vect env' sigma d args in
+ let env',d,args = contract1 env' sigma d args in
contract3 env sigma a b c,NotClean((evk,args),env',d)
| ConversionFailed (env',t1,t2) ->
let (env',t1,t2) = contract2 env' sigma t1 t2 in
@@ -299,9 +299,9 @@ let explain_unification_error env sigma p1 p2 = function
[str "cannot instantiate " ++ quote (pr_existential_key sigma evk)
++ strbrk " because " ++ pr_leconstr_env env sigma c ++
strbrk " is not in its scope" ++
- (if Array.is_empty args then mt() else
+ (if List.is_empty args then mt() else
strbrk ": available arguments are " ++
- pr_sequence (pr_leconstr_env env sigma) (List.rev (Array.to_list args)))]
+ pr_sequence (pr_leconstr_env env sigma) (List.rev args))]
| NotSameArgSize | NotSameHead | NoCanonicalStructure ->
(* Error speaks from itself *) []
| ConversionFailed (env,t1,t2) ->
@@ -729,9 +729,9 @@ let explain_undeclared_universe env sigma l =
spc () ++ str "(maybe a bugged tactic)."
let explain_disallowed_sprop () =
- Pp.(strbrk "SProp not allowed, you need to "
- ++ str "Set Allow StrictProp"
- ++ strbrk " or to use the -allow-sprop command-line-flag.")
+ Pp.(strbrk "SProp is disallowed because the "
+ ++ str "\"Allow StrictProp\""
+ ++ strbrk " flag is off.")
let explain_bad_relevance env =
strbrk "Bad relevance (maybe a bugged tactic)."
diff --git a/vernac/indschemes.ml b/vernac/indschemes.ml
index 7260b13ff6..356ccef06b 100644
--- a/vernac/indschemes.ml
+++ b/vernac/indschemes.ml
@@ -91,12 +91,11 @@ let () =
optwrite = (fun b -> rewriting_flag := b) }
(* Util *)
-
let define ~poly name sigma c types =
- let f = declare_constant ~kind:Decls.(IsDefinition Scheme) in
let univs = Evd.univ_entry ~poly sigma in
let entry = Declare.definition_entry ~univs ?types c in
- let kn = f ~name (DefinitionEntry entry) in
+ let kind = Decls.(IsDefinition Scheme) in
+ let kn = declare_constant ~kind ~name (DefinitionEntry entry) in
definition_message name;
kn
@@ -143,7 +142,7 @@ let try_declare_scheme what f internal names kn =
| UndefinedCst s ->
alarm what internal
(strbrk "Required constant " ++ str s ++ str " undefined.")
- | AlreadyDeclared (kind, id) as exn ->
+ | DeclareUniv.AlreadyDeclared (kind, id) as exn ->
let msg = CErrors.print exn in
alarm what internal msg
| DecidabilityMutualNotSupported ->
diff --git a/vernac/lemmas.ml b/vernac/lemmas.ml
index e08d2ce117..838496c595 100644
--- a/vernac/lemmas.ml
+++ b/vernac/lemmas.ml
@@ -27,38 +27,34 @@ module Proof_ending = struct
| Regular
| End_obligation of DeclareObl.obligation_qed_info
| End_derive of { f : Id.t; name : Id.t }
- | End_equations of { hook : Constant.t list -> Evd.evar_map -> unit
- ; i : Id.t
- ; types : (Environ.env * Evar.t * Evd.evar_info * EConstr.named_context * Evd.econstr) list
- ; wits : EConstr.t list ref
- (* wits are actually computed by the proof
- engine by side-effect after creating the
- proof! This is due to the start_dependent_proof API *)
- ; sigma : Evd.evar_map
- }
+ | End_equations of
+ { hook : Constant.t list -> Evd.evar_map -> unit
+ ; i : Id.t
+ ; types : (Environ.env * Evar.t * Evd.evar_info * EConstr.named_context * Evd.econstr) list
+ ; sigma : Evd.evar_map
+ }
end
module Info = struct
type t =
- { hook : DeclareDef.Hook.t option
- ; compute_guard : lemma_possible_guards
- ; impargs : Impargs.manual_implicits
+ { hook : Declare.Hook.t option
; proof_ending : Proof_ending.t CEphemeron.key
(* This could be improved and the CEphemeron removed *)
- ; other_thms : DeclareDef.Recthm.t list
- ; scope : DeclareDef.locality
+ ; scope : Declare.locality
; kind : Decls.logical_kind
+ (* thms and compute guard are specific only to start_lemma_with_initialization + regular terminator *)
+ ; thms : Declare.Recthm.t list
+ ; compute_guard : lemma_possible_guards
}
- let make ?hook ?(proof_ending=Proof_ending.Regular) ?(scope=DeclareDef.Global Declare.ImportDefaultBehavior)
+ let make ?hook ?(proof_ending=Proof_ending.Regular) ?(scope=Declare.Global Declare.ImportDefaultBehavior)
?(kind=Decls.(IsProof Lemma)) () =
{ hook
; compute_guard = []
- ; impargs = []
; proof_ending = CEphemeron.create proof_ending
- ; other_thms = []
+ ; thms = []
; scope
; kind
}
@@ -66,14 +62,14 @@ end
(* Proofs with a save constant function *)
type t =
- { proof : Proof_global.t
+ { proof : Declare.Proof.t
; info : Info.t
}
let pf_map f pf = { pf with proof = f pf.proof }
let pf_fold f pf = f pf.proof
-let set_endline_tactic t = pf_map (Proof_global.set_endline_tactic t)
+let set_endline_tactic t = pf_map (Declare.Proof.set_endline_tactic t)
(* To be removed *)
module Internal = struct
@@ -85,7 +81,7 @@ module Internal = struct
end
let by tac pf =
- let proof, res = Pfedit.by tac pf.proof in
+ let proof, res = Declare.by tac pf.proof in
{ pf with proof }, res
(************************************************************************)
@@ -100,27 +96,39 @@ let initialize_named_context_for_proof () =
let d = if Decls.variable_opacity id then NamedDecl.drop_body d else d in
Environ.push_named_context_val d signv) sign Environ.empty_named_context_val
+let add_first_thm ~info ~name ~typ ~impargs =
+ let thms =
+ { Declare.Recthm.name
+ ; impargs
+ ; typ = EConstr.Unsafe.to_constr typ
+ ; args = [] } :: info.Info.thms
+ in
+ { info with Info.thms }
+
(* Starting a goal *)
let start_lemma ~name ~poly
?(udecl=UState.default_univ_decl)
- ?(info=Info.make ())
- sigma c =
+ ?(info=Info.make ()) ?(impargs=[]) sigma c =
(* We remove the bodies of variables in the named context marked
"opaque", this is a hack tho, see #10446 *)
let sign = initialize_named_context_for_proof () in
let goals = [ Global.env_of_context sign , c ] in
- let proof = Proof_global.start_proof sigma ~name ~udecl ~poly goals in
- { proof ; info }
+ let proof = Declare.start_proof sigma ~name ~udecl ~poly goals in
+ let info = add_first_thm ~info ~name ~typ:c ~impargs in
+ { proof; info }
+(* Note that proofs opened by start_dependent lemma cannot be closed
+ by the regular terminators, thus we don't need to update the [thms]
+ field. We will capture this invariant by typing in the future *)
let start_dependent_lemma ~name ~poly
?(udecl=UState.default_univ_decl)
?(info=Info.make ()) telescope =
- let proof = Proof_global.start_dependent_proof ~name ~udecl ~poly telescope in
+ let proof = Declare.start_dependent_proof ~name ~udecl ~poly telescope in
{ proof; info }
let rec_tac_initializer finite guard thms snl =
if finite then
- match List.map (fun { DeclareDef.Recthm.name; typ } -> name, (EConstr.of_constr typ)) thms with
+ match List.map (fun { Declare.Recthm.name; typ } -> name, (EConstr.of_constr typ)) thms with
| (id,_)::l -> Tactics.mutual_cofix id l 0
| _ -> assert false
else
@@ -128,12 +136,12 @@ let rec_tac_initializer finite guard thms snl =
let nl = match snl with
| None -> List.map succ (List.map List.last guard)
| Some nl -> nl
- in match List.map2 (fun { DeclareDef.Recthm.name; typ } n -> (name, n, (EConstr.of_constr typ))) thms nl with
+ in match List.map2 (fun { Declare.Recthm.name; typ } n -> (name, n, (EConstr.of_constr typ))) thms nl with
| (id,n,_)::l -> Tactics.mutual_fix id n l 0
| _ -> assert false
let start_lemma_with_initialization ?hook ~poly ~scope ~kind ~udecl sigma recguard thms snl =
- let intro_tac { DeclareDef.Recthm.args; _ } = Tactics.auto_intros_tac args in
+ let intro_tac { Declare.Recthm.args; _ } = Tactics.auto_intros_tac args in
let init_tac, compute_guard = match recguard with
| Some (finite,guard,init_terms) ->
let rec_tac = rec_tac_initializer finite guard thms snl in
@@ -153,18 +161,19 @@ let start_lemma_with_initialization ?hook ~poly ~scope ~kind ~udecl sigma recgua
intro_tac (List.hd thms), [] in
match thms with
| [] -> CErrors.anomaly (Pp.str "No proof to start.")
- | { DeclareDef.Recthm.name; typ; impargs; _}::other_thms ->
+ | { Declare.Recthm.name; typ; impargs; _} :: thms ->
let info =
Info.{ hook
- ; impargs
; compute_guard
- ; other_thms
; proof_ending = CEphemeron.create Proof_ending.Regular
+ ; thms
; scope
; kind
} in
- let lemma = start_lemma ~name ~poly ~udecl ~info sigma (EConstr.of_constr typ) in
- pf_map (Proof_global.map_proof (fun p ->
+ (* start_lemma has the responsibility to add (name, impargs, typ)
+ to thms, once Info.t is more refined this won't be necessary *)
+ let lemma = start_lemma ~name ~impargs ~poly ~udecl ~info sigma (EConstr.of_constr typ) in
+ pf_map (Declare.Proof.map_proof (fun p ->
pi1 @@ Proof.run_tactic Global.(env ()) init_tac p)) lemma
(************************************************************************)
@@ -179,39 +188,19 @@ module MutualEntry : sig
val declare_variable
: info:Info.t
-> uctx:UState.t
- (* Only for the first constant, introduced by compat *)
- -> ubind:UnivNames.universe_binders
- -> name:Id.t
-> Entries.parameter_entry
-> Names.GlobRef.t list
val declare_mutdef
(* Common to all recthms *)
: info:Info.t
- -> ?fix_exn:(Exninfo.iexn -> Exninfo.iexn)
-> uctx:UState.t
- -> ?hook_data:DeclareDef.Hook.t * UState.t * (Names.Id.t * Constr.t) list
- (* Only for the first constant, introduced by compat *)
- -> ubind:UnivNames.universe_binders
- -> name:Id.t
-> Evd.side_effects Declare.proof_entry
-> Names.GlobRef.t list
end = struct
- (* Body with the fix *)
- type et =
- | NoBody of Entries.parameter_entry
- | Single of Evd.side_effects Declare.proof_entry
- | Mutual of Evd.side_effects Declare.proof_entry
-
- type t =
- { entry : et
- ; info : Info.t
- }
-
- (* XXX: Refactor this with the code in
- [ComFixpoint.declare_fixpoint_generic] *)
+ (* XXX: Refactor this with the code in [Declare.declare_mutdef] *)
let guess_decreasing env possible_indexes ((body, ctx), eff) =
let open Constr in
match Constr.kind body with
@@ -221,74 +210,55 @@ end = struct
(mkFix ((indexes,0),fixdecls), ctx), eff
| _ -> (body, ctx), eff
- let adjust_guardness_conditions ~info const =
- let entry = match info.Info.compute_guard with
- | [] ->
- (* Not a recursive statement *)
- Single const
- | possible_indexes ->
- (* Try all combinations... not optimal *)
- let env = Global.env() in
- let pe = Declare.Internal.map_entry_body const
- ~f:(guess_decreasing env possible_indexes)
- in
- Mutual pe
- in { entry; info }
-
- let rec select_body i t =
+ let select_body i t =
let open Constr in
match Constr.kind t with
| Fix ((nv,0),decls) -> mkFix ((nv,i),decls)
| CoFix (0,decls) -> mkCoFix (i,decls)
- | LetIn(na,t1,ty,t2) -> mkLetIn (na,t1,ty, select_body i t2)
- | Lambda(na,ty,t) -> mkLambda(na,ty, select_body i t)
- | App (t, args) -> mkApp (select_body i t, args)
| _ ->
CErrors.anomaly
Pp.(str "Not a proof by induction: " ++
Termops.Internal.debug_print_constr (EConstr.of_constr t) ++ str ".")
- let declare_mutdef ?fix_exn ~uctx ?hook_data ~ubind ~name ?typ ~impargs ~info mutpe i =
- let { Info.hook; compute_guard; scope; kind; _ } = info in
- match mutpe with
- | NoBody pe ->
- DeclareDef.declare_assumption ?fix_exn ~name ~scope ~hook ~impargs ~uctx pe
- | Single pe ->
- (* We'd like to do [assert (i = 0)] here, however this codepath
- is used when declaring mutual cofixpoints *)
- DeclareDef.declare_definition ~name ~scope ~kind ?hook_data ~ubind ~impargs pe
- | Mutual pe ->
- (* if typ = None , we don't touch the type; used in the base case *)
- let pe =
- match typ with
- | None -> pe
- | Some typ ->
- Declare.Internal.map_entry_type pe ~f:(fun _ -> Some typ)
- in
- let pe = Declare.Internal.map_entry_body pe
- ~f:(fun ((body, ctx), eff) -> (select_body i body, ctx), eff) in
- DeclareDef.declare_definition ~name ~scope ~kind ?hook_data ~ubind ~impargs pe
-
- let declare_mutdef ?fix_exn ~uctx ?hook_data ~ubind ~name { entry; info } =
- (* At some point make this a single iteration *)
- (* At some point make this a single iteration *)
- (* impargs here are special too, fixed in upcoming PRs *)
- let impargs = info.Info.impargs in
- let r = declare_mutdef ?fix_exn ~info ~ubind ?hook_data ~uctx ~name ~impargs entry 0 in
- (* Before we used to do this, check if that's right *)
- let ubind = UnivNames.empty_binders in
- let rs =
- List.map_i (
- fun i { DeclareDef.Recthm.name; typ; impargs } ->
- declare_mutdef ?fix_exn ~name ~info ~ubind ?hook_data ~uctx ~typ ~impargs entry i) 1 info.Info.other_thms
- in r :: rs
-
- let declare_variable ~info ~uctx ~ubind ~name pe =
- declare_mutdef ~uctx ~ubind ~name { entry = NoBody pe; info }
-
- let declare_mutdef ~info ?fix_exn ~uctx ?hook_data ~ubind ~name const =
- let mutpe = adjust_guardness_conditions ~info const in
- declare_mutdef ?fix_exn ~uctx ?hook_data ~ubind ~name mutpe
+ let declare_mutdef ~uctx ~info pe i Declare.Recthm.{ name; impargs; typ; _} =
+ let { Info.hook; scope; kind; compute_guard; _ } = info in
+ (* if i = 0 , we don't touch the type; this is for compat
+ but not clear it is the right thing to do.
+ *)
+ let pe, ubind =
+ if i > 0 && not (CList.is_empty compute_guard)
+ then Declare.Internal.map_entry_type pe ~f:(fun _ -> Some typ), UnivNames.empty_binders
+ else pe, UState.universe_binders uctx
+ in
+ (* We when compute_guard was [] in the previous step we should not
+ substitute the body *)
+ let pe = match compute_guard with
+ | [] -> pe
+ | _ ->
+ Declare.Internal.map_entry_body pe
+ ~f:(fun ((body, ctx), eff) -> (select_body i body, ctx), eff)
+ in
+ Declare.declare_entry ~name ~scope ~kind ?hook ~impargs ~uctx pe
+
+ let declare_mutdef ~info ~uctx const =
+ let pe = match info.Info.compute_guard with
+ | [] ->
+ (* Not a recursive statement *)
+ const
+ | possible_indexes ->
+ (* Try all combinations... not optimal *)
+ let env = Global.env() in
+ Declare.Internal.map_entry_body const
+ ~f:(guess_decreasing env possible_indexes)
+ in
+ List.map_i (declare_mutdef ~info ~uctx pe) 0 info.Info.thms
+
+ let declare_variable ~info ~uctx pe =
+ let { Info.scope; hook } = info in
+ List.map_i (
+ fun i { Declare.Recthm.name; typ; impargs } ->
+ Declare.declare_assumption ~name ~scope ~hook ~impargs ~uctx pe
+ ) 0 info.Info.thms
end
@@ -305,7 +275,7 @@ let get_keep_admitted_vars =
let compute_proof_using_for_admitted proof typ pproofs =
if not (get_keep_admitted_vars ()) then None
- else match Proof_global.get_used_variables proof, pproofs with
+ else match Declare.Proof.get_used_variables proof, pproofs with
| Some _ as x, _ -> x
| None, pproof :: _ ->
let env = Global.env () in
@@ -316,64 +286,41 @@ let compute_proof_using_for_admitted proof typ pproofs =
Some (Environ.really_needed env (Id.Set.union ids_typ ids_def))
| _ -> None
-let finish_admitted ~name ~info ~uctx pe =
- let ubind = UnivNames.empty_binders in
- let _r : Names.GlobRef.t list = MutualEntry.declare_variable ~info ~uctx ~ubind ~name pe in
+let finish_admitted ~info ~uctx pe =
+ let _r : Names.GlobRef.t list = MutualEntry.declare_variable ~info ~uctx pe in
()
let save_lemma_admitted ~(lemma : t) : unit =
- let udecl = Proof_global.get_universe_decl lemma.proof in
- let Proof.{ name; poly; entry } = Proof.data (Proof_global.get_proof lemma.proof) in
+ let udecl = Declare.Proof.get_universe_decl lemma.proof in
+ let Proof.{ poly; entry } = Proof.data (Declare.Proof.get_proof lemma.proof) in
let typ = match Proofview.initial_goals entry with
| [typ] -> snd typ
| _ -> CErrors.anomaly ~label:"Lemmas.save_lemma_admitted" (Pp.str "more than one statement.")
in
let typ = EConstr.Unsafe.to_constr typ in
- let proof = Proof_global.get_proof lemma.proof in
+ let proof = Declare.Proof.get_proof lemma.proof in
let pproofs = Proof.partial_proof proof in
let sec_vars = compute_proof_using_for_admitted lemma.proof typ pproofs in
- let universes = Proof_global.get_initial_euctx lemma.proof in
- let ctx = UState.check_univ_decl ~poly universes udecl in
- finish_admitted ~name ~info:lemma.info ~uctx:universes (sec_vars, (typ, ctx), None)
+ let uctx = Declare.Proof.get_initial_euctx lemma.proof in
+ let univs = UState.check_univ_decl ~poly uctx udecl in
+ finish_admitted ~info:lemma.info ~uctx (sec_vars, (typ, univs), None)
(************************************************************************)
(* Saving a lemma-like constant *)
(************************************************************************)
-let default_thm_id = Id.of_string "Unnamed_thm"
-
-let check_anonymity id save_ident =
- if not (String.equal (Nameops.atompart_of_id id) (Id.to_string (default_thm_id))) then
- CErrors.user_err Pp.(str "This command can only be used for unnamed theorem.")
-
-let finish_proved idopt po info =
- let open Proof_global in
- let { Info.hook } = info in
+let finish_proved po info =
+ let open Declare in
match po with
- | { name; entries=[const]; uctx; udecl } ->
- let name = match idopt with
- | None -> name
- | Some { CAst.v = save_id } -> check_anonymity name save_id; save_id in
- let fix_exn = Declare.Internal.get_fix_exn const in
- let () = try
- let hook_data = Option.map (fun hook -> hook, uctx, []) hook in
- let ubind = UState.universe_binders uctx in
- let _r : Names.GlobRef.t list =
- MutualEntry.declare_mutdef ~info ~fix_exn ~uctx ?hook_data ~ubind ~name const
- in ()
- with e when CErrors.noncritical e ->
- let e = Exninfo.capture e in
- Exninfo.iraise (fix_exn e)
- in ()
+ | { entries=[const]; uctx } ->
+ let _r : Names.GlobRef.t list = MutualEntry.declare_mutdef ~info ~uctx const in
+ ()
| _ ->
CErrors.anomaly ~label:"finish_proved" Pp.(str "close_proof returned more than one proof term")
-let finish_derived ~f ~name ~idopt ~entries =
+let finish_derived ~f ~name ~entries =
(* [f] and [name] correspond to the proof of [f] and of [suchthat], respectively. *)
- if Option.has_some idopt then
- CErrors.user_err Pp.(str "Cannot save a proof of Derive with an explicit name.");
-
let f_def, lemma_def =
match entries with
| [_;f_def;lemma_def] ->
@@ -396,7 +343,7 @@ let finish_derived ~f ~name ~idopt ~entries =
let lemma_pretype typ =
match typ with
| Some t -> Some (substf t)
- | None -> assert false (* Proof_global always sets type here. *)
+ | None -> assert false (* Declare always sets type here. *)
in
(* The references of [f] are subsituted appropriately. *)
let lemma_def = Declare.Internal.map_entry_type lemma_def ~f:lemma_pretype in
@@ -406,11 +353,11 @@ let finish_derived ~f ~name ~idopt ~entries =
let _ : Names.Constant.t = Declare.declare_constant ~name ~kind:Decls.(IsProof Proposition) lemma_def in
()
-let finish_proved_equations lid kind proof_obj hook i types wits sigma0 =
+let finish_proved_equations ~kind ~hook i proof_obj types sigma0 =
let obls = ref 1 in
let sigma, recobls =
- CList.fold_left2_map (fun sigma (wit, (evar_env, ev, evi, local_context, type_)) entry ->
+ CList.fold_left2_map (fun sigma (_evar_env, ev, _evi, local_context, _type) entry ->
let id =
match Evd.evar_ident ev sigma0 with
| Some id -> id
@@ -421,34 +368,51 @@ let finish_proved_equations lid kind proof_obj hook i types wits sigma0 =
let sigma, app = Evarutil.new_global sigma (GlobRef.ConstRef cst) in
let sigma = Evd.define ev (EConstr.applist (app, List.map EConstr.of_constr args)) sigma in
sigma, cst) sigma0
- (CList.combine (List.rev !wits) types) proof_obj.Proof_global.entries
+ types proof_obj.Declare.entries
in
hook recobls sigma
-let finalize_proof idopt proof_obj proof_info =
- let open Proof_global in
+let finalize_proof proof_obj proof_info =
+ let open Declare in
let open Proof_ending in
match CEphemeron.default proof_info.Info.proof_ending Regular with
| Regular ->
- finish_proved idopt proof_obj proof_info
+ finish_proved proof_obj proof_info
| End_obligation oinfo ->
DeclareObl.obligation_terminator proof_obj.entries proof_obj.uctx oinfo
| End_derive { f ; name } ->
- finish_derived ~f ~name ~idopt ~entries:proof_obj.entries
- | End_equations { hook; i; types; wits; sigma } ->
- finish_proved_equations idopt proof_info.Info.kind proof_obj hook i types wits sigma
+ finish_derived ~f ~name ~entries:proof_obj.entries
+ | End_equations { hook; i; types; sigma } ->
+ finish_proved_equations ~kind:proof_info.Info.kind ~hook i proof_obj types sigma
+
+let err_save_forbidden_in_place_of_qed () =
+ CErrors.user_err (Pp.str "Cannot use Save with more than one constant or in this proof mode")
+
+let process_idopt_for_save ~idopt info =
+ match idopt with
+ | None -> info
+ | Some { CAst.v = save_name } ->
+ (* Save foo was used; we override the info in the first theorem *)
+ let thms =
+ match info.Info.thms, CEphemeron.default info.Info.proof_ending Proof_ending.Regular with
+ | [ { Declare.Recthm.name; _} as decl ], Proof_ending.Regular ->
+ [ { decl with Declare.Recthm.name = save_name } ]
+ | _ ->
+ err_save_forbidden_in_place_of_qed ()
+ in { info with Info.thms }
let save_lemma_proved ~lemma ~opaque ~idopt =
(* Env and sigma are just used for error printing in save_remaining_recthms *)
- let proof_obj = Proof_global.close_proof ~opaque ~keep_body_ucst_separate:false (fun x -> x) lemma.proof in
- finalize_proof idopt proof_obj lemma.info
+ let proof_obj = Declare.close_proof ~opaque ~keep_body_ucst_separate:false lemma.proof in
+ let proof_info = process_idopt_for_save ~idopt lemma.info in
+ finalize_proof proof_obj proof_info
(***********************************************************************)
(* Special case to close a lemma without forcing a proof *)
(***********************************************************************)
let save_lemma_admitted_delayed ~proof ~info =
- let open Proof_global in
- let { name; entries; uctx; udecl } = proof in
+ let open Declare in
+ let { entries; uctx } = proof in
if List.length entries <> 1 then
CErrors.user_err Pp.(str "Admitted does not support multiple statements");
let { Declare.proof_entry_secctx; proof_entry_type; proof_entry_universes } = List.hd entries in
@@ -460,6 +424,14 @@ let save_lemma_admitted_delayed ~proof ~info =
| Some typ -> typ in
let ctx = UState.univ_entry ~poly uctx in
let sec_vars = if get_keep_admitted_vars () then proof_entry_secctx else None in
- finish_admitted ~name ~uctx ~info (sec_vars, (typ, ctx), None)
-
-let save_lemma_proved_delayed ~proof ~info ~idopt = finalize_proof idopt proof info
+ finish_admitted ~uctx ~info (sec_vars, (typ, ctx), None)
+
+let save_lemma_proved_delayed ~proof ~info ~idopt =
+ (* vio2vo calls this but with invalid info, we have to workaround
+ that to add the name to the info structure *)
+ if CList.is_empty info.Info.thms then
+ let info = add_first_thm ~info ~name:proof.Declare.name ~typ:EConstr.mkSet ~impargs:[] in
+ finalize_proof proof info
+ else
+ let info = process_idopt_for_save ~idopt info in
+ finalize_proof proof info
diff --git a/vernac/lemmas.mli b/vernac/lemmas.mli
index 6a1f8c09f3..b1462f1ce5 100644
--- a/vernac/lemmas.mli
+++ b/vernac/lemmas.mli
@@ -19,10 +19,10 @@ type t
val set_endline_tactic : Genarg.glob_generic_argument -> t -> t
(** [set_endline_tactic tac lemma] set ending tactic for [lemma] *)
-val pf_map : (Proof_global.t -> Proof_global.t) -> t -> t
+val pf_map : (Declare.Proof.t -> Declare.Proof.t) -> t -> t
(** [pf_map f l] map the underlying proof object *)
-val pf_fold : (Proof_global.t -> 'a) -> t -> 'a
+val pf_fold : (Declare.Proof.t -> 'a) -> t -> 'a
(** [pf_fold f l] fold over the underlying proof object *)
val by : unit Proofview.tactic -> t -> t * bool
@@ -35,12 +35,12 @@ module Proof_ending : sig
| Regular
| End_obligation of DeclareObl.obligation_qed_info
| End_derive of { f : Id.t; name : Id.t }
- | End_equations of { hook : Constant.t list -> Evd.evar_map -> unit
- ; i : Id.t
- ; types : (Environ.env * Evar.t * Evd.evar_info * EConstr.named_context * Evd.econstr) list
- ; wits : EConstr.t list ref
- ; sigma : Evd.evar_map
- }
+ | End_equations of
+ { hook : Constant.t list -> Evd.evar_map -> unit
+ ; i : Id.t
+ ; types : (Environ.env * Evar.t * Evd.evar_info * EConstr.named_context * Evd.econstr) list
+ ; sigma : Evd.evar_map
+ }
end
@@ -49,11 +49,11 @@ module Info : sig
type t
val make
- : ?hook: DeclareDef.Hook.t
+ : ?hook: Declare.Hook.t
(** Callback to be executed at the end of the proof *)
-> ?proof_ending : Proof_ending.t
(** Info for special constants *)
- -> ?scope : DeclareDef.locality
+ -> ?scope : Declare.locality
(** locality *)
-> ?kind:Decls.logical_kind
(** Theorem, etc... *)
@@ -68,6 +68,7 @@ val start_lemma
-> poly:bool
-> ?udecl:UState.universe_decl
-> ?info:Info.t
+ -> ?impargs:Impargs.manual_implicits
-> Evd.evar_map
-> EConstr.types
-> t
@@ -84,39 +85,37 @@ type lemma_possible_guards = int list list
(** Pretty much internal, used by the Lemma / Fixpoint vernaculars *)
val start_lemma_with_initialization
- : ?hook:DeclareDef.Hook.t
+ : ?hook:Declare.Hook.t
-> poly:bool
- -> scope:DeclareDef.locality
+ -> scope:Declare.locality
-> kind:Decls.logical_kind
-> udecl:UState.universe_decl
-> Evd.evar_map
-> (bool * lemma_possible_guards * Constr.t option list option) option
- -> DeclareDef.Recthm.t list
+ -> Declare.Recthm.t list
-> int list option
-> t
-val default_thm_id : Names.Id.t
-
(** {4 Saving proofs} *)
val save_lemma_admitted : lemma:t -> unit
val save_lemma_proved
: lemma:t
- -> opaque:Proof_global.opacity_flag
+ -> opaque:Declare.opacity_flag
-> idopt:Names.lident option
-> unit
(** To be removed, don't use! *)
module Internal : sig
val get_info : t -> Info.t
- (** Only needed due to the Proof_global compatibility layer. *)
+ (** Only needed due to the Declare compatibility layer. *)
end
(** Special cases for delayed proofs, in this case we must provide the
proof information so the proof won't be forced. *)
-val save_lemma_admitted_delayed : proof:Proof_global.proof_object -> info:Info.t -> unit
+val save_lemma_admitted_delayed : proof:Declare.proof_object -> info:Info.t -> unit
val save_lemma_proved_delayed
- : proof:Proof_global.proof_object
+ : proof:Declare.proof_object
-> info:Info.t
-> idopt:Names.lident option
-> unit
diff --git a/vernac/library.ml b/vernac/library.ml
index 7c629b08e7..85db501e84 100644
--- a/vernac/library.ml
+++ b/vernac/library.ml
@@ -20,11 +20,11 @@ open Libobject
(*s Low-level interning/externing of libraries to files *)
let raw_extern_library f =
- System.raw_extern_state Coq_config.vo_magic_number f
+ ObjFile.open_out ~file:f
let raw_intern_library f =
System.with_magic_number_check
- (System.raw_intern_state Coq_config.vo_magic_number) f
+ (fun file -> ObjFile.open_in ~file) f
(************************************************************************)
(** Serialized objects loaded on-the-fly *)
@@ -35,7 +35,7 @@ module Delayed :
sig
type 'a delayed
-val in_delayed : string -> in_channel -> 'a delayed * Digest.t
+val in_delayed : string -> ObjFile.in_handle -> segment:string -> 'a delayed * Digest.t
val fetch_delayed : 'a delayed -> 'a
end =
@@ -43,28 +43,32 @@ struct
type 'a delayed = {
del_file : string;
- del_off : int;
+ del_off : int64;
del_digest : Digest.t;
}
-let in_delayed f ch =
- let pos = pos_in ch in
- let _, digest = System.skip_in_segment f ch in
- ({ del_file = f; del_digest = digest; del_off = pos; }, digest)
+let in_delayed f ch ~segment =
+ let seg = ObjFile.get_segment ch ~segment in
+ let digest = seg.ObjFile.hash in
+ { del_file = f; del_digest = digest; del_off = seg.ObjFile.pos; }, digest
(** Fetching a table of opaque terms at position [pos] in file [f],
expecting to find first a copy of [digest]. *)
let fetch_delayed del =
let { del_digest = digest; del_file = f; del_off = pos; } = del in
- try
- let ch = raw_intern_library f in
- let () = seek_in ch pos in
- let obj, _, digest' = System.marshal_in_segment f ch in
- let () = close_in ch in
- if not (String.equal digest digest') then raise (Faulty f);
- obj
- with e when CErrors.noncritical e -> raise (Faulty f)
+ let ch = open_in_bin f in
+ let obj, digest' =
+ try
+ let () = LargeFile.seek_in ch pos in
+ let obj = System.marshal_in f ch in
+ let digest' = Digest.input ch in
+ obj, digest'
+ with e -> close_in ch; raise e
+ in
+ close_in ch;
+ if not (String.equal digest digest') then raise (Faulty f);
+ obj
end
@@ -92,7 +96,7 @@ type summary_disk = {
type library_t = {
library_name : compilation_unit_name;
- library_data : library_disk delayed;
+ library_data : library_disk;
library_deps : (compilation_unit_name * Safe_typing.vodigest) array;
library_digests : Safe_typing.vodigest;
library_extra_univs : Univ.ContextSet.t;
@@ -155,11 +159,12 @@ let register_loaded_library m =
let prefix = Nativecode.mod_uid_of_dirpath libname ^ "." in
let f = prefix ^ "cmo" in
let f = Dynlink.adapt_filename f in
- if Coq_config.native_compiler then
- Nativelib.link_library (Global.env()) ~prefix ~dirname ~basename:f
+ Nativelib.link_library (Global.env()) ~prefix ~dirname ~basename:f
in
let rec aux = function
- | [] -> link (); [libname]
+ | [] ->
+ let () = if Flags.get_native_compiler () then link () in
+ [libname]
| m'::_ as l when DirPath.equal m' libname -> l
| m'::l' -> m' :: aux l' in
libraries_loaded_list := aux !libraries_loaded_list;
@@ -199,7 +204,7 @@ let access_table what tables dp i =
with Faulty f ->
user_err ~hdr:"Library.access_table"
(str "The file " ++ str f ++ str " (bound to " ++ str dir_path ++
- str ") is inaccessible or corrupted,\ncannot load some " ++
+ str ") is corrupted,\ncannot load some " ++
str what ++ str " in it.\n")
in
tables := DPmap.add dp (Fetched t) !tables;
@@ -241,12 +246,11 @@ let mk_summary m = {
let intern_from_file f =
let ch = raw_intern_library f in
- let (lsd : seg_sum), _, digest_lsd = System.marshal_in_segment f ch in
- let ((lmd : seg_lib delayed), digest_lmd) = in_delayed f ch in
- let (univs : seg_univ option), _, digest_u = System.marshal_in_segment f ch in
- let _ = System.skip_in_segment f ch in
- let ((del_opaque : seg_proofs delayed),_) = in_delayed f ch in
- close_in ch;
+ let (lsd : seg_sum), digest_lsd = ObjFile.marshal_in_segment ch ~segment:"summary" in
+ let ((lmd : seg_lib), digest_lmd) = ObjFile.marshal_in_segment ch ~segment:"library" in
+ let (univs : seg_univ option), digest_u = ObjFile.marshal_in_segment ch ~segment:"universes" in
+ let ((del_opaque : seg_proofs delayed),_) = in_delayed f ch ~segment:"opaques" in
+ ObjFile.close_in ch;
register_library_filename lsd.md_name f;
add_opaque_table lsd.md_name (ToFetch del_opaque);
let open Safe_typing in
@@ -296,7 +300,7 @@ let rec_intern_library ~lib_resolver libs (dir, f) =
let native_name_from_filename f =
let ch = raw_intern_library f in
- let (lmd : seg_sum), pos, digest_lmd = System.marshal_in_segment f ch in
+ let (lmd : seg_sum), digest_lmd = ObjFile.marshal_in_segment ch ~segment:"summary" in
Nativecode.mod_uid_of_dirpath lmd.md_name
(**********************************************************************)
@@ -317,7 +321,7 @@ let native_name_from_filename f =
*)
let register_library m =
- let l = fetch_delayed m.library_data in
+ let l = m.library_data in
Declaremods.register_library
m.library_name
l.md_compiled
@@ -334,7 +338,11 @@ let load_require _ (_,(needed,modl,_)) =
List.iter register_library needed
let open_require i (_,(_,modl,export)) =
- Option.iter (fun export -> Declaremods.import_modules ~export @@ List.map (fun m -> MPfile m) modl) export
+ Option.iter (fun export ->
+ let mpl = List.map (fun m -> Unfiltered, MPfile m) modl in
+ (* TODO support filters in Require *)
+ Declaremods.import_modules ~export mpl)
+ export
(* [needed] is the ordered list of libraries not already loaded *)
let cache_require o =
@@ -369,16 +377,17 @@ let require_library_from_dirpath ~lib_resolver modrefl export =
let needed, contents = List.fold_left (rec_intern_library ~lib_resolver) ([], DPmap.empty) modrefl in
let needed = List.rev_map (fun dir -> DPmap.find dir contents) needed in
let modrefl = List.map fst modrefl in
- if Lib.is_module_or_modtype () then
- begin
- warn_require_in_module ();
- add_anonymous_leaf (in_require (needed,modrefl,None));
- Option.iter (fun export ->
- List.iter (fun m -> Declaremods.import_module ~export (MPfile m)) modrefl)
- export
- end
- else
- add_anonymous_leaf (in_require (needed,modrefl,export));
+ if Lib.is_module_or_modtype () then
+ begin
+ warn_require_in_module ();
+ add_anonymous_leaf (in_require (needed,modrefl,None));
+ Option.iter (fun export ->
+ (* TODO import filters *)
+ List.iter (fun m -> Declaremods.import_module Unfiltered ~export (MPfile m)) modrefl)
+ export
+ end
+ else
+ add_anonymous_leaf (in_require (needed,modrefl,export));
()
(************************************************************************)
@@ -386,12 +395,12 @@ let require_library_from_dirpath ~lib_resolver modrefl export =
let load_library_todo f =
let ch = raw_intern_library f in
- let (s0 : seg_sum), _, _ = System.marshal_in_segment f ch in
- let (s1 : seg_lib), _, _ = System.marshal_in_segment f ch in
- let (s2 : seg_univ option), _, _ = System.marshal_in_segment f ch in
- let tasks, _, _ = System.marshal_in_segment f ch in
- let (s4 : seg_proofs), _, _ = System.marshal_in_segment f ch in
- close_in ch;
+ let (s0 : seg_sum), _ = ObjFile.marshal_in_segment ch ~segment:"summary" in
+ let (s1 : seg_lib), _ = ObjFile.marshal_in_segment ch ~segment:"library" in
+ let (s2 : seg_univ option), _ = ObjFile.marshal_in_segment ch ~segment:"universes" in
+ let tasks, _ = ObjFile.marshal_in_segment ch ~segment:"tasks" in
+ let (s4 : seg_proofs), _ = ObjFile.marshal_in_segment ch ~segment:"opaques" in
+ ObjFile.close_in ch;
if tasks = None then user_err ~hdr:"restart" (str"not a .vio file");
if s2 = None then user_err ~hdr:"restart" (str"not a .vio file");
if snd (Option.get s2) then user_err ~hdr:"restart" (str"not a .vio file");
@@ -427,15 +436,15 @@ let error_recursively_dependent_library dir =
let save_library_base f sum lib univs tasks proofs =
let ch = raw_extern_library f in
try
- System.marshal_out_segment f ch (sum : seg_sum);
- System.marshal_out_segment f ch (lib : seg_lib);
- System.marshal_out_segment f ch (univs : seg_univ option);
- System.marshal_out_segment f ch (tasks : 'tasks option);
- System.marshal_out_segment f ch (proofs : seg_proofs);
- close_out ch
+ ObjFile.marshal_out_segment ch ~segment:"summary" (sum : seg_sum);
+ ObjFile.marshal_out_segment ch ~segment:"library" (lib : seg_lib);
+ ObjFile.marshal_out_segment ch ~segment:"universes" (univs : seg_univ option);
+ ObjFile.marshal_out_segment ch ~segment:"tasks" (tasks : 'tasks option);
+ ObjFile.marshal_out_segment ch ~segment:"opaques" (proofs : seg_proofs);
+ ObjFile.close_out ch
with reraise ->
let reraise = Exninfo.capture reraise in
- close_out ch;
+ ObjFile.close_out ch;
Feedback.msg_warning (str "Removed file " ++ str f);
Sys.remove f;
Exninfo.iraise reraise
diff --git a/vernac/locality.ml b/vernac/locality.ml
index 9e784c8bb3..f62eed5e41 100644
--- a/vernac/locality.ml
+++ b/vernac/locality.ml
@@ -34,7 +34,7 @@ let warn_local_declaration =
strbrk "available without qualification when imported.")
let enforce_locality_exp locality_flag discharge =
- let open DeclareDef in
+ let open Declare in
let open Vernacexpr in
match locality_flag, discharge with
| Some b, NoDischarge -> Global (importability_of_bool b)
diff --git a/vernac/locality.mli b/vernac/locality.mli
index 26149cb394..bf65579efd 100644
--- a/vernac/locality.mli
+++ b/vernac/locality.mli
@@ -20,7 +20,7 @@
val make_locality : bool option -> bool
val make_non_locality : bool option -> bool
-val enforce_locality_exp : bool option -> Vernacexpr.discharge -> DeclareDef.locality
+val enforce_locality_exp : bool option -> Vernacexpr.discharge -> Declare.locality
val enforce_locality : bool option -> bool
(** For commands whose default is to not discharge but to export:
diff --git a/vernac/metasyntax.ml b/vernac/metasyntax.ml
index 475d5c31f7..3b9c771b93 100644
--- a/vernac/metasyntax.ml
+++ b/vernac/metasyntax.ml
@@ -877,9 +877,12 @@ let subst_syntax_extension (subst, (local, (pa_sy,pp_sy))) =
let classify_syntax_definition (local, _ as o) =
if local then Dispose else Substitute o
+let open_syntax_extension i o =
+ if Int.equal i 1 then cache_syntax_extension o
+
let inSyntaxExtension : syntax_extension_obj -> obj =
declare_object {(default_object "SYNTAX-EXTENSION") with
- open_function = (fun i o -> if Int.equal i 1 then cache_syntax_extension o);
+ open_function = simple_open open_syntax_extension;
cache_function = cache_syntax_extension;
subst_function = subst_syntax_extension;
classify_function = classify_syntax_definition}
@@ -1454,7 +1457,7 @@ let classify_notation nobj =
let inNotation : notation_obj -> obj =
declare_object {(default_object "NOTATION") with
- open_function = open_notation;
+ open_function = simple_open open_notation;
cache_function = cache_notation;
subst_function = subst_notation;
load_function = load_notation;
@@ -1765,7 +1768,7 @@ let classify_scope_command (local, _, _ as o) =
let inScopeCommand : locality_flag * scope_name * scope_command -> obj =
declare_object {(default_object "DELIMITERS") with
cache_function = cache_scope_command;
- open_function = open_scope_command;
+ open_function = simple_open open_scope_command;
load_function = load_scope_command;
subst_function = subst_scope_command;
classify_function = classify_scope_command}
@@ -1831,7 +1834,7 @@ let classify_custom_entry (local,s as o) =
let inCustomEntry : locality_flag * string -> obj =
declare_object {(default_object "CUSTOM-ENTRIES") with
cache_function = cache_custom_entry;
- open_function = open_custom_entry;
+ open_function = simple_open open_custom_entry;
load_function = load_custom_entry;
subst_function = subst_custom_entry;
classify_function = classify_custom_entry}
diff --git a/vernac/obligations.ml b/vernac/obligations.ml
index a29ba44907..5e746afc74 100644
--- a/vernac/obligations.ml
+++ b/vernac/obligations.ml
@@ -10,252 +10,16 @@
open Printf
-(**
- - Get types of existentials ;
- - Flatten dependency tree (prefix order) ;
- - Replace existentials by de Bruijn indices in term, applied to the right arguments ;
- - Apply term prefixed by quantification on "existentials".
-*)
-
-open Constr
open Names
open Pp
open CErrors
open Util
-module NamedDecl = Context.Named.Declaration
-
(* For the records fields, opens should go away one these types are private *)
open DeclareObl
open DeclareObl.Obligation
open DeclareObl.ProgramDecl
-let succfix (depth, fixrels) =
- (succ depth, List.map succ fixrels)
-
-let check_evars env evm =
- Evar.Map.iter
- (fun key evi ->
- if Evd.is_obligation_evar evm key then ()
- else
- let (loc,k) = Evd.evar_source key evm in
- Pretype_errors.error_unsolvable_implicit ?loc env evm key None)
- (Evd.undefined_map evm)
-
-type oblinfo =
- { ev_name: int * Id.t;
- ev_hyps: EConstr.named_context;
- ev_status: bool * Evar_kinds.obligation_definition_status;
- ev_chop: int option;
- ev_src: Evar_kinds.t Loc.located;
- ev_typ: types;
- ev_tac: unit Proofview.tactic option;
- ev_deps: Int.Set.t }
-
-(** Substitute evar references in t using de Bruijn indices,
- where n binders were passed through. *)
-
-let subst_evar_constr evm evs n idf t =
- let seen = ref Int.Set.empty in
- let transparent = ref Id.Set.empty in
- let evar_info id = List.assoc_f Evar.equal id evs in
- let rec substrec (depth, fixrels) c = match EConstr.kind evm c with
- | Evar (k, args) ->
- let { ev_name = (id, idstr) ;
- ev_hyps = hyps ; ev_chop = chop } =
- try evar_info k
- with Not_found ->
- anomaly ~label:"eterm" (Pp.str "existential variable " ++ int (Evar.repr k) ++ str " not found.")
- in
- seen := Int.Set.add id !seen;
- (* Evar arguments are created in inverse order,
- and we must not apply to defined ones (i.e. LetIn's)
- *)
- let args =
- let n = match chop with None -> 0 | Some c -> c in
- let (l, r) = List.chop n (List.rev (Array.to_list args)) in
- List.rev r
- in
- let args =
- let rec aux hyps args acc =
- let open Context.Named.Declaration in
- match hyps, args with
- (LocalAssum _ :: tlh), (c :: tla) ->
- aux tlh tla ((substrec (depth, fixrels) c) :: acc)
- | (LocalDef _ :: tlh), (_ :: tla) ->
- aux tlh tla acc
- | [], [] -> acc
- | _, _ -> acc (*failwith "subst_evars: invalid argument"*)
- in aux hyps args []
- in
- if List.exists
- (fun x -> match EConstr.kind evm x with
- | Rel n -> Int.List.mem n fixrels
- | _ -> false) args
- then
- transparent := Id.Set.add idstr !transparent;
- EConstr.mkApp (idf idstr, Array.of_list args)
- | Fix _ ->
- EConstr.map_with_binders evm succfix substrec (depth, 1 :: fixrels) c
- | _ -> EConstr.map_with_binders evm succfix substrec (depth, fixrels) c
- in
- let t' = substrec (0, []) t in
- EConstr.to_constr evm t', !seen, !transparent
-
-
-(** Substitute variable references in t using de Bruijn indices,
- where n binders were passed through. *)
-let subst_vars acc n t =
- let var_index id = Util.List.index Id.equal id acc in
- let rec substrec depth c = match Constr.kind c with
- | Var v -> (try mkRel (depth + (var_index v)) with Not_found -> c)
- | _ -> Constr.map_with_binders succ substrec depth c
- in
- substrec 0 t
-
-(** Rewrite type of an evar ([ H1 : t1, ... Hn : tn |- concl ])
- to a product : forall H1 : t1, ..., forall Hn : tn, concl.
- Changes evars and hypothesis references to variable references.
-*)
-let etype_of_evar evm evs hyps concl =
- let open Context.Named.Declaration in
- let rec aux acc n = function
- decl :: tl ->
- let t', s, trans = subst_evar_constr evm evs n EConstr.mkVar (NamedDecl.get_type decl) in
- let t'' = subst_vars acc 0 t' in
- let rest, s', trans' = aux (NamedDecl.get_id decl :: acc) (succ n) tl in
- let s' = Int.Set.union s s' in
- let trans' = Id.Set.union trans trans' in
- (match decl with
- | LocalDef (id,c,_) ->
- let c', s'', trans'' = subst_evar_constr evm evs n EConstr.mkVar c in
- let c' = subst_vars acc 0 c' in
- Term.mkNamedProd_or_LetIn (LocalDef (id, c', t'')) rest,
- Int.Set.union s'' s',
- Id.Set.union trans'' trans'
- | LocalAssum (id,_) ->
- Term.mkNamedProd_or_LetIn (LocalAssum (id, t'')) rest, s', trans')
- | [] ->
- let t', s, trans = subst_evar_constr evm evs n EConstr.mkVar concl in
- subst_vars acc 0 t', s, trans
- in aux [] 0 (List.rev hyps)
-
-let trunc_named_context n ctx =
- let len = List.length ctx in
- List.firstn (len - n) ctx
-
-let rec chop_product n t =
- let pop t = Vars.lift (-1) t in
- if Int.equal n 0 then Some t
- else
- match Constr.kind t with
- | Prod (_, _, b) -> if Vars.noccurn 1 b then chop_product (pred n) (pop b) else None
- | _ -> None
-
-let evar_dependencies evm oev =
- let one_step deps =
- Evar.Set.fold (fun ev s ->
- let evi = Evd.find evm ev in
- let deps' = Evd.evars_of_filtered_evar_info evm evi in
- if Evar.Set.mem oev deps' then
- invalid_arg ("Ill-formed evar map: cycle detected for evar " ^ Pp.string_of_ppcmds @@ Evar.print oev)
- else Evar.Set.union deps' s)
- deps deps
- in
- let rec aux deps =
- let deps' = one_step deps in
- if Evar.Set.equal deps deps' then deps
- else aux deps'
- in aux (Evar.Set.singleton oev)
-
-let move_after (id, ev, deps as obl) l =
- let rec aux restdeps = function
- | (id', _, _) as obl' :: tl ->
- let restdeps' = Evar.Set.remove id' restdeps in
- if Evar.Set.is_empty restdeps' then
- obl' :: obl :: tl
- else obl' :: aux restdeps' tl
- | [] -> [obl]
- in aux (Evar.Set.remove id deps) l
-
-let sort_dependencies evl =
- let rec aux l found list =
- match l with
- | (id, ev, deps) as obl :: tl ->
- let found' = Evar.Set.union found (Evar.Set.singleton id) in
- if Evar.Set.subset deps found' then
- aux tl found' (obl :: list)
- else aux (move_after obl tl) found list
- | [] -> List.rev list
- in aux evl Evar.Set.empty []
-
-let eterm_obligations env name evm fs ?status t ty =
- (* 'Serialize' the evars *)
- let nc = Environ.named_context env in
- let nc_len = Context.Named.length nc in
- let evm = Evarutil.nf_evar_map_undefined evm in
- let evl = Evarutil.non_instantiated evm in
- let evl = Evar.Map.bindings evl in
- let evl = List.map (fun (id, ev) -> (id, ev, evar_dependencies evm id)) evl in
- let sevl = sort_dependencies evl in
- let evl = List.map (fun (id, ev, _) -> id, ev) sevl in
- let evn =
- let i = ref (-1) in
- List.rev_map (fun (id, ev) -> incr i;
- (id, (!i, Id.of_string
- (Id.to_string name ^ "_obligation_" ^ string_of_int (succ !i))),
- ev)) evl
- in
- let evts =
- (* Remove existential variables in types and build the corresponding products *)
- List.fold_right
- (fun (id, (n, nstr), ev) l ->
- let hyps = Evd.evar_filtered_context ev in
- let hyps = trunc_named_context nc_len hyps in
- let evtyp, deps, transp = etype_of_evar evm l hyps ev.Evd.evar_concl in
- let evtyp, hyps, chop =
- match chop_product fs evtyp with
- | Some t -> t, trunc_named_context fs hyps, fs
- | None -> evtyp, hyps, 0
- in
- let loc, k = Evd.evar_source id evm in
- let status = match k with
- | Evar_kinds.QuestionMark { Evar_kinds.qm_obligation=o } -> o
- | _ -> match status with
- | Some o -> o
- | None -> Evar_kinds.Define (not (Program.get_proofs_transparency ()))
- in
- let force_status, status, chop = match status with
- | Evar_kinds.Define true as stat ->
- if not (Int.equal chop fs) then true, Evar_kinds.Define false, None
- else false, stat, Some chop
- | s -> false, s, None
- in
- let info = { ev_name = (n, nstr);
- ev_hyps = hyps; ev_status = force_status, status; ev_chop = chop;
- ev_src = loc, k; ev_typ = evtyp ; ev_deps = deps; ev_tac = None }
- in (id, info) :: l)
- evn []
- in
- let t', _, transparent = (* Substitute evar refs in the term by variables *)
- subst_evar_constr evm evts 0 EConstr.mkVar t
- in
- let ty, _, _ = subst_evar_constr evm evts 0 EConstr.mkVar ty in
- let evars =
- List.map (fun (ev, info) ->
- let { ev_name = (_, name); ev_status = force_status, status;
- ev_src = src; ev_typ = typ; ev_deps = deps; ev_tac = tac } = info
- in
- let force_status, status = match status with
- | Evar_kinds.Define true when Id.Set.mem name transparent ->
- true, Evar_kinds.Define false
- | _ -> force_status, status
- in name, typ, src, (force_status, status), deps, tac) evts
- in
- let evnames = List.map (fun (ev, info) -> ev, snd info.ev_name) evts in
- let evmap f c = pi1 (subst_evar_constr evm evts 0 f c) in
- Array.of_list (List.rev evars), (evnames, evmap), t', ty
-
let pperror cmd = CErrors.user_err ~hdr:"Program" cmd
let error s = pperror (str s)
@@ -270,11 +34,6 @@ let explain_no_obligations = function
Some ident -> str "No obligations for program " ++ Id.print ident
| None -> str "No obligations remaining"
-type obligation_info =
- (Names.Id.t * types * Evar_kinds.t Loc.located *
- (bool * Evar_kinds.obligation_definition_status)
- * Int.Set.t * unit Proofview.tactic option) array
-
let assumption_message = Declare.assumption_message
let default_tactic = ref (Proofview.tclUNIT ())
@@ -374,8 +133,8 @@ let solve_by_tac ?loc name evi t poly uctx =
try
(* the status is dropped. *)
let env = Global.env () in
- let body, types, _, uctx =
- Pfedit.build_by_tactic env ~uctx ~poly ~typ:evi.evar_concl t in
+ let body, types, _univs, _, uctx =
+ Declare.build_by_tactic env ~uctx ~poly ~typ:evi.evar_concl t in
Inductiveops.control_only_guard env (Evd.from_ctx uctx) (EConstr.of_constr body);
Some (body, types, uctx)
with
@@ -403,13 +162,13 @@ let rec solve_obligation prg num tac =
++ str (string_of_list ", " (fun x -> string_of_int (succ x)) remaining));
in
let obl = subst_deps_obl obls obl in
- let scope = DeclareDef.(Global Declare.ImportNeedQualified) in
+ let scope = Declare.(Global Declare.ImportNeedQualified) in
let kind = kind_of_obligation (snd obl.obl_status) in
let evd = Evd.from_ctx prg.prg_ctx in
let evd = Evd.update_sigma_env evd (Global.env ()) in
let auto n oblset tac = auto_solve_obligations n ~oblset tac in
let proof_ending = Lemmas.Proof_ending.End_obligation (DeclareObl.{name = prg.prg_name; num; auto}) in
- let hook = DeclareDef.Hook.make (DeclareObl.obligation_hook prg obl num auto) in
+ let hook = Declare.Hook.make (DeclareObl.obligation_hook prg obl num auto) in
let info = Lemmas.Info.make ~hook ~proof_ending ~scope ~kind () in
let poly = prg.prg_poly in
let lemma = Lemmas.start_lemma ~name:obl.obl_name ~poly ~info evd (EConstr.of_constr obl.obl_type) in
@@ -550,7 +309,7 @@ let show_term n =
++ Printer.pr_constr_env env sigma prg.prg_body)
let add_definition ~name ?term t ~uctx ?(udecl=UState.default_univ_decl)
- ?(impargs=[]) ~poly ?(scope=DeclareDef.Global Declare.ImportDefaultBehavior) ?(kind=Decls.Definition) ?tactic
+ ?(impargs=[]) ~poly ?(scope=Declare.Global Declare.ImportDefaultBehavior) ?(kind=Decls.Definition) ?tactic
?(reduce=reduce) ?hook ?(opaque = false) obls =
let info = Id.print name ++ str " has type-checked" in
let prg = ProgramDecl.make ~opaque name ~udecl term t ~uctx [] None [] obls ~impargs ~poly ~scope ~kind reduce ?hook in
@@ -569,14 +328,14 @@ let add_definition ~name ?term t ~uctx ?(udecl=UState.default_univ_decl)
| _ -> res)
let add_mutual_definitions l ~uctx ?(udecl=UState.default_univ_decl) ?tactic
- ~poly ?(scope=DeclareDef.Global Declare.ImportDefaultBehavior) ?(kind=Decls.Definition) ?(reduce=reduce)
+ ~poly ?(scope=Declare.Global Declare.ImportDefaultBehavior) ?(kind=Decls.Definition) ?(reduce=reduce)
?hook ?(opaque = false) notations fixkind =
- let deps = List.map (fun (n, b, t, imps, obls) -> n) l in
+ let deps = List.map (fun ({ Declare.Recthm.name; _ }, _, _) -> name) l in
List.iter
- (fun (n, b, t, impargs, obls) ->
- let prg = ProgramDecl.make ~opaque n ~udecl (Some b) t ~uctx deps (Some fixkind)
+ (fun ({ Declare.Recthm.name; typ; impargs; _ }, b, obls) ->
+ let prg = ProgramDecl.make ~opaque name ~udecl (Some b) typ ~uctx deps (Some fixkind)
notations obls ~impargs ~poly ~scope ~kind reduce ?hook
- in progmap_add n (CEphemeron.create prg)) l;
+ in progmap_add name (CEphemeron.create prg)) l;
let _defined =
List.fold_left (fun finished x ->
if finished then finished
diff --git a/vernac/obligations.mli b/vernac/obligations.mli
index 101958072a..89ed4c3498 100644
--- a/vernac/obligations.mli
+++ b/vernac/obligations.mli
@@ -8,105 +8,131 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Environ
open Constr
-open Evd
-open Names
-
-val check_evars : env -> evar_map -> unit
-
-val evar_dependencies : evar_map -> Evar.t -> Evar.Set.t
-val sort_dependencies : (Evar.t * evar_info * Evar.Set.t) list -> (Evar.t * evar_info * Evar.Set.t) list
-
-(* ident, type, location, (opaque or transparent, expand or define), dependencies, tactic to solve it *)
-type obligation_info =
- (Id.t * types * Evar_kinds.t Loc.located *
- (bool * Evar_kinds.obligation_definition_status) * Int.Set.t * unit Proofview.tactic option) array
-
-(* env, id, evars, number of function prototypes to try to clear from
- evars contexts, object and type *)
-val eterm_obligations
- : env
- -> Id.t
- -> evar_map
- -> int
- -> ?status:Evar_kinds.obligation_definition_status
- -> EConstr.constr
- -> EConstr.types
- -> obligation_info *
-
- (* Existential key, obl. name, type as product, location of the
- original evar, associated tactic, status and dependencies as
- indexes into the array *)
- ((Evar.t * Id.t) list * ((Id.t -> EConstr.constr) -> EConstr.constr -> constr)) *
-
- (* Translations from existential identifiers to obligation
- identifiers and for terms with existentials to closed terms,
- given a translation from obligation identifiers to constrs,
- new term, new type *)
- constr * types
+
+(** Coq's Program mode support. This mode extends declarations of
+ constants and fixpoints with [Program Definition] and [Program
+ Fixpoint] to support incremental construction of terms using
+ delayed proofs, called "obligations"
+
+ The mode also provides facilities for managing and auto-solving
+ sets of obligations.
+
+ The basic code flow of programs/obligations is as follows:
+
+ - [add_definition] / [add_mutual_definitions] are called from the
+ respective [Program] vernacular command interpretation; at this
+ point the only extra work we do is to prepare the new definition
+ [d] using [RetrieveObl], which consists in turning unsolved evars
+ into obligations. [d] is not sent to the kernel yet, as it is not
+ complete and cannot be typchecked, but saved in a special
+ data-structure. Auto-solving of obligations is tried at this stage
+ (see below)
+
+ - [next_obligation] will retrieve the next obligation
+ ([RetrieveObl] sorts them by topological order) and will try to
+ solve it. When all obligations are solved, the original constant
+ [d] is grounded and sent to the kernel for addition to the global
+ environment. Auto-solving of obligations is also triggered on
+ obligation completion.
+
+{2} Solving of obligations: Solved obligations are stored as regular
+ global declarations in the global environment, usually with name
+ [constant_obligation_number] where [constant] is the original
+ [constant] and [number] is the corresponding (internal) number.
+
+ Solving an obligation can trigger a bit of a complex cascaded
+ callback path; closing an obligation can indeed allow all other
+ obligations to be closed, which in turn may trigged the declaration
+ of the original constant. Care must be taken, as this can modify
+ [Global.env] in arbitrarily ways. Current code takes some care to
+ refresh the [env] in the proper boundaries, but the invariants
+ remain delicate.
+
+{2} Saving of obligations: as open obligations use the regular proof
+ mode, a `Qed` will call `Lemmas.save_lemma` first. For this reason
+ obligations code is split in two: this file, [Obligations], taking
+ care of the top-level vernac commands, and [DeclareObl], which is
+ called by `Lemmas` to close an obligation proof and eventually to
+ declare the top-level [Program]ed constant.
+
+ There is little obligations-specific code in [DeclareObl], so
+ eventually that file should be integrated in the regular [Declare]
+ path, as it gains better support for "dependent_proofs".
+
+ *)
val default_tactic : unit Proofview.tactic ref
-val add_definition
- : name:Names.Id.t
- -> ?term:constr -> types
+(** Start a [Program Definition c] proof. [uctx] [udecl] [impargs]
+ [kind] [scope] [poly] etc... come from the interpretation of the
+ vernacular; `obligation_info` was generated by [RetrieveObl] It
+ will return whether all the obligations were solved; if so, it will
+ also register [c] with the kernel. *)
+val add_definition :
+ name:Names.Id.t
+ -> ?term:constr
+ -> types
-> uctx:UState.t
- -> ?udecl:UState.universe_decl (* Universe binders and constraints *)
+ -> ?udecl:UState.universe_decl (** Universe binders and constraints *)
-> ?impargs:Impargs.manual_implicits
-> poly:bool
- -> ?scope:DeclareDef.locality
+ -> ?scope:Declare.locality
-> ?kind:Decls.definition_object_kind
-> ?tactic:unit Proofview.tactic
-> ?reduce:(constr -> constr)
- -> ?hook:DeclareDef.Hook.t
+ -> ?hook:Declare.Hook.t
-> ?opaque:bool
- -> obligation_info
+ -> RetrieveObl.obligation_info
-> DeclareObl.progress
-val add_mutual_definitions
- (* XXX: unify with MutualEntry *)
- : (Names.Id.t * constr * types * Impargs.manual_implicits * obligation_info) list
+(* XXX: unify with MutualEntry *)
+
+(** Start a [Program Fixpoint] declaration, similar to the above,
+ except it takes a list now. *)
+val add_mutual_definitions :
+ (Declare.Recthm.t * Constr.t * RetrieveObl.obligation_info) list
-> uctx:UState.t
- -> ?udecl:UState.universe_decl
- (** Universe binders and constraints *)
+ -> ?udecl:UState.universe_decl (** Universe binders and constraints *)
-> ?tactic:unit Proofview.tactic
-> poly:bool
- -> ?scope:DeclareDef.locality
+ -> ?scope:Declare.locality
-> ?kind:Decls.definition_object_kind
-> ?reduce:(constr -> constr)
- -> ?hook:DeclareDef.Hook.t -> ?opaque:bool
+ -> ?hook:Declare.Hook.t
+ -> ?opaque:bool
-> Vernacexpr.decl_notation list
- -> DeclareObl.fixpoint_kind -> unit
+ -> DeclareObl.fixpoint_kind
+ -> unit
-val obligation
- : int * Names.Id.t option * Constrexpr.constr_expr option
+(** Implementation of the [Obligation] command *)
+val obligation :
+ int * Names.Id.t option * Constrexpr.constr_expr option
-> Genarg.glob_generic_argument option
-> Lemmas.t
-val next_obligation
- : Names.Id.t option
- -> Genarg.glob_generic_argument option
- -> Lemmas.t
+(** Implementation of the [Next Obligation] command *)
+val next_obligation :
+ Names.Id.t option -> Genarg.glob_generic_argument option -> Lemmas.t
-val solve_obligations : Names.Id.t option -> unit Proofview.tactic option
- -> DeclareObl.progress
-(* Number of remaining obligations to be solved for this program *)
+(** Implementation of the [Solve Obligation] command *)
+val solve_obligations :
+ Names.Id.t option -> unit Proofview.tactic option -> DeclareObl.progress
val solve_all_obligations : unit Proofview.tactic option -> unit
-val try_solve_obligation : int -> Names.Id.t option -> unit Proofview.tactic option -> unit
+(** Number of remaining obligations to be solved for this program *)
+val try_solve_obligation :
+ int -> Names.Id.t option -> unit Proofview.tactic option -> unit
-val try_solve_obligations : Names.Id.t option -> unit Proofview.tactic option -> unit
+val try_solve_obligations :
+ Names.Id.t option -> unit Proofview.tactic option -> unit
val show_obligations : ?msg:bool -> Names.Id.t option -> unit
-
val show_term : Names.Id.t option -> Pp.t
-
val admit_obligations : Names.Id.t option -> unit
exception NoObligations of Names.Id.t option
val explain_no_obligations : Names.Id.t option -> Pp.t
-
val check_program_libraries : unit -> unit
diff --git a/vernac/pfedit.ml b/vernac/pfedit.ml
new file mode 100644
index 0000000000..e6c66ee503
--- /dev/null
+++ b/vernac/pfedit.ml
@@ -0,0 +1,19 @@
+(* Compat API / *)
+let get_current_context = Declare.get_current_context
+[@@ocaml.deprecated "Use [Declare.get_current_context]"]
+let solve = Proof.solve
+[@@ocaml.deprecated "Use [Proof.solve]"]
+let by = Declare.by
+[@@ocaml.deprecated "Use [Declare.by]"]
+let refine_by_tactic = Proof.refine_by_tactic
+[@@ocaml.deprecated "Use [Proof.refine_by_tactic]"]
+
+(* We don't want to export this anymore, but we do for now *)
+let build_by_tactic ?side_eff env ~uctx ~poly ~typ tac =
+ let b, t, _unis, safe, uctx =
+ Declare.build_by_tactic ?side_eff env ~uctx ~poly ~typ tac in
+ b, t, safe, uctx
+[@@ocaml.deprecated "Use [Proof.build_by_tactic]"]
+
+let build_constant_by_tactic = Declare.build_constant_by_tactic
+[@@ocaml.deprecated "Use [Proof.build_constant_by_tactic]"]
diff --git a/vernac/ppvernac.ml b/vernac/ppvernac.ml
index 054b60853f..b97cdfa51c 100644
--- a/vernac/ppvernac.ml
+++ b/vernac/ppvernac.ml
@@ -86,7 +86,13 @@ open Pputils
let pr_module = Libnames.pr_qualid
- let pr_import_module = Libnames.pr_qualid
+ let pr_one_import_filter_name (q,etc) =
+ Libnames.pr_qualid q ++ if etc then str "(..)" else mt()
+
+ let pr_import_module (m,f) =
+ Libnames.pr_qualid m ++ match f with
+ | ImportAll -> mt()
+ | ImportNames ns -> surround (prlist_with_sep pr_comma pr_one_import_filter_name ns)
let sep_end = function
| VernacBullet _
@@ -162,8 +168,8 @@ open Pputils
keyword "Search" ++ spc() ++ prlist_with_sep spc pr_search sl ++ pr_in_out_modules b
let pr_option_ref_value = function
- | QualidRefValue id -> pr_qualid id
- | StringRefValue s -> qs s
+ | Goptions.QualidRefValue id -> pr_qualid id
+ | Goptions.StringRefValue s -> qs s
let pr_printoption table b =
prlist_with_sep spc str table ++
@@ -179,7 +185,7 @@ open Pputils
| [] -> mt()
| _ as z -> str":" ++ spc() ++ prlist_with_sep sep str z
- let pr_reference_or_constr pr_c = let open Hints in function
+ let pr_reference_or_constr pr_c = function
| HintsReference r -> pr_qualid r
| HintsConstr c -> pr_c c
@@ -785,7 +791,6 @@ let string_of_definition_object_kind = let open Decls in function
return (keyword "Admitted")
| VernacEndProof (Proved (opac,o)) -> return (
- let open Proof_global in
match o with
| None -> (match opac with
| Transparent -> keyword "Defined"
diff --git a/vernac/proof_global.ml b/vernac/proof_global.ml
new file mode 100644
index 0000000000..54d1db44a4
--- /dev/null
+++ b/vernac/proof_global.ml
@@ -0,0 +1,12 @@
+(* compatibility module; can be removed once we agree on the API *)
+
+type t = Declare.Proof.t
+[@@ocaml.deprecated "Use [Declare.Proof.t]"]
+let map_proof = Declare.Proof.map_proof
+[@@ocaml.deprecated "Use [Declare.Proof.map_proof]"]
+let get_proof = Declare.Proof.get_proof
+[@@ocaml.deprecated "Use [Declare.Proof.get_proof]"]
+
+type opacity_flag = Declare.opacity_flag =
+ | Opaque [@ocaml.deprecated "Use [Declare.Opaque]"]
+ | Transparent [@ocaml.deprecated "Use [Declare.Transparent]"]
diff --git a/vernac/pvernac.mli b/vernac/pvernac.mli
index 4de12f5e3b..1718024edd 100644
--- a/vernac/pvernac.mli
+++ b/vernac/pvernac.mli
@@ -28,7 +28,7 @@ module Vernac_ :
val command_entry : vernac_expr Entry.t
val main_entry : vernac_control option Entry.t
val red_expr : raw_red_expr Entry.t
- val hint_info : Hints.hint_info_expr Entry.t
+ val hint_info : hint_info_expr Entry.t
end
(* To be removed when the parser is made functional wrt the tactic
diff --git a/vernac/record.ml b/vernac/record.ml
index d974ead942..9fda98d08e 100644
--- a/vernac/record.ml
+++ b/vernac/record.ml
@@ -59,26 +59,37 @@ let () =
optread = (fun () -> !typeclasses_unique);
optwrite = (fun b -> typeclasses_unique := b); }
-let interp_fields_evars env sigma impls_env nots l =
- List.fold_left2
- (fun (env, sigma, uimpls, params, impls) no ({CAst.loc;v=i}, b, t) ->
- let sigma, (t', impl) = interp_type_evars_impls ~program_mode:false env sigma ~impls t in
- let r = Retyping.relevance_of_type env sigma t' in
- let sigma, b' =
- Option.cata (fun x -> on_snd (fun x -> Some (fst x)) @@
- interp_casted_constr_evars_impls ~program_mode:false env sigma ~impls x t') (sigma,None) b in
- let impls =
- match i with
- | Anonymous -> impls
- | Name id -> Id.Map.add id (compute_internalization_data env sigma Constrintern.Method t' impl) impls
- in
- let d = match b' with
- | None -> LocalAssum (make_annot i r,t')
- | Some b' -> LocalDef (make_annot i r,b',t')
+let interp_fields_evars env sigma ~ninds ~nparams impls_env nots l =
+ let _, sigma, impls, newfs, _ =
+ List.fold_left2
+ (fun (env, sigma, uimpls, params, impls) no ({CAst.loc;v=i}, b, t) ->
+ let sigma, (t', impl) = interp_type_evars_impls env sigma ~impls t in
+ let r = Retyping.relevance_of_type env sigma t' in
+ let sigma, b' =
+ Option.cata (fun x -> on_snd (fun x -> Some (fst x)) @@
+ interp_casted_constr_evars_impls ~program_mode:false env sigma ~impls x t') (sigma,None) b in
+ let impls =
+ match i with
+ | Anonymous -> impls
+ | Name id -> Id.Map.add id (compute_internalization_data env sigma id Constrintern.Method t' impl) impls
+ in
+ let d = match b' with
+ | None -> LocalAssum (make_annot i r,t')
+ | Some b' -> LocalDef (make_annot i r,b',t')
+ in
+ List.iter (Metasyntax.set_notation_for_interpretation env impls) no;
+ (EConstr.push_rel d env, sigma, impl :: uimpls, d::params, impls))
+ (env, sigma, [], [], impls_env) nots l
+ in
+ let _, sigma = Context.Rel.fold_outside ~init:(env,sigma) (fun f (env,sigma) ->
+ let sigma = RelDecl.fold_constr (fun c sigma ->
+ ComInductive.maybe_unify_params_in env sigma ~ninds ~nparams c)
+ f sigma
in
- List.iter (Metasyntax.set_notation_for_interpretation env impls) no;
- (EConstr.push_rel d env, sigma, impl :: uimpls, d::params, impls))
- (env, sigma, [], [], impls_env) nots l
+ EConstr.push_rel f env, sigma)
+ newfs
+ in
+ sigma, (impls, newfs)
let compute_constructor_level evars env l =
List.fold_right (fun d (env, univ) ->
@@ -103,7 +114,7 @@ let check_anonymous_type ind =
| { CAst.v = CSort (Glob_term.UAnonymous {rigid=true}) } -> true
| _ -> false
-let typecheck_params_and_fields finite def poly pl ps records =
+let typecheck_params_and_fields def poly pl ps records =
let env0 = Global.env () in
(* Special case elaboration for template-polymorphic inductives,
lower bound on introduced universes is Prop so that we do not miss
@@ -157,17 +168,15 @@ let typecheck_params_and_fields finite def poly pl ps records =
let fold accu (id, _, _, _) arity r =
EConstr.push_rel (LocalAssum (make_annot (Name id) r,arity)) accu in
let env_ar = EConstr.push_rel_context newps (List.fold_left3 fold env0 records arities relevances) in
- let assums = List.filter is_local_assum newps in
let impls_env =
- let params = List.map (RelDecl.get_name %> Name.get_id) assums in
- let ty = Inductive (params, (finite != Declarations.BiFinite)) in
let ids = List.map (fun (id, _, _, _) -> id) records in
let imps = List.map (fun _ -> imps) arities in
- compute_internalization_env env0 sigma ~impls:impls_env ty ids arities imps
+ compute_internalization_env env0 sigma ~impls:impls_env Inductive ids arities imps
in
+ let ninds = List.length arities in
+ let nparams = List.length newps in
let fold sigma (_, _, nots, fs) arity =
- let _, sigma, impls, newfs, _ = interp_fields_evars env_ar sigma impls_env nots (binders_of_decls fs) in
- (sigma, (impls, newfs))
+ interp_fields_evars env_ar sigma ~ninds ~nparams impls_env nots (binders_of_decls fs)
in
let (sigma, data) = List.fold_left2_map fold sigma records arities in
let sigma =
@@ -311,67 +320,65 @@ let declare_projections indsp ctx ?(kind=Decls.StructureComponent) binder_name f
let (_,_,kinds,sp_projs,_) =
List.fold_left3
(fun (nfi,i,kinds,sp_projs,subst) flags decl impls ->
- let fi = RelDecl.get_name decl in
- let ti = RelDecl.get_type decl in
- let (sp_projs,i,subst) =
- match fi with
- | Anonymous ->
- (None::sp_projs,i,NoProjection fi::subst)
- | Name fid -> try
- let kn, term =
- if is_local_assum decl && primitive then
- let p = Projection.Repr.make indsp
- ~proj_npars:mib.mind_nparams
- ~proj_arg:i
- (Label.of_id fid)
- in
- (* Already defined by declare_mind silently *)
- let kn = Projection.Repr.constant p in
- Declare.definition_message fid;
- kn, mkProj (Projection.make p false,mkRel 1)
- else
- let ccl = subst_projection fid subst ti in
- let body = match decl with
- | LocalDef (_,ci,_) -> subst_projection fid subst ci
- | LocalAssum ({binder_relevance=rci},_) ->
- (* [ccl] is defined in context [params;x:rp] *)
- (* [ccl'] is defined in context [params;x:rp;x:rp] *)
- let ccl' = liftn 1 2 ccl in
- let p = mkLambda (x, lift 1 rp, ccl') in
- let branch = it_mkLambda_or_LetIn (mkRel nfi) lifted_fields in
- let ci = Inductiveops.make_case_info env indsp rci LetStyle in
- (* Record projections have no is *)
- mkCase (ci, p, mkRel 1, [|branch|])
- in
- let proj =
- it_mkLambda_or_LetIn (mkLambda (x,rp,body)) paramdecls in
- let projtyp =
- it_mkProd_or_LetIn (mkProd (x,rp,ccl)) paramdecls in
- try
- let entry = Declare.definition_entry ~univs:ctx ~types:projtyp proj in
- let kind = Decls.IsDefinition kind in
- let kn = declare_constant ~name:fid ~kind (Declare.DefinitionEntry entry) in
- let constr_fip =
- let proj_args = (*Rel 1 refers to "x"*) paramargs@[mkRel 1] in
- applist (mkConstU (kn,u),proj_args)
- in
- Declare.definition_message fid;
- kn, constr_fip
- with Type_errors.TypeError (ctx,te) ->
- raise (NotDefinable (BadTypedProj (fid,ctx,te)))
- in
- let refi = GlobRef.ConstRef kn in
- Impargs.maybe_declare_manual_implicits false refi impls;
- if flags.pf_subclass then begin
- let cl = ComCoercion.class_of_global (GlobRef.IndRef indsp) in
- ComCoercion.try_add_new_coercion_with_source refi ~local:false ~poly ~source:cl
- end;
- let i = if is_local_assum decl then i+1 else i in
- (Some kn::sp_projs, i, Projection term::subst)
- with NotDefinable why ->
- warning_or_error flags.pf_subclass indsp why;
- (None::sp_projs,i,NoProjection fi::subst) in
- (nfi - 1, i, { Recordops.pk_name = fi ; pk_true_proj = is_local_assum decl ; pk_canonical = flags.pf_canonical } :: kinds, sp_projs, subst))
+ let fi = RelDecl.get_name decl in
+ let ti = RelDecl.get_type decl in
+ let (sp_projs,i,subst) =
+ match fi with
+ | Anonymous ->
+ (None::sp_projs,i,NoProjection fi::subst)
+ | Name fid ->
+ try
+ let ccl = subst_projection fid subst ti in
+ let body, p_opt = match decl with
+ | LocalDef (_,ci,_) -> subst_projection fid subst ci, None
+ | LocalAssum ({binder_relevance=rci},_) ->
+ (* [ccl] is defined in context [params;x:rp] *)
+ (* [ccl'] is defined in context [params;x:rp;x:rp] *)
+ if primitive then
+ let p = Projection.Repr.make indsp
+ ~proj_npars:mib.mind_nparams ~proj_arg:i (Label.of_id fid) in
+ mkProj (Projection.make p true, mkRel 1), Some p
+ else
+ let ccl' = liftn 1 2 ccl in
+ let p = mkLambda (x, lift 1 rp, ccl') in
+ let branch = it_mkLambda_or_LetIn (mkRel nfi) lifted_fields in
+ let ci = Inductiveops.make_case_info env indsp rci LetStyle in
+ (* Record projections have no is *)
+ mkCase (ci, p, mkRel 1, [|branch|]), None
+ in
+ let proj = it_mkLambda_or_LetIn (mkLambda (x,rp,body)) paramdecls in
+ let projtyp = it_mkProd_or_LetIn (mkProd (x,rp,ccl)) paramdecls in
+ let entry = Declare.definition_entry ~univs:ctx ~types:projtyp proj in
+ let kind = Decls.IsDefinition kind in
+ let kn =
+ try declare_constant ~name:fid ~kind (Declare.DefinitionEntry entry)
+ with Type_errors.TypeError (ctx,te) when not primitive ->
+ raise (NotDefinable (BadTypedProj (fid,ctx,te)))
+ in
+ Declare.definition_message fid;
+ let term = match p_opt with
+ | Some p ->
+ let _ = DeclareInd.declare_primitive_projection p kn in
+ mkProj (Projection.make p false,mkRel 1)
+ | None ->
+ let proj_args = (*Rel 1 refers to "x"*) paramargs@[mkRel 1] in
+ match decl with
+ | LocalDef (_,ci,_) when primitive -> body
+ | _ -> applist (mkConstU (kn,u),proj_args)
+ in
+ let refi = GlobRef.ConstRef kn in
+ Impargs.maybe_declare_manual_implicits false refi impls;
+ if flags.pf_subclass then begin
+ let cl = ComCoercion.class_of_global (GlobRef.IndRef indsp) in
+ ComCoercion.try_add_new_coercion_with_source refi ~local:false ~poly ~source:cl
+ end;
+ let i = if is_local_assum decl then i+1 else i in
+ (Some kn::sp_projs, i, Projection term::subst)
+ with NotDefinable why ->
+ warning_or_error flags.pf_subclass indsp why;
+ (None::sp_projs,i,NoProjection fi::subst)
+ in
+ (nfi - 1, i, { Recordops.pk_name = fi ; pk_true_proj = is_local_assum decl ; pk_canonical = flags.pf_canonical } :: kinds, sp_projs, subst))
(List.length fields,0,[],[],[]) flags (List.rev fields) (List.rev fieldimpls)
in (kinds,sp_projs)
@@ -702,7 +709,7 @@ let definition_structure udecl kind ~template ~cumulative ~poly finite records =
let ps, data = extract_record_data records in
let ubinders, univs, auto_template, params, implpars, data =
States.with_state_protection (fun () ->
- typecheck_params_and_fields finite (kind = Class true) poly udecl ps data) () in
+ typecheck_params_and_fields (kind = Class true) poly udecl ps data) () in
let template = template, auto_template in
match kind with
| Class def ->
diff --git a/vernac/retrieveObl.ml b/vernac/retrieveObl.ml
new file mode 100644
index 0000000000..b8564037e0
--- /dev/null
+++ b/vernac/retrieveObl.ml
@@ -0,0 +1,296 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Names
+
+(**
+ - Get types of existentials ;
+ - Flatten dependency tree (prefix order) ;
+ - Replace existentials by de Bruijn indices in term, applied to the right arguments ;
+ - Apply term prefixed by quantification on "existentials".
+*)
+
+let check_evars env evm =
+ Evar.Map.iter
+ (fun key evi ->
+ if Evd.is_obligation_evar evm key then ()
+ else
+ let loc, k = Evd.evar_source key evm in
+ Pretype_errors.error_unsolvable_implicit ?loc env evm key None)
+ (Evd.undefined_map evm)
+
+type obligation_info =
+ ( Names.Id.t
+ * Constr.types
+ * Evar_kinds.t Loc.located
+ * (bool * Evar_kinds.obligation_definition_status)
+ * Int.Set.t
+ * unit Proofview.tactic option )
+ array
+
+type oblinfo =
+ { ev_name : int * Id.t
+ ; ev_hyps : EConstr.named_context
+ ; ev_status : bool * Evar_kinds.obligation_definition_status
+ ; ev_chop : int option
+ ; ev_src : Evar_kinds.t Loc.located
+ ; ev_typ : Constr.types
+ ; ev_tac : unit Proofview.tactic option
+ ; ev_deps : Int.Set.t }
+
+(** Substitute evar references in t using de Bruijn indices,
+ where n binders were passed through. *)
+
+let succfix (depth, fixrels) = (succ depth, List.map succ fixrels)
+
+let subst_evar_constr evm evs n idf t =
+ let seen = ref Int.Set.empty in
+ let transparent = ref Id.Set.empty in
+ let evar_info id = CList.assoc_f Evar.equal id evs in
+ let rec substrec (depth, fixrels) c =
+ match EConstr.kind evm c with
+ | Constr.Evar (k, args) ->
+ let {ev_name = id, idstr; ev_hyps = hyps; ev_chop = chop} =
+ try evar_info k
+ with Not_found ->
+ CErrors.anomaly ~label:"eterm"
+ Pp.(
+ str "existential variable "
+ ++ int (Evar.repr k)
+ ++ str " not found.")
+ in
+ seen := Int.Set.add id !seen;
+ (* Evar arguments are created in inverse order,
+ and we must not apply to defined ones (i.e. LetIn's)
+ *)
+ let args =
+ let n = match chop with None -> 0 | Some c -> c in
+ let l, r = CList.chop n (List.rev args) in
+ List.rev r
+ in
+ let args =
+ let rec aux hyps args acc =
+ let open Context.Named.Declaration in
+ match (hyps, args) with
+ | LocalAssum _ :: tlh, c :: tla ->
+ aux tlh tla (substrec (depth, fixrels) c :: acc)
+ | LocalDef _ :: tlh, _ :: tla -> aux tlh tla acc
+ | [], [] -> acc
+ | _, _ -> acc
+ (*failwith "subst_evars: invalid argument"*)
+ in
+ aux hyps args []
+ in
+ if
+ List.exists
+ (fun x ->
+ match EConstr.kind evm x with
+ | Constr.Rel n -> Int.List.mem n fixrels
+ | _ -> false)
+ args
+ then transparent := Id.Set.add idstr !transparent;
+ EConstr.mkApp (idf idstr, Array.of_list args)
+ | Constr.Fix _ ->
+ EConstr.map_with_binders evm succfix substrec (depth, 1 :: fixrels) c
+ | _ -> EConstr.map_with_binders evm succfix substrec (depth, fixrels) c
+ in
+ let t' = substrec (0, []) t in
+ (EConstr.to_constr evm t', !seen, !transparent)
+
+(** Substitute variable references in t using de Bruijn indices,
+ where n binders were passed through. *)
+let subst_vars acc n t =
+ let var_index id = Util.List.index Id.equal id acc in
+ let rec substrec depth c =
+ match Constr.kind c with
+ | Constr.Var v -> (
+ try Constr.mkRel (depth + var_index v) with Not_found -> c )
+ | _ -> Constr.map_with_binders succ substrec depth c
+ in
+ substrec 0 t
+
+(** Rewrite type of an evar ([ H1 : t1, ... Hn : tn |- concl ])
+ to a product : forall H1 : t1, ..., forall Hn : tn, concl.
+ Changes evars and hypothesis references to variable references.
+*)
+let etype_of_evar evm evs hyps concl =
+ let open Context.Named.Declaration in
+ let rec aux acc n = function
+ | decl :: tl -> (
+ let t', s, trans =
+ subst_evar_constr evm evs n EConstr.mkVar
+ (Context.Named.Declaration.get_type decl)
+ in
+ let t'' = subst_vars acc 0 t' in
+ let rest, s', trans' =
+ aux (Context.Named.Declaration.get_id decl :: acc) (succ n) tl
+ in
+ let s' = Int.Set.union s s' in
+ let trans' = Id.Set.union trans trans' in
+ match decl with
+ | LocalDef (id, c, _) ->
+ let c', s'', trans'' = subst_evar_constr evm evs n EConstr.mkVar c in
+ let c' = subst_vars acc 0 c' in
+ ( Term.mkNamedProd_or_LetIn (LocalDef (id, c', t'')) rest
+ , Int.Set.union s'' s'
+ , Id.Set.union trans'' trans' )
+ | LocalAssum (id, _) ->
+ (Term.mkNamedProd_or_LetIn (LocalAssum (id, t'')) rest, s', trans') )
+ | [] ->
+ let t', s, trans = subst_evar_constr evm evs n EConstr.mkVar concl in
+ (subst_vars acc 0 t', s, trans)
+ in
+ aux [] 0 (List.rev hyps)
+
+let trunc_named_context n ctx =
+ let len = List.length ctx in
+ CList.firstn (len - n) ctx
+
+let rec chop_product n t =
+ let pop t = Vars.lift (-1) t in
+ if Int.equal n 0 then Some t
+ else
+ match Constr.kind t with
+ | Constr.Prod (_, _, b) ->
+ if Vars.noccurn 1 b then chop_product (pred n) (pop b) else None
+ | _ -> None
+
+let evar_dependencies evm oev =
+ let one_step deps =
+ Evar.Set.fold
+ (fun ev s ->
+ let evi = Evd.find evm ev in
+ let deps' = Evd.evars_of_filtered_evar_info evm evi in
+ if Evar.Set.mem oev deps' then
+ invalid_arg
+ ( "Ill-formed evar map: cycle detected for evar "
+ ^ Pp.string_of_ppcmds @@ Evar.print oev )
+ else Evar.Set.union deps' s)
+ deps deps
+ in
+ let rec aux deps =
+ let deps' = one_step deps in
+ if Evar.Set.equal deps deps' then deps else aux deps'
+ in
+ aux (Evar.Set.singleton oev)
+
+let move_after ((id, ev, deps) as obl) l =
+ let rec aux restdeps = function
+ | ((id', _, _) as obl') :: tl ->
+ let restdeps' = Evar.Set.remove id' restdeps in
+ if Evar.Set.is_empty restdeps' then obl' :: obl :: tl
+ else obl' :: aux restdeps' tl
+ | [] -> [obl]
+ in
+ aux (Evar.Set.remove id deps) l
+
+let sort_dependencies evl =
+ let rec aux l found list =
+ match l with
+ | ((id, ev, deps) as obl) :: tl ->
+ let found' = Evar.Set.union found (Evar.Set.singleton id) in
+ if Evar.Set.subset deps found' then aux tl found' (obl :: list)
+ else aux (move_after obl tl) found list
+ | [] -> List.rev list
+ in
+ aux evl Evar.Set.empty []
+
+let retrieve_obligations env name evm fs ?status t ty =
+ (* 'Serialize' the evars *)
+ let nc = Environ.named_context env in
+ let nc_len = Context.Named.length nc in
+ let evm = Evarutil.nf_evar_map_undefined evm in
+ let evl = Evarutil.non_instantiated evm in
+ let evl = Evar.Map.bindings evl in
+ let evl = List.map (fun (id, ev) -> (id, ev, evar_dependencies evm id)) evl in
+ let sevl = sort_dependencies evl in
+ let evl = List.map (fun (id, ev, _) -> (id, ev)) sevl in
+ let evn =
+ let i = ref (-1) in
+ List.rev_map
+ (fun (id, ev) ->
+ incr i;
+ ( id
+ , ( !i
+ , Id.of_string
+ (Id.to_string name ^ "_obligation_" ^ string_of_int (succ !i)) )
+ , ev ))
+ evl
+ in
+ let evts =
+ (* Remove existential variables in types and build the corresponding products *)
+ List.fold_right
+ (fun (id, (n, nstr), ev) l ->
+ let hyps = Evd.evar_filtered_context ev in
+ let hyps = trunc_named_context nc_len hyps in
+ let evtyp, deps, transp = etype_of_evar evm l hyps ev.Evd.evar_concl in
+ let evtyp, hyps, chop =
+ match chop_product fs evtyp with
+ | Some t -> (t, trunc_named_context fs hyps, fs)
+ | None -> (evtyp, hyps, 0)
+ in
+ let loc, k = Evd.evar_source id evm in
+ let status =
+ match k with
+ | Evar_kinds.QuestionMark {Evar_kinds.qm_obligation = o} -> o
+ | _ -> (
+ match status with
+ | Some o -> o
+ | None ->
+ Evar_kinds.Define (not (Program.get_proofs_transparency ())) )
+ in
+ let force_status, status, chop =
+ match status with
+ | Evar_kinds.Define true as stat ->
+ if not (Int.equal chop fs) then (true, Evar_kinds.Define false, None)
+ else (false, stat, Some chop)
+ | s -> (false, s, None)
+ in
+ let info =
+ { ev_name = (n, nstr)
+ ; ev_hyps = hyps
+ ; ev_status = (force_status, status)
+ ; ev_chop = chop
+ ; ev_src = (loc, k)
+ ; ev_typ = evtyp
+ ; ev_deps = deps
+ ; ev_tac = None }
+ in
+ (id, info) :: l)
+ evn []
+ in
+ let t', _, transparent =
+ (* Substitute evar refs in the term by variables *)
+ subst_evar_constr evm evts 0 EConstr.mkVar t
+ in
+ let ty, _, _ = subst_evar_constr evm evts 0 EConstr.mkVar ty in
+ let evars =
+ List.map
+ (fun (ev, info) ->
+ let { ev_name = _, name
+ ; ev_status = force_status, status
+ ; ev_src = src
+ ; ev_typ = typ
+ ; ev_deps = deps
+ ; ev_tac = tac } =
+ info
+ in
+ let force_status, status =
+ match status with
+ | Evar_kinds.Define true when Id.Set.mem name transparent ->
+ (true, Evar_kinds.Define false)
+ | _ -> (force_status, status)
+ in
+ (name, typ, src, (force_status, status), deps, tac))
+ evts
+ in
+ let evnames = List.map (fun (ev, info) -> (ev, snd info.ev_name)) evts in
+ let evmap f c = Util.pi1 (subst_evar_constr evm evts 0 f c) in
+ (Array.of_list (List.rev evars), (evnames, evmap), t', ty)
diff --git a/vernac/retrieveObl.mli b/vernac/retrieveObl.mli
new file mode 100644
index 0000000000..c9c45bd889
--- /dev/null
+++ b/vernac/retrieveObl.mli
@@ -0,0 +1,46 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+val check_evars : Environ.env -> Evd.evar_map -> unit
+
+type obligation_info =
+ ( Names.Id.t
+ * Constr.types
+ * Evar_kinds.t Loc.located
+ * (bool * Evar_kinds.obligation_definition_status)
+ * Int.Set.t
+ * unit Proofview.tactic option )
+ array
+(** ident, type, location of the original evar, (opaque or
+ transparent, expand or define), dependencies as indexes into the
+ array, tactic to solve it *)
+
+val retrieve_obligations :
+ Environ.env
+ -> Names.Id.t
+ -> Evd.evar_map
+ -> int
+ -> ?status:Evar_kinds.obligation_definition_status
+ -> EConstr.t
+ -> EConstr.types
+ -> obligation_info
+ * ( (Evar.t * Names.Id.t) list
+ * ((Names.Id.t -> EConstr.t) -> EConstr.t -> Constr.t) )
+ * Constr.t
+ * Constr.t
+(** [retrieve_obligations env id sigma fs ?status body type] returns
+ [obls, (evnames, evmap), nbody, ntype] a list of obligations built
+ from evars in [body, type].
+
+ [fs] is the number of function prototypes to try to clear from
+ evars contexts. [evnames, evmap) is the list of names /
+ substitution functions used to program with holes. This is not used
+ in Coq, but in the equations plugin; [evnames] is actually
+ redundant with the information contained in [obls] *)
diff --git a/vernac/search.ml b/vernac/search.ml
index 68a30b4231..8b54b696f2 100644
--- a/vernac/search.ml
+++ b/vernac/search.ml
@@ -61,7 +61,7 @@ let iter_named_context_name_type f =
let get_current_or_goal_context ?pstate glnum =
match pstate with
| None -> let env = Global.env () in Evd.(from_env env, env)
- | Some p -> Pfedit.get_goal_context p glnum
+ | Some p -> Declare.get_goal_context p glnum
(* General search over hypothesis of a goal *)
let iter_hypothesis ?pstate glnum (fn : GlobRef.t -> env -> constr -> unit) =
diff --git a/vernac/search.mli b/vernac/search.mli
index 6dbbff3a8c..d3b8444b5f 100644
--- a/vernac/search.mli
+++ b/vernac/search.mli
@@ -38,13 +38,13 @@ val search_filter : glob_search_about_item -> filter_function
goal and the global environment for things matching [pattern] and
satisfying module exclude/include clauses of [modinout]. *)
-val search_by_head : ?pstate:Proof_global.t -> int option -> constr_pattern -> DirPath.t list * bool
+val search_by_head : ?pstate:Declare.Proof.t -> int option -> constr_pattern -> DirPath.t list * bool
-> display_function -> unit
-val search_rewrite : ?pstate:Proof_global.t -> int option -> constr_pattern -> DirPath.t list * bool
+val search_rewrite : ?pstate:Declare.Proof.t -> int option -> constr_pattern -> DirPath.t list * bool
-> display_function -> unit
-val search_pattern : ?pstate:Proof_global.t -> int option -> constr_pattern -> DirPath.t list * bool
+val search_pattern : ?pstate:Declare.Proof.t -> int option -> constr_pattern -> DirPath.t list * bool
-> display_function -> unit
-val search : ?pstate:Proof_global.t -> int option -> (bool * glob_search_about_item) list
+val search : ?pstate:Declare.Proof.t -> int option -> (bool * glob_search_about_item) list
-> DirPath.t list * bool -> display_function -> unit
type search_constraint =
@@ -65,12 +65,12 @@ type 'a coq_object = {
coq_object_object : 'a;
}
-val interface_search : ?pstate:Proof_global.t -> ?glnum:int -> (search_constraint * bool) list ->
+val interface_search : ?pstate:Declare.Proof.t -> ?glnum:int -> (search_constraint * bool) list ->
constr coq_object list
(** {6 Generic search function} *)
-val generic_search : ?pstate:Proof_global.t -> int option -> display_function -> unit
+val generic_search : ?pstate:Declare.Proof.t -> int option -> display_function -> unit
(** This function iterates over all hypothesis of the goal numbered
[glnum] (if present) and all known declarations. *)
diff --git a/vernac/vernac.mllib b/vernac/vernac.mllib
index 6e398d87ca..618a61f487 100644
--- a/vernac/vernac.mllib
+++ b/vernac/vernac.mllib
@@ -14,8 +14,10 @@ Proof_using
Egramcoq
Metasyntax
DeclareUniv
-DeclareDef
+RetrieveObl
+Declare
DeclareObl
+ComHints
Canonical
RecLemmas
Library
@@ -43,3 +45,6 @@ ComArguments
Vernacentries
Vernacstate
Vernacinterp
+Proof_global
+Pfedit
+DeclareDef
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index 963b5f2084..aac0b54ed4 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -34,12 +34,12 @@ let (f_interp_redexp, interp_redexp_hook) = Hook.make ()
let get_current_or_global_context ~pstate =
match pstate with
| None -> let env = Global.env () in Evd.(from_env env, env)
- | Some p -> Pfedit.get_current_context p
+ | Some p -> Declare.get_current_context p
let get_goal_or_global_context ~pstate glnum =
match pstate with
| None -> let env = Global.env () in Evd.(from_env env, env)
- | Some p -> Pfedit.get_goal_context p glnum
+ | Some p -> Declare.get_goal_context p glnum
let cl_of_qualid = function
| FunClass -> Coercionops.CL_FUN
@@ -94,13 +94,13 @@ let show_proof ~pstate =
(* spiwack: this would probably be cooler with a bit of polishing. *)
try
let pstate = Option.get pstate in
- let p = Proof_global.get_proof pstate in
- let sigma, env = Pfedit.get_current_context pstate in
+ let p = Declare.Proof.get_proof pstate in
+ let sigma, env = Declare.get_current_context pstate in
let pprf = Proof.partial_proof p in
Pp.prlist_with_sep Pp.fnl (Printer.pr_econstr_env env sigma) pprf
(* We print nothing if there are no goals left *)
with
- | Pfedit.NoSuchGoal
+ | Proof.NoSuchGoal _
| Option.IsNone ->
user_err (str "No goals to show.")
@@ -460,7 +460,7 @@ let vernac_custom_entry ~module_local s =
let check_name_freshness locality {CAst.loc;v=id} : unit =
(* We check existence here: it's a bit late at Qed time *)
if Nametab.exists_cci (Lib.make_path id) || Termops.is_section_variable id ||
- locality <> DeclareDef.Discharge && Nametab.exists_cci (Lib.make_path_except_section id)
+ locality <> Declare.Discharge && Nametab.exists_cci (Lib.make_path_except_section id)
then
user_err ?loc (Id.print id ++ str " already exists.")
@@ -475,8 +475,8 @@ let program_inference_hook env sigma ev =
Evarutil.is_ground_term sigma concl)
then None
else
- let c, _, _, ctx =
- Pfedit.build_by_tactic ~poly:false env ~uctx:(Evd.evar_universe_context sigma) ~typ:concl tac
+ let c, _, _, _, ctx =
+ Declare.build_by_tactic ~poly:false env ~uctx:(Evd.evar_universe_context sigma) ~typ:concl tac
in
Some (Evd.set_universe_context sigma ctx, EConstr.of_constr c)
with
@@ -486,11 +486,14 @@ let program_inference_hook env sigma ev =
let start_lemma_com ~program_mode ~poly ~scope ~kind ?hook thms =
let env0 = Global.env () in
+ let flags = Pretyping.{ all_no_fail_flags with program_mode } in
let decl = fst (List.hd thms) in
let evd, udecl = Constrexpr_ops.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)) = Constrintern.interp_context_evars ~program_mode env0 evd bl in
- let evd, (t', imps') = Constrintern.interp_type_evars_impls ~program_mode ~impls env evd t in
+ let evd, (impls, ((env, ctx), imps)) =
+ Constrintern.interp_context_evars ~program_mode env0 evd bl
+ in
+ let evd, (t', imps') = Constrintern.interp_type_evars_impls ~flags ~impls env evd t in
let flags = Pretyping.{ all_and_fail_flags with program_mode } in
let inference_hook = if program_mode then Some program_inference_hook else None in
let evd = Pretyping.solve_remaining_evars ?hook:inference_hook flags env evd in
@@ -501,7 +504,7 @@ let start_lemma_com ~program_mode ~poly ~scope ~kind ?hook thms =
let recguard,thms,snl = RecLemmas.look_for_possibly_mutual_statements evd thms in
let evd = Evd.minimize_universes evd in
let thms = List.map (fun (name, (typ, (args, impargs))) ->
- { DeclareDef.Recthm.name; typ = EConstr.to_constr evd typ; args; impargs} ) thms in
+ { Declare.Recthm.name; typ = EConstr.to_constr evd typ; args; impargs} ) thms in
let () =
let open UState in
if not (udecl.univdecl_extensible_instance && udecl.univdecl_extensible_constraints) then
@@ -518,17 +521,19 @@ let vernac_definition_hook ~canonical_instance ~local ~poly = let open Decls in
| Coercion ->
Some (ComCoercion.add_coercion_hook ~poly)
| CanonicalStructure ->
- Some (DeclareDef.Hook.(make (fun { S.dref } -> Canonical.declare_canonical_structure ?local dref)))
+ Some (Declare.Hook.(make (fun { S.dref } -> Canonical.declare_canonical_structure ?local dref)))
| SubClass ->
Some (ComCoercion.add_subclass_hook ~poly)
| Definition when canonical_instance ->
- Some (DeclareDef.Hook.(make (fun { S.dref } -> Canonical.declare_canonical_structure ?local dref)))
+ Some (Declare.Hook.(make (fun { S.dref } -> Canonical.declare_canonical_structure ?local dref)))
| Let when canonical_instance ->
- Some (DeclareDef.Hook.(make (fun { S.dref } -> Canonical.declare_canonical_structure dref)))
+ Some (Declare.Hook.(make (fun { S.dref } -> Canonical.declare_canonical_structure dref)))
| _ -> None
+let default_thm_id = Id.of_string "Unnamed_thm"
+
let fresh_name_for_anonymous_theorem () =
- Namegen.next_global_ident_away Lemmas.default_thm_id Id.Set.empty
+ Namegen.next_global_ident_away default_thm_id Id.Set.empty
let vernac_definition_name lid local =
let lid =
@@ -537,7 +542,7 @@ let vernac_definition_name lid local =
CAst.make ?loc (fresh_name_for_anonymous_theorem ())
| { v = Name.Name n; loc } -> CAst.make ?loc n in
let () =
- let open DeclareDef in
+ let open Declare in
match local with
| Discharge -> Dumpglob.dump_definition lid true "var"
| Global _ -> Dumpglob.dump_definition lid false "def"
@@ -565,7 +570,9 @@ let vernac_definition ~atts (discharge, kind) (lid, pl) bl red_option c typ_opt
let env = Global.env () in
let sigma = Evd.from_env env in
Some (snd (Hook.get f_interp_redexp env sigma r)) in
- ComDefinition.do_definition ~program_mode ~name:name.v
+ let do_definition =
+ ComDefinition.(if program_mode then do_definition_program else do_definition) in
+ do_definition ~name:name.v
~poly:atts.polymorphic ~scope ~kind pl bl red_option c typ_opt ?hook
(* NB: pstate argument to use combinators easily *)
@@ -586,7 +593,7 @@ let vernac_exact_proof ~lemma c =
(* spiwack: for simplicity I do not enforce that "Proof proof_term" is
called only at the beginning of a proof. *)
let lemma, status = Lemmas.by (Tactics.exact_proof c) lemma in
- let () = Lemmas.save_lemma_proved ~lemma ~opaque:Proof_global.Opaque ~idopt:None in
+ let () = Lemmas.save_lemma_proved ~lemma ~opaque:Declare.Opaque ~idopt:None in
if not status then Feedback.feedback Feedback.AddedAxiom
let vernac_assumption ~atts discharge kind l nl =
@@ -596,8 +603,8 @@ let vernac_assumption ~atts discharge kind l nl =
if Dumpglob.dump () then
List.iter (fun (lid, _) ->
match scope with
- | DeclareDef.Global _ -> Dumpglob.dump_definition lid false "ax"
- | DeclareDef.Discharge -> Dumpglob.dump_definition lid true "var") idl) l;
+ | Declare.Global _ -> Dumpglob.dump_definition lid false "ax"
+ | Declare.Discharge -> Dumpglob.dump_definition lid true "var") idl) l;
ComAssumption.do_assumptions ~poly:atts.polymorphic ~program_mode:atts.program ~scope ~kind nl l
let is_polymorphic_inductive_cumulativity =
@@ -865,12 +872,62 @@ let vernac_constraint ~poly l =
(**********************)
(* Modules *)
+let add_subnames_of ns full_n n =
+ let open GlobRef in
+ let module NSet = Globnames.ExtRefSet in
+ let add1 r ns = NSet.add (Globnames.TrueGlobal r) ns in
+ match n with
+ | Globnames.SynDef _ | Globnames.TrueGlobal (ConstRef _ | ConstructRef _ | VarRef _) ->
+ CErrors.user_err Pp.(str "Only inductive types can be used with Import (...).")
+ | Globnames.TrueGlobal (IndRef (mind,i)) ->
+ let open Declarations in
+ let dp = Libnames.dirpath full_n in
+ let mib = Global.lookup_mind mind in
+ let mip = mib.mind_packets.(i) in
+ let ns = add1 (IndRef (mind,i)) ns in
+ let ns = Array.fold_left_i (fun j ns _ -> add1 (ConstructRef ((mind,i),j+1)) ns)
+ ns mip.mind_consnames
+ in
+ List.fold_left (fun ns f ->
+ let s = Indrec.elimination_suffix f in
+ let n_elim = Id.of_string (Id.to_string mip.mind_typename ^ s) in
+ match Nametab.extended_global_of_path (Libnames.make_path dp n_elim) with
+ | exception Not_found -> ns
+ | n_elim -> NSet.add n_elim ns)
+ ns Sorts.all_families
+
+let interp_filter_in m = function
+ | ImportAll -> Libobject.Unfiltered
+ | ImportNames ns ->
+ let module NSet = Globnames.ExtRefSet in
+ let dp_m = Nametab.dirpath_of_module m in
+ let ns =
+ List.fold_left (fun ns (n,etc) ->
+ let full_n =
+ let dp_n,n = repr_qualid n in
+ make_path (append_dirpath dp_m dp_n) n
+ in
+ let n = try Nametab.extended_global_of_path full_n
+ with Not_found ->
+ CErrors.user_err
+ Pp.(str "Cannot find name " ++ pr_qualid n ++ spc() ++
+ str "in module " ++ pr_qualid (Nametab.shortest_qualid_of_module m))
+ in
+ let ns = NSet.add n ns in
+ if etc then add_subnames_of ns full_n n else ns)
+ NSet.empty ns
+ in
+ Libobject.Names ns
+
let vernac_import export refl =
- let import_mod qid =
- try Declaremods.import_module ~export @@ Nametab.locate_module qid
- with Not_found ->
- CErrors.user_err Pp.(str "Cannot find module " ++ pr_qualid qid)
- in
+ let import_mod (qid,f) =
+ let m = try Nametab.locate_module qid
+ with Not_found ->
+ CErrors.user_err Pp.(str "Cannot find module " ++ pr_qualid qid)
+ in
+ let f = interp_filter_in m f in
+ Declaremods.import_module f ~export m
+ in
List.iter import_mod refl
let vernac_declare_module export {loc;v=id} binders_ast mty_ast =
@@ -886,7 +943,7 @@ let vernac_declare_module export {loc;v=id} binders_ast mty_ast =
let mp = Declaremods.declare_module id binders_ast (Declaremods.Enforce mty_ast) [] in
Dumpglob.dump_moddef ?loc mp "mod";
Flags.if_verbose Feedback.msg_info (str "Module " ++ Id.print id ++ str " is declared");
- Option.iter (fun export -> vernac_import export [qualid_of_ident id]) export
+ Option.iter (fun export -> vernac_import export [qualid_of_ident id, ImportAll]) export
let vernac_define_module export {loc;v=id} (binders_ast : module_binder list) mty_ast_o mexpr_ast_l =
(* We check the state of the system (in section, in module type)
@@ -907,7 +964,7 @@ let vernac_define_module export {loc;v=id} (binders_ast : module_binder list) mt
List.iter
(fun (export,id) ->
Option.iter
- (fun export -> vernac_import export [qualid_of_ident id]) export
+ (fun export -> vernac_import export [qualid_of_ident id, ImportAll]) export
) argsexport
| _::_ ->
let binders_ast = List.map
@@ -922,14 +979,14 @@ let vernac_define_module export {loc;v=id} (binders_ast : module_binder list) mt
Dumpglob.dump_moddef ?loc mp "mod";
Flags.if_verbose Feedback.msg_info
(str "Module " ++ Id.print id ++ str " is defined");
- Option.iter (fun export -> vernac_import export [qualid_of_ident id])
+ Option.iter (fun export -> vernac_import export [qualid_of_ident id, ImportAll])
export
let vernac_end_module export {loc;v=id} =
let mp = Declaremods.end_module () in
Dumpglob.dump_modref ?loc mp "mod";
Flags.if_verbose Feedback.msg_info (str "Module " ++ Id.print id ++ str " is defined");
- Option.iter (fun export -> vernac_import export [qualid_of_ident ?loc id]) export
+ Option.iter (fun export -> vernac_import export [qualid_of_ident ?loc id, ImportAll]) export
let vernac_declare_module_type {loc;v=id} binders_ast mty_sign mty_ast_l =
if Global.sections_are_opened () then
@@ -950,7 +1007,7 @@ let vernac_declare_module_type {loc;v=id} binders_ast mty_sign mty_ast_l =
List.iter
(fun (export,id) ->
Option.iter
- (fun export -> vernac_import export [qualid_of_ident ?loc id]) export
+ (fun export -> vernac_import export [qualid_of_ident ?loc id, ImportAll]) export
) argsexport
| _ :: _ ->
@@ -1110,7 +1167,7 @@ let focus_command_cond = Proof.no_cond command_focus
all tactics fail if there are no further goals to prove. *)
let vernac_solve_existential ~pstate n com =
- Proof_global.map_proof (fun p ->
+ Declare.Proof.map_proof (fun p ->
let intern env sigma = Constrintern.intern_constr env sigma com in
Proof.V82.instantiate_evar (Global.env ()) n intern p) pstate
@@ -1118,12 +1175,12 @@ let vernac_set_end_tac ~pstate tac =
let env = Genintern.empty_glob_sign (Global.env ()) in
let _, tac = Genintern.generic_intern env tac in
(* TO DO verifier s'il faut pas mettre exist s | TacId s ici*)
- Proof_global.set_endline_tactic tac pstate
+ Declare.Proof.set_endline_tactic tac pstate
-let vernac_set_used_variables ~pstate e : Proof_global.t =
+let vernac_set_used_variables ~pstate e : Declare.Proof.t =
let env = Global.env () in
let initial_goals pf = Proofview.initial_goals Proof.(data pf).Proof.entry in
- let tys = List.map snd (initial_goals (Proof_global.get_proof pstate)) in
+ let tys = List.map snd (initial_goals (Declare.Proof.get_proof pstate)) in
let tys = List.map EConstr.Unsafe.to_constr tys in
let l = Proof_using.process_expr env e tys in
let vars = Environ.named_context env in
@@ -1132,7 +1189,7 @@ let vernac_set_used_variables ~pstate e : Proof_global.t =
user_err ~hdr:"vernac_set_used_variables"
(str "Unknown variable: " ++ Id.print id))
l;
- let _, pstate = Proof_global.set_used_variables pstate l in
+ let _, pstate = Declare.Proof.set_used_variables pstate l in
pstate
(*****************************)
@@ -1218,7 +1275,7 @@ let vernac_hints ~atts dbnames h =
"This command does not support the export attribute in sections.");
| OptDefault | OptLocal -> ()
in
- Hints.add_hints ~locality dbnames (Hints.interp_hints ~poly h)
+ Hints.add_hints ~locality dbnames (ComHints.interp_hints ~poly h)
let vernac_syntactic_definition ~atts lid x only_parsing =
let module_local, deprecation = Attributes.(parse Notations.(module_locality ++ deprecation) atts) in
@@ -1244,16 +1301,26 @@ let vernac_generalizable ~local =
let local = Option.default true local in
Implicit_quantifiers.declare_generalizable ~local
+let allow_sprop_opt_name = ["Allow";"StrictProp"]
+let cumul_sprop_opt_name = ["Cumulative";"StrictProp"]
+
let () =
declare_bool_option
{ optdepr = false;
- optkey = ["Allow";"StrictProp"];
+ optkey = allow_sprop_opt_name;
optread = (fun () -> Global.sprop_allowed());
optwrite = Global.set_allow_sprop }
let () =
declare_bool_option
{ optdepr = false;
+ optkey = cumul_sprop_opt_name;
+ optread = Global.is_cumulative_sprop;
+ optwrite = Global.set_cumulative_sprop }
+
+let () =
+ declare_bool_option
+ { optdepr = false;
optkey = ["Silent"];
optread = (fun () -> !Flags.quiet);
optwrite = ((:=) Flags.quiet) }
@@ -1429,41 +1496,20 @@ let () =
optwrite = CWarnings.set_flags }
let () =
- declare_string_option
- { optdepr = false;
- optkey = ["NativeCompute"; "Profile"; "Filename"];
- optread = Nativenorm.get_profile_filename;
- optwrite = Nativenorm.set_profile_filename }
-
-let () =
- declare_bool_option
- { optdepr = false;
- optkey = ["NativeCompute"; "Profiling"];
- optread = Nativenorm.get_profiling_enabled;
- optwrite = Nativenorm.set_profiling_enabled }
-
-let () =
- declare_bool_option
- { optdepr = false;
- optkey = ["NativeCompute"; "Timing"];
- optread = Nativenorm.get_timing_enabled;
- optwrite = Nativenorm.set_timing_enabled }
-
-let _ =
declare_bool_option
{ optdepr = false;
optkey = ["Guard"; "Checking"];
optread = (fun () -> (Global.typing_flags ()).Declarations.check_guarded);
optwrite = (fun b -> Global.set_check_guarded b) }
-let _ =
+let () =
declare_bool_option
{ optdepr = false;
optkey = ["Positivity"; "Checking"];
optread = (fun () -> (Global.typing_flags ()).Declarations.check_positive);
optwrite = (fun b -> Global.set_check_positive b) }
-let _ =
+let () =
declare_bool_option
{ optdepr = false;
optkey = ["Universe"; "Checking"];
@@ -1516,26 +1562,11 @@ let vernac_set_option ~locality table v = match v with
vernac_set_option0 ~locality table v
| _ -> vernac_set_option0 ~locality table v
-let vernac_add_option key lv =
- let f = function
- | StringRefValue s -> (get_string_table key).add (Global.env()) s
- | QualidRefValue locqid -> (get_ref_table key).add (Global.env()) locqid
- in
- try List.iter f lv with Not_found -> error_undeclared_key key
+let vernac_add_option = iter_table { aux = fun table -> table.add }
-let vernac_remove_option key lv =
- let f = function
- | StringRefValue s -> (get_string_table key).remove (Global.env()) s
- | QualidRefValue locqid -> (get_ref_table key).remove (Global.env()) locqid
- in
- try List.iter f lv with Not_found -> error_undeclared_key key
+let vernac_remove_option = iter_table { aux = fun table -> table.remove }
-let vernac_mem_option key lv =
- let f = function
- | StringRefValue s -> (get_string_table key).mem (Global.env()) s
- | QualidRefValue locqid -> (get_ref_table key).mem (Global.env()) locqid
- in
- try List.iter f lv with Not_found -> error_undeclared_key key
+let vernac_mem_option = iter_table { aux = fun table -> table.mem }
let vernac_print_option key =
try (get_ref_table key).print ()
@@ -1551,8 +1582,8 @@ let get_current_context_of_args ~pstate =
let env = Global.env () in Evd.(from_env env, env)
| Some lemma ->
function
- | Some n -> Pfedit.get_goal_context lemma n
- | None -> Pfedit.get_current_context lemma
+ | Some n -> Declare.get_goal_context lemma n
+ | None -> Declare.get_current_context lemma
let query_command_selector ?loc = function
| None -> None
@@ -1617,7 +1648,7 @@ let vernac_global_check c =
let get_nth_goal ~pstate n =
- let pf = Proof_global.get_proof pstate in
+ let pf = Declare.Proof.get_proof pstate in
let Proof.{goals;sigma} = Proof.data pf in
let gl = {Evd.it=List.nth goals (n-1) ; sigma = sigma; } in
gl
@@ -1652,7 +1683,7 @@ let print_about_hyp_globs ~pstate ?loc ref_or_by_not udecl glopt =
let natureofid = match decl with
| LocalAssum _ -> "Hypothesis"
| LocalDef (_,bdy,_) ->"Constant (let in)" in
- let sigma, env = Pfedit.get_current_context pstate in
+ let sigma, env = Declare.get_current_context pstate in
v 0 (Id.print id ++ str":" ++ pr_econstr_env env sigma (NamedDecl.get_type decl) ++ fnl() ++ fnl()
++ str natureofid ++ str " of the goal context.")
with (* fallback to globals *)
@@ -1696,7 +1727,8 @@ let vernac_print ~pstate ~atts =
| PrintHintGoal ->
begin match pstate with
| Some pstate ->
- Hints.pr_applicable_hint pstate
+ let pf = Declare.Proof.get_proof pstate in
+ Hints.pr_applicable_hint pf
| None ->
str "No proof in progress"
end
@@ -1855,7 +1887,7 @@ let vernac_register qid r =
(* Proof management *)
let vernac_focus ~pstate gln =
- Proof_global.map_proof (fun p ->
+ Declare.Proof.map_proof (fun p ->
match gln with
| None -> Proof.focus focus_command_cond () 1 p
| Some 0 ->
@@ -1866,13 +1898,13 @@ let vernac_focus ~pstate gln =
(* Unfocuses one step in the focus stack. *)
let vernac_unfocus ~pstate =
- Proof_global.map_proof
+ Declare.Proof.map_proof
(fun p -> Proof.unfocus command_focus p ())
pstate
(* Checks that a proof is fully unfocused. Raises an error if not. *)
let vernac_unfocused ~pstate =
- let p = Proof_global.get_proof pstate in
+ let p = Declare.Proof.get_proof pstate in
if Proof.unfocused p then
str"The proof is indeed fully unfocused."
else
@@ -1885,7 +1917,7 @@ let subproof_kind = Proof.new_focus_kind ()
let subproof_cond = Proof.done_cond subproof_kind
let vernac_subproof gln ~pstate =
- Proof_global.map_proof (fun p ->
+ Declare.Proof.map_proof (fun p ->
match gln with
| None -> Proof.focus subproof_cond () 1 p
| Some (Goal_select.SelectNth n) -> Proof.focus subproof_cond () n p
@@ -1895,12 +1927,12 @@ let vernac_subproof gln ~pstate =
pstate
let vernac_end_subproof ~pstate =
- Proof_global.map_proof (fun p ->
+ Declare.Proof.map_proof (fun p ->
Proof.unfocus subproof_kind p ())
pstate
let vernac_bullet (bullet : Proof_bullet.t) ~pstate =
- Proof_global.map_proof (fun p ->
+ Declare.Proof.map_proof (fun p ->
Proof_bullet.put p bullet) pstate
(* Stack is needed due to show proof names, should deprecate / remove
@@ -1917,7 +1949,7 @@ let vernac_show ~pstate =
end
(* Show functions that require a proof state *)
| Some pstate ->
- let proof = Proof_global.get_proof pstate in
+ let proof = Declare.Proof.get_proof pstate in
begin function
| ShowGoal goalref ->
begin match goalref with
@@ -1929,14 +1961,14 @@ let vernac_show ~pstate =
| ShowUniverses -> show_universes ~proof
(* Deprecate *)
| ShowProofNames ->
- Id.print (Proof_global.get_proof_name pstate)
+ Id.print (Declare.Proof.get_proof_name pstate)
| ShowIntros all -> show_intro ~proof all
| ShowProof -> show_proof ~pstate:(Some pstate)
| ShowMatch id -> show_match id
end
let vernac_check_guard ~pstate =
- let pts = Proof_global.get_proof pstate in
+ let pts = Declare.Proof.get_proof pstate in
let pfterm = List.hd (Proof.partial_proof pts) in
let message =
try
diff --git a/vernac/vernacentries.mli b/vernac/vernacentries.mli
index f5cf9702cd..cf233248d7 100644
--- a/vernac/vernacentries.mli
+++ b/vernac/vernacentries.mli
@@ -24,3 +24,6 @@ val interp_redexp_hook : (Environ.env -> Evd.evar_map -> Genredexpr.raw_red_expr
(** Miscellaneous stuff *)
val command_focus : unit Proof.focus_kind
+
+val allow_sprop_opt_name : string list
+val cumul_sprop_opt_name : string list
diff --git a/vernac/vernacexpr.ml b/vernac/vernacexpr.ml
index d6e7a3947a..b622fd9801 100644
--- a/vernac/vernacexpr.ml
+++ b/vernac/vernacexpr.ml
@@ -101,7 +101,14 @@ type verbose_flag = bool (* true = Verbose; false = Silent *)
type coercion_flag = bool (* true = AddCoercion false = NoCoercion *)
type instance_flag = bool option
(* Some true = Backward instance; Some false = Forward instance, None = NoInstance *)
+
type export_flag = bool (* true = Export; false = Import *)
+
+type one_import_filter_name = qualid * bool (* import inductive components *)
+type import_filter_expr =
+ | ImportAll
+ | ImportNames of one_import_filter_name list
+
type onlyparsing_flag = { onlyparsing : bool }
(* Some v = Parse only; None = Print also.
If v<>Current, it contains the name of the coq version
@@ -114,10 +121,6 @@ type option_setting =
| OptionSetInt of int
| OptionSetString of string
-type option_ref_value =
- | StringRefValue of string
- | QualidRefValue of qualid
-
(** Identifier and optional list of bound universes and constraints. *)
type sort_expr = Sorts.family
@@ -192,10 +195,12 @@ type syntax_modifier =
| SetOnlyPrinting
| SetFormat of string * lstring
+type opacity_flag = Opaque | Transparent
+
type proof_end =
| Admitted
(* name in `Save ident` when closing goal *)
- | Proved of Proof_global.opacity_flag * lident option
+ | Proved of opacity_flag * lident option
type scheme =
| InductionScheme of bool * qualid or_by_notation * sort_expr
@@ -283,6 +288,22 @@ type extend_name =
type discharge = DoDischarge | NoDischarge
+type hint_info_expr = Constrexpr.constr_pattern_expr Typeclasses.hint_info_gen
+
+type reference_or_constr =
+ | HintsReference of Libnames.qualid
+ | HintsConstr of Constrexpr.constr_expr
+
+type hints_expr =
+ | HintsResolve of (hint_info_expr * bool * reference_or_constr) list
+ | HintsResolveIFF of bool * Libnames.qualid list * int option
+ | HintsImmediate of reference_or_constr list
+ | HintsUnfold of Libnames.qualid list
+ | HintsTransparency of Libnames.qualid Hints.hints_transparency_target * bool
+ | HintsMode of Libnames.qualid * Hints.hint_mode list
+ | HintsConstructors of Libnames.qualid list
+ | HintsExtern of int * Constrexpr.constr_expr option * Genarg.raw_generic_argument
+
type nonrec vernac_expr =
| VernacLoad of verbose_flag * string
@@ -320,7 +341,7 @@ type nonrec vernac_expr =
| VernacEndSegment of lident
| VernacRequire of
qualid option * export_flag option * qualid list
- | VernacImport of export_flag * qualid list
+ | VernacImport of export_flag * (qualid * import_filter_expr) list
| VernacCanonical of qualid or_by_notation
| VernacCoercion of qualid or_by_notation *
class_rawexpr * class_rawexpr
@@ -333,18 +354,18 @@ type nonrec vernac_expr =
local_binder_expr list * (* binders *)
constr_expr * (* type *)
(bool * constr_expr) option * (* body (bool=true when using {}) *)
- Hints.hint_info_expr
+ hint_info_expr
| VernacDeclareInstance of
ident_decl * (* name *)
local_binder_expr list * (* binders *)
constr_expr * (* type *)
- Hints.hint_info_expr
+ hint_info_expr
| VernacContext of local_binder_expr list
| VernacExistingInstance of
- (qualid * Hints.hint_info_expr) list (* instances names, priorities and patterns *)
+ (qualid * hint_info_expr) list (* instances names, priorities and patterns *)
| VernacExistingClass of qualid (* inductive or definition name *)
@@ -384,7 +405,7 @@ type nonrec vernac_expr =
(* Commands *)
| VernacCreateHintDb of string * bool
| VernacRemoveHints of string list * qualid list
- | VernacHints of string list * Hints.hints_expr
+ | VernacHints of string list * hints_expr
| VernacSyntacticDefinition of
lident * (Id.t list * constr_expr) *
onlyparsing_flag
@@ -399,9 +420,9 @@ type nonrec vernac_expr =
| VernacSetStrategy of
(Conv_oracle.level * qualid or_by_notation list) list
| VernacSetOption of bool (* Export modifier? *) * Goptions.option_name * option_setting
- | VernacAddOption of Goptions.option_name * option_ref_value list
- | VernacRemoveOption of Goptions.option_name * option_ref_value list
- | VernacMemOption of Goptions.option_name * option_ref_value list
+ | VernacAddOption of Goptions.option_name * Goptions.table_value list
+ | VernacRemoveOption of Goptions.option_name * Goptions.table_value list
+ | VernacMemOption of Goptions.option_name * Goptions.table_value list
| VernacPrintOption of Goptions.option_name
| VernacCheckMayEval of Genredexpr.raw_red_expr option * Goal_select.t option * constr_expr
| VernacGlobalCheck of constr_expr
diff --git a/vernac/vernacextend.ml b/vernac/vernacextend.ml
index 1920c276af..d772f274a2 100644
--- a/vernac/vernacextend.ml
+++ b/vernac/vernacextend.ml
@@ -57,9 +57,9 @@ type typed_vernac =
| VtNoProof of (unit -> unit)
| VtCloseProof of (lemma:Lemmas.t -> unit)
| VtOpenProof of (unit -> Lemmas.t)
- | VtModifyProof of (pstate:Proof_global.t -> Proof_global.t)
- | VtReadProofOpt of (pstate:Proof_global.t option -> unit)
- | VtReadProof of (pstate:Proof_global.t -> unit)
+ | VtModifyProof of (pstate:Declare.Proof.t -> Declare.Proof.t)
+ | VtReadProofOpt of (pstate:Declare.Proof.t option -> unit)
+ | VtReadProof of (pstate:Declare.Proof.t -> unit)
type vernac_command = atts:Attributes.vernac_flags -> typed_vernac
diff --git a/vernac/vernacextend.mli b/vernac/vernacextend.mli
index 0d0ebc1086..58c267080a 100644
--- a/vernac/vernacextend.mli
+++ b/vernac/vernacextend.mli
@@ -75,9 +75,9 @@ type typed_vernac =
| VtNoProof of (unit -> unit)
| VtCloseProof of (lemma:Lemmas.t -> unit)
| VtOpenProof of (unit -> Lemmas.t)
- | VtModifyProof of (pstate:Proof_global.t -> Proof_global.t)
- | VtReadProofOpt of (pstate:Proof_global.t option -> unit)
- | VtReadProof of (pstate:Proof_global.t -> unit)
+ | VtModifyProof of (pstate:Declare.Proof.t -> Declare.Proof.t)
+ | VtReadProofOpt of (pstate:Declare.Proof.t option -> unit)
+ | VtReadProof of (pstate:Declare.Proof.t -> unit)
type vernac_command = atts:Attributes.vernac_flags -> typed_vernac
diff --git a/vernac/vernacinterp.ml b/vernac/vernacinterp.ml
index 15a19c06c2..19d41c4770 100644
--- a/vernac/vernacinterp.ml
+++ b/vernac/vernacinterp.ml
@@ -51,24 +51,17 @@ let interp_typed_vernac c ~stack =
(* Default proof mode, to be set at the beginning of proofs for
programs that cannot be statically classified. *)
-let default_proof_mode = ref (Pvernac.register_proof_mode "Noedit" Pvernac.Vernac_.noedit_mode)
-let get_default_proof_mode () = !default_proof_mode
+let proof_mode_opt_name = ["Default";"Proof";"Mode"]
-let get_default_proof_mode_opt () = Pvernac.proof_mode_to_string !default_proof_mode
-let set_default_proof_mode_opt name =
- default_proof_mode :=
- match Pvernac.lookup_proof_mode name with
+let get_default_proof_mode =
+ Goptions.declare_interpreted_string_option_and_ref
+ ~depr:false
+ ~key:proof_mode_opt_name
+ ~value:(Pvernac.register_proof_mode "Noedit" Pvernac.Vernac_.noedit_mode)
+ (fun name -> match Pvernac.lookup_proof_mode name with
| Some pm -> pm
- | None -> CErrors.user_err Pp.(str (Format.sprintf "No proof mode named \"%s\"." name))
-
-let proof_mode_opt_name = ["Default";"Proof";"Mode"]
-let () =
- Goptions.declare_string_option Goptions.{
- optdepr = false;
- optkey = proof_mode_opt_name;
- optread = get_default_proof_mode_opt;
- optwrite = set_default_proof_mode_opt;
- }
+ | None -> CErrors.user_err Pp.(str (Format.sprintf "No proof mode named \"%s\"." name)))
+ Pvernac.proof_mode_to_string
(** A global default timeout, controlled by option "Set Default Timeout n".
Use "Unset Default Timeout" to deactivate it (or set it to 0). *)
@@ -216,7 +209,7 @@ and interp_control ~st ({ CAst.v = cmd } as vernac) =
let before_univs = Global.universes () in
let pstack = interp_expr ~atts:cmd.attrs ~st cmd.expr in
if before_univs == Global.universes () then pstack
- else Option.map (Vernacstate.LemmaStack.map_top_pstate ~f:Proof_global.update_global_env) pstack)
+ else Option.map (Vernacstate.LemmaStack.map_top_pstate ~f:Declare.Proof.update_global_env) pstack)
~st
(* XXX: This won't properly set the proof mode, as of today, it is
@@ -258,7 +251,7 @@ let interp_gen ~verbosely ~st ~interp_fn cmd =
try vernac_timeout (fun st ->
let v_mod = if verbosely then Flags.verbosely else Flags.silently in
let ontop = v_mod (interp_fn ~st) cmd in
- Vernacstate.Proof_global.set ontop [@ocaml.warning "-3"];
+ Vernacstate.Declare.set ontop [@ocaml.warning "-3"];
Vernacstate.freeze_interp_state ~marshallable:false
) st
with exn ->
diff --git a/vernac/vernacinterp.mli b/vernac/vernacinterp.mli
index 9f5bfb46ee..e3e708e87d 100644
--- a/vernac/vernacinterp.mli
+++ b/vernac/vernacinterp.mli
@@ -14,7 +14,7 @@ val interp : ?verbosely:bool -> st:Vernacstate.t -> Vernacexpr.vernac_control ->
(** Execute a Qed but with a proof_object which may contain a delayed
proof and won't be forced *)
val interp_qed_delayed_proof
- : proof:Proof_global.proof_object
+ : proof:Declare.proof_object
-> info:Lemmas.Info.t
-> st:Vernacstate.t
-> control:Vernacexpr.control_flag list
diff --git a/vernac/vernacstate.ml b/vernac/vernacstate.ml
index 6846826bfa..0fca1e9078 100644
--- a/vernac/vernacstate.ml
+++ b/vernac/vernacstate.ml
@@ -45,7 +45,7 @@ module LemmaStack = struct
| Some (l,ls) -> a, (l :: ls)
let get_all_proof_names (pf : t) =
- let prj x = Lemmas.pf_fold Proof_global.get_proof x in
+ let prj x = Lemmas.pf_fold Declare.Proof.get_proof x in
let (pn, pns) = map Proof.(function pf -> (data (prj pf)).name) pf in
pn :: pns
@@ -105,7 +105,7 @@ let make_shallow st =
}
(* Compatibility module *)
-module Proof_global = struct
+module Declare = struct
let get () = !s_lemmas
let set x = s_lemmas := x
@@ -126,7 +126,7 @@ module Proof_global = struct
end
open Lemmas
- open Proof_global
+ open Declare
let cc f = match !s_lemmas with
| None -> raise NoCurrentProof
@@ -145,39 +145,40 @@ module Proof_global = struct
| Some x -> s_lemmas := Some (LemmaStack.map_top_pstate ~f x)
let there_are_pending_proofs () = !s_lemmas <> None
- let get_open_goals () = cc get_open_goals
+ let get_open_goals () = cc Proof.get_open_goals
- let give_me_the_proof_opt () = Option.map (LemmaStack.with_top_pstate ~f:get_proof) !s_lemmas
- let give_me_the_proof () = cc get_proof
- let get_current_proof_name () = cc get_proof_name
+ let give_me_the_proof_opt () = Option.map (LemmaStack.with_top_pstate ~f:Proof.get_proof) !s_lemmas
+ let give_me_the_proof () = cc Proof.get_proof
+ let get_current_proof_name () = cc Proof.get_proof_name
- let map_proof f = dd (map_proof f)
+ let map_proof f = dd (Proof.map_proof f)
let with_current_proof f =
match !s_lemmas with
| None -> raise NoCurrentProof
| Some stack ->
- let pf, res = LemmaStack.with_top_pstate stack ~f:(map_fold_proof_endline f) in
+ let pf, res = LemmaStack.with_top_pstate stack ~f:(Proof.map_fold_proof_endline f) in
let stack = LemmaStack.map_top_pstate stack ~f:(fun _ -> pf) in
s_lemmas := Some stack;
res
- type closed_proof = Proof_global.proof_object * Lemmas.Info.t
+ type closed_proof = Declare.proof_object * Lemmas.Info.t
- let return_proof ?allow_partial () = cc (return_proof ?allow_partial)
+ let return_proof () = cc return_proof
+ let return_partial_proof () = cc return_partial_proof
- let close_future_proof ~opaque ~feedback_id pf =
- cc_lemma (fun pt -> pf_fold (fun st -> close_future_proof ~opaque ~feedback_id st pf) pt,
- Internal.get_info pt)
+ let close_future_proof ~feedback_id pf =
+ cc_lemma (fun pt -> pf_fold (fun st -> close_future_proof ~feedback_id st pf) pt,
+ Lemmas.Internal.get_info pt)
- let close_proof ~opaque ~keep_body_ucst_separate f =
- cc_lemma (fun pt -> pf_fold ((close_proof ~opaque ~keep_body_ucst_separate f)) pt,
- Internal.get_info pt)
+ let close_proof ~opaque ~keep_body_ucst_separate =
+ cc_lemma (fun pt -> pf_fold ((close_proof ~opaque ~keep_body_ucst_separate)) pt,
+ Lemmas.Internal.get_info pt)
let discard_all () = s_lemmas := None
- let update_global_env () = dd (update_global_env)
+ let update_global_env () = dd (Proof.update_global_env)
- let get_current_context () = cc Pfedit.get_current_context
+ let get_current_context () = cc Declare.get_current_context
let get_all_proof_names () =
try cc_stack LemmaStack.get_all_proof_names
diff --git a/vernac/vernacstate.mli b/vernac/vernacstate.mli
index 7607f8373a..fb6d8b6db6 100644
--- a/vernac/vernacstate.mli
+++ b/vernac/vernacstate.mli
@@ -25,8 +25,8 @@ module LemmaStack : sig
val pop : t -> Lemmas.t * t option
val push : t option -> Lemmas.t -> t
- val map_top_pstate : f:(Proof_global.t -> Proof_global.t) -> t -> t
- val with_top_pstate : t -> f:(Proof_global.t -> 'a ) -> 'a
+ val map_top_pstate : f:(Declare.Proof.t -> Declare.Proof.t) -> t -> t
+ val with_top_pstate : t -> f:(Declare.Proof.t -> 'a ) -> 'a
end
@@ -50,7 +50,7 @@ val make_shallow : t -> t
val invalidate_cache : unit -> unit
(* Compatibility module: Do Not Use *)
-module Proof_global : sig
+module Declare : sig
exception NoCurrentProof
@@ -65,16 +65,16 @@ module Proof_global : sig
val with_current_proof :
(unit Proofview.tactic -> Proof.t -> Proof.t * 'a) -> 'a
- val return_proof : ?allow_partial:bool -> unit -> Proof_global.closed_proof_output
+ val return_proof : unit -> Declare.closed_proof_output
+ val return_partial_proof : unit -> Declare.closed_proof_output
- type closed_proof = Proof_global.proof_object * Lemmas.Info.t
+ type closed_proof = Declare.proof_object * Lemmas.Info.t
val close_future_proof :
- opaque:Proof_global.opacity_flag ->
feedback_id:Stateid.t ->
- Proof_global.closed_proof_output Future.computation -> closed_proof
+ Declare.closed_proof_output Future.computation -> closed_proof
- val close_proof : opaque:Proof_global.opacity_flag -> keep_body_ucst_separate:bool -> Future.fix_exn -> closed_proof
+ val close_proof : opaque:Declare.opacity_flag -> keep_body_ucst_separate:bool -> closed_proof
val discard_all : unit -> unit
val update_global_env : unit -> unit
@@ -89,7 +89,7 @@ module Proof_global : sig
val get : unit -> LemmaStack.t option
val set : LemmaStack.t option -> unit
- val get_pstate : unit -> Proof_global.t option
+ val get_pstate : unit -> Declare.Proof.t option
val freeze : marshallable:bool -> LemmaStack.t option
val unfreeze : LemmaStack.t -> unit