Exemple #1
0
void
s3_cfg_write_simple(s3_cfg_t *_cfg, const char *_fn)
{
  FILE *file = NULL;
  s3_arraylist_t *rules = NULL;
  s3_cfg_rule_t *rule = NULL;
  int i, j, count;

  assert(_cfg != NULL);
  assert(_fn != NULL);

  if ((file = fopen(_fn, "w")) == NULL)
    E_FATAL("Failed to open output file for writing");

  rules = &_cfg->rules;
  count = s3_arraylist_count(rules);
  for (i = 1; i < count; i++) {
    rule = (s3_cfg_rule_t *)s3_arraylist_get(rules, i);
    fprintf(file, "%f %s %d",
            rule->score, s3_cfg_id2str(_cfg, rule->src), rule->len);
    for (j = 0; j < rule->len; j++)
      fprintf(file, " %s", s3_cfg_id2str(_cfg, rule->products[j]));
  }
  fprintf(file, "\n");
  
  fclose(file);
}
static void
convert_cfg_rule(s3_cfg_t *_cfg,
		 s2_fsg_t *_fsg,
		 s3_cfg_rule_t *_rule,
		 int _src,
		 int _dest,
		 int *_expansions,
		 param_t *_params)
{
  int index;
  int i, j, n;
  int cur, u, v;
  s3_cfg_id_t id;
  s3_cfg_item_t *item;
  s3_cfg_rule_t *rule;
  s2_fsg_trans_t *trans;

  cur = _src;

  /* Check whether the target rule has any variables that exceeded the
   * expansion count
   */
  for (i = 0; i < _rule->len; i++) {
    id = _rule->products[i];
    if (_expansions[s3_cfg_id2index(id)] > S3_CFG_MAX_FSG_EXPANSION)
      return;
  }

  /* Iterate through the production variables. */
  for (i = 0; i < _rule->len; i++) {
    id = _rule->products[i];

    /* For each terminal:
     *   1.  Create a new state.
     *   2.  Add a single definite transition from the current state to the
     *       new state that emits the terminal.
     *   3.  Use the new state as the current state.
     */
    if (s3_cfg_is_terminal(id)) {
      trans = (s2_fsg_trans_t*)ckd_calloc(1, sizeof(s2_fsg_trans_t));
      trans->from_state = cur;
      trans->to_state = _fsg->n_state++;
      trans->prob = 1.0;
      trans->word = (char *)ckd_salloc(s3_cfg_id2str(_cfg, id));
      trans->next = _fsg->trans_list;
      _fsg->trans_list = trans;

      cur = _fsg->n_state;
    }

    /* For each non-terminal X:
     *   1.  Create a new destination state, v.
     *   2.  Increment expansion count for X.
     *   3.  For each cfg rule with X as source:
     *      a.  Create a new source state, u.
     *      b.  Convert the rule with u as src and v as dest.
     *      d.  Create a new epsilon transition from the current state to u 
     *          with the rule's expansion probability.
     *   4.  Set the current state to v.
     *   5.  Decrement expansion count for X.
     */
    else {
      index = s3_cfg_id2index(id);
      v = _fsg->n_state++;
      _expansions[index]++;
      item = (s3_cfg_item_t *)s3u_arraylist_get(&_cfg->item_info, index);
      n = s3u_arraylist_count(&item->rules);
      for (j = 0; j < n; j++) {
	rule = (s3_cfg_rule_t *)s3u_arraylist_get(&item->rules, j);
	u = _fsg->n_state++;
	convert_cfg_rule(_cfg, _fsg, rule, u, v, _expansions, _params);
	
	trans = (s2_fsg_trans_t*)ckd_calloc(1, sizeof(s2_fsg_trans_t));
	trans->from_state = cur;
	trans->to_state = u;
	trans->prob = rule->prob_score;
	trans->word = NULL;
	trans->next = _fsg->trans_list;
	_fsg->trans_list = trans;
      }
	
      cur = v;
      _expansions[index]--;
    }
  }
}