/***************************************
*                                      *
*   Copyright (c) 2007 Jean-Eric Pin   *
*   All rights reserved.               *
*                                      *
*   TAB = 2 spaces                     *
*                                      *
***************************************/

/*-------------------------------------------------------------------
 * Test.c    Jean-Eric Pin 28/05/07
 *-------------------------------------------------------------------
 */     

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include "Main.h"
#include "Calcul.h"
#include "DclassesIteratif.h"
#include "Blocs.h"
#include "Espace.h"
#include "Exemples.h"
#include "FichierUnix.h"
#include "Globales.h"
#include "Initialisation.h"
#include "InitiauxFinaux.h"
#include "InitLaTeX.h"
#include "Inverses.h"
#include "Matrices.h"
#include "MatricesBooleennes.h"
#include "MatricesMaxPlus.h"
#include "Memoire.h"
#include "Menu.h"
#include "Preferences.h"
#include "Reduction.h"
#include "Sortie.h"
#include "SortieLaTeX.h"
#include "SortieDclasses.h"
#include "SortieLaTeXDclasses.h"
#include "SortieLaTeXVarietes.h"
#include "Syntactique.h"
#include "Test.h"
#include "Transitions.h"
#include "TriParTas.h"
#include "Utilitaires.h"
#include "Zero.h"

extern unsigned long NbElements, NbReelElements, NbIdempotents, NbRclasses, 
       NbLclasses, NbDclasses;
extern unsigned long NbRelations, TailleMaxi, TailleTableDeHachage, TailleTableDeHachageMoinsUn;
extern unsigned short PossedeUnNeutre, OptionAction, SauvegardeSouhaitee, NbEtats,
    NbLettres, TypeSemigroupe, TypeCalcul, EtatInitial1, InitiauxDejaSpecifies, 
    FinauxDejaSpecifies, MemoireAllouee, SortieLaTeX, LongueurMax, PartiePointee,
    FichierExempleOuvert, FichierLaTeXOuvert, SemigroupeRenverse, SemiReduit;
extern char **Messages;
extern Lecture_ LectureFichier;
extern Produit_ Produit, ProduitNormal;
extern Hachage_ Hachage;
extern Hachage_ HachageSecondaire;
extern EstEgal_ EstEgal;
extern Alloue_ AlloueMemoireElement;
extern Libere_ LibereMemoireElement;
extern Entree_ Entree;
extern element *Generateurs;
extern unsigned long *TableDeHachage;
extern unsigned long *TableIdempotents;
extern info *Table;
extern info2 *Table2;
extern char CheminPref[255];
extern char DirBABEL[255];
extern char DirExemples[255];
extern char DirLaTeX[255];     
extern char NomFichier[255];
extern FILE *fichier, *fichierLaTeX;    /* Voir Main.c */

char *NomLaTeX;
char *NomFichierLaTeX;
char ** ListeExemples;


void InitTest(void)
{
  InitVariables();
  SemigroupeRenverse   = SauvegardeSouhaitee
                      = InitiauxDejaSpecifies
                      = FinauxDejaSpecifies
                      = PartiePointee
                      = EtatInitial1
                      = FichierExempleOuvert
                      = FichierLaTeXOuvert
                      = 0;  /* Remise a jour preventive */
  NomLaTeX = ALLOC(char, LONGUEUR_NOM);
  NomFichierLaTeX = ALLOC(char, 255);
}

void SuiteTest(void)
{
  strcpy(NomFichierLaTeX, DirLaTeX);
  strcat(NomFichierLaTeX, NomLaTeX);    
  strcat(NomFichierLaTeX, ".tex");
  fichierLaTeX = Ouverture(NomFichierLaTeX, "w");
  FichierLaTeXOuvert = 1;
  EnTeteFichierLaTeX(fichierLaTeX);
  TailleTableDeHachage = EstimationTailleTableDeHachage(TailleMaxi + 1);
   TailleTableDeHachageMoinsUn = TailleTableDeHachage - 1;
  if (TypeSemigroupe == MatricesEntieres)
    SortieSemiAnneauZst();
  SortieGenerateurs(); 
  Calcul();
  free(TableDeHachage);  /* En principe, la table de hachage ne sert plus */
  CalculDclasses();
  CalculHclasses();
  CalculIdempotents(); 
  TesteZero();
  CalculListeIdempotents();
  CalculxOmega();
  CalculReguliers();
  CalculDansUnGroupe();
  CalculBlocs(); 
  TriParTas();
  if (PartiePointee)
    CalculSyntactique();
  LongueurLaTeX();
  SortieLaTeXGenerale(fichierLaTeX);
  SortieLaTeXEstCommutatif(fichierLaTeX);
  SortieLaTeXEstIdempotent(fichierLaTeX);
  SortieLaTeXEstNilpotent(fichierLaTeX);
  SortieLaTeXEstAperiodique(fichierLaTeX);
  SortieLaTeXEstUnGroupe(fichierLaTeX);
  SortieLaTeXEstJRLtrivial(fichierLaTeX);
  if ((NbIdempotents * NbIdempotents) < SMALL)  /* Algorithmes en O(|E(S)|^2) */
  {
     SortieLaTeXEstEcom(fichierLaTeX);
     SortieLaTeXEstBG(fichierLaTeX);
  }
  if (TypeCalcul == Semigroupe)    /* Calcul de semigroupes */
  {
    if ((NbElements * NbIdempotents) < SMALL)  /* Algorithmes en O(|S||E(S)|) */
    {
       SortieLaTeXEstL1(fichierLaTeX);
      SortieLaTeXEstLG(fichierLaTeX);
      if (PartiePointee)
        SortieLaTeXEstB1Plus(fichierLaTeX);
    }
  }
  if ((NbElements * NbElements) < SMALL)  /* Algorithmes en O(|S|^2) */
  {
     SortieLaTeXEstDA(fichierLaTeX);
     SortieLaTeXEstDS(fichierLaTeX);
  }
  if ((NbElements * NbElements * NbElements) < SMALL)  /* Algorithmes en O(|S|^3) */
  {
     SortieLaTeXEstRvL(fichierLaTeX);
  }
  fprintf(fichierLaTeX, "\n");
  SortieLaTeXListeElements(fichierLaTeX);
  SortieLaTeXRelations(fichierLaTeX);
  SortieLaTeXIdempotents(fichierLaTeX);
  SortieLaTeXIdealMinimal(fichierLaTeX);
  SortieLaTeXDclasses(fichierLaTeX);
  CalculInverses();
  SortieLaTeXInverses(fichierLaTeX);
  CalculKS();
  SortieLaTeXKS(fichierLaTeX);
  FinFichierLaTeX(fichierLaTeX); 
  Fermeture(fichierLaTeX); 
  FichierLaTeXOuvert = 0;
  LibereMemoire();  
  free(NomLaTeX);
  free(NomFichierLaTeX);
}

void Test(void) 
{
  InitTest();
  printf("Test T2\n"); 
  Produit = ProduitTransitions;
  Tn(2);
  strcat(NomLaTeX, "T2"); 
  SuiteTest();

  InitTest();
  printf("Test T3\n"); 
  Produit = ProduitTransitions;
  Tn(3);
  strcat(NomLaTeX, "T3"); 
  SuiteTest(); 

  InitTest();
  printf("Test T4\n"); 
  Produit = ProduitTransitions;
  Tn(4);
  strcat(NomLaTeX, "T4"); 
  SuiteTest(); 

  InitTest();
  printf("Test B2\n"); 
  Produit = ProduitTransitionsPartielles;
  BAn(2);
  strcat(NomLaTeX, "B2"); 
  SuiteTest(); 

  InitTest();
  printf("Test B3\n"); 
  Produit = ProduitTransitionsPartielles;
  BAn(3);
  strcat(NomLaTeX, "B3"); 
  SuiteTest(); 

  InitTest();
  printf("Test B4\n"); 
  Produit = ProduitTransitionsPartielles;
  BAn(4);
  strcat(NomLaTeX, "B4"); 
  SuiteTest(); 

  InitTest();
  printf("Test CompteurSeuil 2\n"); 
  Produit = ProduitTransitionsPartielles;
  CompteurSeuil(2);
  strcat(NomLaTeX, "CompteurSeuil2"); 
  SuiteTest(); 

  InitTest();
  printf("Test CompteurSeuil 3\n"); 
  Produit = ProduitTransitionsPartielles;
  CompteurSeuil(3);
  strcat(NomLaTeX, "CompteurSeuil3"); 
  SuiteTest(); 

  InitTest();
  printf("Test CompteurSeuil 4\n"); 
  Produit = ProduitTransitionsPartielles;
  CompteurSeuil(4);
  strcat(NomLaTeX, "CompteurSeuil4"); 
  SuiteTest(); 

  InitTest();
  printf("Test Multiplication 15\n"); 
  Produit = ProduitTransitions;
  Multiplication(15);
  strcat(NomLaTeX, "Multiplication15"); 
  SuiteTest(); 

  InitTest();
  printf("Test S2\n"); 
  Produit = ProduitTransitions;
  Sn(2);
  strcat(NomLaTeX, "S2"); 
  SuiteTest();

  InitTest();
  printf("Test S3\n"); 
  Produit = ProduitTransitions;
  Sn(3);
  strcat(NomLaTeX, "S3"); 
  SuiteTest(); 

  InitTest();
  printf("Test S4\n"); 
  Produit = ProduitTransitions;
  Sn(4);
  strcat(NomLaTeX, "S4"); 
  SuiteTest(); 

  InitTest();
  printf("Test F2\n"); 
  Produit = ProduitTransitionsPartielles;
  Fn(2);
  strcat(NomLaTeX, "F2"); 
  SuiteTest();

  InitTest();
  printf("Test F3\n"); 
  Produit = ProduitTransitionsPartielles;
  Fn(3);
  strcat(NomLaTeX, "F3"); 
  SuiteTest(); 

  InitTest();
  printf("Test F4\n"); 
  Produit = ProduitTransitionsPartielles;
  Fn(4);
  strcat(NomLaTeX, "F4"); 
  SuiteTest(); 

  InitTest();
  printf("Test I2\n"); 
  Produit = ProduitTransitionsPartielles;
  In(2);
  strcat(NomLaTeX, "I2"); 
  SuiteTest();

  InitTest();
  printf("Test I3\n"); 
  Produit = ProduitTransitionsPartielles;
  In(3);
  strcat(NomLaTeX, "I3"); 
  SuiteTest(); 

  InitTest();
  printf("Test I4\n"); 
  Produit = ProduitTransitionsPartielles;
  In(4);
  strcat(NomLaTeX, "I4"); 
  SuiteTest(); 

  InitTest();
  printf("Test O2\n"); 
  Produit = ProduitTransitions;
  On(2);
  strcat(NomLaTeX, "O2"); 
  SuiteTest(); 

  InitTest();
  printf("Test O3\n"); 
  Produit = ProduitTransitions;
  On(3);
  strcat(NomLaTeX, "O3"); 
  SuiteTest(); 

  InitTest();
  printf("Test O4\n"); 
  Produit = ProduitTransitions;
  On(4);
  strcat(NomLaTeX, "O4"); 
  SuiteTest(); 

  InitTest();
  printf("Test POI2\n"); 
  Produit = ProduitTransitionsPartielles;
  POIn(2);
  strcat(NomLaTeX, "POI2"); 
  SuiteTest(); 

  InitTest();
  printf("Test POI3\n"); 
  Produit = ProduitTransitionsPartielles;
  POIn(3);
  strcat(NomLaTeX, "POI3"); 
  SuiteTest(); 

  InitTest();
  printf("Test POI4\n"); 
  Produit = ProduitTransitionsPartielles;
  POIn(4);
  strcat(NomLaTeX, "POI4"); 
  SuiteTest(); 

  InitTest();
  printf("Test POPI2\n"); 
  Produit = ProduitTransitionsPartielles;
  POPIn(2);
  strcat(NomLaTeX, "POPI2"); 
  SuiteTest();

  InitTest();
  printf("Test POPI3\n"); 
  Produit = ProduitTransitionsPartielles;
  POPIn(3);
  strcat(NomLaTeX, "POPI3"); 
  SuiteTest(); 

  InitTest();
  printf("Test POPI4\n"); 
  Produit = ProduitTransitionsPartielles;
  POPIn(4);
  strcat(NomLaTeX, "POPI4"); 
  SuiteTest(); 

  InitTest();
  printf("Test Z2Z\n"); 
  Produit = ProduitTransitions;
  ZnZ(2);
  strcat(NomLaTeX, "Z2Z"); 
  SuiteTest();

  InitTest();
  printf("Test Z3Z\n"); 
  Produit = ProduitTransitions;
  ZnZ(3);
  strcat(NomLaTeX, "Z3Z"); 
  SuiteTest(); 

  InitTest();
  printf("Test Z14Z\n"); 
  Produit = ProduitTransitions;
  ZnZ(14);
  strcat(NomLaTeX, "Z14Z"); 
  SuiteTest(); 

  InitTest();
  printf("Test RB2\n"); 
  Produit = ProduitMatricesBooleennes;
  RBn(2);
  strcat(NomLaTeX, "RB2"); 
  SuiteTest();

  InitTest();
  printf("Test RB3\n"); 
  Produit = ProduitMatricesBooleennes;
  RBn(3);
  strcat(NomLaTeX, "RB3"); 
  SuiteTest(); 

  InitTest();
  printf("Test Trn2\n"); 
  Produit = ProduitMatricesBooleennes;
  Trn(2);
  strcat(NomLaTeX, "Trn2"); 
  SuiteTest(); 

  InitTest();
  printf("Test Trn3\n"); 
  Produit = ProduitMatricesBooleennes;
  Trn(3);
  strcat(NomLaTeX, "Trn3"); 
  SuiteTest(); 

  InitTest();
  printf("Test Trn4\n"); 
  Produit = ProduitMatricesBooleennes;
  Trn(4);
  strcat(NomLaTeX, "Trn4"); 
  SuiteTest(); 

  InitTest();
  printf("Test U2\n"); 
  Produit = ProduitMatricesBooleennes;
  Un(2);
  strcat(NomLaTeX, "U2"); 
  SuiteTest();

  InitTest();
  printf("Test U3\n"); 
  Produit = ProduitMatricesBooleennes;
  Un(3);
  strcat(NomLaTeX, "U3"); 
  SuiteTest(); 

  InitTest();
  printf("Test U4\n"); 
  Produit = ProduitMatricesBooleennes;
  Un(4);
  strcat(NomLaTeX, "U4"); 
  SuiteTest(); 

  InitTest();
  printf("Test DeuxPetitesMatrices5_3\n"); 
  Produit = ProduitMatricesEntieres;
  DeuxPetitesMatrices(5,3);
  strcat(NomLaTeX, "DeuxPetitesMatrices5_3"); 
  SuiteTest(); 

  InitTest();
  printf("Test ExempleNonKnast\n"); 
  Produit = ProduitTransitionsPartielles;
  ExempleNonKnast();
  strcat(NomLaTeX, "NonKnast"); 
  SuiteTest(); 

  InitTest();
  printf("Test ExempleTransitions\n"); 
  Produit = ProduitTransitionsPartielles;
  ExempleTransitions();
  strcat(NomLaTeX, "Transitions"); 
  SuiteTest(); 

  InitTest();
  printf("Test ExempleMatricesBooleennes\n"); 
  Produit = ProduitMatricesBooleennes;
  ExempleMatricesBooleennes();
  strcat(NomLaTeX, "MatricesBooleennes"); 
  SuiteTest(); 

  InitTest();
  printf("Test ExempleMatricesEntieres\n"); 
  Produit = ProduitMatricesEntieres;
  ExempleMatricesEntieres();
  strcat(NomLaTeX, "MatricesEntieres"); 
  SuiteTest(); 

  InitTest();
  printf("Test ExempleMatricesMaxPlus\n"); 
  Produit = ProduitMatricesMaxPlus;
  ExempleMatricesMaxPlus();
  strcat(NomLaTeX, "MatricesMaxPlus"); 
  SuiteTest(); 
}

void InitListeExemples(void)
{
  short j;
  
  ListeExemples = ALLOC(char *, 232);
  for (j = 0; j < 232; j++)
    ListeExemples[j] = ALLOC(char, 40);
  ListeExemples[0] = "((ab+bc)(bcc)*a)+";
  ListeExemples[1] = "(a,b)*aA*b(b,c)*";
  ListeExemples[2] = "(a,bb,bab)*";
  ListeExemples[3] = "(a(ab)*b)*";
  ListeExemples[4] = "(A*aA*_I_A*bA*)aA*";
  ListeExemples[5] = "(A*aA*_I_A*bA*)cA*";
  ListeExemples[6] = "(A*aabbA*)^c";
  ListeExemples[7] = "(a*ba*ba*)*";
  ListeExemples[8] = "exemple1";  /* "(a*bab*)*" */
  ListeExemples[9] = "(A2)*a(A2)*a(A2)*";
  ListeExemples[10] = "(A3)*a(A3)*a(A3)*";
  ListeExemples[11] = "(aa,baa,aabb)*";
  ListeExemples[12] = "(aaa,ba,abaa,aab)*";
  ListeExemples[13] = "(ab,aba)*";
  ListeExemples[14] = "(ab,ba)*";
  ListeExemples[15] = "(ab,cd)*";
  ListeExemples[16] = "(ab,cde)*";
  ListeExemples[17] = "(ab)e";
  ListeExemples[18] = "(ab)*(a*+b*)";
  ListeExemples[19] = "(ab)*+(aba)*";
  ListeExemples[20] = "(ab)*a(ab)+b(ab)*";
  ListeExemples[21] = "(ab)*W(a5b)*";
  ListeExemples[22] = "(aba,b)*";
  ListeExemples[23] = "(aba)*";
  ListeExemples[24] = "(abaaa,aabaa,aaaba)*";
  ListeExemples[25] = "(abaab)+";
  ListeExemples[26] = "(abaaba)+";
  ListeExemples[27] = "(abab)*";
  ListeExemples[28] = "(abb,b)*";
  ListeExemples[29] = "(ba,abba)*";
  ListeExemples[30] = "133,223";
  ListeExemples[31] = "133,223,113";
  ListeExemples[32] = "222,033";
  ListeExemples[33] = "231,133";
  ListeExemples[34] = "233,023";
  ListeExemples[35] = "233,123,003";
  ListeExemples[36] = "233,123,023";
  ListeExemples[37] = "313,213";
  ListeExemples[38] = "2333,0242,0234";
  ListeExemples[39] = "22001341";
  ListeExemples[40] = "a(a,b)*aa(a,c)*a";
  ListeExemples[41] = "a(a,b)*b(b,c)*c";
  ListeExemples[42] = "a{a,b}*a{a,c}*a{a,b}*a";
  ListeExemples[43] = "a{a,b}*aa{a,b,c}*a";
  ListeExemples[44] = "a{a,b}*aaA*a_U_a{b,c}*a{b,c}*a";
  ListeExemples[45] = "a{a,b}*ab{b,c}*c";
  ListeExemples[46] = "A*a(A*aA*_I_A*bA*)bA*";
  ListeExemples[47] = "A*aaA*+A*bbA*";
  ListeExemples[48] = "A*aaA*+A*bbA*+1";
  ListeExemples[49] = "A*abA*-aba";
  ListeExemples[50] = "A*abaA*";
  ListeExemples[51] = "A*abbaA*";
  ListeExemples[52] = "A*abbaababaaaA*";
  ListeExemples[53] = "A+aA*";
  ListeExemples[54] = "A+aaA*";
  ListeExemples[55] = "a+ba+U(A*bA*bA*)";
  ListeExemples[56] = "aA*a{b,c}*a";
  ListeExemples[57] = "aA*aa*aA*a";
  ListeExemples[58] = "aA*abA*c";
  ListeExemples[59] = "aA*ac*bA*c";
  ListeExemples[60] = "aA*bA*a";
  ListeExemples[61] = "aA*bA*c";
  ListeExemples[62] = "aA*bbA*a";
  ListeExemples[63] = "abaU(A*bA*bA*)";
  ListeExemples[64] = "abimpair";
  ListeExemples[65] = "ac(a+b)*";
  ListeExemples[66] = "anca";
  ListeExemples[67] = "anca3";
  ListeExemples[68] = "Arbib206";
  ListeExemples[69] = "b(aa)*c";
  ListeExemples[70] = "b*aa*";
  ListeExemples[71] = "b*abA*";
  ListeExemples[72] = "BA2o";
  ListeExemples[73] = "Band3";
  ListeExemples[74] = "BG+";
  ListeExemples[75] = "BG+2";
  ListeExemples[76] = "BG+3";
  ListeExemples[77] = "bool1";
  ListeExemples[78] = "bool2";
  ListeExemples[79] = "bool3";
  ListeExemples[80] = "bool4";
  ListeExemples[81] = "BunPlus";
  ListeExemples[82] = "Cano1";
  ListeExemples[83] = "Cano2";
  ListeExemples[84] = "Cano3";
  ListeExemples[85] = "Cano4";
  ListeExemples[86] = "Cano5";
  ListeExemples[87] = "Cano6";
  ListeExemples[88] = "Cano7";
  ListeExemples[89] = "Cano8";
  ListeExemples[90] = "Cano9";
  ListeExemples[91] = "carton1";
  ListeExemples[92] = "carton2";
  ListeExemples[93] = "carton3";
  ListeExemples[94] = "carton4";
  ListeExemples[95] = "Cerny4";
  ListeExemples[96] = "Champarnaud-Pin";
  ListeExemples[97] = "coextB2RZ";
  ListeExemples[98] = "Comet1";
  ListeExemples[99] = "Comet2";
  ListeExemples[100] = "Comet3";
  ListeExemples[101] = "Comet4";
  ListeExemples[102] = "ContreExemple";
}

void TestExemples(void) 
{
  short j;
  
  InitListeExemples();
  for (j = 11; j < 12; j++)
  {
    InitTest();
    strcat(NomLaTeX, ListeExemples[j]); 
    strcpy(NomFichier, DirExemples);
    strcat(NomFichier, NomLaTeX);
    fichier = Ouverture(NomFichier, "r");
    FichierExempleOuvert = 1;
    printf("%s\n", NomFichier);
    LectureExemple(fichier);
    FichierExempleOuvert = 0;
    Produit = ProduitNormal;
    SuiteTest(); 
  }
}