Lower Pine relationals na-aware: comparisons with an na operand are falsy#57
Merged
Conversation
…alsy TradingView evaluates every relational comparison (==, !=, <, >, <=, >=) with an na operand as falsy. The naive C++ lowering diverges on the int na sentinel (INT_MIN != x is TRUE, NA == NA is TRUE, ordered ops leak) and on float x != NaN (IEEE TRUE); float ==/</>/<=/>= already match via IEEE NaN semantics and stay naive. Pinned by pf-probe-concord-lockedregime-composed (792/792 events): a bar-0 na latched into `var int locked_regime` via an isfirst ternary stays na forever on TV — every later comparison is falsy — while the naive lowering let the engine heal the latch and over-fire ~1,300 entries on the exemplar strategy. Implementation: shared _lower_relational wraps only diverging cells (any na-capable int operand; != with an na-capable float operand) in a single-evaluation nz-style lambda (!is_na(l) && !is_na(r) && (l op r)), applied at both relational emission sites (visit_binop and the request.security expression builder). bool/string/color relationals stay naive (no na sentinel). Monotone-safe: for non-na operands the lambda is bit-identical to the naive comparison. Gates: pytest 1510 + 1 skipped (13 new cells RED on base); whole-corpus differential transpile 73 changed .cpp, all wrap-only (collapse-audited); 73/73 changed strategies byte-identical engine output; corpus tiers 240/11/1; sentinel set byte-identical incl. the KI-68 na-int exemplar; mover strategies reach exact TV parity (private-set canonical excellent, full 412-slug sweep 2 up / 0 down). Reviewed fresh-context, ARM64. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
TradingView evaluates every relational comparison (
==,!=,<,>,<=,>=) with an na operand as falsy. The naive C++ lowering diverges on the int na sentinel (INT_MIN != x→ TRUE,NA == NA→ TRUE, ordered ops leak) and on floatx != NaN(IEEE TRUE); float==/</>/<=/>=already match TV via IEEE NaN semantics and stay naive.Pinned by a dedicated clean-room probe at 792/792 events: an na latched into a
var intat bar 0 through anisfirstternary stays na forever on TV — every later comparison falsy — while the naive lowering let the engine heal the latch and over-fire ~1,300 entries on the exemplar strategy.Implementation
_lower_relationalwraps only diverging cells — any na-capable int operand;!=with an na-capable float operand — in a single-evaluation nz-style lambda:!is_na(l) && !is_na(r) && (l op r). Operands hoisted to temporaries (mutating operands evaluated exactly once)._visit_binopand therequest.securityexpression builder.Verification
:=-retype exemplar and float-relational probes;!=-as-change-detector idiom A/B'd at trade level (byte-identical).Known residuals (non-blocking, recorded)
🤖 Generated with Claude Code