Skip to content

engine: MDL writer prints wildcard subscripts as '*' instead of 'Dim!' -- exported .mdl fails re-parse #847

Closed

Description

@bpowers

Problem

The MDL writer emits XMILE wildcard syntax inside subscript lists, producing .mdl files that simlin's own MDL parser rejects.

Vensim SUM(a[DimA!]) imports as sum(a[*]) (the bang-subscript reduction is canonicalized to an XMILE wildcard). On export, MdlPrintVisitor::walk_index in src/simlin-engine/src/mdl/writer.rs (~line 627) prints IndexExpr0::Wildcard as *:

fn walk_index(&mut self, expr: &IndexExpr0) -> String {
    match expr {
        IndexExpr0::Wildcard(_) => "*".to_string(),
        ...

But MDL subscript lists require the dimension-bang form (DimA!). Re-parsing the exported file fails with:

expected symbol in subscript list, found *

Root cause

The expression printer is context-free: it has no dimension table, so it cannot reconstruct which dimension the wildcard ranges over. Fixing this requires threading per-variable dimension context into the writer so a[*] on a variable arrayed over DimA prints as a[DimA!]. (Multi-dimensional cases need positional mapping of each wildcard slot to the corresponding dimension.)

Impact

A corpus sweep (parse -> project_to_mdl -> re-parse over all test/**/*.mdl under 200KB) shows ~17 fixtures fail re-parse from this alone, out of 29/240 total re-parse failures (the remainder includes the zero-arg builtin class tracked separately). Affected fixtures include:

  • test/sdeverywhere/models/sum/sum.mdl
  • test/sdeverywhere/models/vector/vector.mdl
  • test/sdeverywhere/models/except/except.mdl
  • test/test-models/tests/subscript_aggregation
  • test/metasd/scientific-revolution/scirev7.mdl

Severity: critical for MDL export of any arrayed model using bang-subscript reductions (SUM/PROD/VMIN/VMAX/etc.) -- the exported file is unusable in Vensim and unreadable by simlin itself.

Component

src/simlin-engine/src/mdl/writer.rs (MdlPrintVisitor::walk_index, project_to_mdl equation path)

Possible approach

Pass the variable's resolved dimensions into the print visitor (similar context is already available where equations are written per-variable), and map each wildcard subscript position to format_mdl_ident(dim_name) + "!". A corpus-wide parse -> export -> re-parse sweep would make a good regression gate.

Related: the second re-parse failure class (zero-arg builtins like PI()) is filed separately.

Context: identified during an MDL writer round-trip corpus sweep.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions