Extend the GALEC export and render all targets from a walkable template IR - #338
Open
micahkc wants to merge 1 commit into
Open
Extend the GALEC export and render all targets from a walkable template IR#338micahkc wants to merge 1 commit into
micahkc wants to merge 1 commit into
Conversation
…te IR SPEC_0034 gains GAL-027..030 and D12..D17. Auto-discretization is permanently out of scope (D12): clocked discrete-time Modelica is the supported input. Projection features: - Matrix algebra lowering (GAL-027): matrix x matrix / matrix x vector / vector x matrix products, transpose, identity element-unroll into ascending-index sum trees; chained products (A*P*transpose(A)) take true product elements; Integer array literals widen to Real. - initial equation -> Startup lowering (GAL-028/D14): oriented, dependency-sorted statements after literal mirroring with pre-slot re-seeding; the manifest start mirrors the projection-time evaluation at default parameters (const-eval learned identity and elementwise array arithmetic); blanket ET021 retired. - Matrices.solve -> solveLinearEquations by name (GAL-029 slice 2a/D13; inv and solve2 get guidance diagnostics): method signals clauses are declared by construction via the validator's own escape dataflow (rumoca_ir_galec::computed_method_escapes), the manifest carries per-method Signals + ErrorSignalStatus, and the C track switches to a status-word ABI with a partial-pivot LU helper. NAN relational accounting stays staged as slice 2b. Template-IR rendering architecture (D16/D17): - template_ir.rs serializes the validated block into a language-neutral walkable tree: GALEC-faithful quoted names plus identifier stems, 1-based subscripts, T7-strict Real literal text, kind-tagged expression nodes, dual whole-array value/element forms with a copy flag. Adding a target language is adding a template. - The .alg text renders from the embedded alg.jinja walking template, pinned byte-identical to the rumoca-ir-galec typed printer (parity test); the printer remains the parser-facing half of the language module. - The C track's model.h.jinja/model.c.jinja are walking templates owning every C spelling; c_print.rs is deleted. c_mangle.rs survives as the Production Code manifest's name policy, kept in lockstep with the C template's keyword list by a keyword-fixture test. - New non-eFMI embedded-rust-galec target: a dependency-free #![no_std] crate root with Result<(), Signals> methods (Rust is outside the Beta-1 ProductionCode schema, so the honesty header says so). A quadrotor altitude-estimator fixture exercises the whole scope across all four targets; its end-to-end test is hermetic via an MSL name stub and proves the C and Rust exports agree bit-for-bit with each other and to 1e-9 with an independently written reference implementation. GALEC target capability gates now admit initialization and delegate external-function rejection to the projection's precise ET002 check. Signed-off-by: micahkc <mkcondie01@gmail.com>
micahkc
marked this pull request as ready for review
August 11, 2026 03:56
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.
Extends the GALEC/eFMI export with matrix algebra, computed initialization, and linear-solve support, and moves every GALEC rendering onto walking templates over a language-neutral GALEC template IR. SPEC_0034 gains GAL-027..030 and D12..D17; all changes are spec-first.
Projection features
*,transpose, andidentitylower to element-unrolled, ascending-index sum trees. Chained products (A*P*transpose(A)) take true product elements (a subscript-distribution bug was found and regression-pinned). Integer array literals widen to Real.initial equation→Startup(GAL-028): oriented, dependency-sorted statements after literal start mirroring, with'previous(x)'pre-slot re-seeding. The manifeststartis the projection-time evaluation at default parameters (const-eval learnedidentityand elementwise array arithmetic), so GAL-020 mirroring holds by construction. Blanket ET021 is retired; un-lowerable forms fail with stableunsupported-feature:ids.Modelica.Math.Matrices.solvemaps by name to thesolveLinearEquationsbuiltin (D13;inv/solve2get guidance diagnostics). Methodsignalsclauses are declared by construction via the validator's own escape-set dataflow (newrumoca_ir_galec::computed_method_escapes), the AC manifest carries per-methodSignals+ErrorSignalStatus, and signal-bearing blocks switch the C ABI to status-word-returning methods with a partial-pivot LU helper. NAN relational accounting (T9) stays staged as slice 2b.Rendering architecture (D16/D17)
template_ir.rsserializes the validated block into a walkable tree: both name spellings (GALEC quoted tokens + collision-checked identifier stems), 1-based subscripts, T7-strict Real literal text, kind-tagged expression nodes, dual whole-array value/element forms with acopyflag. Adding a target language is adding a template..algrenders from the embeddedalg.jinjawalking template, byte-identical to therumoca-ir-galectyped printer (pinned by a parity test; the printer remains the parser-facing half of the language module — the parity pin is the drift guard, please don't "clean up" either side without it).model.h.jinja/model.c.jinjaare walking templates owning every C spelling;c_print.rsis deleted.c_mangle.rssurvives solely as the Production Code manifest's name policy, kept in lockstep with the C template's keyword list by a keyword-fixture test (double/union/registervariables).embedded-rust-galectarget: a dependency-free#![no_std]crate root withResult<(), Signals>methods, honestly labeled NOT an eFMI Production Code container (the Beta-1 ProductionCode XSD restrictslanguageto C/C++).Fixture and tests
A quadrotor altitude-estimator fixture (
examples/models/) exercises the whole scope through all four targets. Its end-to-end test is hermetic via an MSL name stub (the solve mapping is by name, so the body never inlines) and proves the C and Rust exports agree bit-for-bit with each other and to 1e-9 with an independently written reference implementation. Also new: theembedded-rust-galecsuite, the estimator-scope battery (initialization/solve + the.algparity pin), and the keyword-lockstep test.Reviewer notes
initialization = trueandexternal_functions = true, delegating rejection to the projection's precise ET002 check (with theModelica.Math.Matricesnamespace exempted since it maps by name). Same outcomes for unsupported models, different message/timing.libm::(models without them have zero dependencies); matrix unrolling grows with state dimension (fine at embedded scale, no guardrail for large n); the fixed-start skip matches the DAE phase's origin-string prefix (a structured origin would be sturdier — follow-up).render_template_with_json_contextinrumoca-phase-codegen, re-export growth, and new CLI dispatch arms. No non-GALEC code path executes a changed line.All crate and CLI test suites pass locally (template-target render checks, the C↔Rust equivalence harness, the production-container suite, and a full workspace sweep); clippy and fmt clean; based on current
main.