You raise an interesting point here: when is the priority or
precedence of "fixed literal command words" and "dynamic dictation
elements" when the combination is ambiguously specified in a grammar.
To investigate further, I wrote a test/showcase file. It's attached to
this e-mail (although I'm not sure Google Groups can handle e-mails
with attachments). Please take a look at its contents, they are very
much self-documenting, because I made use of doctests.
My conclusion is that both Dragonfly and DNS behave correctly and as
expected for normal (non-ambiguous) grammars. For ambiguous grammars
(i.e. those where a recognized word could either be a literal command
word or part of a dynamic dictation) DNS appears to give the dynamic
dictation precedence over fixed command words.
DNS passes the recognized words in combination with the associated
"rule IDs" to Dragonfly, which then correctly processes them. The
recognition processing logic within Dragonfly is therefore good, and
does what it should do. I can however see no way to affect the
priority DNS gives to the recognized words. The (low-level binary)
grammar definition language used by DNS doesn't appear to contain any
way of changing priorities or precedences.
Best regards,
Charlie T
PS: Don't you like the way I'm testing Dragonfly functionality in the
attachment? No more need for painstakingly reloading a command module
and re-speaking the phrases you want to test over and over again...!
def BombRule(CompoundRuleClass): CompoundRuleClass.spec += " [bomb [<chain>]]" CompoundRuleClass.extras += (Dictation("chain"),) _orig_process_recognition = CompoundRuleClass._process_recognition def _new_process_recognition(self, node, extras): _orig_process_recognition(self, node, extras) if extras.has_key("chain"): Mimic(*extras["chain"].words).execute() CompoundRuleClass._process_recognition = _new_process_recognition return CompoundRuleClass
def OptionalBombRule(CompoundRuleClass): orig_spec = CompoundRuleClass.spec CompoundRuleClass = BombRule(CompoundRuleClass) CompoundRuleClass.spec = orig_spec + " [[bomb] [<chain>]]" return CompoundRuleClass
def ChainedRule(CompoundRuleClass): CompoundRuleClass.spec += " [<chain>]" CompoundRuleClass.extras += (Dictation("chain"),) _orig_process_recognition = CompoundRuleClass._process_recognition def _new_process_recognition(self, node, extras): _orig_process_recognition(self, node, extras) if extras.has_key("chain"): Mimic(*extras["chain"].words).execute() CompoundRuleClass._process_recognition = _new_process_recognition return CompoundRuleClass
def BombChain(CompoundRuleClass): CompoundRuleClass = BombRule(CompoundRuleClass) _orig_process_recognition = CompoundRuleClass._process_recognition def _new_process_recognition(self, node, extras): for i, word in enumerate(extras["bombChain"].words): if word == "then": extras["bombChain"].words[i] = "bomb" _orig_process_recognition(self, node, extras) CompoundRuleClass._process_recognition = _new_process_recognition return CompoundRuleClass@GrammarRule@BombChainclass StringRule(CompoundRule): spec = "string <bombChain>" extras = Dictation("bombChain"), def _process_recognition(self, node, extras): (Text ("\"") + Mimic(*extras["bombChain"].words) + Text("\"")).execute()#decorator
def BombRule(CompoundRuleClass):
_orig_process_recognition = CompoundRuleClass._process_recognition
def _new_process_recognition(self, node, extras):
words = []
bombCount = 0
#seek out bomb
for name, value in extras.items():
if type(value) == NatlinkDictationContainer:
if value.words.count("bomb") == 0:
continue # try to find another dictation container with a bomb
else:
words = value.words
bombCount = words.count("bomb")
break
if bombCount:
bombIndex = words.index("bomb")
extras[name] = NatlinkDictationContainer(words[0:bombIndex])
_orig_process_recognition(self, node, extras)
if bombCount:
Mimic(*words[bombIndex + 1:]).execute()
CompoundRuleClass._process_recognition = _new_process_recognition
return CompoundRuleClass