Constraint lists

A grammar will generally accept any utterance that it covers. However, what the caller says may not always make sense within the context. For example, the alphanum_lc built-in grammar may accept any alphanumeric string; but if you use it to recognize order numbers, it may accept order numbers that don’t actually appear in your database. If your grammar accepts such an invalid number, you’re effectively just wasting CPU resources until the error is discovered.

You can avoid this problem with a constraint list.

A constraint list is simple a text file (encoded as UTF-8) that contains allowed words and/or phrases. When the file is paired with a grammar, that grammar will reject results that aren’t explicitly defined in the constraint list.

The use of constraint lists is subject to a few limitations:

  • All values in the constraint list must be covered by the source grammar.
  • Grammars containing a constraint list cannot import other grammars.
  • You cannot use constraint lists with grammars that also use garbage rules (see the GARBAGE rule section under Special rules (NULL, VOID, and GARBAGE)).

You can import a grammar with a constraint list into any other grammar. This makes it possible to provide other rules before, after, or in parallel to the constraint list grammar.

Constraint file syntax

A constraint list contains alphabetic characters (for recognition purposes, upper and lowercase characters are the same).

  • Each entry must appear on a separate line, with no quotation marks.
  • Entries are limited to 20 words or 20 symbols (delimiters are ignored).
  • Accented characters (such as è) and the tilde character (~) are not allowed.
  • Non-alphanumeric characters such as dashes or spaces are ignored. Generally, they are not allowed, but can be allowed if accepted by the grammars being constrained.

Whitespace delimiters

By default, each character in a constraint entry is treated as a separate word regardless of whitespace. For example, if you want your list to recognize it when the caller says “Jay Ay Bee Five Oh One”, you can code it as either:

jab501

or as:

j a b 5 0 1

However, you can add an optional ::DELIMITED header in your file to indicate there are spaces between each element or word in each constraint.

For example, these constraint files are identical:

Space-delimited elements

No delimiters

::DELIMITED
j a b 5 0 1
f 4 5 h o 5
2 l p 4 k 6 k 2 k
jab501
f45ho5
2lp4k6k2k

However, in the first column you could put words instead of individual letters:

::DELIMITED
red yellow
blue red black
white black black

Delimiters are also useful when you need two characters to represent the pronunciation of a single character; for example, the “ch” letter in Spanish.

Adjusting weights of constraint entries

By default, all entries in the constraint file have equal probability for recognition. You can modify the relative weights by adding the ::WEIGHT parameter at the top of the file, and then appending a weight to each entry.

This feature is especially useful when some entries are more frequent then others, and you want to emphasize these entries. A higher weight makes the entry more easily recognized. For example:

::DELIMITED
::WEIGHT 10.0
j a b 5 0 1 2.0
f 4 5 h o 5 5.5
2 l p 4 k 6 k 2 k 10.0

The parameter format is:

::WEIGHTED max

The max value indicates the maximum expected value used for a weight in the subsequent entries.

When this parameter is present, every constraint entry must be followed by <space><float_number> where the number is a weight. The space is required even if ::DELIMITED is not used.

If any weight is non-numeric, the entries file will fail to load. If a weight is set greater than "max", the value of max is used and a warning is generated.

Mapping words to synonyms

You can map symbols in the constraint list to alternative synonyms. For example, the digit "0" can map to the word “oh” or “zero”.

To create a map, use the "mappings:" keyword between ::DELIMITED and the first constraint entry. For example:

::DELIMITED
mappings: 0 oh 0 zero 1 one 2 two 3 three 4 four 5 five 6 six 7 seven 8 eight 9 nine 
3 5 7 0
3 0 9 3

In this example, the digits are mapped to their word equivalents (all on a single "mappings:" line right after the ::DELIMITED header).

The maximum length of any single mapping line is 1024 characters. However, you can put mappings on more than one line in the file:

::DELIMITED
mappings: 0 oh 0 zero
mappings: 1 one 2 two 3 three
mappings: 4 four 5 five 6 six
mappings: 7 seven 8 eight 9 nine
3 5 7 0
3 0 9 3

Importing grammars with constraint lists

To import a grammar with a constraint list, use the SWI_param.constraintlist property in the grammar’s URI:

URI="myapp/alpha.grxml?SWI_param.constraintlist=myapp/list.txt"

Here, list.txt is the constraint list to be applied.

In addition, the constraint list can appear in a rule URI:

URI="myapp/alpha.grxml#alpharule?SWI_param.constraintlist=myapp/
list.txt"

To avoid confusion, do not provide constraint lists to both a parent and child grammar, as the parent grammar constraint list will overwrite the child constraint information.