Wednesday, June 20, 2007

Don't think of an elephant: Activating symbols

George Lakoff says "Don't think of an elephant". Can you? Of course not; Not anymore. At the moment we're primed by a word, there's no turning back. It activates the imagery of a concept in all its fullness. This automatic, involuntary activation is a basic psychological mechanism at the crux of human intuition. As it turns out, it's also at the centerpiece of Hofstadter's architectures.

The Republicans, Lakoff argues, are masters in exploring this phenomenon. As the host of FOX NEWS will tell liberals: "How can you be against tax relief? I don't understand how any sane person in America can be against tax relief." What's biasing the debate here, of course, is the activation of the word relief--it stands in stark contrast to, for example, a "tax cut".

Yesterday Christian convinced me that we should start work on designing and programming the thing; "it will help us to think"; so that's what this, and upcoming, posts, are all about.

So how should these activations be modeled? I'm following here Harry Foundalis's award-winning thesis (see, for instance, pp. 156--163). Harry suggests that a sigmoid function is the best option for the case. In "current_state", the x axis, we have a discrete number of steps. Concepts can, by propagating activation, increase the current_state of any node. Time will take care of decaying all this exciting activation. So here's Harry proposal:

The advantage of using a sigmoid is that, at low levels of activation, the system should act "prudently", trying to maintain the concept node active; or at least not letting it decay too quickly. At the other end of the scale, when activation is high, it should remain high for some time: the system acts "conservatively", trying to find out what the current thought is all about. Why on earth is "elephant" active at this point?

This is the start of my framework: A class to handle activations. For the mathematics involved, here's an online spreadsheet with the function and a graph. The class architecture, implemented in Delphi, follows:

Tactivation = class
number_discrete_steps: integer;
current_state, level: real;
last_update: tDateTime;
std_wait_time: real;
procedure Recompute_Level;

Constructor Create(steps: integer);
procedure increase (steps: integer);
Function Get_Level:real;
procedure decay;

Most of the variables should be trivial. I'm using around 100 states (but the class is flexible). std_wait_time is multiplied to the actual activation level (obtained by calling Get_Level) before any decay, producing some interesting behavior: active concepts stay for quite some time, disproportionately to their activation level.

Of course, this class follows the basic principle of being (i) closed for modification, while it's also (ii) open for extension. It's closed for modification: unless a bug is found, no line of code should be changed here. But say, for instance, that someone wants to test another function (instead of the sigmoid): it's just a question of overriding Recompute_Level. To modify the decay behavior, just override decay. So nothing that's done and tested and running should be changed, ever. That simple.

I wonder whether Eric, Abhijit and Francisco are also using the sigmoid.