void add_to_best_list(APPROX_PARAMS *ap, OPTION **new_b_options, int *new_cand_num, OPTION *to_add) { ASSERT(*new_cand_num < ap->beam || to_add->lprob > new_b_options[ap->beam - 1]->lprob); int i; for (i = *new_cand_num - 1; i >= 0; i--) { if (new_b_options[i]->lprob < to_add->lprob) { new_b_options[i + 1] = new_b_options[i]; } else { new_b_options[i + 1] = to_add; break; } } //should be inserted on the first position if (i == -1) { new_b_options[0] = to_add; } if (*new_cand_num == ap->beam) { pt_free(&(new_b_options[ap->beam]->pt)); ps_free(&(new_b_options[ap->beam]->ps)); free_options(new_b_options[ap->beam]); } else { (*new_cand_num)++; } return; }
double label_sentence(APPROX_PARAMS *ap, MODEL_PARAMS *mp, SENTENCE *sent) { ASSERT(ap->beam >= 1 && ap->beam < MAX_BEAM); ASSERT(ap->search_br_factor >= 1); OPTION *best_options[MAX_SENT_LEN + 1][MAX_BEAM + 1]; best_options[0][0] = root_prediction(ap, mp, sent); int cand_num = 1; int t; for (t = 1; t < sent->len + 1; t++) { cand_num = search_options(ap, mp, sent, best_options[t-1], cand_num, best_options[t]); ASSERT(cand_num <= ap->beam); } double best_lprob = best_options[sent->len][0]->lprob; pt_fill_sentence(best_options[sent->len][0]->pt, mp, sent); ps_fill_sentence(best_options[sent->len][0]->ps, mp, sent); save_candidates(ap, mp, sent, best_options[sent->len], cand_num); int i; for (i = 0; i < cand_num; i++) { pt_free(&(best_options[sent->len][i]->pt)); ps_free(&(best_options[sent->len][i]->ps)); free_options(best_options[sent->len][i]); } return best_lprob; }
void free_proc(struct vmproc *vmp) { map_free_proc(vmp); pt_free(&vmp->vm_pt); region_init(&vmp->vm_regions_avl); #if VMSTATS vmp->vm_bytecopies = 0; #endif vmp->vm_region_top = 0; reset_vm_rusage(vmp); }
void end(B b) { tt_free(); pt_free(); int i; for(i = 0; i < 64; i++) free(sqs[i]); free(b->superbp); free(b->superbs); free(b->pieces); free(b); }
/*===========================================================================* * do_fork * *===========================================================================*/ int do_fork(message *msg) { int r, proc, childproc; struct vmproc *vmp, *vmc; pt_t origpt; vir_bytes msgaddr; SANITYCHECK(SCL_FUNCTIONS); if(vm_isokendpt(msg->VMF_ENDPOINT, &proc) != OK) { printf("VM: bogus endpoint VM_FORK %d\n", msg->VMF_ENDPOINT); SANITYCHECK(SCL_FUNCTIONS); return EINVAL; } childproc = msg->VMF_SLOTNO; if(childproc < 0 || childproc >= NR_PROCS) { printf("VM: bogus slotno VM_FORK %d\n", msg->VMF_SLOTNO); SANITYCHECK(SCL_FUNCTIONS); return EINVAL; } vmp = &vmproc[proc]; /* parent */ vmc = &vmproc[childproc]; /* child */ assert(vmc->vm_slot == childproc); /* The child is basically a copy of the parent. */ origpt = vmc->vm_pt; *vmc = *vmp; vmc->vm_slot = childproc; region_init(&vmc->vm_regions_avl); vmc->vm_endpoint = NONE; /* In case someone tries to use it. */ vmc->vm_pt = origpt; #if VMSTATS vmc->vm_bytecopies = 0; #endif if(pt_new(&vmc->vm_pt) != OK) { printf("VM: fork: pt_new failed\n"); return ENOMEM; } SANITYCHECK(SCL_DETAIL); if(map_proc_copy(vmc, vmp) != OK) { printf("VM: fork: map_proc_copy failed\n"); pt_free(&vmc->vm_pt); return(ENOMEM); } /* Only inherit these flags. */ vmc->vm_flags &= VMF_INUSE; /* inherit the priv call bitmaps */ memcpy(&vmc->vm_call_mask, &vmp->vm_call_mask, sizeof(vmc->vm_call_mask)); /* Tell kernel about the (now successful) FORK. */ if((r=sys_fork(vmp->vm_endpoint, childproc, &vmc->vm_endpoint, PFF_VMINHIBIT, &msgaddr)) != OK) { panic("do_fork can't sys_fork: %d", r); } if((r=pt_bind(&vmc->vm_pt, vmc)) != OK) panic("fork can't pt_bind: %d", r); { vir_bytes vir; /* making these messages writable is an optimisation * and its return value needn't be checked. */ vir = msgaddr; if (handle_memory(vmc, vir, sizeof(message), 1) != OK) panic("do_fork: handle_memory for child failed\n"); vir = msgaddr; if (handle_memory(vmp, vir, sizeof(message), 1) != OK) panic("do_fork: handle_memory for parent failed\n"); } /* Inform caller of new child endpoint. */ msg->VMF_CHILD_ENDPOINT = vmc->vm_endpoint; SANITYCHECK(SCL_FUNCTIONS); return OK; }
/*===========================================================================* * do_fork * *===========================================================================*/ PUBLIC int do_fork(message *msg) { int r, proc, s, childproc, fullvm; struct vmproc *vmp, *vmc; pt_t origpt; vir_bytes msgaddr; SANITYCHECK(SCL_FUNCTIONS); if(vm_isokendpt(msg->VMF_ENDPOINT, &proc) != OK) { printf("VM: bogus endpoint VM_FORK %d\n", msg->VMF_ENDPOINT); SANITYCHECK(SCL_FUNCTIONS); return EINVAL; } childproc = msg->VMF_SLOTNO; if(childproc < 0 || childproc >= NR_PROCS) { printf("VM: bogus slotno VM_FORK %d\n", msg->VMF_SLOTNO); SANITYCHECK(SCL_FUNCTIONS); return EINVAL; } vmp = &vmproc[proc]; /* parent */ vmc = &vmproc[childproc]; /* child */ assert(vmc->vm_slot == childproc); if(vmp->vm_flags & VMF_HAS_DMA) { printf("VM: %d has DMA memory and may not fork\n", msg->VMF_ENDPOINT); return EINVAL; } fullvm = vmp->vm_flags & VMF_HASPT; /* The child is basically a copy of the parent. */ origpt = vmc->vm_pt; *vmc = *vmp; vmc->vm_slot = childproc; vmc->vm_regions = NULL; yielded_init(&vmc->vm_yielded_blocks); vmc->vm_endpoint = NONE; /* In case someone tries to use it. */ vmc->vm_pt = origpt; vmc->vm_flags &= ~VMF_HASPT; #if VMSTATS vmc->vm_bytecopies = 0; #endif if(pt_new(&vmc->vm_pt) != OK) { printf("VM: fork: pt_new failed\n"); return ENOMEM; } vmc->vm_flags |= VMF_HASPT; if(fullvm) { SANITYCHECK(SCL_DETAIL); if(map_proc_copy(vmc, vmp) != OK) { printf("VM: fork: map_proc_copy failed\n"); pt_free(&vmc->vm_pt); return(ENOMEM); } if(vmp->vm_heap) { vmc->vm_heap = map_region_lookup_tag(vmc, VRT_HEAP); assert(vmc->vm_heap); } SANITYCHECK(SCL_DETAIL); } else { vir_bytes sp; struct vir_region *heap, *stack; vir_bytes text_bytes, data_bytes, stack_bytes, parent_gap_bytes, child_gap_bytes; /* Get SP of new process (using parent). */ if(get_stack_ptr(vmp->vm_endpoint, &sp) != OK) { printf("VM: fork: get_stack_ptr failed for %d\n", vmp->vm_endpoint); return ENOMEM; } /* Update size of stack segment using current SP. */ if(adjust(vmp, vmp->vm_arch.vm_seg[D].mem_len, sp) != OK) { printf("VM: fork: adjust failed for %d\n", vmp->vm_endpoint); return ENOMEM; } /* Copy newly adjust()ed stack segment size to child. */ vmc->vm_arch.vm_seg[S] = vmp->vm_arch.vm_seg[S]; text_bytes = CLICK2ABS(vmc->vm_arch.vm_seg[T].mem_len); data_bytes = CLICK2ABS(vmc->vm_arch.vm_seg[D].mem_len); stack_bytes = CLICK2ABS(vmc->vm_arch.vm_seg[S].mem_len); /* how much space after break and before lower end (which is the * logical top) of stack for the parent */ parent_gap_bytes = CLICK2ABS(vmc->vm_arch.vm_seg[S].mem_vir - vmc->vm_arch.vm_seg[D].mem_len); /* how much space can the child stack grow downwards, below * the current SP? The rest of the gap is available for the * heap to grow upwards. */ child_gap_bytes = VM_PAGE_SIZE; if((r=proc_new(vmc, VM_PROCSTART, text_bytes, data_bytes, stack_bytes, child_gap_bytes, 0, 0, CLICK2ABS(vmc->vm_arch.vm_seg[S].mem_vir + vmc->vm_arch.vm_seg[S].mem_len), 1)) != OK) { printf("VM: fork: proc_new failed\n"); return r; } if(!(heap = map_region_lookup_tag(vmc, VRT_HEAP))) panic("couldn't lookup heap"); assert(heap->phys); if(!(stack = map_region_lookup_tag(vmc, VRT_STACK))) panic("couldn't lookup stack"); assert(stack->phys); /* Now copy the memory regions. */ if(vmc->vm_arch.vm_seg[T].mem_len > 0) { struct vir_region *text; if(!(text = map_region_lookup_tag(vmc, VRT_TEXT))) panic("couldn't lookup text"); assert(text->phys); if(copy_abs2region(CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys), text, 0, text_bytes) != OK) panic("couldn't copy text"); } if(copy_abs2region(CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys), heap, 0, data_bytes) != OK) panic("couldn't copy heap"); if(copy_abs2region(CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys + vmc->vm_arch.vm_seg[D].mem_len) + parent_gap_bytes, stack, child_gap_bytes, stack_bytes) != OK) panic("couldn't copy stack"); } /* Only inherit these flags. */ vmc->vm_flags &= (VMF_INUSE|VMF_SEPARATE|VMF_HASPT); /* inherit the priv call bitmaps */ memcpy(&vmc->vm_call_mask, &vmp->vm_call_mask, sizeof(vmc->vm_call_mask)); /* Tell kernel about the (now successful) FORK. */ if((r=sys_fork(vmp->vm_endpoint, childproc, &vmc->vm_endpoint, vmc->vm_arch.vm_seg, PFF_VMINHIBIT, &msgaddr)) != OK) { panic("do_fork can't sys_fork: %d", r); } if(fullvm) { vir_bytes vir; /* making these messages writable is an optimisation * and its return value needn't be checked. */ vir = arch_vir2map(vmc, msgaddr); handle_memory(vmc, vir, sizeof(message), 1); vir = arch_vir2map(vmp, msgaddr); handle_memory(vmp, vir, sizeof(message), 1); } if((r=pt_bind(&vmc->vm_pt, vmc)) != OK) panic("fork can't pt_bind: %d", r); /* Inform caller of new child endpoint. */ msg->VMF_CHILD_ENDPOINT = vmc->vm_endpoint; SANITYCHECK(SCL_FUNCTIONS); return OK; }
//TODO don't forget to move pt OPTION_LIST *process_opt(APPROX_PARAMS *ap, MODEL_PARAMS *mp, SENTENCE *sent, OPTION **new_b_options, int *new_cand_num, OPTION *opt, OPTION_LIST *ol) { /* if ol longer than QUEUE_SIZE_LIMIT, then prune to half that length. Requires calling with opt=NULL to initialize count */ static int queue_size; if (opt == NULL) { queue_size = 0; OPTION_LIST *ol2; for (ol2 = ol; ol2 != NULL; ol2 = ol2->prev) queue_size++; return ol; } queue_size--; ASSERT(opt->outputs.num == ACTION_NUM); double min_lprob = - MAXDOUBLE; double min_lprob_with_pred = -MAXDOUBLE; if (*new_cand_num == ap->beam) { min_lprob = new_b_options[ap->beam - 1]->lprob - max_word_pred_lprob(ap, mp, sent, new_b_options, *new_cand_num, opt); min_lprob_with_pred = new_b_options[ap->beam - 1]->lprob; } //do not need to consider if (opt->lprob < min_lprob) { pt_free(&(opt->pt)); ps_free(&(opt->ps)); free_options(opt); return ol; } //they are not yet computed ACTION_SET as = get_next_actions(ap, mp, opt, sent); set_mask(mp, opt, &as); comp_option(ap, mp, opt); // ----------------------- SYNTAX ----------------------------------------------- //check SHIFT (first because it is the operation that updates candidate list) if (as.acts[SHIFT]) { if (log(opt->outputs.q[SHIFT]) + opt->lprob >= min_lprob) { //create sequence of shift operation //update queue and stack //TODO Implement more efficiently pruning after each decision OPTION *as_opt = create_option(SYNT_STEP, 0, opt->previous_act, SHIFT, opt, opt->period, &opt->stack, &opt->srl_stack, opt->queue, pt_clone(opt->pt), ps_clone(opt->ps), &mp->out_link_pos, get_pos_out_num()); int pos = sent->pos[opt->period + ap->input_offset]; int feat = sent->feat_out[opt->period + ap->input_offset]; int word = sent->word_out[opt->period + ap->input_offset]; set_links(ap, mp, as_opt, sent); comp_option(ap, mp, as_opt); if (log(as_opt->outputs.q[pos]) + as_opt->lprob < min_lprob_with_pred) { pt_free(&(as_opt->pt)); ps_free(&(as_opt->ps)); free_option(as_opt); } else { OPTION *last_opt = create_word_prediction_seq(ap, mp, sent, as_opt, 1); OPTION *feat_opt = last_opt->previous_option->previous_option; comp_option(ap, mp, feat_opt); if (log(feat_opt->outputs.q[feat]) + feat_opt->lprob < min_lprob_with_pred) { pt_free(&(last_opt->pt)); ps_free(&(last_opt->ps)); OPTION *po = last_opt->previous_option, *ppo = last_opt->previous_option->previous_option; free_option(last_opt); free_option(po); free_option(ppo); free_option(as_opt); } else { OPTION *word_opt = last_opt->previous_option; comp_option(ap, mp, word_opt); // if (log(word_opt->outputs.q[word]) + word_opt->lprob < min_lprob_with_pred) { if (log(word_opt->outputs.q[word]) + word_opt->lprob < min_lprob_with_pred + SMALL_POS_VAL) { pt_free(&(last_opt->pt)); ps_free(&(last_opt->ps)); OPTION *po = last_opt->previous_option, *ppo = last_opt->previous_option->previous_option; free_option(last_opt); free_option(po); free_option(ppo); free_option(as_opt); } else { fill_lprob(last_opt); add_to_best_list(ap, new_b_options, new_cand_num, last_opt); } } } } } //update if (*new_cand_num == ap->beam) { min_lprob = new_b_options[ap->beam - 1]->lprob - max_word_pred_lprob(ap, mp, sent, new_b_options, *new_cand_num, opt); min_lprob_with_pred = new_b_options[ap->beam - 1]->lprob; // not necessary, but could save space: //ol = prune_options(ol, min_lprob); } //check LA if (as.acts[LA]) { int d = st_peek(&opt->stack); int h = opt->queue; if (log(opt->outputs.q[LA]) + opt->lprob >= min_lprob) { //create sequence of LA operations //update queue and stack OPTION *as_opt = create_option(SYNT_STEP, 0, opt->previous_act, LA, opt, opt->period, &opt->stack, &opt->srl_stack, opt->queue, pt_clone(opt->pt), ps_clone(opt->ps), &mp->out_link_la_label, mp->deprel_num); set_links(ap, mp, as_opt, sent); comp_option(ap, mp, as_opt); double deprel_min_prob = exp(min_lprob - as_opt->lprob); int best_rels[MAX_DEPREL_SIZE]; int fanout = get_best_labels(ap, as_opt, deprel_min_prob, mp->deprel_num, best_rels); int i; for (i = 0; i < fanout; i++) { OPTION *new_opt = create_option_light(SYNT_STEP, 1, LA, best_rels[i], as_opt, as_opt->period, &as_opt->stack, &as_opt->srl_stack, as_opt->queue, pt_clone(as_opt->pt), ps_clone(as_opt->ps), &mp->out_link_act, ACTION_NUM); pt_add_link(new_opt->pt, h, d, best_rels[i]); if (ap->intern_synt_deproj == DEPROJ_NO) { st_pop(&new_opt->stack); } else { // Do nothing } set_links(ap, mp, new_opt, sent); fill_lprob(new_opt); ol = increase_list_asc(ol, new_opt); queue_size++; } pt_free(&(as_opt->pt)); ps_free(&(as_opt->ps)); as_opt->pt = NULL; as_opt->ps = NULL; if (fanout == 0) { free_option(as_opt); } } } //check RA if (as.acts[RA]) { int d = opt->queue; int h = st_peek(&opt->stack); //when agrees if (log(opt->outputs.q[RA]) + opt->lprob >= min_lprob) { //create sequence of RA operations //update queue and stack OPTION *as_opt = create_option(SYNT_STEP, 0, opt->previous_act, RA, opt, opt->period, &opt->stack, &opt->srl_stack, opt->queue, pt_clone(opt->pt), ps_clone(opt->ps), &mp->out_link_ra_label, mp->deprel_num); set_links(ap, mp, as_opt, sent); comp_option(ap, mp, as_opt); double deprel_min_prob = exp(min_lprob - as_opt->lprob); int best_rels[MAX_DEPREL_SIZE]; int fanout = get_best_labels(ap, as_opt, deprel_min_prob, mp->deprel_num, best_rels); int i; for (i = 0; i < fanout; i++) { OPTION *new_opt = create_option_light(SYNT_STEP, 1, RA, best_rels[i], as_opt, as_opt->period, &as_opt->stack, &as_opt->srl_stack, as_opt->queue, pt_clone(as_opt->pt), ps_clone(as_opt->ps), &mp->out_link_act, ACTION_NUM); pt_add_link(new_opt->pt, h, d, best_rels[i]); set_links(ap, mp, new_opt, sent); fill_lprob(new_opt); ol = increase_list_asc(ol, new_opt); queue_size++; } pt_free(&(as_opt->pt)); ps_free(&(as_opt->ps)); as_opt->pt = NULL; as_opt->ps = NULL; if (fanout == 0) { free_option(as_opt); } //TODO Try processing immediately SHIFT operation //should speed-up (it will make it way to best_list and //prune other optinos) } } //check RED if (as.acts[RED]) { if (log(opt->outputs.q[RED]) + opt->lprob >= min_lprob) { //create sequence of reduce operation //update queue and stack OPTION *as_opt = create_option_light(SYNT_STEP, 1, RED, RED, opt, opt->period, &opt->stack, &opt->srl_stack, opt->queue, pt_clone(opt->pt), ps_clone(opt->ps), &mp->out_link_act, ACTION_NUM); st_pop(&as_opt->stack); set_links(ap, mp, as_opt, sent); fill_lprob(as_opt); ol = increase_list_asc(ol, as_opt); queue_size++; } } //check SWITCH if (as.acts[SWITCH]) { if (log(opt->outputs.q[SWITCH]) + opt->lprob >= min_lprob) { OPTION *as_opt = create_option_light(SRL_STEP, 1, SWITCH, SWITCH, opt, opt->period, &opt->stack, &opt->srl_stack, opt->queue, pt_clone(opt->pt), ps_clone(opt->ps), &mp->out_link_act, ACTION_NUM); // OPTION *as_opt = create_option_light(SYNT_STEP, 1, SWITCH, SWITCH, opt, opt->period, &opt->stack, &opt->srl_stack, opt->queue, // pt_clone(opt->pt), ps_clone(opt->ps), &mp->out_link_act, ACTION_NUM); set_links(ap, mp, as_opt, sent); fill_lprob(as_opt); ol = increase_list_asc(ol, as_opt); queue_size++; } } // ----------------------- SEMANTICS ----------------------------------------------- //check PREDIC_NO if (as.acts[PREDIC_NO]) { if (log(opt->outputs.q[PREDIC_NO]) + opt->lprob >= min_lprob) { OPTION *as_opt = create_option_light(SRL_STEP, 1, PREDIC_NO, PREDIC_NO, opt, opt->period, &opt->stack, &opt->srl_stack, opt->queue, pt_clone(opt->pt), ps_clone(opt->ps), &mp->out_link_act, ACTION_NUM); set_links(ap, mp, as_opt, sent); fill_lprob(as_opt); ol = increase_list_asc(ol, as_opt); queue_size++; } } if (as.acts[PREDIC_YES]) { int q = opt->queue; int q_bank = sent->bank[q]; int q_lemma = sent->lemma[q]; if (log(opt->outputs.q[PREDIC_YES]) + opt->lprob >= min_lprob) { //create sequence of predicate prediction operations OPTION *as_opt = create_option(SRL_STEP, 0, opt->previous_act, PREDIC_YES, opt, opt->period, &opt->stack, &opt->srl_stack, opt->queue, pt_clone(opt->pt), ps_clone(opt->ps), &mp->out_link_sense[q_bank][q_lemma][0], mp->sense_num[q_bank][q_lemma]); set_links(ap, mp, as_opt, sent); comp_option(ap, mp, as_opt); double sense_min_prob = exp(min_lprob - as_opt->lprob); int best_senses[MAX_SENSE_SIZE]; int fanout = get_best_labels(ap, as_opt, sense_min_prob, mp->sense_num[q_bank][q_lemma], best_senses); int i; for (i = 0; i < fanout; i++) { OPTION *new_opt = create_option_light(SRL_STEP, 1, PREDIC_YES, best_senses[i], as_opt, as_opt->period, &as_opt->stack, &as_opt->srl_stack, as_opt->queue, pt_clone(as_opt->pt), ps_clone(as_opt->ps), &mp->out_link_act, ACTION_NUM); ps_set_sense(new_opt->ps, q, best_senses[i]); set_links(ap, mp, new_opt, sent); fill_lprob(new_opt); ol = increase_list_asc(ol, new_opt); queue_size++; } pt_free(&(as_opt->pt)); ps_free(&(as_opt->ps)); as_opt->pt = NULL; as_opt->ps = NULL; if (fanout == 0) { free_option(as_opt); } } } //check SRL_LA int q_bank = sent->bank[opt->queue]; if (q_bank >= 0 && as.acts[SRL_LA[q_bank]]) { int d = st_peek(&opt->srl_stack); int h = opt->queue; if (log(opt->outputs.q[SRL_LA[q_bank]]) + opt->lprob >= min_lprob) { //create sequence of SRL_LA operations //update queue and stack OPTION *as_opt = create_option(SRL_STEP, 0, opt->previous_act, SRL_LA[q_bank], opt, opt->period, &opt->stack, &opt->srl_stack, opt->queue, pt_clone(opt->pt), ps_clone(opt->ps), &mp->out_link_sem_la_label[q_bank], mp->role_num[q_bank]); set_links(ap, mp, as_opt, sent); comp_option(ap, mp, as_opt); double rel_min_prob = exp(min_lprob - as_opt->lprob); int best_rels[MAX_ROLE_SIZE]; int fanout = get_best_labels(ap, as_opt, rel_min_prob, mp->role_num[q_bank], best_rels); int i; for (i = 0; i < fanout; i++) { OPTION *new_opt = create_option_light(SRL_STEP, 1, SRL_LA[q_bank], best_rels[i], as_opt, as_opt->period, &as_opt->stack, &as_opt->srl_stack, as_opt->queue, pt_clone(as_opt->pt), ps_clone(as_opt->ps), &mp->out_link_act, ACTION_NUM); ps_add_link(new_opt->ps, h, d, best_rels[i]); set_links(ap, mp, new_opt, sent); fill_lprob(new_opt); ol = increase_list_asc(ol, new_opt); queue_size++; } pt_free(&(as_opt->pt)); ps_free(&(as_opt->ps)); as_opt->pt = NULL; as_opt->ps = NULL; if (fanout == 0) { free_option(as_opt); } } } q_bank = -1; //check SRL_RA int s_bank = sent->bank[st_peek(&opt->srl_stack)]; if (s_bank >= 0 && as.acts[SRL_RA[s_bank]]) { int d = opt->queue; int h = st_peek(&opt->srl_stack); if (log(opt->outputs.q[SRL_RA[s_bank]]) + opt->lprob >= min_lprob) { //create sequence of RA operations //update queue and stack OPTION *as_opt = create_option(SRL_STEP, 0, opt->previous_act, SRL_RA[s_bank], opt, opt->period, &opt->stack, &opt->srl_stack, opt->queue, pt_clone(opt->pt), ps_clone(opt->ps), &mp->out_link_sem_ra_label[s_bank], mp->role_num[s_bank]); set_links(ap, mp, as_opt, sent); comp_option(ap, mp, as_opt); double rel_min_prob = exp(min_lprob - as_opt->lprob); int best_rels[MAX_ROLE_SIZE]; int fanout = get_best_labels(ap, as_opt, rel_min_prob, mp->role_num[s_bank], best_rels); int i; for (i = 0; i < fanout; i++) { OPTION *new_opt = create_option_light(SRL_STEP, 1, SRL_RA[s_bank], best_rels[i], as_opt, as_opt->period, &as_opt->stack, &as_opt->srl_stack, as_opt->queue, pt_clone(as_opt->pt), ps_clone(as_opt->ps), &mp->out_link_act, ACTION_NUM); ps_add_link(new_opt->ps, h, d, best_rels[i]); set_links(ap, mp, new_opt, sent); fill_lprob(new_opt); ol = increase_list_asc(ol, new_opt); queue_size++; } pt_free(&(as_opt->pt)); ps_free(&(as_opt->ps)); as_opt->pt = NULL; as_opt->ps = NULL; if (fanout == 0) { free_option(as_opt); } } } s_bank = -1; //check SRL_RED if (as.acts[SRL_RED]) { if (log(opt->outputs.q[SRL_RED]) + opt->lprob >= min_lprob) { //create sequence of reduce operation //update queue and stack OPTION *as_opt = create_option_light(SRL_STEP, 1, SRL_RED, SRL_RED, opt, opt->period, &opt->stack, &opt->srl_stack, opt->queue, pt_clone(opt->pt), ps_clone(opt->ps), &mp->out_link_act, ACTION_NUM); st_pop(&as_opt->srl_stack); set_links(ap, mp, as_opt, sent); fill_lprob(as_opt); ol = increase_list_asc(ol, as_opt); queue_size++; } } //check SRL_SWITCH if (as.acts[SRL_SWITCH]) { if (log(opt->outputs.q[SRL_SWITCH]) + opt->lprob >= min_lprob) { OPTION *as_opt = create_option_light(SYNT_STEP, 1, SRL_SWITCH, SRL_SWITCH, opt, opt->period, &opt->stack, &opt->srl_stack, opt->queue, pt_clone(opt->pt), ps_clone(opt->ps), &mp->out_link_act, ACTION_NUM); set_links(ap, mp, as_opt, sent); fill_lprob(as_opt); ol = increase_list_asc(ol, as_opt); queue_size++; } } if (as.acts[SRL_FLIP]) { if (log(opt->outputs.q[SRL_FLIP]) + opt->lprob >= min_lprob) { OPTION *as_opt = create_option_light(SRL_STEP, 1, SRL_FLIP, SRL_FLIP, opt, opt->period, &opt->stack, &opt->srl_stack, opt->queue, pt_clone(opt->pt), ps_clone(opt->ps), &mp->out_link_act, ACTION_NUM); int srl_s = st_pop(&as_opt->srl_stack); int srl_s_under = st_pop(&as_opt->srl_stack); st_push(&as_opt->srl_stack, srl_s); st_push(&as_opt->srl_stack, srl_s_under); set_links(ap, mp, as_opt, sent); fill_lprob(as_opt); ol = increase_list_asc(ol, as_opt); queue_size++; } } pt_free(&(opt->pt)); ps_free(&(opt->ps)); opt->pt = NULL; opt->ps = NULL; if (opt->next_options->prev == NULL) { free_options(opt); } if (queue_size > QUEUE_SIZE_LIMIT) { printf("Warning: indiscriminately pruning search queue from length %d to %d\n", queue_size, (int) (QUEUE_SIZE_LIMIT / 1.5)); OPTION_LIST *ol2; int cnt = 0; for (ol2 = ol; ol2 != NULL; ol2 = ol2->prev) { cnt++; if (cnt > (int) (QUEUE_SIZE_LIMIT / 1.5)) { // reduce to 2/3 of limit prune_options(ol2, 0.0); break; } } queue_size = cnt - 1; } return ol; }