Skip to content

engine: array-producing builtins nested inside other BuiltinFn calls produce incorrect results in interpreter #364

@bpowers

Description

@bpowers

Problem

Array-producing builtins (VECTOR ELM MAP, VECTOR SORT ORDER, ALLOCATE AVAILABLE) produce incorrect results in the interpreter when nested inside other BuiltinFn calls. For example:

  • MAX(VECTOR ELM MAP(source[*], offsets[*]), 15) returns 15 for element 0 instead of the correct value 30 (when VEM should produce 30 for that element).
  • SUM(VECTOR ELM MAP(...)) returns NaN.

The root cause appears to be how array-producing builtins interact with the per-element evaluation context when wrapped inside another BuiltinFn. The outer builtin evaluates the inner array-producing builtin in a context where the per-element iteration state is not correctly propagated, causing the inner builtin to return wrong values or NaN rather than the correctly mapped element.

This is a pre-existing limitation, not introduced by PR #361 (VM vector operations).

Why it matters

  • Correctness: Models that compose array-producing builtins inside scalar builtins (a common Vensim/Stella pattern) will silently produce wrong simulation results.
  • Developer experience: The failure mode is silent -- wrong values rather than errors -- making it difficult to diagnose.
  • Model compatibility: Real-world SD models frequently nest these operations (e.g., MAX(VEM(...), threshold), SUM(VEM(...)), MIN(ALLOCATE_AVAILABLE(...), cap)).

Component(s) affected

Possible approaches

  1. Ensure array-producing builtins fully materialize their result array before the outer builtin evaluates, so the outer builtin sees the correct per-element value rather than an incomplete or context-dependent intermediate.
  2. Propagate the per-element iteration index through nested builtin calls so inner array-producing builtins know which element they should compute.
  3. Review how the interpreter's calc_eval / element iteration interacts with BuiltinFn::Vem, BuiltinFn::Vso, and BuiltinFn::AllocateAvailable when they appear as arguments to another BuiltinFn.

Context

Identified during code review of PR #361 (VM vector operations). The issue is pre-existing in the interpreter and was surfaced by testing nested compositions of array-producing builtins.

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