/** * We've already built the sentence disjuncts, and we've pruned them * and power_pruned(GENTLE) them also. The sentence contains a * conjunction. deletable[][] has been initialized to indicate the * ranges which may be deleted in the final linkage. * * This routine deletes irrelevant disjuncts. It finds them by first * marking them all as irrelevant, and then marking the ones that * might be useable. Finally, the unmarked ones are removed. */ void conjunction_prune(Sentence sent, Parse_Options opts) { Disjunct * d; int w; count_context_t *ctxt = sent->count_ctxt; ctxt->current_resources = opts->resources; ctxt->deletable = sent->deletable; count_set_effective_distance(sent); /* We begin by unmarking all disjuncts. This would not be necessary if whenever we created a disjunct we cleared its marked field. I didn't want to search the program for all such places, so I did this way. XXX FIXME, someday ... */ for (w=0; w<sent->length; w++) { for (d=sent->word[w].d; d != NULL; d=d->next) { d->marked = FALSE; } } init_fast_matcher(sent); ctxt->local_sent = sent->word; ctxt->null_links = (opts->min_null_count > 0); /* for (d = sent->word[0].d; d != NULL; d = d->next) { if ((d->left == NULL) && region_valid(sent, 0, sent->length, d->right, NULL)) { mark_region(sent, 0, sent->length, d->right, NULL); d->marked = TRUE; } } mark_region(sent, 0, sent->length, NULL, NULL); */ if (ctxt->null_links) { mark_region(sent, -1, sent->length, NULL, NULL); } else { for (w=0; w<sent->length; w++) { /* consider removing the words [0,w-1] from the beginning of the sentence */ if (ctxt->deletable[-1][w]) { for (d = sent->word[w].d; d != NULL; d = d->next) { if ((d->left == NULL) && region_valid(sent, w, sent->length, d->right, NULL)) { mark_region(sent, w, sent->length, d->right, NULL); d->marked = TRUE; } } } } } delete_unmarked_disjuncts(sent); free_fast_matcher(sent); ctxt->local_sent = NULL; ctxt->current_resources = NULL; ctxt->deletable = NULL; count_unset_effective_distance(sent); }
static int pp_prune(Sentence sent, Parse_Options opts) { pp_knowledge * knowledge; size_t i, w; int total_deleted, N_deleted; bool change, deleteme; multiset_table *cmt; if (sent->postprocessor == NULL) return 0; if (!opts->perform_pp_prune) return 0; knowledge = sent->postprocessor->knowledge; cmt = cms_table_new(); for (w = 0; w < sent->length; w++) { Disjunct *d; for (d = sent->word[w].d; d != NULL; d = d->next) { char dir; d->marked = true; for (dir=0; dir < 2; dir++) { Connector *c; for (c = ((dir) ? (d->left) : (d->right)); c != NULL; c = c->next) { insert_in_cms_table(cmt, connector_string(c)); } } } } total_deleted = 0; change = true; while (change) { char dir; change = false; N_deleted = 0; for (w = 0; w < sent->length; w++) { Disjunct *d; for (d = sent->word[w].d; d != NULL; d = d->next) { if (!d->marked) continue; deleteme = false; for (i = 0; i < knowledge->n_contains_one_rules; i++) { pp_rule* rule = &knowledge->contains_one_rules[i]; /* the ith rule */ const char * selector = rule->selector; /* selector string for this rule */ pp_linkset * link_set = rule->link_set; /* the set of criterion links */ if (rule->selector_has_wildcard) continue; /* If it has a * forget it */ for (dir = 0; dir < 2; dir++) { Connector *c; for (c = ((dir) ? (d->left) : (d->right)); c != NULL; c = c->next) { if (!post_process_match(selector, connector_string(c))) continue; /* printf("pp_prune: trigger ok. selector = %s c->string = %s\n", selector, c->string); */ /* We know c matches the trigger link of the rule. */ /* Now check the criterion links */ if (!rule_satisfiable(cmt, link_set)) { deleteme = true; rule->use_count++; } if (deleteme) break; } if (deleteme) break; } if (deleteme) break; } if (deleteme) /* now we delete this disjunct */ { N_deleted++; total_deleted++; d->marked = false; /* mark for deletion later */ for (dir=0; dir < 2; dir++) { Connector *c; for (c = ((dir) ? (d->left) : (d->right)); c != NULL; c = c->next) { change |= delete_from_cms_table(cmt, connector_string(c)); } } } } } lgdebug(D_PRUNE, "Debug: pp_prune pass deleted %d\n", N_deleted); } cms_table_delete(cmt); if (total_deleted > 0) { delete_unmarked_disjuncts(sent); if (verbosity_level(D_PRUNE)) { prt_error("\n\\"); prt_error("Debug: After pp_prune:\n\\"); print_disjunct_counts(sent); } } print_time(opts, "pp pruning"); return total_deleted; }