3.1. Natex

Several matching strategies built in Natex.

Emora STDM supports several ways for interpreting the contexts of user inputs through Natex (Natural Langauge Expression), some of which you already experienced in Matching Strategy.

Literal

A literal is what you intend the system to say. A literal is represented by reversed primes (`..`):

transitions = {
    'state': 'start',
    '`Hello. How are you?`': 'end'  # literal
}
  • #3: the system prompts the literal and ends the dialogue.

S: Hello. How are you?

Matching

Natex supports several ways of matching the input with key terms.

Term

The condition is true if the input exactly matches the term. A term is represented as a string and can have more than one token:

transitions = {
    'state': 'start',
    '`Hello. How are you?`': {         # literal
        'could be better': {           # term
            '`I hope your day gets better soon :(`': 'end'
        },
        'error': {
            '`Sorry, I didn\'t understand you.`': 'end'
        }
    }
}
  • #4: matches the input with 'could be better'.

  • #7: error is a reserved term indicating the default condition of this conditional branching, similar to the wildcard condition (_) in a match statement.

S: Hello. How are you?
U: Could be better..
S: I hope your day gets better soon :(

Set

The condition is true if the input exactly matches any term in the set. A set is represented by curly brackets ({}):

transitions = {
    'state': 'start',
    '`Hello. How are you?`': {         # literal
        'could be better': {           # term
            '`I hope your day gets better soon :(`': 'end'
        },
        '{good, not bad}': {           # set
            '`Glad to hear that you are doing well :)`': 'end'
        },
        'error': {
            '`Sorry, I didn\'t understand you.`': 'end'
        }
    }
}
  • #7: matches the input with either 'good' or 'not bad'.

S: Hello. How are you?
U: Good!!
S: Glad to hear that you are doing well :)

Unordered List

The condition is true if some terms in the input match all terms in the unordered list, regardless of the order. An unordered list is represented by angle brackets (<>):

transitions = {
    'state': 'start',
    '`Hello. How are you?`': {         # literal
        'could be better': {           # term
            '`I hope your day gets better soon :(`': 'end'
        },
        '{good, not bad}': {           # set
            '`Glad to hear that you are doing well :)`': 'end'
        },
        '<very, good>': {              # unordered list
            '`So glad that you are having a great day!`': 'end'
        },
        'error': {
            '`Sorry, I didn\'t understand you.`': 'end'
        }
    }
}
  • #10: matches the input with both 'very' and 'good' in any order.

S: Hello. How are you?
U: Very good!
S: So glad that you are having a great day!

Ordered List

The condition is true if some terms in the input match all terms in the ordered list, a.k.a. sequence, in the same order. An ordered list is represented by square brackets ([]):

transitions = {
    'state': 'start',
    '`Hello. How are you?`': {         # literal
        'could be better': {           # term
            '`I hope your day gets better soon :(`': 'end'
        },
        '{good, not bad}': {           # set
            '`Glad to hear that you are doing well :)`': 'end'
        },
        '<very, good>': {              # unordered list
            '`So glad that you are having a great day!`': 'end'
        },
        '[so, good]': {                # ordered list (sequence)
            '`Things are just getting better for you!`': 'end'
        },
        'error': {
            '`Sorry, I didn\'t understand you.`': 'end'
    }
}
  • #13: matches the input with both 'so' and 'good' in that order.

S: Hello. How are you?
U: So good!
S: Things are just getting better for you!

Currently, it matches the input "could be better" with the condition in #4, but does not match "it could be better" or "could be better for sure", where there are terms other than the ones indicated in the condition.

  1. Update the condition such that it matches all three inputs.

  2. How about matching inputs such as "could be much better" or "could be really better"?

Rigid Sequence

The condition is true if all terms in the input exactly match all terms in the rigid sequence in the same order. A rigid sequence is represented by square brackets ([ ]), where the left bracket is followed by an exclamation mark (!):

transitions = {
    'state': 'start',
    '`Hello. How are you?`': {         # literal
        'could be better': {           # term
            '`I hope your day gets better soon :(`': 'end'
        },
        '{good, not bad}': {           # set
            '`Glad to hear that you are doing well :)`': 'end'
        },
        '<very, good>': {              # unordered list
            '`So glad that you are having a great day!`': 'end'
        },
        '[so, good]': {                # ordered list (sequence)
            '`Things are just getting better for you!`': 'end'
        },
        '[!hello, world]': {           # rigid sequence
            '`You\'re a programmer!`': 'end'
        },
        'error': {
            '`Sorry, I didn\'t understand you.`': 'end'
        }
    }
    }
}

#16: matches the input with both 'hello' and 'world' in that order.

S: Hello. How are you?
U: Hello World
S: You're a programmer!

There is no difference between matching a term (e.g., 'hello world') and matching a rigid sequence (e.g., '[!hello, world]'). The rigid sequence is designed specifically for negation, which will be deprecated in the next version.

Negation

The condition is true if all terms in the input exactly match all terms in the rigid sequence except for ones that are negated. A negation is represented by a hyphen (-):

transitions = {
    'state': 'start',
    '`Hello. How are you?`': {         # literal
        'could be better': {           # term
            '`I hope your day gets better soon :(`': 'end'
        },
        '{good, not bad}': {           # set
            '`Glad to hear that you are doing well :)`': 'end'
        },
        '<very, good>': {              # unordered list
            '`So glad that you are having a great day!`': 'end'
        },
        '[so, good]': {                # ordered list (sequence)
            '`Things are just getting better for you!`': 'end'
        },
        '[!hello, world]': {           # rigid sequence
            '`You\'re a programmer!`': 'end'
        },
        '[!-not, aweful]': {           # negation
            '`Sorry to hear that :(`': 'end'
        },
        'error': {
            '`Sorry, I didn\'t understand you.`': 'end'
        }
    }
}
  • #19: matches the input with 'aweful' and zero to many terms prior to it that are not 'not'.

S: Hello. How are you?
U: Aweful!
S: Sorry to hear that :(

Nesting

It is possible to nest conditions for more advanced matching. Let us create a term condition that matches both "so good" and "very good" using a nested set:

transitions = {
    'state': 'start',
    '`Hello. How are you?`': {
        '{so, very} good': {
                '`Things are just getting better for you!`': 'end'
            },
        'error': {
            '`Sorry, I didn\'t understand you.`': 'end'
        }
    }
}
  • #4: uses a set inside a term.

Does this condition match "good"?

However, it does not match when other terms are included in the input (e.g., "It's so good to be here"). To broaden the matching scope, you can put the condition inside a sequence:

transitions = {
    'state': 'start',
    '`Hello. How are you?`': {
        '[{so, very} good]': {
                '`Things are just getting better for you!`': 'end'
            },
        'error': {
            '`Sorry, I didn\'t understand you.`': 'end'
        }
    }
}
  • #4: the term condition is inside the sequence.

What if we want the condition to match the above inputs as well as "fantastic"? You can put the condition under a set and add fantastic as another term:

transitions = {
    'state': 'start',
    '`Hello. How are you?`': {
        '{[{so, very} good], fantastic}': {
                '`Things are just getting better for you!`': 'end'
            },
        'error': {
            '`Sorry, I didn\'t understand you.`': 'end'
        }
    }
}
  • #4: the sequence condition and the new term fantastic is inside the set.

S: Hello. How are you?
U: I'm very good, thank you!
S: Things are just getting better for you!

The above transitions match "Fantastic" but not "It's fantastic". Update the condition such that it can match both inputs.

Variable

Saving user content can be useful in many ways. Let us consider the following transitions:

transitions = {
    'state': 'start',
    '`What is your favorite animal?`': {
        '[{dogs, cats, hamsters}]': {
            '`I like them too!`': 'end'
        },
        'error': {
            '`I\'ve never heard of that animal.`': 'end'
        }
    }
}
S: What is your favorite animal?
U: I like dogs
S: I like them too!

Users may feel more engaged if the system says, "I like dogs too" instead of "them". Natex allows you to create a variable to store the matched term. A variable is represented by a string preceded (without spaces) by a dollar sign $:

transitions = {
    'state': 'start',
    '`What is your favorite animal?`': {
        '[$FAVORITE_ANIMAL={dogs, cats, hamsters}]': {
            '`I like` $FAVORITE_ANIMAL `too!`': 'end'
        },
        'error': {
            '`I\'ve never heard of that animal.`': 'end'
        }
    }
}
  • #4: creates a variable FAVORITE_ANIMAL storing the matched term from the user content.

  • #5: uses the value of the variable to generate the follow-up system utterance.

In #5, two literals, `I like` and `too!` surround the variable $FAVORITE_ANIMAL. If a variable were indicated inside a literal, STDM would throw an error.

S: What is your favorite animal?
U: I like dogs!!
S: I like dogs too!

Last updated

©2023 Emory University - All rights reserved