示例#1
0
Automate* copier_automate( const Automate* automate ){
	Automate * res = creer_automate();
	Ensemble_iterateur it1;
	// On ajoute les états de l'automate
	for(
		it1 = premier_iterateur_ensemble( get_etats( automate ) );
		! iterateur_ensemble_est_vide( it1 );
		it1 = iterateur_suivant_ensemble( it1 )
	){
		ajouter_etat( res, get_element( it1 ) );
	}
	// On ajoute les états initiaux
	for(
		it1 = premier_iterateur_ensemble( get_initiaux( automate ) );
		! iterateur_ensemble_est_vide( it1 );
		it1 = iterateur_suivant_ensemble( it1 )
	){
		ajouter_etat_initial( res, get_element( it1 ) );
	}
	// On ajoute les états finaux
	for(
		it1 = premier_iterateur_ensemble( get_finaux( automate ) );
		! iterateur_ensemble_est_vide( it1 );
		it1 = iterateur_suivant_ensemble( it1 )
	){
		ajouter_etat_final( res, get_element( it1 ) );
	}
	// On ajoute les lettres
	for(
		it1 = premier_iterateur_ensemble( get_alphabet( automate ) );
		! iterateur_ensemble_est_vide( it1 );
		it1 = iterateur_suivant_ensemble( it1 )
	){
		ajouter_lettre( res, (char) get_element( it1 ) );
	}
	// On ajoute les transitions
	Table_iterateur it2;
	for(
		it2 = premier_iterateur_table( automate->transitions );
		! iterateur_ensemble_est_vide( it2 );
		it2 = iterateur_suivant_ensemble( it2 )
	){
		Cle * cle = (Cle*) get_cle( it2 );
		Ensemble * fins = (Ensemble*) get_valeur( it2 );
		for(
			it1 = premier_iterateur_ensemble( fins );
			! iterateur_ensemble_est_vide( it1 );
			it1 = iterateur_suivant_ensemble( it1 )
		){
			int fin = get_element( it1 );
			ajouter_transition( res, cle->origine, cle->lettre, fin );
		}
	};
	return res;
}
示例#2
0
Automate *automate_accessible( const Automate * automate){
	Automate* clone = copier_automate(automate);
	Ensemble* etats = creer_ensemble(NULL, NULL, NULL);
	Ensemble_iterateur it_etat;
	Ensemble_iterateur it_lettre;

	// On calcule l'ensemble des états accessibles
	for(it_etat = premier_iterateur_ensemble(get_initiaux(automate));
		! iterateur_ensemble_est_vide( it_etat );
		it_etat = iterateur_suivant_ensemble( it_etat )){
		ajouter_elements(etats, etats_accessibles(automate, get_element(it_etat)));
		ajouter_element(etats, get_element(it_etat));
	}

	// On détermine les états qui ne sont pas accessibles => ceux qui sont dans get_etats mais pas dans etats
	Ensemble* non_accessible = creer_difference_ensemble(get_etats(automate), etats);

	// On parcourt l'ensemble obtenu	
	for(it_etat = premier_iterateur_ensemble(non_accessible);
		! iterateur_ensemble_est_vide( it_etat );
		it_etat = iterateur_suivant_ensemble( it_etat )){

		const intptr_t etat_courant = get_element(it_etat);

		// On cherche toutes les transitions partant d'un état
		for(it_lettre = premier_iterateur_ensemble(get_alphabet(automate));
			! iterateur_ensemble_est_vide( it_lettre );
			it_lettre = iterateur_suivant_ensemble( it_lettre )){
			
			Cle cle;
			initialiser_cle( &cle, etat_courant, get_element(it_lettre));				
			Table_iterateur it = trouver_table( clone->transitions, (intptr_t) &cle );				
			// Si on trouve une transition partant d'un état non accessible
			if( !iterateur_est_vide( it ) ){				
				delete_table( clone->transitions, (intptr_t) &cle); // on la supprime
			}			
		}
		// si c'est un état final, on pense à le supprimer
		if (est_un_etat_final_de_l_automate(automate, etat_courant))
		{
			retirer_element(clone->finaux, etat_courant);			
		}
		// si c'est un état initial, on pense à le supprimer
		if (est_un_etat_initial_de_l_automate(automate, etat_courant))
		{
			retirer_element(clone->initiaux, etat_courant);			
		}
	}
	// On supprime tous les états non accessibles de l'automate
	deplacer_ensemble(clone->etats, etats);
	
	return clone;
}
示例#3
0
void print_automate( const Automate * automate ){
	printf("- Etats : ");
	print_ensemble( get_etats( automate ), NULL );
	printf("\n- Initiaux : ");
	print_ensemble( get_initiaux( automate ), NULL );
	printf("\n- Finaux : ");
	print_ensemble( get_finaux( automate ), NULL );
	printf("\n- Alphabet : ");
	print_ensemble( get_alphabet( automate ), print_lettre );
	printf("\n- Transitions : ");
	print_table( 
		automate->transitions,
		( void (*)( const intptr_t ) ) print_cle, 
		( void (*)( const intptr_t ) ) print_ensemble_2,
		""
	);
	printf("\n");
}
示例#4
0
/**
 * \par Implémentation
 * La fonction ne considère que les derniers états atteints avant de tester si au moins un est final</br>
 * \par
 * On lit un mot depuis l'ensemble des états initiaux puis réitère à partir des voisins trouvés à l'étape précédente
 * @param  automate
 * @param  mot
 * @return
 */
int le_mot_est_reconnu( const Automate* automate, const char* mot ){
	Ensemble * fins = copier_ensemble(get_initiaux(automate));
	int i;
	for(i = 0; i < strlen(mot); i++)
	{
		fins = delta(automate, fins, mot[i]);
	}

	Ensemble_iterateur it1;
	for(
		it1 = premier_iterateur_ensemble(fins);
		! iterateur_ensemble_est_vide( it1 );
		it1 = iterateur_suivant_ensemble( it1 )
	){
		if (est_un_etat_final_de_l_automate(automate, get_element(it1)))
			return 1;
	}
	return 0;
}
示例#5
0
int test_execute_fonctions(){
	BEGIN_TEST

	int res = 1;
	
	Automate * automate2;
	Automate * automate;
	Automate * result = NULL;
	Ensemble * ens = NULL;
	Ensemble * ens1 = NULL;
	
	automate  = creer_automate();
	result = NULL;
		ajouter_lettre( automate, 'a' );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
		ajouter_etat_final( automate, 1 );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
		ajouter_etat_initial( automate, 1 );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	get_initiaux( automate );
	liberer_automate( automate );

	automate  = creer_automate();
	get_finaux( automate );
	liberer_automate( automate );

	automate  = creer_automate();
	get_alphabet( automate );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
	est_un_etat_initial_de_l_automate( automate, 1 );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
	est_un_etat_final_de_l_automate( automate, 1 );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
	est_une_lettre_de_l_automate( automate, 'a' );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	ens = NULL;
	ens1 = creer_ensemble( NULL, NULL, NULL );
	ens =  delta_star( automate, ens1, "aba" );
	if( ens ) liberer_ensemble( ens );
	liberer_ensemble( ens1 );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
	le_mot_est_reconnu( automate, "abaa" );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
		result =  mot_to_automate( "abbaa" );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	ens = NULL;
	ens = etats_accessibles( automate, 0 );
	if( ens ) liberer_ensemble( ens );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
	result = automate_accessible( automate );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
	result = miroir( automate );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
	result = automate_co_accessible(automate );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
	result = creer_automate_des_prefixes( automate );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
	result = creer_automate_des_suffixes( automate );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
	result = creer_automate_des_facteurs( automate );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	automate  = creer_automate();
	result = NULL;
	ens = creer_ensemble( NULL, NULL, NULL );
	result =  creer_automate_des_sur_mot(
		automate, ens
	);
	if( result ) liberer_automate( result );
	liberer_automate( automate );
	liberer_ensemble( ens );

	automate  = creer_automate();
	automate2  = creer_automate();
	result = NULL;
	result = creer_automate_de_concatenation( automate, automate2 );
	if( result ) liberer_automate( result );
	liberer_automate( automate );
	liberer_automate( automate2 );

	automate  = creer_automate();
	result = NULL;
	result = creer_automate_des_sous_mots( automate );
	if( result ) liberer_automate( result );
	liberer_automate( automate );

	return res;
}
示例#6
0
int test_creer_automate(){
	BEGIN_TEST;

	int result = 1;

	Automate * automate = creer_automate();

	ajouter_lettre( automate, 'a' );
	ajouter_lettre( automate, 'd' );

	ajouter_etat( automate, 3 );
	ajouter_etat_final( automate, 6 );

	ajouter_transition( automate, 3, 'a', 5 );
	ajouter_transition( automate, 3, 'b', 3 );

	ajouter_etat_final( automate, 5 );
	ajouter_etat_initial( automate, 3 );

	TEST( 
		1
		&& est_un_etat_de_l_automate( automate, 3)
		&& est_un_etat_de_l_automate( automate, 5)
		&& est_un_etat_de_l_automate( automate, 6)
		, result
	);
	TEST( 
		1
		&& ! est_un_etat_final_de_l_automate( automate, 3)
		&& est_un_etat_final_de_l_automate( automate, 5)
		&& est_un_etat_final_de_l_automate( automate, 6)
		, result
	);
	TEST( 
		1
		&& est_un_etat_initial_de_l_automate( automate, 3)
		&& ! est_un_etat_initial_de_l_automate( automate, 5)
		, result
	);
	TEST( 
		1
		&& est_une_lettre_de_l_automate( automate, 'a')
		&& est_une_lettre_de_l_automate( automate, 'b')
		&& est_une_lettre_de_l_automate( automate, 'd')
		&& ! est_une_lettre_de_l_automate( automate, 'c')
		, result
	);
	TEST( 
		1
		&& est_une_transition_de_l_automate( automate, 3, 'a', 5 )
		&& est_une_transition_de_l_automate( automate, 3, 'b', 3 )
		&& ! est_une_transition_de_l_automate( automate, 3, 'b', 5 )
		&& ! est_une_transition_de_l_automate( automate, 3, 'a', 3 )
		&& ! est_une_transition_de_l_automate( automate, 5, 'a', 3 )
		&& ! est_une_transition_de_l_automate( automate, 5, 'b', 3 )
		&& ! est_une_transition_de_l_automate( automate, 5, 'a', 5 )
		&& ! est_une_transition_de_l_automate( automate, 5, 'b', 5 )
		, result
	);

	const Ensemble* ens = get_initiaux( automate );

	TEST( 
		1
		&& ens
		&& est_dans_l_ensemble( ens, 3 )
		&& ! est_dans_l_ensemble( ens, 5 )
		&& ! est_dans_l_ensemble( ens, 6 )
		, result
	);

	ens = get_finaux( automate );

	TEST( 
		1
		&& ens
		&& ! est_dans_l_ensemble( ens, 3 )
		&& est_dans_l_ensemble( ens, 5 )
		&& est_dans_l_ensemble( ens, 6 )
		, result
	);

	ens = get_alphabet( automate );

	TEST( 
		1
		&& ens
		&& est_dans_l_ensemble( ens, 'a')
		&& est_dans_l_ensemble( ens, 'b')
		&& ! est_dans_l_ensemble( ens, 'c')
		&& est_dans_l_ensemble( ens, 'd')
		, result
	);


	liberer_automate( automate );

	return result;
}
void creergraphe(Automate *a){
  FILE* f=fopen("./auto.gv","w+");
  fprintf(f, "digraph graphe {\n\trankdir=S;\n\tsize=\"8,5\"\n\tnode [shape = doublecircle];\n\t");
  Ensemble_iterateur it;
  for(it = premier_iterateur_ensemble(get_finaux(a));
      ! iterateur_ensemble_est_vide( it );
      it = iterateur_suivant_ensemble( it )){
    fprintf(f, "%d ", (int)get_element( it));
  }
  fprintf(f,";\n\t");
  
  fprintf(f,"\n\tnode [shape = circle];\n\t"); 
  Table_iterateur it2;
  for( it2 = premier_iterateur_table(get_transitions( a ));
       ! iterateur_ensemble_est_vide( it2 );
       it2 = iterateur_suivant_ensemble( it2 )
       ){
    Cle * cle = (Cle*) get_cle( it2 );
    Ensemble * fins = (Ensemble*) get_valeur( it2 );
    for( it = premier_iterateur_ensemble( fins );
	 ! iterateur_ensemble_est_vide( it );
	 it = iterateur_suivant_ensemble( it )
	 ){ 
      int fin = get_element( it );
      fprintf(f,"%d",(int)get_origine_cle(cle));
    
      fprintf(f," -> ");
      fprintf(f,"%d",(int)fin);

      fprintf(f," [ label =\"");  
      char lettre=get_lettre_cle(cle);
      fprintf(f,"%c",lettre);

    
      fprintf(f, ":");
      fprintf(f,"%d",get_cout_cle(cle));

      fprintf(f,"\"];\n\t");
    }
  }   
  fprintf(f,"node [shape = point];\n\t");
  for(it = premier_iterateur_ensemble(get_initiaux(a));
      ! iterateur_ensemble_est_vide( it );
      it = iterateur_suivant_ensemble( it )){
    fprintf(f,"i%d ",(int)get_element(it));
  } 
  fprintf(f,";\n\t");
  for(it = premier_iterateur_ensemble(get_initiaux(a));
      ! iterateur_ensemble_est_vide( it );
      it = iterateur_suivant_ensemble( it )){
    fprintf(f,"i%d",(int)get_element(it));
    fprintf(f," -> ");
    fprintf(f,"%d",(int)get_element(it));

    fprintf(f," [ label =\"start\" ];\n\t");
  }
  
  fprintf(f,"}\n");
  fclose(f);

}
示例#8
0
int est_un_etat_initial_de_l_automate( const Automate* automate, int etat ){
	return est_dans_l_ensemble(get_initiaux(automate), etat);
}
示例#9
0
// À chaque itération de l'algo, on prend une lettre du premier ou du second automate, jusqu'à ce qu'on arrive à la dernière lettre.
// Produit cartésien des états.
// Exemple : mot 1 : aaaa, mot 2 : bbbb
// Quelques résulats possibles : aabbaabb; aaaabbbb: bbbbaaaa; aaababbb: baababba
Automate * creer_automate_du_melange(
	const Automate* automate1,  const Automate* automate2
){
	int i, j, k, nbelau1, nbelau2, etat_act, et1, et2;
	int ** nouveaux_etats = NULL;
	Automate * melange = creer_automate();
	Ensemble_iterateur it1, it2;
	Table_iterateur it_transition;
	Table *cle1 = creer_table(
		( int(*)(const intptr_t, const intptr_t) ) comparer_int , 
		( intptr_t (*)( const intptr_t ) ) copier_int,
		( void(*)(intptr_t) ) supprimer_int
	);
	Table *cle2 = creer_table(
		( int(*)(const intptr_t, const intptr_t) ) comparer_int , 
		( intptr_t (*)( const intptr_t ) ) copier_int,
		( void(*)(intptr_t) ) supprimer_int
	);
	const Ensemble * finaux1 = get_finaux(automate1); const Ensemble * finaux2 = get_finaux(automate2);
	const Ensemble * initiaux1 = get_initiaux(automate1); const Ensemble * initiaux2 = get_initiaux(automate2);
	
	nbelau1 = taille_ensemble(automate1->etats);
	nbelau2 = taille_ensemble(automate2->etats);
	nouveaux_etats = malloc(nbelau1 * sizeof(int *));
	for(i=0; i<nbelau1; i++)
		nouveaux_etats[i]=malloc(nbelau2 * sizeof(int));
	k = 0;
	
	// Création des états, états initiaux, états finaux de l'automate.
	for (it1 = premier_iterateur_ensemble(automate1->etats), i=0; ! iterateur_ensemble_est_vide(it1); it1 = iterateur_suivant_ensemble(it1), i++){
		
		et1 = get_element(it1);
		add_table(cle1, et1, i);
		for (it2 = premier_iterateur_ensemble(automate2->etats), j=0; ! iterateur_ensemble_est_vide(it2); it2 = iterateur_suivant_ensemble(it2), j++){
			
			et2 = get_element(it2);
			ajouter_etat(melange, k);
			add_table(cle2, et2, j);
			if (est_dans_l_ensemble(finaux1, et1) && est_dans_l_ensemble(finaux2, et2))
				ajouter_etat_final(melange, k);
			if (est_dans_l_ensemble(initiaux1, et1) && est_dans_l_ensemble(initiaux2, et2))
				ajouter_etat_initial(melange, k);
			
			
			nouveaux_etats[i][j] = k;
			k++;
		}
	}
	
	// Les transitions sont ensuite crées
	// D'abord celles de l'ancien automate 1
	for (it_transition = premier_iterateur_table(automate1->transitions); !iterateur_est_vide(it_transition); it_transition = iterateur_suivant_table(it_transition)) {
		
		Cle * cle = (Cle*) get_cle(it_transition);
		Ensemble * fins = (Ensemble*) get_valeur(it_transition);

		for (it1 = premier_iterateur_ensemble(fins), i=0; ! iterateur_ensemble_est_vide(it1); it1 = iterateur_suivant_ensemble(it1), i++){
			
			etat_act = get_element(it1);
			for(i = 0; i < nbelau2; i++) {

				ajouter_transition(melange,
					nouveaux_etats[(int)get_valeur(trouver_table(cle1, cle->origine))][i],
					cle->lettre,
					nouveaux_etats[(int)get_valeur(trouver_table(cle1, etat_act))][i]);
			}
		}
	}
	
	// Puis celles de l'ancien automate 2
	for (it_transition = premier_iterateur_table(automate2->transitions); !iterateur_est_vide(it_transition); it_transition = iterateur_suivant_table(it_transition)) {
		
		Cle * cle = (Cle*) get_cle(it_transition);
		Ensemble * fins = (Ensemble*) get_valeur(it_transition);

		for (it1 = premier_iterateur_ensemble(fins), i=0; ! iterateur_ensemble_est_vide(it1); it1 = iterateur_suivant_ensemble(it1), i++){
			
			etat_act = get_element(it1);
			for(i = 0; i < nbelau1; i++) {

				ajouter_transition(melange,
					nouveaux_etats[i][(int)get_valeur(trouver_table(cle2, cle->origine))],
					cle->lettre,
					nouveaux_etats[i][(int)get_valeur(trouver_table(cle2, etat_act))]);
			}
		}
	}
	
	liberer_table(cle1);
	liberer_table(cle2);
	return melange;
}
示例#10
0
Automate * creer_automate_de_concatenation(
	const Automate* automate1, const Automate* automate2
	){
	/**
	 * \par Implémentation
	 * 
	 * On créé un automate, copie de automate1 avec comme états finaux ceux de automate2
	 */
	 Automate* concat = copier_automate(automate1);
	 deplacer_ensemble(concat->finaux, automate2->finaux);


	/**
	 * Puis on créé un modificateur qui nous permet de passer en paramètres de fonction
	 * l'automate de destination et une valeur de décalage des états.
	 * Cette valeur permet de ne pas avoir deux états avec la même valeur.
	 */
	 int decalage = get_max_etat(automate1);
	 AutomateInt* modificateur = creer_automate_int();
	 modificateur->automate = concat;
	 modificateur->valeur = decalage;

	/**
	 * On ajoute les transitions de l'automate 2 avec les états décalés.
	 */
	 pour_toute_transition(automate2, incrementer_etats_transition, modificateur);
	 liberer_automate_int(modificateur);

	/**
	 * Pour chaque état initial du second automate
	 */
	 Ensemble_iterateur initial2;
	 for(
	 	initial2 = premier_iterateur_ensemble(get_initiaux(automate2));
	 	! iterateur_ensemble_est_vide( initial2 );
	 	initial2 = iterateur_suivant_ensemble( initial2 )){
		/**
		 * Pour chaque lettre de son alphabet
		 */
		 Ensemble_iterateur lettre;
		 for(
		 	lettre = premier_iterateur_ensemble(get_alphabet(automate2));
		 	! iterateur_ensemble_est_vide(lettre);
		 	lettre = iterateur_suivant_ensemble(lettre)){

		 	Cle cle;
		 	printf("initial2 : %d\n", (int) get_element(initial2));
		 	printf("lettre : %c\n", (char) get_element(lettre));
		 	initialiser_cle(&cle, (int) get_element(initial2), (char) get_element(lettre));
		 	Table_iterateur destination = trouver_table(automate2->transitions, (intptr_t) &cle);
		 	printf("avant clé\n");
		 	print_cle(&cle);
		 	printf("après clé\n");
		 	if (!iterateur_est_vide(destination)){
		 		AutomateTransition* modif_trans = creer_automate_transition();
		 		modif_trans->automate = concat;
		 		modif_trans->lettre = get_element(lettre);

		 		Ensemble* destinations = (Ensemble*) get_valeur(destination);
		 		Ensemble_iterateur etat_dest;
				/**
				 * Pour chaque transition de la forme (i2, a2, q2), avec i2 intial, a2 lettre de l'alphabet
				 * et q2 état de l'automate2
				 */
				for(
				 	etat_dest = premier_iterateur_ensemble(destinations);
				 	! iterateur_ensemble_est_vide(etat_dest);
				 	etat_dest = iterateur_suivant_ensemble(etat_dest)){
				 	modif_trans->destination = get_element(etat_dest)+decalage;
					/**
					 * On ajoute une transition dans l'automate de concaténation ayant pour origine
					 * un état initial, la lettre a2 et l'état q2
					 */
					 pour_tout_element(get_finaux(automate1), simuler_epsilon_transition, modif_trans);
				}
				initialiser_cle(&cle, (int) get_element(initial2) + decalage, get_element(lettre));
		 		delete_table(concat->transitions, (intptr_t) &cle);
		 		liberer_automate_transition(modif_trans);
			}
		}
	 }

	return concat;
}