Progetto C Programmazione Università

di il
41 risposte

Progetto C Programmazione Università

Ciao a tutti , dovrei presentare un progetto per l università ed essendo il mio primo progetto vorrei avere qualche dritta vi posto la richiesta del professore:

Scrivere un programma ANSI C che acquisisce da tastiera due formule di logica proposizionale
e stabilisce se esse sono equivalenti. Per semplicita, ciascuna formula puo contenere al piu tre
occorrenze di connettivi logici (negazione, disgiunzione, congiunzione, implicazione, doppia im-
plicazione), i quali possono essere rappresentati come singole cifre decimali. Di conseguenza, la
formula puo contenere al piu quattro occorrenze di proposizioni, le quali possono essere rappresen-
tate come singole lettere. Ciascuna formula non deve contenere parentesi, quindi bisogna applicare
le regole di precedenza e associativita.

Ho iniziato a fare qualcosa e ho pensato di creare delle strutture in cui salvare il valore della proposizione pero poi non ho tanto le idee chiare per il proseguito...grazie mille ragazzi

41 Risposte

  • Re: Progetto C Programmazione Università

    Le parole magiche sono:

    1) definire la grammatica della logica proposizionale
    2) imprementare un parser ricorsivo discendente
    3) leggere da tastiera la stringa che rappresenta l'espressione
    4) con il parser creare l'albero corrispondente all'espressione
    5) implementare le regole i semplificazione applicabili all'albero
    6) applicare le regole di semplificazione all' espressione 'P1 == P2'

    Se al termine della semplificazione ti ritrovi con l'albero nullo, o, in alternativa, con il valore VERO, allora le due espressioni sono equivalenti, altrimenti no.

    Se non sai di che cosa stia parlando, ti trovi in un bel guaio
  • Re: Progetto C Programmazione Università

    Be allora sono in un bel guaio....aaaaa...comunque gli alberi li stiamo studiando ora...essendo un progetto per quelli del 2° e del 3° che devono recuperare l esame , il proff ci ha dato la possibilita di farlo cosi da avvantaggiarci per giugno e sinceramente mi farebbe comodo....
    cominciamo dal passo 1 ....come dovrei definire la grammatica???
  • Re: Progetto C Programmazione Università

    Ad esempio:
  • Re: Progetto C Programmazione Università

    Non so usarlo dovrei vedere bene....ma se invece utilizzo un array di strutture e li salvo ogni singolo carattere???
  • Re: Progetto C Programmazione Università

    migliorabile ha scritto:


    Le parole magiche sono:

    1) definire la grammatica della logica proposizionale
    2) imprementare un parser ricorsivo discendente
    3) leggere da tastiera la stringa che rappresenta l'espressione
    4) con il parser creare l'albero corrispondente all'espressione
    5) implementare le regole i semplificazione applicabili all'albero
    6) applicare le regole di semplificazione all' espressione 'P1 == P2'

    Se al termine della semplificazione ti ritrovi con l'albero nullo, o, in alternativa, con il valore VERO, allora le due espressioni sono equivalenti, altrimenti no.

    Se non sai di che cosa stia parlando, ti trovi in un bel guaio
    Credo che l'esercizio come è stato espresso non habbia bisogno degli alberi, altrimenti non sarebbe stata così necessaria la restrizione per cui non ci sono parentesi.
    Inoltre c'è la restrizione sul numero di proposizioni, 4, quindi si potrebbe anche usare un approccio naif valutando se tutte le 6 combinazioni true false nella prima formula danno lo stesso risultato nella seconda. In questo modo il problema si ridurrebbe alla valutazione di 2 formule e al confronto dei 2 risultati.

    Quindi si potrebbe risolvere con uno stack che memorizza gli operatori e un vettore che memorizza gli operandi, e valutando le espressioni come scritte in notazione polacca inversa, attraverso un algoritmo ricorsivo con backtracking.
  • Re: Progetto C Programmazione Università

    dvaosta ha scritto:


    migliorabile ha scritto:


    Le parole magiche sono:

    1) definire la grammatica della logica proposizionale
    2) imprementare un parser ricorsivo discendente
    3) leggere da tastiera la stringa che rappresenta l'espressione
    4) con il parser creare l'albero corrispondente all'espressione
    5) implementare le regole i semplificazione applicabili all'albero
    6) applicare le regole di semplificazione all' espressione 'P1 == P2'

    Se al termine della semplificazione ti ritrovi con l'albero nullo, o, in alternativa, con il valore VERO, allora le due espressioni sono equivalenti, altrimenti no.

    Se non sai di che cosa stia parlando, ti trovi in un bel guaio
    Credo che l'esercizio come è stato espresso non habbia bisogno degli alberi, altrimenti non sarebbe stata così necessaria la restrizione per cui non ci sono parentesi.
    Inoltre c'è la restrizione sul numero di proposizioni, 4, quindi si potrebbe anche usare un approccio naif valutando se tutte le 6 combinazioni true false nella prima formula danno lo stesso risultato nella seconda. In questo modo il problema si ridurrebbe alla valutazione di 2 formule e al confronto dei 2 risultati.

    Quindi si potrebbe risolvere con uno stack che memorizza gli operatori e gli operandi, e valutando le espressioni come scritte in notazione polacca inversa, attraverso un algoritmo ricorsivo con backtracking.
  • Re: Progetto C Programmazione Università

    Ni, forse.
    Come la metti con le regole di precedenza ed associativita'?
    a or b and c
    vuol dire
    a or (b and c)
    NON
    (a or b) and c
    Una qualche forma di albero mi sa che deve comunque essere implementata.

    Muble, mumble....

    In effetti, un approccio alla RPN ci potrebbe stare. Comunque l'albero c'e', anche se in forma implicita

    Il caro vecchio RPN!!!
  • Re: Progetto C Programmazione Università

    Si può usare uno stack,ma data la semplicità dell'esercizio si può usare direttamente la stringa in ingresso come stack.
    Si eseguirà un parser proprio come se lo facessimo su carta,prendiamo come definizione che i caratteri maiuscoli siano valori true e i caratteri minuscoli siano valori false.
    Per una semplice logica booleana avremo dunque che

    !a|b = A|b = A
    !b&!c = B&C = B
    !a&!b|!c&!d = A&B|C&D = A|C = A

    Descriviamo quindi una grammatica,sviluppiamo alcune funzioni di supporto,allacciamo il tutto:
    
    ///BOOLEAN CALCULATOR
    /// Grammatica elementare:
    /// wordfalse   : "abcdefghijklmnopqrstuvwxyz"
    /// wordTRUE    : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    /// word        : wordtrue || wordfalse
    /// operatornot : "!" : operatornot word
    /// operatoror  : "|" : word operatoror word
    /// operatorand : "&" : word operatorand word
    /// precedenza  : operatornot,operatorand,operatoror
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX 100
    #define STEP_WORD 0
    #define STEP_OPERATOR 1
    
    int iswordfalse(char c)
    {
        if ( (c >= 'a' && c <= 'z') )
            return 1;
        return 0;
    }
    
    int iswordtrue(char c)
    {
        if ( (c >= 'A' && c <= 'Z') )
            return 1;
        return 0;
    }
    
    char setword(char c,int boo)
    {
        if (iswordfalse(c) && boo)
            return  c - ('a' - 'A');
        else if (iswordtrue(c) && !boo)
            return  c + ('a' - 'A');
    
        return c;
    }
    
    int isword(char c)
    {
        if ( iswordfalse(c) || iswordtrue(c) )
            return 1;
        return 0;
    }
    
    int isoperator(char c)
    {
        switch (c)
        {
            case '!':case '&':case '|':return 1;
        }
        return 0;
    }
    
    char operate(char lvalue,char ope, char rvalue)
    {
        switch (ope)
        {
            case '!':
                if ( iswordfalse(rvalue) )
                    return setword(rvalue,1);
                else
                    return setword(rvalue,0);
    
            case '&':
                if ( iswordtrue(lvalue) && iswordtrue(rvalue))
                    return setword(lvalue,1);
                else
                    return setword(lvalue,0);
    
            case '|':
                if ( iswordtrue(lvalue) || iswordtrue(rvalue))
                {
                    if (iswordtrue(lvalue))
                        return lvalue;
                    else
                        return rvalue;
                }
                else
                    return setword(lvalue,0);
        }
    
        return 0;
    }
    
    void strep(char* d,const char c,int str)
    {
        *d++ = c;
        while ( *d != '\0' )
        {
            *d = *(d + str);
            d++;
        }
    }
    
    char* syntax(char* buffer)
    {
        //tolgo spazii e enter
        //controllo che var sia 1 word e che sia alternato con operator
        //formula non può finire con operator
    
        char *rpb = buffer;
        char *avb = buffer;
        int step = STEP_WORD;
    
        while ( *avb != '\0' && *avb != '\n')
        {
            if (*avb == ' ')
            {
                ++avb;
                continue;
            }
    
            if (step == STEP_WORD)
            {
                step = STEP_OPERATOR;
                if ( !isword(*avb) )
                {
                    if (*avb != '!') return avb;
                }
                else
                {
                    *rpb++ = *avb++;
                    continue;
                }
            }
    
            if ( step == STEP_OPERATOR)
            {
                if ( !isoperator(*avb) ) return avb;
                step = STEP_WORD;
            }
    
            *rpb++ = *avb++;
        }
    
        if (step == STEP_WORD)
            return avb;
    
        *rpb = '\0';
    
        return NULL;
    }
    
    int parser_not(char* buffer)
    {
        char* stop;
        char rt;
    
        for ( ;  *buffer != '\0' ; buffer++)
        {
            if ( *buffer == '!')
            {
                stop = buffer;
                ++buffer;
                rt = operate(0,'!',*buffer);
                strep(stop,rt,1);
                buffer = stop;
            }
    
        }//all char
    
        return 0;
    }
    
    int parser_orand(char* buffer,char op)
    {
        char* stop;
        char rt,lv;
    
        for ( ;  *buffer != '\0' ; buffer++)
        {
            if ( *buffer == op)
            {
                ++buffer;
                rt = operate(lv,op,*buffer);
                strep(stop,rt,2);
                buffer = stop - 1;
            }
            else
            {
                stop = buffer;
                lv = *buffer;
            }
        }//all char
    
        return 0;
    }
    
    char parser(char* buffer)
    {
        parser_not(buffer);
        parser_orand(buffer,'&');
        parser_orand(buffer,'|');
        return *buffer;
    }
    
    int main ()
    {
        char buffer[MAX];
    
        printf("Insert formula:");
        gets(buffer);
    
        printf("Syntax...");
        char* erc = syntax(buffer);
        if ( erc != NULL)
        {
            printf("error at char :%d\n",(erc - buffer) + 1);
            return -1;
        }
        printf("ok\n");
    
        printf("eval = %c\n", parser(buffer));
    
        return 0;
    }
    
    Ora basta modificarlo per le proprie esigenze.
  • Re: Progetto C Programmazione Università

    Io sto scrivendo lo stesso programma, probabilmente per lo stesso prof e ho lo stesso problema.
    - ho scritto l'acquisizione della stringa
    - la sua validazione
    - l'inserimento di tutti i valori possibili per le proposizioni

    ma devo trovare un modo per semplificare la formula. Avevo pensato di farlo ricorsivamente, ma con le poche conoscenze che ho di programmazione (sono tre mesi che facciamo il c) mi trovo un po' in difficoltà: avete qualche idea? Non chiedo codice pronto, solo una piccola imbeccata e questa cosa della notazione polacca potrebbe essere un'idea.
  • Re: Progetto C Programmazione Università

    Scusate visto che c'è il topic vorrei chiedere una cosa..

    Ho fatto anche io questo programma, il mio problema però è l'equivalenza..
    COme la implemento in C?
    Enumerazione? Mi date una dritta perché non so come impostare l'equivalenza..
    Il resto ovviamente l'ho già fatto.
  • Re: Progetto C Programmazione Università


    Ma vi aiutate a vicenda????
    Margherita posta il codice in modo che i tuoi compagni possano scopiazzarlo un pò....
    Se ve lo faccio io poi non vi crede nessuno.....e sicuramente fate un cut/paste bibblico.....
  • Re: Progetto C Programmazione Università

    Il codice non l'ho messo perché sono dal telefono e non riesco ovviamente comunque io ho quasi fatto, devo solo implementarlo..
    Ho l'idea ma non sapendo se era giusta chiedevo..
  • Re: Progetto C Programmazione Università

    Non credo gli convenga copiarlo, per due motivi: il prof cancella tutti i progetti con uguale codice e dopo ti tocca discuterlo con lui all'orale e se non hai scritto tu riga per riga, non riesci a dirgli nemmeno come hai importato le librerie! Nel caso, lo tolgo...io non ho mai copiato una riga di codice che fosse una, chiedo solo qualche consiglio, non riesco a capire i codici altrui: comunque ormai dovrei orientarmi con la notazione postfissa a scrivere qualcosa per la risoluzione
  • Re: Progetto C Programmazione Università

    Avete al massimo 4 variabile e 3 operatori quindi potete usare vettori di dimensione fissa e dopo l'inserimento date errore se superate i limiti.fine syntax.
    Se conoscete la matematica per la soluzione basta tradurla in c..... porca paletta!
    1)Un vettore che contenga i dati correttamente formattati(syntax)
    2)analizzo il vettore alla ricerca delle negazioni modificando il valore del vettore stesso
    3)ripeto le operazioni per il resto degli operatori
    ...
    ora che ho il parser
    ...
    eseguo un loop per tutti i valori e se i risultati delle due formule sono uguali allora sono equivalenti.


    stanotte se non mi addormento vi faccio un regalo....
Devi accedere o registrarti per scrivere nel forum
41 risposte