Skip to content

Commit

Permalink
Validate Proof command: runs typing.ml on the current proof
Browse files Browse the repository at this point in the history
  • Loading branch information
SkySkimmer committed Apr 25, 2023
1 parent 4c4c43a commit 328e47a
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 1 deletion.
@@ -0,0 +1,5 @@
- **Added:**
:cmd:`Validate Proof` runs the type checker on the current proof,
complementary with :cmd:`Guarded` which runs the guard checker.
(`#17467 <https://github.com/coq/coq/pull/17467>`_,
by Gaëtan Gilbert).
5 changes: 5 additions & 0 deletions doc/sphinx/language/core/variants.rst
Expand Up @@ -39,6 +39,11 @@ Private (matching) inductive types
quotient types / higher-order inductive types in projects such as
the `HoTT library <https://github.com/HoTT/HoTT>`_.

Reducing definitions from the inductive's module can expose
:g:`match` to unification, which may result in invalid proof terms.
Errors from such terms are delayed until proof completion. Use
:cmd:`Validate Proof` to track down which tactic produced the problem term.

.. example::

.. coqtop:: all
Expand Down
8 changes: 8 additions & 0 deletions doc/sphinx/proofs/writing-proofs/proof-mode.rst
Expand Up @@ -1023,6 +1023,14 @@ Requesting information
fixpoint and cofixpoint is violated at some time of the construction
of the proof without having to wait the completion of the proof.

.. cmd:: Validate Proof

This command checks that the current partial proof is well-typed.
It is useful to track down tactic bugs as without it errors are
delayed until the proof is complete.

It does not check the guard condition, use :cmd:`Guarded` for that.

.. _showing_diffs:

Showing differences between proof steps
Expand Down
1 change: 1 addition & 0 deletions doc/tools/docgram/fullGrammar
Expand Up @@ -520,6 +520,7 @@ command: [
| "Show" "Intros"
| "Show" "Match" reference
| "Guarded"
| "Validate" "Proof"
| "Create" "HintDb" IDENT; [ "discriminated" | ]
| "Remove" "Hints" LIST1 global opt_hintbases
| "Hint" hint opt_hintbases
Expand Down
1 change: 1 addition & 0 deletions doc/tools/docgram/orderedGrammar
Expand Up @@ -818,6 +818,7 @@ command: [
| "Show" "Intros"
| "Show" "Match" qualid
| "Guarded"
| "Validate" "Proof"
| "Create" "HintDb" ident OPT "discriminated"
| "Remove" "Hints" LIST1 qualid OPT ( ":" LIST1 ident )
| "Comments" LIST0 [ one_term | string | natural ]
Expand Down
22 changes: 22 additions & 0 deletions test-suite/success/ValidateProof.v
@@ -0,0 +1,22 @@

Module M.
Private Inductive foo := .

Definition to_nat (f:foo) : nat := match f with end.
End M.

Lemma bar : False.
Proof.
exact_no_check I.
Fail Validate Proof.
Abort.

Lemma bar f : M.to_nat f = 0.
Proof.
Validate Proof.

cbv.

Fail Validate Proof.

Abort.
1 change: 1 addition & 0 deletions vernac/g_proofs.mlg
Expand Up @@ -95,6 +95,7 @@ GRAMMAR EXTEND Gram
| IDENT "Show"; IDENT "Intros" -> { VernacSynPure (VernacShow (ShowIntros true)) }
| IDENT "Show"; IDENT "Match"; id = reference -> { VernacSynPure (VernacShow (ShowMatch id)) }
| IDENT "Guarded" -> { VernacSynPure VernacCheckGuard }
| IDENT "Validate"; IDENT "Proof" -> { VernacSynPure VernacValidateProof }
(* Hints for Auto and EAuto *)
| IDENT "Create"; IDENT "HintDb" ;
id = IDENT ; b = [ IDENT "discriminated" -> { true } | -> { false } ] ->
Expand Down
2 changes: 2 additions & 0 deletions vernac/ppvernac.ml
Expand Up @@ -724,6 +724,8 @@ let pr_synpure_vernac_expr v =
| VernacCheckGuard ->
return (keyword "Guarded")

| VernacValidateProof -> return (keyword "Validate Proof")

(* Resetting *)
| VernacResetName id ->
return (keyword "Reset" ++ spc() ++ pr_lident id)
Expand Down
2 changes: 1 addition & 1 deletion vernac/vernac_classifier.ml
Expand Up @@ -100,7 +100,7 @@ let classify_vernac e =
| VernacProof _
| VernacFocus _ | VernacUnfocus
| VernacSubproof _
| VernacCheckGuard
| VernacCheckGuard | VernacValidateProof
| VernacUnfocused
| VernacBullet _ ->
VtProofStep { proof_block_detection = Some "bullet" }
Expand Down
43 changes: 43 additions & 0 deletions vernac/vernacentries.ml
Expand Up @@ -2109,6 +2109,45 @@ let vernac_check_guard ~pstate =
Inductiveops.control_only_guard env sigma pfterm;
str "The condition holds up to here."

let vernac_validate_proof ~pstate =
let pts = Declare.Proof.get pstate in
let { Proof.entry; Proof.sigma } = Proof.data pts in
let hyps, pfterm, pftyp = List.hd (Proofview.initial_goals entry) in
(* XXX can the initial hyps contain something broken? For now assume they're correct.
NB: in the "Lemma foo args : bla." case the args are part of the
term and intro'd after the proof is opened. Only the section
variables are in the hyps. *)
let env = Environ.reset_with_named_context hyps (Global.env ()) in
let sigma = Evarconv.solve_unif_constraints_with_heuristics env sigma in
let sigma' = Typing.check env sigma pfterm pftyp in
let evar_issues =
(* Use Evar.Map.merge as a kind of for_all2 *)
Evar.Map.merge (fun e orig now -> match orig, now with
| None, None -> assert false
| Some _, Some _ -> None (* assume same *)
| Some evi, None ->
let EvarInfo evi' = Evd.find sigma' e in
let body = match Evd.evar_body evi' with
| Evar_empty -> assert false
| Evar_defined body -> body
in
Some
Pp.(str "Evar " ++ Printer.pr_evar sigma (e, evi)
++ spc() ++ str "was inferred by unification to be" ++ spc()
++ pr_econstr_env (Evd.evar_env env evi') sigma' body)
| None, Some _ -> (* ignore new evar *)
assert (not (Evd.is_defined sigma e));
None
)
(Evd.undefined_map sigma)
(Evd.undefined_map sigma')
in
(* TODO check ustate *)

if Evar.Map.is_empty evar_issues then
str "No issues found."
else prlist_with_sep fnl snd (Evar.Map.bindings evar_issues)

let translate_vernac_synterp ?loc ~atts v = let open Vernacextend in match v with
| EVernacNotation { local; decl } ->
vtdefault(fun () -> Metasyntax.add_notation_interpretation ~local (Global.env()) decl)
Expand Down Expand Up @@ -2429,6 +2468,10 @@ let translate_pure_vernac ?loc ~atts v = let open Vernacextend in match v with
vtreadproof(fun ~pstate ->
unsupported_attributes atts;
Feedback.msg_notice @@ vernac_check_guard ~pstate)
| VernacValidateProof ->
vtreadproof(fun ~pstate ->
unsupported_attributes atts;
Feedback.msg_notice @@ vernac_validate_proof ~pstate)
| VernacProof (tac, using) ->
vtmodifyproof(fun ~pstate ->
unsupported_attributes atts;
Expand Down
1 change: 1 addition & 0 deletions vernac/vernacexpr.mli
Expand Up @@ -486,6 +486,7 @@ type nonrec synpure_vernac_expr =
| VernacEndSubproof
| VernacShow of showable
| VernacCheckGuard
| VernacValidateProof
| VernacProof of Genarg.raw_generic_argument option * section_subset_expr option

| VernacAddOption of Goptions.option_name * Goptions.table_value list
Expand Down

0 comments on commit 328e47a

Please sign in to comment.