Ejemplo n.º 1
0
/**
 * This function minimizes the given automaton. Note
 * that it must be deterministic. For more information,
 * see comments in this library's .h file.
 */
void elag_minimize(SingleGraph automaton,int level) {
struct list_int* initials=get_initial_states(automaton);
if (initials==NULL) {
   /* No initial state should mean 'empty automaton' */
   if (automaton->number_of_states!=0) {
      /* If not, we fail */
      fatal_error("No initial state in non empty automaton in elag_minimize\n");
   }
   return;
}
if (initials->next!=NULL) {
   fatal_error("Non-deterministic automaton in elag_minimize\n");
}
free_list_int(initials);
if (level>0) {
   /* If necessary, we remove transitions that are included in the
    * default ones */
   compact_default_transitions(automaton);
}
SymbolAlphabet* alph=build_symbol_alphabet(automaton);
TransitionCollection** transitions=build_transition_collections(automaton,alph);
/* Now that we have numbered transitions, we don't need the symbol
 * alphabet anymore */
free_SymbolAlphabet(alph);
int nbColors;
int nbShades;
int* color=(int*)calloc(automaton->number_of_states,sizeof(int));
if (color==NULL) {
   fatal_alloc_error("elag_minimize");
}
int* shade=init_colors(automaton,&nbShades);
do {
   int s;
   /* We copy the shades into the color array */
   for (s=0;s<automaton->number_of_states;s++) {
      color[s]=shade[s];
   }
   nbColors=nbShades;
   nbShades=0;
   /* We update the colors of the transitions' destination states */
   update_colors(transitions,color,automaton->number_of_states);
   /* Now, for each state #s, we look for its shade, comparing it with
    * all the states #i so that i<s */
   for (s=0;s<automaton->number_of_states;s++) {
      shade[s]=get_shade(s,transitions,color,shade,&nbShades);
   }
   /* We stop when no more shades have been introduced */
} while (nbColors!=nbShades);
int* chosen=choose_states(color,nbColors,automaton->number_of_states);
for (int i=0;i<automaton->number_of_states;i++) {
   free_TransitionCollection(transitions[i]);
}
free(transitions);
free(shade);
/* We allocate the resulting automaton */
SingleGraph result=new_SingleGraph(nbColors,PTR_TAGS);
for (int c=0;c<nbColors;c++) {
   SingleGraphState state=add_state(result);
   SingleGraphState original=automaton->states[chosen[c]];
   /* We set the initiality and finality of the state */
   state->control=original->control;
   state->outgoing_transitions=original->outgoing_transitions;
   original->outgoing_transitions=NULL;
   /* We renumber the transitions' destination states */
   for (Transition* t1=state->outgoing_transitions;t1!=NULL;t1=t1->next) {
      t1->state_number=color[t1->state_number];
   }
   state->default_state=original->default_state;
}
/* Now we have to replace the old automaton by the new one */
move_SingleGraph(automaton,&result,free_symbol);
/* And we don't need these arrays anymore */
free(color);
free(chosen);
}
Ejemplo n.º 2
0
int test_palette(struct pldraw *pldraw, char * const *opts, int opts_n)
{
	struct plep *plep;
	static const int greys = 256;
	struct plep_rect rect;
	struct plep_rect area;
	int ret = 0;
	int cur_rotation;
	int xres;
	int yres;
	float x_grid, y_grid;
	int width;
	int tmp;
	int i;

	assert(pldraw != NULL);
	assert(g_initialised);

	plep = pldraw_get_plep(pldraw);
	plep_set_opt(plep, PLEP_SYNC_UPDATE, 1);
	xres = pldraw_get_xres(pldraw);
	yres = pldraw_get_yres(pldraw);
	cur_rotation = pldraw_get_rotation(pldraw);

	if (yres > xres) {
		const int new_rotation =
			cur_rotation + ((cur_rotation % 180) ? -90 : 90);

		pldraw_set_rotation(pldraw, new_rotation);
		xres = pldraw_get_xres(pldraw);
		yres = pldraw_get_yres(pldraw);
	}

	x_grid = xres / 24.0;
	y_grid = yres / 18.0;

	LOG("greyscale palettes");

	area.a.x = x_grid * 0.5;
	area.a.y = y_grid * 0.5;
	area.b.x = x_grid * 23.5;
	area.b.y = y_grid * 3.0;
	width = area.b.x - area.a.x;
	memcpy(&rect, &area, sizeof rect);
	rect.b.x = rect.a.x;
	--rect.b.y;

	for (i = 0; i < width; ++i) {
		const int grey = i * greys / width;
		const pldraw_color_t col = pldraw_get_grey(pldraw, grey);
		pldraw_draw_line(pldraw, col, &rect);
		++rect.a.x;
		++rect.b.x;
	}

	draw_border(pldraw, g_black, &area);

	area.a.y = y_grid * 3.5;
	area.b.y = y_grid * 6.0;
	memcpy(&rect, &area, sizeof rect);

	for (i = 0; i < 16; ++i) {
		const int grey = pldraw_grey_16[i];
		const pldraw_color_t col = pldraw_get_grey(pldraw, grey);
		rect.b.x = area.a.x + (width * (i + 1)) / 16;
		pldraw_fill_rect(pldraw, col, &rect);
		rect.a.x = rect.b.x;
	}

	draw_border(pldraw, g_black, &area);

	if (plep_update_screen(plep, g_clear_wf) < 0)
		ret = -1;

	LOG("primary and secondary colours");

	width = x_grid * 24;
	width /= 90;
	width /= 2;
	width += 1;
	width *= 90;

	tmp = (x_grid * 21.5 - width) / 2;

	rect.a.x = x_grid * 0.5;
	rect.a.y = y_grid * 6.5;
	rect.b.x = x_grid * 0.5 + tmp;
	rect.b.y = y_grid * 9.5;
	pldraw_fill_rect(pldraw, g_red, &rect);

	rect.a.y = y_grid * 10.5;
	rect.b.y = y_grid * 13.5;
	pldraw_fill_rect(pldraw, g_green, &rect);

	rect.a.y = y_grid * 14.5;
	rect.b.y = y_grid * 17.5;
	pldraw_fill_rect(pldraw, g_blue, &rect);

	rect.a.x = x_grid * 1.5 + tmp;
	rect.a.y = y_grid * 6.5;
	rect.b.x = x_grid * 1.5 + (2 * tmp);
	rect.b.y = y_grid * 9.5;
	pldraw_fill_rect(pldraw, g_cyan, &rect);

	rect.a.y = y_grid * 10.5;
	rect.b.y = y_grid * 13.5;
	pldraw_fill_rect(pldraw, g_magenta, &rect);

	rect.a.y = y_grid * 14.5;
	rect.b.y = y_grid * 17.5;
	pldraw_fill_rect(pldraw, g_yellow, &rect);

	area.a.x = x_grid * 0.5;
	area.a.y = y_grid * 6.5;
	area.b.x = rect.b.x;
	area.b.y = y_grid * 17.5;

	if (plep_update(plep, &area, g_clear_wf) < 0)
		ret = -1;

	LOG("colour shades");

	area.a.x = x_grid * 23.5 - width;
	area.a.y = y_grid * 6.5;
	area.b.x = x_grid * 23.5;
	area.b.y = y_grid * 17.5;
	i = 0;

	rect.a.x = area.a.x;
	rect.a.y = area.a.y;
	rect.b.y = area.b.y;

	for (i = 1; i <= 90; ++i) {
		const int r = pldraw_grey_16[get_shade(0, i)];
		const int g = pldraw_grey_16[get_shade(30, i)];
		const int b = pldraw_grey_16[get_shade(60, i)];
		const pldraw_color_t col =
			pldraw_get_color(pldraw, r, g, b);
		rect.b.x = area.a.x + (width * i / 90);
		pldraw_fill_rect(pldraw, col, &rect);
		rect.a.x = rect.b.x;
	}

	if (plep_update(plep, &area, g_clear_wf) < 0)
		ret = -1;

	pldraw_set_rotation(pldraw, cur_rotation);

	return ret;
}