FA-81166 / Music interval and transposition theory / Open access
Chord symbol to pitch classes: slash bass duplicated · case 01
C/E returns [4,0,4,7] with the third listed twice instead of [4,0,7].
ROOT CAUSE
The bass note is prepended without removing it from its existing chord-tone position.
VERIFIED REPAIR
Restore the slash bass placement step so that it reads `if b in tones: tones.remove(b) tones.insert(0, b)`.
Unsuccessful approach: Rotating the chord to start on the bass reorders the remaining tones, so C/E returns [4,7,0].
Case contract
Input a chord symbol: root letter with optional # or b, a quality from "", m, dim, aug, 7, maj7, m7, m7b5, dim7, sus4, mMaj7, 6, and optionally "/" plus a bass note (letter with optional # or b and nothing else). Return pitch classes root-first in template order; for a slash chord the bass moves to the front (removed from its old position if it is a chord tone, otherwise added). Unknown or malformed symbols return None.
Why this case matters
Lead-sheet, accompaniment and guitar-chart tools expand chord symbols into voicings.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
base = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11}
shapes = {'': [0, 4, 7], 'm': [0, 3, 7], 'dim': [0, 3, 6], 'aug': [0, 4, 8], '7': [0, 4, 7, 10], 'maj7': [0, 4, 7, 11], 'm7': [0, 3, 7, 10], 'm7b5': [0, 3, 6, 10], 'dim7': [0, 3, 6, 9], 'sus4': [0, 5, 7], 'mMaj7': [0, 3, 7, 11], '6': [0, 4, 7, 9]}
def root(s):
if not s or s[0] not in base:
return None, s
if s[1:2] in ('#', 'b'):
return (base[s[0]] + (1 if s[1] == '#' else -1)) % 12, s[2:]
return base[s[0]], s[1:]
if not isinstance(x, str):
return None
head, slash, tail = x.partition('/')
r, quality = root(head)
if r is None or quality not in shapes:
return None
tones = [(r + i) % 12 for i in shapes[quality]]
if slash:
b, rest = root(tail)
if b is None or rest:
return None
tones.insert(0, b)
return tones
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('C', [0, 4, 7]), ('Cm', [0, 3, 7]), ('Bb', [10, 2, 5]), ('Bbm7', [10, 1, 5, 8]), ('Bb7', [10, 2, 5, 8]), ('C/E', [4, 0, 7]), ('F/A', [9, 5, 0]), ('D/F#', [6, 2, 9])], [('Bbm7', [10, 1, 5, 8]), ('Bb7', [10, 2, 5, 8]), ('F#m7b5', [6, 9, 0, 4]), ('Ebmaj7', [3, 7, 10, 2]), ('C/G', [7, 0, 4]), ('F/A', [9, 5, 0]), ('Bb/D', [2, 10, 5]), ('Gb/Bb', [10, 6, 1])], [('Ebmaj7', [3, 7, 10, 2]), ('Gdim7', [7, 10, 1, 4]), ('Aaug', [9, 1, 5]), ('Dsus4', [2, 7, 9]), ('F/A', [9, 5, 0]), ('Bb/D', [2, 10, 5]), ('G7/F', [5, 7, 11, 2]), ('B/D#', [3, 11, 6])], [('Dsus4', [2, 7, 9]), ('C/Bb', [10, 0, 4, 7]), ('Am/G', [7, 9, 0, 4]), ('Bb/D', [2, 10, 5]), ('Cmaj7/B', [11, 0, 4, 7]), ('Cb', [11, 3, 6]), ('D/F#', [6, 2, 9]), ('Ebm/Gb', [6, 3, 10])], [('C/E', [4, 0, 7]), ('G7/F', [5, 7, 11, 2]), ('Cb', [11, 3, 6]), ('Cbm', [11, 2, 6]), ('E#', [5, 9, 0]), ('A6', [9, 1, 4, 6]), ('D/F#', [6, 2, 9]), ('Gb/Bb', [10, 6, 1])]]
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 | [0, 4, 7] | [0, 4, 7] | Passed |
| oracle 1 | [0, 3, 7] | [0, 3, 7] | Passed |
| oracle 2 | [10, 2, 5] | [10, 2, 5] | Passed |
| oracle 3 | [10, 1, 5, 8] | [10, 1, 5, 8] | Passed |
| oracle 4 | [10, 2, 5, 8] | [10, 2, 5, 8] | Passed |
| oracle 5 | [4, 0, 4, 7] | [4, 0, 7] | Failed |
| oracle 6 | [9, 5, 9, 0] | [9, 5, 0] | Failed |
| oracle 7 | [6, 2, 6, 9] | [6, 2, 9] | Failed |
SHA-256 / 80854834ff2bb7e1350a3853f389e7c4e9294f46862de786966d5a438187bbaa
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
base = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11}
shapes = {'': [0, 4, 7], 'm': [0, 3, 7], 'dim': [0, 3, 6], 'aug': [0, 4, 8], '7': [0, 4, 7, 10], 'maj7': [0, 4, 7, 11], 'm7': [0, 3, 7, 10], 'm7b5': [0, 3, 6, 10], 'dim7': [0, 3, 6, 9], 'sus4': [0, 5, 7], 'mMaj7': [0, 3, 7, 11], '6': [0, 4, 7, 9]}
def root(s):
if not s or s[0] not in base:
return None, s
if s[1:2] in ('#', 'b'):
return (base[s[0]] + (1 if s[1] == '#' else -1)) % 12, s[2:]
return base[s[0]], s[1:]
if not isinstance(x, str):
return None
head, slash, tail = x.partition('/')
r, quality = root(head)
if r is None or quality not in shapes:
return None
tones = [(r + i) % 12 for i in shapes[quality]]
if slash:
b, rest = root(tail)
if b is None or rest:
return None
tones = tones[tones.index(b):] + tones[:tones.index(b)] if b in tones else [b] + tones
return tones
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('C', [0, 4, 7]), ('Cm', [0, 3, 7]), ('Bb', [10, 2, 5]), ('Bbm7', [10, 1, 5, 8]), ('Bb7', [10, 2, 5, 8]), ('C/E', [4, 0, 7]), ('F/A', [9, 5, 0]), ('D/F#', [6, 2, 9])], [('Bbm7', [10, 1, 5, 8]), ('Bb7', [10, 2, 5, 8]), ('F#m7b5', [6, 9, 0, 4]), ('Ebmaj7', [3, 7, 10, 2]), ('C/G', [7, 0, 4]), ('F/A', [9, 5, 0]), ('Bb/D', [2, 10, 5]), ('Gb/Bb', [10, 6, 1])], [('Ebmaj7', [3, 7, 10, 2]), ('Gdim7', [7, 10, 1, 4]), ('Aaug', [9, 1, 5]), ('Dsus4', [2, 7, 9]), ('F/A', [9, 5, 0]), ('Bb/D', [2, 10, 5]), ('G7/F', [5, 7, 11, 2]), ('B/D#', [3, 11, 6])], [('Dsus4', [2, 7, 9]), ('C/Bb', [10, 0, 4, 7]), ('Am/G', [7, 9, 0, 4]), ('Bb/D', [2, 10, 5]), ('Cmaj7/B', [11, 0, 4, 7]), ('Cb', [11, 3, 6]), ('D/F#', [6, 2, 9]), ('Ebm/Gb', [6, 3, 10])], [('C/E', [4, 0, 7]), ('G7/F', [5, 7, 11, 2]), ('Cb', [11, 3, 6]), ('Cbm', [11, 2, 6]), ('E#', [5, 9, 0]), ('A6', [9, 1, 4, 6]), ('D/F#', [6, 2, 9]), ('Gb/Bb', [10, 6, 1])]]
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 | [0, 4, 7] | [0, 4, 7] | Passed |
| oracle 1 | [0, 3, 7] | [0, 3, 7] | Passed |
| oracle 2 | [10, 2, 5] | [10, 2, 5] | Passed |
| oracle 3 | [10, 1, 5, 8] | [10, 1, 5, 8] | Passed |
| oracle 4 | [10, 2, 5, 8] | [10, 2, 5, 8] | Passed |
| oracle 5 | [4, 7, 0] | [4, 0, 7] | Failed |
| oracle 6 | [9, 0, 5] | [9, 5, 0] | Failed |
| oracle 7 | [6, 9, 2] | [6, 2, 9] | Failed |
SHA-256 / 115248e0fb8c89091cbdf451e0dd981d287cc5ff033ab1518b28535fdb6a030f
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
base = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11}
shapes = {'': [0, 4, 7], 'm': [0, 3, 7], 'dim': [0, 3, 6], 'aug': [0, 4, 8], '7': [0, 4, 7, 10], 'maj7': [0, 4, 7, 11], 'm7': [0, 3, 7, 10], 'm7b5': [0, 3, 6, 10], 'dim7': [0, 3, 6, 9], 'sus4': [0, 5, 7], 'mMaj7': [0, 3, 7, 11], '6': [0, 4, 7, 9]}
def root(s):
if not s or s[0] not in base:
return None, s
if s[1:2] in ('#', 'b'):
return (base[s[0]] + (1 if s[1] == '#' else -1)) % 12, s[2:]
return base[s[0]], s[1:]
if not isinstance(x, str):
return None
head, slash, tail = x.partition('/')
r, quality = root(head)
if r is None or quality not in shapes:
return None
tones = [(r + i) % 12 for i in shapes[quality]]
if slash:
b, rest = root(tail)
if b is None or rest:
return None
if b in tones:
tones.remove(b)
tones.insert(0, b)
return tones
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('C', [0, 4, 7]), ('Cm', [0, 3, 7]), ('Bb', [10, 2, 5]), ('Bbm7', [10, 1, 5, 8]), ('Bb7', [10, 2, 5, 8]), ('C/E', [4, 0, 7]), ('F/A', [9, 5, 0]), ('D/F#', [6, 2, 9])], [('Bbm7', [10, 1, 5, 8]), ('Bb7', [10, 2, 5, 8]), ('F#m7b5', [6, 9, 0, 4]), ('Ebmaj7', [3, 7, 10, 2]), ('C/G', [7, 0, 4]), ('F/A', [9, 5, 0]), ('Bb/D', [2, 10, 5]), ('Gb/Bb', [10, 6, 1])], [('Ebmaj7', [3, 7, 10, 2]), ('Gdim7', [7, 10, 1, 4]), ('Aaug', [9, 1, 5]), ('Dsus4', [2, 7, 9]), ('F/A', [9, 5, 0]), ('Bb/D', [2, 10, 5]), ('G7/F', [5, 7, 11, 2]), ('B/D#', [3, 11, 6])], [('Dsus4', [2, 7, 9]), ('C/Bb', [10, 0, 4, 7]), ('Am/G', [7, 9, 0, 4]), ('Bb/D', [2, 10, 5]), ('Cmaj7/B', [11, 0, 4, 7]), ('Cb', [11, 3, 6]), ('D/F#', [6, 2, 9]), ('Ebm/Gb', [6, 3, 10])], [('C/E', [4, 0, 7]), ('G7/F', [5, 7, 11, 2]), ('Cb', [11, 3, 6]), ('Cbm', [11, 2, 6]), ('E#', [5, 9, 0]), ('A6', [9, 1, 4, 6]), ('D/F#', [6, 2, 9]), ('Gb/Bb', [10, 6, 1])]]
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 | [0, 4, 7] | [0, 4, 7] | Passed |
| oracle 1 | [0, 3, 7] | [0, 3, 7] | Passed |
| oracle 2 | [10, 2, 5] | [10, 2, 5] | Passed |
| oracle 3 | [10, 1, 5, 8] | [10, 1, 5, 8] | Passed |
| oracle 4 | [10, 2, 5, 8] | [10, 2, 5, 8] | Passed |
| oracle 5 | [4, 0, 7] | [4, 0, 7] | Passed |
| oracle 6 | [9, 5, 0] | [9, 5, 0] | Passed |
| oracle 7 | [6, 2, 9] | [6, 2, 9] | Passed |
SHA-256 / eb72f5d763c630c97bd4a310da45b275a7283ab6666417925f265451589eb65c
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:50:00.563876+00:00.
Case digest / 4668b9be9d9fe65dd8b4593a15f80966344a184078317c26d0b0763b92e412e4