/** * This uses link_array. It post-processes * this linkage, and prints the appropriate thing. There are no fat * links in it. */ Linkage_info analyze_thin_linkage(Sentence sent, Parse_Options opts, int analyze_pass) { int i; Linkage_info li; PP_node * pp; Postprocessor * postprocessor; Sublinkage *sublinkage; Parse_info pi = sent->parse_info; build_digraph(pi, word_links); memset(&li, 0, sizeof(li)); sublinkage = x_create_sublinkage(pi); postprocessor = sent->dict->postprocessor; compute_link_names(sent); for (i=0; i<pi->N_links; i++) { copy_full_link(&(sublinkage->link[i]), &(pi->link_array[i])); } if (analyze_pass==PP_FIRST_PASS) { post_process_scan_linkage(postprocessor, opts, sent, sublinkage); free_sublinkage(sublinkage); free_digraph(pi, word_links); return li; } /* The code below can be used to generate the "islands" array. For this to work, * however, you have to call "build_digraph" first (as in analyze_fat_linkage). * and then "free_digraph". For some reason this causes a space leak. */ pp = post_process(postprocessor, opts, sent, sublinkage, TRUE); li.N_violations = 0; li.and_cost = 0; li.unused_word_cost = unused_word_cost(sent->parse_info); li.improper_fat_linkage = FALSE; li.inconsistent_domains = FALSE; li.disjunct_cost = disjunct_cost(pi); li.null_cost = null_cost(pi); li.link_cost = link_cost(pi); li.andlist = NULL; if (pp==NULL) { if (postprocessor != NULL) li.N_violations = 1; } else if (pp->violation!=NULL) { li.N_violations++; } free_sublinkage(sublinkage); free_digraph(pi, word_links); return li; }
/** Assign parse score (cost) to linkage, used for parse ranking. */ void linkage_score(Linkage lkg, Parse_Options opts) { lkg->lifo.unused_word_cost = unused_word_cost(lkg); if (opts->use_sat_solver) { lkg->lifo.disjunct_cost = 0.0; } else { lkg->lifo.disjunct_cost = compute_disjunct_cost(lkg); } lkg->lifo.link_cost = compute_link_cost(lkg); lkg->lifo.corpus_cost = -1.0; lg_corpus_score(lkg); }
/** * This uses link_array. It enumerates and post-processes * all the linkages represented by this one. We know this contains * at least one fat link. */ Linkage_info analyze_fat_linkage(Sentence sent, Parse_Options opts, int analyze_pass) { int i; Linkage_info li; DIS_node *d_root; PP_node *pp; Postprocessor *postprocessor; Sublinkage *sublinkage; Parse_info pi = sent->parse_info; PP_node accum; /* for domain ancestry check */ D_type_list * dtl0, * dtl1; /* for domain ancestry check */ sublinkage = x_create_sublinkage(pi); postprocessor = sent->dict->postprocessor; build_digraph(pi, word_links); structure_violation = FALSE; d_root = build_DIS_CON_tree(pi, word_links); /* may set structure_violation to TRUE */ li.N_violations = 0; li.improper_fat_linkage = structure_violation; li.inconsistent_domains = FALSE; li.unused_word_cost = unused_word_cost(sent->parse_info); li.disjunct_cost = disjunct_cost(pi); li.null_cost = null_cost(pi); li.link_cost = link_cost(pi); li.and_cost = 0; li.andlist = NULL; if (structure_violation) { li.N_violations++; free_sublinkage(sublinkage); free_digraph(pi, word_links); free_DIS_tree(d_root); return li; } if (analyze_pass==PP_SECOND_PASS) { li.andlist = build_andlist(sent, word_links); li.and_cost = li.andlist->cost; } else li.and_cost = 0; compute_link_names(sent); for (i=0; i<pi->N_links; i++) accum.d_type_array[i] = NULL; for (;;) { /* loop through all the sub linkages */ for (i=0; i<pi->N_links; i++) { patch_array[i].used = patch_array[i].changed = FALSE; patch_array[i].newl = pi->link_array[i].l; patch_array[i].newr = pi->link_array[i].r; copy_full_link(&sublinkage->link[i], &(pi->link_array[i])); } fill_patch_array_DIS(d_root, NULL, word_links); for (i=0; i<pi->N_links; i++) { if (patch_array[i].changed || patch_array[i].used) { sublinkage->link[i]->l = patch_array[i].newl; sublinkage->link[i]->r = patch_array[i].newr; } else if ((dfs_root_word[pi->link_array[i].l] != -1) && (dfs_root_word[pi->link_array[i].r] != -1)) { sublinkage->link[i]->l = -1; } } compute_pp_link_array_connectors(sent, sublinkage); compute_pp_link_names(sent, sublinkage); /* 'analyze_pass' logic added ALB 1/97 */ if (analyze_pass==PP_FIRST_PASS) { post_process_scan_linkage(postprocessor,opts,sent,sublinkage); if (!advance_DIS(d_root)) break; else continue; } pp = post_process(postprocessor, opts, sent, sublinkage, TRUE); if (pp==NULL) { if (postprocessor != NULL) li.N_violations = 1; } else if (pp->violation == NULL) { /* the purpose of this stuff is to make sure the domain ancestry for a link in each of its sentences is consistent. */ for (i=0; i<pi->N_links; i++) { if (sublinkage->link[i]->l == -1) continue; if (accum.d_type_array[i] == NULL) { accum.d_type_array[i] = copy_d_type(pp->d_type_array[i]); } else { dtl0 = pp->d_type_array[i]; dtl1 = accum.d_type_array[i]; while((dtl0 != NULL) && (dtl1 != NULL) && (dtl0->type == dtl1->type)) { dtl0 = dtl0->next; dtl1 = dtl1->next; } if ((dtl0 != NULL) || (dtl1 != NULL)) break; } } if (i != pi->N_links) { li.N_violations++; li.inconsistent_domains = TRUE; } } else if (pp->violation!=NULL) { li.N_violations++; } if (!advance_DIS(d_root)) break; } for (i=0; i<pi->N_links; ++i) { free_d_type(accum.d_type_array[i]); } /* if (display_on && (li.N_violations != 0) && (verbosity > 3) && should_print_messages) printf("P.P. violation in one part of conjunction.\n"); */ free_sublinkage(sublinkage); free_digraph(pi, word_links); free_DIS_tree(d_root); return li; }