Special rules
In addition to the rules you create, there are several reserved rules outlined in section 2.2.3 of the SRGS Specification. These rules dictate special behavior for the Speech Engine.
While helpful and functional, these rules should be considered best used either temporarily or as a last resort because they can negatively affect the processing during decodes. In almost every case, the same result that can be obtained through these special rules can also be achieved through programming.
These rules are:
- GARBAGE
- VOID
- NULL
In ABNF, the way to reference a special rule is to use $NAME where NAME is the name of the special rule, in all caps (e.g. $GARBAGE). In GrXML, special rules are referenced by <ruleref special="NAME" /> where NAME is the name of rule in all caps (e.g. <ruleref special="GARBAGE" />). Note that the attribute special is used with <ruleref> here instead of the normal uri attribute.
GARBAGE
The GARBAGE rule functions like a wild card. It filters out any words that are not matched by the other words within its rule and discards them.
You would only want to use it temporarily at best, as it can greatly increase the decode time. It should not be used to create a hot word or keyword spotting grammar - this will not work.
ABNF Example
#ABNF 1.0; language en-US; mode voice; root $yesorno; $yes = yes [please]; $no = no $GARBAGE; |
GrXML Example
<?xml version="1.0" encoding="UTF-8" ?> <grammar xmlns="http://www.w3.org/2001/06/grammar" xml:lang="en-US" root="yesorno" mode="voice"> <rule id="yesorno"> <one-of> <item><ruleref uri="#yes" /></item> <item><ruleref uri="#no" /></item> </one-of> </rule> <rule id="yes"> yes <item repeat="0-1">please</item> </rule> <rule id="no"> no <ruleref special="GARBAGE"/> </rule> </grammar> |
The above grammar would allow the user to say "no", "no, thank you", or "no, you stupid machine." All that would be returned would be the matched "no" rule. "Thank you", "you stupid machine" or anything else spoken after “no” would not be returned as part of the answer.
Note that engaging the out-of-vocabulary filter can slow down recognition times, and even cause additional misrecognitions if used too aggressively.
If possible, we recommend creating specific "filler entries” using grammar rules. These would match frequently occurring out-of-vocabulary words instead of using the GARBAGE rule. For example, it is often better to use a rule like:
ABNF Example
$no = no | no thank you | no you stupid machine; |
GrXML Example
<rule id="no"> <one-of> <item>no</item> <item>no thank you</item> <item>no you stupid machine</item> </one-of> </rule> |
...instead of the GARBAGE rule, assuming your users are frequently giving responses like the ones mentioned above.
This is because while you don’t need the filler words for your interpretation, they do actually add to the confidence of the match. “No” has the same interpretation as “no, thank you.” But when those filler words are matched, it increases the likelihood that the Engine has decoded the entire utterance correctly.
The GARBAGE rule is tempting because it would seem to alleviate the need to account for any number of possible words around those in your grammar. However, it also presents the possibility of getting false positive matches. This would be where a match is made incorrectly.
The reason for this is that if the GARBAGE rule matches anything around its grammar entry, it’s also possible that you’ll be matching entries in the GARBAGE rule when you don’t want to. See the example below:
ABNF Example - How NOT to Use the GARBAGE Rule!
#ABNF 1.0; language en-US; mode voice; root $yesorno; $no = no $GARBAGE; $dontknow = [I] don’t know | [I have] no idea; |
GrXML Example - How NOT to Use the GARBAGE Rule!
<rule id="no"> no <ruleref special="GARBAGE"/> </rule> <rule id="dontknow"> <one-of> <item> <item repeat="0-1">I</item> don't know </item> <item> <item repeat="0-1">I have</item> no idea </item> </one-of> </rule> |
In this example, the parse “no idea” is intended to match the dontknow rule, and it would. But in this case, it will also match the no rule, and probably return it as the first interpretation.
VOID
The VOID rule invalidates any matched rule that contains it, and hence any answer that contains it. In other words, it throws away any input that matches the rule.
The VOID rule is most effectively used as a preventative against giving nonsensical input. Suppose that you have a flight booking application that sometimes misrecognizes "San Diego" and "San Francisco." This could result in a nonsensical flight request, e.g. San Diego to San Diego. To counter this, you could use the VOID rule to prevent the destination from matching the departure:
ABNF Example
#ABNF 1.0; language en-US; mode voice; root $utterance; $cities = San Diego | San Francisco | Portland | Seattle; $destination = $cities; $departure = $cities; $notallowed = (San Diego to San Diego | San Francisco to San Francisco) $VOID; $flights = $departure to $destination | $notallowed; $utterance = I want a flight from $flights; |
GrXML Example
<?xml version="1.0" encoding="UTF-8" ?> <grammar xmlns="http://www.w3.org/2001/06/grammar" xml:lang="en-US" root="utterance" mode="voice"> <rule id="cities"> <one-of> <item>San Diego</item> <item>San Francisco</item> <item>Portland</item> <item>Seattle</item> </one-of> </rule> <rule id="destination"> <ruleref uri="#cities" /> </rule> <rule id="departure"> <ruleref uri="#cities" /> </rule> <rule id="notallowed"> <one-of> <item>San Diego to San Diego</item> <item>San Francisco to San Francisco</item> </one-of> <ruleref special="VOID"/> </rule> <rule id="flights"> <one-of> <item><ruleref uri="#departure" /> to <ruleref uri="#destination" /></item> <item><ruleref uri="#notallowed" /></item> </one-of> </rule> <rule id="utterance"> I want a flight from <ruleref uri="#flights" /> </rule> </grammar> |
Ideally, you would want to write a grammar that only contains valid destination/departure combinations in the first place. But, explicitly enumerating all of these combinations would be much more tedious than simply disallowing the specific unwanted destination/departure combinations. In this case, the VOID rule is a simple and effective way of eliminating possible misrecognitions without a huge undertaking.
The VOID rule is one of the most difficult rules to use correctly, and is misused more often than not. It’s sometimes most easily understood by explaining how NOT to use it, as with the example below.
Ultimately, it discards the match. At a glance, it’d seem perfect to use to deter people from providing an unwanted response. Users often try to use the $VOID rule to throw out values they don’t want like “operator” in a yes/no grammar.
ABNF Example - How NOT to Use the $VOID Rule!
#ABNF 1.0; language en-US; mode voice; root $yesorno; $yesorno = $yes | $no | operator $VOID; $yes = yes [please]; $no = no [thanks]; |
GrXML Example - How NOT to Use the $VOID Rule!
<?xml version="1.0" encoding="UTF-8" ?> <grammar xmlns="http://www.w3.org/2001/06/grammar" xml:lang="en-US" root="yesorno" mode="voice"> <rule id="yesorno"> <one-of> <item><ruleref uri="#yes"/></item> <item><ruleref uri="#no"/></item> <item>operator <ruleref special="VOID"/></item> </one-of> </rule> <rule id="yes"> yes <item repeat="0-1">please</item> </rule> <rule id="no"> no <item repeat="0-1">thanks</item> </rule> </grammar> |
In this example if the caller says “operator”, the VOID rule will force the recognition to be either “yes” or “no”, and will end up getting a low confidence. The result will basically be the same as not having the operator word in the grammar at all – the application will either misrecognize or reprompt due to a low confidence score.
NULL
The NULL rule is automatically matched as soon as it is processed by the Engine, without the user having spoken anything. It is a programming tool, and is matched as the text of the grammar is parsed.
The NULL rule is illustrated below with standard grammar operations rewritten to use the NULL rule.
ABNF Example
$yes = yes [please]; /* Identical rule expansion using the $NULL rule */ $yes = $yes (please | $NULL); |
GrXML Example
<rule id="yes"> yes <item repeat="0-1">please</item> </rule> <!-- Identical rule expansion using the NULL rule --> <rule id="yes"> yes <one-of> <item>please</item> <item><ruleref special="NULL"/></item> </one-of> </rule> |
In the above examples, the expansion used to make “please” optional can be rewritten as in the second rule. When the grammar is parsed, the ASR automatically knows that it can choose to match either “please” or NULL. Since it has to match NULL automatically, it can return with a valid parse without matching the word “please.”
Since the above example simply takes more keystrokes to accomplish the same feature when using the $NULL rule, let’s look at a more practical application.
In the example below, you’re building a numbers grammar, which you want evenly weighted:
ABNF Example
#ABNF 1.0; language en-US; mode voice; root $twenties; $OneToNine = one|two|three|four|five|six|seven|eight|nine; $twenties = twenty ($OneToNine | $NULL) |
When the speaker says any number in the twenties, they have an option to state a number between twenty and twenty-nine. This grammar will let them say the word “twenty” and then they can optionally use the $OneToNine rule to specify additional values.
The $twenties rule specifies that the caller can either say something from within the $OneToNine rule, or not.
However, if this rule implies that there is just as likely a chance of the speaker saying “twenty” as there is of them saying any other number within the twenties. Statistically, this may not be accurate. Each number within the twenties should have a one-tenth chance of being said.
To counter this, you would add weights to the $twenties rule to bring the NULL option’s weight down to 10%, and increase the $OneToNine rule’s weight up to 90%:
$twenties = twenty (/.9/$OneToNine | /.1/$NULL) |
Now the NULL rule is automatically matched, which only serves the purpose of taking up one-tenth of the weight of the $twenties rule. However, this is an important component of this rule, since you want all possible numbers in the twenties to have an equal likelihood of being matched.
In GrXML, this same grammar takes the form:
GrXML Example
<?xml version="1.0" encoding="UTF-8" ?> <grammar xmlns="http://www.w3.org/2001/06/grammar" xml:lang="en-US" root="twenties" mode="voice"> <rule id="OneToNine"> <one-of> <item>one</item> <item>two</item> <item>three</item> <item>four</item> <item>five</item> <item>six</item> <item>seven</item> <item>eight</item> <item>nine</item> </one-of> </rule> <rule id="twenties"> twenty <one-of> <item weight=".9"><ruleref uri="#OneToNine"/></item> <item weight=".1"><ruleref special="NULL"/></item> </one-of> </rule> </grammar> |
As is the case with the VOID rule, there are cases where you would not want to use the NULL rule.
In the example below, the $word rule can be repeated an infinite number of times, as defined by the <0-> operator.
ABNF $NULL rule Example - How NOT to Use!
#ABNF 1.0; language en-US; mode voice; $utt = $NULL $word<0->[$NULL|a] ($NULL); $word = (a | b | $NULL); |
GrXML $NULL rule Example - How NOT to Use!
<?xml version="1.0" encoding="UTF-8" ?> <grammar xmlns="http://www.w3.org/2001/06/grammar" xml:lang="en-US" root="utt" mode="voice"> <rule id="utt"> <ruleref special="NULL"/> <item repeat="0-"><ruleref uri="#word"/></item> <item repeat="0-1"> <one-of> <item><ruleref special="NULL"/></item> <item>a</item> </one-of> </item> <ruleref special="NULL"/> </rule> <rule id="word"> <one-of> <item>a</item> <item>b</item> <item><ruleref special="NULL"/></item> </one-of> </rule> </grammar> |
Other cases where the NULL rule are used are simply unnecessary and may slow down compilation or the parsing of the grammar.