Contraint Solver as a Compositional Model

Experimental Studio

24 04 2018

-------------------------

Luc Döbereiner, David Pirrò, Daniele Pozzi



During his residency, Luc is writing a piece for cello and doublebass which will be premiered by Schallfeld at Villa Elizabeth, Berlin, on 29th May 2019. The piece is based on transitions between neighbouring harmonics and multiphonics, which articulate both the affordances offered by the bodies of acoustic intstruments and the constraints of the musicians's own bodies (fingering techniques etc.), as well as the intersections of such limitations. 


These transitions are formalised in the form of a constraint solver that, given a specific starting point (i.e. a given multiphonic on a specific position), finds all the possible solutions that satisfy the constraints in the chosen domain. It thus generates sequences of multiphonics / harmonics that can be played continously - at each position, two different multiphonics / harmonics can be played at the same time, on neighbouring strings.


So the constraint solver allows

  • to get to know all the possibilities of the instrument
  • to formalise transitions between all these possibilities

LD

I'm interested in having one thing played and one thing added on a neighbouring string. So I have always a continuous sound that has usually two things played at the same time. And then you take off the first thing, you add another thing and so on. That kind of continuous transition. So, let's say, you are in a certain place, you are playing a certain mulptiphonic. Which other multiphonics or other harmonics could you play that have certain harmonic relationships - either they share notes, or they have certain intervals in their relation - that can be played - which you can play at the same time ?


I wrote some things by hand, you know, just actually imagining where's the hand, and then thinking of all the harmonics in there. And that took me like 2 hours to write 4 notes. And that may not even have been the most interesting possibility. 

 

So I tried to think how could I do this search algorithm. For example, if you play an artificial harmonics, you have two fingers on one string, let's say your index and your ring finger. First of all, you can only go to neighbouring strings, you cannot jump. Also because of the bow, you cannot bow two distant strings at the same time. Then you could go with your middle finger in between on the same area in the neighbouring strings, but you can't go elsewhere. I like the crazy constraints of the body, somehow. It gives you something you could never come up with. And I also like it because the instrumentalists all the time think of this. Which fingering can I use, and so on. To have an algorithm, or a program, that can give them new things that they haven't thought about it's very nice, they discover the instrument in a new way. 

LD

The basic idea of a constraint solver is that you have a domain.

A constraint solver is basically a search algorithm, in essence. What you have is, you describe a problem not by describing and algorithm actually, or a recipe to solve it. But you describe the output that you want. You describe the properties of something, and you have a domain that can be infinite or finite of things or values, whatever. The algorithm finds solutions that fit your constraints. It tries to find basically combinations in this domain.

 

DP

But solutions are in general not unique, right? If you have three variables, for example, and you establish a constraint relationship between them, it is not necessary that you have one possible outcome.

 

LD

No, there can be any number of solutions, depends also on the type of system you have. Normally most systems are able to find all solutions. The system that I have, it's a quite simple and basic system, that is able to spit out the solution and asks for a continuation function - it's actually a bit like this wreck thing. You can call, you get the next solution. So the solutions are ordered in a certain way, it depends on the order of the domain and the way you index the domain. Basically what it does is a backtracking search. Let's say your domain is all the values from 1 to 10. And the domain is the same for all the variables. Then it assign a value from the domain to (it instantiates) the first variable. It checks wether this works, if it works it instantiates the next one. If that doesn't work, and if it doesn't work for all the possible values of the second variable, then it would go back to the first variable and assign it the next value from its domain.