-
Notifications
You must be signed in to change notification settings - Fork 755
[rfc] Introduce a new ERASEcast kind for evaluation using verified erasure … #20503
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| (************************************************************************) | ||
| (* * 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 Constr | ||
| open Conversion | ||
|
|
||
| (** The erase evaluation function can either return an evaluated term or an error if the | ||
| evaluated term cannot be read back *) | ||
| type erase_evaluation_function = | ||
| Environ.env -> Constr.t -> types -> (Constr.t, unit) result | ||
|
|
||
| let erase_evaluation : erase_evaluation_function option ref = ref None | ||
|
|
||
| let install_erase_conv fn = | ||
| match !erase_evaluation with | ||
| | None -> erase_evaluation := Some fn | ||
| | Some _ -> CErrors.anomaly Pp.(str"Attempting to install erasure evaluation twice!") | ||
|
|
||
| let evaluate_term env c ty = | ||
| match !erase_evaluation with | ||
| | None -> Result.Error () | ||
| | Some ev -> ev env c ty | ||
|
|
||
| let evaluate_args env ctx args = | ||
| let open Context.Rel.Declaration in | ||
| if Int.equal (Array.length args) 0 then args else | ||
| let newargs = Array.make (Array.length args) args.(0) in | ||
| let ctx = Vars.smash_rel_context ctx in | ||
| let rec aux ctx n = | ||
| match ctx with | ||
| | LocalAssum (_, ty) :: ctx -> | ||
| let arg' = | ||
| match evaluate_term env args.(n) ty with | ||
| | Result.Ok arg' -> arg' | ||
| | Result.Error () -> args.(n) | ||
| in | ||
| newargs.(n) <- arg'; | ||
| (* ctx is a telescope (reverse context) *) | ||
| aux (List.rev (Vars.subst1_rel_context arg' (List.rev ctx))) (succ n) | ||
| | LocalDef _ :: _ -> assert false (* Context is smashed beforehand *) | ||
| | [] -> () | ||
| in | ||
| let () = aux (List.rev ctx) 0 in | ||
| newargs | ||
|
|
||
| let erase_eval env expected_type = | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see the point in having this function here instead of in the plugin. Why not call the cast eg CustomCast and directly install |
||
| let hd, args = Constr.decompose_app expected_type in | ||
| match Constr.kind hd with | ||
| | Ind (ind, u) -> | ||
| if Array.length args > 0 then | ||
| let specif = (Inductive.lookup_mind_specif env ind, u) in | ||
| let indty = Inductive.type_of_inductive specif in | ||
| let paramsctxt = (fst (fst specif)).Declarations.mind_params_ctxt in | ||
| let nparams = List.length paramsctxt in | ||
| let ctx, concl = Term.decompose_prod_n_decls nparams indty in | ||
| let params, indices = CArray.chop (fst (fst specif)).Declarations.mind_nparams args in | ||
| let instconcl = Vars.(substl (subst_of_rel_context_instance ctx params) concl) in | ||
| let indsctx, _ = Term.destArity instconcl in | ||
| let indices' = evaluate_args env indsctx indices in | ||
| let newty = Term.appvectc hd (Array.append params indices') in | ||
| Result.Ok newty | ||
| else Result.Error () | ||
| | _ -> Result.Error () | ||
|
|
||
| let erase_conv pb env ty ty' = | ||
| match erase_eval env ty' with | ||
| | Result.Ok newty -> default_conv pb env ty newty | ||
| | Result.Error () -> Result.Error () | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| (************************************************************************) | ||
| (* * 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 Constr | ||
| open Conversion | ||
|
|
||
| val erase_eval : Environ.env -> Constr.t -> (Constr.t, unit) result | ||
|
|
||
| val erase_conv : conv_pb -> types kernel_conversion_function | ||
|
|
||
| (** The erase evaluation function can either return an evaluated term or an error if the | ||
| evaluated term cannot be read back *) | ||
| type erase_evaluation_function = | ||
| Environ.env -> Constr.t -> types -> (Constr.t, unit) result | ||
|
|
||
| (** Link a specific evaluation function. By default it is the function always returning an error. *) | ||
| val install_erase_conv : erase_evaluation_function -> unit |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1528,6 +1528,19 @@ struct | |
| error_actual_type ?loc !!env sigma cj tval | ||
| (ConversionFailed (!!env,cty,tval)) | ||
| end | ||
| | Some ERASEcast -> | ||
| let tval = nf_evar sigma tval in | ||
| let exp = EConstr.to_constr_opt sigma tval in | ||
| begin | ||
| match exp with | ||
| | Some exp -> | ||
| (match Eraseconv.erase_eval !!env exp with | ||
| | Result.Ok newexp -> pretype (mk_tycon (EConstr.of_constr newexp)) env sigma c, tval | ||
| | Result.Error () -> user_err ?loc Pp.(str"Erasure evaluation failed for type" ++ spc () ++ | ||
| quote (Termops.Internal.print_constr_env !!env sigma tval))) | ||
| | None -> user_err ?loc Pp.(str"Erasure casts do not support evars in the expected type:" ++ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this check is incomplete, the env may contain evars too
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, and we should check for a closed env as well. |
||
| quote (Termops.Internal.print_constr_env !!env sigma tval)) | ||
| end | ||
| | None | Some DEFAULTcast -> | ||
| pretype (mk_tycon tval) env sigma c, tval | ||
| in | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Fail Check (2 <<<: nat). | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about allow returning a message (Pp.t) in the error case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed that will be done :)