| Safe Haskell | Safe-Inferred |
|---|---|
| Language | Haskell2010 |
Harmonic.Evaluation.Scoring.Progression
Description
Composable score of a ProgressionContext along four axes:
psRootMotion— per-edge root motion smoothness (Hindemith-derived)psVoiceLeading— cyclic voice-leading cost over the triad layerpsCadenceFav— Neo4j-backed cadence transition favourability (0.0 if computed offline; online callers override)psModeValidity— fraction of bars whose mode layer carries the expected 7-PC chroma (Phase 1 invariant guarantees walk-generated progressions score 1.0)
Each component lives in [0, 1] with higher = better. totalScore
combines components via a weighted sum; defaultWeights makes
cadence-favourability the dominant axis (the user's stated preference).
The normalisations applied to per-component raw measurements are
intentionally simple placeholders — to be refined from observed
distributions once multi-attempt generation is live (see the project's
data-driven tuning memory). The function signatures are stable; only the
internal transforms inside scoreRootMotion / scoreVoiceLeading /
scoreModeValidity are subject to retuning.
Synopsis
- data ProgressionScore = ProgressionScore {
- psRootMotion :: !Double
- psVoiceLeading :: !Double
- psCadenceFav :: !Double
- psModeValidity :: !Double
- data ProgressionScoreWeights = ProgressionScoreWeights {
- wRootMotion :: !Double
- wVoiceLeading :: !Double
- wCadenceFav :: !Double
- wModeValidity :: !Double
- defaultWeights :: ProgressionScoreWeights
- defaultWeightsOffline :: ProgressionScoreWeights
- scoreProgression :: ProgressionContext -> ProgressionScore
- totalScore :: ProgressionScoreWeights -> ProgressionScore -> Double
- type TransitionMap = Map Text [(Cadence, Double)]
- cadenceFavFromMap :: TransitionMap -> Progression -> Double
- scoreProgressionOnline :: Text -> ProgressionContext -> BoltActionT IO ProgressionScore
- computeCadenceFav :: Text -> Progression -> BoltActionT IO Double
Score record
data ProgressionScore Source #
Per-progression scoring breakdown. Each component is in [0, 1]; higher
is better.
Constructors
| ProgressionScore | |
Fields
| |
Instances
| Show ProgressionScore Source # | |
Defined in Harmonic.Evaluation.Scoring.Progression Methods showsPrec :: Int -> ProgressionScore -> ShowS # show :: ProgressionScore -> String # showList :: [ProgressionScore] -> ShowS # | |
| Eq ProgressionScore Source # | |
Defined in Harmonic.Evaluation.Scoring.Progression Methods (==) :: ProgressionScore -> ProgressionScore -> Bool # (/=) :: ProgressionScore -> ProgressionScore -> Bool # | |
data ProgressionScoreWeights Source #
Weights applied to each scoring axis in totalScore. Conventionally
sum to 1.0 so the resulting total stays in [0, 1].
Constructors
| ProgressionScoreWeights | |
Fields
| |
Instances
| Show ProgressionScoreWeights Source # | |
Defined in Harmonic.Evaluation.Scoring.Progression Methods showsPrec :: Int -> ProgressionScoreWeights -> ShowS # show :: ProgressionScoreWeights -> String # showList :: [ProgressionScoreWeights] -> ShowS # | |
| Eq ProgressionScoreWeights Source # | |
Defined in Harmonic.Evaluation.Scoring.Progression Methods (==) :: ProgressionScoreWeights -> ProgressionScoreWeights -> Bool # (/=) :: ProgressionScoreWeights -> ProgressionScoreWeights -> Bool # | |
Default weights
defaultWeights :: ProgressionScoreWeights Source #
Cadence-favourability dominant: 0.4 fav, 0.2 each on root motion,
voice leading, mode validity.
defaultWeightsOffline :: ProgressionScoreWeights Source #
Offline-mode weights — cadence favourability dropped, remaining three
renormalised to 1/3 each.
Scoring (offline)
scoreProgression :: ProgressionContext -> ProgressionScore Source #
Pure score: computes root-motion, voice-leading, and mode-validity
components. psCadenceFav is left at 0.0 — online callers override
this field after consulting the graph.
totalScore :: ProgressionScoreWeights -> ProgressionScore -> Double Source #
Weighted sum of components. Conventional weights sum to 1.0 → total
in [0, 1].
Cadence-favourability (online + pure helper)
type TransitionMap = Map Text [(Cadence, Double)] Source #
A pre-fetched, composer-blend-resolved map from source cadence (keyed by
its show representation) to its outgoing transitions. Each transition
carries the destination Cadence and the blended weight (output of
applyComposerBlend).
cadenceFavFromMap :: TransitionMap -> Progression -> Double Source #
Compute psCadenceFav from a pre-fetched transition map. Pure — no IO.
The progression is treated as a cyclic loop: edges are
(C₀ → C₁), …, (C_{N-2} → C_{N-1}), (C_{N-1} → C₀). Each edge is
scored by edgeScore (hybrid presence + share). The per-progression
score is the mean of per-edge scores — length-independent and in
[0, 1].
Matching by show (not Eq) matches the DB's identity convention
(MATCH (c:Cadence {show: $show}) at Query.hs:113-137). The DB-side
Cadence is reconstructed via constructCadence (movement, chord),
which may differ from a generated Cadences cadenceIntervals field;
the show instance projects to (movement, functionality) only.
scoreProgressionOnline Source #
Arguments
| :: Text | Seek string (composer blend; same format as |
| -> ProgressionContext | |
| -> BoltActionT IO ProgressionScore |
Online variant of scoreProgression. Pure components match the offline
version exactly; psCadenceFav is populated from Neo4j edge weights
under the composer blend parsed from the supplied seek string.
Runs inside 'Bolt.BoltActionT IO' so the caller controls connection lifecycle (typically a single shared pipe across a multi-attempt loop).
computeCadenceFav :: Text -> Progression -> BoltActionT IO Double Source #
Cyclic per-edge favourability mean, computed against Neo4j. Builds the
TransitionMap by fetching each unique source cadence's outgoing
transitions once, applying the composer blend, then delegating to the
pure cadenceFavFromMap.
Number of graph queries = number of distinct source-cadence show keys
in the progression (≤ N for an N-bar progression).