Skip to content

Improve empty range handling#460

Merged
ducky64 merged 3 commits intomasterfrom
better-empty-handling
Mar 29, 2026
Merged

Improve empty range handling#460
ducky64 merged 3 commits intomasterfrom
better-empty-handling

Conversation

@ducky64
Copy link
Copy Markdown
Collaborator

@ducky64 ducky64 commented Mar 29, 2026

Addition with empty ranges now results in the empty range, and sum on empty range is defined consistently. Sum on empty array now defined as 0, consistent with the initial accumulator value interpretation.

Does not change any examples, empty is only used for analog signal values (single value only) and input thresholds (hulled).

Improves test coverage of empty cases.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refines the compiler’s expression evaluation semantics around empty ranges (RangeEmpty), aiming to make range arithmetic and reductions behave consistently when empty values are present.

Changes:

  • Makes RangeEmpty an absorbing value for range ADD and MULT operations.
  • Defines SUM behavior over arrays of ranges when empty values are present (and introduces an explicit empty-array interpretation in the range-unpack path).
  • Updates INTERSECTION-reduction over arrays of ranges to return RangeEmpty when the input contains empties or is all-empty.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +308 to +309
// The implicit initial value of sum is 0
case ArrayValue.UnpackRange.EmptyArray() => RangeValue(0, 0)
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the SUM-over-ranges path, the EmptyArray() case here is currently unreachable because the earlier match arm case (Op.SUM, ArrayValue.Empty(_)) => FloatValue(0) will short-circuit for any empty array (including arrays intended to be ranges). If the intent is for SUM of an empty range-array to return RangeValue(0, 0), this needs a refactor (eg, handle ArrayValue.UnpackRange(...) before the generic empty-array case, or make the empty-array case type-aware). Otherwise, the EmptyArray() branch should be removed to avoid dead code / misleading semantics.

Suggested change
// The implicit initial value of sum is 0
case ArrayValue.UnpackRange.EmptyArray() => RangeValue(0, 0)

Copilot uses AI. Check for mistakes.
Comment on lines 305 to 310
case ArrayValue.UnpackRange.FullRange(valMins, valMaxs) => RangeValue(valMins.sum, valMaxs.sum)
case _ => ErrorValue("unpack_range(empty) is undefined")
case ArrayValue.UnpackRange.RangeWithEmpty(_, _) => RangeEmpty
case ArrayValue.UnpackRange.EmptyRange() => RangeEmpty
// The implicit initial value of sum is 0
case ArrayValue.UnpackRange.EmptyArray() => RangeValue(0, 0)
}
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes alter empty-range propagation semantics (eg, SUM returning RangeEmpty when any element is empty, and defining behavior for empty/all-empty arrays). There are existing evaluation tests in compiler/src/test/scala/edg/compiler/ExprEvaluateTest.scala with TODOs for empty-range cases, but no assertions covering these new behaviors; please add tests for the updated empty-range cases to prevent regressions.

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +25
case (_: RangeType, RangeEmpty) => RangeEmpty
case (RangeEmpty, _: RangeType) => RangeEmpty
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Op.ADD now treats RangeEmpty as an absorbing element (result is always RangeEmpty). This is a behavior change from the previous identity-like behavior and should be covered by a targeted unit test (eg, RangeEmpty + RangeValue, RangeValue + RangeEmpty, and RangeEmpty + RangeEmpty) so downstream users don't silently see different results without test signal.

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +42
case (_: RangeType, RangeEmpty) => RangeEmpty
case (RangeEmpty, _: RangeType) => RangeEmpty
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Op.MULT empty-range handling was changed to make RangeEmpty absorbing. Please add/extend a unit test for RangeEmpty * RangeValue, RangeValue * RangeEmpty, and RangeEmpty * RangeEmpty to lock in the intended semantics.

Copilot uses AI. Check for mistakes.
Comment on lines +344 to +345
case ArrayValue.UnpackRange.RangeWithEmpty(_, _) => RangeEmpty
case ArrayValue.UnpackRange.EmptyRange() => RangeEmpty
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

intersection over an array of ranges now returns RangeEmpty when the input contains empty values (RangeWithEmpty) or is all-empty (EmptyRange). Since this previously fell through to an error, please add a unit test covering these cases to ensure the new behavior is intentional and stable.

Copilot uses AI. Check for mistakes.
@ducky64 ducky64 merged commit 5d9a140 into master Mar 29, 2026
12 checks passed
@ducky64 ducky64 deleted the better-empty-handling branch March 29, 2026 23:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants