Skip to content
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

feat: elidible subterms #3201

Merged
merged 15 commits into from
Jan 31, 2024
Merged

Conversation

mhuisi
Copy link
Contributor

@mhuisi mhuisi commented Jan 19, 2024

This PR adds two new delaboration settings: pp.deepTerms : Bool (default: true) and pp.deepTerms.threshold : Nat (default: 20).

Setting pp.deepTerms to false will make the delaborator terminate early after pp.deepTerms.threshold layers of recursion and replace the omitted subterm with the symbol if the subterm is deeper than pp.deepTerms.threshold / 4 (i.e. it is not shallow). To display the omitted subterm in the InfoView, can be clicked to open a popup with the delaborated subterm.

InfoView with pp.deepTerms set to false (click to show image)

image

Implementation

  • The delaborator is adjusted to use the new configuration settings and terminate early if the threshold is exceeded and the corresponding term to omit is shallow.
  • To be able to distinguish from regular terms, a new constructor Lean.Elab.Info.ofOmissionInfo is added to Lean.Elab.Info that takes a value of a new type Lean.Elab.OmissionInfo.
    • ofOmissionInfo is needed in Lean.Widget.makePopup for the Lean.Widget.InteractiveDiagnostics.infoToInteractive RPC procedure that is used to display popups when clicking on terms in the InfoView. It ensures that the expansion of an omitted subterm is delaborated using explicit := false, which is typically set to true in popups for regular terms.
    • Several Info widget utility functions are adjusted to support ofOmissionInfo.
  • The list delaborator is adjusted with special support for so that long lists [x₁, ..., xₖ, ..., xₙ] are shortened to [x₁, ..., xₖ, ⋯].

@mhuisi mhuisi requested a review from kmill January 19, 2024 13:26
@mhuisi mhuisi requested review from Kha and leodemoura as code owners January 19, 2024 13:26
@github-actions github-actions bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Jan 19, 2024
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4 that referenced this pull request Jan 19, 2024
@nomeata
Copy link
Collaborator

nomeata commented Jan 19, 2024

Neat!

Just based on the PR description, for lists and arrays, did you consider putting the ellipsis in the middle, in case the user cares more about what's at the end?

@mhuisi
Copy link
Contributor Author

mhuisi commented Jan 19, 2024

One of the reasons why we are implementing this setting is because complete delaboration takes a significant amount of time for some users with especially large terms - it's not just for readability. Putting it somewhere in the middle would require us to traverse the full term, erasing this benefit of the option.

I'm also not sure if it's easy to implement just for lists with the existing delaboration architecture (whether a term should be omitted is controlled by the function steering the delaboration, not individual delaborators - the adjusted list delaborator in this PR is merely propagating the omitted term for readability).

@nomeata
Copy link
Collaborator

nomeata commented Jan 19, 2024

That makes sense, thanks for the explanation!

@leanprover-community-mathlib4-bot leanprover-community-mathlib4-bot added the builds-mathlib CI has verified that Mathlib builds against this PR label Jan 19, 2024
@leanprover-community-mathlib4-bot
Copy link
Collaborator

leanprover-community-mathlib4-bot commented Jan 19, 2024

Mathlib CI status (docs):

@Vtec234 Vtec234 self-assigned this Jan 19, 2024
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4 that referenced this pull request Jan 19, 2024
Copy link
Member

@Vtec234 Vtec234 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation looks sensible. It's a bit sad that we have to add OmissionInfo to Elab.Info. I think this is because delab-info is starting to diverge further from elab-info (you'll never get OmissionInfo from the elaborator, right?). At one point I believe we discussed splitting out a separate Delab.Info. It may be worth considering again.

@kim-em kim-em added the full-ci label Jan 22, 2024
@kim-em
Copy link
Collaborator

kim-em commented Jan 22, 2024

Added full-ci so I can test the impact on the REPL and lean-training-data. No need to wait for me to report back, I'm sure this will be an easy adaptation.

leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4 that referenced this pull request Jan 22, 2024
@mhuisi
Copy link
Contributor Author

mhuisi commented Jan 22, 2024

The implementation looks sensible. It's a bit sad that we have to add OmissionInfo to Elab.Info. I think this is because delab-info is starting to diverge further from elab-info (you'll never get OmissionInfo from the elaborator, right?). At one point I believe we discussed splitting out a separate Delab.Info. It may be worth considering again.

I had the same thought when implementing this. However, it seems that all other Info constructors are used in the elaborator, and so I decided that splitting out a separate type for a single field may not be worth it. Regardless, this is worth revisiting if it comes up again.

At one point I believe we discussed splitting out a separate Delab.Info.

Do you remember where or why this was discussed?

Copy link
Collaborator

@kmill kmill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice feature to have, and overall it looks like a good implementation.

There are two things I'd like to see before merging:

  1. Adjusting the name. I think something like pp.omitDeepTerms with the opposite truth value would be clearer. Pretty printing deep terms is the natural default, and omitting deep terms seems like a special setting. As a counterpoint, one could argue that pp.deepTerms follows the convention of pp.proofs, but as a countercounterpoint these are dissimilar because a term being a proof is an intrinsic property, but depth depends on where the expression appears.
  2. Adding a test file. It'd be nice to see that the feature can be turned on and off, and that it can handle long lists. (Probably best to set the maxDepth low.) For test files, Sebastian suggested to me that we are using module comments to say what things are meant to be testing. (lean/run/rawStrings.lean is one example)

src/Init/NotationExtra.lean Show resolved Hide resolved
src/Lean/PrettyPrinter/Delaborator/Options.lean Outdated Show resolved Hide resolved
src/Lean/Server/FileWorker/WidgetRequests.lean Outdated Show resolved Hide resolved
| `([$xs,*]) => `([$x, $xs,*])
| `(⋯) => `([$x, $tail]) -- Unexpands to `[x, y, z, ⋯]` for `⋯ : List α`
| _ => throw ()
| _ => throw ()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For long lists, I guess this unexpander has been yielding quadratic complexity. Maybe eventually we should have a delaborator instead, so it can allocate the array all at once. That could also implement Joachim's suggestion to show the first and last elements of a long list. That's not for this PR though.

src/Lean/PrettyPrinter/Delaborator/Basic.lean Show resolved Hide resolved
src/Lean/PrettyPrinter/Delaborator/Basic.lean Outdated Show resolved Hide resolved
src/Lean/PrettyPrinter/Delaborator/Basic.lean Outdated Show resolved Hide resolved
@@ -251,7 +281,7 @@ partial def delab : Delab := do
else
return ← annotateTermInfo (← ``(_))
Copy link
Collaborator

@kmill kmill Jan 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we wanted to adjust pp.proofs to use this new syntax, I suppose this if/else could be replaced with something like

    let pf ← omission
    if ← getPPOption getPPProofsWithType then
      let stx ← withType delab
      return ← `(($pf : $stx)) >>= annotateCurPos
    else
      return pf

That's untested -- I'm just wanting to record how big of a change this would be. I don't think pp.proofs should be touched in this PR.

@mhuisi mhuisi force-pushed the mhuisi/elidible-subterms branch from 0ef6a90 to fc3a3e9 Compare January 30, 2024 12:08
@mhuisi mhuisi requested a review from kim-em as a code owner January 30, 2024 12:08
leanprover-community-mathlib4-bot added a commit to leanprover-community/batteries that referenced this pull request Jan 30, 2024
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4 that referenced this pull request Jan 30, 2024
Copy link
Collaborator

@kmill kmill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The heuristic is a good idea for handling some potential annoyances when omitting terms. Maybe in the future we might have some additional pretty printing options to control it, but I believe it's better to add them later if they're requested.

Once we have docstrings on the API functions and we decide whether or not to rename pp.maxTermDepth, then I think it'll be ready.

src/Lean/PrettyPrinter/Delaborator/Basic.lean Show resolved Hide resolved
src/Lean/PrettyPrinter/Delaborator/Basic.lean Outdated Show resolved Hide resolved
src/Lean/PrettyPrinter/Delaborator/Basic.lean Show resolved Hide resolved
src/Lean/PrettyPrinter/Delaborator/Options.lean Outdated Show resolved Hide resolved
src/Lean/PrettyPrinter/Delaborator/Options.lean Outdated Show resolved Hide resolved
leanprover-community-mathlib4-bot added a commit to leanprover-community/batteries that referenced this pull request Jan 31, 2024
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4 that referenced this pull request Jan 31, 2024
leanprover-community-mathlib4-bot added a commit to leanprover-community/batteries that referenced this pull request Jan 31, 2024
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4 that referenced this pull request Jan 31, 2024
Copy link
Collaborator

@kmill kmill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

(The rationale for pp.deepTerms is that, even though we think pp.omitDeepTerms is a clearer name, it's important to follow Sebastian's design for the pp options and be consistent with the analogous pp.proofs. Furthermore, this option will likely soon become a closer analogue since it too should use similar logic and use the omission syntax.)

@mhuisi mhuisi added this pull request to the merge queue Jan 31, 2024
Merged via the queue into leanprover:master with commit cd0be38 Jan 31, 2024
19 checks passed
github-merge-queue bot pushed a commit that referenced this pull request Feb 15, 2024
By having the `pp.proofs` feature use `⋯` when omitting proofs, when
users copy/paste terms from the InfoView the elaborator can give an
error message explaining why the term cannot be elaborated.

Also adds `pp.proofs.threshold` option to allow users to pretty print
shallow proof terms. By default, only atomic proof terms are pretty
printed.

This adjustment was suggested in PR #3201, which added `⋯` and the
related `pp.deepTerms` option.
arthur-adjedj pushed a commit to arthur-adjedj/lean4 that referenced this pull request Feb 19, 2024
By having the `pp.proofs` feature use `⋯` when omitting proofs, when
users copy/paste terms from the InfoView the elaborator can give an
error message explaining why the term cannot be elaborated.

Also adds `pp.proofs.threshold` option to allow users to pretty print
shallow proof terms. By default, only atomic proof terms are pretty
printed.

This adjustment was suggested in PR leanprover#3201, which added `⋯` and the
related `pp.deepTerms` option.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
builds-mathlib CI has verified that Mathlib builds against this PR toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants