Skip to content

engine: CrossElement over-approximation for fixed-index subscript refs in LTM causal graph #448

Description

@bpowers

Description

In db_analysis.rs, fixed-index subscript references like source[NYC] in A2A (array-to-array) equations are classified as CrossElement, which creates a full NxN cross-product of edges in the element-level causal graph. This is an over-approximation -- the correct behavior would be to create edges only from the specifically referenced element(s) to all target elements.

For example, if variable x is dimensioned over Cities (NYC, LA, CHI) and its equation references source[NYC], the current code creates edges from all 3 elements of source to all 3 elements of x (9 edges). The correct result would be 3 edges: from source[NYC] to each of x[NYC], x[LA], x[CHI].

Why it matters

  • Correctness: The false edges could theoretically merge otherwise independent stock partitions in cycle analysis, leading to spurious feedback loops being reported.
  • Precision: The element-level causal graph carries unnecessary edges that reduce the analytical value of the graph.
  • Maintainability: The current behavior has been flagged in code review 3 times as P1 but deferred each time because the practical impact is minimal.

The practical impact today is minimal because the false edges receive zero link scores and do not affect loop scoring. However, as the LTM analysis matures and is used for more downstream purposes, the imprecision could become material.

Component(s) affected

  • src/simlin-engine/src/db_analysis.rs -- classify_in_expr function and ElementDependencyKind enum

Proposed approach

  1. Add a FixedElement variant to ElementDependencyKind that carries the specific element index/indices being referenced.
  2. Thread dimension context through classify_in_expr so it can resolve subscript names to element indices.
  3. When building element-level edges, FixedElement would create edges only from the specified source element(s) to the target elements, rather than the full cross-product.

Context

Identified during code review of LTM array support on the ltm-arrays branch. The issue has been flagged in review 3 times as P1 but deferred due to the zero-link-score mitigation making the practical impact negligible for current use cases.

Activity

  1. bpowers commented on Apr 30, 2026

    @bpowers
    OwnerAuthor

    Fixed in commit 1272dd0 ("engine: per-reference LTM element graph and per-shape link scores (#477)").

    The N-by-N over-approximation for fixed-index subscript references has been eliminated. classify_in_expr and the CrossElement lump no longer exist. The element graph is now built by an AST-walking per-reference emitter:

    • RefShape enum (src/simlin-engine/src/db_analysis.rs:77-94) with variants Bare, FixedIndex(Vec<String>), Wildcard, DynamicIndex.
    • collect_reference_sites walks the AST and tags each reference with its shape.
    • emit_edges_for_reference (db_analysis.rs:525-625) emits edges based on shape: a FixedIndex(["NYC"]) reference emits edges only from source[NYC] to each target element (N edges), not the full N x N cross-product.

    Per-shape partial equations (build_partial_equation_shaped in ltm_augment.rs) and per-shape link scores (emit_per_shape_link_scores in db_ltm.rs) build on the same RefShape taxonomy, so the resolution is end-to-end consistent.

    Tracked in docs/tech-debt.md item #20 (RESOLVED 2026-04-25). Verified on main at HEAD 630fceb (2026-04-29).

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