int sao_isomorfos(grafo g, grafo f)
{
    int i = 0;
    int j, k;
    int iso = 0;
    int tam = g.n_vertices;
    int *tmp = (int*) malloc(sizeof(int));
    int v[tam], t_perm = 0;
    lista *perm;

    perm = constroi_lista();

    for(i=0; i < tam; i++)
    {
        v[i] = i;
    }

    if((g.n_vertices != f.n_vertices) || (g.arestas != f.arestas)
       || (!iguais(g, f)))
        return iso;

    perm = nova_permuta(perm, v, 0, tam);
    t_perm = tamanho_lista(perm);

    for(i=0; i < t_perm; i++)
    {
        tmp = (int*) remove_lista(perm);
        //mostre(tmp, tam);
        iso = 1;
        for(j=0; j < tam; j++)
        {
            for(k=0; k < tam; k++)
            {
                if(g.matriz[j][k] != f.matriz[tmp[j]][tmp[k]])
                {
                    iso = 0;
                    /*printf("Nao e isomorfo - ");
                    mostre(tmp, tam);*/
                    break;
                }
            }
            if(!iso)
                break;
        }
        if(iso)
        {
            /*printf("E isomorfo - ");
            mostre(tmp, tam);*/
            destroi_lista(perm);
            return 1;
        }
    }
    destroi_lista(perm);
    return 0;
}
Exemple #2
0
Sinais* simula(t_circuito* circuto, Sinais* entradas)
{
    int i, j, validos;
    Tempo t;

    Transicao *listaTr = NULL;
    Transicao *itTr = NULL;

    Evento *fila = NULL;
    Pulso *p = NULL;

    ListaComponente *portasAlteradas = NULL;
    Componente gate = NULL;
    ValorLogico resultado;

    Sinais *saidas = novaSinais();

    if(!circuto || !entradas)
        return NULL;

    validos = 0;

    // Validação da correspência das entradas entre os arquivos '.v' e '.in'
    for( i=0 ; i < circuto->listaFiosEntrada->tamanho ; i++ )
    {
        for( j=0 ; j < entradas->quantidade ; j++ )
        {
            if( iguais( circuto->listaFiosEntrada->itens[i]->nome, entradas->lista[j].nome ) )
            {
                circuto->listaFiosEntrada->itens[i]->sinalEntrada = &(entradas->lista[j]);
                validos++;
                break;
            }
        }
    }

    ///
    printf("\nENTRADAS:\n  .v = %d\n .in = %d\n batem = %d\n\n",
           circuto->listaFiosEntrada->tamanho,
           entradas->quantidade,
           validos);
    ///

    if(validos < circuto->listaFiosEntrada->tamanho)
    {
        printf("O arquivo de entradas tem menos sinais de entrada que o circuito.\n");
        return NULL;
    }

    // Inicialização da fila de eventos com os valores das entradas
    fila = NULL;

    for( i=0 ; i < circuto->listaFiosEntrada->tamanho ; i++ )
    {
        t = 0;

        p = circuto->listaFiosEntrada->itens[i]->sinalEntrada->pulsos;
        while(p->valor != nulo)
        {
            insereEvento(&fila, t, circuto->listaFiosEntrada->itens[i], p->valor);
            t = t + p->tempo;

            p++;
        }

        insereEvento(&fila, t, circuto->listaFiosEntrada->itens[i], x); // este sinal fica até infitito
    }

    // ATENÇÃO: Sabemos que todos os componentes são inicializados com o valorDinamico em xis

    // A partir daqui, ocorre a simulação propriamente dita, usado fila de eventos
    t = 0;

    while(fila)
    {
        portasAlteradas = novaListaComponente();

        t = fila->quando;

        listaTr = popEvento(&fila);
        itTr = listaTr;

        // atualiza valores de fios e faz uma lista das portas alteradas pelas transicoes em listaTr
        while(itTr)
        {
            if(itTr->fio->valorDinamico != itTr->novoValor) // apenas se houver mudança de valor no fio
            {
                for( i=0 ; i < itTr->fio->listaSaida->tamanho ; i++ )
                {
                    if( !contemComponente( portasAlteradas, itTr->fio->listaSaida->itens[i] ) ) {
                        insereComponente( portasAlteradas, itTr->fio->listaSaida->itens[i] );
                    }
                }

                if(itTr->fio->tipo.operador == output)
                {
                    if( !(itTr->fio->sinalSaida) )
                        itTr->fio->sinalSaida = novoSinal( itTr->fio->nome );

                    addPulso( itTr->fio->sinalSaida, itTr->fio->valorDinamico, t - itTr->fio->sinalSaida->duracaoTotal );
                }

                itTr->fio->valorDinamico = itTr->novoValor;
            }

            itTr = itTr->proximo;
        }

        free(listaTr); // popEvento não liberou a lista de transições, fazemos isso aqui
        listaTr = NULL;

        for( i=0 ; i < portasAlteradas->tamanho ; i++ )
        {
            gate = portasAlteradas->itens[i];

            switch( gate->tipo.operador )
            {
            case op_not:
                if(gate->listaEntrada->itens[0]->valorDinamico == x)
                    resultado = x;
                else if (gate->listaEntrada->itens[0]->valorDinamico == zero)
                    resultado = um;
                else if (gate->listaEntrada->itens[0]->valorDinamico == um)
                    resultado = zero;

                // cria eventos relativ. às saidas da porta
                for(j=0 ; j < gate->listaSaida->tamanho ; j++)
                {
                    insereEvento(&fila, t + gate->tipo.atraso, gate->listaSaida->itens[j], resultado);
                }

                break;

            case op_buf:
                // cria eventos relativ. às saidas da porta
                for(j=0 ; j < gate->listaSaida->tamanho ; j++)
                {
                    insereEvento(&fila, t + gate->tipo.atraso, gate->listaSaida->itens[j], gate->listaEntrada->itens[0]->valorDinamico);
                }

                break;

            case op_and:
                resultado = um;

                // computa o valor
                for(j=0 ; j < gate->listaEntrada->tamanho ; j++)
                {
                    if(gate->listaEntrada->itens[j]->valorDinamico == x)
                    {
                        resultado = x;
                        break;
                    }
                    else if(gate->listaEntrada->itens[j]->valorDinamico == zero)
                    {
                        resultado = zero;
                    }
                }

                // cria eventos relativ. às saidas da porta
                for(j=0 ; j < gate->listaSaida->tamanho ; j++)
                {
                    insereEvento(&fila, t + gate->tipo.atraso, gate->listaSaida->itens[j], resultado);
                }

                break;

            case op_or:
                resultado = zero;

                // computa o valor
                for(j=0 ; j < gate->listaEntrada->tamanho ; j++)
                {
                    if(gate->listaEntrada->itens[j]->valorDinamico == x)
                    {
                        resultado = x;
                        break;
                    }
                    else if(gate->listaEntrada->itens[j]->valorDinamico == um)
                    {
                        resultado = um;
                    }
                }

                // cria eventos relativ. às saidas da porta
                for(j=0 ; j < gate->listaSaida->tamanho ; j++)
                {
                    insereEvento(&fila, t + gate->tipo.atraso, gate->listaSaida->itens[j], resultado);
                }

                break;

            case op_xor:
                if(gate->listaEntrada->itens[0]->valorDinamico == x || gate->listaEntrada->itens[1]->valorDinamico == x)
                {
                    resultado = x;
                }
                else
                {
                    if ( (gate->listaEntrada->itens[0]->valorDinamico == um && gate->listaEntrada->itens[1]->valorDinamico == zero) ||
                         (gate->listaEntrada->itens[0]->valorDinamico == zero && gate->listaEntrada->itens[1]->valorDinamico == um) )
                    {
                        resultado = um;
                    }
                    else
                    {
                        resultado = zero;
                    }
                }

                // cria eventos relativ. às saidas da porta
                for(j=0 ; j < gate->listaSaida->tamanho ; j++)
                {
                    insereEvento(&fila, t + gate->tipo.atraso, gate->listaSaida->itens[j], resultado);
                }

                break;

            case op_nand:
                resultado = um;

                // computa o valor
                for(j=0 ; j < gate->listaEntrada->tamanho ; j++)
                {
                    if(gate->listaEntrada->itens[j]->valorDinamico == x)
                    {
                        resultado = x;
                        break;
                    }
                    else if(gate->listaEntrada->itens[j]->valorDinamico == zero)
                    {
                        resultado = zero;
                    }
                }

                // fazemos a negação do resultado se este for diferente de x
                if(resultado != x)
                    resultado = (resultado == zero ? um : zero);

                // cria eventos relativ. às saidas da porta
                for(j=0 ; j < gate->listaSaida->tamanho ; j++)
                {
                    insereEvento(&fila, t + gate->tipo.atraso, gate->listaSaida->itens[j], resultado);
                }

                break;

            case op_nor:
                resultado = zero;

                // computa o valor
                for(j=0 ; j < gate->listaEntrada->tamanho ; j++)
                {
                    if(gate->listaEntrada->itens[j]->valorDinamico == x)
                    {
                        resultado = x;
                        break;
                    }
                    else if(gate->listaEntrada->itens[j]->valorDinamico == um)
                    {
                        resultado = um;
                    }
                }

                // fazemos a negação do resultado se este for diferente de x
                if(resultado != x)
                    resultado = (resultado == zero ? um : zero);

                // cria eventos relativ. às saidas da porta
                for(j=0 ; j < gate->listaSaida->tamanho ; j++)
                {
                    insereEvento(&fila, t + gate->tipo.atraso, gate->listaSaida->itens[j], resultado);
                }

                break;

            case op_xnor:
                if(gate->listaEntrada->itens[0]->valorDinamico == x || gate->listaEntrada->itens[1]->valorDinamico == x)
                {
                    resultado = x;
                }
                else
                {
                    if ( (gate->listaEntrada->itens[0]->valorDinamico == um && gate->listaEntrada->itens[1]->valorDinamico == um) ||
                         (gate->listaEntrada->itens[0]->valorDinamico == zero && gate->listaEntrada->itens[1]->valorDinamico == zero) )
                    {
                        resultado = um;
                    }
                    else
                    {
                        resultado = zero;
                    }
                }

                // cria eventos relativ. às saidas da porta
                for(j=0 ; j < gate->listaSaida->tamanho ; j++)
                {
                    insereEvento(&fila, t + gate->tipo.atraso, gate->listaSaida->itens[j], resultado);
                }

                break;

            default:
                break;
            }
        }

    }

    // copia as saidas da simulação do ciruito para o retorno
    for(i=0 ; i < circuto->listaFiosSaida->tamanho ; i++)
        addSinalPronto(saidas, circuto->listaFiosSaida->itens[i]->sinalSaida);

    return saidas;
}