Diff for /rpl/src/simplification.c between versions 1.50 and 1.77

version 1.50, 2014/10/13 07:12:54 version 1.77, 2022/09/07 13:40:42
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.19    RPL/2 (R) version 4.1.34
   Copyright (C) 1989-2014 Dr. BERTRAND Joël    Copyright (C) 1989-2021 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
   
Line 25 Line 25
   
 /*  /*
 ================================================================================  ================================================================================
     Fonction d'affichage d'un arbre q-aire
   ================================================================================
     Entrées : pointeur sur une structure struct_processus
   --------------------------------------------------------------------------------
     Sorties :
   --------------------------------------------------------------------------------
     Effets de bord : néant
   ================================================================================
   */
   
   static void
   affichage_arbre(struct_processus *s_etat_processus, struct_arbre *s_arbre,
           int niveau)
   {
       int                         i;
   
       integer8                    branche;
   
       struct_liste_chainee        *l_element_courant;
   
       unsigned char               *chaine;
   
       if (niveau == 0)
       {
           printf("--- Arbre $%016X\n", s_arbre);
       }
   
       // Affichage de la feuille (fonction ou donnée générale s'il n'y 
       // a pas de branche)
   
       l_element_courant = (*s_arbre).feuille;
   
       for(i = 0; i < niveau; i++)
       {
           printf("  ");
       }
   
       while(l_element_courant != NULL)
       {
           if ((chaine = formateur(s_etat_processus, 0,
                   (*l_element_courant).donnee)) == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           printf("%s ", chaine);
           free(chaine);
   
           l_element_courant = (*l_element_courant).suivant;
       }
   
       printf("\n");
   
       // Affichage des branches (arguments de la fonction dans la feuille)
   
       for(branche = 0; branche < (*s_arbre).nombre_branches; branche++)
       {
           affichage_arbre(s_etat_processus, (*s_arbre).branches[branche],
                   niveau + 1);
       }
   
       if (niveau == 0)
       {
           printf("--- Fin de l'arbre\n");
       }
   
       return;
   }
   
   
   /*
   ================================================================================
   Fonction de transcription d'un arbre en liste chaînée    Fonction de transcription d'un arbre en liste chaînée
 ================================================================================  ================================================================================
   Entrées : pointeur sur une structure struct_processus    Entrées : pointeur sur une structure struct_processus
Line 66  transcription_arbre(struct_processus *s_ Line 139  transcription_arbre(struct_processus *s_
         }          }
     }      }
   
     if ((l_liste = allocation_maillon(s_etat_processus)) == NULL)      // Ajout des fonctions
   
       if ((*s_arbre).nombre_branches != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          free((*s_arbre).branches);
         return(NULL);  
     }      }
   
     // Ajout de la fonction      l_liste = (*s_arbre).feuille;
   
     (*l_liste).suivant = NULL;  
     (*l_liste).donnee = (*s_arbre).feuille;  
   
     free((*s_arbre).branches);  
     free(s_arbre);      free(s_arbre);
   
     // Chaînage des arguments      // Chaînage des arguments
Line 111  transcription_arbre(struct_processus *s_ Line 180  transcription_arbre(struct_processus *s_
   
 /*  /*
 ================================================================================  ================================================================================
     Fonction de simplification d'un arbre
   ================================================================================
     Entrées : pointeur sur une structure struct_processus
   --------------------------------------------------------------------------------
     Sorties :
   --------------------------------------------------------------------------------
     Effets de bord : néant
   ================================================================================
   */
   
   static int
   ordonnancement_branches(const void *a1, const void *a2)
   {
       struct_arbre    **_a1;
       struct_arbre    **_a2;
   
       _a1 = (struct_arbre **) a1;
       _a2 = (struct_arbre **) a2;
   
       if (((**_a1).feuille != NULL) && ((**_a2).feuille != NULL))
       {
           // Si les types sont identiques, on ne change rien.
   
           if ((*(*(**_a1).feuille).donnee).type ==
                   (*(*(**_a2).feuille).donnee).type)
           {
               return(0);
           }
   
           // On rejette les nombres à la fin.
   
           if (((*(*(**_a1).feuille).donnee).type == INT) ||
                   ((*(*(**_a1).feuille).donnee).type == REL) ||
                   ((*(*(**_a1).feuille).donnee).type == CPL))
           {
               return(1);
           }
           else
           {
               return(-1);
           }
       }
   
       return(0);
   }
   
   
   static int
   ordonnancement_instructions_neg(const void *a1, const void *a2)
   {
       struct_arbre    **_a1;
   
       _a1 = (struct_arbre **) a1;
   
       if ((**_a1).feuille != NULL)
       {
           // On rejette NEG à la fin de l'arbre.
   
           if ((*(*(**_a1).feuille).donnee).type == FCT)
           {
               if (strcmp((*((struct_fonction *) (*(*(**_a1).feuille).donnee)
                       .objet)).nom_fonction, "NEG") == 0)
               {
                   return(1);
               }
               else
               {
                   return(-1);
               }
           }
           else
           {
               return(0);
           }
       }
   
       return(0);
   }
   
   
   static void
   simplification_arbre(struct_processus *s_etat_processus,
           struct_arbre *s_arbre)
   {
       integer8                i;
       integer8                j;
       integer8                nouveaux_elements;
   
       struct_arbre            *s_branche;
   
       struct_liste_chainee    *l_element_courant;
       struct_liste_chainee    *l_element_suivant;
   
       struct_objet            *s_objet;
   
       if ((*(*(*s_arbre).feuille).donnee).type != FCT)
       {
           // L'objet formant le noeud n'est pas une fonction. Il n'y a aucune
           // simplification possible.
   
           return;
       }
   
       // Transformation des soustractions que l'on remplace par
       // une addition de l'opposé. Si l'on a une soustraction,
       // on greffe donc une instruction NEG dans l'arbre.
       // Note : à cet instant, l'instruction '-' ne peut avoir que deux
       // opérandes.
   
       if (strcmp((*((struct_fonction *) (*(*((*s_arbre).feuille)).donnee).objet))
               .nom_fonction, "-") == 0)
       {
           if ((*s_arbre).nombre_branches != 2)
           {
               (*s_etat_processus).erreur_execution = d_ex_simplification;
               return;
           }
   
           liberation(s_etat_processus, (*((*s_arbre).feuille)).donnee);
   
           if (((*((*s_arbre).feuille)).donnee = allocation(s_etat_processus,
                   FCT)) == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           if (((*((struct_fonction *) (*(*((*s_arbre).feuille)).donnee).objet))
                   .nom_fonction = malloc(2 * sizeof(unsigned char))) == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           strcpy((*((struct_fonction *) (*(*((*s_arbre).feuille)).donnee).objet))
                   .nom_fonction, "+");
           (*((struct_fonction *) (*(*((*s_arbre).feuille)).donnee).objet))
                   .nombre_arguments = 1;
   
           if ((s_branche = malloc(sizeof(struct_arbre))) == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           if (((*s_branche).branches = malloc(sizeof(struct_arbre *))) == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           if (((*s_branche).feuille = allocation_maillon(s_etat_processus))
                   == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           (*(*s_branche).feuille).suivant = NULL;
   
           if (((*(*s_branche).feuille).donnee = allocation(s_etat_processus, FCT))
                   == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           if (((*((struct_fonction *) (*(*(*s_branche).feuille).donnee).objet))
                   .nom_fonction = malloc(4 * sizeof(unsigned char))) == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           strcpy((*((struct_fonction *) (*(*(*s_branche).feuille).donnee).objet))
                   .nom_fonction, "NEG");
           (*((struct_fonction *) (*(*(*s_branche).feuille).donnee).objet))
                   .nombre_arguments = 1;
           (*s_branche).branches[0] = (*s_arbre).branches[1];
           (*s_branche).nombre_branches = 1;
           (*s_arbre).branches[1] = s_branche;
       }
   
       // La feuille est une fonction, on peut envisager la simplification
       // de l'arbre. Pour cela, on descend d'un niveau pour greffer
       // de nouvelles branches.
   
       if (strcmp((*((struct_fonction *) (*(*(*s_arbre).feuille).donnee).objet))
               .nom_fonction, "+") == 0)
       {
           qsort((*s_arbre).branches, (size_t) (*s_arbre)
                   .nombre_branches, sizeof(struct_arbre *),
                   ordonnancement_instructions_neg);
   
           for(i = 0; i < (*s_arbre).nombre_branches; i++)
           {
               s_objet = (*((*((*s_arbre).branches[i])).feuille)).donnee;
   
               if ((*s_objet).type == FCT)
               {
                   if (strcmp((*((struct_fonction *) (*s_objet).objet))
                           .nom_fonction, "-") == 0)
                   {
                       simplification_arbre(s_etat_processus,
                               (*s_arbre).branches[i]);
                       s_objet = (*((*((*s_arbre).branches[i])).feuille)).donnee;
                   }
   
                   if (strcmp((*((struct_fonction *) (*s_objet).objet))
                           .nom_fonction, "+") == 0)
                   {
                       simplification_arbre(s_etat_processus,
                               (*s_arbre).branches[i]);
   
                       /*
                        On greffe.
   +
     +
       2
       SIN
         3
     10
   
                        doit donner :
   +
     2
     SIN
       3
     10
                       */
   
                       nouveaux_elements = (*(*s_arbre).branches[i])
                               .nombre_branches;
   
                       if (((*s_arbre).branches = realloc((*s_arbre).branches,
                               ((unsigned) ((*s_arbre).nombre_branches
                               + nouveaux_elements))
                               * sizeof(struct_arbre *))) == NULL)
                       {
                           (*s_etat_processus).erreur_systeme =
                                   d_es_allocation_memoire;
                           return;
                       }
   
                       for(j = 0; j < nouveaux_elements; j++)
                       {
                           (*s_arbre).branches[(*s_arbre).nombre_branches++] =
                                   (*(*s_arbre).branches[i]).branches[j];
                       }
   
                       l_element_courant = (*s_arbre).feuille;
                       (*s_arbre).feuille = (*(*s_arbre).branches[i]).feuille;
   
                       l_element_suivant = (*s_arbre).feuille;
                       while((*l_element_suivant).suivant != NULL)
                       {
                           l_element_suivant = (*l_element_suivant).suivant;
                       }
   
                       (*l_element_suivant).suivant = l_element_courant;
                       free((*(*s_arbre).branches[i]).branches);
                       free((*s_arbre).branches[i]);
   
                       // Retrait de la branche
                   
                       for(j = i + 1; j < (*s_arbre).nombre_branches; j++)
                       {
                           (*s_arbre).branches[j - 1] = (*s_arbre).branches[j];
                       }
   
                       (*s_arbre).nombre_branches--;
   
                       // Réorganisation des valeurs numériques en queue.
   
                       qsort((*s_arbre).branches, (size_t) (*s_arbre)
                               .nombre_branches, sizeof(struct_arbre *),
                               ordonnancement_branches);
                   }
               }
           }
   
           if (((*s_arbre).branches = realloc((*s_arbre).branches,
                   ((unsigned) (*s_arbre).nombre_branches)
                   * sizeof(struct_arbre *))) == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
       }
   
       return;
   }
   
   
   /*
   ================================================================================
   Fonction 'simplification' (ne libère pas les paramètres)    Fonction 'simplification' (ne libère pas les paramètres)
 ================================================================================  ================================================================================
   Entrées : pointeur sur une structure struct_processus    Entrées : pointeur sur une structure struct_processus
Line 126  simplification(struct_processus *s_etat_ Line 491  simplification(struct_processus *s_etat_
 {  {
     struct_objet                *s_objet_simplifie;      struct_objet                *s_objet_simplifie;
   
 #   ifdef   EXPERIMENTAL_CODE   
   
     integer8                    i;      integer8                    i;
     integer8                    nombre_arguments;      integer8                    nombre_arguments;
   
Line 185  simplification(struct_processus *s_etat_ Line 548  simplification(struct_processus *s_etat_
                             return(NULL);                              return(NULL);
                         }                          }
   
                         (*s_arbre).inversion = d_faux;  
                         (*s_arbre).nombre_branches = nombre_arguments;                          (*s_arbre).nombre_branches = nombre_arguments;
   
                           if (((*s_arbre).feuille = allocation_maillon(
                                   s_etat_processus)) == NULL)
                           {
                               (*s_etat_processus).erreur_systeme =
                                       d_es_allocation_memoire;
                               return(NULL);
                           }
   
                           (*(*s_arbre).feuille).donnee = copie_objet(
                                   s_etat_processus, (*l_element_courant).donnee,
                                   'P');
                           (*(*s_arbre).feuille).suivant = NULL;
   
                         if (((*s_arbre).branches = malloc(((size_t) (*s_arbre)                          if (((*s_arbre).branches = malloc(((size_t) (*s_arbre)
                                 .nombre_branches) * sizeof(struct_arbre *)))                                  .nombre_branches) * sizeof(struct_arbre *)))
                                 == NULL)                                  == NULL)
Line 197  simplification(struct_processus *s_etat_ Line 572  simplification(struct_processus *s_etat_
                             return(NULL);                              return(NULL);
                         }                          }
   
                         for(i = 0; i < nombre_arguments; i++)                          for(i = nombre_arguments - 1; i >= 0; i--)
                         {                          {
                             if (l_liste_locale == NULL)                              if (l_liste_locale == NULL)
                             {                              {
Line 206  simplification(struct_processus *s_etat_ Line 581  simplification(struct_processus *s_etat_
                                 return(NULL);                                  return(NULL);
                             }                              }
   
                             if (((*s_arbre).branches[i] = malloc(                              (*s_arbre).branches[i] = (struct_arbre *)
                                     sizeof(struct_arbre))) == NULL)  
                             {  
                                 (*s_etat_processus).erreur_systeme =  
                                         d_es_allocation_memoire;  
                                 return(NULL);  
                             }  
   
                             (*(*s_arbre).branches[i]).feuille =  
                                     (*l_liste_locale).donnee;                                      (*l_liste_locale).donnee;
                             (*(*s_arbre).branches[i]).inversion = d_faux;  
                             (*(*s_arbre).branches[i]).nombre_branches = 0;  
                             (*(*s_arbre).branches[i]).branches = NULL;  
   
                             l_ancienne_liste_locale = l_liste_locale;                              l_ancienne_liste_locale = l_liste_locale;
                             l_liste_locale = (*l_liste_locale).suivant;                              l_liste_locale = (*l_liste_locale).suivant;
Line 267  simplification(struct_processus *s_etat_ Line 631  simplification(struct_processus *s_etat_
                         return(NULL);                          return(NULL);
                     }                      }
   
                     (*s_arbre).feuille = copie_objet(s_etat_processus,                      if (((*s_arbre).feuille = allocation_maillon(
                             (*l_element_courant).donnee, 'P');                              s_etat_processus)) == NULL)
                     (*s_arbre).inversion = d_faux;                      {
                           (*s_etat_processus).erreur_systeme =
                                   d_es_allocation_memoire;
                           return(NULL);
                       }
   
                       (*(*s_arbre).feuille).donnee = copie_objet(
                               s_etat_processus, (*l_element_courant).donnee, 'P');
                       (*(*s_arbre).feuille).suivant = NULL;
                     (*s_arbre).nombre_branches = 0;                      (*s_arbre).nombre_branches = 0;
                     (*s_arbre).branches = NULL;                      (*s_arbre).branches = NULL;
   
Line 305  simplification(struct_processus *s_etat_ Line 677  simplification(struct_processus *s_etat_
          * Simplification de l'arbre           * Simplification de l'arbre
          */           */
   
 #       if 0          affichage_arbre(s_etat_processus, s_arbre, 0);
         simplification_arbre();          simplification_arbre(s_etat_processus, s_arbre);
 #       endif          affichage_arbre(s_etat_processus, s_arbre, 0);
   
           if ((*s_etat_processus).erreur_systeme != d_es)
           {
               return(NULL);
           }
   
         /*          /*
          * Transcription de l'arbre q-aire simplifié en expression algébrique.           * Transcription de l'arbre q-aire simplifié en expression algébrique.
Line 397  simplification(struct_processus *s_etat_ Line 774  simplification(struct_processus *s_etat_
                 .nom_fonction, ">>");                  .nom_fonction, ">>");
     }      }
     else      else
 #   endif  
     {      {
         s_objet_simplifie = copie_objet(s_etat_processus, s_objet, 'P');          s_objet_simplifie = copie_objet(s_etat_processus, s_objet, 'P');
     }      }

Removed from v.1.50  
changed lines
  Added in v.1.77


CVSweb interface <joel.bertrand@systella.fr>