| Safe Haskell | Safe-Inferred |
|---|---|
| Language | Haskell2010 |
Harmonic.Evaluation.Database.Query
Description
This module implements the Evaluation (E) component of the Creative Systems Framework. It fetches transition probabilities from Neo4j and resolves composer-weighted scores for candidate cadences.
The database is treated as abstract/pitch-agnostic. Root notes and voicings are computed at runtime from user-defined starting conditions.
Synopsis
- type ComposerWeights = Map Text Double
- parseComposerWeights :: Text -> ComposerWeights
- normalizeWeights :: ComposerWeights -> ComposerWeights
- fetchTransitions :: Text -> BoltActionT IO [(Cadence, ComposerWeights)]
- resolveWeights :: ComposerWeights -> [(Cadence, ComposerWeights)] -> [(Cadence, Double)]
- applyComposerBlend :: ComposerWeights -> [(Cadence, ComposerWeights)] -> [(Cadence, Double)]
Composer Weight Parsing
type ComposerWeights = Map Text Double Source #
Map from composer name to weight (e.g., "bach" -> 0.7)
parseComposerWeights :: Text -> ComposerWeights Source #
Parse a composer selection string into normalized weights.
Composer names are matched case-insensitively against the corpus —
Bach, "bach", BACH, "bAcH" all collapse to the same key.
Names are lower-cased here at parse time; resolveWeights lowercases
corpus edge keys at lookup time so the match is robust regardless of
the case convention used during corpus ingestion.
Supported formats: "bach debussy" -> equal weights, normalized to sum 1.0 "Bach:30 Debussy:70" -> weighted, normalized; case-insensitive "bach:0.3, debussy:0.7" -> already normalized (or re-normalized if needed)
Examples: parseComposerWeights "bach debussy" == Map.fromList [("bach", 0.5), ("debussy", 0.5)] parseComposerWeights "Bach:30 DEBUSSY:70" == Map.fromList [("bach", 0.3), ("debussy", 0.7)]
normalizeWeights :: ComposerWeights -> ComposerWeights Source #
Normalize weights so they sum to 1.0
Graph Queries
fetchTransitions :: Text -> BoltActionT IO [(Cadence, ComposerWeights)] Source #
Fetch all outgoing transitions from a cadence node.
Returns: List of (Cadence, ComposerWeights) pairs for all [:NEXT] edges. The Cadence is reconstructed from Neo4j node properties (movement, chord).
Query: MATCH (c:Cadence {show: $show})-[r:NEXT]->(n:Cadence) RETURN n.movement, n.chord, r.weights
Weight Resolution
resolveWeights :: ComposerWeights -> [(Cadence, ComposerWeights)] -> [(Cadence, Double)] Source #
Resolve transition weights using the active composer blend.
For each candidate (Cadence, ComposerWeights), compute a single score by multiplying each composer's edge weight by the user's blend weight and summing.
Example: candidate weights: {"bach": 5, "debussy": 3} user blend: {"bach": 0.7, "debussy": 0.3} score = 5 * 0.7 + 3 * 0.3 = 4.4
applyComposerBlend :: ComposerWeights -> [(Cadence, ComposerWeights)] -> [(Cadence, Double)] Source #
Apply composer blend to filter transitions, keeping only those with score > 0