Annotation of rpl/src/simplification.c, revision 1.50

1.1       bertrand    1: /*
                      2: ================================================================================
1.49      bertrand    3:   RPL/2 (R) version 4.1.19
1.47      bertrand    4:   Copyright (C) 1989-2014 Dr. BERTRAND Joël
1.1       bertrand    5: 
                      6:   This file is part of RPL/2.
                      7: 
                      8:   RPL/2 is free software; you can redistribute it and/or modify it
                      9:   under the terms of the CeCILL V2 License as published by the french
                     10:   CEA, CNRS and INRIA.
                     11:  
                     12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
                     13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                     14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
                     15:   for more details.
                     16:  
                     17:   You should have received a copy of the CeCILL License
                     18:   along with RPL/2. If not, write to info@cecill.info.
                     19: ================================================================================
                     20: */
                     21: 
                     22: 
1.11      bertrand   23: #include "rpl-conv.h"
1.1       bertrand   24: 
                     25: 
                     26: /*
                     27: ================================================================================
1.50    ! bertrand   28:   Fonction de transcription d'un arbre en liste chaînée
1.1       bertrand   29: ================================================================================
                     30:   Entrées : pointeur sur une structure struct_processus
                     31: --------------------------------------------------------------------------------
                     32:   Sorties :
                     33: --------------------------------------------------------------------------------
                     34:   Effets de bord : néant
                     35: ================================================================================
                     36: */
                     37: 
1.50    ! bertrand   38: static struct_liste_chainee *
        !            39: transcription_arbre(struct_processus *s_etat_processus, struct_arbre *s_arbre)
1.1       bertrand   40: {
1.50    ! bertrand   41:    integer8                i;
1.1       bertrand   42: 
                     43:    struct_liste_chainee    *l_element_courant;
1.50    ! bertrand   44:    struct_liste_chainee    *l_liste;
        !            45:    struct_liste_chainee    *l_nouvelle_pile_locale;
        !            46:    struct_liste_chainee    *l_pile_locale;
1.1       bertrand   47: 
1.50    ! bertrand   48:    l_pile_locale = NULL;
1.1       bertrand   49: 
1.50    ! bertrand   50:    for(i = 0; i < (*s_arbre).nombre_branches; i++)
1.1       bertrand   51:    {
1.50    ! bertrand   52:        if ((l_nouvelle_pile_locale = allocation_maillon(s_etat_processus))
        !            53:                == NULL)
        !            54:        {
        !            55:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !            56:            return(NULL);
        !            57:        }
1.1       bertrand   58: 
1.50    ! bertrand   59:        (*l_nouvelle_pile_locale).suivant = l_pile_locale;
        !            60:        l_pile_locale = l_nouvelle_pile_locale;
1.1       bertrand   61: 
1.50    ! bertrand   62:        if (((*l_pile_locale).donnee = (void *) transcription_arbre(
        !            63:                s_etat_processus, (*s_arbre).branches[i])) == NULL)
1.1       bertrand   64:        {
1.50    ! bertrand   65:            return(NULL);
1.1       bertrand   66:        }
1.50    ! bertrand   67:    }
        !            68: 
        !            69:    if ((l_liste = allocation_maillon(s_etat_processus)) == NULL)
        !            70:    {
        !            71:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !            72:        return(NULL);
        !            73:    }
1.1       bertrand   74: 
1.50    ! bertrand   75:    // Ajout de la fonction
        !            76: 
        !            77:    (*l_liste).suivant = NULL;
        !            78:    (*l_liste).donnee = (*s_arbre).feuille;
        !            79: 
        !            80:    free((*s_arbre).branches);
        !            81:    free(s_arbre);
        !            82: 
        !            83:    // Chaînage des arguments
        !            84: 
        !            85:    while(l_pile_locale != NULL)
        !            86:    {
        !            87:        l_element_courant = (void *) (*l_pile_locale).donnee;
        !            88: 
        !            89:        if (l_element_courant == NULL)
1.1       bertrand   90:        {
1.50    ! bertrand   91:            (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.1       bertrand   92:            return(NULL);
                     93:        }
                     94: 
1.50    ! bertrand   95:        while((*l_element_courant).suivant != NULL)
1.1       bertrand   96:        {
                     97:            l_element_courant = (*l_element_courant).suivant;
                     98:        }
                     99: 
1.50    ! bertrand  100:        (*l_element_courant).suivant = l_liste;
        !           101:        l_liste = (void *) (*l_pile_locale).donnee;
1.1       bertrand  102: 
1.50    ! bertrand  103:        l_nouvelle_pile_locale = (*l_pile_locale).suivant;
        !           104:        liberation_maillon(s_etat_processus, l_pile_locale);
        !           105:        l_pile_locale = l_nouvelle_pile_locale;
1.1       bertrand  106:    }
                    107: 
1.50    ! bertrand  108:    return(l_liste);
1.1       bertrand  109: }
                    110: 
                    111: 
                    112: /*
                    113: ================================================================================
1.50    ! bertrand  114:   Fonction 'simplification' (ne libère pas les paramètres)
1.1       bertrand  115: ================================================================================
1.50    ! bertrand  116:   Entrées : pointeur sur une structure struct_processus
1.1       bertrand  117: --------------------------------------------------------------------------------
                    118:   Sorties :
                    119: --------------------------------------------------------------------------------
                    120:   Effets de bord : néant
                    121: ================================================================================
                    122: */
                    123: 
1.50    ! bertrand  124: struct_objet *
        !           125: simplification(struct_processus *s_etat_processus, struct_objet *s_objet)
1.1       bertrand  126: {
1.50    ! bertrand  127:    struct_objet                *s_objet_simplifie;
        !           128: 
        !           129: #  ifdef   EXPERIMENTAL_CODE 
        !           130: 
        !           131:    integer8                    i;
        !           132:    integer8                    nombre_arguments;
        !           133: 
        !           134:    struct_arbre                *s_arbre;
        !           135: 
        !           136:    struct_liste_chainee        *l_element_courant;
        !           137: 
        !           138:    // Attention : l_liste_locale et l_ancienne_liste_locale ne contiennent pas
        !           139:    // un pointeur sur une struct_objet, mais sur une struct_arbre.
1.1       bertrand  140: 
1.50    ! bertrand  141:    struct_liste_chainee        *l_liste_locale;
        !           142:    struct_liste_chainee        *l_ancienne_liste_locale;
1.1       bertrand  143: 
1.50    ! bertrand  144:    if ((*s_objet).type == ALG)
1.1       bertrand  145:    {
1.50    ! bertrand  146:        /*
        !           147:         * Transcription de l'expression algébrique en arbre q-aire
        !           148:         */
1.1       bertrand  149: 
1.50    ! bertrand  150:        l_liste_locale = NULL;
        !           151:        l_element_courant = (*s_objet).objet;
1.1       bertrand  152: 
1.50    ! bertrand  153:        while(l_element_courant != NULL)
1.1       bertrand  154:        {
1.50    ! bertrand  155:            switch((*(*l_element_courant).donnee).type)
        !           156:            {
        !           157:                // Toutes les fonctions (intrinsèques, extrinsèques et
        !           158:                // utilisateurs).
        !           159: 
        !           160:                case FCT:
        !           161:                {
        !           162:                    // Il s'agit d'un objet de type ALG. Nous pouvons donc
        !           163:                    // sauter les délimiteurs d'expression.
        !           164: 
        !           165:                    if ((l_element_courant != (*s_objet).objet) &&
        !           166:                            ((*l_element_courant).suivant != NULL))
        !           167:                    {
        !           168:                        nombre_arguments = (*((struct_fonction *)
        !           169:                                (*(*l_element_courant).donnee).objet))
        !           170:                                .nombre_arguments;
        !           171: 
        !           172:                        // Si le nombre d'arguments vaut 0, la fonction
        !           173:                        // apparaît en notation algébrique comme une fonction
        !           174:                        // infixe.
        !           175: 
        !           176:                        if (nombre_arguments == 0)
        !           177:                        {
        !           178:                            nombre_arguments = 2;
        !           179:                        }
        !           180: 
        !           181:                        if ((s_arbre = malloc(sizeof(struct_arbre))) == NULL)
        !           182:                        {
        !           183:                            (*s_etat_processus).erreur_systeme =
        !           184:                                    d_es_allocation_memoire;
        !           185:                            return(NULL);
        !           186:                        }
        !           187: 
        !           188:                        (*s_arbre).inversion = d_faux;
        !           189:                        (*s_arbre).nombre_branches = nombre_arguments;
        !           190: 
        !           191:                        if (((*s_arbre).branches = malloc(((size_t) (*s_arbre)
        !           192:                                .nombre_branches) * sizeof(struct_arbre *)))
        !           193:                                == NULL)
        !           194:                        {
        !           195:                            (*s_etat_processus).erreur_systeme =
        !           196:                                    d_es_allocation_memoire;
        !           197:                            return(NULL);
        !           198:                        }
        !           199: 
        !           200:                        for(i = 0; i < nombre_arguments; i++)
        !           201:                        {
        !           202:                            if (l_liste_locale == NULL)
        !           203:                            {
        !           204:                                (*s_etat_processus).erreur_execution =
        !           205:                                        d_ex_manque_argument;
        !           206:                                return(NULL);
        !           207:                            }
        !           208: 
        !           209:                            if (((*s_arbre).branches[i] = malloc(
        !           210:                                    sizeof(struct_arbre))) == NULL)
        !           211:                            {
        !           212:                                (*s_etat_processus).erreur_systeme =
        !           213:                                        d_es_allocation_memoire;
        !           214:                                return(NULL);
        !           215:                            }
        !           216: 
        !           217:                            (*(*s_arbre).branches[i]).feuille =
        !           218:                                    (*l_liste_locale).donnee;
        !           219:                            (*(*s_arbre).branches[i]).inversion = d_faux;
        !           220:                            (*(*s_arbre).branches[i]).nombre_branches = 0;
        !           221:                            (*(*s_arbre).branches[i]).branches = NULL;
        !           222: 
        !           223:                            l_ancienne_liste_locale = l_liste_locale;
        !           224:                            l_liste_locale = (*l_liste_locale).suivant;
        !           225: 
        !           226:                            liberation_maillon(s_etat_processus,
        !           227:                                    l_ancienne_liste_locale);
        !           228:                        }
        !           229: 
        !           230:                        // Introduction de l'arbre dans la pile locale
        !           231: 
        !           232:                        l_ancienne_liste_locale = l_liste_locale;
        !           233: 
        !           234:                        if ((l_liste_locale = allocation_maillon(
        !           235:                                s_etat_processus)) == NULL)
        !           236:                        {
        !           237:                            (*s_etat_processus).erreur_systeme =
        !           238:                                    d_es_allocation_memoire;
        !           239:                            return(NULL);
        !           240:                        }
        !           241: 
        !           242:                        (*l_liste_locale).suivant = l_ancienne_liste_locale;
        !           243:                        (*l_liste_locale).donnee = (void *) s_arbre;
        !           244:                    }
1.1       bertrand  245: 
1.50    ! bertrand  246:                    break;
        !           247:                }
1.1       bertrand  248: 
1.50    ! bertrand  249:                default:
1.1       bertrand  250:                {
1.50    ! bertrand  251:                    l_ancienne_liste_locale = l_liste_locale;
        !           252: 
        !           253:                    if ((l_liste_locale = allocation_maillon(s_etat_processus))
        !           254:                            == NULL)
        !           255:                    {
        !           256:                        (*s_etat_processus).erreur_systeme =
        !           257:                                d_es_allocation_memoire;
        !           258:                        return(NULL);
        !           259:                    }
        !           260: 
        !           261:                    (*l_liste_locale).suivant = l_ancienne_liste_locale;
        !           262: 
        !           263:                    if ((s_arbre = malloc(sizeof(struct_arbre))) == NULL)
        !           264:                    {
        !           265:                        (*s_etat_processus).erreur_systeme =
        !           266:                                d_es_allocation_memoire;
        !           267:                        return(NULL);
        !           268:                    }
        !           269: 
        !           270:                    (*s_arbre).feuille = copie_objet(s_etat_processus,
        !           271:                            (*l_element_courant).donnee, 'P');
        !           272:                    (*s_arbre).inversion = d_faux;
        !           273:                    (*s_arbre).nombre_branches = 0;
        !           274:                    (*s_arbre).branches = NULL;
        !           275: 
        !           276:                    (*l_liste_locale).donnee = (void *) s_arbre;
        !           277:                    break;
1.1       bertrand  278:                }
                    279:            }
1.50    ! bertrand  280: 
        !           281:            l_element_courant = (*l_element_courant).suivant;
1.1       bertrand  282:        }
                    283: 
1.50    ! bertrand  284:        // Toute l'expression a été balayée. On ne doit plus avoir qu'un
        !           285:        // seul niveau dans la pile locale, ce niveau contenant l'arbre
        !           286:        // à réduire.
        !           287: 
        !           288:        if (l_liste_locale == NULL)
        !           289:        {
        !           290:            (*s_etat_processus).erreur_execution = d_ex_erreur_evaluation;
        !           291:            return(NULL);
        !           292:        }
        !           293:        else if ((*l_liste_locale).suivant != NULL)
        !           294:        {
        !           295:            (*s_etat_processus).erreur_execution = d_ex_erreur_evaluation;
        !           296:            return(NULL);
        !           297:        }
        !           298: 
        !           299:        s_arbre = (void *) (*l_liste_locale).donnee;
        !           300: 
        !           301:        liberation_maillon(s_etat_processus, l_liste_locale);
        !           302:        l_liste_locale = NULL;
        !           303: 
        !           304:        /*
        !           305:         * Simplification de l'arbre
        !           306:         */
        !           307: 
        !           308: #      if 0
        !           309:        simplification_arbre();
        !           310: #      endif
        !           311: 
        !           312:        /*
        !           313:         * Transcription de l'arbre q-aire simplifié en expression algébrique.
        !           314:         * Seule une fonction récursive permet de faire cette conversion
        !           315:         * simplement.
        !           316:         */
        !           317: 
        !           318:        l_liste_locale = transcription_arbre(s_etat_processus, s_arbre);
1.1       bertrand  319: 
1.50    ! bertrand  320:        if ((s_objet_simplifie = allocation(s_etat_processus, ALG))
        !           321:                == NULL)
        !           322:        {
        !           323:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           324:            return(NULL);
        !           325:        }
1.1       bertrand  326: 
1.50    ! bertrand  327:        // Ajout des délimiteurs '<<' et '>>' à la liste d'instructions
1.1       bertrand  328: 
1.50    ! bertrand  329:        if (((*s_objet_simplifie).objet = allocation_maillon(s_etat_processus))
        !           330:                == NULL)
1.1       bertrand  331:        {
1.50    ! bertrand  332:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           333:            return(NULL);
        !           334:        }
1.1       bertrand  335: 
1.50    ! bertrand  336:        l_element_courant = (*s_objet_simplifie).objet;
1.1       bertrand  337: 
1.50    ! bertrand  338:        if (((*l_element_courant).donnee = allocation(s_etat_processus,
        !           339:                FCT)) == NULL)
        !           340:        {
        !           341:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           342:            return(NULL);
1.1       bertrand  343:        }
                    344: 
1.50    ! bertrand  345:        (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
        !           346:                .nombre_arguments = 0;
        !           347:        (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
        !           348:                .fonction = instruction_vers_niveau_superieur;
1.1       bertrand  349: 
1.50    ! bertrand  350:        if (((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
        !           351:                .nom_fonction = malloc(3 * sizeof(unsigned char))) == NULL)
        !           352:        {
        !           353:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           354:            return(NULL);
        !           355:        }
1.1       bertrand  356: 
1.50    ! bertrand  357:        strcpy((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
        !           358:                .nom_fonction, "<<");
1.1       bertrand  359: 
1.50    ! bertrand  360:        (*l_element_courant).suivant = l_liste_locale;
1.1       bertrand  361: 
1.50    ! bertrand  362:        while((*l_element_courant).suivant != NULL)
1.1       bertrand  363:        {
1.50    ! bertrand  364:            l_element_courant = (*l_element_courant).suivant;
1.1       bertrand  365:        }
                    366: 
1.50    ! bertrand  367:        if (((*l_element_courant).suivant =
        !           368:                allocation_maillon(s_etat_processus)) == NULL)
        !           369:        {
        !           370:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           371:            return(NULL);
        !           372:        }
1.1       bertrand  373: 
1.50    ! bertrand  374:        l_element_courant = (*l_element_courant).suivant;
        !           375:        (*l_element_courant).suivant = NULL;
1.1       bertrand  376: 
1.50    ! bertrand  377:        if (((*l_element_courant).donnee = allocation(s_etat_processus,
        !           378:                FCT)) == NULL)
        !           379:        {
        !           380:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           381:            return(NULL);
        !           382:        }
1.1       bertrand  383: 
1.50    ! bertrand  384:        (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
        !           385:                .nombre_arguments = 0;
        !           386:        (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
        !           387:                .fonction = instruction_vers_niveau_inferieur;
1.1       bertrand  388: 
1.50    ! bertrand  389:        if (((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
        !           390:                .nom_fonction = malloc(3 * sizeof(unsigned char))) == NULL)
1.1       bertrand  391:        {
1.50    ! bertrand  392:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           393:            return(NULL);
1.1       bertrand  394:        }
1.50    ! bertrand  395: 
        !           396:        strcpy((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
        !           397:                .nom_fonction, ">>");
        !           398:    }
        !           399:    else
        !           400: #  endif
        !           401:    {
        !           402:        s_objet_simplifie = copie_objet(s_etat_processus, s_objet, 'P');
1.1       bertrand  403:    }
                    404: 
1.50    ! bertrand  405:    return(s_objet_simplifie);
1.1       bertrand  406: }
                    407: 
                    408: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>