Skip to content

Fix DDM precedence for single-argument wrapper ops#437

Open
joehendrix wants to merge 1 commit intomainfrom
jhx/ddm_prec
Open

Fix DDM precedence for single-argument wrapper ops#437
joehendrix wants to merge 1 commit intomainfrom
jhx/ddm_prec

Conversation

@joehendrix
Copy link
Contributor

@joehendrix joehendrix commented Feb 17, 2026

Summary

Reduce unnecessary parentheses in DDM pretty printing by overhauling syntax elaboration — convert SyntaxDef to an inductive type with std/passthrough variants, fix precedence for wrapper and string-literal ops, remove dead unwrap code, and rewrite the precedence documentation.

Details

  • Single string-literal syntax ops get maxPrec + 1 (never parenthesized)
  • Give Nat and Decimal literals maxPrec + 1 so they are never spuriously
    parenthesized (e.g., i + (1)i + 1)
  • Remove unused unwrap field from SyntaxDefAtom and related dead code
    (unwrapSpecs, unwrapTree); unwrap is only used via metadata in Gen.lean
  • Replace unsafe array indexing with bounds-checked access in Format.lean
  • Fix missing whitespace in C_Simp measure/invariant/pre/post grammar

Documentation

  • Rewrite precedence section of DDM documentation; fix broken link, grammar,
    and section hierarchy
  • Add lychee link checker to CI doc build

🤖 Generated with Claude Code

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@joehendrix joehendrix force-pushed the jhx/ddm_prec branch 5 times, most recently from 8374f0c to e2bf62b Compare February 17, 2026 21:44
@joehendrix joehendrix marked this pull request as ready for review February 17, 2026 22:04
@joehendrix joehendrix requested a review from a team as a code owner February 17, 2026 22:04
@joehendrix joehendrix force-pushed the jhx/ddm_prec branch 2 times, most recently from 3cac801 to b1d7961 Compare February 17, 2026 23:14
- Introduce SyntaxDef.passthrough so wrapper ops inherit the argument's
  precedence instead of forcing maxPrec parenthesization
- Remove dead unwrap field from SyntaxDefAtom.ident (only used via metadata)
- Replace sorry proofs with decideProp checks and panic fallbacks
- Move passthrough decision after argument-usage validation so polymorphic
  ops with inferred type params are still checked
- Replace unsafe array indexing with bounds-checked access in Format.lean
- Fix missing whitespace in C_Simp invariant/decreases grammar tokens

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@shigoel shigoel left a comment

Choose a reason for hiding this comment

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

Thanks!

Without the `rightassoc` annotation, this is equivalent to the definition:

```
fn implies (p : Pred, q : Pred) : Pred => @[prec(20)] p:20 " ==> " q:19;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there no way to infer the correct argument precedence values? I would think that the operator precedence already fully determines the parsing behavior, and from that we should be able to infer how a dual printer should behave.

precedence in syntax definitions.
### Precedence

Precedence controls when parentheses are inserted during pretty-printing.
Copy link
Contributor

Choose a reason for hiding this comment

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

Cool!

Do you assume that every language will use ( ) to group expressions? Seems fine but I'm asking out of curiosity. What about other ways to manipulate precedence, like inserting $ in Lean, would there be ways to generate that during printing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants