Summary
With region = {north, south, east} and coast = {north, east} (a subrange of region), pop[region] a stock:
| equation |
result (identical on origin/main d04593e6 and branch compiler-unification-v2 HEAD) |
x[region] = SUM(pop[coast]) |
refused: error in model 'main' variable 'x': mismatched_dimensions -- pop (snippet shows the whole SUM(pop[coast]), no span marker) |
x[region] = SUM(pop[coast] * 2) |
refused, same text |
x = SUM(pop[coast]) (scalar equation) |
refused: error in model 'main' variable 'x': dimension_in_scalar_context, span under coast |
x[region] = SUM(pop[*:coast]) |
compiles, 400 400 400 (= 100 + 300) |
x = SUM(pop[*:coast]) |
compiles, 400 |
x[coast] = SUM(pop[coast]) |
compiles: 100 300 on the branch (by name); 100 200 on origin/main (positional, GH #1029) |
Exact text of the first row, from simlin simulate:
SUM(pop[coast])
error in model 'main' variable 'x': mismatched_dimensions -- pop
error compiling model 'main': SimulationError{not_simulatable: failed to compile fragments for variables: x}
Is the refusal right?
Yes, as far as XMILE goes. Section 3.7.1 of docs/reference/xmile-v1.0.html makes a dimension name inside a subscript a placeholder for the enclosing element's index, and says "the array containing the equation MUST itself be sized using those dimension names". coast is not a dimension of x[region], so pop[coast] in that equation is not a valid placeholder, and the spec's slicing (3.7.1.2) is spelled with * and lo:hi ranges. Simlin's named-subrange slice is the star range pop[*:coast], which compiles in both equations, and the MDL importer spells Vensim's pop[coast!] as that StarRange (the writer round-trips it back to coast!, mdl/writer_tests.rs::star_range_subscript_renders_as_bang), so imported models do not reach this refusal.
What is wrong is what the refusal says
mismatched_dimensions -- pop blames the variable. pop is fine; the offending token is the dimension name coast, which pairs with no axis of the target, and the message neither names it nor marks its span (the scalar-equation arm, dimension_in_scalar_context with the span under coast, already does better).
- Nothing points at the spelling that means what the modeller almost certainly meant (
pop[*:coast], one token away), or says that a dimension name in a subscript is only a placeholder for the target's own dimensions.
A modeller coming from Vensim (SUM(pop[coast!])) or from a hand-written XMILE file hits this on the first subrange reduce they write and gets pointed at the wrong identifier.
Where to look
- The
sim_err!(MismatchedDimensions, id.as_str().to_string()) arms in src/simlin-engine/src/compiler/context.rs's subscript lowering (the dimension-name index resolves to no active axis of the target); EquationError::details carries the reason, so the fix is to put the dimension name (and the *:coast suggestion when the named dimension is a subdimension of the source axis, DimensionsContext knows) in details and the span on the index.
src/simlin-engine/src/ast/expr2.rs around the DimensionInScalarContext raise for the scalar-equation arm, which already spans the index and could carry the same suggestion.
Acceptance
- A row per {apply-to-all target over a different dimension, scalar target} x {subrange name, unrelated dimension name} pinning the message text and span through
TestProject::error_diagnostics.
SUM(pop[*:coast]) in both equations and x[coast] = SUM(pop[coast]) keep compiling with the values above.
Related
Discovery context
Identified during PR #1040 (branch compiler-unification-v2): the V9b report's out-of-scope discovery that SUM(pop[coast]) (probe e10_subdim_reducer) "is refused on both binaries". Reproduced with simlin simulate on origin/main at d04593e6 and branch HEAD; pre-existing and unchanged by the branch.
Summary
With
region = {north, south, east}andcoast = {north, east}(a subrange ofregion),pop[region]a stock:origin/maind04593e6and branchcompiler-unification-v2HEAD)x[region] = SUM(pop[coast])error in model 'main' variable 'x': mismatched_dimensions -- pop(snippet shows the wholeSUM(pop[coast]), no span marker)x[region] = SUM(pop[coast] * 2)x = SUM(pop[coast])(scalar equation)error in model 'main' variable 'x': dimension_in_scalar_context, span undercoastx[region] = SUM(pop[*:coast])400 400 400(= 100 + 300)x = SUM(pop[*:coast])400x[coast] = SUM(pop[coast])100 300on the branch (by name);100 200onorigin/main(positional, GH #1029)Exact text of the first row, from
simlin simulate:Is the refusal right?
Yes, as far as XMILE goes. Section 3.7.1 of
docs/reference/xmile-v1.0.htmlmakes a dimension name inside a subscript a placeholder for the enclosing element's index, and says "the array containing the equation MUST itself be sized using those dimension names".coastis not a dimension ofx[region], sopop[coast]in that equation is not a valid placeholder, and the spec's slicing (3.7.1.2) is spelled with*andlo:hiranges. Simlin's named-subrange slice is the star rangepop[*:coast], which compiles in both equations, and the MDL importer spells Vensim'spop[coast!]as thatStarRange(the writer round-trips it back tocoast!,mdl/writer_tests.rs::star_range_subscript_renders_as_bang), so imported models do not reach this refusal.What is wrong is what the refusal says
mismatched_dimensions -- popblames the variable.popis fine; the offending token is the dimension namecoast, which pairs with no axis of the target, and the message neither names it nor marks its span (the scalar-equation arm,dimension_in_scalar_contextwith the span undercoast, already does better).pop[*:coast], one token away), or says that a dimension name in a subscript is only a placeholder for the target's own dimensions.A modeller coming from Vensim (
SUM(pop[coast!])) or from a hand-written XMILE file hits this on the first subrange reduce they write and gets pointed at the wrong identifier.Where to look
sim_err!(MismatchedDimensions, id.as_str().to_string())arms insrc/simlin-engine/src/compiler/context.rs's subscript lowering (the dimension-name index resolves to no active axis of the target);EquationError::detailscarries the reason, so the fix is to put the dimension name (and the*:coastsuggestion when the named dimension is a subdimension of the source axis,DimensionsContextknows) indetailsand the span on the index.src/simlin-engine/src/ast/expr2.rsaround theDimensionInScalarContextraise for the scalar-equation arm, which already spans the index and could carry the same suggestion.Acceptance
TestProject::error_diagnostics.SUM(pop[*:coast])in both equations andx[coast] = SUM(pop[coast])keep compiling with the values above.Related
out[Sub] = src[Sub]reading positionally; thex[coast] = SUM(pop[coast])row above measures it live onorigin/mainand by name on the branch sincebe7adbbf(Phase 6b, design-plan item "A subscript naming a dimension resolves through one rule").Discovery context
Identified during PR #1040 (branch
compiler-unification-v2): the V9b report's out-of-scope discovery thatSUM(pop[coast])(probee10_subdim_reducer) "is refused on both binaries". Reproduced withsimlin simulateonorigin/mainatd04593e6and branch HEAD; pre-existing and unchanged by the branch.