def __init__(self, num_choice_500s, num_specs): mapping = {} extras = [] defaults = {} w500 = get_500_words() spec_base = "" text_base = "" for k in range(0, num_choice_500s): extra_name = "giant_" + str(k) spec_base += " <" + extra_name + ">" text_base += " %(" + extra_name + ")s" extras.append(get_giant_choice(extra_name)) for i in range(0, num_specs): word = w500[i] mapping[word + spec_base] = R(Text(word + text_base), show=False) MergeRule.__init__(self, name="complexity test", mapping=mapping, extras=extras, defaults=defaults)
def __init__(self, name=None, mapping=None, extras=None, defaults=None, exported=None, refresh=True): MergeRule.__init__(self, name, mapping, extras, defaults, exported) self._merger = None if refresh: self.refresh()
def test_name_generation(self): size = 10 names = set() for i in range(0, size): names.add(MergeRule.get_merge_name()) self.assertTrue(len(names) == size)
def reset(self, mapping): grammar = self._grammar # save reference because Grammar.remove_rule nullifies it ccr = self._merger is not None if grammar is not None and not ccr: grammar.unload() grammar.remove_rule(self) extras = self.extras if self.extras else [ IntegerRefST("n", 1, 50), Dictation("s") ] defaults = self.defaults if self.defaults else {"n": 1, "s": ""} MergeRule.__init__(self, self.name, mapping, extras, defaults, self.exported, self.context) if ccr: self._merger.merge(MergeInf.SELFMOD) if grammar is not None and not ccr: grammar.add_rule(self) grammar.load()
def _create_repeat_rule(self, rule): ORIGINAL, SEQ, TERMINAL = "original", "caster_base_sequence", "terminal" alts = [RuleRef(rule=rule)] #+[RuleRef(rule=sm) for sm in selfmod] single_action = Alternative(alts) max = settings.SETTINGS["miscellaneous"]["max_ccr_repetitions"] sequence = Repetition(single_action, min=1, max=max, name=SEQ) original = Alternative(alts, name=ORIGINAL) terminal = Alternative(alts, name=TERMINAL) class RepeatRule(CompoundRule): spec = "[<" + ORIGINAL + "> original] [<" + SEQ + ">] [terminal <" + TERMINAL + ">]" extras = [sequence, original, terminal] def _process_recognition(self, node, extras): original = extras[ORIGINAL] if ORIGINAL in extras else None sequence = extras[SEQ] if SEQ in extras else None terminal = extras[TERMINAL] if TERMINAL in extras else None if original is not None: original.execute() if sequence is not None: for action in sequence: action.execute() if terminal is not None: terminal.execute() return RepeatRule(name="Repeater" + MergeRule.get_merge_name())
def merge(self, time, name=None, enable=True, save=False): '''combines MergeRules, SelfModifyingRules; handles CCR for apps; instantiates affiliated rules; adds everything to its grammar ; assumptions made: * SelfModifyingRules have already made changes to themselves * the appropriate activation boolean(s) in the appropriate map has already been set''' current_rule = None self.wipe() base = self._base_global named_rule = None '''get base CCR rule''' if time == MergeInf.BOOT: # rebuild via config for name, rule in self._global_rules.iteritems(): '''we want to be able to make permanent changes at boot time, not just to activated rules, but to everything -- but we dont' want it to interfere with normal merge logic-- hence the introduction of the BOOT_NO_MERGE time''' mp = MergePair( MergeInf.BOOT_NO_MERGE, MergeInf.GLOBAL, None, rule, False ) # copies not made at boot time, allows user to make permanent changes self._run_filters(mp) if self._config[CCRMerger._GLOBAL][name]: mp = MergePair( time, MergeInf.GLOBAL, base, rule, False ) # copies not made at boot time, allows user to make permanent changes self._run_filters(mp) if base is None: base = rule else: base = self._compatibility_merge(mp, base, rule) else: # rebuild via composite if not self._config["ccr_on"]: self._config["ccr_on"] = True self.save_config() composite = base.composite.copy( ) # IDs of all rules that the composite rule is made of if time != MergeInf.SELFMOD: assert name is not None named_rule = self._global_rules[name] if enable is False: composite.discard( named_rule.ID) # throw out rule getting disabled else: # enable CCR rule self._config[CCRMerger._ORDER].append(name) current_rule = name base = None for rule in self._get_rules_by_composite(composite): mp = MergePair(time, MergeInf.GLOBAL, base, rule.copy(), False) self._run_filters(mp) if base is None: base = rule else: base = self._compatibility_merge( mp, base, mp.rule2) # mp.rule2 because named_rule got copied if time != MergeInf.SELFMOD and enable == True: mp = MergePair(time, MergeInf.GLOBAL, base, named_rule.copy(), True) self._run_filters(mp) base = self._compatibility_merge( mp, base, mp.rule2) # mp.rule2 because named_rule got copied '''compatibility check and filter function active selfmodrules''' for name2, rule in self._self_modifying_rules.iteritems(): '''no need to make copies of selfmod rules because even if filter functions trash their mapping, they'll just regenerate it next time they modify themselves; furthermore, they need to preserve state''' if self._config[CCRMerger._SELFMOD][name2]: mp = MergePair(time, MergeInf.SELFMOD, base, rule, False) self._run_filters(mp) base = self._compatibility_merge(mp, base, rule) '''have base, make copies, merge in apps''' active_apps = [] for rule in self._app_rules.values(): base_copy = base.copy( ) if base is not None else base # make a copy b/c commands will get stripped out context = rule.get_context() non_copy = rule.non if rule.non else None mp = MergePair(time, MergeInf.APP, base_copy, rule.copy(), False, CCRMerger.specs_per_rulename(self._global_rules)) self._run_filters(mp) rule = self._compatibility_merge( mp, base_copy, mp.rule2) # mp.rule2 because named_rule got copied rule.set_context(context) rule.non = non_copy active_apps.append(rule) '''negation context for appless version of base rule''' contexts = [app_rule.get_context() for app_rule in self._app_rules.values() \ if app_rule.get_context() is not None]# get all contexts negation_context = None for context in contexts: negate = ~context if negation_context is None: negation_context = negate else: negation_context & negate '''handle empty merge''' if base is None: base = MergeRule() ''' save results for next merge ''' self._base_global = base.copy() '''instantiate non-ccr rules affiliated with rules in the base CCR rule''' active_global = self._get_rules_by_composite(base.composite, True) global_non_ccr = [rule.non() for rule in active_global \ if rule.non is not None] '''update grammars''' self._add_grammar(base, True, negation_context) for rule in global_non_ccr: self._add_grammar(rule) for rule in active_apps: self._add_grammar(rule, True, rule.get_context()) if rule.non is not None: self._add_grammar(rule.non(), False, rule.get_context()) for grammar in self._grammars: grammar.load() '''save if necessary''' if time in [MergeInf.RUN, MergeInf.SELFMOD] and save: # everything in base composite is active, everything in selfmod is active, update the config as such active_global_names = [ rule.get_pronunciation() for rule in active_global ] for rule_name in self._global_rules: self._config[CCRMerger._GLOBAL][ rule_name] = rule_name in active_global_names active_selfmod_names = [ name3 for name3 in self._config[CCRMerger._SELFMOD] if self._config[CCRMerger._SELFMOD][name3] ] #[rule.get_pronunciation() for rule in selfmod] for rule_name in self._self_modifying_rules: self._config[CCRMerger._SELFMOD][ rule_name] = rule_name in active_selfmod_names self._sync_enabled() if len(self._config[CCRMerger._ORDER]) > 0: current_rule = self._config[CCRMerger._ORDER][-1] self._apply_format(current_rule) if save: self.save_config() if time == MergeInf.BOOT and not self._config["ccr_on"]: self.ccr_off()