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

/*-------------------------------------------------------------------
 * SortieVarietes.c    Jean-Eric Pin 07/12/96
 *-------------------------------------------------------------------
 */     

#include <stdlib.h>
#include <stdio.h>
#include "Globales.h"
#include "Main.h"
#include "Reduction.h"
#include "Sortie.h"
#include "SortieVarietes.h"
#include "Utilitaires.h"
#include "Varietes.h"
#include "Zero.h"

extern unsigned short NbEtats, NbLettres, LongueurMax, TypeCalcul, TypeSemigroupe,
                      PossedeUnZero;
extern unsigned long TestsEffectues, Varietes;
extern unsigned long NbElements, NbIdempotents, nZero, DernierMot, NbDclasses, 
       NbRclasses, NbLclasses;
extern element *Generateurs;
extern element Identite;
extern info *Table;
extern char **Messages;
extern adresses Adresses;

/****************************************************
*
* SortieEstCommutatif. OK
*
****************************************************/

void SortieEstCommutatif(void)
{  
  TestCommutatif();
  if (Varietes & SEM_COMMUTATIF)
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
            Messages[M_Is_commutative]);
  else            /* Ce %s n'est pas commutatif, car */
  {
    printf("%s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
            Messages[M_Is_not_commutative]);
    printf("%c%c %s %c%c\n", *Adresses.commutatif_1 + 'a', *Adresses.commutatif_2 + 'a',
            Messages[M_Is_different],  *Adresses.commutatif_2 + 'a', *Adresses.commutatif_1 + 'a');  /* %c%c est different de %c%c */
  }
}

/****************************************************
*
* SortieEstIdempotent. OK
*
****************************************************/

void SortieEstIdempotent(void)
{
  TestIdempotent();
  if (Varietes & SEM_IDEMPOTENT)
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_in_Bands]);
  else    /* "Ce %s n'est pas idempotent, car l'identite uu = u n'est pas satisfaite lorsque */
  {
    printf("%s %s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
            Messages[M_Is_not_in_Bands], Messages[M_because_uu]);
    printf("u = ");
    SortieMot(*Adresses.idempotent);
    printf("\n");
  }
}

/****************************************************
*
* SortieEstJ1. OK
*
****************************************************/

void SortieEstJ1(void)
{  
  TestCommutatif();
  if ((Varietes & SEM_COMMUTATIF) == 0) /* Ce %s n'est pas dans J1, car */
  {
    printf("%s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_not_commutative]);
    printf("%c%c %s %c%c\n", *Adresses.commutatif_1 + 'a', *Adresses.commutatif_2 + 'a', Messages[M_Is_different],
            *Adresses.commutatif_2 + 'a', *Adresses.commutatif_1 + 'a');  /* %c%c est different de %c%c */
  }
  else
  {
    TestIdempotent();
    if (Varietes & SEM_IDEMPOTENT)  /* Ce %s n'est pas dans J1, car l'identite uu = u n'est pas satisfaite lorsque */
    {
      printf("%s %s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
              Messages[M_Is_not_in_J1], Messages[M_because_uu]);
      printf("u = ");
      SortieMot(*Adresses.idempotent);
      printf("\n");
    }
    else  /* Ce %s est dans J1 */
      printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_this_semi] : Messages[M_This_mono], Messages[M_Is_in_J1]);
  }
}

/****************************************************
*
* SortieEstNilpotent. OK
*
****************************************************/

void SortieEstNilpotent(void)
{  
  TestNilpotent();
  if (Varietes & SEM_NILPOTENT)
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_Nil]);
  else
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_not_in_Nil]);
}

/****************************************************
*
* SortieEstAperiodique. OK
*
****************************************************/

void SortieEstAperiodique(void)
{
  TestAperiodique();
  if (Varietes & SEM_APERIODIQUE)    /* Ce %s est aperiodique */
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_aperiodic]);
  else    /* Ce %s n'est pas aperiodique, car l'identite u^u = u^ n'est pas satisfaite lorsque */
  {
    printf("%s %s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
                  Messages[M_Is_not_aperiodic], Messages[M_because_u_omega]);
    printf("u = ");
    SortieMot(*Adresses.aperiodique);
    printf("\n");
  }
}

/****************************************************
*
* SortieEstUnGroupe. OK
*
****************************************************/

void SortieEstUnGroupe(void)
{  
  TestUnGroupe();
  if (Varietes & SEM_GROUPE)
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_in_G]);
  else
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_not_in_G]);
}

/****************************************************
*
* SortieEstJRLtrivial. OK
*
****************************************************/

void SortieEstJRLtrivial(void)
{  
  TestDtrivial();
  if (Varietes & SEM_D_TRIVIAL)
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_Jtrivial]);
  else
  {
    TestRtrivial();
    if (Varietes & SEM_R_TRIVIAL)
      printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_Rtrivial]);
    else
    {
      TestLtrivial();
      if (Varietes & SEM_L_TRIVIAL)
        printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_Ltrivial]);
      else                          /* ni R-trivial, ni L-trivial */
        printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_not_RLtrivial]);
    }
  }
}

/****************************************************
*
* SortieEstDA. OK
*
****************************************************/

void SortieEstDA(void)
{
  TestAperiodique();
  if (!(Varietes & SEM_APERIODIQUE))  /* Ce semigroupe n'est pas aperiodique */
    return;
  TestDA();  
  if (Varietes & SEM_DA)    /* Ce %s est dans DA */
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_in_DA]);
  else    /* Ce %s n'est pas dans DA, car l'identite (xy)^(yx)^(xy)^ = (xy)^ n'est pas satisfaite lorsque */
  {
    printf("%s %s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
            Messages[M_Is_not_in_DA], Messages[M_because_DA]);
    printf("x = ");
    SortieMot(*Adresses.DA_x);
    printf(", y = ");
    SortieMot(*Adresses.DA_y);
    printf("\n");
  }
}

/****************************************************
*
* SortieEstDS. OK
*
****************************************************/

void SortieEstDS(void)
{
  TestDS();
  if (Varietes & SEM_DS)    /* Ce %s est dans DS */
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_in_DS]);
  else    /* Ce %s n'est pas dans DS, car l'identite ((xy)^(yx)^(xy))^ = (xy)^ n'est pas satisfaite lorsque */
  {
    printf("%s %s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
            Messages[M_Is_not_in_DS], Messages[M_because_DS]);
    printf("x = ");
    SortieMot(*Adresses.DS_x);
    printf(", y = ");
    SortieMot(*Adresses.DS_y);
    printf("\n");
  }
}

/****************************************************
*
* SortieEstRvL. OK
*
****************************************************/

void SortieEstRvL(void)
{
  TestRvL();
  if (Varietes & SEM_RvL)    /* Ce %s est dans R v L */
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_in_RvL]);
  else    /* Ce %s n'est pas dans R v L, car l'identite (xy)^x(zx)^ = (xy)^(zx)^ n'est pas satisfaite lorsque */
  {
    printf("%s %s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
            Messages[M_Is_not_in_RvL], Messages[M_because_RvL]);
    printf("x = ");
    SortieMot(*Adresses.RvL_x);
    printf(", y = ");
    SortieMot(*Adresses.RvL_y);
    printf(", z = ");
    SortieMot(*Adresses.RvL_z);
    printf("\n");
  }
}

/****************************************************
*
* SortieEstL1. OK
*
****************************************************/

void SortieEstL1(void)
{
  TestL1();
  if (Varietes & SEM_LI)    /* Ce %s est dans L1 */
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_in_L1]);
  else    /* Ce %s n'est pas dans L1, car l'identite ese = e n'est pas satisfaite lorsque */
  {
    printf("%s %s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
            Messages[M_Is_not_in_L1], Messages[M_because_L1]);
    printf("e = ");
    SortieMot(*Adresses.L1_e);
    printf(", s = ");
    SortieMot(*Adresses.L1_s);
    printf("\n");
  }
}

/****************************************************
*
* SortieEstLG. OK
*
****************************************************/

void SortieEstLG(void)
{
  TestLG();
  if (Varietes & SEM_LG)    /* Ce %s est dans LG */
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_in_LG]);
  else    /* Ce %s n'est pas dans LG, car l'identite ese = e n'est pas satisfaite lorsque */
  {
    printf("%s %s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
            Messages[M_Is_not_in_LG], Messages[M_because_LG]);
    printf("e = ");
    SortieMot(*Adresses.LG_e);
    printf(", s = ");
    SortieMot(*Adresses.LG_s);
    printf("\n");
  }
}

/****************************************************
*
* SortieEstB1. OK
*
****************************************************/

void SortieEstB1(void)
{
  TestB1();
  if (Varietes & SEM_B_UN)    /* Ce %s est dans B1 */
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_in_B1]);
  else    /* Ce %s n'est pas dans B1, car l'identite (epfqe)^pfs(erfse)^ = (epfqe)^(erfse)^ n'est pas satisfaite lorsque */
  {
    printf("%s %s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
            Messages[M_Is_not_in_B1], Messages[M_because_B1]);
    printf("e = ");
    SortieMot(*Adresses.B1_e);
    printf(", f = ");
    SortieMot(*Adresses.B1_f);
    printf(", p = ");
    SortieMot(*Adresses.B1_p);
    printf(", q = ");
    SortieMot(*Adresses.B1_q);
    printf(", r = ");
    SortieMot(*Adresses.B1_r);
    printf(", s = ");
    SortieMot(*Adresses.B1_s);
    printf("\n");
  }
}

/****************************************************
*
* SortieEstB1Plus. OK
*
****************************************************/

void SortieEstB1Plus(void)
{
  TestB1Plus();
  if (Varietes & SEM_B_UN_PLUS)    /* Ce %s est dans B1Plus */
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_in_B1Plus]);
  else    /* Ce %s n'est pas dans B1+, car l'identite ese <= e n'est pas satisfaite lorsque */
  {
    printf("%s %s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
            Messages[M_Is_not_in_B1Plus], Messages[M_because_B1Plus]);
    printf("e = ");
    SortieMot(*Adresses.B1Plus_e);
    printf(", s = ");
    SortieMot(*Adresses.B1Plus_s);
    printf("\n");
  }
}

/****************************************************
*
* SortieEstEcom. OK
*
****************************************************/

void SortieEstEcom(void)
{
  TestECom();
  if (Varietes & SEM_ECOM)    /* Ce %s est dans Ecom */
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_in_Ecom]);
  else    /* Ce %s n'est pas dans Ecom, car l'identite ef = fe n'est pas satisfaite lorsque */
  {
    printf("%s %s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
            Messages[M_Is_not_in_Ecom], Messages[M_because_Ecom]);
    printf("e = ");
    SortieMot(*Adresses.ECom_e);
    printf(", f = ");
    SortieMot(*Adresses.ECom_f);
    printf("\n");
  }
}

/****************************************************
*
* SortieEstBG. OK
*
****************************************************/

void SortieEstBG(void)
{
  TestBG();
  if (Varietes & SEM_BG)    /* Ce %s est dans BG */
    printf("%s %s\n", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono], Messages[M_Is_in_BG]);
  else    /* Ce %s n'est pas dans BG, car l'identite (ef)^ = (fe)^ n'est pas satisfaite lorsque */
  {
    printf("%s %s %s ", TypeCalcul == Semigroupe ? Messages[M_This_semi] : Messages[M_This_mono],
            Messages[M_Is_not_in_BG], Messages[M_because_BG]);
    printf("e = ");
    SortieMot(*Adresses.BG_e);
    printf(", f = ");
    SortieMot(*Adresses.BG_f);
    printf("\n");
  }
}