Skip to content

Rework custom validators to work with generic rules#190

Merged
Soupstraw merged 5 commits intomasterfrom
jj/export-gref
May 6, 2026
Merged

Rework custom validators to work with generic rules#190
Soupstraw merged 5 commits intomasterfrom
jj/export-gref

Conversation

@Soupstraw
Copy link
Copy Markdown
Contributor

@Soupstraw Soupstraw commented Apr 28, 2026

Summary

  • Custom generators and validators on generic rules can now refer to their generic argument: looking up a GRef resolves to the type bound at the enclosing rule.
  • Adds generateFromGRef and validateFromGRef (plus validateFromName) so closures attached to generic rules can delegate to whatever type the generic was instantiated with.
  • Moves GRef from Codec.CBOR.Cuddle.Huddle to Codec.CBOR.Cuddle.CDDL so the lookup helpers can live alongside their monads. Huddle re-exports it without the constructor.
  • runCBORValidator now takes a CTreeRoot ValidatorPhase directly instead of a ValidateEnv.
  • Added MonadCddl typeclass which has methods for looking up rules from the root CDDL.
  • GenEnv and ValidateEnv gain geLocal / veLocal fields holding the active generic bindings; populated by synthMono wrapping the captured custom generator/validator at monomorphization time.

How it works

Monomorphization (Resolve.synthMono) builds a localBinds :: Map Name (CTree _) mapping each generic parameter (e.g. a0) to its bound CTree. Previously the body got substituted with these bindings but the opaque custom generator/validator closures didn't, so calling generateFromName "a0" from inside a custom closure failed with Unbound reference: a0.

resolveGenericRef now wraps the captured g/v closures with withLocalGenBindings / withLocalValidateBindings so the closure pushes its binding map onto geLocal / veLocal for the duration of its run. The new lookupGRef consults that map; generateFromGRef and validateFromGRef build on top.

@Soupstraw Soupstraw marked this pull request as draft April 29, 2026 10:33
@Soupstraw Soupstraw changed the title Export GRef constructor Rework custom validators to work with generic rules Apr 29, 2026
@Soupstraw Soupstraw force-pushed the jj/export-gref branch 3 times, most recently from 6a06249 to 08e1745 Compare April 29, 2026 13:44
@Soupstraw Soupstraw marked this pull request as ready for review May 4, 2026 10:26
@Soupstraw Soupstraw requested a review from lehins May 4, 2026 10:27
@Soupstraw Soupstraw force-pushed the jj/export-gref branch 3 times, most recently from b8b555e to cb06c59 Compare May 4, 2026 14:27
@lehins lehins requested a review from neilmayhew May 5, 2026 18:42
Copy link
Copy Markdown
Contributor

@neilmayhew neilmayhew left a comment

Choose a reason for hiding this comment

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

Cool stuff!

The suggestions are all very minor, mostly stylistic things.

Comment thread src/Codec/CBOR/Cuddle/CDDL/CBORGenerator.hs Outdated
Comment thread src/Codec/CBOR/Cuddle/CDDL/CBORGenerator.hs Outdated
Comment thread src/Codec/CBOR/Cuddle/CDDL/Resolve.hs Outdated
Comment thread src/Codec/CBOR/Cuddle/CDDL/CTree.hs Outdated
Comment thread src/Codec/CBOR/Cuddle/CBOR/Validator.hs Outdated
Comment thread src/Codec/CBOR/Cuddle/CDDL/CBORGenerator.hs Outdated
Comment thread src/Codec/CBOR/Cuddle/CDDL/Resolve.hs Outdated
Comment thread src/Codec/CBOR/Cuddle/CDDL/Resolve.hs Outdated
@neilmayhew
Copy link
Copy Markdown
Contributor

I think the percentages in your final commit message are a little off. I think they should be 33% / 67%. (Did you use AI, by any chance? I've noticed that AI often isn't great at maths.)

@Soupstraw
Copy link
Copy Markdown
Contributor Author

Soupstraw commented May 6, 2026

@neilmayhew I assume it picked these numbers from the specific sample it got from running the tests, still a bit odd to mention those numbers in the commit message instead of the actual probabilities. Seems like Claude is a hardcore empiricist 😅

@Soupstraw Soupstraw force-pushed the jj/export-gref branch 6 times, most recently from ce56ca3 to db663c4 Compare May 6, 2026 10:28
Soupstraw added 2 commits May 6, 2026 13:34
Custom generators and validators attached to a generic Huddle rule can
now look up the type bound to a generic parameter at the enclosing
rule. Add `generateFromGRef` and `validateFromGRef` helpers, plus
`validateFromName`. Custom closures attached to generic rules are
wrapped at monomorphization time to install the active local bindings
into `geLocal`/`veLocal` on `GenEnv`/`ValidateEnv`, which a new
`lookupGRef` method on `MonadCddl` consults.

`runCBORValidator` now takes a `CTreeRoot ValidatorPhase` directly.
`GRef` moves to `Codec.CBOR.Cuddle.CDDL` so lower-level modules can
use it; `Huddle` re-exports it without the constructor.
New Huddle example `tagRangeExample`: `foo<a> = #6.1280(a) / #6.1400(a)`
used at `[foo<uint>, foo<nint>]`, with a custom generator that picks any
tag in `1280..1400` (biased toward the edges via `frequency`) and a
custom validator accepting the same range. Both delegate to the bound
generic type via `generateFromGRef` / `validateFromGRef`.

Wired into the `Generated value validates` round-trip suite, plus a
separate property that classifies tag samples to surface edge
coverage (33% edge / 67% middle).
@Soupstraw Soupstraw enabled auto-merge May 6, 2026 10:35
@Soupstraw Soupstraw merged commit bfc0b5e into master May 6, 2026
11 checks passed
@Soupstraw Soupstraw deleted the jj/export-gref branch May 6, 2026 10:39
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.

2 participants