Repository navigation
fix(runtime): follow the library body of SequenceFunctions::excludingAt - #1540
Merged
Merged
Conversation
The body, (seq->subsequence(1, startIndex - 1), seq->subsequence(endIndex + 1)), collects over an empty range for a start one past the end, an end past the end or an inverted range, so nothing is removed and no error is raised; a start beyond size + 1 reaches seq#(size + 1) and stays the index error, as do an index 0 and a subsequence whose end is past the end. The compiled Go and C helpers answer the same as the interpreter. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Contributor
Author
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
…ll anchor Co-Authored-By: jason.han <hanhuijun@gmail.com>
…gAt cases Co-Authored-By: jason.han <hanhuijun@gmail.com>
…the sequence An end index of MaxInt64 overflowed end+1 before positionsBetween selected the tail, so (1,2,3)->excludingAt(2, 9223372036854775807) answered [1,1,2,3] where the compiled targets answer [1]; the tail is now selected only when the end lies inside the sequence. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…x note Co-Authored-By: jason.han <hanhuijun@gmail.com>
The fenced bucket block of docs/project/pilot-execution-referee.md still carried the pre-excludingAt values (agree 228, pilot-error 4, both-error 17) while the skill anchor and the referee run had moved to 229/38/7/16. Only the committed-case total is gate-checked; the bucket block is prose. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ibrary-body Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # .agents/skills/testing-pilot-execution-referee/SKILL.md # docs/project/pilot-execution-referee.md
This was referenced Oct 26, 2026
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.
What and why
SequenceFunctions::excludingAtreportedErrIndexOutOfRangefor a start one past the end, an end past the end or an inverted range —(1, 2, 3)->excludingAt(4)and(1, 2, 3)->excludingAt(3, 2)failed with "start index 4 is outside 1..3" / "end index 2 is outside 2..3" — where its normative library body answers the sequence unchanged.builtinSequenceExcludingAtvalidated both endpoints against the sequence before modelling the twosubsequencecalls of the body; the compiled Go and C helpers (sysmlExcludingAt,sysml_excluding_at) did the same.The body is now followed literally in all three places: the positions before
startIndex, then the positions afterendIndex. The only remaining checks are the ones the body itself makes — a start beyondsize + 1makessubsequence(1, startIndex - 1)evaluateseq#(size + 1)(an index error), and an index below 1 is noPositive.Before → after, on
(1, 2, 3):excludingAt(2),excludingAt(1, 2)[1, 3],[3]excludingAt(4)(start = size + 1)ErrIndexOutOfRange[1, 2, 3]excludingAt(4, 9)ErrIndexOutOfRange[1, 2, 3]excludingAt(2, 9)(straddling)ErrIndexOutOfRange[1]excludingAt(3, 2)(inverted by one)ErrIndexOutOfRange[1, 2, 3]excludingAt(3, 1)(wider inversion)ErrIndexOutOfRange[1, 2, 2, 3]—subsequence(1, 2)thensubsequence(2), the overlap repeated()->excludingAt(1)ErrIndexOutOfRange()excludingAt(2, 9223372036854775807)ErrIndexOutOfRange[1](the tail is selected only when the end lies inside the sequence, so noend + 1arithmetic on an unbounded end)excludingAt(5)(start > size + 1)ErrIndexOutOfRangeErrIndexOutOfRange("start index 5 is outside 1..4":seq#(4)insubsequence(1, 4))excludingAt(0),excludingAt(1, 0)ErrIndexOutOfRangeErrIndexOutOfRange(noPositive)subsequence(2, 5)ErrIndexOutOfRangeErrIndexOutOfRange(unchanged:2..5evaluatesseq#(4))subsequencewas checked against the same body and left as it is:(startIndex..endIndex)->collect {in i; seq#(i)}evaluates every position of the range, so an end past the end reaches a genuineseq#(i)out-of-range and stays that typed error; an inverted range is empty and stays the empty sequence.seq#(i)out-of-range semantics are untouched.Over an undetermined operand (
xs : Real[2..4]):excludingAt(xs, 5)is now<undetermined>(a four-element value admits it),excludingAt(xs, 6)is the error; the other definite-error probes (excludingAt(xs, 0),excludingAt(xs, 1, 0),subsequence(xs, 2, 5)) are unchanged.The v1 migration notes for
ExcludeAt/excludeAt/removeAtandReplacingAt/replacingAt/replaceAt(internal/translate/migrate/primitives.go,docs/reference/sysml-v1-migration.md) say the narrowed difference: v2 now fails only on an index outside1..Size(seq)+1, andreplacingAtappends atSize(seq)+1.Specification basis
KerML 1.1 Beta 2 §9.4.14 Sequence Functions has no prose for
excludingAtorsubsequence; the bodies in the normative library (vendoredKernel Libraries/Kernel Function Library/SequenceFunctions.kerml) are the definition:docs/project/spec-compliance.md: the row "An endpoint ofsubsequenceorexcludingAtthat is outside the sequence …" (SequenceFunctionssummary row loses its "except the out-of-range endpoints" qualifier. The pinned pilot evaluatesexcludingAtnatively, not by the body, and is split (agrees for in-range and by-one inverted, throws for a start or end past the end, drops the overlap of a wider inversion); the row says the body wins.How it was verified
New tests (four layers):
tests/parser/testdata/parse/calc_sequence_excluding_at.{sysml,golden}calc_sequence_excluding_at,_past_the_end,_straddling,_inverted,_out_of_range,_zero,calc_sequence_subsequence_past_the_end(no trace fixture: nothing here is ordering-sensitive)internal/exec/runtime/robustness_excluding_at_test.goTestRuntimeRobustnessExcludingAtTestCollectionResults/TestCollectionOperationErrors/TestDefiniteLibraryErrorsSurviveOpenOperands/TestUndeterminedLibraryResultsre-adjudicated to the body (the old error expectations forexcludingAt(4),(2, 1),(2, 9),()->excludingAt(1)become result expectations;excludingAt(5),(0),(1, 0),()->excludingAt(2)keep the error)tests/codegenSeq::ExAtgains the past-the-end, straddling, inverted, zero-end and empty-source cases, interpreter as oracle, Go and C targetsGates (corpora fetched: training examples, pilot corpora, spec examples, pilot library XMI, PSSM suite; Reference FMUs not fetched, that gate skipped here):
go build ./...✓,go vet ./...✓,gofmt -l .empty ✓go test ./...✓ (every package ok;cmd/sysmlandtests/codegenhit the default 10 m timeout under the full-suite load on this machine and pass when re-run with-timeout 40m, 310 s and 342 s)python3 scripts/changelog.py check✓,mkdocs build --strict✓Pilot-exec referee (
go run -C tools ./cmd/pilot-exec-diff, pilot 0.62.0, develop's pin), 500 → 504 cases; every moved or new row:w6d:excluding-at-out-of-range(1,2,3)->excludingAt(4)[1, 2, 3]; pilot throwsIllegalArgumentException: fromIndex(4) > toIndex(3)from a Java sublistundetermined:excludingat-unbound-pastexcludingAt(xs, 5),xs : Real[2..4]<undetermined>(a four-elementxsadmits start 5); pilot throwsIndexOutOfBoundsExceptionover its one unevaluated elementw6d:excluding-at-beyond-the-endexcludingAt(5)(new)seq#(4)w6d:excluding-at-straddlingexcludingAt(2, 9)(new)[1]; pilot throwsfromIndex(9) > toIndex(3)w6d:excluding-at-invertedexcludingAt(3, 2)(new)[1, 2, 3]w6d:excluding-at-inverted-overlapexcludingAt(3, 1)(new)[1, 2, 2, 3]; pilot[1, 2, 3](its native implementation drops the overlap)Bucket totals: agree 228 → 229, disagree 37 → 38, pilot-error 4 → 7, both-error 17 → 16, the rest unchanged. The referee has no committed baseline;
docs/project/pilot-execution-referee.mdand thetesting-pilot-execution-refereeskill anchor record the counts as measured (case total, bucket lists and the prose onexcludingAt(xs, 5)). After the merge ofdevelop(#1538's tenempty_second_operand.cases, allpilot-unevaluated) both files say 514 cases over twenty-three fixtures andagree 229 · kind-only 1 · order-only 0 · disagree 38 · differs-by-design 5 · pilot-unevaluated 167 · pilot-silent 24 · pilot-error 7 · ours-error 10 · ours-undetermined 17 · both-error 16 · nondeterministic 0, which is whatgo run -C tools ./cmd/pilot-exec-diffprints on the merged tree;TestDocumentedCaseCountpasses. Only the case total is gate-checked, so the fenced bucket block of the doc, missed at first, was corrected by hand against that run.Merge with
develop:origin/developat0286c9845(after #1538, #1541, #1542, #1544–#1547 landed) is merged in with one merge commit; the two conflicts were the case total and the bucket lists ofdocs/project/pilot-execution-referee.mdand.agents/skills/testing-pilot-execution-referee/SKILL.md, resolved to carry both #1538's rows and these (above). On the merged tree:go build ./...,go vet ./...,gofmt -l .empty;go testofinternal/exec/runtime,tests/migrate,internal/translate/...,tests/codegen(TestCompiledCalc*) andtools/referee/execpass;python3 scripts/changelog.py checkandmkdocs build --strictpass; the pilot-exec referee gives the 514-case totals above. Earlier dry merge against #1529chore/pilot-pin-2026-09at8a100b317(still open): clean; the pilot-exec referee at its 2026-09 pin (0.63.0, evaluator rebuilt from #1529'spilot-pin.sh) gives the same bucket totals and the same verdict for everyexcludingAtrow as the 0.62.0 run above.Checklist
make testandmake lintpass locallychanges/unreleased/<slug>.<section>.md, not as an edit toCHANGELOG.mdmake docs-countsrun if a gate count moved (compliance rows need nothing: the census is counted at docs build)F4,K5) in the body, docs, or changelogLink to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/4793fedf215e4fca9ddc5ff9cbb45786
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/4793fedf215e4fca9ddc5ff9cbb45786?variant=devin
Requested by: @HuiJun