#3662 Music Theory Knowledge Graph
- Get link
- X
- Other Apps
#3662 Music Theory Knowledge Graph
#3662 Provide a wide range of entities and relationships for a music theory knowledge graph
Here’s a comprehensive menu of entities and relationship types you can mix-and-match to design a rich music-theory knowledge graph. I’ve grouped things so you can adopt only what you need and still keep the schema coherent.
Core pitch & harmony
Entities
-
Note, Pitch, PitchClass (C, C♯/D♭…), Octave, Register
-
Interval (m2, M3, P5…), CompoundInterval
-
Scale (major, natural minor, harmonic minor, melodic minor, pentatonic, whole-tone, chromatic), Mode (Ionian…Locrian; Dorian ♯4, etc.)
-
Chord (triad, seventh, extended, altered), ChordQuality (major, minor, diminished, augmented, dominant), ChordTone (root, 3rd, 5th, 7th), Extension (9, 11, 13), Alteration (♭9, ♯11, ♭13)
-
Key, KeySignature, Tonality (major/minor/modal), Tonic/Dominant/Subdominant (HarmonicFunction)
-
Cadence (PAC, IAC, HC, PC, deceptive), Progression (I–vi–IV–V, ii–V–I…), RomanNumeral, FiguredBass
-
Modulation, PivotChord, SecondaryDominant, BorrowedChord (mode mixture), Neapolitan, AugmentedSixth (It/Fr/Ger), TritoneSubstitution
-
ChordScale (e.g., Mixolydian for V7), GuideToneLine
Relationships (examples)
-
PITCHCLASS enharmonic_equivalent_of PITCHCLASS
-
NOTE has_pitch PITCH
;PITCH in_octave OCTAVE
-
INTERVAL between NOTE ↔ NOTE
;CHORD built_from INTERVAL
-
SCALE consists_of PITCHCLASS
;MODE derived_from SCALE
-
CHORD contains CHORDTONE
;CHORD has_quality CHORDQUALITY
;CHORD has_extension EXTENSION
;CHORD has_alteration ALTERATION
-
KEY uses KeySignature
;KEY has_tonality TONALITY
-
CHORD diatonic_to KEY
;CHORD borrowed_from MODE
-
ROMANNUMERAL analyzes CHORD
;FIGUREDBASS realizes CHORD
-
CHORD resolves_to CHORD
;PROGRESSION orders CHORD
-
FUNCTION assigned_to CHORD
(e.g., Dominant → V7) -
CADENCE concludes PROGRESSION
;CADENCE type_of cadence_class
-
SECONDARYDOMINANT targets CHORD
-
AUGMENTEDSIXTH resolves_to DOMINANT
-
MODULATION from KEY → to KEY
;PIVOTCHORD pivots_between KEY ↔ KEY
Rhythm, meter & form
Entities
-
TimeSignature, Meter (simple/compound/complex), Beat, Subdivision, Tempo, TempoMarking, Pulse, Polyrhythm, Tuplet, Syncopation, Hemiola
-
Articulation (staccato, legato…), Dynamics (pp…ff), Accents
-
Motif, Cell, Figure, Phrase, Period, Sentence, Theme
-
Form (Binary, Ternary, Rondo, Sonata, Strophic, Verse–Chorus, 12-bar Blues), Section (Intro, Exposition, Development, Bridge, Coda), RehearsalMark
Relationships
-
TIMESIGNATURE defines METER
;METER groups BEAT
-
TEMPO measured_in BPM
;PHRASE has_motif MOTIF
-
SECTION part_of FORM
;PHRASE contained_in SECTION
-
RHYTHMIC_EVENT uses Subdivision/Tuplet
-
ACCENT applied_to NOTE/CHORD
;DYNAMICS applied_to SECTION
-
HEMIOLA occurs_over TIMESIGNATURE
-
MOTIF transforms_to MOTIF
(augmentation, diminution, inversion, retrograde)
Voice-leading & counterpoint
Entities
-
Voice (Soprano, Alto, Tenor, Bass… or any instrument line), Texture (monophony, homophony, polyphony), SpeciesCounterpoint (1st–5th), VoiceLeadingRule (e.g., avoid parallels), TendencyTone (leading tone, 4̂ in V7), Resolution
Relationships
-
VOICE performs NOTE
;VOICE leading_to NOTE
-
TENDENCYTONE resolves_to NOTE
-
VOICELEADINGRULE constrains VOICE_PAIR
-
TEXTURE realized_by VOICE_SET
-
NONCHORDTONE type_of (passing, neighbor, suspension, retardation, appoggiatura, escape, anticipation, pedal)
-
NONCHORDTONE resolves_to CHORDTONE
;prepared_by NOTE
;suspended_from NOTE
Orchestration, instruments & timbre
Entities
-
Instrument, Family (strings, winds…), Range, TransposingInstrument, Clef, Staff, NotationSymbol, Technique (pizz., sul pont., flutter-tongue…), TimbreDescriptor (bright, dark), OrchestrationPattern
Relationships
-
INSTRUMENT belongs_to FAMILY
;INSTRUMENT has_range RANGE
-
INSTRUMENT notated_in CLEF
;INSTRUMENT sounds_at TRANSPOSITION
-
TECHNIQUE applicable_to INSTRUMENT
;TECHNIQUE affects TIMBRE
-
NOTE realized_as NotationSymbol
;PART written_on STAFF
Tuning, acoustics & systems
Entities
-
TuningSystem (12-TET, just intonation, meantone, Pythagorean), Temperament, A4Reference, Cent
-
Fundamental, Partial (Overtone), HarmonicSeries, Spectrum, Formant
-
Tonnetz, CircleOfFifths, VoiceLeadingGraph
Relationships
-
TUNINGSYSTEM defines INTERVAL_RATIOS
-
PITCH has_frequency Hz
;FUNDAMENTAL has_partial PARTIAL(n)
-
KEY adjacent_on CircleOfFifths KEY
;CHORD neighbors Tonnetz CHORD
-
PITCH distance_in_cents CENT
Analysis frameworks (classical, jazz, set theory, world)
Entities
-
SetTheory: PitchClassSet, ForteNumber, SetOperation (Tn, In), ZRelation
-
SchenkerianLevel (foreground/middleground/background), Urlinie, Bassbrechung
-
JazzTheory: ChordSymbol, SlashChord, UpperStructureTriad, Lick, ImprovisationPattern, GuideToneLine
-
World systems: Raga, Arohana/Avarohana, Pakad; Tala; Maqam, Jins; GamelanScale (slendro/pelog)
Relationships
-
PITCHCLASSSET labeled_by FORTE_NUMBER
;PITCHCLASSSET related_by SETOPERATION to PITCHCLASSSET
-
URLINIE spans SCALE_DEGREES
;BASSBRECHUNG outlines HARMONY
-
CHORD uses UPPERSTRUCTURETRIAD
;SLASHCHORD bass_is PITCHCLASS
-
LICK compatible_with CHORDSCALE
;GUIDETONELINE threads_through PROGRESSION
-
RAGA defined_by AROHANA/AVAROHANA
;RAGA characteristic_phrase PAKAD
-
MAQAM built_from JINS
;TALA cycles BEAT_PATTERN
Digital/notation layer (optional but handy)
Entities
-
MIDIEvent (note_on/off), Velocity, PitchBend, ControlChange, NotatedEvent, BarNumber, GridPosition, Score, DAWProject
Relationships
-
MIDIEvent represents NOTE
;NOTE has_velocity VELOCITY
-
NOTATEDEVENT aligns_to GRIDPOSITION
;SCORE contains SECTION
Practical properties (attach to many entities)
-
Name, Symbol, Spelling (enharmonics), ScaleDegrees, Accidentals, SemitoneSpan, Quality, Function, Degree (e.g., ̂1, ̂5), Inversion (6, 6⁴, 4₂…), Voicing, Registration, Frequency(Hz), Cents, Probability (for generative models), Difficulty, GenreTag, StyleTag
Example triples (human-readable)
-
C♯ enharmonic_equivalent_of D♭
-
C major scale consists_of {C, D, E, F, G, A, B}
-
V7 of G major resolves_to I (Gmaj7) ; function = Dominant
-
Ger+6 resolves_to V ; contains {♭6, 1, ♯4, ♭3} (relative scale degrees)
-
ii–V–I in C orders {Dmin7 → G7 → Cmaj7}
-
Leading tone (B in C major) resolves_to C (tendency-tone)
-
Mixolydian is_chordscale_for V7
-
Upper-structure triad (E major) over C7 yields {♯9, ♭13} colors
-
Sonata form has_section {Exposition, Development, Recap}
-
Raga Yaman defined_by Arohana/Avarohana ; pakad = phrase motif
-
Alto Sax sounds_at M2 down ; notated_in treble clef
Optional: minimal Cypher-ish schema sketch
// Labels CREATE CONSTRAINT note_name IF NOT EXISTS FOR (n:Note) REQUIRE n.name IS UNIQUE; CREATE CONSTRAINT pc_name IF NOT EXISTS FOR (p:PitchClass) REQUIRE p.name IS UNIQUE; CREATE CONSTRAINT chord_id IF NOT EXISTS FOR (c:Chord) REQUIRE c.symbol IS UNIQUE; CREATE CONSTRAINT scale_id IF NOT EXISTS FOR (s:Scale) REQUIRE s.name IS UNIQUE; CREATE CONSTRAINT key_id IF NOT EXISTS FOR (k:Key) REQUIRE k.name IS UNIQUE; // Relationship types you’ll likely use // :ENHARMONIC_EQUIVALENT, :IN_OCTAVE, :BUILT_FROM, :CONSISTS_OF, :DERIVED_FROM, // :CONTAINS, :HAS_QUALITY, :HAS_EXTENSION, :HAS_ALTERATION, :DIATONIC_TO, // :BORROWED_FROM, :ANALYZES, :REALIZES, :RESOLVES_TO, :ORDERS, :HAS_FUNCTION, // :CONCLUDES, :TARGETS, :PIVOTS_BETWEEN, :MODULATES_TO, :ADJACENT_ON_COF, :NEIGHBORS_ON_TONNETZ
Design notes & tips
-
Model concepts (e.g., “Dominant function”) separately from instances (a specific V7 in G major). Attach analysis as nodes (Roman numerals, figured bass) so you can keep multiple analytical layers.
-
Keep enharmonics and spelling explicit—crucial for notation vs. pitch-class logic.
-
Use scale-degree properties (
degree
,accidental
) on Note-in-Key edges for powerful queries (e.g., “all ♭6 in minor keys that resolve to 5”). -
Voice-leading pays off if you store events (note onsets, durations) and connect them by
:LEADS_TO
within the same voice. -
For jazz, upper-structure & chord-scale links make recommendation/voicing engines trivial.
-
For set theory, store Forte numbers and Tn/In links to enable similarity queries.
If you want, I can turn this into a seed CSV (entities + relationship rows) or a ready-to-run Neo4j schema with sample data (e.g., ii–V–I in all keys, common cadences, and voice-leading rules).
Awesome — I’ll give you a ready-to-run Neo4j seed that sets up the schema and inserts a compact but versatile starter dataset (pitches, chord qualities, functions, modes, a few keys, and ii–V–I progressions + PAC cadences). You can paste this whole thing into Neo4j Browser.
Neo4j schema + seed data (copy/paste into Neo4j Browser)
// ===================== // 0) Clean slate (optional in a dev DB) // ===================== OPTIONAL MATCH (n) DETACH DELETE n; // ===================== // 1) Constraints // ===================== CREATE CONSTRAINT note_name IF NOT EXISTS FOR (n:Note) REQUIRE n.name IS UNIQUE; CREATE CONSTRAINT pc_name IF NOT EXISTS FOR (p:PitchClass) REQUIRE p.name IS UNIQUE; CREATE CONSTRAINT qual_name IF NOT EXISTS FOR (q:ChordQuality)REQUIRE q.name IS UNIQUE; CREATE CONSTRAINT func_name IF NOT EXISTS FOR (f:HarmonicFunction) REQUIRE f.name IS UNIQUE; CREATE CONSTRAINT scale_name IF NOT EXISTS FOR (s:Scale) REQUIRE s.name IS UNIQUE; CREATE CONSTRAINT mode_name IF NOT EXISTS FOR (m:Mode) REQUIRE m.name IS UNIQUE; CREATE CONSTRAINT key_name IF NOT EXISTS FOR (k:Key) REQUIRE k.name IS UNIQUE; CREATE CONSTRAINT chord_symbol IF NOT EXISTS FOR (c:Chord) REQUIRE c.symbol IS UNIQUE; CREATE CONSTRAINT roman_id IF NOT EXISTS FOR (r:RomanNumeral)REQUIRE r.id IS UNIQUE; CREATE CONSTRAINT prog_id IF NOT EXISTS FOR (p:Progression) REQUIRE p.id IS UNIQUE; CREATE CONSTRAINT cadence_name IF NOT EXISTS FOR (c:Cadence) REQUIRE c.name IS UNIQUE; // ===================== // 2) Core vocab // ===================== // 2a) Pitch classes (12-TET names; include common enharmonics as aliases) UNWIND [ {name:'C', enh:['B#']}, {name:'C#', enh:['Db']}, {name:'D', enh:[]}, {name:'D#', enh:['Eb']}, {name:'E', enh:['Fb']}, {name:'F', enh:['E#']}, {name:'F#', enh:['Gb']}, {name:'G', enh:[]}, {name:'G#', enh:['Ab']}, {name:'A', enh:[]}, {name:'A#', enh:['Bb']}, {name:'B', enh:['Cb']} ] AS pc MERGE (p:PitchClass {name: pc.name}) WITH p, pc UNWIND pc.enh AS alt MERGE (e:PitchClass {name: alt}) MERGE (p)-[:ENHARMONIC_EQUIVALENT]->(e); // 2b) Chord qualities UNWIND [ {name:'major', symbol:''}, {name:'minor', symbol:'m'}, {name:'diminished', symbol:'dim'}, {name:'augmented', symbol:'aug'}, {name:'dominant7', symbol:'7'}, {name:'major7', symbol:'maj7'}, {name:'minor7', symbol:'m7'}, {name:'half-diminished7', symbol:'m7b5'} ] AS cq MERGE (:ChordQuality {name:cq.name, symbol:cq.symbol}); // 2c) Harmonic functions UNWIND ['Tonic','Subdominant','Dominant'] AS fn MERGE (:HarmonicFunction {name:fn}); // 2d) Scales & modes MERGE (maj:Scale {name:'Major', degrees:[1,2,3,4,5,6,7]}); MERGE (minNat:Scale {name:'Natural Minor', degrees:[1,2,b3,4,5,b6,b7]}); UNWIND [ {name:'Ionian', parent:'Major', degree:1}, {name:'Dorian', parent:'Major', degree:2}, {name:'Phrygian', parent:'Major', degree:3}, {name:'Lydian', parent:'Major', degree:4}, {name:'Mixolydian',parent:'Major', degree:5}, {name:'Aeolian', parent:'Major', degree:6}, {name:'Locrian', parent:'Major', degree:7} ] AS m MATCH (s:Scale {name:m.parent}) MERGE (mode:Mode {name:m.name, parent:s.name, degree:m.degree}) MERGE (mode)-[:DERIVED_FROM]->(s); // ===================== // 3) A handful of keys // ===================== UNWIND [ {name:'C major', tonic:'C', mode:'Ionian'}, {name:'G major', tonic:'G', mode:'Ionian'}, {name:'D major', tonic:'D', mode:'Ionian'}, {name:'F major', tonic:'F', mode:'Ionian'}, {name:'A minor', tonic:'A', mode:'Aeolian'}, {name:'E minor', tonic:'E', mode:'Aeolian'} ] AS k MATCH (t:PitchClass {name:k.tonic}) MATCH (m:Mode {name:k.mode}) MERGE (key:Key {name:k.name}) ON CREATE SET key.tonic = k.tonic, key.mode = k.mode MERGE (key)-[:TONIC]->(t) MERGE (key)-[:MODE]->(m); // ===================== // 4) Helper: make a chord quickly // ===================== CALL { WITH 'stub' AS _ RETURN 1 AS ok } YIELD ok WITH ok CALL { // procedure-like subquery: CREATE chord, link to pc, quality, key, function, roman numeral WITH [ // C major ii–V–I {key:'C major', rn:'ii', root:'D', symbol:'Dm7', quality:'minor7', func:'Subdominant'}, {key:'C major', rn:'V', root:'G', symbol:'G7', quality:'dominant7', func:'Dominant'}, {key:'C major', rn:'I', root:'C', symbol:'Cmaj7', quality:'major7', func:'Tonic'}, // G major ii–V–I {key:'G major', rn:'ii', root:'A', symbol:'Am7', quality:'minor7', func:'Subdominant'}, {key:'G major', rn:'V', root:'D', symbol:'D7', quality:'dominant7', func:'Dominant'}, {key:'G major', rn:'I', root:'G', symbol:'Gmaj7', quality:'major7', func:'Tonic'}, // D major ii–V–I {key:'D major', rn:'ii', root:'E', symbol:'Em7', quality:'minor7', func:'Subdominant'}, {key:'D major', rn:'V', root:'A', symbol:'A7', quality:'dominant7', func:'Dominant'}, {key:'D major', rn:'I', root:'D', symbol:'Dmaj7', quality:'major7', func:'Tonic'}, // F major ii–V–I {key:'F major', rn:'ii', root:'G', symbol:'Gm7', quality:'minor7', func:'Subdominant'}, {key:'F major', rn:'V', root:'C', symbol:'C7', quality:'dominant7', func:'Dominant'}, {key:'F major', rn:'I', root:'F', symbol:'Fmaj7', quality:'major7', func:'Tonic'}, // Minor keys: Em (iiø–V–i) and Am (iiø–V–i) using functional jazz-ish analysis {key:'E minor', rn:'iiø', root:'F#',symbol:'F#m7b5',quality:'half-diminished7', func:'Subdominant'}, {key:'E minor', rn:'V', root:'B', symbol:'B7', quality:'dominant7', func:'Dominant'}, {key:'E minor', rn:'i', root:'E', symbol:'Em7', quality:'minor7', func:'Tonic'}, {key:'A minor', rn:'iiø', root:'B', symbol:'Bm7b5', quality:'half-diminished7', func:'Subdominant'}, {key:'A minor', rn:'V', root:'E', symbol:'E7', quality:'dominant7', func:'Dominant'}, {key:'A minor', rn:'i', root:'A', symbol:'Am7', quality:'minor7', func:'Tonic'} ] AS rows UNWIND rows AS r MATCH (k:Key {name:r.key}) MATCH (pc:PitchClass {name:r.root}) MATCH (q:ChordQuality {name:r.quality}) MATCH (f:HarmonicFunction {name:r.func}) MERGE (c:Chord {symbol:r.symbol}) ON CREATE SET c.root = r.root, c.quality = r.quality MERGE (c)-[:ROOT]->(pc) MERGE (c)-[:HAS_QUALITY]->(q) MERGE (c)-[:DIATONIC_TO]->(k) MERGE (c)-[:HAS_FUNCTION]->(f) WITH r, k, c MERGE (rn:RomanNumeral {id: r.key + ':' + r.rn}) ON CREATE SET rn.text = r.rn MERGE (rn)-[:ANALYZES]->(c) RETURN count(*) AS made } RETURN 'Seeded chords & roman numerals' AS status; // ===================== // 5) Progressions (ii–V–I) + order edges // ===================== UNWIND [ 'C major','G major','D major','F major','E minor','A minor' ] AS keyName MATCH (k:Key {name:keyName}) WITH k, CASE WHEN k.name ENDS WITH 'minor' THEN ['iiø','V','i'] ELSE ['ii','V','I'] END AS steps MATCH (rn1:RomanNumeral {id: k.name + ':' + steps[0]})-[:ANALYZES]->(c1:Chord) MATCH (rn2:RomanNumeral {id: k.name + ':' + steps[1]})-[:ANALYZES]->(c2:Chord) MATCH (rn3:RomanNumeral {id: k.name + ':' + steps[2]})-[:ANALYZES]->(c3:Chord) MERGE (p:Progression {id: k.name + ':ii-V-I'}) ON CREATE SET p.name = 'ii–V–I', p.inKey = k.name MERGE (p)-[:ORDERS {step:1}]->(c1) MERGE (p)-[:ORDERS {step:2}]->(c2) MERGE (p)-[:ORDERS {step:3}]->(c3); // ===================== // 6) Cadences (PAC linking V → I / i) // ===================== UNWIND [ 'C major','G major','D major','F major','E minor','A minor' ] AS keyName MATCH (k:Key {name:keyName}) WITH k, CASE WHEN k.name ENDS WITH 'minor' THEN 'i' ELSE 'I' END AS tonicRN MATCH (:RomanNumeral {id: k.name + ':V'})-[:ANALYZES]->(dom:Chord) MATCH (:RomanNumeral {id: k.name + ':' + tonicRN})-[:ANALYZES]->(ton:Chord) MERGE (cad:Cadence {name: k.name + ':PAC'}) ON CREATE SET cad.kind='PAC' MERGE (cad)-[:RESOLVES {type:'authentic'}]->(dom) MERGE (dom)-[:RESOLVES_TO]->(ton); // ===================== // 7) Convenience: circle-of-fifths neighbors for the included keys // ===================== UNWIND [ ['C major','G major'], ['G major','D major'], ['D major','A major'], ['F major','C major'] ] AS pair WITH pair MATCH (k1:Key {name:pair[0]}), (k2:Key {name:pair[1]}) MERGE (k1)-[:ADJACENT_ON_COF]->(k2); // Done RETURN 'OK' AS seeded;
What you can query immediately
-
All chords and their functions in a key:
MATCH (k:Key {name:'C major'})<-[:DIATONIC_TO]-(c:Chord)-[:HAS_FUNCTION]->(f) RETURN c.symbol AS chord, f.name AS function ORDER BY function, chord;
-
The ii–V–I progression (ordered) in each key:
MATCH (p:Progression {name:'ii–V–I'})- [o:ORDERS]->(c:Chord) RETURN p.inKey AS key, o.step AS step, c.symbol AS chord ORDER BY key, step;
-
Find perfect authentic cadences and their resolution targets:
MATCH (cad:Cadence {kind:'PAC'})-[:RESOLVES]->(:Chord)-[:ANALYZES]<-(:RomanNumeral {text:'V'}), (:RomanNumeral)-[:ANALYZES]->(ton:Chord)<-[:RESOLVES_TO]-(:Chord) RETURN cad.name AS cadence, ton.symbol AS final_tonic ORDER BY cadence;
Want CSVs instead?
If you prefer to bulk-load, use this schema for two CSVs:
nodes.csv
id,label,name,props_json
pc:C,PitchClass,C,"{}"
pc:G,PitchClass,G,"{}"
cq:dom7,ChordQuality,dominant7,"{""symbol"":""7""}"
fn:Dom,HarmonicFunction,Dominant,"{}"
key:Cmaj,Key,C major,"{""tonic"":""C"",""mode"":""Ionian""}"
ch:C7,Chord,C7,"{""root"":""C"",""quality"":""dominant7"",""symbol"":""C7""}"
rn:Cmaj:V,RomanNumeral,V,"{}"
prog:Cmaj:ii-V-I,Progression,ii–V–I,"{""inKey"":""C major""}"
cad:Cmaj:PAC,Cadence,C major:PAC,"{""kind"":""PAC""}"
rels.csv
start_id,rel_type,end_id,props_json
key:Cmaj,TONIC,pc:C,"{}"
ch:C7,ROOT,pc:C,"{}"
ch:C7,HAS_QUALITY,cq:dom7,"{}"
rn:Cmaj:V,ANALYZES,ch:C7,"{}"
prog:Cmaj:ii-V-I,ORDERS,ch:Dm7C,"{""step"":1}"
prog:Cmaj:ii-V-I,ORDERS,ch:G7C,"{""step"":2}"
prog:Cmaj:ii-V-I,ORDERS,ch:Cmaj7C,"{""step"":3}"
cad:Cmaj:PAC,RESOLVES,rn:Cmaj:V,"{""type"":""authentic""}"
If you’d like, I can generate full CSVs for all 12 major and 12 minor keys (ii–V–I / iiø–V–i, common borrowed chords, N6, It/Fr/Ger+6, secondary dominants, and a minimal set-theory layer) so you can LOAD CSV
straight into Neo4j — just say the word and tell me whether you prefer “one big CSV” or “separate per-entity CSVs.”
From <https://chatgpt.com/> ChatGPT 5
- Get link
- X
- Other Apps
Comments
Post a Comment