Teneo Developers

Condition Syntax Reference

A language condition specifies patterns that need to be present in a user input for the condition to be fulfilled. Depending on where the condition is used, a match may result in a flow being triggered, a transition being selected, or a listener being applied.

There are two types of conditions: atomic conditions, which can be used on their own, and complex conditions, which are a combination of one or more conditions and an operator.

Atomic Conditions

The smallest building block of a condition is an atomic condition. The different types of atomic conditions are:

  • Word Conditon
  • Word Part Condition
  • Language Object Condition
  • Annotation Condition
  • Script Condition

Word Condition

A word condition simply specifies a word that needs to be present in the user input.

ConditionMatched user inputUnmatched user input
loveloveloves
I love tofuHe loves me

Word Part Condition

A word part condition specifies a part of a word that needs to be present in the input. A wildcard (*) is added at the beginning and/or end of the word, and means that the word may contain any number of other characters at that point.

The wildcard may also be used by itself to represent a single word.

ConditionMatched user inputUnmatched user input
love*loverbeloved
lovedglove
ConditionMatched user inputUnmatched user input
*loveglovelover
cloveclover
lovebeloved
ConditionMatched user inputUnmatched user input
*love*belovedluv
clover
love
ConditionMatched user inputUnmatched user input
I + love + *I love tofuI love
I love catsIt's you who I love
I love martial arts

Language Object Condition

A language object condition specifies a language object that needs to match the user input. If we have a language object named 'FRUITS.LIST' with a condition like: (banana/apple/pear) the following applies:

ConditionMatched user inputUnmatched user input
%FRUITS.LISTbananacucumber
May I have an apple?May I have a tomato?

Language objects are themselves containers of language conditions. They are described at more length here.

Annotation Condition

An annotation condition specifies a label that a word (or sequence of words) must have been annotated with. An annotation condition is thus not applied to the input words themselves, but to annotation labels. Teneo comes with several different annotators:

  • a Part of Speech tagger that annotates each word in the input with its Part of Speech,
  • a set of Named Entity Recognizers that annotate words (or word sequences) as persons, locations, or similar,
  • a Language Detector that annotates each sentence with the language it is written in.

A full list of all annotations and entities can be found in the Annotations Reference.

Conditions are used on annotation labels the same way they are used on language objects; it's just the prefix that looks slightly different. An annotation label should be prefixed with %$.

ConditionMatched user inputUnmatched user input
%$LOCATION.NERBerlinapp
open Berlin on a mapopen my favorite app

Script Condition

You may use a Groovy script as a condition. It needs to be embraced with curly brackets ({ ... }). For a Script condition to be fulfilled, the result of the expression evaluation has to have a Boolean value of true. If the result type is not a Boolean, then it is converted to Boolean according to Groovy’s type conversion rules.

ConditionMatched user inputUnmatched user input
{ coffeeTypeInFocus == 'espresso' }The variable 'coffeeTypeInFocus' has the value 'espresso'. The input words are irrelevant.The variable 'coffeeTypeInFocus' does not have the value 'espresso'. The input words are irrelevant.

Basic operators

You can combine conditions with operators to form more complex conditions. In this section we'll go through the most commonly used, basic operators.

Note that a complex condition may in turn be combined with another condition, to form another complex condition. You then use brackets to show how the condition should be read:

`( %I_LOVE.PHR / %I_LIKE.PHR ) + %ANIMALS.LIST`

OR ( / )

When conditions are combined with the OR-operator (/), at least one of them needs to match the input.

ConditionMatched user inputUnmatched user input
dog / cat / hamster / parakeet / goldfishI have a dogI don't like cats or dogs
I used to have a cat
I don't have a parakeet

AND ( & )

Conditions that are combined with the AND-operator (&) must all match the input. The AND-operator does not require the words in the input to appear in a certain order.

ConditionMatched user inputUnmatched user input
I & love & youI love youeveryone loves you
you are the person whom I love

FOLLOWED BY ( + )

Conditions that are combined with the FOLLOWED BY-operator (+) must all match the input, in the order stated. The operator is a good choice for word combinations whose sense would shift if the word order were rearranged.

ConditionMatched user inputUnmatched user input
John + loves + AnnaJohn loves AnnaAnna loves John
John really loves his girlfriend Anna

DIRECTLY FOLLOWED BY ( >> )

Conditions combined with the DIRECTLY FOLLOWED BY-operator (>>) must all match the input, in the order stated. There may not come any words between the matches.

ConditionMatched user inputUnmatched user input
I >> love >> youI love youI don't love you.
I love you now and always!I said he'll always love you

NOT DIRECTLY FOLLOWED BY ( !>>)

When two conditions are combined with the NOT DIRECTLY FOLLOWED BY-operator (!>>), the left side condition must match the user input, and the right side condition must NOT match the words immediately following the first match.

The right side condition does not have to match anything in the input, it's merely restricting the left side condition.

In this example we're looking for inputs containing the word 'call' not directly followed by 'you'.

ConditionMatched user inputUnmatched user input
call !>> youI want to call JohnI want to call you John
I want you to make a call

NOT (!)

The NOT-operator (!) takes only one condition, and states that whatever is specified in that condition must not match the user input.

ConditionMatched user inputUnmatched user input
!catI have a dogI don't have a cat
I love catsAre you a cat?
ConditionMatched user inputUnmatched user input
(I+love+you) & !(%DO_NOT.VB.MUL)I love youI don't love you

COMPOUND ( | )

The COMPOUND-operator (|) allows compound words to be written in a variety of ways: as one word, with a hypen or with a blank. The COMPOUND-operator can only be used to combine atomic word conditions. This means that a condition like %LANGUAGE_OBJECT|%LANGUAGE_OBJECT is syntactically wrong.

ConditionMatched user inputUnmatched user input
doghouseWe have a doghouse
We have a dog-house
We have a dog house

§ can be used as an alternative for | compound.

Extendend AND-operators

Extended AND-operators are different variations of the AND-operator. Just as for the basic AND-operator (&), both the left side condition and the right side condition must match the user input.

In addition, they impose some restrictions on the words (or corresponding annotations) that these conditions have been applied to. For example, when using the SAME MATCH-operator (&=) the conditions must have been applied to the same part of the input, whereas, for the DIFFERENT MATCH-operator (&^), the conditions must have been applied to different parts of the input.

In the example below, apple is part of both the language objects FRUITS.LIST and COMPANY_NAMES.LIST:

ConditionMatched user inputUnmatched user input
%COMPANY_NAMES.LIST &= %FRUITS.LISTapplemicrosoft banana
%COMPANY_NAMES.LIST &^ %FRUITS.LISTmicrosoft bananaapple
apple apple

DIFFERENT MATCH ( &^ )

The DIFFERENT MATCH-operator (&) is conceptually very similar to the basic AND-operator. The only difference is that the left side condition and the right side condition must have been applied to different parts of the input (for the basic AND-operator that does not have to be the case).

In the example below, we want to make sure there are two cities mentioned in the input (if we would have used the basic AND-operator a single mention would have satisfied both conditions).

ConditionMatched user inputUnmatched user input
%CITIES.LIST &^ %CITIES.LISTBerlin ParisBerlin

SAME MATCH ( &= )

When you combine two conditions with the SAME MATCH-operator (&=), both conditions need to match the input. In addition, these conditions must have been applied to the same words (or corresponding annotations) in the input.

This operator is particularly useful when you want to constrain both the word itself, and the annotation it's been annotated with. In this example we're looking for a synonym of the word buy (%BUY.VB.SYN) that is annotated as past tense (%$PAST.POS).

ConditionMatched user inputUnmatched user input
%BUY.VB.SYN &= %$PAST.POSI bought a t-shirtI'd like to buy a t-shirt
I have purchased a sweaterI want to purchase a sweater

Here we're looking for something that both matches a list of German cities, and a list of airline destinations (this particular airline does fly to Berlin, but not to Hannover).

ConditionMatched user inputUnmatched user input
%CITIES_GERMANY.LIST &= %AIRLINE_DESTINATIONS.LISTA ticket to Berlin pleaseI want to go to Paris please.
Take me to Hannover please.

BIGGER MATCH ( &>)

When you combine two conditions with the BIGGER MATCH-operator (&>), both conditions need to match the input. In addition, the left side condition must have been applied to all the words (or annotations at the corresponding positions) of the right side condition, and possibly some more. In other words, the match of the right side condition must be fully contained in the match of the left side condition.

This operator is particularly useful when you want to limit the scope of a list to only cover items that contain a specific word. In this example we're looking for printers that are both listed among the supported ones and contain the string 'epson' in their names.

ConditionMatched user inputUnmatched user input
%SUPPORTED_PRINTERS.LIST &> epsonI need the documentation for Epson 202XWhere do I download a driver for HP 202XXL?
Where do I download a driver for Epson SSLX?

Here we're looking for car brands that contain the word 'hybrid'.

ConditionMatched user inputUnmatched user input
%CAR_BRANDS.LIST &> hybridHonda Accord HybridSubaru Forrester
Ford Fusion Hybrid

SMALLER MATCH ( &< )

When you combine two conditions with the SMALLER MATCH-operator &<, both conditions need to match the input. In addition, the match of the left side condition must be fully contained in the match of the right side condition. The right side match may contain also other words/annotations.

The example below matches American cities that are mentioned as parts of movie titles.

ConditionMatched user inputUnmatched user input
%CITIES_USA.LIST &< %MOVIE_TITLES.LISTThe movie Fear and Loathing in Las VegasI like going around loathing in Las Vegas
Have you ever seen Escape from New York?The Lord of the Rings is a great film

OVERLAP MATCH ( &~ )

When you combine two conditions using the OVERLAP MATCH-operator &~, the conditions on the left and right must share at least one used word. You could use this to require an optional condition part on the left side of the condition to be present. This can be useful if the optional condition is part of a referenced language object.

This example shows how you might use a list of US states to catch that users are referring to a state university.

ConditionMatched user inputUnmatched user input
(alaska / california / ohio)>>(state):O) &~ stateI attend Ohio StateI live in Ohio
California State has a great football teamHollywood is in the state of California

Negated AND-operators

Negated AND-operators are useful when you want to specify something to be matched, and then add a constraint on that match.

Common to all negated AND-operators is that they consist of a left side condition that MUST match the input and a right side condition that impose some kind of restriction on that match — something that may NOT match all, a subset, or a superset of those words.

NOT SAME MATCH ( !&= )

When you combine two conditions with the NOT SAME MATCH-operator (!&=), the left side condition must match the input. The right side condition specifies something that must NOT match those exact same words (or their annotations).

You can thus use this operator when you're looking for something that SHOULD match on something particular, but SHOULD NOT match on something different.

In this example, we're looking for a European city that is not a German city (i.e. any non-German European city).

ConditionMatched user inputUnmatched user input
%CITIES_EUROPE.LIST !&= %CITIES_GERMANY.LISTI want to go to ParisI want to go to Berlin
I want to go to Paris from Berlin

Here the user input should contain the word 'play' not annotated as a noun:

ConditionMatched user inputUnmatched user input
play !&= %$NN.POSI want to play some musicI am going to see a play in the theater
I want to play in a play

Finally, in this example, any word normalized to meta matches, except when it's written exactly as Metà (more on the Exact option (:E) here) :

ConditionMatched user inputUnmatched user input
meta !&= Metà:EIt is a meta questionWe attended the Metà conference
It is a META question

NOT BIGGER MATCH ( !&> )

When you combine two conditions with the NOT BIGGER MATCH-operator (!&&g;) the left side condition must match the input. The right side condition specifies a constraint on that match — it specifies something that may NOT be part of that match.

You can thus use this operator when you want to restrict the coverage of a language object. In this example we want to match variations of how do I install, but we want to exclude variations that contain the word add.

ConditionMatched user inputUnmatched user input
%HOW_DO_I_INSTALL.PHR !&> %ADD.VB.LEXHow do I install the driver?How can I add this gizmo?
Can you help me installing the app?

This example will match as long as what is matched by * isn’t also matched by COLORS.LIST.

ConditionMatched user inputUnmatched user input
(%I_NEED.PHR >> %NUMBERS.LIST >> * >> %MY_PRODUCTS.LIST) !&> %COLORS.LISTI need 5 new bracketsI need five green brackets
I really need 7 new shelves

NOT SMALLER MATCH ( !&< )

When you combine two conditions with the NOT SMALLER MATCH-operator (!&<), the left side condition must match the input. The right side condition specifies a constraint on that match — it specifies a condition that must NOT generate a match that fully contains the first match.

You can thus use this operator when you want to constrain the context of a match. In this example we're looking for the phrase more than but we want to disqualify any match that is part of the longer phrase no more than.

ConditionMatched user inputUnmatched user input
(more>>than) !&< (no>>more>>than)A word with more than ten lettersA word with no more than ten letters

Here we're looking for matches of I like, but we want to disregard matches that also contain don't.

ConditionMatched user inputUnmatched user input
(I + like) !&< (I + %DO_NOT.MUL + like)I really like all vegetablesI don't like vegetables

In this example, we're looking for the word nice when not preceded by to, via, or from:

ConditionMatched user inputUnmatched user input
nice !&< (( to/via/from) >> nice)Such a nice day!I go via Nice
So nice to see you!I fly out from nice.

NOT OVERLAP MATCH ( !&~)

When you combine two conditions with the NOT OVERLAP MATCH-operator (!&~), the left side condition must match the user input. The right side condition specifies a restriction on that match — it specifies something it may not overlap with.

You can thus use this operator when you want to constrain the context of a match. In this example, we're looking for the phrase can you close but we want it to be disqualified if it's overlapping with a match of why can.

ConditionMatched user inputUnmatched user input
(can + you + close ) !&~ (why + can )Can you close an accountWhy can you close an account

Here we're looking for phrases like are you angry but want to keep out inputs like are you making me angry :

ConditionMatched user inputUnmatched user input
( %ARE_YOU.PHR + %ANGRY.ADJ.SYN) !&~ (me >> %ANGRY.ADJ.SYN)Are you angry now?Why are you making me angry?

Limit unused words

Normally, a language condition only specifies which words must be present in an input. There may be other words in the input not accounted for by the condition, and the input will still satisfy the condition.

With 'Limit unused words' you can add restrictions on how many words besides those specified in the condition may be present in the user input. The option is available with a Conditional Match Requirement, under the 'Condition' panel inside 'Advanced Options'.

In the example below, we are looking for inputs that don't contain any words other than how are you.

ConditionUnused word limitMatched user inputUnmatched user input
how + are + you0How are you?How are you removing an item?
How are you doing?

Here we allow one unused word to appear:

ConditionUnused word limitMatched user inputUnmatched user input
how + are + you1How are you?How are you removing an item?
How are you doing?How are you doing dear?

MAYBE option (~)

The MAYBE-operator (~) allows you to specify words that may appear in the input, but don't have to. These words won't count as unused words. They may appear any number of times and still not count.

ConditionUnused word limitMatched user inputUnmatched user input
(how+are+you) ~(doing/feeling/dear/%HI.PHR)0How are you?How are you removing an item?
Hi dear, how are you doing?
Hi, hi, hi, how are you doing?

In the example below we are looking for inputs where the user asks for the price of something we've just talked about, e.g. What's the cost? or How much is it?. We want to exclude inputs where the user is asking for the price of some new referent, e.g. How much is the espresso?. We will thus limit the number of unused words to 0 and use the MAYBE-operator to specify that other words may be part of the input, as long as they are not annotated as nouns.

ConditionUnused word limitMatched user inputUnmatched user input
%WHAT_IS_THE_PRICE_OF.PHR ~ ( * !&= %$NN.POS )0How much is it?How much is an espresso?
What is the cost then?What is the cost of the ticket
What is the cost?The new iPhone, what is the cost of it?

The MAYBE-operator will always be applied to the full input, and allow any number of the specified words to appear in the input. It can't be used to specify optional elements at specific positions; for that, you should use the Optional Match option.

In short, the MAYBE-operator should only be used in conjunction with Limit unused words. For all other use cases, use the Optional Match option instead.

Optional Match option (:O)

When attaching the Optional Match option ( :O) to an element of a condition, it lets the enclosed atomic or complex condition become an optional part of the surrounding condition, hence the element doesn't have to match the input for the condition to be fulfilled, but it may.

Please note that the Optional Match option is only applicable to bracketed conditions.

ConditionMatched user inputUnmatched user input
I >> (really):O >> like >> youI like youI sometimes like you
I really like youI really really like you
I >> (will>>always):O + like + youI like youI will like you
I will always like youI always like you

In the example below we use the Optional Match option to set the variable 'milk' when appropriate:

ConditionMatched user inputUnmatched user input
%ESPRESSO.NN.LEX & (with>>milk):O^{ milk = 'yes' }an espresso with milk please'yes'
an espresso please''

Position option

The Position Option (:<sentence_position>) can be applied to a word condition or a word part condition. For the constrained condition to be fulfilled, the word must appear in the user input at the specified position in the sentence. The first word in the sentence has position 1. A position relative to the sentence end may be specified by giving a negative number; the last word on the sentence has position -1. Note that position value 0 is invalid.

ConditionMatched user inputUnmatched user input
play:1play a songI saw a play
play the track pleaseyou play it too loud
who >> are >> you:-1who are youwho are you talking to

Exact option (:E)

Generally, condition matching is case-insensitive. But when you use the Exact Option (:E), the word must appear in the input exactly as written in the condition; thus no normalization, spelling tolerance, auto-correction, or simplification is applied.

Please note:

  • The Exact Option may only be applied to words or word part conditions. This means that a condition like %LANGUAGE_OBJECT:E is syntactically wrong.
  • The Exact Option is not applicable to bracketed conditions: a condition like (one/two):E has invalid syntax and should be written as (one:E/two:E)
ConditionMatched user inputUnmatched user input
horse:EhorseHorse
hoarse
*house:EboathouseBOATHOUSE
DogHouse
Love*:ELovedloved
beloved

Longest Match option (:L)

The Longest Match option offers additional fine-tuning useful when working with used words or attached scripts. When testing your bot and conditions, Teneo tries to be as efficient as possible. If a match for an input is found, the condition is considered to be true, and processing continues with the next steps. It usually does not matter if a condition could have been true in many different ways. However, there are special cases where it is necessary to know which parts of a user input triggered the condition. If we care about the used words or have attached scripts to parts of our condition, we want Teneo to find the most precise or longest match for that input. The longest match becomes important whenever we can have overlapping entities, that is, a multiple word entity which contains a word or words that are entities themselves. If a shorter match is chosen, we lose the additional information.

When attaching the Longest Match option (:L) to an element of a condition, it forces the enclosed atomic or complex condition to be true for the match using the most words possible.

Please note that the Longest Match option only is applicable to bracketed conditions.

ConditionMatched user inputUnmatched user input
(york / (new>>york) ):LI want to book a flight to York.York
Can you recommend hotels in New York?New York
( (hbo>>2) / (hbo>>comedy) / (hbo>>family) / (hbo>>latino) / (hbo>>signature) / (hbo>>zone) / hbo):LI watch hbohbo
How can I subscribe to HBO comedy?HBO comedy

In this example we use Longest Match to assure the correct value is set to the variable 'country':

ConditionMatched user inputUnmatched user input
((porto>>novo)^{country="Benin"} / ((porto>>alegre)/(porto>>velho))^{country="Brazil"} / (porto/(porto>>de>>mós))^{country="Portugal"}):LWhere is Porto Novo located?'Benin'
Which country has a city called porto?'Portugal'

Predicate scripts

Predicate scripts allow you to add additional value-dependent constraints to a condition element based on NLU variables or annotations associated with the condition. Like propagation scripts, predicate scripts can be attached to bracketed condition parts, language objects, entities, and input annotations. If the predicate script is evaluated as false, the match is disregarded. The predicate script has access to NLU variables, input annotation variables, and used words of the associated object. It does not have access to flow or session variables and it cannot propagate values.

ConditionMatched user inputUnmatched user input
(*):{_USED_WORDS.toLowerCase() != "hello"}HiHello
Welcomehello
%ANIMALS.LIST:{lob.sAnimalType == "Pet"}CatTiger
DogWasp
%$NUMBER:{lob.numericValue > 100}13199
13000.4

Shortcuts

While working with conditions. There are some shortcuts inside Teneo that helps the developer to write its own conditions. They are as follows:

  • Ctrl + space - Auto complete the Language Object name, as seen here.
  • Alt + double click - Open Flow or Language Object in edit mode.
  • Alt + restart - Full engine restart, which is helpful when testing your newly created condition in Try Out.

Engine Access methods

Some other conditions that can be used as an additional is the engine access methods. These are as follows:

ConditionDescription
_.getUserInputText()Get full user input (string).
_getUserInputWords()Get user input (list).
_.getUsedWords(_.ORIGINAL)Get raw triggering words (list).
_.getUsedWords(_.SIMPLIFIED)Get processed triggering words (list).
_.getUsedWords(_.FINAL)Get final triggering words (list).
_.getNotUsedRawWords()Get words not triggering (list).
_.getLangObjVariable(‘x’)value of Language Object variable 'x'.
_.setSessVarLifespan(‘x’, 3)set life span of variable 'x'.
_.getThisFlow()Get the flow that was currently processed.
==Insert comments here==Comments made by the developer.