#!/usr/bin/perl
use locale;
<<DOC; 
 FEVRIER 2006
 usage : perl patron2graphml.pl liste-de-token.txt
 Le programme prend en entrée le nom du fichier contenant les patrons
 à traiter (des blancs entre les termes du patron)
 Le programme construit en sortie un fichier au format graphml

DOC

#-------------------------
# definitions de variables
#-------------------------
my $file="$ARGV[0]";
#le fichier de patron qu on veut traiter
my %listeMot={}; #premier dictionnaire qui associe la clé mot  à une référence qui pointe vers une liste
my %listePatron={}; #deuxieme dictionnaire qui sert à compter le nombre d occurences.

#-------------------------
# Partie 1
# A. ouverture du fichier des patrons : ce fichier contient sur chaque ligne une sequence : mot1 mot2
# B. dans la boucle while qui suit on va reperer pour chaque mot (a gauche du patron) 
# l'ensemble des mots associés (a droite du precedent)
# on cree ensuite un tableau indexe qui associe au mot de gauche la liste des mots associes
# motgauche -> (motdroite-1,motdroite-2,...)
# on n'ajoute qu'une seule occurrence des mots presents a droite mais on compte 
# la frequence d'un patron donne dans un tableau de patron 
#-------------------------

open(F,$file);
while (my $ligne=<F>) {
    $ligne=~/([\w]+)[^\w]+([\w]+)/;
	#\w en perl signifie n' importe quel caractere sauf les caractères accentués. Pour avoir aussi les caractères accentués, utiliser: use locale; Cette expression régulière
	#nous permet d'isoler le nom des adj, en récupérant les contenus des parentheses.
	my $mot1=$1;
    my $mot2=$2;
    print "M1 : $mot1\n";
    print "M2 : $mot2\n";
    my $patron="$mot1\t$mot2";
	
    if (!(exists($listeMot{$mot1})))
	#on vérifie si ça n 'esxiste pas deja, si on a pas deja cette clé dans le tableau, à l'aide de la fonction exists
	{
	my @tmp=();
	push(@tmp,$mot2);
	#on crée cette liste en ajoutant l' adj qui suit la clé
	$listeMot{$mot1}=\@tmp;
	#le"\" crée la référence vers la liste @tmp. On associe la clé à cette référence.
	print "FM : $listeMot{$mot1}\n";
	$listePatron{$patron}++; #on compte le nbr d ocurence
    }
    else { #si la clé existait déjà
	my $tmp=$listeMot{$mot1}; #ici, on range dans $tmp, la référence associée à la clé mot1.
	my @tmp2=@$tmp; #@$tmp : déréférence. Permet de récupérer la liste à partir de la référence.
	
	if (!(grep(/$mot2/, @tmp2))) 
	#grep est aussi une fonction de perl qui permet de verifier si une chaine de caractere est contenu dans un tableau
	#on cherche si $mot2 n'est pas deja dans le tableau @tmp2
	{
	    push(@tmp2,$mot2); #s'il n y est pas deja , on l ajoute
	}
	$listeMot{$mot1}=\@tmp2;
	print "NM : $listeMot{$mot1}\n";
	$listePatron{$patron}++; #on incrémente encore le nbr de patrons
    }
}
close(F);
#print %listeMot,"\n";

#-------------------------
# Partie 2
# A. Creation du fichier de sortie et squelette minimal
# B. parcours du tableau des associations motgauche -> (motdroite-1,motdroite-2,...)
# pour chaque motgauche on cree un noeud du graphe idem pour chaque mot de la liste associee
# afin de ne pas creer de doublon on utilise un tableau contenant pour chaque mot son indice
# on verifie dans ce tableau la presence ou non du mot a associer a un noeud
#-------------------------

open (F,">patron-graphml.xml");
print F "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
print F "<graphml>\n";
print F " <key id=\"d0\" for=\"node\" attr.name=\"forme\" attr.type=\"string\"/>\n";
print F " <key id=\"d1\" for=\"edge\" attr.name=\"frequence\" attr.type=\"double\"/>\n";
print F "  <graph edgedefault=\"undirected\">\n";

my $id=1;
my $listeId={}; #on crée une liste des identifiants

while (($mot, $liste) = each(%listeMot)) 
#each est une fonction qui permet de parcourir un tableau indexé, en récupérant  chaque fois, la clé, la valeur, la clé, la valeur ... 
#Tant que cette fonction peut tourner, on le fait
{
    my @tmp=@$liste; #on reconstruit le tableau a partir de la reference
    print "$mot\t@tmp\n";
    if ($mot !~/HASH/) #pour nettoyer 
	{
	my $tmpID;
	
	if (!(exists($listeId{$mot})))
	#si cette clé n existe pas deja dans la listeID
	{
	    print F "  <node id=\"$id\"><data key=\"d0\">$mot</data></node>\n";
	    $listeId{$mot}=$id; 
	    $tmpID=$id; 
	    $id++;
	}
	else {
	    $tmpID=$listeId{$mot};
	}
	foreach my $cible (@tmp) 
	#$cible va correspondre à chacun des adjectifs
	{
	    my $nbpatron=0;
	    $patron="$mot\t$cible";
	    $nbpatron=$listePatron{$patron};
	    if (!(exists($listeId{$cible}))) {
		print F "  <node id=\"$id\"><data key=\"d0\">$cible</data></node>\n";
		$listeId{$cible}=$id;
		print F "  <edge source=\"$tmpID\" target=\"$id\"><data key=\"d1\">$nbpatron</data></edge>\n";
		$id++;
	    }
	    else {
		print F "  <edge source=\"$tmpID\" target=\"$listeId{$cible}\"><data key=\"d1\">$nbpatron</data></edge>\n";
	    }
	}
    }
    
} 


print F " </graph>\n";
print F "</graphml>\n";


close(F);

