Add Printing Reversible flags: check printed terms reparse to equal terms, escalating printing options when not - #22283
Open
JasonGross wants to merge 1 commit into
Conversation
JasonGross
force-pushed
the
reversible-printing-options
branch
from
July 16, 2026 18:09
10f54af to
2cc8544
Compare
JasonGross
force-pushed
the
reversible-printing-options
branch
from
July 16, 2026 20:23
2cc8544 to
c80241f
Compare
JasonGross
force-pushed
the
reversible-printing-options
branch
from
July 21, 2026 00:04
c80241f to
3bbe92f
Compare
JasonGross
marked this pull request as ready for review
July 21, 2026 00:18
JasonGross
force-pushed
the
reversible-printing-options
branch
from
July 21, 2026 00:56
2f6b566 to
06b513d
Compare
JasonGross
force-pushed
the
reversible-printing-options
branch
from
July 27, 2026 02:44
06b513d to
66b2d7f
Compare
JasonGross
added a commit
to theorem-labs/rocq
that referenced
this pull request
Jul 27, 2026
Port of the fifth mode added to rocq-prover#22283: the reparsed form must be convertible with the original when sorts and universes are ignored entirely (Reductionops.is_conv_nounivs), the laxest of the conversion-based checks. Includes refman, changelog and output-test updates. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
JasonGross
added a commit
to theorem-labs/rocq
that referenced
this pull request
Jul 27, 2026
Port of the fifth mode added to rocq-prover#22283: the reparsed form must be convertible with the original when sorts and universes are ignored entirely, the laxest of the conversion-based checks. Implemented with a local fully-permissive conversion comparator since 9.2 lacks Reductionops.is_conv_nounivs. Includes refman, changelog and output-test updates. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
…erms, escalating printing options when not Add five mutually exclusive flags — Printing Reversible Up To Unification, Up To Conversion, Up To Conversion Modulo Universe Unification, Up To Conversion Modulo Universes, and Up To Conversion Modulo Sorts And Universes — under which the printer checks each printed term by reparsing and re-elaborating it and comparing the result against the original at the selected strictness. When the check fails, printing options are escalated until the printed form becomes reversible; if no combination suffices, a reversible-printing warning is emitted. Comparison modes: - Up To Unification: the reparse must unify with the original. - Up To Conversion: conversion, strict on universes. - Up To Conversion Modulo Universe Unification: conversion threading universe unification through the evar map (fails when e.g. a fresh flexible level cannot be equated with an algebraic universe). - Up To Conversion Modulo Universes: conversion ignoring universe levels and instance level components while requiring sort qualities to agree (SProp/Prop/Type distinct; quality variables compare structurally, so sort-polymorphic instances whose omission would change the elaborated quality are kept). - Up To Conversion Modulo Sorts And Universes: conversion ignoring sorts and universes entirely (Reductionops.is_conv_nounivs), the laxest of the conversion-based checks. Includes output tests, reference-manual documentation and a changelog entry. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
JasonGross
force-pushed
the
reversible-printing-options
branch
from
July 27, 2026 04:08
66b2d7f to
96cfce2
Compare
JasonGross
added a commit
to theorem-labs/rocq
that referenced
this pull request
Jul 27, 2026
Port of the fifth mode added to rocq-prover#22283: the reparsed form must be convertible with the original when sorts and universes are ignored entirely (Reductionops.is_conv_nounivs), the laxest of the conversion-based checks. Includes refman, changelog and output-test updates. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Written by Claude (Anthropic AI) at the request of and under the supervision of @JasonGross.
What
Five new mutually-exclusive flags (setting one unsets the others):
Set Printing Reversible Up To UnificationSet Printing Reversible Up To Conversion Modulo Sorts And UniversesSet Printing Reversible Up To Conversion Modulo UniversesSet Printing Reversible Up To Conversion Modulo Universe UnificationSet Printing Reversible Up To ConversionWhen one is set, every term print (
Printer.pr_econstr_env& friends:Check,Print,About, goal display, error messages, ...) goes through a reparsability check: the externalized term is rendered to a string, parsed back (with a fresh end-of-input variant of thelconstrentry), re-elaborated withinterp_open_constr, and compared to the original term up to the selected equivalence. When the check fails, printing options are progressively turned on — coercions, implicit arguments, unsetting notations, universes (first with, then without notations), parentheses, and finally the raw-print options ofPrinting All— until the printed form passes; if none does, the most explicit form is used and areversible-printingwarning is emitted.The five equivalences:
Reductionops.is_conv_nounivs): sort qualities, universe levels and universe instances may all differ. The laxest of the conversion-based checks.Conversion.generic_convcomparator):SetvsType@{u}is accepted,Prop/SProp/Typeare pairwise distinguished, and the quality components of instances are compared structurally — so a sort-polymorphic instance whose omission would change the elaborated quality stays printed.Reductionops.infer_conv): the universes (and sort qualities) introduced by the reparse may be unified against the original ones. Not comparable with the two previous modes in strictness: stricter on levels (a fresh level cannot be unified with an algebraic universe, so e.g. the sort ofCheck Typeescalates), laxer than Modulo Universes on qualities (they get unified rather than compared).Reductionops.is_conv) — universe instances of polymorphic constants generally get printed.Since neither conversion nor unification of two terms compares their types (kernel conversion does not compare lambda binder types, which is only complete when both sides share a type), the types of the original and reparsed terms are compared too when the printed expression stands for a term.
Example (from the test)
A printing-only notation that does not print what it parses escalates to unsetting notation printing (
2 + 3displayed through a lying notation gets printed asNat.add 2 3); goal display is checked as well (seetest-suite/output/ReversiblePrinting.v).Implementation notes
printing/reversiblePrinting.ml;printingalready depends onparsing, so the roundtrip really goes through the parser (catching printer/parser grammar mismatches), not just through re-internalization of theconstr_expr.PrintingFlags.trecords introduced recently, andPrinterrenders the chosenconstr_exprwith the flags that were used to produce it, so what is checked is exactly what is displayed.eq_constr_nounivsfast-path: that would treat sorts of different qualities as equal and erase exactly the sort-sensitivity that distinguishes it from Modulo Sorts And Universes.Caveats
Arguments-scoped subterm printers) are reparsed without that scope, which can cause spurious escalation.Check Type) are inherently unreparsable under strict conversion and under universe unification (but not under the two modulo-universes modes, which ignore the levels) and produce the warning there.🤖 Generated with Claude Code
https://claude.ai/code/session_019ttctspSoVoquHLQtbPVZw
https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b