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''' self.wipe() base = self._base_global named_rule = None '''get base CCR rule''' if time == Inf.BOOT: # rebuild via config for name, rule in self._global_rules.iteritems(): if self._config[CCRMerger._GLOBAL][name]: mp = MergePair(time, Inf.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 composite = base.composite.copy()# IDs of all rules that the composite rule is made of if time != Inf.SELFMOD: named_rule = self._global_rules[name] if name is not None else None if enable == False: composite.discard(named_rule.ID) # throw out rule getting disabled base = None for rule in self._get_rules_by_composite(composite): mp = MergePair(time, Inf.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 != Inf.SELFMOD and enable == True: mp = MergePair(time, Inf.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, Inf.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() mp = MergePair(time, Inf.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) active_apps.append(rule) '''negation context for appless version of base rule''' contexts = [rule.get_context() for rule in self._app_rules.values() \ if 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()) for grammar in self._grammars: grammar.load() '''save if necessary''' if time in [Inf.RUN, Inf.SELFMOD] and save: # everything in base composite is active, everything in selfmod is active, update the config as such active_global_names = [rule.get_name() 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_name() 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.save_config()
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 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() 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) 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()) 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] if time == MergeInf.BOOT: self._apply_format("_default") else: self._apply_format(current_rule) if save: self.save_config()