sir: text format for Vars - #21
Open
Eduardogbg wants to merge 36 commits into
Open
Conversation
Eduardogbg
marked this pull request as ready for review
August 13, 2026 04:55
Eduardogbg
force-pushed
the
sir/text-format
branch
3 times, most recently
from
August 15, 2026 19:25
965b494 to
eb508c6
Compare
Eduardogbg
force-pushed
the
sir/text-format
branch
3 times, most recently
from
August 18, 2026 06:48
d674566 to
8fca58e
Compare
Eduardogbg
force-pushed
the
sir/text-format
branch
from
August 18, 2026 08:27
8fca58e to
47b2074
Compare
Philogy
reviewed
Aug 19, 2026
| let (preludes, identifiers) ← operands rest | ||
| return (prelude ++ preludes, #[identifier] ++ identifiers) | ||
|
|
||
| def parseMnemonic (functions : List String) (line : Line) (mnemonic : String) |
Contributor
There was a problem hiding this comment.
I'd make the parsing of mnemonics more modular here, every mnemonic is quite repetitive and will be annoying to review once we start adding all the ops
Kernel reduction of `parse` was never the obstacle. The elaborator's smart unfolding copies the unreduced lexer term that `internVariable` stores in the interning state, once per unfolding attempt, and the copies miss the whnf cache. Plain delta reduction does not, so `parse_rfl` disables smart unfolding at the proof site: the witness goes from unelaborable to 1.4s of elaboration and 0.65s in the kernel, on the ordinary `rfl` trust story.
`sir-extract` reads a `.sir` file and writes a comment-free Lean module defining the program it denotes. Declaration names are restricted to plain identifiers before emission, and read, parse, and write failures use path-qualified errors. Generated modules are ordinary committed source: reviewable, diffable, and tracked by Lake, unlike a program conjured at elaboration time.
`Ensures P` is `Except Diagnostic (PLift P)`: a real monad, so checks compose in `do`, while the clause each one discharges rides in its type and cannot be forged. `ensureAll` matches the shape `WellFormed` is already written in, so a check reads like the clause it proves. Acyclicity of the call graph is not decidable as stated, so it takes a rank certificate instead.
decimalDigits was the one definition in this layer written by well-founded recursion, so it never reduced in the kernel and nothing mentioning print could be settled by rfl. It becomes structural on a fuel argument, which reduces: seven-digit values take milliseconds. That makes five closed example witnesses provable. Each shows parse (print p) = .ok p for one program and pins the printed text, which is also the only place the surface syntax is written down against a program that means something. Each witness reduces the printing and parsing halves separately. Composing them puts parse to work on an unreduced print term, and those copies miss the whnf cache in the same way smart unfolding does.
A numeric literal in an operand position expands to a fresh variable defined by a preceding const, but the result name was interned first, so the temporary got the higher id while being printed first. Reprinting and reparsing such a program returned it renamed rather than unchanged. Operand literals are now lifted before results are interned, matching printer order. The generated temporaries therefore receive the lower identifiers they occupy in emitted text, so reparsing no longer swaps their identifiers with statement results.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Spec/Check.lean no longer imports Proofs modules; each clause is a plain decider. Proofs/Check.lean proves Program.wellFormed_of_check, exported from Vars.Theorems. Examples derive the three positive WellFormed witnesses from the checker.
Eduardogbg
force-pushed
the
sir/text-format
branch
from
August 19, 2026 21:54
5de10f6 to
7cf443f
Compare
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Eduardogbg
force-pushed
the
sir/text-format
branch
from
August 19, 2026 22:27
7cf443f to
b8b3fab
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
this PR adds the SIR text format for
Vars: lexer, parser, printer, an extractor from.sirto a Lean module, and a well-formedness checker with a soundness theorem.Varsstatement and terminator (textmallocisVars.Stmt.malloc,mallocanyismallocUninit). numeric literals in operand position become a freshconst;initis required,mainoptional; a function's first block is its entry, as in the rust parser.normalizeis a normal form for alpha equivalence (alphaEquiv_iff_normalize_eq,alphaEquiv_equivalence).parse ∘ print = normalizefor well-formed programs (parse_print_normalize) andparse ∘ print = idon normal forms (parse_print, unconditional since parser output is always normal,parse_normal):printis a section ofparse, the normal forms are a retract of the text.WellFormedclause has a proof-free decider inSir/Vars/Spec/Check.lean(checkIcallArity,checkIretArity,checkAcyclicCalls,checkEntryArity,checkValidJumpTargets,checkVariablesDefinedBeforeUse), failing with aDiagnostic;checkAcyclicCallscomputes a rank on the call graph and checks it decreases along every call.checkWellFormedsequences them andwellFormed_of_check : checkWellFormed p = .ok () → p.WellFormedis the exported soundness theorem; the extractor runs the checker, the example programs get theirWellFormedwitnesses from it byrfland an ill-formed one is rejected with its diagnostic (Sir/Examples/Text.lean).lake env lean --run SirExtract.lean input.sir Output.lean namewrites the parsed program as Lean source. examples have their printed text pinned and reparsed (Sir/Examples/Text.lean).