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

/*-------------------------------------------------------------------
 * SortieLaTeXVarietes.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 "Varietes.h"
#include "SortieLaTeX.h"
#include "SortieLaTeXVarietes.h"
#include "Utilitaires.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;

/****************************************************
*
* SortieLaTeXEstCommutatif. OK
*
****************************************************/

void SortieLaTeXEstCommutatif(FILE *fichier)
{  
  TestCommutatif();
  if (Varietes & SEM_COMMUTATIF)
    fprintf(fichier, "\\noindent This %s is commutative.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else            /* Ce %s n'est pas commutatif, car */
  {
    fprintf(fichier, "\\noindent This %s is not commutative, since ", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    fprintf(fichier, "$%c%c \\not= %c%c$.\n", *Adresses.commutatif_1 + 'a', *Adresses.commutatif_2 + 'a',
            *Adresses.commutatif_2 + 'a', *Adresses.commutatif_1 + 'a');  /* %c%c est different de %c%c */
  }
}

/****************************************************
*
* SortieLaTeXEstIdempotent. OK
*
****************************************************/

void SortieLaTeXEstIdempotent(FILE *fichier)
{
  TestIdempotent();
  if (Varietes & SEM_IDEMPOTENT)
    fprintf(fichier, "This %s is idempotent.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else    /* "Ce %s n'est pas idempotent, car l'identite uu = u n'est pas satisfaite lorsque */
  {
    fprintf(fichier, "This %s is not idempotent, since $u \\not= u^2$ for $u = ", 
            TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    SortieLaTeXMot(*Adresses.idempotent, fichier);
    fprintf(fichier, "$.\n");
  }
}

/****************************************************
*
* SortieLaTeXEstJ1. OK
*
****************************************************/

void SortieLaTeXEstJ1(FILE *fichier)
{  
  TestCommutatif();
  if ((Varietes & SEM_COMMUTATIF) == 0) /* Ce %s n'est pas dans J1, car */
  {
    fprintf(fichier, "This %s is not commutative since ", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    fprintf(fichier, "$%c%c \\not= %c%c$\n", *Adresses.commutatif_1 + 'a', *Adresses.commutatif_2 + 'a',
          *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 */
    {
      fprintf(fichier, "This %s is not idempotent, since $u \\not= u^2$ for $u = ", 
              TypeCalcul == Semigroupe ? "semigroup" : "monoid");
      SortieLaTeXMot(*Adresses.idempotent, fichier);
      fprintf(fichier, "$.\n");
    }
    else  /* Ce %s est dans J1 */
      fprintf(fichier, "This %s is idempotent and commutative.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  }
}

/****************************************************
*
* SortieLaTeXEstNilpotent. OK
*
****************************************************/

void SortieLaTeXEstNilpotent(FILE *fichier)
{  
  TestNilpotent();
  if (Varietes & SEM_NILPOTENT)
    fprintf(fichier, "This %s is nilpotent.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else
    fprintf(fichier, "This %s is not nilpotent.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
}

/****************************************************
*
* SortieLaTeXEstAperiodique. OK
*
****************************************************/

void SortieLaTeXEstAperiodique(FILE *fichier)
{
  TestAperiodique();
  if (Varietes & SEM_APERIODIQUE)    /* Ce %s est aperiodique */
    fprintf(fichier, "This %s is aperiodic.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else    /* Ce %s n'est pas aperiodique, car l'identite u^u = u^ n'est pas satisfaite lorsque */
  {
    fprintf(fichier, "This %s is not aperiodic, since the identity $x^\\omega = x^ {\\omega + 1}$ is not satisfied for $x = ", 
            TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    SortieLaTeXMot(*Adresses.aperiodique, fichier);
    fprintf(fichier, "$.\n");
  }
}

/****************************************************
*
* SortieLaTeXEstUnGroupe. OK
*
****************************************************/

void SortieLaTeXEstUnGroupe(FILE *fichier)
{  
  TestUnGroupe();
  if (Varietes & SEM_GROUPE)
    fprintf(fichier, "This %s is a group.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else
    fprintf(fichier, "This %s is not a group.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
}

/****************************************************
*
* SortieLaTeXEstJRLtrivial. OK
*
****************************************************/

void SortieLaTeXEstJRLtrivial(FILE *fichier)
{  
  TestDtrivial();
  if (Varietes & SEM_D_TRIVIAL)
    fprintf(fichier, "This %s is $\\cal J$-trivial.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else
  {
    TestRtrivial();
    if (Varietes & SEM_R_TRIVIAL)
      fprintf(fichier, "This %s is $\\cal R$-trivial.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    else
    {
      TestLtrivial();
      if (Varietes & SEM_L_TRIVIAL)
        fprintf(fichier, "This %s is $\\cal L$-trivial.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
      else                          /* ni R-trivial, ni L-trivial */
        fprintf(fichier, "This %s is neither $\\cal R$-trivial nor $\\cal L$-trivial.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    }
  }
}

/****************************************************
*
* SortieLaTeXEstDA. OK
*
****************************************************/

void SortieLaTeXEstDA(FILE *fichier)
{
  TestAperiodique();
  if (!(Varietes & SEM_APERIODIQUE))    /* Ce semigroupe n'est pas aperiodique */
    return;
  TestDA();
  if (Varietes & SEM_DA)    /* Ce %s est dans DA */
    fprintf(fichier, "This %s is in $\\DA$.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else    /* Ce %s n'est pas dans DA, car l'identite (xy)^(yx)^(xy)^ = (xy)^ n'est pas satisfaite lorsque */
  {
    fprintf(fichier, "This %s is not in $\\DA$ since the identity ", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    fprintf(fichier, "$(xy)^\\omega (yx)^\\omega (xy)^\\omega = (xy)^\\omega$ is not satisfied for $x = ");
    SortieLaTeXMot(*Adresses.DA_x, fichier);
    fprintf(fichier, "$ and $y = ");
    SortieLaTeXMot(*Adresses.DA_y, fichier);
    fprintf(fichier, "$.\n");
  }
}

/****************************************************
*
* SortieLaTeXEstDS. OK
*
****************************************************/

void SortieLaTeXEstDS(FILE *fichier)
{
  TestDS();
  if (Varietes & SEM_DS)    /* Ce %s est dans DS */
    fprintf(fichier, "This %s is in $\\DS$.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else    /* Ce %s n'est pas dans DS, car l'identite ((xy)^(yx)^(xy))^ = (xy)^ n'est pas satisfaite lorsque */
  {
    fprintf(fichier, "This %s is not in $\\DS$, since the identity $((xy)^\\omega (yx)^\\omega (xy)^\\omega)^\\omega = (xy)^\\omega$ is not satisfied for $x = ", 
            TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    SortieLaTeXMot(*Adresses.DS_x, fichier);
    fprintf(fichier, "$ and $y = ");
    SortieLaTeXMot(*Adresses.DS_y, fichier);
    fprintf(fichier, "$.\n");
  }
}

/****************************************************
*
* SortieLaTeXEstRvL. OK
*
****************************************************/

void SortieLaTeXEstRvL(FILE *fichier)
{
  TestRvL();
  if (Varietes & SEM_RvL)    /* Ce %s est dans R v L */
    fprintf(fichier, "This %s is in $\\vR \\vee \\vL$.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else    /* Ce %s n'est pas dans R v L, car l'identite (xy)^x(zx)^ = (xy)^(zx)^ n'est pas satisfaite lorsque */
  {
     fprintf(fichier, "This %s is not in $\\vR \\vee \\vL$ since the identity $(xy)^\\omega x (zx)^\\omega = (xy)^\\omega(zx)^\\omega$ is not satisfied for $x = ", 
            TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    SortieLaTeXMot(*Adresses.RvL_x, fichier);
    fprintf(fichier, "$, $y = ");
    SortieLaTeXMot(*Adresses.RvL_y, fichier);
    fprintf(fichier, "$ and $z = ");
    SortieLaTeXMot(*Adresses.RvL_z, fichier);
    fprintf(fichier, "$.\n");
  }
}

/****************************************************
*
* SortieLaTeXEstL1. OK
*
****************************************************/

void SortieLaTeXEstL1(FILE *fichier)
{
  TestL1();
  if (Varietes & SEM_LI)    /* Ce %s est dans L1 */
    fprintf(fichier, "This %s is locally trivial.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else    /* Ce %s n'est pas dans L1, car l'identite ese = e n'est pas satisfaite lorsque */
  {
    fprintf(fichier, "This %s is not locally trivial, since $ese \\not= e$ for $e = ", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    SortieLaTeXMot(*Adresses.L1_e, fichier);
    fprintf(fichier, "$ and $s = ");
    SortieLaTeXMot(*Adresses.L1_s, fichier);
    fprintf(fichier, "$.\n");
  }
}

/****************************************************
*
* SortieLaTeXEstLG. OK
*
****************************************************/

void SortieLaTeXEstLG(FILE *fichier)
{
  TestLG();
  if (Varietes & SEM_LG)    /* Ce %s est dans LG */
    fprintf(fichier, "This %s is locally a group.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else    /* Ce %s n'est pas dans LG, car l'identite ese = e n'est pas satisfaite lorsque */
  {
    fprintf(fichier, "This %s is not locally a group since the identity $(ese)^\\omega = e$ is not satisfied for $e = ", 
            TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    SortieLaTeXMot(*Adresses.LG_e, fichier);
    fprintf(fichier, "$ and $s = ");
    SortieLaTeXMot(*Adresses.LG_s, fichier);
    fprintf(fichier, "$.\n");
  }
}

/****************************************************
*
* SortieLaTeXEstB1. OK
*
****************************************************/

void SortieLaTeXEstB1(FILE *fichier)
{
  TestB1();
  if (Varietes & SEM_B_UN)    /* Ce %s est dans B1 */
    fprintf(fichier, "This %s is of dot-depth one.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else    /* Ce %s n'est pas dans B1, car l'identite (epfqe)^pfs(erfse)^ = (epfqe)^(erfse)^ n'est pas satisfaite lorsque */
  {
    fprintf(fichier, "This %s is not of dot-depth one, since the Knast identity ", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    fprintf(fichier, "$(epfqe)^\\omega pfs(erfse)^\\omega = (epfqe)^\\omega(erfse)^\\omega$ is not satisfied for $e = ");
    SortieLaTeXMot(*Adresses.B1_e, fichier);
    fprintf(fichier, "$, $f = ");
    SortieLaTeXMot(*Adresses.B1_f, fichier);
    fprintf(fichier, "$, $p = ");
    SortieLaTeXMot(*Adresses.B1_p, fichier);
    fprintf(fichier, "$, $q = ");
    SortieLaTeXMot(*Adresses.B1_q, fichier);
    fprintf(fichier, "$, $r = ");
    SortieLaTeXMot(*Adresses.B1_r, fichier);
    fprintf(fichier, "$, $s = ");
    SortieLaTeXMot(*Adresses.B1_s, fichier);
    fprintf(fichier, "$\n");
  }
}

/****************************************************
*
* SortieLaTeXEstB1Plus. OK
*
****************************************************/

void SortieLaTeXEstB1Plus(FILE *fichier)
{
  TestB1Plus();
  if (Varietes & SEM_B_UN_PLUS)    /* Ce %s est dans B1Plus */
    fprintf(fichier, "This ordered %s is in $\\LJ^+$\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else    /* Ce %s n'est pas dans B1+, car l'identite ese <= e n'est pas satisfaite lorsque */
  {
    fprintf(fichier, "This ordered %s is not in $\\LJ^+$ since the identity $ese \\leq e$ is not satisfied for $e = ", 
            TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    SortieLaTeXMot(*Adresses.B1Plus_e, fichier);
    fprintf(fichier, "$, $s = ");
    SortieLaTeXMot(*Adresses.B1Plus_s, fichier);
    fprintf(fichier, "$.\n");
  }
}

/****************************************************
*
* SortieLaTeXEstEcom. OK
*
****************************************************/

void SortieLaTeXEstEcom(FILE *fichier)
{
  TestECom();
  if (Varietes & SEM_ECOM)    /* Ce %s est dans Ecom */
    fprintf(fichier, "The idempotents of this %s commute.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else    /* Ce %s n'est pas dans Ecom, car l'identite ef = fe n'est pas satisfaite lorsque */
  {
    fprintf(fichier, "The idempotents of this %s do not commute, since $ef \\not= fe$ for $e = ", 
            TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    SortieLaTeXMot(*Adresses.ECom_e, fichier);
    fprintf(fichier, "$ and $f = ");
    SortieLaTeXMot(*Adresses.ECom_f, fichier);
    fprintf(fichier, "$.\n");
  }
}

/****************************************************
*
* SortieLaTeXEstBG. OK
*
****************************************************/

void SortieLaTeXEstBG(FILE *fichier)
{
  TestBG();
  if (Varietes & SEM_BG)    /* Ce %s est dans BG */
    fprintf(fichier, "This %s is a block-group.\n", TypeCalcul == Semigroupe ? "semigroup" : "monoid");
  else    /* Ce %s n'est pas dans BG, car l'identite (ef)^ = (fe)^ n'est pas satisfaite lorsque */
  {
    fprintf(fichier, "This %s is not a block-group, since the identity $(ef)^\\omega = (fe)^\\omega$ is not satisfied for $e = ", 
            TypeCalcul == Semigroupe ? "semigroup" : "monoid");
    SortieLaTeXMot(*Adresses.BG_e, fichier);
    fprintf(fichier, "$ and $f = ");
    SortieLaTeXMot(*Adresses.BG_f, fichier);
    fprintf(fichier, "$.\n");
  }
}