aboutsummaryrefslogtreecommitdiffhomepage
path: root/toplevel/obligations.ml
diff options
context:
space:
mode:
Diffstat (limited to 'toplevel/obligations.ml')
-rw-r--r--toplevel/obligations.ml184
1 files changed, 127 insertions, 57 deletions
diff --git a/toplevel/obligations.ml b/toplevel/obligations.ml
index d772af3c1..d937c400a 100644
--- a/toplevel/obligations.ml
+++ b/toplevel/obligations.ml
@@ -21,7 +21,7 @@ open Pp
open Errors
open Util
-let declare_fix_ref = ref (fun _ _ _ _ _ -> assert false)
+let declare_fix_ref = ref (fun _ _ _ _ _ _ -> assert false)
let declare_definition_ref = ref (fun _ _ _ _ _ -> assert false)
let trace s =
@@ -298,11 +298,15 @@ type obligation_info =
(Names.Id.t * Term.types * Evar_kinds.t Loc.located *
Evar_kinds.obligation_definition_status * Int.Set.t * unit Proofview.tactic option) array
+type 'a obligation_body =
+ | DefinedObl of 'a
+ | TermObl of constr
+
type obligation =
{ obl_name : Id.t;
obl_type : types;
obl_location : Evar_kinds.t Loc.located;
- obl_body : constr option;
+ obl_body : constant obligation_body option;
obl_status : Evar_kinds.obligation_definition_status;
obl_deps : Int.Set.t;
obl_tac : unit Proofview.tactic option;
@@ -320,6 +324,8 @@ type program_info = {
prg_name: Id.t;
prg_body: constr;
prg_type: constr;
+ prg_ctx: Univ.universe_context_set;
+ prg_subst : Universes.universe_opt_subst;
prg_obligations: obligations;
prg_deps : Id.t list;
prg_fixkind : fixpoint_kind option ;
@@ -383,27 +389,43 @@ let _ =
let evar_of_obligation o = make_evar (Global.named_context_val ()) o.obl_type
-let get_obligation_body expand obl =
- let c = Option.get obl.obl_body in
+let get_body subst obl =
+ match obl.obl_body with
+ | None -> assert false
+ | Some (DefinedObl c) ->
+ let _, ctx = Environ.constant_type_in_ctx (Global.env ()) c in
+ let pc = subst_univs_fn_puniverses (Univ.level_subst_of subst) (c, Univ.UContext.instance ctx) in
+ DefinedObl pc
+ | Some (TermObl c) ->
+ TermObl (subst_univs_fn_constr subst c)
+
+let get_obligation_body expand subst obl =
+ let c = get_body subst obl in
+ let c' =
if expand && obl.obl_status == Evar_kinds.Expand then
- match kind_of_term c with
- | Const c -> constant_value (Global.env ()) c
- | _ -> c
- else c
-
-let obl_substitution expand obls deps =
+ (match c with
+ | DefinedObl pc -> constant_value_in (Global.env ()) pc
+ | TermObl c -> c)
+ else (match c with
+ | DefinedObl pc -> mkConstU pc
+ | TermObl c -> c)
+ in c'
+
+let obl_substitution expand subst obls deps =
Int.Set.fold
(fun x acc ->
let xobl = obls.(x) in
let oblb =
- try get_obligation_body expand xobl
+ try get_obligation_body expand subst xobl
with e when Errors.noncritical e -> assert false
in (xobl.obl_name, (xobl.obl_type, oblb)) :: acc)
deps []
-let subst_deps expand obls deps t =
- let subst = obl_substitution expand obls deps in
- Vars.replace_vars (List.map (fun (n, (_, b)) -> n, b) subst) t
+let subst_deps expand subst obls deps t =
+ let subst = Universes.make_opt_subst subst in
+ let osubst = obl_substitution expand subst obls deps in
+ Vars.subst_univs_fn_constr subst
+ (Vars.replace_vars (List.map (fun (n, (_, b)) -> n, b) osubst) t)
let rec prod_app t n =
match kind_of_term (strip_outer_cast t) with
@@ -431,17 +453,18 @@ let replace_appvars subst =
in map_constr aux
let subst_prog expand obls ints prg =
- let subst = obl_substitution expand obls ints in
+ let usubst = Universes.make_opt_subst prg.prg_subst in
+ let subst = obl_substitution expand usubst obls ints in
if get_hide_obligations () then
(replace_appvars subst prg.prg_body,
- replace_appvars subst (Termops.refresh_universes prg.prg_type))
+ replace_appvars subst ((* Termops.refresh_universes *) prg.prg_type))
else
let subst' = List.map (fun (n, (_, b)) -> n, b) subst in
(Vars.replace_vars subst' prg.prg_body,
- Vars.replace_vars subst' (Termops.refresh_universes prg.prg_type))
+ Vars.replace_vars subst' ((* Termops.refresh_universes *) prg.prg_type))
-let subst_deps_obl obls obl =
- let t' = subst_deps true obls obl.obl_deps obl.obl_type in
+let subst_deps_obl subst obls obl =
+ let t' = subst_deps true subst obls obl.obl_deps obl.obl_type in
{ obl with obl_type = t' }
module ProgMap = Map.Make(Id)
@@ -509,6 +532,9 @@ let declare_definition prg =
{ const_entry_body = Future.from_val (body,Declareops.no_seff);
const_entry_secctx = None;
const_entry_type = Some typ;
+ const_entry_proj = None;
+ const_entry_polymorphic = pi2 prg.prg_kind;
+ const_entry_universes = Univ.ContextSet.to_context prg.prg_ctx;
const_entry_opaque = false;
const_entry_inline_code = false;
const_entry_feedback = None;
@@ -556,10 +582,9 @@ let declare_mutual_definition l =
let fixkind = Option.get first.prg_fixkind in
let arrrec, recvec = Array.of_list fixtypes, Array.of_list fixdefs in
let fixdecls = (Array.of_list (List.map (fun x -> Name x.prg_name) l), arrrec, recvec) in
+ let (local,poly,kind) = first.prg_kind in
let fixnames = first.prg_deps in
- let kind =
- fst first.prg_kind,
- if fixkind != IsCoFixpoint then Fixpoint else CoFixpoint in
+ let kind = if fixkind != IsCoFixpoint then Fixpoint else CoFixpoint in
let indexes, fixdecls =
match fixkind with
| IsFixpoint wfl ->
@@ -578,13 +603,15 @@ let declare_mutual_definition l =
mkCoFix (i,fixdecls),Declareops.no_seff) 0 l
in
(* Declare the recursive definitions *)
- let kns = List.map4 (!declare_fix_ref kind) fixnames fixdecls fixtypes fiximps in
+ let ctx = Univ.ContextSet.to_context first.prg_ctx in
+ let kns = List.map4 (!declare_fix_ref (local, poly, kind) ctx)
+ fixnames fixdecls fixtypes fiximps in
(* Declare notations *)
List.iter Metasyntax.add_notation_interpretation first.prg_notations;
Declare.recursive_message (fixkind != IsCoFixpoint) indexes fixnames;
let gr = List.hd kns in
let kn = match gr with ConstRef kn -> kn | _ -> assert false in
- first.prg_hook (fst first.prg_kind) gr;
+ first.prg_hook local gr;
List.iter progmap_remove l; kn
let shrink_body c =
@@ -597,20 +624,25 @@ let shrink_body c =
(b, 1, []) ctx
in List.map (fun (c,t) -> (c,None,t)) ctx, b', Array.of_list args
-let declare_obligation prg obl body =
+let declare_obligation prg obl body uctx =
let body = prg.prg_reduce body in
let ty = prg.prg_reduce obl.obl_type in
match obl.obl_status with
- | Evar_kinds.Expand -> { obl with obl_body = Some body }
+ | Evar_kinds.Expand -> { obl with obl_body = Some (TermObl body) }
| Evar_kinds.Define opaque ->
let opaque = if get_proofs_transparency () then false else opaque in
+ let poly = pi2 prg.prg_kind in
let ctx, body, args =
- if get_shrink_obligations () then shrink_body body else [], body, [||]
+ if get_shrink_obligations () && not poly then
+ shrink_body body else [], body, [||]
in
let ce =
{ const_entry_body = Future.from_val(body,Declareops.no_seff);
const_entry_secctx = None;
const_entry_type = if List.is_empty ctx then Some ty else None;
+ const_entry_proj = None;
+ const_entry_polymorphic = poly;
+ const_entry_universes = uctx;
const_entry_opaque = opaque;
const_entry_inline_code = false;
const_entry_feedback = None;
@@ -623,9 +655,13 @@ let declare_obligation prg obl body =
Auto.add_hints false [Id.to_string prg.prg_name]
(Auto.HintsUnfoldEntry [EvalConstRef constant]);
definition_message obl.obl_name;
- { obl with obl_body = Some (it_mkLambda_or_LetIn (mkApp (mkConst constant, args)) ctx) }
+ { obl with obl_body =
+ if poly then
+ Some (DefinedObl constant)
+ else
+ Some (TermObl (it_mkLambda_or_LetIn (mkApp (mkConst constant, args)) ctx)) }
-let init_prog_info n b t deps fixkind notations obls impls k reduce hook =
+let init_prog_info n b t ctx deps fixkind notations obls impls kind reduce hook =
let obls', b =
match b with
| None ->
@@ -645,9 +681,10 @@ let init_prog_info n b t deps fixkind notations obls impls k reduce hook =
obls, b
in
{ prg_name = n ; prg_body = b; prg_type = reduce t;
+ prg_ctx = ctx; prg_subst = Univ.LMap.empty;
prg_obligations = (obls', Array.length obls');
prg_deps = deps; prg_fixkind = fixkind ; prg_notations = notations ;
- prg_implicits = impls; prg_kind = k; prg_reduce = reduce;
+ prg_implicits = impls; prg_kind = kind; prg_reduce = reduce;
prg_hook = hook; }
let get_prog name =
@@ -734,14 +771,14 @@ let dependencies obls n =
obls;
!res
-let goal_kind = Decl_kinds.Local, Decl_kinds.DefinitionBody Decl_kinds.Definition
+let goal_kind poly = Decl_kinds.Local, poly, Decl_kinds.DefinitionBody Decl_kinds.Definition
-let goal_proof_kind = Decl_kinds.Local, Decl_kinds.Proof Decl_kinds.Lemma
+let goal_proof_kind poly = Decl_kinds.Local, poly, Decl_kinds.Proof Decl_kinds.Lemma
-let kind_of_opacity o =
+let kind_of_obligation poly o =
match o with
- | Evar_kinds.Define false | Evar_kinds.Expand -> goal_kind
- | _ -> goal_proof_kind
+ | Evar_kinds.Define false | Evar_kinds.Expand -> goal_kind poly
+ | _ -> goal_proof_kind poly
let not_transp_msg =
str "Obligation should be transparent but was declared opaque." ++ spc () ++
@@ -755,17 +792,37 @@ let rec string_of_list sep f = function
| x :: ((y :: _) as tl) -> f x ^ sep ^ string_of_list sep f tl
(* Solve an obligation using tactics, return the corresponding proof term *)
-let solve_by_tac evi t =
+
+let solve_by_tac evi t poly subst ctx =
let id = Id.of_string "H" in
+ let concl = Universes.subst_opt_univs_constr subst evi.evar_concl in
(* spiwack: the status is dropped *)
- let (entry,_) = Pfedit.build_constant_by_tactic
- id ~goal_kind evi.evar_hyps evi.evar_concl (Tacticals.New.tclCOMPLETE t) in
+ let (entry,_,subst) = Pfedit.build_constant_by_tactic
+ id ~goal_kind:(goal_kind poly) evi.evar_hyps (concl, ctx) (Tacticals.New.tclCOMPLETE t) in
let env = Global.env () in
let entry = Term_typing.handle_side_effects env entry in
let body, eff = Future.force entry.Entries.const_entry_body in
assert(Declareops.side_effects_is_empty eff);
Inductiveops.control_only_guard (Global.env ()) body;
- body
+ body, subst, entry.Entries.const_entry_universes
+
+ (* try *)
+ (* let substref = ref (Univ.LMap.empty, Univ.UContext.empty) in *)
+ (* Pfedit.start_proof id (goal_kind poly) evi.evar_hyps *)
+ (* (Universes.subst_opt_univs_constr subst evi.evar_concl, ctx) *)
+ (* (fun subst-> substref:=subst; fun _ _ -> ()); *)
+ (* Pfedit.by (tclCOMPLETE t); *)
+ (* let _,(const,_,_,_) = Pfedit.cook_proof ignore in *)
+ (* Pfedit.delete_current_proof (); *)
+ (* Inductiveops.control_only_guard (Global.env ()) *)
+ (* const.Entries.const_entry_body; *)
+ (* let subst, ctx = !substref in *)
+ (* subst_univs_fn_constr (Universes.make_opt_subst subst) const.Entries.const_entry_body, *)
+ (* subst, const.Entries.const_entry_universes *)
+ (* with reraise -> *)
+ (* let reraise = Errors.push reraise in *)
+ (* Pfedit.delete_current_proof(); *)
+ (* raise reraise *)
let rec solve_obligation prg num tac =
let user_num = succ num in
@@ -776,9 +833,12 @@ let rec solve_obligation prg num tac =
else
match deps_remaining obls obl.obl_deps with
| [] ->
- let obl = subst_deps_obl obls obl in
- Lemmas.start_proof obl.obl_name (kind_of_opacity obl.obl_status) obl.obl_type
- (fun strength gr ->
+ let ctx = prg.prg_ctx in
+ let obl = subst_deps_obl prg.prg_subst obls obl in
+ let kind = kind_of_obligation (pi2 prg.prg_kind) obl.obl_status in
+ Lemmas.start_proof obl.obl_name kind
+ (Universes.subst_opt_univs_constr prg.prg_subst obl.obl_type, ctx)
+ (fun strength gr ->
let cst = match gr with ConstRef cst -> cst | _ -> assert false in
let obl =
let transparent = evaluable_constant cst (Global.env ()) in
@@ -786,10 +846,10 @@ let rec solve_obligation prg num tac =
match obl.obl_status with
| Evar_kinds.Expand ->
if not transparent then error_not_transp ()
- else constant_value (Global.env ()) cst
+ else DefinedObl cst
| Evar_kinds.Define opaque ->
if not opaque && not transparent then error_not_transp ()
- else Globnames.constr_of_global gr
+ else DefinedObl cst
in
if transparent then
Auto.add_hints true [Id.to_string prg.prg_name]
@@ -798,8 +858,15 @@ let rec solve_obligation prg num tac =
in
let obls = Array.copy obls in
let _ = obls.(num) <- obl in
- let res =
- try update_obls prg obls (pred rem)
+(* let ctx = Univ.ContextSet.of_context ctx in *)
+ let subst = Univ.LMap.empty (** FIXME *) in
+ let res =
+ try update_obls
+ {prg with prg_body = Universes.subst_opt_univs_constr subst prg.prg_body;
+ prg_type = Universes.subst_opt_univs_constr subst prg.prg_type;
+ prg_ctx = ctx;
+ prg_subst = Univ.LMap.union prg.prg_subst subst}
+ obls (pred rem)
with e when Errors.noncritical e ->
pperror (Errors.print (Cerrors.process_vernac_interp_error e))
in
@@ -835,7 +902,7 @@ and solve_obligation_by_tac prg obls i tac =
| None ->
try
if List.is_empty (deps_remaining obls obl.obl_deps) then
- let obl = subst_deps_obl obls obl in
+ let obl = subst_deps_obl prg.prg_subst obls obl in
let tac =
match tac with
| Some t -> t
@@ -844,8 +911,11 @@ and solve_obligation_by_tac prg obls i tac =
| Some t -> t
| None -> snd (get_default_tactic ())
in
- let t = solve_by_tac (evar_of_obligation obl) tac in
- obls.(i) <- declare_obligation prg obl t;
+ let t, subst, ctx =
+ solve_by_tac (evar_of_obligation obl) tac
+ (pi2 prg.prg_kind) prg.prg_subst prg.prg_ctx
+ in
+ obls.(i) <- declare_obligation {prg with prg_subst = subst} obl t ctx;
true
else false
with e when Errors.noncritical e ->
@@ -929,10 +999,10 @@ let show_term n =
Printer.pr_constr_env (Global.env ()) prg.prg_type ++ spc () ++ str ":=" ++ fnl ()
++ Printer.pr_constr_env (Global.env ()) prg.prg_body)
-let add_definition n ?term t ?(implicits=[]) ?(kind=Global,Definition) ?tactic
+let add_definition n ?term t ctx ?(implicits=[]) ?(kind=Global,false,Definition) ?tactic
?(reduce=reduce) ?(hook=fun _ _ -> ()) obls =
let info = str (Id.to_string n) ++ str " has type-checked" in
- let prg = init_prog_info n term t [] None [] obls implicits kind reduce hook in
+ let prg = init_prog_info n term t ctx [] None [] obls implicits kind reduce hook in
let obls,_ = prg.prg_obligations in
if Int.equal (Array.length obls) 0 then (
Flags.if_verbose msg_info (info ++ str ".");
@@ -947,12 +1017,12 @@ let add_definition n ?term t ?(implicits=[]) ?(kind=Global,Definition) ?tactic
| Remain rem -> Flags.if_verbose (fun () -> show_obligations ~msg:false (Some n)) (); res
| _ -> res)
-let add_mutual_definitions l ?tactic ?(kind=Global,Definition) ?(reduce=reduce)
+let add_mutual_definitions l ctx ?tactic ?(kind=Global,false,Definition) ?(reduce=reduce)
?(hook=fun _ _ -> ()) notations fixkind =
let deps = List.map (fun (n, b, t, imps, obls) -> n) l in
List.iter
(fun (n, b, t, imps, obls) ->
- let prg = init_prog_info n (Some b) t deps (Some fixkind)
+ let prg = init_prog_info n (Some b) t ctx deps (Some fixkind)
notations obls imps kind reduce hook
in progmap_add n prg) l;
let _defined =
@@ -975,13 +1045,13 @@ let admit_prog prg =
(fun i x ->
match x.obl_body with
| None ->
- let x = subst_deps_obl obls x in
- (** ppedrot: seems legit to have admitted obligations as local *)
+ let x = subst_deps_obl prg.prg_subst obls x in
+ let ctx = Univ.ContextSet.to_context prg.prg_ctx in
let kn = Declare.declare_constant x.obl_name ~local:true
- (ParameterEntry (None, x.obl_type,None), IsAssumption Conjectural)
+ (ParameterEntry (None,false,(x.obl_type,ctx),None), IsAssumption Conjectural)
in
assumption_message x.obl_name;
- obls.(i) <- { x with obl_body = Some (mkConst kn) }
+ obls.(i) <- { x with obl_body = Some (DefinedObl kn) }
| Some _ -> ())
obls;
ignore(update_obls prg obls 0)