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; }
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)); }