Skip to content

formal: a record's reading decomposes by simp; no per-record reading lemma - #382

Merged
martyall merged 1 commit into
pickles/records-as-valuesfrom
pickles/reads-simps
Sep 19, 2026
Merged

martyall merged 1 commit into
pickles/records-as-valuesfrom
pickles/reads-simps

Conversation

@martyall

Copy link
Copy Markdown
Member

Stacked on #379. Closes #380.

The readings gate demanded reads_x/scoped_x beside every CircuitType instance, on the ground that reads_ofEquiv matches only the literal ofEquiv term and simp will not look inside a named instance. Probing showed otherwise, and showed what was actually missing.

What the probes found

  • rw [CircuitType.reads_ofEquiv] and simp only [CircuitType.reads_ofEquiv] fire through a named instance today: instances are reducible.
  • The per-record lemmas formal: the statement records are the circuit inputs, projected off the proof #379 introduced were useless in a stronger sense: they restate the equivalence, and a consumer holding Reads V x a still cannot reach a leaf, because equivProd x is not syntactically a tuple and reads_prod never fires. The load-bearing lemmas in the tree (reads_affinePoint, reads_spongeState, ~130 uses) are componentwise, a different artifact.
  • The componentwise form is free: @[simps apply] on each decomposition, plus the former lemmas as a simp set, and simp [reads_simps] at h turns a nested record's Reads or Scoped into its leaves'. Checked end to end on UnfinalizedProof (13 leaves) and WrapStatement.

The change

  • Snarky.Encoding.ReadsAttr declares reads_simps; Snarky.Encoding.Simps fills it with the formers' reading lemmas and the hand-written leaf instances' (AffinePoint, SpongeState, Type1). Two new modules; nothing existing rebuilds.
  • Pickles/Encoding.lean: each record is its equivalence with @[simps apply] and a one-line ofEquiv instance. The 34 lemmas go, and the Type1 instance Snarky already has. About 450 lines to 220.
  • check-readings.sh accepts either style: the two lemmas by hand, or an @[simps decomposition on the ofEquiv argument. Its sed used GNU-only \?, so on macOS it had checked nothing; portable now, it sees the tree's 22 instances.
  • Roots: the 16 instances as -- synthesis script-surface entries, the 16 projection lemmas as plain roots, as Snarky does for Type1.equivCarrier_apply.

Untouched, by design: the six hand-written instances and their named lemmas.

Verified

Build, the consumer probe, readings (22 instances), dead-code, shake on the CI list, runLinter on Snarky/Pickles/PicklesFixture, style, check-cs, a check-halves lane.

🤖 Generated with Claude Code

…lemma

The readings gate demanded `reads_x`/`scoped_x` beside every `CircuitType` instance on the
ground that `reads_ofEquiv` matches only the literal `ofEquiv` term. It does not: instances
are reducible, and `rw`/`simp only [reads_ofEquiv]` fire through a named instance. What a
consumer lacked was the next step — `equivProd x` is not syntactically a tuple, so
`reads_prod` never fired — and that is one `@[simps apply]` per decomposition.

`Snarky.Encoding.Simps` collects the formers' reading lemmas and the hand-written leaf
instances' as the `reads_simps` set (declared in `Snarky.Encoding.ReadsAttr`): with each
decomposition's projection lemma, `simp [reads_simps] at h` turns a nested record's `Reads`
or `Scoped` into its leaves'. `Pickles.Encoding` is the equivalences with `@[simps apply]`
and the one-line instances — 34 lemmas and the `Type1` instance Snarky already has go; the
instances are script-surface roots, the projection lemmas the records' API.

The gate accepts either style. Its `sed` used a GNU-only `\?`, so on macOS it had checked
nothing; portable now, it sees the tree's 22 instances.

Closes #380.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@martyall
martyall merged commit 0b94e49 into pickles/records-as-values Sep 19, 2026
1 check passed
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.

1 participant