FAILURE MAP
← Case archive

FA-90246 / Bytecode virtual machines / Open access

Numeric for loop: last iteration dropped · case 01

for i = 1, 4 yields 1, 2, 3.

Verified by executionVariant 1 · 10 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The precomputed count is used as the number of iterations instead of count + 1.

VERIFIED REPAIR

Run count + 1 iterations (capped at 20 values).

Unsuccessful approach: Moving the +1 inside the cap truncates long loops to 19 values.

Case contract

Numeric for-loop preparation (Lua-style FORPREP/FORLOOP). A zero step is an error. With integer init and step, a float limit is floored for positive steps and ceiled for negative ones; the loop is skipped when init is already past the limit in the step direction; otherwise the iteration count (limit - init) // step is precomputed (for negative steps (init - limit) // -step) and the loop runs count + 1 times. Otherwise the loop uses floats and re-tests v <= limit (v >= limit for negative steps). Return at most the first 20 control values.

Why this case matters

Loop-preparation opcodes must precompute counts exactly to avoid off-by-one and overflow bugs.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(init, limit, step):
    if step == 0:
        return 'error: for step is zero'
    if isinstance(init, int) and isinstance(step, int):
        if isinstance(limit, float):
            limit = math.floor(limit) if step > 0 else math.ceil(limit)
        if (step > 0 and init > limit) or (step < 0 and init < limit):
            return []
        count = (limit - init) // step if step > 0 else (init - limit) // (-step)
        out = []
        v = init
        for _ in range(min(count, 19)):
            out.append(v)
            v += step
        return out
    out = []
    v = float(init)
    while (v <= limit if step > 0 else v >= limit) and len(out) < 20:
        out.append(v)
        v += step
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: ascending integer loop', (1, 4, 1), [1, 2, 3, 4]),
  ('descending loop with remainder', (11, 1, -3), [11, 8, 5, 2]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -3.5, 1), [-5, -4]),
  ('float limit ceils for descending loops', (6, 2.5, -1), [6, 5, 4, 3]),
  ('init equal to limit runs once', (1, 1, 1), [1]),
  ('descending init equal to limit runs once', (1, 1, -1), [1]),
  ('long loop is capped at 20 values',
   (0, 101, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 6, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 5, 1), [1, 2, 3, 4, 5]),
  ('descending loop with remainder', (12, 1, -3), [12, 9, 6, 3]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -4.5, 1), [-5]),
  ('float limit ceils for descending loops', (7, 2.5, -1), [7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (2, 2, 1), [2]),
  ('descending init equal to limit runs once', (2, 2, -1), [2]),
  ('long loop is capped at 20 values',
   (0, 102, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 7, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 6, 1), [1, 2, 3, 4, 5, 6]),
  ('descending loop with remainder', (13, 1, -3), [13, 10, 7, 4, 1]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -5.5, 1), []),
  ('float limit ceils for descending loops', (8, 2.5, -1), [8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (3, 3, 1), [3]),
  ('descending init equal to limit runs once', (3, 3, -1), [3]),
  ('long loop is capped at 20 values',
   (0, 103, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 8, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 7, 1), [1, 2, 3, 4, 5, 6, 7]),
  ('descending loop with remainder', (14, 1, -3), [14, 11, 8, 5, 2]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -6.5, 1), []),
  ('float limit ceils for descending loops', (9, 2.5, -1), [9, 8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (4, 4, 1), [4]),
  ('descending init equal to limit runs once', (4, 4, -1), [4]),
  ('long loop is capped at 20 values',
   (0, 104, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 9, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 8, 1), [1, 2, 3, 4, 5, 6, 7, 8]),
  ('descending loop with remainder', (15, 1, -3), [15, 12, 9, 6, 3]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -7.5, 1), []),
  ('float limit ceils for descending loops', (10, 2.5, -1), [10, 9, 8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (5, 5, 1), [5]),
  ('descending init equal to limit runs once', (5, 5, -1), [5]),
  ('long loop is capped at 20 values',
   (0, 105, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 10, 0), 'error: for step is zero')]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression: ascending integer loop[1, 2, 3][1, 2, 3, 4]Failed
descending loop with remainder[11, 8, 5][11, 8, 5, 2]Failed
descending loop with odd step[7, 5, 3][7, 5, 3, 1]Failed
float limit floors for ascending loops[-5][-5, -4]Failed
float limit ceils for descending loops[6, 5, 4][6, 5, 4, 3]Failed
init equal to limit runs once[][1]Failed
descending init equal to limit runs once[][1]Failed
long loop is capped at 20 values[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18][0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]Failed
float loop reaches its limit exactly[1.0, 0.75, 0.5, 0.25, 0.0][1.0, 0.75, 0.5, 0.25, 0.0]Passed
control: zero steperror: for step is zeroerror: for step is zeroPassed

SHA-256 / 19d9ffb7a54a4f514580a1e3da6ef37122db26527de5334b45a3ae1c467f7e95

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(init, limit, step):
    if step == 0:
        return 'error: for step is zero'
    if isinstance(init, int) and isinstance(step, int):
        if isinstance(limit, float):
            limit = math.floor(limit) if step > 0 else math.ceil(limit)
        if (step > 0 and init > limit) or (step < 0 and init < limit):
            return []
        count = (limit - init) // step if step > 0 else (init - limit) // (-step)
        out = []
        v = init
        for _ in range(min(count + 1, 19)):
            out.append(v)
            v += step
        return out
    out = []
    v = float(init)
    while (v <= limit if step > 0 else v >= limit) and len(out) < 20:
        out.append(v)
        v += step
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: ascending integer loop', (1, 4, 1), [1, 2, 3, 4]),
  ('descending loop with remainder', (11, 1, -3), [11, 8, 5, 2]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -3.5, 1), [-5, -4]),
  ('float limit ceils for descending loops', (6, 2.5, -1), [6, 5, 4, 3]),
  ('init equal to limit runs once', (1, 1, 1), [1]),
  ('descending init equal to limit runs once', (1, 1, -1), [1]),
  ('long loop is capped at 20 values',
   (0, 101, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 6, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 5, 1), [1, 2, 3, 4, 5]),
  ('descending loop with remainder', (12, 1, -3), [12, 9, 6, 3]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -4.5, 1), [-5]),
  ('float limit ceils for descending loops', (7, 2.5, -1), [7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (2, 2, 1), [2]),
  ('descending init equal to limit runs once', (2, 2, -1), [2]),
  ('long loop is capped at 20 values',
   (0, 102, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 7, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 6, 1), [1, 2, 3, 4, 5, 6]),
  ('descending loop with remainder', (13, 1, -3), [13, 10, 7, 4, 1]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -5.5, 1), []),
  ('float limit ceils for descending loops', (8, 2.5, -1), [8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (3, 3, 1), [3]),
  ('descending init equal to limit runs once', (3, 3, -1), [3]),
  ('long loop is capped at 20 values',
   (0, 103, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 8, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 7, 1), [1, 2, 3, 4, 5, 6, 7]),
  ('descending loop with remainder', (14, 1, -3), [14, 11, 8, 5, 2]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -6.5, 1), []),
  ('float limit ceils for descending loops', (9, 2.5, -1), [9, 8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (4, 4, 1), [4]),
  ('descending init equal to limit runs once', (4, 4, -1), [4]),
  ('long loop is capped at 20 values',
   (0, 104, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 9, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 8, 1), [1, 2, 3, 4, 5, 6, 7, 8]),
  ('descending loop with remainder', (15, 1, -3), [15, 12, 9, 6, 3]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -7.5, 1), []),
  ('float limit ceils for descending loops', (10, 2.5, -1), [10, 9, 8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (5, 5, 1), [5]),
  ('descending init equal to limit runs once', (5, 5, -1), [5]),
  ('long loop is capped at 20 values',
   (0, 105, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 10, 0), 'error: for step is zero')]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression: ascending integer loop[1, 2, 3, 4][1, 2, 3, 4]Passed
descending loop with remainder[11, 8, 5, 2][11, 8, 5, 2]Passed
descending loop with odd step[7, 5, 3, 1][7, 5, 3, 1]Passed
float limit floors for ascending loops[-5, -4][-5, -4]Passed
float limit ceils for descending loops[6, 5, 4, 3][6, 5, 4, 3]Passed
init equal to limit runs once[1][1]Passed
descending init equal to limit runs once[1][1]Passed
long loop is capped at 20 values[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18][0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]Failed
float loop reaches its limit exactly[1.0, 0.75, 0.5, 0.25, 0.0][1.0, 0.75, 0.5, 0.25, 0.0]Passed
control: zero steperror: for step is zeroerror: for step is zeroPassed

SHA-256 / 668fd5afb14678e3bb415ceb1e509cf04736ff8f31665f0e2ba6fc2ce1fd5856

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(init, limit, step):
    if step == 0:
        return 'error: for step is zero'
    if isinstance(init, int) and isinstance(step, int):
        if isinstance(limit, float):
            limit = math.floor(limit) if step > 0 else math.ceil(limit)
        if (step > 0 and init > limit) or (step < 0 and init < limit):
            return []
        count = (limit - init) // step if step > 0 else (init - limit) // (-step)
        out = []
        v = init
        for _ in range(min(count, 19) + 1):
            out.append(v)
            v += step
        return out
    out = []
    v = float(init)
    while (v <= limit if step > 0 else v >= limit) and len(out) < 20:
        out.append(v)
        v += step
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: ascending integer loop', (1, 4, 1), [1, 2, 3, 4]),
  ('descending loop with remainder', (11, 1, -3), [11, 8, 5, 2]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -3.5, 1), [-5, -4]),
  ('float limit ceils for descending loops', (6, 2.5, -1), [6, 5, 4, 3]),
  ('init equal to limit runs once', (1, 1, 1), [1]),
  ('descending init equal to limit runs once', (1, 1, -1), [1]),
  ('long loop is capped at 20 values',
   (0, 101, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 6, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 5, 1), [1, 2, 3, 4, 5]),
  ('descending loop with remainder', (12, 1, -3), [12, 9, 6, 3]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -4.5, 1), [-5]),
  ('float limit ceils for descending loops', (7, 2.5, -1), [7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (2, 2, 1), [2]),
  ('descending init equal to limit runs once', (2, 2, -1), [2]),
  ('long loop is capped at 20 values',
   (0, 102, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 7, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 6, 1), [1, 2, 3, 4, 5, 6]),
  ('descending loop with remainder', (13, 1, -3), [13, 10, 7, 4, 1]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -5.5, 1), []),
  ('float limit ceils for descending loops', (8, 2.5, -1), [8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (3, 3, 1), [3]),
  ('descending init equal to limit runs once', (3, 3, -1), [3]),
  ('long loop is capped at 20 values',
   (0, 103, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 8, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 7, 1), [1, 2, 3, 4, 5, 6, 7]),
  ('descending loop with remainder', (14, 1, -3), [14, 11, 8, 5, 2]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -6.5, 1), []),
  ('float limit ceils for descending loops', (9, 2.5, -1), [9, 8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (4, 4, 1), [4]),
  ('descending init equal to limit runs once', (4, 4, -1), [4]),
  ('long loop is capped at 20 values',
   (0, 104, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 9, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 8, 1), [1, 2, 3, 4, 5, 6, 7, 8]),
  ('descending loop with remainder', (15, 1, -3), [15, 12, 9, 6, 3]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -7.5, 1), []),
  ('float limit ceils for descending loops', (10, 2.5, -1), [10, 9, 8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (5, 5, 1), [5]),
  ('descending init equal to limit runs once', (5, 5, -1), [5]),
  ('long loop is capped at 20 values',
   (0, 105, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 10, 0), 'error: for step is zero')]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression: ascending integer loop[1, 2, 3, 4][1, 2, 3, 4]Passed
descending loop with remainder[11, 8, 5, 2][11, 8, 5, 2]Passed
descending loop with odd step[7, 5, 3, 1][7, 5, 3, 1]Passed
float limit floors for ascending loops[-5, -4][-5, -4]Passed
float limit ceils for descending loops[6, 5, 4, 3][6, 5, 4, 3]Passed
init equal to limit runs once[1][1]Passed
descending init equal to limit runs once[1][1]Passed
long loop is capped at 20 values[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19][0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]Passed
float loop reaches its limit exactly[1.0, 0.75, 0.5, 0.25, 0.0][1.0, 0.75, 0.5, 0.25, 0.0]Passed
control: zero steperror: for step is zeroerror: for step is zeroPassed

SHA-256 / 025d37bd763c993ce66d1815cc231af6f3cde19aff47017fe24a9ab0d290d0fd

Verification & scope

A deterministic, bounded teaching model of one bytecode virtual machine mechanism with a stipulated instruction encoding; it is not a production VM and claims no conformance to any real specification. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:51:25.030186+00:00.

Case digest / b7940bda589759f9c239d695c26fe3251a250beae60b5c09480d71afba6e770e