This functor defines constraints on lists which help to express pattern in music. To combine multiple patterns to motifs see, e.g., Score.defSubscript, or the contribution Motifs.
Functor
Import
- FD
- FS
- Combinator
- Select(fd) at "x-ozlib://duchier/cp/Select.ozf"
- GUtils at "x-ozlib://anders/strasheela/source/GeneralUtils.ozf"
- LUtils at "x-ozlib://anders/strasheela/source/ListUtils.ozf"
- Score at "x-ozlib://anders/strasheela/source/ScoreCore.ozf"
Export
Define
proc{PlainPattern Xs Proc}
PlainPattern constraints Xs to a plain pattern (ie. no nesting or combination of patterns). The pattern is specified by the procedere Proc given to PlainPattern. Proc constraints a single pattern item and is called recursively. Proc expects two arguments: the current item and its predecessor in the list.
proc{PlainPattern2 Xs Proc}
PlainPattern2 constraints Xs to a plain pattern (ie. no nesting or combination of patterns) and is a variant of PlainPattern which adds additional control. The pattern is specified by the procedere Proc given to PlainPattern2. Proc constraints a single pattern item and is called recursively. Proc expects three arguments: the current item, a list with all previous pattern items in reverse order (last is first), the number of generations processed so far.
proc{Continuous Xs A}
Constrain all elements in Xs to fulfill the relation: Predecessor A X. For instance, if A is '>:' then the relation Predecessor >: X constraints all elements in Xs to decrease.
proc{AllEqual Xs}
Constrain all elements in the Xs to be equal.
proc{Increasing Xs}
Constrain all elements in Xs to be greater then their predecessor in Xs.
proc{Decreasing Xs}
Constrain all elements in Xs to be less then their predecessor in Xs.
proc{NoRepetition Xs}
Consecutive values in Xs are not equal.
proc{Arch Xs Args}
Constraints Xs to form an "arc", i.e. there is only a single change of direction.
Args:
'firstRel' (default '<:'): a relation atom ('<:', '=<:', '>:', '>=:')
'turningPointPos' (default mid): specifies at which position within Xs the arc changes direction, positive int or atom mid
proc{InInterval Xs Min Max}
Constraints all elements in Xs to fall in interval [Min, Max], including.
proc{Cycle Xs L}
Unifies every element in Xs with its Lth predecessor.
proc{Cycle2 Xs Ys}
Constrains all elements in the list Xs (FD variables) to form a cycle pattern of the (shorter) list Ys (FD variables). I.e. Xs enumerates the elementes of Ys in sequential order and loops back to the first element of Ys after the last element has been reached.
proc{Rotation Xs Ys}
Constrains all elements in the list Xs (FD variables) to form a rotation pattern of the (shorter) list Ys (FD variables).
?? unfinished doc: I probably should just do an example...
!! TODO: additional args/control, see CM
proc{Heap Xs Ys}
proc{Random Xs Ys}
Constraints the domain of each element in Xs to contain only the elements of Ys.
!! Only a random distribution enforces a random ordering here.
proc{Palindrome Xs Ys Elide}
Constrains all elements in the list Xs (FD variables) to form a palindrome pattern of the (shorter) list Ys (FD variables).
Elide (true | first | last | unit) allows to specify which elements in the pattern are not directly repeated when the pattern reverses direction.
?? unfinished doc: I probably should just do an example...
proc{Line Xs Ys}
Constrains all elements in the list Xs (FD variables) to form a line pattern of the (shorter) list Ys (FD variables). I.e. Xs enumerates the elements of Ys in sequential order and sticks on the last element once it has been reached.
proc{Accumulation Xs Ys}
proc{Intervals Xs Ys Offset}
Ys (a list of FD ints, implicitly declared) are the intervals between Xs (list of FD ints) plus an Offset (a FD int) in order to avoid negative intervals.
proc{AbsIntervals Xs Ys}
Ys (a list of FD ints, implicitly declared) are the absolute intervals between Xs (list of FD ints).
proc{RestrictMaxInterval Xs MaxInterval}
Restricts the maximum absolute interval between Xs (list of FD ints) to MaxInterval (FD int).
proc{ArithmeticSeries Xs Difference}
Constrains all elements in the list/stream Xs (FD variables) to form an arithmetic series, with the difference Difference (a FD variable) between the series members.
proc{GeometricSeries Xs Quotient}
Constrains all elements in the list/stream Xs (FD variables) to form an geometric series, with the quotient Quotient (a FD variable) between the series members.
proc{Max Xs Y}
Y is constrained to be the maximum element in Xs. Xs is a list of FD integers and Y is (implicitely declared) a FD integer.
proc{Min Xs Y}
Y is constrained to be the minimum element in Xs. Xs is a list of FD integers and Y is (implicitely declared) a FD integer.
fun{DxsToXs Dxs Start}
Expects a list of integers considered as distances and returns a list of integers beginning with Start where the given distances apply.
NB: no constraint, integers can be negative.
fun{XsToDxs Xs}
Expects a list of integers and returns the distances between them, also a list of integers.
NB: no constraint, integers can be negative.
proc{ArithmeticMean Xs EncodedMean Quotient}
Constrains EncodedMean/Quotient (two FD int) to be the arithmetic means of Xs (a list of FD ints). Encoding the means by the expression EncodedMean/Quotient allows to represent means which are ratios by FD ints. In the following example, the mean is constrained to 1.5
{ArithmeticMean Xs 15 10}
proc{Range Xs A Y}
Y (a FD int) is the distance between the maximum and the minimum value in Xs (a list of FD ints). A is a relation such as '=:' etc.
NB: this rule poses the Max and Min pattern on Xs.
proc{FirstToLastDistance Xs A Y}
Y (a FD int) is the distance between the first and the last value in Xs (a list of FD ints). A is a relation such as '=:' etc.
proc{WindowedPattern MyPattern Xs Yss Args}
[Higher-level pattern constraint] Applies the pattern constraint MyPattern to sublists of Xs (a list of FD ints). MyPattern is a binary procedure which expects a list of FD ints as first arg, and one or more single FD ints as remaining args (but see args patternArgs and includeIndex below). Yss is a list of list of FD ints, which are the accumulated "remaining args" of MyPattern. The strength of WindowedPattern lies in the fact that Yss can be further constrained!
Args:
'windowlength' (default 3): length of Xs sublists to which is MyPattern is applied. At the end, sublists can be shorter if minwindowlength < windowlength.
'minwindowlength' (default same as windowlength): minimum length of Xs sublists permitted. This setting is used as an abort condition. If the last sublist is shorter than minwindowlength, the pattern constraint application is skipped.
'windowoffset' (default same as windowlength): "offset" of Xs element positions between the first elements of consecutive sublists. windowoffset must be =< than windowlength, but > 0.
These arguments are integers (for a static setting), but windowlength and windowoffset can also be lists of integers. In the latter case, each integer is used for a single application of MyPattern. If the given list is too short to provide a value for each individual pattern constraint application, then the last value is simply used for the remaining calls as well. In any case, the given list must at least be of length 2 (otherwise it is a static setting, and no list is required).
'patternArgs' (default false): If this argument is *not* false, then MyPattern is a ternary procedure which expects a single value or a record of further args as third argument. Like for windowlength and windowoffset patternArgs, patternArgs supports a static setting (a single value, must not be a list) or a dynamic setting (a list of values). Note that static arguments can also be provided directly to the definition of MyPattern.
'includeIndex' (default false): if true, then MyPattern is a ternary procedure which expects the accumulated number of recursive calls so far of as third argument. Only one of the arguments patternArgs and includeIndex must be non-false.
Example:
{WindowedPattern proc {$ Xs Y} {Pattern.max Xs Y} end
Xs [Ys]
unit(windowlength:2
windowoffset:2)}
Results in the following constraint applications
{Pattern.max {List.take Xs 2} {Nth Ys 1}}
{Pattern.max {List.take {List.drop Xs 2} 2} {Nth Ys 2}}
...
See the test file for a few full examples.
fun{WindowedPatternRecursions N Args}
[Aux for WindowedPattern] Returns the number of recursive constraint applications caused by WindowedPattern. WindowedPatternRecursions is useful, for example, to obtain the length of lists of FD ints given in Yss to WindowedPattern.
N is length of Xs given to WindowedPattern, Args is args given to WindowedPattern.
proc{UseMotifs Xs Motifs Args}
[Higher-level pattern constraint] UseMotifs constrains the list Xs to consist of "motif instances" declared in the list Motifs, a list of motif specs. More specifically, UseMotifs constrains that Xs is quasi the result appending declared motifs in any order and possibly with repetitions. However, UseMotifs is a constraint (e.g., the resulting order of motif instances can depend on other constraints).
Xs can be a list of FD ints. In this case, Motifs must be a list of list of FD its. Elements in Motifs can differ in length. For example, Xs can be the list of note pitches of a voice and Motifs defines possible "pitch motifs". Alternatively, Xs can be the list of intervals between note pitches and Motifs defines "interval motifs" which are transposable. Or Xs is a list of duration factors instead of durations and Motifs defines "duration factor motifs" which can be "stretched".
However, Xs is not limited to a list of FD ints, a list of other values is possible as well. For example, elements in Xs can be pairs of Pitch#Duration. In this case, an element in Motifs would also be a list of FD integer pairs. Although the motifs can differ in length, all elements of Xs and all elements of each motif must be equally nested and only differ in constrained variables so that they can be unified.
A motif spec can contain elements which should be ignored (i.e. don't result in any constraints). These elements are marked with '_'.
UseMotifs expects the following optional arguments
'workOutEven': If 'workOutEven' is false (the default), then the end of Xs may only contain the beginning of a Motifs element. By contrast, Xs contains only full elements of Motifs if 'workOutEven' is true.
'indices': an optional return value, a list of FD ints. For each element in Xs, indices contains an FD int which specifies to which motif index (e.g. position of its motif in Motifs) the Xs element belongs. These variables can be used, for example, to constrain that certain motifs should follow each other or to constrain how often some motif occurs.
Note that the argument 'indices' is particular important in case the elements in Motifs do include each other, that is some element in Motifs is fully contained as the beginning in another element of Motifs. For example, if Motifs contains [1 2] and also [1 2 2]. In this case, UseMotif would block internally as it could not decide for any motif and would not apply motif constraints anymore. This behaviour is avoided when the variables at the argument 'indices' are distributed (e.g., add a parameter to the notes to which the parameter values in Xs belong).
Note that this constraint processes the elements of Xs "from left to right". Constraining the next motif is always delayed until the previous motif is known, because it depends on the length of the previous motif where the next motif starts. Consequently, the distribution strategy should determine variables in that order.
fun{MakeIndexConstructor Constructor IndexParamNames}
[aux for UseMotifs] Returns a score item constructor (i.e. returns a function that returns score items) with added parameters for pattern motif indices. Constructor is the score item constructor to specialise (a unary function or class, e.g. HS.note). IndexParamNames is a list of atoms used to mark the added parameters (in an info tag motifIndex(IndexParamName) of these parameters).
The added parameters are created implicitly and not supported by the textual representation (i.e. the method toInitRecord leaves them out as well), but accessible with the function GetMotifIndex (see below) or the method getParameters (which returns a list of all parameter objects).
Important: for efficiency, the distribution strategy should visit early parameters with info tab 'motifIndex'. Constructors created by MakeIndexConstructor add this info tab to all index parameters.
NOTE: obsolete definition, use MotifIndexMixin instead.
fun{GetMotifIndex X IndexParamName}
[aux for UseMotifs] Expects X, a score item with added index variable(s) and returns the index variable value (FD int) associated with the name IndexParamName (an atom), in other words the number of the motif to which X belongs. For example, all notes that are part of an instance of the motif which has been declared first have the motif index value 1 and so forth.
NOTE: obsolete definition, use MotifIndexMixin instead.
MotifIndexMixin extends note classes with the parameter motifIndex, in other words the number of the pattern motif to which self belongs. For example, all notes that are part of an instance of the motif which has been declared first have the motif index value 1 and so forth.
NOTE: the pattern motif indices are not implicitly bound to the parameter motifIndex. This has to be done explicitly using the argument indices of UseMotifs. (This is done already by constructors such as Segs.makeCounterpoint_PatternMotifs).
NOTE: for efficiency, the distribution strategy should visit early parameters with info tab 'motifIndex'. Constructors created by MakeIndexConstructor add this info tab to all index parameters.
class MotifIndexMixin
feat !MotifIndexType
- initMotifIndexMixin(motifIndex:MI)
- getMotifIndex(X)
- getMotifIndexParameter(X)
end
fun{IsMotifIndexMixin X}
fun{MakeMotifIndexClass SuperClass}
[concrete class constructor] Expects a note class, and a class that is extended with an motif index parameter (see MotifIndexMixin).
MotifStartMixin extends note classes with the parameter motifStartB (0/1-int), which indicates whether a new pattern motifs starts with this note. This definition does not implicitly constraint the motifStartB parameter. Instead, this parameter should be constraint externally (e.g., by specifying {Segs.makeParametersAccessor {GUtils.toFun getMotifStart}} as an argument to motifAccessors of a counterpoint constructor defined in Segs).
class MotifStartMixin
feat !MotifStartType
- initMotifStartMixin(motifStartB:MS)
- getMotifStartB(X)
- getMotifStartBParameter(X)
end
fun{IsMotifStartMixin X}
fun{MakeMotifStartClass SuperClass}
[concrete class constructor] Expects a note class, and a class that is extended with an motifStartB parameter (see MotifStartMixin).
fun{GetMotifStartNotes Notes}
Expects a list of notes created with MakeMotifIndexNote_MotifStart. Returns a concurrent stream of the notes that are the first note of some motif.
Note: results must be processed concurrently to avoid blocking.
fun{GetMotifStartIndices Notes}
Expects a list of notes created with MakeMotifIndexNote_MotifStart. Returns a concurrent stream of the motif indices (motif types) from the first note of some motif. (E.g., can be used to apply a pattern constraint to motif indices)
Note: results must be processed concurrently to avoid blocking.
proc{MarkovChain Xs Decl}
Constraints Xs (a list of FD ints) to form an nth-order markov chain according to Decl. A Decl clause takes any number of predecessors into account and specifies a single successor. Decl is a list of list pairs in the form PredecessorSeq#PossibleSucessors
: after the occurance of PredecessorSeq in a sublist of Xs follows a value in PossibleSucessors. For example, the first order markov chain {MarkovChain Xs [[1]#[2 3] [2]#[1] [3]#[2]]}
causes any 1 in Xs to be followed by either 2 or 3 and any 2 by 1 etc.
The list in PredecessorSeq can be of any length to specify any markov chain order. However, in all clauses the length should be equal.
Additionally, the declaration can use the wildcard symbol 'x' which matches every FD int. For example, the clause [x 1]#[2]
states that 1 is followed by 2.
NB: The list of declarations in Decl specifies a number of disjunctions without any implicit 'otherwise' clause. An inappropriate Decl can cause no solution.
Markov chains of order N pose constraints only on sublists of length N: a clauses [x x 1]#[2]
does not simply constrain 1 to be followed by 2 but does constrain 1 with two predecessors be followed by 2. Workaround: append some aux FD ints in front of the list and remove them later again (this workaround is not automatically integrated in MarkovChain to avoid any undesired side effects -- its no foolproof trick and the user should thus be aware of it).
NB: MarkovChain only specifies that certain elements follow each other. In opposite to the [usual / common] definition of a markov chain, however, MarkovChain does NOT constrain the probability of certain successors.
proc{MarkovChain_1 Xs Decl}
Constraints Xs (a list of FD ints) to form a first order markov chain according to Decl. Decl is a record with only integers as features and lists of integers as fields. MarkovChain_1 poses the constraints that each element in Xs with the value of the Decl feature XVal is followed by an element whose value is one of the elements in the field of XVal.
For example, {MarkovChain_1 Xs unit(1:[2 3] 2:[1] 3:[2])}
causes any 1 in Xs to be followed by either 2 or 3 and any 2 by 1 etc.
NB: MarkovChain_1 only specifies that certain elements follow each other. In opposite to the [usual / common] definition of a markov chain, however, MarkovChain_1 does NOT constrain the probability of certain successors.
fun{MakeLSystem Axiom N Rules}
Returns a list of determined values sorted according to an L-system. Axiom is the first pattern period (a list) and N is the number of periods (an integer). N=0 results in the axiom. Rules is a unary function, whose argument is the last pattern value and which returns the next period (a list). Rules can be defined, e.g., by a case expression.
NB: MakeLSystem works best with determined values and is thus no constraint as many other definitions in this functor. Nevertheless, symbols of the L-system can be replaced by variables (e.g. using LUtils.replace). See ./testing/Pattern-test.oz for examples.
fun{MakeLSystem_B N Constants Axiom Rules}
This function is a variant of MakeLSystem which is more convenient to use. It also returns a list of determined values sorted according to an L-system. As in MakeLSystem, N is the number of periods (an integer) and Axiom is the first pattern period (a list). Constants is a list of symbols which always remain fixed (a list of atoms). In contrast to MakeLSystem, Rules is a record which defines a mapping how a symbol is replaced in the following generation. The features in the record denote the L-system symbols for each mapping. The values at these features are typically unary functions. The function returns a list with the symbols of the next generation. For example, the Algae example (example 1 at http://en.wikipedia.org/wiki/Lindenmayer_system) is defined as follows.
{MakeLSystem_B 5 nil [a] unit(a: fun {$ _} [a b] end
b: fun {$ _} [a] end)}
The function expects the symbol it replaces as argument. This can be used, for example to hand over symbol arguments in parameterised L-systems. In case this function argument is not required, it is possibly for convenience to replace the function by its return value. The next example demonstrates a simple parameterised L-system.
{MakeLSystem_B 5 nil [a(1)] unit(a: fun {$ a(I)} [a(I+1) b] end
b: [a(1)])}
fun{MakeLSystem2 Start N Rules}
Returns a list of determined values sorted according to an L-system. Similar to MakeLSystem, however MakeLSystem2 allows the definition of context sensitive L-systems, systems which look not only at single values, but also at predecessors and/or successors (in the former period/generation). Rules is function of three arguments: the whole pattern so far in reverse order (i.e. a list with the direct predecessor first), the current value and the succeeding values (a list). The first argument is nil in the very first iteration. The third arg of Rules is list with successors of X in proceeding generation (normal order) excluding later generations. This arg is nil at any end of a period. Rules may, e.g., define an if or a case statement and can freely access all its arguments (e.g. to define the current element is x and the butfirst is y).
NB: MakeLSystem works best with determined values and is no constraint as most other definitions in this functor. Nevertheless, symbols of the L-system can be replaced by variables (e.g. using LUtils.replace). See ./testing/Pattern-test.oz for examples.
fun{LSystemConstsToParams Xs Vars}
[Convenience for L-systems] Transform the result of an L-system (Xs, a list of atoms or records) which contain constants into a result with parameters. Put differently, collects the constant symbols (atoms) as parameters into their preceeding L-system variable symbol (atom or record). The resulting parameterised L-system variables are records whose features are the constants following them before the next L-system variable. The feature values specify how often this constant occured before the next non-constant. The L-system variable labels are specified in Vars (a list of atoms), everything else is considered a constant.
Note that this function requires that the first element is always an L-system variable.
proc{OneOverFNoise Xs}
Constraints a list of FD integers to random values according to 1/f noise (i.e. x_n = (x_{n-1} + x_{n-1}^2) mod 1). All Xs are in the domain 0#Max.
This constraint is quasi deterministic -- determining a single variable determines the whole list only by constraint propagation.
!! Currently, Max is fixed to 100
proc{OneOverFNoiseDeterm L Start Xs}
Returns a list of determistically created floats according to 1/f noise (i.e. x_n = (x_{n-1} + x_{n-1}^2) mod 1). L is the length of the list and Start is the first list value.
spectrum: 1/f noise falls -3dB per octave.
fun{MapTail Xs Fn}
Collects the results of applying the unary function Fn (expecting a list) to Xs and recursively to the tail of each list Fn was applied to.
For instance, {MapTail [1 2 3 4] fun {$ Xs} Xs end}
returns [[1 2 3 4] [2 3 4] [3 4] [4]]
.
fun{MapTailInd Xs Fn}
Similar to MapTail, but Fn is a binary function expecting the index as first argument.
fun{MapTailN Xs N Fn}
Similar to MapTailInt, but Fn is only applied to the first N lists.
In case N > {Length Xs}, an exception is raised.
proc{ForTail Xs P}
Applies the unary procedure P (expecting a list) to Xs and recursively to the tail of each list P was applied to.
proc{ForTailInd Xs P}
Similar to ForTail, but P is a binary procedure expecting the index as first argument.
proc{ForTailN Xs N P}
Similar to ForTail, but P is only applied to the first N lists.
In case N > {Length Xs}, an exception is raised.
fun{MapNeighbours Xs N Fn}
Traverses through list Xs by mapping the unary function Fn (expecting a list) on each list of N (an int > 0) neighboring elements in Xs. The length of returned list is by N-1 shorter then Xs.
For instance, {MapNeighbours [1 2 3 4 5] 3 fun {$ Xs} Xs end}
returns [[1 2 3] [2 3 4] [3 4 5]]
.
NB: MapNeighbours returns nil for N > {Length Xs}
BTW: this pattern substitutes the most common pattern matching rule application mechanism of PWConstraints.
fun{MapNeighboursInd Xs N Fn}
Similar to MapNeighbours, but Fn is a binary function expecting the index as first argument.
proc{ForNeighbours Xs N P}
Similar to MapNeighbours, but P is a unary procedure applied to each list of N neighboring elements in Xs without a return value.
proc{ForNeighboursInd Xs N P}
Similar to ForNeighbours, but P is a binary procedure expecting the index as first argument.
fun{Map2Neighbours Xs Fn}
Traverses through Xs by mapping the binary function Fn on neighboring elements in Xs. The length of returned list is by one shorter then Xs.
proc{For2Neighbours Xs Proc}
Traverses through Xs by applying the binary procedure Proc on neighboring elements in Xs.
{For2Neighbours [1 2 3] P} -> {P 1 2} {P 2 3}
proc{ApplyToRange Xs Start#End P}
Applys P (a unary proc expecting a list) to the sublist of Xs (a list) that consists in the Start-th (and int) to the End-th (and int) elements (including).
proc{ForRanges Xs Ranges P}
Applies P (a unary proc expecting a list) to each sublist of Xs (a list) that is declared by a range in Ranges. Ranges is a list consisting in integers and/or pairs of the form Start#End (two integers).
fun{MapRanges Xs Ranges Fn}
Collects the results of applying Fn (a unary function expecting a list) to each sublist of Xs (a list) that is declared by a range in Ranges. Ranges is a list consisting in integers and/or pairs of the form Start#End (two integers).
proc{ParallelForAll Xss Proc}
Traverses all lists in Xss in parallel and sequentially applies the unary procedure Proc (which expects a list as arg) on all first list elements, all second list elements etc. All sublists in Xss must be of same length.
proc{ParallelMap Xss Fn Ys}
Traverses all lists in Xss in parallel and sequentially applies the unary function Fn (which expects a list as arg) on all first list elements, all second list elements etc. The results of Fn are bound sequentially to the elements in Ys. All sublists in Xss and Ys must be of same length.
proc{ForCartesianProduct Xs Ys P}
Applies the binary procedure P on all possible combinations of Xs and Ys. The order of applications is [{P X1 Y1} {P X1 Y2} ... {P X1 Yn} {P X2 Y1} ... {P Xn Yn}].
proc{MapCartesianProduct Xs Ys Fn Zs}
Collects in Zs the result of applying the binary function Fn on all possible combinations of Xs and Ys. The order in Zs is [{Fn X1 Y1} {Fn X1 Y2} ... {Fn X1 Yn} {Fn X2 Y1} ... {Fn Xn Yn}].
proc{ForCartesianProduct2 Xss P}
Collects the result of applying the unary procedure Fn (expecting a list) on all possible sublist combinations of Xss (a list of lists). ForCartesianProduct2 is a generalisation of ForCartesianProduct of a arbitrary number of lists to combine.
fun{MapCartesianProduct2 Xss Fn}
Collects the result of applying the unary function Fn (expecting a list) on all possible sublist combinations of Xss (a list of lists).
fun{Sublists Xs N}
Chop Xs into overlapping subsequences of length N. For example, {Sublists [a b c d] 2} results in [[a b] [b c] [c d]].
fun{AdjoinedSublists Xs N}
Chops Xs into non-overlapping subsequences of length N. For example, {AdjoinedSublists [a b c d e f] 2} results in [[a b] [c d] [e f]].
proc{ForPairwise Xs P}
Applies the binary procedure P on all pairwise combinations of Xs, i.e. {P Xs1 Xs2} .. {P Xs1 XsN} {P Xs2 Xs3} .. {P XsN-1 XsN}.
fun{MapPairwise Xs Fn}
Collects the result of applying the binary function Fn on all pairwise combinations of Xs, i.e. [{Fn Xs1 Xs2} .. {Fn Xs1 XsN} {Fn Xs2 Xs3} .. {Fn XsN-1 XsN}].
proc{ForSublists Xs P}
Applies P (a unary procedure expecting a list) to any sublist in Xs (i.e. any list of succeeding elements in Xs).
fun{MapSublists Xs Fn}
Applies Fn (a unary function expecting a list) to any sublist in Xs (i.e. any list of succeeding elements in Xs) and returns all collected results in a list.
fun{CollectPM Xs PatternExpr}
Implements a pattern matching language very similar to the pattern matching language of PMC from PWConstraints.
CollectPM returns in a list any list of elements from Xs (a list) which match the PatternExpr (a list of pattern symbols).
The pattern matching language of CollectPM introduces three symbols: '*' is a place-holder matching 0 or more elements, '?' is a place-holder matching exactly one element and 'x' represents a pattern matching 'variable' (see Anders PhD thesis: Sec on PMC in survey II). For example, the PatternExpr [? * x x] matches any pair of subsequent elements of Xs except for the first pair: {CollectPM [a b c d] [? * x x]} returns [[b c] [c d]].
proc{ForPM Xs PatternExpr P}
Applies P (a unary procedure expecting a list) on all lists of elements from Xs (a list) which match the pattern matching expression PatternExpr (a list of pattern symbols). See CollectPM for details.
fun{MapPM Xs PatternExpr Fn}
Applies Fn (a unary function expecting a list) on all lists of elements from Xs (a list) which match the pattern matching expression PatternExpr (a list of pattern symbols) and returns the results in a list. See CollectPM for details.
proc{Zip Xss Ys}
'Zips' the sublists of Xss together in Ys by sequentially alternating between the sublists in Xss. E.g. {Zip [[1 2 3] [10 12 14]]} returns [1 10 2 12 3 14].
NB: there is also List.zip which does something different.
proc{TransformDisj Xs Fns I Ys}
Ys is some transformation of Xs. Fns is a list of binary procedures (both arguments are lists) which represent possible transformations. I (an argument which may be interesting as an output) is an index into Fns, a decision for I is equivalent with a decision for a certain transformation function. The domain of I is implicitly constrained to 1#{Length Fns}.
The length of the two arguments of each Fn must correspond with the lengths of Xs and Ys for a success. A mismatch causes the respective Fn to be ruled out in the disjuction.
See also GUtils.applySelected.
proc{SelectList Xss I Ys}
Out of a list of lists of FD ints in Xss the Ith (a FD int) list Ys is selected (a list of FD ints). All lists in Xss and Ys must be of the same length.
proc{SelectMultiple Xs Is Ys}
Is (a list of FD ints) are the indices into Xs (a list of FD ints) at whose positions the values are Ys (a list of FD ints).
Is and Ys are of equal length, Xs will often be longer than Ys.
NB: Is are always increasing to reduce symmetries (i.e. multiple solutions with the same Xs).
BTW: usage example: constrain only specific elements in Xs (i.e. Ys) by a pattern and constrain also the position of the elements to select (e.g. see examples/increasingTendency.oz).
Or: constrain that at the Is values in Xs the direction changes (access predecessor and successor of each Y, e.g., by {Select.fd Xs I-1 Y}).
proc{ApplyToN Xs N P}
Applies P (a procedure expecting a list) to a sublist of N (an integer) elements out of Xs (a list of FD ints). Note that the sublist does not need to consist in neighbouring elements of Xs (but sublist elements are in the same order as in Xs).
NB: Is and Ys is not necessaily fully determined. However, not determining these values also avoids fully exploring multiple symmetric solutions (i.e. solutions with equal Xs).
fun{RotateList Xs I}
Rotates Xs (a list of arbitrary elements) I times: each time the first element of Xs is put at the end of Xs.
fun{RotateSublists Xs N I}
Expects a list Xs and returns a variant in which every Nth sublist is rotated. For example, if N=2 then every two elements are swapped. I specifies how far the rotation conducted. For example, if N=3 and I=1 then every sublist triple is rearranged such that the first in the triple becomes the last. If I=2 then this operation is done twice (in effect the last in the triple becomes the first).
proc{Average Xs Y}
Y (FD int, implicitly declared) is the average of Xs (list of FD ints).
proc{HowManyDistinct Xs N}
N elements in Xs are pairwise distinct. Xs is a list of FD integers, N is a FD integer.
proc{MinDistinct Xs N}
At least N elements in Xs are pairwise distinct. Xs is a list of FD integers, N is a FD integer.
proc{HowManyAs Xs Val A N}
N elements in Xs are 'as' Val, i.e. either equal, or greater etc. A states the relation of the N elements to Val (A is one of '=:', '>:', '>=:', '<:', '=<:', '\\=:').
Xs is a list of FD integers, Val and N are FD integers.
proc{HowMany X Xs N}
X {FD int} occures N (FD int) times in Xs (list of FD ints).
NB: weak propagation! In particular, there is NO propagation on X (except that it is explicitly limited to the union of all values in Xs).
proc{Once X Xs}
X {FD int} occures only once in Xs (list of FD ints).
NB: weak propagation! In particular, there is NO propagation on X (except that it is explicitly limited to the union of all values in Xs).
proc{ForN Xs Fn N}
Constraint Fn (a unary function returning an 0/1 int) holds for N elements in Xs. N is a FD integer.
proc{ForPercent Xs Fn Min Max}
Constraint Fn (a unary function returning an 0/1 int) holds for between Min and Max percent. Min and Max are (determined) integers.
proc{NDifferences Xs Ys N}
Xs and Ys are similar lists of the same length, but N elements differ. Xs and Ys are lists of FD integers, N is a FD integer.
proc{ForNEither Xs Fn1 Fn2 N}
N elements of Xs hold the constraint Fn1, the rest holds Fn2. Fn1 and Fn2 are unary functions returning an 0/1 int, N is a FD integer.
proc{AllTrue Bs}
Bs is a list of 0/1 integers (not implicitly declared). All elements in Bs are true (i.e. all elements are 1).
proc{AllTrueR Bs B}
Reified version of AllTrue.
proc{OneTrue Bs}
Bs is a list of 0/1 integers (not implicitly declared). Exactly on element in Bs is true (i.e. one element is 1 and the rest is 0).
proc{OneTrueR Bs B}
Reified version of OneTrue.
proc{SomeTrue Bs}
Bs is a list of 0/1 integers (not implicitly declared). At least one element in Bs is true (one element certainly is 1, the rest can be 0 or 1).
proc{SomeTrueR Bs B}
Reified version of SomeTrue.
proc{HowManyTrue Bs N}
Bs is a list of 0/1 integers (not implicitly declared) and N is a FD int (implicitly declared): N elements in Bs are true (i.e. 1).
proc{HowManyTrueR Bs N B}
Reified version of HowManyTrue.
proc{FirstNTrue Bs N}
The first N (a FD int) elements in Bs (a list of 0/1-ints) are true (i.e. 1).
In other words, N is the position of the first element in Bs that is 0. If there is no 0 in Bs, then N = {Length Bs}.
(In principle, elements of Bs can be larger than 1, larger values still count as true.)
proc{PercentTrue Bs Percent}
Bs is a list of 0/1 integers (not implicitly declared) and Percent is a FD int (implicitly declared): Percent % elements in Bs are true (i.e. 1).
NOTE: Percent is rounded to integer value -- complementary percent values don't necessarily sum up to exactly 100 (e.g., 1/3 corresponds to 33 percent and 2/3 to 66 percent). Also, there is only a single solution for Percent for a specific determined list Bs (e.g., Bs = [1 1 0] <-> Percent = 66; Percent = 65 causes fail in this case).
Summary: PercentTrue is highly restricted for defining soft of probabilistic CSPs -- I would need true soft multiplication and division propagators instead.
proc{PercentTrue_Range Bs MinPercent MaxPercent}
Like PercentTrue, but a range is specified: the percentage of true values in Bs is between MinPercent and MaxPercent (both FD ints, not implicitly declared).
If MinPercent or MaxPercent are undetermined in the CSP, they might be undetermined in the solution too.
proc{PercentEqual_Range Xs Ys Min Max}
Constrains the percentage how many corresponding elements in Xs and Ys (lists of FD ints) are equal. The percentage is specifies by the range Min to Max (both FD ints, not implicitly declared).
proc{WhichTrue Bs I}
WhichTrue constraints the Ith element in Bs to be true. Bs is a list of 0/1 integers and I is a FD int. Only a single element of Bs is true (i.e. 1).
fun{SymbolToDirection Symbol}
Transforms one of the three direction symbols '-', '=' and '+' to the corresponding integer from 0, 1, or 2 representing a direction as used by constraints such as Direction and Contour.
fun{DirectionToSymbol Direction}
Transforms one of the integers 0, 1, and 2 representing a direction to the corresponding symbol from '-', '=' and '+'.
proc{Direction X1 X2 Dir}
Dir is constrained to the direction of the interval between X1 and X2. An interval 'upwards' (the predecessor is smaller than the successor) is represented by 2, an 'horizontal' interval (the predecessor and the successor are equal) is represented by 1, and an interval 'downwards' by 0.
X1, X2, and Dir are all FD integers, Dir is implicitly declared.
proc{DirectionR X1 X2 Dir B}
DirectionR is the reified version of Direction. B=1 <-> 'Dir represents the direction between X1 and X2'. An interval 'upwards' (the predecessor is smaller than the successor) is represented by 2, an 'horizontal' interval (the predecessor and the successor are equal) is represented by 1, and an interval 'downwards' by 0.
X1, X2, Dir and B are all FD integers. Dir is explicitly constrained to be in 0#2 and B in 0#1.
proc{Contour Xs Dirs}
Dirs is constrained to the contour of Xs: each element in Dirs represents the direction of an interval between two neighbouring elements in Xs. An interval 'upwards' (the predecessor is smaller than the successor) is represented by 2, an 'horizontal' interval (the predecessor and the successor are equal) is represented by 1, and an interval 'downwards' by 0.
Xs and Dirs are both lists of FD integers. The list Xs is one element longer than the list Dirs.
proc{InverseContour Xs Ys}
Xs and Ys are both contours of equal length (i.e. both lists of FD ints with domain 0#2). Ys is the inversion of Xs (and vice versa).
proc{ContourMatrix Xs Dirs}
ContourMatrix is a constraint similar in concept to Contour, but is more precise (and computationally more expensive). Dirs (FD list, implicitly created) is constrained to the contour matrix of Xs (FD list), unfolded into a list. Each element in Dirs represents the direction of an interval between two elements in Xs, i.e. {Direction {Nth Xs Pos_I} {Nth Xs Pos_J}}. Dir collects the results of Pos_I#Pos_J in the order [1#2 1#3 .. 1#N 2#3 .. 2#N .. N-1#N].
In Dirs, an interval 'upwards' is represented by 2, an 'horizontal' interval is represented by 1, and an interval 'downwards' by 0.
?? This concept stems from [R. Morris, 1987].
proc{DirectionOfContour Xs Dir Min}
Pattern that constraints contour of Xs, e.g., to be primarily ascending or descending. DirectionOfContour constrains that the minimum number of occurances of directions Dir (FD in 0#2) between elements in Xs (list of FD) is Min (FD int), measured in percent. For example, {DirectionOfContour Xs {SymbolToDirection '+'} 75} constrains that at least 75 percent of the intervals between elements in Xs are ascending.
proc{Undulating Xs Args}
Restricts the occurances of "changes of direction" (local min/max) in Xs.
Args:
min (default 3): minimal number of elements in X without a direction change (i.e. change of direction occurs at position min+1 the earliest).
max (default false): maximal number of elements in X without a direction change (ignored if false).
Note: if a local max/min is repeated, then this does not count as a change of direction!
proc{Hook Xs Args}
Contour constraint where all intervals go in the same directions except one. The interval which goes in the opposite direction always either goes up or down (no repetition).
Args
'oppositePos' (default last): position of the interval which goes in opposite direction (integer or 'last')
'oppositeDir': direction of the interval which goes in opposite direction (FD int).
'repetition' (default false): Boolean specifying whether there can be repetitions among the "other" intervals.
Naming: value sequence forms a "hook" if oppositePos is last or 1.
proc{Stairs Xs Args}
Pattern where segments of Args.n elements in Xs (FD ints) follow continuous relation As.rel. For n=2, the result is similar to a common pitch sequence for Organ pedal.
Args
'n' (default 2):
'rel' (default '<:'):
Note: presently only works if length of Xs is multiple of Args.n.
proc{DirectionChangeR X Y Z B}
Returns 0/1-int in B whether Y is either the maximum or the minimum in [X, Y, Z]. X, Y, Z and B are FD integers. Y must either be greater or smaller than both X and Z (i.e. the values 1 1 2 represent not a direction change).
proc{LocalMaxR X Y Z B}
Variant of DirectionChangeR that addresses repetitions. Like DirectionChangeR, DirectionChange2R returns a 0/1-int in B whether Y is either the maximum or the minimum in [X, Y, Z]. X, Y, Z and B are FD integers. However, DirectionChange2R is defined such that X and Y might be equal values, but Y and Z must not be equal. For example, the values 1 1 2 do represent a direction change.
So, if DirectionChange2R is used to identify direction changes in a longer list then the last element of a repeated local max/min is considered a direction change. However, also if there is no actual direction change, but at least one repeated value then the last is considered the direction change.
*/
proc {DirectionChange2R X Y Z ?B}
{FD.disj
{FD.conj (X =<: Y) (Y >: Z)}
{FD.conj (X >=: Y) (Y <: Z)}
B}
end
/** %% Returns 0/1-int in B whether Y is the maximum in [X, Y, Z]. X, Y, Z and B are FD integers.
proc{LocalMinR X Y Z B}
Returns 0/1-int in B whether Y is the minimum in [X, Y, Z]. X, Y, Z and B are FD integers.
fun{GetLocalMax Xs}
Returns the local maxima in Xs (list of FD ints). The result is again a list of FD ints, shorter than Xs.
NB: repeated local max are ignored completely (see Pattern.directionChangeR), and so are the first and last element in Xs.
fun{GetLocalMin Xs}
Returns the local minima in Xs (list of FD ints). The result is again a list of FD ints, shorter than Xs.
NB: repeated local min are ignored completely (see Pattern.directionChangeR), and so are the first and last element in Xs.
proc{ConstrainLocalMax Xs P}
Apply the pattern constraint P (a unary proc expecting a stream of FD ints) to the local maxima in Xs.
NOTE: This constraint can be expensive, because the constraint application is delayed until the local max are known. Also, note that elements in Xs are processed in their order. Predetermining which elements are local max improves efficiency (e.g., with a contour constraint). Moreover, P should be able to concurrently process a stream (instead of a list only).
proc{ConstrainLocalMin Xs P}
Same as ConstrainLocalMax for local minima.
proc{FdInts Xs Mins Maxs}
Constraints the domain bounderies of the elements in Xs (FD integers). Mins specifies the mininum and and Max the maximum domain value for each element in Xs.
proc{FdRanges Xs Mids Ranges}
Constraints the domain bounderies of the elements in Xs (FD integers). Mids specifies the middle domain value and Ranges the width between the minimum and maximum domain value for each element in Xs.
fun{MkUniqueSeq MaxN MaxDeviation}
Returns a unary procedure which constraints its argument (a list of FD ints). The returned procedure is applied to multiple FD integer lists; the procedure pairwise 'unifies' the FD integers of each list. MaxDeviation (an integer) determines how far each constrained interval may differ from its restriction.
This pattern can, e.g., be used to define a canon.
Please note: MkUniqueSeq must be called within the constraint script, otherwise the rule blocks.
fun{MkUniqueIntervalSeq MaxN MaxDeviation}
Returns a unary procedure which constraints its argument (a list of FD ints). The returned procedure is applied to multiple FD integer lists; the procedure 'unifies' the interval sequence between the FD integers of each list. MaxDeviation (an integer) determines how far each constrained interval may differ from its restriction.
This pattern can, e.g., be used to define a canon with a free transposition.
Please note: MkUniquePitchSeqFn must be called within the constraint script, otherwise the rule blocks.
proc{ConjAll Xs B}
B is constrained to 1 in case the sum of all elements in Xs equals the length of Xs and B is 0 otherwise. This is a shorthand for multiple nested FD.conj
!! All elements in Xs must be 0#1 integers (i.e. no more than 1), as this constraint computes simply the sum.
proc{DisjAll Xs B}
B is constrained to 1 in case the sum of all elements in Xs is >= 1 and B is 0 otherwise. This is a shorthand for multiple nested FD.disj.
proc{ZerosOnlyAtEnd Xs}
Constrains Xs (list of FD ints) such that any zeros only occur at the end of Xs.
Possible usage: when constraining the 'length' of a list, 'non existing' list elements are encoded by zeros. This constraint avoids symmeries in such a CSP: 'non-existing' list elements occur at the end of the list.
proc{RelevantLength Xs N}
Constrains N (a FD int, implicitly declared) to the position of the first occurence of a zero in Xs (list of FD ints).
Possible usage: when constraining the 'length' of a list, 'non existing' list elements are encoded by zeros. This constraint returns the effectiv length of the list.
This pattern rule implies the semantics of ZerosOnlyAtEnd.
proc{ForAllItems Items Meth}
Performs List.forAll on a list of items, but Meth can be a method or procedure.
fun{MapItems Items Meth}
Performs List.map on a list of items, but Meth can be a method or function.
proc{EqualizeParam Items1 Items2 Accessor}
Expects two lists of items (both of the same length) and an Accessor (unary function or method). The variables returned by the Accessor are constrained to be equal for Items at corresponding positions in the two lists. Example: items at corresponding positions in the two lists are constrained to start at the same time.
{EqualizeParam Items1 Items2 getStartTime}
proc{FenvBoundaries Xs FenvUpperDom FenvLowerDom}
Pattern constraint applicator for parameter of a list of Items (a list of Items). Accessor is a unary method or function, and MyPattern is a procedure expecting a list of FD ints.
Example:
{ForParams MyNotes getPitch Increasing}
*/
proc {ForParams Items Accessor MyPattern}
{ForParams2 Items Accessor MyPattern nil}
end
/** %% Like ParamPattern, but MyPattern can expect more arguments. More specifically, MyPattern is a procedure expecting a list of FD ints as first arguments and zero or more furher arguments. OtherPatternArgs is a list of additional arguments to MyPattern.
Example:
{ForParams2 MyNotes getPitch Continuous ['<:']}
*/
proc {ConstrainParams2 Items Accessor MyPattern OtherPatternArgs}
{Procedure.apply MyPattern
{MapItems Items Accessor} | OtherPatternArgs}
end
Using Fenvs
/** %% Restricts the upper and lower domain boundary of a list of FD ints (Xs) by two Fenvs. Each fenv is "sampled" where the number of samples is the lengt of Xs, and these samples are then used as domain boundaries.
Remember that fenv values are always floats, these are internally rounded to integers.
fun{FenvToContour MyFenv N}
Expects a fenv, and returns its contour with N (int) directions encoded as expected by Pattern.direction.
proc{FenvContour Xs MyFenv}
Constraints the contour of the elements in Xs (FD ints) to follow the contour of MyFenv (a fenv). Internally, Pattern.contour is used.
proc{FenvContour2 Xs MyFenv}
Variant of FenvContour: each interval either follows the direction of MyFenv -- or performs a repetition. For example, if for a certain interval the corresponding subsection of MyFenv ascends then the interval has either the direction '+' or '=' (expressed with the symbols supporterd by SymbolToDirection). Nevertheless, horizontal sections of MyFenv constrain interval directions to '=' only.
proc{ApproximateContour Dirs1 Dirs2 MinPercentError MaxErrorPercent}
Contour Dirs2 (List of FD ints) quasi paraphrases original contour Dirs1 (List of FD ints). In at maximum MaxErrorPercent (FD int) and at least MinPercentError (FD int) cases, an ascending or descending value of Dir1 can be a constant value in Dir2 while constant values can be ascending or descending. In other words the direction values are either the same or differ by one. Dirs1 and Dirs2 must be of same length.
proc{Approximate Xs Ys MinPercentError MaxErrorPercent}
Ys (List of FD ints) quasi paraphrases original Xs (List of FD ints). At maximum MaxErrorPercent (FD int) and at least MinPercentError (FD int) values of Ys can arbitrarily differ from Xs. Xs and Ys must be of same length.
End