def _apply(rule_a, rule_b): """Applies rule_b to rule_a, returning set of derived rules.""" outputs = [] if rule_a.arity == 2: new_arity = 1 + rule_b.arity if new_arity <= 2: # Cannot apply an arity 2 rule to an arity 2 rule because this would lead # to a rule with 3 different non-terminal indexes, which is disallowed # by our QCFG conventions. source_0 = _substitute(rule_a.source, rule_b.source) target_0 = _substitute(rule_a.target, rule_b.target) outputs.append((source_0, target_0, new_arity)) # Rule can potentially be applied to either non-terminal in rule_a. source_1 = _substitute(rule_a.source, rule_b.source, nt=qcfg_rule.NT_2) target_1 = _substitute(rule_a.target, rule_b.target, nt=qcfg_rule.NT_2) outputs.append((source_1, target_1, new_arity)) elif rule_a.arity == 1: new_arity = rule_b.arity source = _substitute(rule_a.source, rule_b.source) target = _substitute(rule_a.target, rule_b.target) outputs.append((source, target, new_arity)) output_rules = set() for source, target, arity in outputs: source, target = rule_utils.canonicalize_nts(source, target, arity) output_rules.add( qcfg_rule.QCFGRule(tuple(source), tuple(target), arity)) return output_rules
def _get_rules_for_other_examples(induced_rules, other_examples): """Add rules for examples outside of sample that cannot be derived.""" new_rules = set() for source_str, target_str in other_examples: goal_rule = qcfg_rule.QCFGRule(tuple(source_str.split()), tuple(target_str.split()), arity=0) if not derivation_utils.can_derive(goal_rule, induced_rules, None): new_rules.add(goal_rule) print("Added %s rules for examples outside of initial sample." % len(new_rules)) return new_rules
def get_exact_match_rules(dataset): """Return set of rules for terminal sequences in both source and target.""" matches = set() for source_str, target_str in dataset: source = source_str.split() target = target_str.split() matches.update(_find_exact_matches(source, target)) exact_match_rules = set() for match in matches: rule = qcfg_rule.QCFGRule(source=tuple(match), target=tuple(match), arity=0) exact_match_rules.add(rule) return exact_match_rules
def _make_rule(nts, source, target): """Canoncalize NT indexes and return QCFGRule.""" arity = len(nts) source, target = rule_utils.canonicalize_nts(source, target, arity) return qcfg_rule.QCFGRule(tuple(source), tuple(target), arity)
def _example_to_rule(source_str, target_str): """Convert (source, target) example to a QCFGRule.""" return qcfg_rule.QCFGRule(tuple(source_str.split()), tuple(target_str.split()), arity=0)