• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

softklin

[Prolog] Dúvida numa função parecida com um filtro

4 mensagens neste tópico

Boas pessoal.

Tenho de fazer uma função na linguagem Prolog que pega numa lista de casas de um tabuleiro e remove algumas que estejam fora das regras definidas (neste caso é apnas verificar se estão dentro dos limites impostos pelo tabuleiro). Tentei fazer a seguinte definição recursiva:

% limites maximos do tabuleiro
limites(5, 5).

filtrarCasas([], Validas).
filtrarCasas([casa(X, Y, E, G, H, F)|Cs], Validas) :- limites(Xm, Ym),
                                                                                   (X =< Xm),
                                                                                   (Y =< Ym),
                                                                                   (X > 0),
                                                                                   (Y > 0),
                                                                                   Validas = ([casa(X, Y, E, G, H, F) | Validas]),
                                                                                   filtrarCasas(Cs, Validas).
filtrarCasas([_|Cs], Validas) :- filtrarCasas(Cs, Validas).

A função até filtra as casas de modo correcto, mas o resultado não é o pretendido. Se chamar assim:

filtrarCasas([casa(9,9,'A',5,1,2), casa(2,3,'A',5,1,2), casa(0,5,'A',5,1,2)], Validas)

o resultado é uma lista infinita com a casa correcta:

Validas = [casa(2,3,'A',5,1,2),casa(2,3,'A',5,1,2),casa(2,3,'A',5,1,2),casa(2,3,'A',5,1,2),casa(2,3,'A',5,1,2),casa(2,3,'A',5,1,2),casa(2,3,'A',5,1,2),casa(2,3,'A',5,1,2),casa(2,3,'A',5,1,2),casa(...)|...]

Alguma ideia do que está mal na função? Tem uma condição de paragem, não estou mesmo a perceber o porquê da lista infinita...

Obrigado desde já.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

A filtragem numa lista vazia não devia devolver uma lista vaza?

Parece-me que estavas a querer fazer uma versão com acumuladores, mas nesse caso precisavas de 3 argumentos.

Sem usares acumuladores, o segundo predicado fica semelhante ao último, com a diferença que tens que adicionar a cabeça da lista ao resultado.

Qualquer coisa do género

f([H|T],[H|R]):-..., f(T,R).

Não executei o teu código, mas diria que tens um problema aqui: Validas = ([casa(X, Y, E, G, H, F) | Validas]). Penso que o que querias fazer se obtém usando o append, mas terias sempre de usar dois nomes diferentes, caso contrário o predicado falharia.

Já agora, fazeres trace da execução pode-te ajudar a perceber o problema.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Olá Rui Carlos, obrigado pela resposta.

Tentei dividir a lista em cabeça|cauda, como sugeriste, mas não deu. Também tentei com o append, mas tudo o que consegui foi um endereço de memória do prolog (ex:  _1234).

De qualquer forma, não conseguimos fazer nada com essa função, pelo que seguimos outra estratégia de resolução.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pegando no código que apresentei, só precisavas de adicionar as condições (ou seja, substituir as "..." pelas condições).

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora