Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

* pattern in topic

Help
hokascha
2012-01-17
2013-04-25
  • hokascha
    hokascha
    2012-01-17

    Hi,

    I am trying to implement some kind of dialog in AIML. Here's simple example:

    <category>
        <pattern>HELLO</pattern>
        <template>
            Hello!
        </template>
    </category>
    <category>
        <pattern>TRANSLATE</pattern>
        <template>
            Tell me the text you want to <set name="topic">translate</set>.
        </template>
    </category>
    <topic name="translate">
        <category>
            <pattern>*</pattern>
            <template>OK, I translate <translate><star/></translate></template>
        </category>
    </topic>
    

    This works well unless the user says "Hello" after the bot asked the user to tell him the text to translate:

    U: Hello
    A: Hello!
    U: Translate good morning
    A: OK, I translate good morning
    U: Translate hello
    A: Hello!

    Looks like Program E isn't prioritizing the topic. Is that by design?

    Thanks a lot,

    Kevin

     
  • hokascha
    hokascha
    2012-01-17

    oops, this was a wrong example of the dialog, here is a correct one:

    U: Hello
    A: Hello!
    U: Translate
    A: Tell me the text you want to translate.
    U: Hello
    A: Hello!

     
  • Adeena
    Adeena
    2012-01-18

    Hi!

    The problem is that after this category executes:
    <topic name="translate">
    <category>
    <pattern>*</pattern>
    <template>OK, I translate <translate><star/></translate></template>
    </category>
    </topic>

    You still have your topic set to translate.

    I recommend changing that category to this:
    <topic name="translate">
    <category>
    <pattern>*</pattern>
    <template>OK, I translate <translate><star/></translate></template>
                    <think><set name="topic"></set></think>
    </category>
    </topic>

    That should work.

    -Adeena
    riotsw.com

     
  • hokascha
    hokascha
    2012-01-18

    Hi!

    Thanks Adeena, but the category inside the topic-tags isn't even executed, when the user says something that matches outside, like I showed in my last example.

    Kevin

     
  • Anne Kootstra
    Anne Kootstra
    2012-01-18

    The pattern matching algorithm in the AIML interpreter processes the input as a single string: PATTERN <that> THAT <topic> TOPIC. During pattern matching of the string there is and order of preference:

    1. _ <that> THAT <topic> TOPIC
    2. WORD <that> THAT <topic> TOPIC
    3. WORD * <that> THAT <topic> TOPIC
    4. * WORD <that> THAT <topic> TOPIC

    However, it is possible to use the _ to capture all the input when the topic is active.

    <topic name="translate">
    <category>
    <pattern>_</pattern>
    <template>OK, I translate <translate><star/></translate></template>
    </category>
    </topic>

    Kind regards,

    Anne

     
  • hokascha
    hokascha
    2012-01-18

    Anne, thanks a lot, this works perfectly. Looks like I am on a good way to understand the "_" wildcard ;-) One more question. Now that I can capture all input, how can I capture all input that is *not* defined in the current topic? Like this:

    <topic name="yes_no">
        <category>
            <pattern>YES</pattern>
            <template>you said yes.<settopic></settopic></template>
        </category>
        <category>
            <pattern>NO</pattern>
            <template>you said no.<settopic></settopic></template>
        </category>
        <category>
            <pattern>_</pattern>
            <template>Say yes or no!</template>
        </category>
    </topic>
    

    The conversation should loop inside the topic until the user says yes or no, no matter what patterns are defined outside the topic. Is this possible? My above example of course doesn't do this, because "_" always matches first.

    Best regards,

    Kevin

     
  • Anne Kootstra
    Anne Kootstra
    2012-01-20

    As you've notived, _ is greedy and will match before WORD. This is something that hard to overcome and as such the _ is only used in special circumstances. In most situations you will want to use * for the situation you are in.

    Kind regards,

    Anne

     
  • hokascha
    hokascha
    2012-01-21

    OK, so there's no way to catch all input that is not defined in the current topic? Because * doesn't match when the input is defined outside the current topic, it doesn't seem to be the solution here.

    Best regards,

    Kevin

     
  • Anne Kootstra
    Anne Kootstra
    2012-01-26

    You are right, the * inside a topic will be of no use to you when you have the same patterns outside the topic. You can see the order that I'd say all AIML interpreters/engines will adhere to.

       pattern | topic | that
    1.  _         |   *      |   *
    2. Word   |   *      |   *
    3.  *          | topic |   *
    4.  *          | *        |   *

    It is possible to have the effect you are looking for, but that means a fundamental shift in the way you write your AIML. It means that you prepend all patterns with their respective topic, and if a category has no topic, with a *. That way you can use the above principle to create the effect you need. Below is an example.

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <aiml version="1.0">
    <category>
        <pattern>*</pattern>
        <template>
            <srai>TOPIC <get name="topic"/> INPUT <star index="1"/></srai>
        </template>
    </category>
    <category>
        <pattern>TOPIC INPUT *</pattern>
        <template>
            Default No Topic Catch All: "<star index="1"/>".
                    <think><set name="topic">default</set></think>
        </template>
    </category>
    <category>
        <pattern>TOPIC * INPUT *</pattern>
        <template>
            Default Topic Catch All: "<star index="1"/>".
        </template>
    </category>
    <category>
        <pattern>SETTOPIC *</pattern>
        <template>
            SET TOPIC <set name="topic"><star index="1"/></set>.
        </template>
    </category>
    <category>
        <pattern>CLEARTOPIC</pattern>
        <template>
            Clear Topic <set name="topic"></set>.
        </template>
    </category>
    <category>
        <pattern>TRANSLATE</pattern>
        <template>
            Tell me the text you want to <set name="topic">translate</set>.
        </template>
    </category>
    <category>
        <pattern>TOPIC * INPUT HELLO</pattern>
        <template>
            Regular Hello "<star index="1"/>"
        </template>
    </category>
    <category>
        <pattern>TOPIC TRANSLATE INPUT *</pattern>
        <template>
            I want to translate: "<star index="1"/>".
        </template>
    </category>
    </aiml>
    

    Using the same principle you can create both examples: translate and YesNo you asked about.

    Kind regards

    Anne