dgadelha / Portugol-Webstudio

IDE online para o Portugol
https://portugol.dev
GNU General Public License v3.0
259 stars 51 forks source link

Avaliação de expressões completa vs short-circuit #228

Open ronneyns opened 4 months ago

ronneyns commented 4 months ago

Descrição do problema

A situação que venho reportar é a respeito do tipo de avaliação de expressões booleanas (completa ou short-circuit). A IDE parece usar a avaliação completa de expressão, o que pode causar erros em algumas condições.

Código

// Implementação de algoritmos de ordenação
programa {

  funcao ordenacao_insercao(inteiro vetor[], inteiro tamanho) {
    para (inteiro i = 1; i < tamanho; i = i + 1) {
      inteiro posicao = i
      inteiro chave = vetor[posicao]
      enquanto ((posicao > 0) e (vetor[posicao - 1] > chave)) {
        vetor[posicao] = vetor[posicao - 1]
        posicao = posicao - 1
      }
      vetor[posicao] = chave
    }
  }

  funcao inicio() {
    inteiro TAMANHO = 10
    inteiro vetor[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0} // {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

    ordenacao_insercao(vetor, TAMANHO)
  }
}

// Demonstração do problema que ocorre devido à avaliação de expressão
programa {
  funcao inicio() {
    inteiro vetor[] = {0, 1, 2}
    inteiro posicao
    logico teste

    // Teste 1/2: com valor falso e operador "e"
    posicao = 2
    escreva("Posição: ", posicao)
    teste = falso e (vetor[posicao] > 0)
    escreva(", teste: ", teste, "\n")

    posicao = posicao - 1
    escreva("Posição: ", posicao)
    teste = falso e (vetor[posicao] > 0)
    escreva(", teste: ", teste, "\n")

    posicao = posicao - 1
    escreva("Posição: ", posicao)
    teste = falso e (vetor[posicao] > 0)
    escreva(", teste: ", teste, "\n")

    posicao = posicao - 1
    escreva("Posição: ", posicao)
    teste = falso e (vetor[posicao] > 0)
    escreva(", teste: ", teste, "\n")

    // Teste 2/2: com valor verdadeiro e operador "ou"
    posicao = 2
    escreva("Posição: ", posicao)
    teste = verdadeiro ou (vetor[posicao] > 5)
    escreva(", teste: ", teste, "\n")

    posicao = posicao - 1
    escreva("Posição: ", posicao)
    teste = verdadeiro ou (vetor[posicao] > 5)
    escreva(", teste: ", teste, "\n")

    posicao = posicao - 1
    escreva("Posição: ", posicao)
    teste = verdadeiro ou (vetor[posicao] > 5)
    escreva(", teste: ", teste, "\n")

    posicao = posicao - 1
    escreva("Posição: ", posicao)
    teste = verdadeiro ou (vetor[posicao] > 5)
    escreva(", teste: ", teste, "\n")
  }
}

Comentários adicionais

Primeiramente, parabéns pelo excelente trabalho nesta IDE de Portugol! O problema ocorreu enquanto demonstrava o algoritmo de Insertion Sort (ver a função "ordenacao_insercao" na seção de código). Vi que o problema estava na avaliação da condição "enquanto ((posicao > 0) e (vetor[posicao - 1] > chave))" no loop interno, quando a variável "posicao" obtinha o valor 0 (zero) (pois configuraria erro por tentativa de acesso a uma posição por meio de índice fora dos limites do vetor). A questão ocorreu pela avaliação completa da expressão, o que não seria possível se a expressão já fosse avaliada com falsa após a avaliação apenas da primeira condição "posicao > 0". Coloco no final da seção de código outro programa que demonstra o mesmo problema de outra forma, usando o valor "falso" e o operador "e" e também o valor "verdadeiro" e o operador "ou".