Summary
analyze_expr_polarity_with_context in src/simlin-engine/src/ltm.rs only handles the scalar two-arg forms Max(a, Some(b)) and Min(a, Some(b)). Every array reducer (Sum, Mean, Max(_, None), Min(_, None), Stddev, Rank) falls through the catch-all Expr2::App(_, _, _) => LinkPolarity::Unknown arm. Any variable computed via SUM(x[*]) or MEAN(x[*]) therefore contributes Unknown polarity, and every loop crossing such a node is classified Undetermined.
Why this matters
For Sum and Mean, polarity is trivially the argument's polarity (monotone in every element), so an entire class of arrayed feedback loops is misclassified as undetermined when their polarity is in fact recoverable.
Locations
src/simlin-engine/src/ltm.rs:2042-2075 -- the polarity analyzer with the catch-all Unknown
src/simlin-engine/src/ltm.rs:2341 -- strict GF monotonicity epsilon (EPSILON = 1e-10) flags numeric import noise as Unknown
Suggested fix
- Add explicit cases in the polarity match: pass through the argument's polarity for
Sum and Mean; return Unknown for Stddev and Rank (which have no monotone polarity).
- For array
Max(_, None) / Min(_, None), return the argument's polarity (max/min of a monotone family is monotone).
- Consider a plateau-tolerant GF monotonicity check that ignores noise below a configurable epsilon rather than the strict 1e-10.
Severity
medium
References
Summary
analyze_expr_polarity_with_contextinsrc/simlin-engine/src/ltm.rsonly handles the scalar two-arg formsMax(a, Some(b))andMin(a, Some(b)). Every array reducer (Sum,Mean,Max(_, None),Min(_, None),Stddev,Rank) falls through the catch-allExpr2::App(_, _, _) => LinkPolarity::Unknownarm. Any variable computed viaSUM(x[*])orMEAN(x[*])therefore contributesUnknownpolarity, and every loop crossing such a node is classifiedUndetermined.Why this matters
For
SumandMean, polarity is trivially the argument's polarity (monotone in every element), so an entire class of arrayed feedback loops is misclassified as undetermined when their polarity is in fact recoverable.Locations
src/simlin-engine/src/ltm.rs:2042-2075-- the polarity analyzer with the catch-allUnknownsrc/simlin-engine/src/ltm.rs:2341-- strict GF monotonicity epsilon (EPSILON = 1e-10) flags numeric import noise asUnknownSuggested fix
SumandMean; returnUnknownforStddevandRank(which have no monotone polarity).Max(_, None)/Min(_, None), return the argument's polarity (max/min of a monotone family is monotone).Severity
medium
References
docs/tech-debt.mditem fix new user creation flow #21