Proves four ∀-quantified, structurally-inductive round-trip theorems:
· nameFromTokens?_round_trip : ∀ n, fromTokens? (toTokens n) = some n
· classifierFromTokens?_round_trip: ∀ φ, fromTokens? φ.toTokens = some φ
· cTermFromTokens?_round_trip : ∀ t, fromTokens? t.toTokens = some t
· artifactFromTokens?_round_trip : ∀ a, a.supported → fromTokens? a.toTokens = some a
These are the canonical universal round-trips — the parser
inverts the canonical token form on every meta-mirror value.
No `decide`, no `native_decide`, no kernel-depth tricks: pure
structural induction on the meta-mirror type, with sufficient
fuel guaranteed by the per-type length-vs-depth lemma.
Implementation:
(1) Fixed latent double-paren bug in `nameToLeanSource`: dropped
extra parens around recursive sub-name calls (consistent
with classifier/cterm renderers). Pre-fix, 3-level deep
names like `eq0.i` (FaceFormula.eq0 encoding) failed to
round-trip silently — no test exercised them. Added a
`set_option maxRecDepth 4000 in theorem … decide`-based
regression test.
(2) Refactored parsers to fuel-based. `parseName?Aux`,
`parseClassifier?Aux`, `parseMetaCTerm?Aux`, `parseArtifact?Aux`
each take a Nat fuel that decreases on every recursive call,
so they're total without `partial`. Top-level wrappers pass
`tokens.length + 1`, always sufficient.
(3) Added canonical token forms `nameToTokens`,
`MetaClassifier.toTokens`, `MetaCTerm.toTokens`,
`MetaArtifact.toTokens` — direct value→[Token] mappings,
parallel to the renderers but at the token level.
(4) Phase 2 (parser correctness on toTokens): four mutual-induction
theorems, one per meta-mirror type. Each proves
`parser?Aux fuel (value.toTokens ++ rest) = some (value, rest)`
when fuel ≥ value.depth.
(5) Length-vs-depth lemmas: nameToTokens_length_bound,
classifierToTokens_length_bound, cTermToTokens_length_bound.
Each by induction.
(6) Token-level universal round-trip theorems: composed from (4)
and (5) by setting rest = []. These are the headline results.
Phase 3 (tokenize ∘ render = toTokens, the String-level extension)
is documented but unproven — substantial String/List reasoning
required. The kernel-rooted decide tests for closed instances
(MetaCTerm.empty, sym, app, etc.) provide empirical evidence.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>