Beispiel #1
0
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;         
    
}
Beispiel #2
0
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;
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}	
Beispiel #5
0
/*===========================================================================*
 *				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;
}
Beispiel #6
0
/*===========================================================================*
 *				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;
}
Beispiel #7
0
//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;
}