Argg, had an whole reply typed out, only to loose it again. Here's a second attempt:
-I've just uploaded the android version of aici to the web:
http://bragisoft.com/chat-online/. It's still a very simple bot, it doesn't even yet have pattens to handle 'x is y' or the x of y is z'. They should be added before
Steve's competition takes off. (some chatlog would probably be helpful for getting out some of the kinks)
About new tricks: you have sort of beaten me to the punch by a couple of days. I'm currently trying to get a first pattern learning algorithm to work. At the moment, it's still very simple: record a static input string and attach a static response to it. I'm hoping to get this working before the chatbot battles as a fallback, when it can't find a proper reply. In a next iteration, 'sub-topics' like subject, location, time,... should be recognized in new patterns,...
I'm actually trying to implement 2 things for the time of 1: the learning algorithm is written in a new front-end language which sits on top of the resonating neural network. This will become the new 'do-patterns' so that you have 'for, do, if,... + the rest of the network's features. It'll also give a better upgrade path for already existing networks (the pattern-matching algoritm can now be rendered and distributed as text). (and it should also allow me to document the code a bit better).
Here's the actual learning algorithm:
(it's currently still very much inked-into the already existing code, so things like 'callbackin' and 'callbackOut' are defined in another file and reference existing neurons.
//callback for var-path
//builds a new input pattern, based on the last input statement found in the log
//The input pattern is added to a new rule (which is added to a special 'learned' topic.
//The rule is linked to the CallbackIn, which is an output pattern.
//callbackOut will contain the newly created input pattern when done (single textneuron).
Cluster LearnPattern(code)
{
this()
{
var iInputs = GetLastInputFromLog();
int iCount = Count(iInputs);
if(iCount > 0)
{
string iSpace = " ";
CallbackOut = CCToS(Interleaf(ref(iInputs), ref(iSpace))); //we need to convert the list of words back to a single sentence, where each word is seperated with spaces, so we have a visual representation for the pattern.
var iCurrent = iInputs[0];
AddLink(CallBackOut, iCurrent, ParsedPatternStart);
for(int i = 1; i < iCount; i++)
{
var iNext = new(Neuron);
AddLink(iCurrent, iNext, iInputs[i]);
iCurrent = iNext;
}
AddLink(iCurrent, CallBackOut, Rule);
var iRule = MakeCluster(Rule, CallbackOut); //add it to a new rule
var iOutput = MakeCluster(OutputPatterns, CallbackIn); //link the rule with the output.
AddLink(iRule, iOutput, OutputPatterns);
AddChild(AutoLearned, iRule); //add the rule to the default topic.
}
}
GetLastInputFromLog(): var
{
var log = GetFirstOut(OutputSin, CurrentConversation);
if(count(log) > 0 && ChildCount(log) > 2)
{
var iFound = ChildAt(log, ChildCount(log) - 3);
return GetChildrenRange(iFound, 0, ChildCount(ifound) -1); //each log item also contains a date-time stamp at the end, which has to be removed.
}
}
}
//callback for var-path
//builds an output pattern based on the content of CallbackIn and returns this (through CallbackOut).
Cluster BuildOutputPattern(code)
{
this()
{
int iCount = Count(CallBackIn);
if(iCount > 0)
{
CallbackOut = CCToS(CallBackIn); //we need to convert the list of words back to a single sentence, to form the neuron that represents the pattern (also useful for the editors).
var iParsedPattern = MakeCluster(ParsedPatternOutput, CallbackIn);
AddLink(CallbackOut, iParsedPattern, ParsedPatternOutput);
}
}
}