/** * Increase the number of disjuncts associated to each word in the * sentence by working with word-clusters. Return true if the number * of disjuncts were expanded, else return false. */ bool lg_expand_disjunct_list(Sentence sent) { size_t w; Cluster *clu = lg_cluster_new(); bool expanded = false; for (w = 0; w < sent->length; w++) { X_node * x; Disjunct * d = sent->word[w].d; for (x = sent->word[w].x; x != NULL; x = x->next) { Disjunct *dx = build_expansion_disjuncts(clu, x); if (dx) { unsigned int cnt = count_disjuncts(d); d = catenate_disjuncts(dx, d); d = eliminate_duplicate_disjuncts(d); if (cnt < count_disjuncts(d)) expanded = true; } } sent->word[w].d = d; } lg_cluster_delete(clu); return expanded; }
/** * Takes the list of disjuncts pointed to by d, eliminates all * duplicates, and returns a pointer to a new list. * It frees the disjuncts that are eliminated. */ Disjunct * eliminate_duplicate_disjuncts(Disjunct * d) { int i, h, count; Disjunct *dn, *dx, *dxn, *front; count = 0; disjunct_dup_table *dt; dt = disjunct_dup_table_new(next_power_of_two_up(2 * count_disjuncts(d))); for (;d!=NULL; d = dn) { dn = d->next; h = hash_disjunct(d); front = NULL; for (dx = dt->dup_table[h]; dx != NULL; dx = dxn) { dxn = dx->next; if (disjunct_matches_alam(dx,d)) { /* we know that d should be killed */ d->next = NULL; free_disjuncts(d); count++; front = catenate_disjuncts(front, dx); break; } else if (disjunct_matches_alam(d,dx)) { /* we know that dx should be killed off */ dx->next = NULL; free_disjuncts(dx); count++; } else { /* neither should be killed off */ dx->next = front; front = dx; } } if (dx == NULL) { /* we put d in the table */ d->next = front; front = d; } dt->dup_table[h] = front; } /* d is now NULL */ for (i = 0; i < dt->dup_table_size; i++) { for (dx = dt->dup_table[i]; dx != NULL; dx = dxn) { dxn = dx->next; dx->next = d; d = dx; } } if ((verbosity > 2) && (count != 0)) printf("killed %d duplicates\n", count); disjunct_dup_table_delete(dt); return d; }