FA-81116 / Music interval and transposition theory / Open access
Transposing instrument written and concert pitch: written part transposed toward concert pitch · case 01
A concert C for Bb clarinet is written as Bb instead of D: the written part moves the same way as the sounding pitch.
ROOT CAUSE
The to_written branch adds the sounding offset instead of subtracting it.
VERIFIED REPAIR
Restore the written direction step so that it reads `out = pitch - table[inst]`.
Unsuccessful approach: Subtracting the magnitude of the offset works for downward-sounding instruments but writes piccolo and D trumpet parts in the wrong direction.
Case contract
Input [instrument, pitch, direction]. Each instrument has a stipulated sounding offset in semitones (concert = written + offset): Bb clarinet -2, A clarinet -3, F horn -7, Eb alto sax -9, Bb tenor sax -14, Eb baritone sax -21, guitar -12, piccolo +12, D trumpet +2, flute 0. direction to_concert adds the offset, to_written subtracts it. pitch and result must be MIDI 0..127; otherwise, or for unknown instrument or direction, return None.
Why this case matters
Score and part generators convert between written and sounding pitch for every transposing instrument.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
table = {'Bb clarinet': -2, 'A clarinet': -3, 'F horn': -7, 'Eb alto sax': -9, 'Bb tenor sax': -14, 'Eb baritone sax': -21, 'guitar': -12, 'piccolo': 12, 'D trumpet': 2, 'flute': 0}
if not isinstance(x, list) or len(x) != 3:
return None
inst, pitch, direction = x
if inst not in table or not isinstance(pitch, int) or not 0 <= pitch <= 127:
return None
if direction == 'to_concert':
out = pitch + table[inst]
elif direction == 'to_written':
out = pitch + table[inst]
else:
return None
if out < 0 or out > 127:
return None
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[(['Bb clarinet', 62, 'to_concert'], 60), (['Bb clarinet', 60, 'to_written'], 62), (['F horn', 67, 'to_concert'], 60), (['Eb alto sax', 69, 'to_concert'], 60), (['Eb alto sax', 60, 'to_written'], 69), (['Bb tenor sax', 74, 'to_concert'], 60), (['Bb tenor sax', 60, 'to_written'], 74), (['piccolo', 60, 'to_concert'], 72)], [(['F horn', 60, 'to_written'], 67), (['Bb tenor sax', 74, 'to_concert'], 60), (['Bb tenor sax', 60, 'to_written'], 74), (['piccolo', 60, 'to_concert'], 72), (['D trumpet', 60, 'to_concert'], 62), (['guitar', 64, 'to_concert'], 52), (['flute', 60, 'to_concert'], 60), (['Bb clarinet', 127, 'to_written'], None)], [(['Eb alto sax', 60, 'to_written'], 69), (['piccolo', 72, 'to_written'], 60), (['guitar', 64, 'to_concert'], 52), (['flute', 60, 'to_concert'], 60), (['flute', 60, 'to_written'], 60), (['flute', 127, 'to_concert'], 127), (['piccolo', 115, 'to_concert'], 127), (['A clarinet', 60, 'to_written'], 63)], [(['Bb tenor sax', 60, 'to_written'], 74), (['D trumpet', 62, 'to_written'], 60), (['flute', 127, 'to_concert'], 127), (['piccolo', 115, 'to_concert'], 127), (['Eb baritone sax', 10, 'to_concert'], None), (['piccolo', 120, 'to_concert'], None), (['Bb clarinet', 1, 'to_concert'], None), (['F horn', 126, 'to_written'], None)], [(['Bb clarinet', 60, 'to_written'], 62), (['piccolo', 72, 'to_written'], 60), (['piccolo', 120, 'to_concert'], None), (['Bb clarinet', 1, 'to_concert'], None), (['Bb clarinet', 127, 'to_written'], None), (['Bb clarinet', 128, 'to_concert'], None), (['Bb clarinet', -1, 'to_written'], None), (['oboe', 60, 'to_concert'], None)]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("oracle %d" % i, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| oracle 0 | 60 | 60 | Passed |
| oracle 1 | 58 | 62 | Failed |
| oracle 2 | 60 | 60 | Passed |
| oracle 3 | 60 | 60 | Passed |
| oracle 4 | 51 | 69 | Failed |
| oracle 5 | 60 | 60 | Passed |
| oracle 6 | 46 | 74 | Failed |
| oracle 7 | 72 | 72 | Passed |
SHA-256 / 26f44634027d155a6807b010f7ba68b66fef3969e3cc92fb7ceb4e5c654f2ff1
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
table = {'Bb clarinet': -2, 'A clarinet': -3, 'F horn': -7, 'Eb alto sax': -9, 'Bb tenor sax': -14, 'Eb baritone sax': -21, 'guitar': -12, 'piccolo': 12, 'D trumpet': 2, 'flute': 0}
if not isinstance(x, list) or len(x) != 3:
return None
inst, pitch, direction = x
if inst not in table or not isinstance(pitch, int) or not 0 <= pitch <= 127:
return None
if direction == 'to_concert':
out = pitch + table[inst]
elif direction == 'to_written':
out = pitch - abs(table[inst])
else:
return None
if out < 0 or out > 127:
return None
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[(['Bb clarinet', 62, 'to_concert'], 60), (['Bb clarinet', 60, 'to_written'], 62), (['F horn', 67, 'to_concert'], 60), (['Eb alto sax', 69, 'to_concert'], 60), (['Eb alto sax', 60, 'to_written'], 69), (['Bb tenor sax', 74, 'to_concert'], 60), (['Bb tenor sax', 60, 'to_written'], 74), (['piccolo', 60, 'to_concert'], 72)], [(['F horn', 60, 'to_written'], 67), (['Bb tenor sax', 74, 'to_concert'], 60), (['Bb tenor sax', 60, 'to_written'], 74), (['piccolo', 60, 'to_concert'], 72), (['D trumpet', 60, 'to_concert'], 62), (['guitar', 64, 'to_concert'], 52), (['flute', 60, 'to_concert'], 60), (['Bb clarinet', 127, 'to_written'], None)], [(['Eb alto sax', 60, 'to_written'], 69), (['piccolo', 72, 'to_written'], 60), (['guitar', 64, 'to_concert'], 52), (['flute', 60, 'to_concert'], 60), (['flute', 60, 'to_written'], 60), (['flute', 127, 'to_concert'], 127), (['piccolo', 115, 'to_concert'], 127), (['A clarinet', 60, 'to_written'], 63)], [(['Bb tenor sax', 60, 'to_written'], 74), (['D trumpet', 62, 'to_written'], 60), (['flute', 127, 'to_concert'], 127), (['piccolo', 115, 'to_concert'], 127), (['Eb baritone sax', 10, 'to_concert'], None), (['piccolo', 120, 'to_concert'], None), (['Bb clarinet', 1, 'to_concert'], None), (['F horn', 126, 'to_written'], None)], [(['Bb clarinet', 60, 'to_written'], 62), (['piccolo', 72, 'to_written'], 60), (['piccolo', 120, 'to_concert'], None), (['Bb clarinet', 1, 'to_concert'], None), (['Bb clarinet', 127, 'to_written'], None), (['Bb clarinet', 128, 'to_concert'], None), (['Bb clarinet', -1, 'to_written'], None), (['oboe', 60, 'to_concert'], None)]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("oracle %d" % i, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| oracle 0 | 60 | 60 | Passed |
| oracle 1 | 58 | 62 | Failed |
| oracle 2 | 60 | 60 | Passed |
| oracle 3 | 60 | 60 | Passed |
| oracle 4 | 51 | 69 | Failed |
| oracle 5 | 60 | 60 | Passed |
| oracle 6 | 46 | 74 | Failed |
| oracle 7 | 72 | 72 | Passed |
SHA-256 / c23f326d3c913e180d3816a83b8c1620510eda642f71f3c74fe8b084d3c89973
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
table = {'Bb clarinet': -2, 'A clarinet': -3, 'F horn': -7, 'Eb alto sax': -9, 'Bb tenor sax': -14, 'Eb baritone sax': -21, 'guitar': -12, 'piccolo': 12, 'D trumpet': 2, 'flute': 0}
if not isinstance(x, list) or len(x) != 3:
return None
inst, pitch, direction = x
if inst not in table or not isinstance(pitch, int) or not 0 <= pitch <= 127:
return None
if direction == 'to_concert':
out = pitch + table[inst]
elif direction == 'to_written':
out = pitch - table[inst]
else:
return None
if out < 0 or out > 127:
return None
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[(['Bb clarinet', 62, 'to_concert'], 60), (['Bb clarinet', 60, 'to_written'], 62), (['F horn', 67, 'to_concert'], 60), (['Eb alto sax', 69, 'to_concert'], 60), (['Eb alto sax', 60, 'to_written'], 69), (['Bb tenor sax', 74, 'to_concert'], 60), (['Bb tenor sax', 60, 'to_written'], 74), (['piccolo', 60, 'to_concert'], 72)], [(['F horn', 60, 'to_written'], 67), (['Bb tenor sax', 74, 'to_concert'], 60), (['Bb tenor sax', 60, 'to_written'], 74), (['piccolo', 60, 'to_concert'], 72), (['D trumpet', 60, 'to_concert'], 62), (['guitar', 64, 'to_concert'], 52), (['flute', 60, 'to_concert'], 60), (['Bb clarinet', 127, 'to_written'], None)], [(['Eb alto sax', 60, 'to_written'], 69), (['piccolo', 72, 'to_written'], 60), (['guitar', 64, 'to_concert'], 52), (['flute', 60, 'to_concert'], 60), (['flute', 60, 'to_written'], 60), (['flute', 127, 'to_concert'], 127), (['piccolo', 115, 'to_concert'], 127), (['A clarinet', 60, 'to_written'], 63)], [(['Bb tenor sax', 60, 'to_written'], 74), (['D trumpet', 62, 'to_written'], 60), (['flute', 127, 'to_concert'], 127), (['piccolo', 115, 'to_concert'], 127), (['Eb baritone sax', 10, 'to_concert'], None), (['piccolo', 120, 'to_concert'], None), (['Bb clarinet', 1, 'to_concert'], None), (['F horn', 126, 'to_written'], None)], [(['Bb clarinet', 60, 'to_written'], 62), (['piccolo', 72, 'to_written'], 60), (['piccolo', 120, 'to_concert'], None), (['Bb clarinet', 1, 'to_concert'], None), (['Bb clarinet', 127, 'to_written'], None), (['Bb clarinet', 128, 'to_concert'], None), (['Bb clarinet', -1, 'to_written'], None), (['oboe', 60, 'to_concert'], None)]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("oracle %d" % i, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| oracle 0 | 60 | 60 | Passed |
| oracle 1 | 62 | 62 | Passed |
| oracle 2 | 60 | 60 | Passed |
| oracle 3 | 60 | 60 | Passed |
| oracle 4 | 69 | 69 | Passed |
| oracle 5 | 60 | 60 | Passed |
| oracle 6 | 74 | 74 | Passed |
| oracle 7 | 72 | 72 | Passed |
SHA-256 / 19cda1ff01bcceedac91a608f8f2a0f2438219d4fdb3a4f23c0c32dcfd58a729
Verification & scope
A deterministic bounded teaching model with a stipulated toy contract; it is not a complete music notation or theory engine. 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:49:59.962780+00:00.
Case digest / 7f0c997bdf615a269e6b5cfdc19a6220a760cee25207c9f3f65b5626dcf998e3