We can apply some complex constraint expressions directly to the score. However, a more general notion is to encapsulate a constraint expression into a compositional rule (implemented by a procedure) which then can be applied one or more times. Example: choral melody with simple voice leading rule. Example introduces the notion of a context: a voice leading rule makes a note and its previous note interdependend. declare local MIDI pitch domain reduction: only 'wite keys' (c major) proc {InCMajor MyNote} {List.forAll [1 3 6 8 10] list of 'black' pitch classes (c=0) proc {$ BlackKey} {FD.modI {MyNote getPitch($)} 12} \=: BlackKey end} end Determine the pitch of the first and last note of MyVoice proc {StartAndEndWithFundamental MyVoice} Notes = {MyVoice getItems($)} in {Notes.1 getPitch($)} = 60 {{List.last Notes} getPitch($)} = 60 end voice leading: only intervals up to a fifth, no pitch repetition proc {NoBigJump Pitch1 Pitch2} all intervals between minor second and fourth are allowed {FD.distance Pitch1 Pitch2 '>=:' 1} {FD.distance Pitch1 Pitch2 '=<:' 5} end in proc {ChoralMelody MyMelody} N = 9 in MyMelody = {Score.makeScore seq(items: {LUtils.collectN N fun {$} predetermined and constant note durations note(duration: 4 pitch: {FD.int 53#72} amplitude: 80) end} startTime: 0 timeUnit:beats(4)) unit} Apply compositional rules: rule on melody {StartAndEndWithFundamental MyMelody} rule on single notes {MyMelody forAll(test: isNote InCMajor)} rule on pitch pair {Pattern.for2Neighbours {MyMelody mapItems($ getPitch)} NoBigJump} end end SDistro.exploreOne simplifies definition of a CSP with a score a solution: the score distribution strategy is not part of the script but given to SDistro.exploreOne. {SDistro.exploreOne ChoralMelody unit(order:size value:random)} {OS.srand 11} the random seed can be set to 'select' a solution