|
View:
New views
10 Messages
—
Rating Filter:
Alert me
|
|
|
ChatterBean 00.007 is now availableChatterBean version 00.007 is now available. This
version implements the transformational elements, making it the first ChatterBean release to support the full set of AIML 1.0.1 tags. A lot of work is yet to be done before the project reaches standard compliance (for one thing, correct whitespace handling is yet to be implemented), let alone fulfill its stated objectives. Still, an important milestone has been reached. As you probably guessed, another change in this release is a new version number system. From now on, every release will have a series number and a version number. Version numbers are assigned sequentially within a series, while series numbers follow this convention: * 00: Alpha series; * 01: Beta series; * 02: Production series. Whether the series number will keep advancing after ChatterBean upgrades to production status is not yet decided. http://chatterbean.bitoflife.cjb.net PS: In recent times, some people have contacted me to send contributions such as bug reports, code fragments and even an invitation to join a web ring. I wish you to know that I appreciate your help, and although my lack of organization has so far prevented me to properly address most of it, I have not forgotten nor dismissed it. -- Ja mata ne. Helio Perroni Filho _______________________________________________________ Yahoo! doce lar. Fa?a do Yahoo! sua homepage. http://br.yahoo.com/homepageset.html _______________________________________________ alicebot-developer mailing list alicebot-developer@... http://list.alicebot.org/mailman/listinfo/alicebot-developer |
|
|
Re: ChatterBean 00.007 is now availableRight on!
I'm a pretty big Java and C++ person and this looks pretty cool. I especially liked reading: The classes used to build that tree are located inside the bitoflife.chatterbean.aiml package; every time ChatterBean's AIML parser reads a tag, it uses reflection to create an instance of a class with the same name of the tag, feed it with attributes and, perhaps, add children objects to it. For example, every time the parser reads a <category> tag, it creates an instance of the bitoflife.chatterbean.aiml.Category class. The parser code simply assumes that, for every tag it reads, there will be a class with the same name inside the bitoflife.chatterbean.aiml package; there is no program code telling it what tags are valid or not. I too in my C++ RebeccaAIML use a similar technique. Unfortunately C++ does not have reflection so I have one extra programming step: //Boy I wish C++ had reflection :-( Tag &createTag(String className) { if(className == "category") return new Category; else if(className == "date") return new Date; else if // ... so on } Also I saw from your page: there is no program code telling it what tags are valid or not. Same here. I use the xsd from Program-D and a Sax parser error handling instead. Great work! --- Helio Perroni Filho <xperroni@...> wrote: > ChatterBean version 00.007 is now available. This > version implements the transformational elements, > making it the first ChatterBean release to support > the > full set of AIML 1.0.1 tags. A lot of work is yet to > be done before the project reaches standard > compliance > (for one thing, correct whitespace handling is yet > to > be implemented), let alone fulfill its stated > objectives. Still, an important milestone has been > reached. > > As you probably guessed, another change in this > release is a new version number system. From now on, > every release will have a series number and a > version > number. Version numbers are assigned sequentially > within a series, while series numbers follow this > convention: > > * 00: Alpha series; > * 01: Beta series; > * 02: Production series. > > Whether the series number will keep advancing after > ChatterBean upgrades to production status is not yet > decided. > > http://chatterbean.bitoflife.cjb.net > > PS: In recent times, some people have contacted me > to > send contributions such as bug reports, code > fragments > and even an invitation to join a web ring. I wish > you > to know that I appreciate your help, and although my > lack of organization has so far prevented me to > properly address most of it, I have not forgotten > nor > dismissed it. > > -- > Ja mata ne. > Helio Perroni Filho > > > > > > > > > > > > Yahoo! doce lar. Fa?a do Yahoo! sua homepage. > http://br.yahoo.com/homepageset.html > > _______________________________________________ > alicebot-developer mailing list > alicebot-developer@... > http://list.alicebot.org/mailman/listinfo/alicebot-developer > .................................................o' \,=./ `o Mehri (o o) ---=--=---=--=--=---=--=--=--=--=---=--=--=-----ooO--(_)--Ooo--- __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com _______________________________________________ alicebot-developer mailing list alicebot-developer@... http://list.alicebot.org/mailman/listinfo/alicebot-developer |
|
|
Re: ChatterBean 00.007 is now available--- mehri <foreverlinux@...> escreveu:
> //Boy I wish C++ had reflection :-( > Tag &createTag(String className) > { > if(className == "category") > return new Category; > else if(className == "date") > return new Date; > else if // ... so on > > } Have you tried to use function pointers? For every tag, you would have a function responsible or returning a new instance of a given class, and then you could have a map collection mapping tag names to function pointers: // Include the library for map templates. #include <map> // ... /* Function pointer type for a tag-maker function. */ typedef Tag& (*TagMaker)(void); /* Name-to-maker-function map. Must be filled somewhere else. */ map<String, TagMaker> makers; // ... Tag &createTag(String className) { /* Gets the function pointer from the map. */ TagMaker maker = makers[className]; return maker(); } This might seem more complicated than Java reflection, but it is feasible, and for a lenghty set of possible tags, much more efficient than an if-then-else chain -- retrieving a value from the map takes a time of O(1) in assintotic notation, while going down a conditional chain takes O(n) in the worst case, where n is the length of the chain. -- Ja mata ne. Helio Perroni Filho _______________________________________________________ Yahoo! doce lar. Fa?a do Yahoo! sua homepage. http://br.yahoo.com/homepageset.html _______________________________________________ alicebot-developer mailing list alicebot-developer@... http://list.alicebot.org/mailman/listinfo/alicebot-developer |
|
|
Re: ChatterBean 00.007 is now availableProblem is that from the xml I get the AIML tag name
as a String. From the string I have to instantiate the class with the same name. With reflection this can be done easily. Without reflection it's painful. For example, with C++ how can you do a: String someClassName = "InnerTemplate"; return new someClassName; I know of a few ways but none are elegant and all are more complex then simply registering the classes in a factory method: Tag &tagClass createClass(String someClassName) { if(someClassName == "InnerTemplate") return new InnerTemplate; else if(someClassName == "xxx") return new XXX } Right now I'm working on a dll layering scheme to allow overriding or adding custom AIML tags. The creator of the dll will have to inherit from a factory and write their own: Tag &tagClass createClass(String someClassName) method. --- Helio Perroni Filho <xperroni@...> wrote: > --- mehri <foreverlinux@...> escreveu: > > > //Boy I wish C++ had reflection :-( > > Tag &createTag(String className) > > { > > if(className == "category") > > return new Category; > > else if(className == "date") > > return new Date; > > else if // ... so on > > > > } > > Have you tried to use function pointers? For every > tag, you would have a function responsible or > returning a new instance of a given class, and then > you could have a map collection mapping tag names to > function pointers: > > // Include the library for map templates. > #include <map> > > // ... > > /* Function pointer type for a tag-maker function. > */ > typedef Tag& (*TagMaker)(void); > > /* Name-to-maker-function map. Must be filled > somewhere else. */ > map<String, TagMaker> makers; > > // ... > > Tag &createTag(String className) > { > /* Gets the function pointer from the map. */ > TagMaker maker = makers[className]; > > return maker(); > } > > This might seem more complicated than Java > reflection, > but it is feasible, and for a lenghty set of > possible > tags, much more efficient than an if-then-else chain > -- retrieving a value from the map takes a time of > O(1) in assintotic notation, while going down a > conditional chain takes O(n) in the worst case, > where > n is the length of the chain. > > -- > Ja mata ne. > Helio Perroni Filho > > > > > > > > > > > > Yahoo! doce lar. Fa?a do Yahoo! sua homepage. > http://br.yahoo.com/homepageset.html > > _______________________________________________ > alicebot-developer mailing list > alicebot-developer@... > http://list.alicebot.org/mailman/listinfo/alicebot-developer > .................................................o' \,=./ `o Mehri (o o) ---=--=---=--=--=---=--=--=--=--=---=--=--=-----ooO--(_)--Ooo--- __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com _______________________________________________ alicebot-developer mailing list alicebot-developer@... http://list.alicebot.org/mailman/listinfo/alicebot-developer |
|
|
Re: Dynamic tag instantiation in C++ (was: ChatterBean 00.007 is now available)--- mehri <foreverlinux@...> escreveu: > Problem is that from the xml I get the AIML tag name > as a String. From the string I have to instantiate > the class with the same name. Hence my idea of providing factory functions for each tag, mapping the tag names to pointers for the factoy functions, and then retrieving the pointers from a map as the tags are read from the XML document. As I exposed, it is not as simple as reflection, but it can be done, and is more efficient than conditional chains. > I know of a few ways but none are elegant and all > are more complex then simply registering the classes in > a factory method: > > Tag &tagClass createClass(String someClassName) > { > if(someClassName == "InnerTemplate") > return new InnerTemplate; > else if(someClassName == "xxx") > return new XXX > } The problem with this approach is that you have to modify the factory method each time you add a new tag. With a global factory map, however, you could demand each new tag to register itself at loading time: // aiml.h // Global field. map<String, FactoryFunction> factories; // ... // category.h #include <aiml> class Category { // ... } Tag& newCategory() { return new Category(); } // Ugly hack to allow load-time execution of code. class CategoryRegister { public: CategoryRegister() { factories["Category"] = newCategory; } } // Makes the class constructor be called at loading time. CategoryRegister& categoryRegister; -- Ja mata ne. Helio Perroni Filho _______________________________________________________ Yahoo! doce lar. Faça do Yahoo! sua homepage. http://br.yahoo.com/homepageset.html _______________________________________________ alicebot-developer mailing list alicebot-developer@... http://list.alicebot.org/mailman/listinfo/alicebot-developer |
|
|
Re: Dynamic tag instantiation in C++ (was: ChatterBean 00.007 is now available)Hey Helio.
Good discussion here. I like it that you've taken an interest to this debate and you seem to be a pretty good fellow C++'er. > Hence my idea of providing factory functions for > each > tag, mapping the tag names to pointers for the > factoy > functions, and then retrieving the pointers from a > map > as the tags are read from the XML document. As I > exposed, it is not as simple as reflection, but it > can > be done, and is more efficient than conditional > chains. Agreed when considering the overall worse case senario using Big-O. O(log n) with a balanced tree (std::map) versus the worst case run time of a conditional statement O(n) Now what about the best case senario? With a std::map, you still get Omega(log n) but with a conditional statement you end up with Omega(1). Practically we do not always run into the worst case senario. In my mock example: > > Tag &tagClass createClass(String someClassName) > > { > > if(someClassName == "InnerTemplate") > > return new InnerTemplate; > > else if(someClassName == "xxx") > > return new XXX > > } Let us consider the best case senario in which InnerTemplate is given as "someClassName". In that case, the conditional will be quicker than finding it in a map since it is at the top of the conditional statements. Now let us consider if the very last conditional statement is encountered. The map would have been quicker. Certain tags are going to occur higher in frequency on average than others so I group those at the top. The overall runtime is actually a bit quicker than if I were to search a map since I know ahead of time which tags occur at a higher frequency. I know that these tags are going to occur at a higher frequency for *every* set of AIML tags because these are the required tags such as pattern and template and so on... Other tags such as <AIML> are going to be at the bottom. I only create one AIML class mapped to the AIML tag name since that tag only exists once for each aiml file. So, I might take a single hit on the AIML tag, costing me O(n) compared to the O(log(n)) but I quickly make up for it when I start encountering pattern and template tags which are closer to the top. > // Ugly hack to allow load-time execution of code. > class CategoryRegister > { > public: > CategoryRegister() > { > factories["Category"] = newCategory; > } > } So you still have to write code to say, new Category here? With each new tag you add you still have to hand code the "new TagName"? That and you even say Ugly hack in your comments. That's my troubles. It's ugly if you go down that route. Plus if I keep my tag memory allocation grouped together in the simple factory method I can always add new factory methods that perhaps do not use conditional statements but other algorithms such as a HashMap which would probably be quicker depending on the type of AIML data set you are loading and its size: /** * Determines which algorithm to use to load * the AIML tags. By default it uses * conditional statements but you can change * it to use a Balanced tree with * tagLoadAlgorithm(BalancedTree) * * or HashMap * tagLoadAlgorithm(HashMap) * * or SkipList * * tagLoadAlgorithm(SkipList) * * or etc... */ void tagLoadAlgorithm(Enum algorithm); --- Helio Perroni Filho <xperroni@...> wrote: > > --- mehri <foreverlinux@...> escreveu: > > > Problem is that from the xml I get the AIML tag > name > > as a String. From the string I have to > instantiate > > the class with the same name. > > Hence my idea of providing factory functions for > each > tag, mapping the tag names to pointers for the > factoy > functions, and then retrieving the pointers from a > map > as the tags are read from the XML document. As I > exposed, it is not as simple as reflection, but it > can > be done, and is more efficient than conditional > chains. > > > I know of a few ways but none are elegant and all > > are more complex then simply registering the > classes > in > > a factory method: > > > > Tag &tagClass createClass(String someClassName) > > { > > if(someClassName == "InnerTemplate") > > return new InnerTemplate; > > else if(someClassName == "xxx") > > return new XXX > > } > > The problem with this approach is that you have to > modify the factory method each time you add a new > tag. > With a global factory map, however, you could demand > each new tag to register itself at loading time: > > // aiml.h > > // Global field. > map<String, FactoryFunction> factories; > > // ... > > // category.h > > #include <aiml> > > class Category > { > // ... > } > > Tag& newCategory() > { > return new Category(); > } > > // Ugly hack to allow load-time execution of code. > class CategoryRegister > { > public: > CategoryRegister() > { > factories["Category"] = newCategory; > } > } > > // Makes the class constructor be called at loading > time. > CategoryRegister& categoryRegister; > > -- > Ja mata ne. > Helio Perroni Filho > > > > > > > > > > > > Yahoo! doce lar. Faça do Yahoo! sua homepage. > http://br.yahoo.com/homepageset.html > > _______________________________________________ > alicebot-developer mailing list > alicebot-developer@... > http://list.alicebot.org/mailman/listinfo/alicebot-developer > .................................................o' \,=./ `o Mehri (o o) ---=--=---=--=--=---=--=--=--=--=---=--=--=-----ooO--(_)--Ooo--- __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com _______________________________________________ alicebot-developer mailing list alicebot-developer@... http://list.alicebot.org/mailman/listinfo/alicebot-developer |
|
|
Re: Dynamic tag instantiation in C++ (was: ChatterBean 00.007 is now available)--- mehri <foreverlinux@...> escreveu:
> > Hence my idea of providing factory functions for each > > tag, mapping the tag names to pointers for the factoy > > functions, and then retrieving the pointers from a map > > as the tags are read from the XML document. As I > > exposed, it is not as simple as reflection, but it > > can be done, and is more efficient than conditional > > chains. > > Agreed when considering the overall worse case > senario using Big-O. O(log n) with a balanced tree > (std::map) versus the worst case run time of a conditional > statement O(n) > > Now what about the best case senario? With a > std::map, you still get Omega(log n) but with a > conditional statement you end up with Omega(1). Not if the (key, value) pairs are sorted appropriately, something you can do with std::map, admitedly with some extra work. > Certain tags are going to occur higher in frequency > on average than others so I group those at the top. > The overall runtime is actually a bit quicker than if I > were to search a map since I know ahead of time > which tags occur at a higher frequency. Some tags are indeed bound to be on the top of the frequency list, such as (category), (pattern) and (template); others can appear very often in some AIML sets and not so much in others. With a map, you could eventually provide features to adapt the ordering according to run-time hit frequency, or provide a config file for the botmaster to define the priorities. > > // Ugly hack to allow load-time execution of code. > > class CategoryRegister > > { > > public: > > CategoryRegister() > > { > > factories["Category"] = newCategory; > > } > > } > > So you still have to write code to say, new Category > here? With each new tag you add you still have to > hand code the "new TagName"? Yes, but this is code you keep on the same unit of the tag itself. The other way you have to go back to the createTag() function each time you add a new tag, which means at least one extra unit to recompile. > That and you even say Ugly hack in your comments. In that specific case it is an ugly hack, yes. But I know dynamic libraries provide better ways to run code at load time, and since you said you intended to use DLL's on your project... Anyway, this is how I would do things, but what do I know? If I was such a great C++ programmer I wouldn't do everything in Java. ^_^' -- Ja mata ne. Helio Perroni Filho _______________________________________________________ Yahoo! doce lar. Faça do Yahoo! sua homepage. http://br.yahoo.com/homepageset.html _______________________________________________ alicebot-developer mailing list alicebot-developer@... http://list.alicebot.org/mailman/listinfo/alicebot-developer |
|
|
Re: Dynamic tag instantiation in C++ (was: ChatterBean 00.007 is now available)You make some good points here and you are making me
think in a new direction. > Not if the (key, value) pairs are sorted > appropriately, something you can do with std::map, > admitedly with some extra work. Hmmm....This stumped me for a second. But what you are talking about is changing the comparison operator for the keys correct? So the map is ordered with higher frequency tags closer to the begining. Actually that opens a lot of doors. If I want to do conditional statements I can just iterate through the map starting at the begining to the end because of this ordering. Also, it will be easy at runtime to allow the user of the api to change the ordering of the map's keys through configuration as well as specify if they want to use the map's "find" operator or conditional statements. > Yes, but this is code you keep on the same unit of > the > tag itself. The other way you have to go back to the > createTag() function each time you add a new tag, > which means at least one extra unit to recompile. Agreed. This is a difficult design decision for me to make and requires one extra step of discipline to ensure that I add each new tag to that particular method. > In that specific case it is an ugly hack, yes. But I > know dynamic libraries provide better ways to run > code > at load time, and since you said you intended to use > DLL's on your project... > > Anyway, this is how I would do things, but what do I > know? If I was such a great C++ programmer I > wouldn't > do everything in Java. ^_^' > You sound like a pretty proficient C++'er. Certainly using dll's opens more options for loading at runtime but not enought to make this solution any more elegant as far as I can see. To myself, cosmetically, having a string-to-class factory method does not seem that horrible. For creators of the custom dll for the custom tags they will have to inherit from the factory method and add their new's to their custom string-to-class method. What I do have a question about for this methodology would be this portion of your pseudocode: > class CategoryRegister > { > public: > CategoryRegister() > { > factories["Category"] = newCategory; > } > } You still have to write the "new Category" in a seperate class for registeration? Regardless of how well you design your subclass you still have to go to a different class to add code? That's my hangup. No matter how clever, you still have go outside of your subclass to add code for the engine to recognize your new Tag class. --- Helio Perroni Filho <xperroni@...> wrote: > --- mehri <foreverlinux@...> escreveu: > > > > Hence my idea of providing factory functions for > each > > > tag, mapping the tag names to pointers for the > factoy > > > functions, and then retrieving the pointers from > a > map > > > as the tags are read from the XML document. As I > > > exposed, it is not as simple as reflection, but > it > > > can be done, and is more efficient than > conditional > > > chains. > > > > Agreed when considering the overall worse case > > senario using Big-O. O(log n) with a balanced > tree > > (std::map) versus the worst case run time of a > conditional > > statement O(n) > > > > Now what about the best case senario? With a > > std::map, you still get Omega(log n) but with a > > conditional statement you end up with Omega(1). > > > > Certain tags are going to occur higher in > frequency > > on average than others so I group those at the > top. > > The overall runtime is actually a bit quicker than > if I > > were to search a map since I know ahead of time > > which tags occur at a higher frequency. > > Some tags are indeed bound to be on the top of the > frequency list, such as (category), (pattern) and > (template); others can appear very often in some > AIML > sets and not so much in others. With a map, you > could > eventually provide features to adapt the ordering > according to run-time hit frequency, or provide a > config file for the botmaster to define the > priorities. > > > > // Ugly hack to allow load-time execution of > code. > > > class CategoryRegister > > > { > > > public: > > > CategoryRegister() > > > { > > > factories["Category"] = newCategory; > > > } > > > } > > > > So you still have to write code to say, new > Category > > here? With each new tag you add you still have to > > hand code the "new TagName"? > > Yes, but this is code you keep on the same unit of > the > tag itself. The other way you have to go back to the > createTag() function each time you add a new tag, > which means at least one extra unit to recompile. > > > That and you even say Ugly hack in your comments. > > In that specific case it is an ugly hack, yes. But I > know dynamic libraries provide better ways to run > code > at load time, and since you said you intended to use > DLL's on your project... > > Anyway, this is how I would do things, but what do I > know? If I was such a great C++ programmer I > wouldn't > do everything in Java. ^_^' > > -- > Ja mata ne. > Helio Perroni Filho > > > > > > > > > > > > Yahoo! doce lar. Faça do Yahoo! sua homepage. > http://br.yahoo.com/homepageset.html > > _______________________________________________ > alicebot-developer mailing list > alicebot-developer@... > http://list.alicebot.org/mailman/listinfo/alicebot-developer > .................................................o' \,=./ `o Mehri (o o) ---=--=---=--=--=---=--=--=--=--=---=--=--=-----ooO--(_)--Ooo--- __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com _______________________________________________ alicebot-developer mailing list alicebot-developer@... http://list.alicebot.org/mailman/listinfo/alicebot-developer |
|
|
Re: Dynamic tag instantiation in C++ (was: ChatterBean 00.007 is now available)--- mehri <foreverlinux@...> escreveu:
> > Not if the (key, value) pairs are sorted > > appropriately, something you can do with std::map, > > admitedly with some extra work. > > Hmmm....This stumped me for a second. > > But what you are talking about is changing the > comparison operator for the keys correct? So the > map is ordered with higher frequency tags closer to the > begining. Yes, that is the idea. Actually with a reasonably good comparison operator, you could achieve better assintotic time with this approach than with a conditional chain -- whose time is O(n/2) in the normal case, whereas a binary tree search would yield O(lg n/2). > What I do have a question about for this methodology > would be this portion of your pseudocode: > > > class CategoryRegister > > { > > public: > > CategoryRegister() > > { > > factories["Category"] = newCategory; > > } > > } > > You still have to write the "new Category" in a > seperate class for registeration? Regardless of how > well you design your subclass you still have to go > to a different class to add code? > > That's my hangup. No matter how clever, you still > have go outside of your subclass to add code for the > engine to recognize your new Tag class. In Java, you could write the registration code into a static block, which would be executed at class-loading time. C++ doesn't have such a feature as far as I know, so we have to hack it with static field initialization. You could conceivably move the registration code (class and field) into the tag class, but I can't see exactly what that would buy us, with the possible exception of better-looking code. _______________________________________________________ Yahoo! doce lar. Faça do Yahoo! sua homepage. http://br.yahoo.com/homepageset.html _______________________________________________ alicebot-developer mailing list alicebot-developer@... http://list.alicebot.org/mailman/listinfo/alicebot-developer |
|
|
Greek AIML setsHi all,
I wonder if anyone has ever managed to develop Greek AIML-sets. I would be very interested to use them with the AIML PAD. I tried to write some patterns in greek and load them in aiml pad but unfortunately they don't work. Any ideas? Thanks in advance __________________________________________________ ×ñçóéìïðïéåßôå Yahoo!; ÂáñåèÞêáôå ôá åíï÷ëçôéêÜ ìçíýìáôá (spam); Ôï Yahoo! Mail äéáèÝôåé ôçí êáëýôåñç äõíáôÞ ðñïóôáóßá êáôÜ ôùí åíï÷ëçôéêþí ìçíõìÜôùí http://mail.yahoo.gr _______________________________________________ alicebot-developer mailing list alicebot-developer@... http://list.alicebot.org/mailman/listinfo/alicebot-developer |
| Free Forum Powered by Nabble | Forum Help |