示例#1
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;
}
示例#2
0
int test_delta_delta_star(){
	BEGIN_TEST;

	int result = 1;

	Automate* automate = creer_automate();


	ajouter_etat( automate, 3 );
	ajouter_etat( automate, 5 );
	ajouter_transition( automate, 3, 'a', 5 );
	ajouter_transition( automate, 5, 'b', 3 );
	ajouter_transition( automate, 5, 'a', 5 );
	ajouter_transition( automate, 5, 'c', 6 );
	ajouter_etat_initial( automate, 3 );
	ajouter_etat_final( automate, 6 );

	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 )

		&& est_un_etat_initial_de_l_automate( automate, 3 )
		&& ! est_un_etat_initial_de_l_automate( automate, 5 )
		&& ! est_un_etat_initial_de_l_automate( automate, 6 )

		&& ! 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 )
		
		&& est_une_lettre_de_l_automate( automate, 'a' )
		&& est_une_lettre_de_l_automate( automate, 'b' )
		&& est_une_lettre_de_l_automate( automate, 'c' )
		&& ! est_une_lettre_de_l_automate( automate, 'd' )

		&& est_une_transition_de_l_automate( automate, 3, 'a', 5 )
		&& 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, 'c', 6 )
		
		&& ! est_une_transition_de_l_automate( automate, 3, 'b', 5 )
		&& ! est_une_transition_de_l_automate( automate, 1, 'b', 5 )
		&& ! est_une_transition_de_l_automate( automate, 3, 'a', 1 )
		, result
	);

	Ensemble * etat_courant = creer_ensemble( NULL, NULL, NULL );
	ajouter_element( etat_courant, 3 ); 

	deplacer_ensemble( etat_courant, delta( automate, etat_courant, 'a' ) );

	TEST(
		1
		&& est_dans_l_ensemble( etat_courant, 5 )
		&& taille_ensemble( etat_courant ) ==1
		, result
	);

	deplacer_ensemble(
		etat_courant, delta_star( automate, etat_courant, "ab" ) 
	);

	TEST(
		1
		&& est_dans_l_ensemble( etat_courant, 3 )
		&& taille_ensemble( etat_courant ) ==1
		, result
	);

	deplacer_ensemble(
		etat_courant, delta_star( automate, etat_courant, "ac" )
	);

	TEST(
		1
		&& est_dans_l_ensemble( etat_courant, 6 )
		&& taille_ensemble( etat_courant ) ==1
		, result
	);

	deplacer_ensemble(
		etat_courant, delta_star( automate, etat_courant, "" )
	);

	TEST(
		1
		&& est_dans_l_ensemble( etat_courant, 6 )
		&& taille_ensemble( etat_courant ) ==1
		, result
	);

	deplacer_ensemble(
		etat_courant, delta_star( automate, etat_courant, "c" )
	);

	TEST(
		1
		&& taille_ensemble( etat_courant ) == 0
		, result
	);

	liberer_ensemble( etat_courant );
	liberer_automate( automate );

	return result;
}
示例#3
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;
}