Music Applet 2.2.1 Released

Music Applet 2.2.1 has been released! As you might guess from the version number, this is primarily a bug-fix release. In particular, this release fixes a compatibility issue with GTK+ 2.12 that prevented the song information tooltip from actually having any song information in it. In addition to a few other, more minor, bug fixes, there’s also an updated Polish translation.

The bleeding edge

I donated blood recently. What makes this particular instance notable is that I learned first-hand why they put a tarp down on the floor in the donation area.

I knew things weren’t going to go well when I saw that the technician was having a really difficult time trying to find where to stick the needle. As in, spent a good minute working on that problem. I’ve donated many times before, but that’s the first time I ever witnessed that level of effort being exerted to find the target. So, either the physiology of my arm radically changed since the last time I donated, or the technician who was going to stick me wasn’t very good.

Given that I generally try to avoid radiological sources, and I haven’t wandered into any Level 4 Biohazard labs recently, I was leaning towards the latter. But at that point, what are you going to do?

Now, I readily admit that I am a wuss. I always make sure to look the other way when they do the needle stick, and never look back until they have the thing over it in place. But I haven’t found any good ways to disable my tactile sense, so I still noticed that there was also an unusual amount of activity going on with that needle.

Then I heard the technician call someone else over for help. At that point, in a moment of weakness, curiousity got the better of me.

Now, as an aside, I would like to remind the reader that blood, like IP packets, does not just get piled onto a truck, but travels through a series of tubes. The standard blood donation procedure augments this general paradigm by running a tube from your arm into a bag. And, when you think about it, a bag is nothing more than a fat little tube with one end blocked off. So, if things are going well, your blood should always be in a tube of some sort.

When I looked back at my arm, the first thing I noticed was that a fair amount of blood was in fact not in a tube at all, but had instead gotten spread out one way or another over my arm.

I remarked, “Ooh, that doesn’t look good.”

The technician quickly assured me that everything was under control, and by the way, maybe you would like to look the other way for a little while longer?

Since I didn’t get a look at what happened after that, I’m going to assume that someone competent got the needle properly in place and stopped any further bleeding. Well, any further unintended bleeding, at least. Soon after that I noticed the technician wiping something up off the floor directly below the arm in question.

So, now you know why they put that tarp down.

For the record, the rest of the donation proceeded relatively uneventfully, aside from the technician having to repeatedly adjust the pressure to hit the sweet spot of continued blood flow without the arm going numb. Which was also something I never had happen any other time I donated.

Plus, obviously, I survived, so there is one thing about the whole ordeal that went right.

In retrospect, I’m not sure I want to know the story behind why, during the screening process, that technician donned a face mask clearly labeled “Splatter Shield” when doing the needle stick for the iron test. You know, where they have to squeeze your finger to coax out a couple drops of blood to fill a pipette via capillary action? I mean, how high does one’s blood pressure need to be to make that precaution necessary?

The Political Genius of Stephen Colbert

As everyone knows by now, Dr. Stephen T. Colbert, DFA, is running for president of the United States. In South Carolina.

Some people might think that Stephen Colbert’s chances of becoming president are negligible, just because South Carolina only has 8 electoral votes, whereas 270 are needed to win (unless someone intervenes, of course). Some might even write his candidacy off as a joke.

Well, some people are wrong.

Stephen Colbert is a trans-media powerhouse, almost as though he were a white, male Oprah. At least, I’m told he’s white. Like Stephen Colbert, I don’t see color. People tell me he’s white, and I believe them, since taxis in New York stop for him.

Besides his award-deserving cable news program The Colbert Report, his syndicated talk radio show Colbert on the ERT, his autobiography I Am America (And So Can You!), his unpublished novel Stephen Colber’s Alpha Squad 7: Lady Nocturne: A Tek Jansen Adventure, his spin-off animated series Stephen Colbert Presents: Stephen Colber’s Alpha Squad 7: The New Tek Jansen Adventures, and his spin-off comic book Stephen Colbert’s Tek Jansen, he also has his own ice cream and line of premium man-seed.

With that kind of unstoppable juggernaut power, most people would be content to rake in the cash. But not Stephen Colbert. He uses his media power for worthy causes in addition to raking in the cash, such as raising wrist awareness, helping us better know our congresspersons, enriching our lexicon, and reminding us all of the #1 threat to America.

Really, when you think about it, Stephen Colbert has done all he can do for this nation without having control of the executive branch.

And when you think about it, only running for president in South Carolina is a masterwork of political genius that would drive Karl Rove into a jealous rage. While other candidates recognize the value in campaigning only in the handful of states that matter, only Stephen Colbert has the fortitude to focus on a single state, avoiding entirely the risk of squandering his corporate sponsorship money on campaigning elsewhere covering a campaign in other states on his cable news program, in accordance with federal election law.

Besides, the prospect of only getting 8 out of 270 electoral votes isn’t really an issue, if you remember your American history. Did you actually think it’s just happenstance that he picked South Carolina to run for president in? Hardly! Remember what happened last time South Carolina didn’t get its way in the presidential election?

You didn’t think calling his fanbase the “Colbert Nation” wasn’t meant to be taken literally, did you?

While the other candidates are focusing on winning one election across all 50 states, Stephen Colbert is clearly going to take the long view and instead win 50 consecutive elections, one state at a time. At that rate, in January 2205, Stephen Colbert will become president of Stephen Colbert’s United States of America. The Colbert Nation will have no 22nd Amendment to stop him!

And lest you think Stephen Colbert won’t have the votes to pull this off, are you kidding me? When Hungary held a poll to choose who to name a new bridge after, Stephen Colbert received over 17,000,000 votes. Not only was this roughly 15,000,000 more than the runner-up, but it was also roughly 7,000,000 more votes than the population of Hungary itself. The people cry out for Stephen Colbert to lead them!

Or at least, to be able to vicariously drive over him. But in contemporary American politics, isn’t that really the same thing?

Python v. Prolog: Round 1: Fight!

Finally, I’ve made some early progress in implementing Old Lady’s bidding system logic in Prolog. Specifically, SWI-Prolog.

While GNU Prolog looks like it has all the features Old Lady would need, it doesn’t look like it’s quite as robust a Prolog implementation as SWI-Prolog is. For example, GNU Prolog doesn’t have a module system, which might be useful whenever Old Lady supports more than just one bidding system — for example, you might want generic stuff in one module, and each particular bidding system in its own module. Also, integrating GNU Prolog into a Python program looks like a trickier proposition than I initially thought. Although GNU Prolog has a Prolog-to-C interface, it’s geared towards embedding a static copy of GNU Prolog into a standalone C program. Getting its compiler wrapper to output a shared library suitable for wrapping a Python module around is probably doable, but would involve more trickery than I’d really care to have to implement.

Which is all not to say that the road to using SWI-Prolog has been particularly wonderful, either. The Debian packages for it are pretty out of date (the last two uploads were in June 2006 and July 2004!). PySWIP provides a Python interface to SWI-Prolog, but requires SWI-Prolog’s shared library; there’s a five-year-old wishlist bug for the Debian packages to include that library, which they currently don’t. While supposedly there is work on getting a non-ancient version of SWI-Prolog packaged, you’ll forgive me if I don’t hold my breath.

Fortunately, compiling the latest SWI-Prolog from source and installing it manually wasn’t too difficult. Unfortunatley, the last released version of PySWIP (0.2.1) doesn’t actually work, so I had to grab the latest code from the SVN repository, which at least is functional.


My intention is to issue a Prolog query of the form

Hand=[...], History=[...], choose_bid(Bid, Hand, History)

where Hand is a list of cards in the player’s hand and History is the list of bids that have been made previously by all players. What the Prolog code will do is find a value for Bid that looks something like bid(1,hearts) or bid(pass), or something along those lines. Nothing fancy.

Unfortunately, PySWIP (or at least the version in the SVN repository) doesn’t provide very useful information out of a query like this. Say for example I issue the following query through PySWIP (with extra whitespace added between the main terms, for readability’s sake):

Hand=[card(7,clubs), card(8,clubs), card(9,clubs), card(ace,clubs), card(6,diamonds), card(8,diamonds), card(ace,diamonds), card(2,hearts), card(10,hearts), card(queen,hearts), card(king,hearts), card(5,spades), card(8,spades)],
choose_bid(Bid, Hand, Hist)

For each solution found, PySWIP returns a dict with what term is assigned to each variable. In the above, PySWIP “helpfully” returns the string 'Functor5075212' as the value assigned to Bid.

Yes, PySWIP, thanks for telling me it’s some complex term. And giving me no way to look at what the term actually is.

I can only get a useful result back if I only ask for simple atoms to be assigned to the variables in the query. But since I don’t know whether there are one or two parameters to the bid term, I have to effectively do two separate queries, one for each case:

Hand=[card(7,clubs), card(8,clubs), card(9,clubs), card(ace,clubs), card(6,diamonds), card(8,diamonds), card(ace,diamonds), card(2,hearts), card(10,hearts), card(queen,hearts), card(king,hearts), card(5,spades), card(8,spades)],
( choose_bid(bid(Level, Denom), Hand, Hist) ; choose_bid(bid(Action), Hand, Hist) )

That is, use a logical disjunction between two separate calls to the choose_bid predicate, which ends up doing twice the work as the original, “correct” query. But at least PySWIP returns useful information in this case:

'Denom': 'clubs', 'Level': 1, 'Action': Variable(362)

I can only assume this sort of brokenness in PySWIP is a bug, and not actually what it’s intended to do for non-atomic terms assigned to variables. (It also gives me the assignments to Hand and Hist, which are also expressed using the nonsense Functor notation, but at least for those it gives me the paramter list too, which would actually be useful, if not for the fact that I already told PySWIP what those variables’ values are, and in fact that I only made them variables instead of inlining them directly in the call to choose_bid since it’s forcing me to make two calls to choose_bid in the first place!)

Suboptimal, yes, but it is at least usable, and the ugliness can be safely hidden in my Python class that builds these queries and parses out the results.

For the truly adventurous, the code is in the Old Lady bzr repository, though it’s not really playable yet, since breathtakingly little of the Standard American Yellow Card has yet been implemented.

Now that’s a presentation

OK, there’s been some talk around here about truly great presentations. While those approaches certainly have their merits, I think British physiologist Giles Brindley is the hands-down winner of Greatest Presentation Ever.

Brindley did some significant research on drug treatments for erectile disfunction, and presented his results at the 1983 Urodynamics Society meeting in Las Vegas.

If you’re wondering why that would be a Great Presentation, consider that, in this instance, “presented his results” is a double entendre.

No, not like that. By which I mean, no, not only like that. It’s much worse/better than that.

Read the full story here, along with some information on other attempted erectile disfunction treatments.

Disclaimer: use this approach in your own presentations at your own risk.

Comments Off

It’s about time

** You are receiving this message because your e-mail address
has been scheduled for DELETION sometime after November 5, 2007. **

Considering that I graduated back in May 2006, this suggests that Purdue keeps your ITaP e-mail account active for 18 months after you leave. For comparison, the Comp Sci department finally got around to shutting down that e-mail address of mine sometime last month.

So, in the exceedingly unlikely chance you’re still using one of my old Purdue e-mail addresses for something, you better get into the habit of using my current, oh-so-hard-to-guess e-mail address (hint: firstname at lastname dot org).

The good news, of course, is that once Purdue finally stops forwarding my mail from that account, the amount of spam I get will go down significantly.

Should I stay or should I go?

So apparently, the Small Press Expo is going to be this weekend in Bethesda. I’ve only taken note of this because Howard “Schlock Mercenary” Tayler and Jeph “Questionable Content” Jacques will be exhibiting there, and at the very least I don’t think Howard Tayler makes it out this far east very frequently.

However, that’s also about the extent of my interest in the goings-on there. I mean, I recognize a few of the other names that’ll be there, but they don’t register much more than a meh. So, is it worth driving down to the D.C. area (including — ick — a stretch on the Beltway and/or a really long ride on the Metro), finding parking, and paying a day’s admission to see all of two exhibitors? Which I guess would involve waiting in line, buying their merch, and having it signed, presumably in that order? (Not having been to a convention type thing like this, I don’t know for sure.)

Plus, the idea of going down around D.C. for the third time in one week isn’t terribly appealing either, but I’m open to being convinced to go.

Mass != Weight

On the off chance that anyone who works at the National Air and Space Museum reads this, take heed:

The kilogram is a unit of mass. The pound is a unit of weight. Weight is the gravitational force exerted on an object. Mass is not affected by gravitational fields (barring relativistic effects, at least).

A kilogram weighs 2.2 pounds on Earth, and weighs one-sixth that on the moon. That does not mean that an object’s mass also decreases by a factor of six when you put it on the moon. If you really want to talk about the weight of the stuff sent up on the Apollo missions, start using newtons as your metric measurement instead of kilograms.

And people wonder why the probes we send to Mars go off course.

Comments Off

Pro Prolog

Last time, I mentioned that different programming paradigms involve thinking about the problem you’re trying to solve in completely different ways. Most languages you normally see in use, be they procedural, object-oriented, functional, or something else, typically involve giving the computer a series of commands to execute. The way you do that can vary quite a bit, but that’s essentially what’s going on. The computer doesn’t particularly care what you’re trying to accomplish; it just does as it’s told. We might call this the Meatwad Programming Paradigm:

Do what I said, ’cause I said it.

- Meatwad

Prolog is different; it’s a logic programming language. In logic programming, instead of giving the computer a series of commands, you give it a database of facts and rules. Facts are, well, simple facts that you know are true. Rules tell the computer how to derive new facts from other facts. Once you load the database, you can ask the computer where things are true. If the computer can use the facts and rules it knows to prove what you asked, it will tell you so. Otherwise, it will report failure.

An example might make this clearer. Let’s say we want to study the relationships between people in a family. Our database needs to have a simple set of relationships we know, such as:


Our facts take the form of predicates with one or more arguments. Here, we’re using father(X,Y) to mean that X is the father of Y. We use mother(X,Y) similarly.

Given just this database, we can execute queries to see if certain parent-child relationships are true. For example:

| ?- father(george,lindsay).
true ?
(4 ms) yes
| ?- father(tobias,buster).

It should be exceedingly obvious that, given the above database, George is Lindsay’s father, but Tobias is not Buster’s father. Technically, Prolog hasn’t proved that Tobias isn’t Buster’s father, but it did fail to prove that he was, which is good enough for Prolog.

Naturally, if this were all we could do with Prolog, it wouldn’t be very interesting. One neat thing is that we can put variables in the arguments to, for example, get a list of everyone whose father is George:

| ?- father(george,X).
X = michael ? a
X = lindsay
X = gob
X = buster
(4 ms) yes

Prolog tells us all the values of X that would satisfy the query. We could have used a variable in the first argument to father instead (to find out who someone’s father is) or use variables for both arguments (to find out all father-child relationships).

Things get a bit more interesting once we start adding some rules to our database. For example, let’s start with a predicate parent(X,Y) that is true whenever X is Y‘s parent:

parent(X,Y) :- father(X,Y).
parent(X,Y) :- mother(X,Y).

The first rule tells Prolog that X is Y‘s parent if X is Y‘s father. The second says that X is Y‘s parent if X is Y‘s mother. Now we can use the parent predicate just like the others we defined via facts:

| ?- parent(lucille,buster).
| ?- parent(X,maeby).
X = tobias ? a
X = lindsay

But this is kid’s stuff so far. Prolog wouldn’t be much of a programming language if we couldn’t use rules recursively, so let’s do that to define arbitrary ancestral relationships between two people:

ancestor(X,Y) :- parent(X,Y).
ancestor(X,Y) :- parent(X,Z), ancestor(Z,Y).

The first rule simply says that X is Y‘s ancestor if X is Y‘s parent. The second one is where things get interesting: X is Y‘s ancestor if X is the parent of some Z, and Z is an ancestor of Y. Now we can use Prolog to probe ancestral relationships of arbitrary length:

| ?- ancestor(george,maeby).
true ?
| ?- ancestor(X,maeby).
X = tobias ? a
X = lindsay
X = george
X = lucille

Observe that that last query finds not only Maeby’s parents (Tobias and Lindsay) but also her grandparents (George and Lucille).

Prolog also lets us use lists in additional to individual terms. To show that we can also implement algorithms in Prolog, here’s a (fairly unoptimized) implementation of mergesort:

mergesort([], []).
mergesort([X], [X]).
mergesort(In, Out) :-
    length(In, InLen),
    InLen >= 2,
    append(X, Y, In),
    length(X, XLen),
    length(Y, YLen),
    ( 0 is YLen - XLen; 1 is YLen - XLen ),
    mergesort(X, XSorted),
    mergesort(Y, YSorted),
    merge(XSorted, YSorted, Out).
merge([], Y, Y).
merge(X, [], X).
merge([XHead | XTail], [YHead | YTail], [XHead | RTail]) :-
    XHead =< YHead,
    merge(XTail, [YHead | YTail], RTail).
merge([XHead | XTail], [YHead | YTail], [YHead | RTail]) :-
    YHead < XHead,
    merge([XHead | XTail], YTail, RTail).

That may look quite a bit like a mergesort written in a functional language, but note that there is some logic programming uniqueness to it. In particularly, we split the “input” list in half by telling Prolog to find two lists X and Y who, appended together, equal the original list, and whose lengths are within 1 of each other. Prolog takes care of figuring out what X and Y should be in any particular instance. Having something called append do double duty as a way to split a list in twain is one of the crazy things logic programming lets you do.

Plain old Prolog does fall down a bit when it comes to math. While it can handle arithmetic just fine, it doesn’t know how to do algebra. For example:

| ?- X is 3 + 5.
X = 8
| ?- 8 is X + 5.
uncaught exception: error(instantiation_error,(is)/2)

From what we’ve seen so far, Prolog doesn’t quite satisfy the needs for implementing a bridge bidding system for Old Lady. On the one hand, predicates and variable unification are a good fit for the bidding rules: something like bid(Bid, HandInfo) could be used to choose a bid if we pass it information about a hand, and can also be used to learn about a hand given a certain bid. This “it works in both directions”-ness is exactly what we’re looking for to both make our own bids and to interpret those of other players, without having to duplicate our rules.

However, an inability to do mathematics more complex than basic arithmetic is a problem, since most of the information communicated through bidding is precisely that: how many HCP a player has, or how many cards of a certain suit he has, and so on. There’s also known mathematical relationships between all the variables: for example, the deck only has 13 spades, so if I have 5 and my partner has at least 3, that tells me that the other two players have at most 5 spades between them. Plain old Prolog doesn’t have an elegant way to express these sorts of constraints.

But notice how I slipped “plain old” in front of Prolog? Some Prolog implementations, such as GNU Prolog (the one I’m experimenting with) also do constraint logic programming, which lets us express mathematical relationships between variables. For example, let’s try to find all numbers less than or equal to 100 that are equal to the square of a prime number:

| ?- fd_domain(X,0,100), fd_prime(Y), X #=# Y * Y.
X = _#3(4:9:25:49)
Y = _#23(2..3:5:7)

The constraint solver in GNU Prolog has figured out that X must be 4, 9, 25, or 49, and Y must be 2, 3, 5, or 7. As we add constraints, we can narrow that down even further. For example, let’s also require that X is even:

| ?- fd_domain(X,0,100), fd_prime(Y), X #=# Y * Y, 0 #=# rem(X, 2).
X = 4
Y = 2

Given this, a way to implement a bidding system in GNU Prolog reveals itself. Encode the bidding system rules in Prolog rules, using these numerical constraints. Then build a query that includes all the basic information we know, namely our hand and the bidding history so far. In evaluating the query, GNU Prolog will determine constraints on the variables of interest (i.e., who has how many of each suit, and their hands’ estimated strength), and pick the next bid we should make.

Even better, GNU Prolog has ways to issue queries from C code. While this might not seem very useful when Old Lady is written in Python, there are ways to interact between C and Python, so we just need to write a little duct tape in C that communicates between GNU Prolog and Python.

So, it turns out I was looking for a constraint logic solver all this time, and was writing an exceedingly two-ninths-assed one in Python.

If any of the above has piqued your interest in Prolog, there’s a pretty good Prolog tutorial here that does a much better job explaining Prolog than I’ve done here.

Klaus has competition

You may recall former fellow Fool Scott “Klaus” Parker groundbreaking presentation on “Simplifying Occlusion-culling Ray-tracing Photorealistic Perspective-warping Graphics”, widely regarded as being “definitely a presentation.”

Well, I do believe that Doug Zongker of the University of Washington has thrown down the proverbial gauntlet with his research paper, “Chicken Chicken Chicken: Chicken Chicken“. Or, if you prefer a more approachable version, here’s a video of him presenting his work:

Klaus, dare you try to compete with this, or are you chicken?