Hello,
I was looking for a nice python library for constraint programming. Unfortunately, the only one I could find was python-constraint which seemed quite nice and straightforward, but after using it for a while, I find it very limited.
So, as a first example, I tried solving the pretty classic musical CSP described at the Strasheela Examples page as the 'All Interval Series' which is taken from music serialism.
The problem states that we want to put a series of all different pitch classes on the chromatic scale, where each interval appears exactly once. We also take account for inversely equivalent intervals.
I used python-constraint in order to construct my CSP by using pure python syntax, and mingus to create a midi track and render it to .pdf, .png and .mid files.
Here's the code:
https://gist.github.com/mmxgn/5891884
Here's the output score with lilypond:
and the link to the midi file.
Σάββατο 29 Ιουνίου 2013
Κυριακή 28 Απριλίου 2013
Python generator awesomeness: SEND+MORE=MONEY
Hello,
One awesome thing with python is its "yield" keyword and the notion of generators. It can be applied in order to program in the functional and logic paradigms.
For example, let's take the following problem:
You have the expression:
So we have the variables S,E,N,D,M,O,R,Y.
With the domains:
A beautiful way to do this is with python generators. For example, this can be solved in a single python statement as such:
Of course the above is not really efficient. This gave me a runtime of 122s on my core 2 duo e8400.
What you can do to improve it a bit? Well, for starters, replace the domains ( i.e range(0,10) ) with two constants out of the loop, i.e. Dom1 = range(1,10) and Dom2=range(1,10) so that they are not computed at each iteration. Then, a solution is more probable to appear at a range of bigger integers (we want two 4-digit numbers added to give a 5-digit number) so we can reverse the way we search the domains. So let's replace the above with:
Can we do more (less)? Yes. If you watch carefully to the above snipplet, we test every possible assignment for a solution while we could reduce the search space by not testing values that could not appear in a solution in the first place. For example, when S gets a value of '3', E cannot appear with the same value in the solution. So, while we search for a solution we sould "propagate" the distinction constraint. Using the yield keyword we can write the above snipplet as:
One awesome thing with python is its "yield" keyword and the notion of generators. It can be applied in order to program in the functional and logic paradigms.
For example, let's take the following problem:
You have the expression:
SEND + MORE = MONEYwhere every letter corresponds to a distinct digit (0 to 9, except S and M that cannot be 0). Find the corresponding digits for each of the letters so that the above equation holds.
So we have the variables S,E,N,D,M,O,R,Y.
With the domains:
S,M = [1,..., 9]
E,N,D,O,R,Y = [0,...,9]And the constraints:
S,E,N,D,M,O,R,Y distinct.
SEND + MORE = MONEY
A beautiful way to do this is with python generators. For example, this can be solved in a single python statement as such:
Just like that. You can get a single solution to this problem to SingleSolution with:solutionGen = (\(s,e,n,d,m,o,r,y)\for s in range(1,10)\for m in range(1,10)\for e in range(0,10)\for n in range(0,10)\for d in range(0,10)\for o in range(0,10)\for r in range(0,10)\for y in range(0,10)\if len(set([s,e,n,d,m,o,r,y])) != len([s,e,n,d,m,o,r,y]) and\s*1000 + e*100 + n*10 + d +\m*1000 + o*100 + r+10 + e ==\m*10000 + o+1000 + n*100 + e*10 + y)
SingleSolution = solution.next()Or every possible solution in a list with:
Solutions = [i for i in solution]Magic.
Of course the above is not really efficient. This gave me a runtime of 122s on my core 2 duo e8400.
What you can do to improve it a bit? Well, for starters, replace the domains ( i.e range(0,10) ) with two constants out of the loop, i.e. Dom1 = range(1,10) and Dom2=range(1,10) so that they are not computed at each iteration. Then, a solution is more probable to appear at a range of bigger integers (we want two 4-digit numbers added to give a 5-digit number) so we can reverse the way we search the domains. So let's replace the above with:
This, will give me a runtime of 16s.Dom1 = range(9,0,-1)Dom2 = range(9,-1,-1)
Can we do more (less)? Yes. If you watch carefully to the above snipplet, we test every possible assignment for a solution while we could reduce the search space by not testing values that could not appear in a solution in the first place. For example, when S gets a value of '3', E cannot appear with the same value in the solution. So, while we search for a solution we sould "propagate" the distinction constraint. Using the yield keyword we can write the above snipplet as:
def solution():Dom1 = range(9,0,-1)Dom2 = range(9,-1,-1)for s in Dom1:for m in Dom1:if m == s:continuefor e in Dom2:if e in [s,m]:continuefor n in Dom2:if n in [s,m,e]:continuefor d in Dom2:if d in [s,m,e,n]:continuefor o in Dom2:if o in [s,m,e,n,d]:continuefor r in Dom2:if r in [s,m,e,n,d,o]:continuefor y in Dom2:if y in [s,m,e,n,d,o,r]:continueif C2(s,e,n,d,m,o,r,y):yield (s,e,n,d,m,o,r,y)
Which gave me a runtime of 0.56s.
Not bad.
Πέμπτη 11 Απριλίου 2013
9 months of Army Service
On 9th of April, I finally completed my 9 month mandatory Service to the Greek Army Armed Forces. It actually seemed like a century of service.
I served:
I served:
- One month of training at the Engineering Corps training camp in Nafplio. First Batallion Third Company.
- Three months at the Hellenic Presidential Guard Company of Administration.
- Five months at the Hellenic Army General Staff Batallion as a soldier of the Honor Guard.
So, now it is over. Time to pick up where I left off: http://9gag.com/gag/7044336.
See you around.
Πέμπτη 31 Μαΐου 2012
PCL&RCL Oz code
Hello,
Just a small update.
Code for my PCL (Propositional Clausal Logic) and RCL (Relational Clausal Logic) theorem prover and model searcher can be found at my github:
git://github.com/mmxgn/generic-logic.git
I was hoping to finish it before giving the link, but I am going to give it anyway.
I hope the usage becomes obvious at the last lines of logic2.oz.
There are some personal life issues that will forbid me to work on it for a long time.
Just a small update.
Code for my PCL (Propositional Clausal Logic) and RCL (Relational Clausal Logic) theorem prover and model searcher can be found at my github:
git://github.com/mmxgn/generic-logic.git
I was hoping to finish it before giving the link, but I am going to give it anyway.
I hope the usage becomes obvious at the last lines of logic2.oz.
There are some personal life issues that will forbid me to work on it for a long time.
Πέμπτη 3 Μαΐου 2012
Propositional Clausal Logic in Oz
Okay,
Just a little update. I wanted to see how one could implement a model searcher/theorem prover in Oz. I found some very useful presentation slides for Declarative Programming by Coen De Roover at:
Just a little update. I wanted to see how one could implement a model searcher/theorem prover in Oz. I found some very useful presentation slides for Declarative Programming by Coen De Roover at:
http://prog.vub.ac.be/~cderoove/declarative_programming/Which I use as a guide for what I am trying to accomplish. Up to now, I have managed to create a PCL model searcher that can do proof by refutation using resolution. Here is some spoiler code:
% Set up a new Propositional Clausal Logic Knowledge base
PCLKB = {New KnowledgeBase init(PCL)}
% Assert some facts in it.
{List.forAll
[
[happy ':-' has_friends]
[friendly ':-' happy]
[wet ':-' rains]
[':-' wet]
]
proc {$ I}
{PCLKB assert(I)}
end
}
% Prove takes place with resolution by refutation
{List.forAll
[
[friendly ':-' has_friends]
[friendly]
[':-' rains]
]
proc {$ I}
{Browse prove(I)}
{Browse
{PCLKB prove(I $)}
}
end
}
and the necessary browser output:
prove([friendly ':-' has_friends])For the moment, I will move to relational clausal logic so I am not going to bother with fixing up and releasing the code, unless someone asks for it of course.
true
prove([friendly])
false
prove([':-' rains])
true
Τρίτη 1 Μαΐου 2012
Set of Subsets in Oz and other stuff
Hello,
I think it is time to start posting to this blog again. I will try and keep it updated with things that have more or less bothered me and other people will more likely find them in their way. These posts will mainly concern Oz and its implementation Mozart, stuff in Inductive Logic Programming, and things about Digital Music .
Generally, what are some interesting things I have been up to these last months:
i.e if we feed the following:
P.S. Is there a way to easily embed code to blogspot posts?
Edit: I just wrote a dummy Propositional Clausal Logic (PCL) model searcher in Oz. I will return to this once it's in a usable form.
I think it is time to start posting to this blog again. I will try and keep it updated with things that have more or less bothered me and other people will more likely find them in their way. These posts will mainly concern Oz and its implementation Mozart, stuff in Inductive Logic Programming, and things about Digital Music .
Generally, what are some interesting things I have been up to these last months:
- Re-factoring the code I have published with my Diploma Thesis. I am planning to re-create it at last as a pure Oz/Strasheela implementation (I have done some progress on that).
- Functional AUdio STream: Faust is a functional programming language that allows rapid development of efficient digital music instruments in C++. It allows easy implementation of VST technology instruments and effects, as well as PureData, etc.
- Fun with wavelets and music.
I am also searching for postgraduate studies in the fields of digital music/music technology.
I will generally update my blog mainly with progress on the above.
I will generally update my blog mainly with progress on the above.
To begin, I have come to the following problem in Oz:
Given a list of distinct elements L, give me a list that contains all the possible sub-lists with distinct elements of L.This could be helpful, for example if you want to, given a set S, to construct the powerset of S.
So, I have come to the following implementation. I hope someone finds that useful:
As you can see here, I implemented it using a search strategy and finite domain constraints. I will change it to a purely algorithmic one.
What do the functions do?
In order to produce the powerset, we must call SearchAllSubsets as {SearchAllSubsets L {List.length L}}.
fun {SearchSubsets L N}
{SearchAll
proc {$ Sol}
SolT in
SolT = {FD.list N 1#{List.length L}}
{FD.distinct SolT}
for K in 1..{List.length SolT}-1 do
{Nth SolT K} <: {Nth SolT K+1}
end
{FD.distribute naive SolT}
{List.map SolT fun {$ I} {Nth L I} end Sol}
end
}
end
fun {SearchAllSubsets L N}
case N of
0 then
nil|nil
else
{List.append
{SearchSubsets L N}
{SearchAllSubsets L N-1}
}
end
end
As you can see here, I implemented it using a search strategy and finite domain constraints. I will change it to a purely algorithmic one.
What do the functions do?
- {SearchSubsets L N}: Returns the subsets of L with exactly N elements. For example, given L=[a b c] and N=2 it will return [a b], [b c] and [a c].
- {SearchAllSubsets L N}: Returns the subsets of L with at most N elements. In the example above, it will return [a b], [b c] and [a c] as well as [a], [b], [c] and the empty set nil.
In order to produce the powerset, we must call SearchAllSubsets as {SearchAllSubsets L {List.length L}}.
i.e if we feed the following:
S = [a b c d]we will get in the browser window the list with 16 elements:
{Browse {SearchAllSubsets S {List.length S}}}
[[a b c d] [a b c] [a b d] [a c d] [b c d] [a b]OK, I think that is all for now. Stay tuned.
[a c] [a d] [b c] [b d] [c d] [a] [b] [c] [d] nil]
P.S. Is there a way to easily embed code to blogspot posts?
Edit: I just wrote a dummy Propositional Clausal Logic (PCL) model searcher in Oz. I will return to this once it's in a usable form.
Σάββατο 8 Οκτωβρίου 2011
Sooperlooper loses connection to engine
If it happens that sooperlooper shows you this dialog:

on newer distributions (I tried it with Fedora 16 beta 1), add your
. (substitude with your host and with your domain) to your `/etc/hosts' file on the line for 127.0.0.1 and try again.
For example, my hostname is `mmxgn' and domain is `emergencia' so my hosts file was:
and I added mmxgn.emergencia next to localhost.
Now when I run `slgui' I can use sooperlooper without the engine dying.
Lost connection to SooperLooper engine.
See the Preferences->Connections tab to start a new one

on newer distributions (I tried it with Fedora 16 beta 1), add your
For example, my hostname is `mmxgn' and domain is `emergencia' so my hosts file was:
127.0.0.1 localhost.localdomain localhost
and I added mmxgn.emergencia next to localhost.
127.0.0.1 localhost.localdomain localhost mmxgn.emergencia
Now when I run `slgui' I can use sooperlooper without the engine dying.
Εγγραφή σε:
Αναρτήσεις (Atom)
