theHarmonicAlgorithm-3.1.1: Real-time harmonic progression generation for TidalCycles live performance
Safe HaskellNone
LanguageGHC2021

Harmonic.Rules.Import.Graph

Description

Write operations for storing cadence nodes and transition edges during data ingestion, plus a re-export of connectNeo4j (the connection itself lives in Harmonic.Database).

Writes are BATCHED and PARAMETERISED: edges travel as a $rows JSON parameter into one UNWIND + MERGE statement per batch, so a full corpus write is a few hundred transactional round trips rather than one auto-committing request per edge, and no value is ever spliced into Cypher text.

Synopsis

Connection

connectNeo4j :: IO DbConn Source #

Connect to the local Neo4j from Harmonic.Config (override with the HA_NEO4J_URL environment variable, e.g. http://localhost:7477 to point a REPL at a scratch container). Probes the server with RETURN 1 so an unreachable database surfaces the error here, at connect time — matching what every online generation path expects.

Schema

initGraph :: DbActionT () Source #

Initialise schema: the uniqueness constraint on the show node key. Idempotent (IF NOT EXISTS) and non-destructive — it touches nothing else in the database. Node identity is the show string (movement + functionality); the functionality half of every key follows the naming contract documented at the head of Harmonic.Rules.Import.Transform.

truncateCadenceGraph :: DbActionT () Source #

Delete every Cadence node and its NEXT edges. Run before a re-ingestion. The cadence graph is small by construction (at most 55 zero-forms x 12 movements = 660 nodes), so a plain DETACH DELETE suffices — no batching machinery required.

Writing cadence transitions

type ComposerWeights = Map Text Double Source #

How much each composer contributes to one NEXT edge. Serialised to a JSON object string on the edge's weights property (sparse: absent composer = weight 0), and summed into a single confidence property.

writeCadenceEdges :: [(Cadence, Cadence, ComposerWeights)] -> DbActionT () Source #

Write cadence transitions in parameterised batches of 1000 rows. Each batch is one transactional UNWIND round trip; MERGE keeps every row idempotent, so a failed run can simply be re-run. Node properties are set only ON CREATE (they are pure functions of the node key, so re-setting them per edge would be redundant writes). Transitions with no composer weight are skipped rather than written with zero confidence.

edgeRow :: (Cadence, Cadence, ComposerWeights) -> Value Source #

One edge as a $rows element. Node fields are pure functions of the cadence (the show key, its movement and chord halves, and the dissonance level computed at write time so queries can filter on it). weights is the JSON object string the read side (parseWeightsJson) parses back; confidence is the sum of all composer weights (what a "*" query ranks on).

batchCypher :: Text Source #

The one write statement: unwind the batch, merge both endpoint nodes and the NEXT edge, stamp the edge's confidence and per-composer weights.

Writing jazz (Change) transitions

initChangeGraph :: DbActionT () Source #

Initialise the jazz-graph schema: uniqueness on the Change node key. Idempotent and label-scoped — resident Cadence data is untouched.

truncateChangeGraph :: DbActionT () Source #

Delete every Change node and its edges — and nothing else: the statement matches by label only, so the classical graph cannot be touched. The jazz graph is small (994 nodes / 9,235 edges from the full Bunks corpus), so a plain DETACH DELETE suffices.

writeChangeEdges :: [((JazzCadence, JazzCadence), ComposerWeights)] -> DbActionT () Source #

Write jazz transitions in parameterised batches of 1000 rows, the same idempotent UNWIND + MERGE shape as writeCadenceEdges.

changeEdgeRow :: ((JazzCadence, JazzCadence), ComposerWeights) -> Value Source #

One jazz edge as a $rows element. The show key comes from jazzShow (same ( movement -> functionality ) shape as the classical key); chord is the plain zero-form interval list (no legacy naming contract in the jazz keyspace); dissonance reuses the classical scorer, which is arity-agnostic.

changeBatchCypher :: Text Source #

The jazz write statement: identical shape to batchCypher with the Change label.