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
Beispiel #2
0
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
Beispiel #4
0
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)
Beispiel #5
0
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)