Archive for décembre, 2007

déc 20 2007

Système Expert en Smalltalk

Published by Romain Bouleis under Developpement

Système expert de diagnostic de panne de connexion Internet

Un système expert est un outil permettant de mettre en application un type d’intelligence artificielle. Son rôle est de reproduire le raisonnement d’un expert dans un domaine donné. Le premier système expert se nomme Dendral et permet d’identifier des constituants chimiques.
Pour réaliser une expertise, il doit proposer des solutions à des problèmes qui lui sont posés. Il fait cela en posant des questions aux utilisateurs et en fonction de leurs réponses, pose de nouvelles questions tout en restant cohérent avec les précédentes jusqu’à ce qu’il n’y ait plus de questions cohérentes à poser et qu’il ait proposé une solution. Par exemple, dans le système expert nommé Mycin permettant d’identifier des agents infectieux, une question peut porter sur le type de l’organisme, et propose deux choix, il est un bâtonnet ou une coque. Si la réponse donnée est bâtonnet, une des questions restant possibles ne pourra pas porter sur des médicaments permettant d’éradiquer les coques.
Pour fonctionner, un système expert est représenté par les éléments suivants: une base de connaissances constituée d’une base de faits et d’une base de règles puis un moteur d’inférence.

Lire la suite (pdf)
La base de faits en XML
La base de règles en XML

Mise à jour du 29/12/2007

Ce programme suscitant un peu d’intérêt, je joins les sources complètes. A défaut d’une image de Visual Works, je donne le fichier généré lors d’un « File out…»  du package. Ce procédé permet de garantir la compatibilité entre les différents systèmes d’exploitation.
Afin d’importer ce fichier, Ouvrir un nouveau « System browser»  et créer un nouveau package. Puis, dans le menu « Package» , choisir « File into…»  et selectionner le fichier joint.
Enfin, pour l’utiliser, voici le code à copier/coller (en remplaçant les chemins de vos fichiers XML) dans un workspace (F6 depuis la fenêtre principale) :


faits := FaitsCollection new.
faits load: '/home/uself/AccessoiresLinux/Developpement/Smalltalk/_Perso/faits.xml'.
regles := ReglesCollection new.
regles load: '/home/uself/AccessoiresLinux/Developpement/Smalltalk/_Perso/regles.xml'.
moteur := Moteur new.
lanceur := LanceurModel new regles: regles ; faits: faits ; moteur: moteur.
LanceurSystemeExpert openWithModel: lanceur.

Selectionner le tout, puis un clic droit, « Do it»  permettra de lancer l’interface de manière à gérer les règles et les faits ainsi qu’à lancer le moteur d’inférence.

Pour rappel, ce programme a été développé sous Visual Works 7.5.

Sources système expert

14 responses so far

déc 07 2007

Simulation d’un système de drainage dans une mine

Published by Romain Bouleis under Developpement, Réseaux

Simulation d’un système de drainage dans une mine en C++ et MPI avec une interface en Java

On s’intéresse ici à la réalisation d’un système de commande assurant une fonction de drainage dans une mine. Le but de ce système est de réguler le niveau d’eau au fond de la mine, par la mise en route d’une pompe lorsqu’un certain seuil (« niveau-eau-haut ») est atteint voir dépassé et ceci jusqu’à ce qu’il soit ramené au niveau d’un autre seuil (« niveau-eau-bas »).
La pompe ne doit toutefois pas fonctionner si les niveau en gaz toxiques présents dans la galerie, méthane et monoxyde de carbone, sont supérieurs à certains seuils (« seuil-CH4 » et « seuil CO »). Un ventilateur permet donc, lorsque cela est nécessaire, d’évacuer ces gaz vers la surface. On souhaite par ailleurs minimiser l’utilisation du ventilateur.

Drainage

Seront utilisés pour modéliser ce système :

  • MPI pour la communication en entre les différents processus (pompe, capteurs, ventilateur…)
  • C++ comme langage de développement pour l’applicatif
  • Le langage Java avec Swing pour l’interface graphique
  • Les threads et les sockets en C++ et en Java pour la communication entre l’applicatif et l’interface

Le rapport avec les sources en annexe.

No responses yet

déc 04 2007

Resume file copy with Java

Published by Romain Bouleis under Developpement

Reprendre la copie d’un fichier en Java

Voici une petite fonction dont le but est de copier un fichier, et le résumer si il existe déjà. Cette solution est très basique, et son implémentation demanderai quelques contrôles supplémentaires comme par exemple s’assurer que la taille du fichier de destination ne soit pas supérieur à celle du fichier source. Voici donc cette fonction :


public class FileTransfert {

	public static void resume(File in, File out) throws IOException {
		FileInputStream fis  = new FileInputStream(in);
		FileOutputStream fos = new FileOutputStream(out,true);

		try {
			int i;
			byte[] buf = new byte[1024];
			fis.skip(out.length());
			while ((i = fis.read(buf)) != -1) {
				fos.write(buf,0, i);
				//System.out.println(out.length());
			}
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		finally {
			if (fis != null)  fis.close();
			if (fos != null) fos.close();
		}
	}

	public static void main(String args[]) {
		try {
			resume(new File("/home/rb/test"), new File("/home/rb/test2"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Un peu plus sur les transferts de fichiers en Java ici .

2 responses so far

déc 02 2007

Représentation et transformation des Graphes Conceptuels

Published by Romain Bouleis under Developpement

La modélisation de phrases peut être faite à l’aide de « Graphes Conceptuels ». Ces graphes peuvent eux-mêmes être représentés par un fichier XML associé à une feuille de style XSL générant une image SVG.

Cette représentation à l’avantage de séparer les informations liées à la phrase et la mise en forme liée au graphe. On pourra ainsi avoir, pour la même phrase, plusieurs représentation possibles.

Le but du travail est de définir une représentation XML des phrases et une mise en forme XSL afin de pouvoir les afficher sous forme de graphes conceptuels et de prédicats.

Un graphe conceptuel est constitué de relations reliés à des concepts. Une relation peut avoir plusieurs concepts en entrées, mais un seul en sortie. Voici un exemple de graphe conceptuel représentant la phrase « Un étudiant et un professeur se rendent au cours de XML » :

Graphe

Lire le rapport complet
Toutes les sources

No responses yet

déc 02 2007

Communication entre Java et C++ grâce aux sockets

Published by Romain Bouleis under Developpement, Réseaux

Lors de la réalisation d’une application, j’ai été confronté au problème suivant : faire communiquer Java et C++. Il existe plusieurs moyen pour parvenir à cela :

  • L’utilisation des pipes
  • L’utilisation d’un fichier commun
  • L’utilisation des stdin et stdout
  • L’utilisation d’une solution réseau : corba, socket…

C’est cette dernière solution que j’ai choisi et dont ce billet va traiter.

Lors de ce type de communication, il faut nécessairement un serveur et un client. Le serveur devra être exécuté avant le client qui s’y connectera. Une fois la connexion établie, il n’y a plus de différences entre le client et le serveur, les deux attendront un éventuel message, et les deux seront prêt à en émettre.

Pour pouvoir se faire (être prêt à émettre et à recevoir en même temps), le client et le serveur devront être multithread, un thread sera chargé d’attendre un message et un autre d’en envoyer.

Dans cet exemple, l’application Java aura le rôle de serveur, et application C++ aura le rôle de client. Si vous comprenez bien le mécanisme, vous n’aurez pas de mal à les intervertir.

Tout d’abord, intéressons nous au serveur (Serveur.java)

Pour faire un Thread en Java, une méthode consiste à faire une classe qui étend de « Thread»  et qui redéfinit la méthode « run» . Le contenu de cette méthode sera celui exécuté par le thread. Dans notre cas, cette méthode devra attendre qu’un client se connecte puis attendra un éventuel message :


/**
 *
 * @author Romain Bouleis www.bouleis.fr
 *
 */
public class Server extends Thread{
	private int port;
	private boolean run = true;
	private PrintWriter out;
	private BufferedReader in;
	public Server(int port) {
		this.port = port;
	}
	/**
	 * {@docRoot} start the server
	 */
	public void run() {
		ServerSocket server;
		Socket client;
		try {
			//crée un nouveau socket
			server = new java.net.ServerSocket (this.port);
			//attend un client
			client  = server.accept();
			System.out.println("[Server] client connected");
			//writer sur le socket
			out = new PrintWriter(client.getOutputStream(), true);
			//reader sur le soket
			in  = new BufferedReader (new InputStreamReader(client.getInputStream()));
			String msg = "";
			//tant que le serveur est actif et que le client est connecte
			while(this.run && msg != null) {
				//attend un message
				msg = in.readLine();
				//traiter le message
				System.out.println("[server] message reçu : "+msg);
				//arete le serveur si le message est "exit"
				if("exit".equals(msg)) this.run = false;
			}
			//ferme le reader et le writer
			out.close();
			in.close();
			//ferme le socket
			client.close();
			server.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void main(String args[]) {
		Server s = new Server(8000);
		s.start();
	}
}

Ce code executera un serveur attendant un client sur le port 8000. Pour pouvoir envoyer un message à un éventuel client, il faut rajouter une méthode :


public void sendCommand(String c) {
	if(out != null) out.println(c);
	else System.err.println("no client");
}

public static void main(String args[]) {
	Server s = new Server(8000);
	s.start();
	//attendre la connexion d'un client
	s.sendCommand("envoie de cette ligne au client");
}

On peut tester le serveur grâce à telnet : telnet localhost 8000. Lors d’envoie de messages, ils devraient s’afficher dans la console depuis laquelle le serveur a été lancé.

Intéressons nous maintenant au client. De la même façon, un thread sera crée pour attendre des messages du serveur.


#define SOCKET_PORT 8000

using namespace std;

int socketDescriptor;

Client::Client() { }

//se connecte au serveur
void Client::init(char* socket_host) {
	struct sockaddr_in serverAddress;
	struct hostent *hostInfo;

	cout << "[Client] connecting..." <<
	//Choix de l'hôte
  	hostInfo = gethostbyname(socket_host);
 	if (hostInfo == NULL) {
    	cout << "[Client] problem interpreting host: " <<
		exit(1);
 	}

	// Creation du socket.
  	socketDescriptor = socket(PF_INET, SOCK_STREAM, 0);
  	if (socketDescriptor < 0) {
   		cerr << "[Client] cannot create socket\n";
    	exit(1);
  	}

	serverAddress.sin_family = hostInfo->h_addrtype;
  	memcpy((char *) &serverAddress.sin_addr.s_addr,
    hostInfo->h_addr_list[0], hostInfo->h_length);
  	serverAddress.sin_port = htons(SOCKET_PORT);
 	memset(serverAddress.sin_zero, '\0', sizeof serverAddress.sin_zero);

	connect(socketDescriptor, (struct sockaddr *)&serverAddress, sizeof(serverAddress));

	cout << "[Client] connected to server" <<
}

//cree un thread executant la methode runWaitMessage
pthread_t Client::runWaitMessageThread() {
	pthread_t attente;
	(void) pthread_create(&attente, NULL, Client::runWaitMessage, (void*) &socketDescriptor);
	return attente;
}

//attends des messages
void * Client::runWaitMessage(void * args) {
	cout << "[Client] Waiting messages thread running..." <
	char line[255];
	memset(line, '\0', sizeof(line));
	while(recv(socketDescriptor, line, sizeof(line), 0) > 1) {
		//remove the \n at the end of the string
		unsigned int i=0;
		char line_[strlen(line)-1];
		for(i=0;i<strlen(line);i++)
			line_[i] = line[i];
		}
		line_[i] = '\0';
		cout << "[Client] " << line_ << " received" <<

		//on traite le message

		memset(line, '\0', sizeof(line));
	}
	return (void *) 1;
}

//send a command
void Client::sendCommande(string s) {
	char * message;
	string s_ = s;
	s += "\r\n";
	message = (char *) s.c_str();
	send(socketDescriptor,message,strlen(message),0);
	cout << "[Client] " << s_ << " sent" <
}

//close the socket
void Client::closeClient() {
	close(socketDescriptor);
	cout << "[Client] disconnected" <<
}

Enfin, on peut lancer le client avec la méthode suivante :


int main(int argc, char* argv[]) {
	Client *client = new Client();
	client->init("localhost");
	client->runWaitMessageThread();
	client->sendCommande(message);
}

No responses yet