Teneo Developers

Advanced Condition Coding

We have already seen the basics of Condition Syntax, but there is still plenty more that can be achieved with conditions. On this page, we will cover more advanced condition coding approaches together with some arguments on where to use which operator.

We will be going over the following topics:

Brackets ()

Teneo Engine has no built in order of evaluation of operators. Therefore, brackets must be used if the operator on the left side of an operand is different from the one on the right side.

( A & B ) / CA & B / C

Negations (!)

Negations should not be placed in a language object. An additional negation in a language condition could reverse the intended meaning of the condition.


Longest match (:L)

With the Longest match option (:L), the engine will return the match with the highest number of used words. When Teneo Engine evaluates an entity object, it applies the Longest match option by default. So if we have an entity that recognizes 'Pepsi' and 'Pepsi Cola' using two separate entries in the first column of the entity, and the user input contains the words 'Pepsi Cola', Teneo engine will match on entry 'Pepsi Cola' and not on 'Pepsi'.

Consider an example in which we have a language condition used to recognize destinations in user inputs: (%CITY.ENTITY/%COUNTRY.ENTITY).We could use this propagation script to extract the destination: (%CITY.ENTITY/%COUNTRY.ENTITY)^{sDestination = _USED_WORDS}.

When a user mentions 'Mexico City', the variable to extract the destination will contain 'Mexico'. By default, the engine would go for the shortest match. However, we could use the Longest match option to force the engine to look a bit further: ((%CITY.ENTITY/%COUNTRY.ENTITY)^{sDestination = _USED_WORDS}):L. With this option, the destination stored will be 'Mexico City'.

Mexico City(%CITY.ENTITY/%COUNTRY.ENTITY)^{sDestination = _USED_WORDS}Mexico
Mexico City((%CITY.ENTITY/%COUNTRY.ENTITY)^{sDestination = _USED_WORDS}):LMexico City

Optional match (:O)

In some cases, we may want to define optional elements in a condition.

In the condition A >> ( B ):O >> C, 'B' is optional. This will trigger inputs 'A C' or 'A B C', but not 'A F C'. Note that round brackets are used to delimit the optional word(s). The 'O' may be uppercase or lowercase.

For example, let's say we want to capture inputs like 'Add (a) (new) reminder':

( (add/create/set/(set>>up)) >> (a):O >> (new):O >> reminder )

Other examples:

  • To recognize the Renault Scenic or the Renault Grand Scenic: renault >> (grand):O >> scenic
  • To recognize Buzz Lightyear, a.k.a. Buzz: buzz>>(lightyear):O

MAYBE operator (~)

With the MAYBE operator, the word(s) following the operator may be in the user input, but is not mandatory.

Bear in mind that the MAYBE operator always works on the entire user input. It cannot be made to work on just a part of the user input, e.g. by using the + operator first. The MAYBE operator should not be used inside a language object; it is a logical operator, and works on the entire user input. The operator works repeatedly on its operands if the same word is available multiple times in the user input.

Example use case 1: We expect a predictable user input that might contain a small number of extra words.

  • We are in the context of space flight information.
  • We want to recognize inputs like 'and what about Pluto' or 'and for Pluto'.
  • We don't want to recognize an input like 'What is the circumference of Pluto'.
  • This condition would work (with unrecognized words set to 0): %PLANETS.LIST ~ (what / about / and / for)

Example use case 2: We want to extract an unpredictable user input after eliminating stop words.

  • We asked the user for their name.
  • We don't know how long their name will be.
  • They might answer with 'My name is …'.
  • This condition would work: %TRUE.SCRIPT ~ (my/the/it/name/is)
%TRUE.SCRIPT ~ (my/the/it/name/is)%TRUE.SCRIPT & (my/the/it/name/is)

MAYBE operator vs Optional match

The MAYBE operator 'scans' the entire user input. It will use all the words in the user input that match its right-hand operand, even if there are multiple matches in the user input.

The Optional match option will use the minimum number of words that are optional. Even when combined with the Longest match option, Optional match will only use the first occurrence of an optional word in the user input. Also, when optional words are separated by the OR operator, only the left-most word matching in the user input will be used by the Optional match option.

Consider the following example condition: %PLANETS.LIST~(and/what/about). This condition will match all words in user inputs 'and what about pluto', 'and pluto', 'what about pluto', 'pluto'. You may think you can achieve the same by using this condition: %PLANETS.LIST & ((and):o>>(what):o>>(about):o):L. However, that would get very messy soon if many permutations of the optional words have to be accounted for. And if you try to make the condition more 'flexible' by applying the OR operator to separate the optional words, you will find that only one of the optional words will be used, even when you apply the Longest match option as well.

Anchoring a condition to beginning or end

In some cases, we may want a condition to specify the first or last word in an input. When using language objects, certain words can be anchored to the beginning or end as follows:


When using raw text rather than language objects, we can anchor a one word condition to the beginning of an input like so: Hello:1. This 'position option', in this case ':1', only works with raw text.

Extended AND operators

When required in more complex conditions, the AND operator can be extended in the following ways.

Different match (&^)

With this operator, the left- and right-hand operands cannot match on the same words in the user input.

To understand how exactly this works in practice, consider the following use case: we want to recognize user inputs like 'I want to send something by boat'. Using the regular AND operator, our condition might look something like %I_WANT.PHR & %SEND.VB.SYN & %BOAT.NN.SYN. However, the AND operator would fall short here, because this condition would match the input 'I want the ship to sail today', because the word 'ship' matches both BOAT.NN.SYN and SEND.VB.SYN.

This is where the different match operator comes into play. The above condition can easily be rewritten to be more accurate: %I_WANT.PHR &^ %SEND.VB.SYN &^ %BOAT.NN.SYN.


Same match (&=)

With this operator, both operands must match in the user input and they must match on the exact same word(s). This is particularly useful if we want a linguistic match plus a POS tagger annotation to be true on the same word(s).

For example, say we want to match on the verb 'to cancel' (or a synonym) but only if it is in the past tense: %CANCEL.VB.SYN &= %MST_PAST.ANNOT. This would recognize input such as 'I cancelled my flight' or 'Why have you cancelled my subscription', but not input like 'I want to cancel my flight' or 'I am cancelling my subscription'.


In this other example, inputs must match the condition on both sides of the operator: (%CITIES_SWEDEN.LIST &= %AIRLINE_DESTINATIONS.LIST). This condition matches all airline destinations in Sweden.

Not same match (!&=)

This operator allows you to negate on the words matched by the first operand. Whereas standard negation works on the entire input, not same match works on words matched by the first operand.

For example, let's say we want to recognize user inputs containing two fruits, one of which should be an apple: (%FRUIT.LIST !&= %APPLE.NN.LEX) &^ %APPLE.NN.LEX. This would match input like 'I like apples and bananas', but not 'I like green apples and red apples'.


Smaller match (&<)

With smaller match, the matched words of the left-hand operand are a minority subset of the matched words of the right-hand operand. In other words, if we have a condition specifying X &< Y, the smaller match of X (a minority of the words in X) must match with Y.

For example, this condition matches the subset of all cars containing the subset 'hybrid': (hybrid <& %ALL_CARS.LIST). This condition would match inputs like 'Honda Accord Hybrid' or 'Ford Fusion Hybrid'.

(hybrid <& %ALL_CARS.LIST)(%ALL_CARS.LIST <& hybrid)

Bigger match (&>)

With bigger match, the matched words of the right-hand operand are a majority subset of the matched words of the left-hand operand. In other words, if we have a condition specifying X &&rt; Y, the bigger match of Y (a majority of the words in Y) must match with X.

For example, this condition matches the subset of music artists whose names include 'James': (%MUSIC_ARTISTS.LIST &> james). This matches inputs like 'Rick James', 'James Brown', and 'James'.


Not smaller match (!&<)

With this operator, the matched words of the left-hand operand should not be a subset of the matched words of the right-hand operand.

For example, if we want to match 'more than' but we don't want to match 'not more than', we could use this operator in a condition like this' (more >> than) !&< (not>>more>>than). Note that, if you look at the example, this operator makes it possible to code a 'not directly preceded by' condition.

(more >> than) !&< (not>>more>>than)(more >> than) !&> (not>>more>>than)

Not bigger match (!&>)

With this operator, the left-hand operand must match the user input. In addition, the matched words should NOT match the right-hand operand. This operator allows you to put a constraint on the word matched by the left-hand operand. This is useful when the left-hand operand matches on multiple words in the user input (e.g. containing PHR language object).

For example, let's say we want to match on user inputs about renting a room, but not when they talk about subletting a room: (%HOW_DO_I_RENT.PHR !&> %SUBLET.VB.LEX) &^ %ROOM.NN.LEX.


In another example, we want to recognize an order for a product but not if it includes colors: (%I_NEED.PHR >> %NUMBERS.LIST >> * >> %MY_PRODUCTS.LIST) !&> %COLORS.LIST.