%% %% This defines a variant of ./KeepMusicRepresentationOutsideComputationalSpace.oz %% Probably this can be removed.. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Second CSP: two sequences of N notes (start/duration pairs). Both sequences start at the same time. All note start times (except the two first) are different. %% %% This very simple rhythmical problem is formulated three times, once with with a %% Strasheela score inside the script, once outside, and once with a plain list representation. The second %% is much faster (because copying is more cheap??) %% %% fun {MakeVoice N} {Score.makeScore2 seq(items: {LUtils.collectN N fun {$} note(duration: {FD.int 1#8} pitch: 60%{FD.int 60#72} amplitude: 80) end} info:voice) unit} end proc {ScriptWithScoreDataInside MyScore} N = 100 Voice1 Voice2 in Voice1 = {MakeVoice N} Voice2 = {MakeVoice N} MyScore = {Score.makeScore sim(items: [Voice1 Voice2] startTime: 0 timeUnit:beats(4)) unit} {FD.distinctB {Append {Voice1 mapItems($ getStartTime)}.2 {Voice2 mapItems($ getStartTime)}.2}} %% search strategy {FD.distribute {SDistro.makeFDDistribution unit(order:size value:min)} {LUtils.accum [{Voice1 mapItems($ getDurationParameter)} {Voice2 mapItems($ getDurationParameter)} {Voice1 mapItems($ getStartTimeParameter)} {Voice2 mapItems($ getStartTimeParameter)}] Append}} end /* {{Score.makeScore container(items: {LUtils.collectN 3 fun {$} element(addParameters:[{New Score.parameter init(info:startTime)} {New Score.parameter init(info:duration)}]) end}) unit(container:Score.container element:Score.element)} toInitRecord($)} */ /* %% unfinished declare fun {MakeVoice2 N} {Score.makeScore2 container(items: {LUtils.collectN N fun {$} element(addParameters:[{New Score.parameter init(value:{FD.int 1#FD.sup} info:startTime)} {New Score.parameter init(value:{FD.int 1#8} info:duration)}]) end} info:voice) unit(container:Score.container element:Score.element)} end fun {GetStartTimePar X} {LUtils.find {X getParameters($)} fun {$ Par} {Par hasThisInfo($ startTime)} end} end fun {GetDurationPar X} {LUtils.find {X getParameters($)} fun {$ Par} {Par hasThisInfo($ duration)} end} end fun {GetStartTime X} {{GetStartTimePar X} getValue($)} end fun {GetDuration X} {{GetDurationPar X} getValue($)} end proc {ConstraintTiming X Y} {GetStartTime X} + {GetDuration X} =: {GetStartTime Y} end proc {ScriptWithScoreDataInside2 MyScore} N = 100 Voice1 Voice2 in Voice1 = {MakeVoice2 N} Voice2 = {MakeVoice2 N} MyScore = {Score.makeScore container(items: [Voice1 Voice2]) unit(container:Score.container)} %% usually implicit timing constraints {Pattern.for2Neighbours {Voice1 getItems($)} ConstraintTiming} {Pattern.for2Neighbours {Voice2 getItems($)} ConstraintTiming} %% !! these constraints cause fail! {GetStartTime {Voice1 getItems($)}.1} = 0 {GetStartTime {Voice2 getItems($)}.1} = 0 %% actual constraint {FD.distinctB {Append {Voice1 mapItems($ GetStartTime)}.2 {Voice2 mapItems($ GetStartTime)}.2}} %% search strategy {FD.distribute {SDistro.makeFDDistribution unit(order:size value:min)} {LUtils.accum [{Voice1 mapItems($ GetDurationPar)} {Voice2 mapItems($ GetDurationPar)} {Voice1 mapItems($ GetStartTimePar)} {Voice2 mapItems($ GetStartTimePar)}] Append}} end */ declare proc {ConstrainStarts Starts Durs} for S1 in {LUtils.butLast Starts} S2 in Starts.2 D1 in {LUtils.butLast Durs} do S1 + D1 =: S2 end end proc {PlainScript Sol} N = 100 Durs1 = {FD.list N 1#8} Durs2 = {FD.list N 1#8} Starts1 = {FD.list N 0#FD.sup} Starts2 = {FD.list N 0#FD.sup} in Sol = {LUtils.matTrans [Durs1 Starts1]}#{LUtils.matTrans [Durs2 Starts2]} Starts1.1 = 0 Starts2.1 = 0 {ConstrainStarts Starts1 Durs1} {ConstrainStarts Starts2 Durs2} {FD.distinctB {Append Starts1.2 Starts2.2}} %% search strategy {FD.distribute ff {LUtils.accum [Durs1 Durs2 Starts1 Starts2] Append}} end /* %% time: 2.89 secs %% 1#stat(b:0 c:0 depth:1 f:0 s:1 start:201) %% ScriptWithScore heap: 3757k %% MakeVoice heap: 1870k {ExploreOne ScriptWithScoreDataInside} %% time: 3.14 %% 1#stat(b:0 c:0 depth:1 f:0 s:1 start:401) {ExploreOne ScriptWithScoreDataInside2} {ExploreOne ScriptWithScoreDataOutside} %% time: 500ms %% 1#stat(b:0 c:0 depth:1 f:0 s:1 start:201) %% PlainScript heap: 66k %% ConstrainStarts heap: 6560b {ExploreOne PlainScript} */ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /* %% testing the data structure declare VarPointers VarDecls VarTuple %% create a few var pointers for testing VarPointers = [{New VarPointer init(domain:fd initDomain:1#10)} {New VarPointer init(domain:fd initDomain:2#10)} {New VarPointer init(domain:fd initDomain:3#10)} {New VarPointer init(domain:fd initDomain:4#10)}] %% test type checking {IsVarPointer VarPointers.1} {IsVarPointer bla} %% Given a list of varpointers create corresponding variable declarations. As a side effect, this operation determines the indices of the varpointers. %% !! This operation should still be performed OUTSIDE the script, so the list of actually required variables can be reduced (e.g. the script may only constrain the note pitches and leave all other note parameters out..) VarDecls = {MakeVarDecls VarPointers} %% !! the variables are always created INSIDE the script VarTuple = {MakeVarTuple VarDecls} %% apply constraint to first two VarPointers: this is correctly reflected by vars i VarTuple {ApplyToVars proc {$ X Y} X <: Y end [{Nth VarPointers 2} {Nth VarPointers 1}] VarTuple} */ /* %% start profiler only here (check heap usage of these procs) declare SpaceWithVarPointers = {Space.new MyScriptWithVarPointers} SpaceWithScore = {Space.new MyScriptWithScore} proc {CloneSpaceWithVarPointers _} _ = {Space.clone SpaceWithVarPointers} end proc {CloneSpaceWithScore _} _ = {Space.clone SpaceWithScore} end proc {MakeMyScore _} _ = {Score.makeScore seq(items: {LUtils.collectN N fun {$} note(duration: 4 pitch: {FD.int 60#60+N1} amplitude: 80) end} startTime: 0 timeUnit:beats(4)) unit} end {For 1 100 1 CloneSpaceWithVarPointers} %% needs 224k {For 1 100 1 CloneSpaceWithScore} %% needs 256k {For 1 100 1 MakeMyScore} %% needs 8390k */ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Result: it seems that the idea to keep the data of the music representaiton outside of the script (i.e. space) does not make any significant difference to the memory needs %% %% astonishingly, creating the music representation needs much more memory than cloning the space with a CSP 'containing' the music representation. How clever is the cloning of the space done: does it only clone the variables of the problem, i.e. the constraint store, propagators etc.?? %% %% %% .. on 7 march 2006 I got a reply by R. Collet: Re: What is actually copied when a space is cloned? on a question about this.. %% %% %% I may communicate over space boundaries (via a port? See Text of Christina p. 40), but I can not communicate chunks (??) -- see email by R. Collet: Re: memoization + search script, 4. Mai 2006 12:53:05 MESZ %% I.e. I can wrap data into procedures?? %%