Como usar o testador

O testador é um programa em Prolog que define vários predicados úteis para verificar se seu programa está resolvendo as chapas a contento. Este mesmo testador (ou talvez uma versão mais aperfeiçoada) será usado para avaliar os programas da turma.

Abaixo listamos os proncipais predicados que podem ser úteis para você. A convenção que usaremos nestas descrições é a seguinte. Um argumento precedido de sinal + significa um argumento que tem que entrar instanciado ao chamar-se o predicado. Seria um parâmetro de entrada do predicado. Um argumento precedido de - é um parâmetro de saída.

jmOk(+Chapa,+Expr)

Recebe uma chapa e uma expressão e verifica se a expressão é uma resolução válida da chapa dada. Imprime algumas mensagens de erro, pricipalmente relativas ao uso de DEC.

jmTest

Sem argumentos, este predicado gera uma chapa ao acaso e passa-a ao predicado resolve. Imprime a chapa e a solução proposta, se houver. Chama também jmOk para verificará solução, se houver.

jmTest(+Chapa)

Dada uma chapa, este predicado passa-a ao predicado resolve. Imprime a chapa e a solução proposta, se houver. Chama também jmOk para verificará solução, se houver.

jmConta(+N,-Lista)

Este predicado recebe um número inteiro e positivo N, e realiza N testes aleatórios com o predicado resolve. Mais precisamente, são geradas N chapas aleatórias, cada uma delas é passada ao resolve, e as expressões retornadas são verificadas pelo jmOk. No final, a Lista é instanciada com as chapas que não puderam ser resolvidas a contento. Este predicado é útil para verificar quais chapas o seu programa ainda está achando difíceis.

jmRealTest

Este predicado testa o resolve com TODAS as possíveis chapas. Pode demorar muito. Lembre-se de que existem 10000 chapas ao todo.

Problemas com o testador

Andei observando alguns problemas com o testador, tanto em casa (num PC) como na escola (numa estação Unix). Ele não verifica direito as contas em alguns casos. Dois destes casos estão narrados abaixo. Outros podem existir, embora estes dois são os únicos que eu observei.

O primeiro caso ocorre quando estão envolvidos números inteiros muito grandes, acima da capacidade de uma palavra da máquina (aparentemente). Um produto de dois inteiros grandes, por exemplo, pode dar um número negativo ou um número que, apesar de positivo, não corresponde ao resultado correto. Exemplos (Unix):

| ?- X is 5040 * 40320.

     X=1886208 
yes

Obviamente isto está errado, pois o resultado deveria terminar em zero. Contudo, é isto que dá, e não vem mensagem de erro alguma.

O segundo caso envolve números reais grandes. Acima de um certo valor, a capacidade da máquina é excedida e o resultado é simplesmente um valor infinito. O problema é que o testador vai achar que dois valores infinitos são iguais e validar uma expressão errada. Por exemplo, a seguinte resolução da chapa 2737 está obviamente errada:

2 ^ fat(7) = 3 ^ fat(7)

mas o testador aceitou alegremente a expressão abaixo (no Unix):

[=,[^,2,[fat,7]],[^,3,[fat,7]]]

por causa do "efeito infinito" relatado.


Joao Meidanis
Last modified: Mon Oct 6 18:41:13 EDT 1997