struct fsm* ConditionMerger::union_trees(struct fsm* fst1, struct fsm* fst2) {
  struct fsm* ret = fsm_topsort(
                      fsm_minimize(
                        fsm_determinize(
                          fsm_union(
                            fsm_copy(fst1),
                            fsm_copy(fst2)))));
  fsm_sort_arcs(ret, 1);
  return ret;
}
示例#2
0
文件: flags.c 项目: unhammer/hfst3
struct fsm *flag_eliminate(struct fsm *net, char *name) {

    struct flags *flags, *f, *ff;
    struct fsm *filter, *succeed_flags, *fail_flags, *self, *newfilter, *newnet;
    int flag, fstatus, found;

    filter = NULL;

    flags = flag_extract(net);
    /* Check that flag actually exists in net */
    if (name != NULL) { 
        for (found = 0, f = flags; f != NULL; f = f->next) {
            if (strcmp(name,f->name) == 0)
                found = 1;
        }
        if (found == 0) {
#ifdef ORIGINAL
	    fprintf(stderr,"Flag attribute '%s' does not occur in the network.\n",name);
#else
            // TODO: Handle this in some other way.
#endif
            return(net);
        }
    }

    flag = 0;

    for (f = flags; f != NULL; f = f->next) {

        if ((name == NULL || strcmp(f->name,name) == 0) &&
            (f->type | FLAG_UNIFY | FLAG_REQUIRE | FLAG_DISALLOW | FLAG_EQUAL)) {
            
            succeed_flags = fsm_empty_set();
            fail_flags = fsm_empty_set();
            self = flag_create_symbol(f->type, f->name, f->value);
            
            for (ff = flags, flag = 0; ff != NULL; ff = ff->next) {
                fstatus = flag_build(f->type, f->name, f->value, ff->type, ff->name, ff->value);
                if (fstatus == FAIL) {
                    fail_flags = fsm_minimize(fsm_union(fail_flags, flag_create_symbol(ff->type, ff->name, ff->value)));
                    flag = 1;
                }
                if (fstatus == SUCCEED) {
                    succeed_flags = fsm_minimize(fsm_union(succeed_flags, flag_create_symbol(ff->type, ff->name, ff->value)));
                    flag = 1;
                }
            }
        }

        if (flag) {
            if (f->type == FLAG_REQUIRE) {
                newfilter = fsm_complement(fsm_concat(fsm_optionality(fsm_concat(fsm_universal(), fail_flags)), fsm_concat(fsm_complement(fsm_contains(succeed_flags)), fsm_concat(self, fsm_universal()))));
                
            } else {
                newfilter = fsm_complement(fsm_contains(fsm_concat(fail_flags,fsm_concat(fsm_complement(fsm_contains(succeed_flags)),self))));
            }

            filter = (filter == NULL) ? newfilter : fsm_intersect(filter, newfilter);
        }
        flag = 0;
    }
    if (filter != NULL) {
        extern int g_flag_is_epsilon;
        int old_g_flag_is_epsilon;
        old_g_flag_is_epsilon = g_flag_is_epsilon;
        g_flag_is_epsilon = 0;
        newnet = fsm_compose(fsm_copy(filter),fsm_compose(net,fsm_copy(filter)));
        g_flag_is_epsilon = old_g_flag_is_epsilon;
    } else {
        newnet = net;
    }
    flag_purge(newnet, name);
    newnet = fsm_minimize(newnet);
    sigma_cleanup(newnet,0);
    xxfree(flags);
    return(fsm_topsort(newnet));
}