Filrer/3 en prolog, probleme

prolog

a marqué ce sujet comme résolu.

J’essaye d’écrire un prédicat filtre du style

filter([a,a,b,c,d,d],[a,d],L) et L s’unifie avec [b,c]

J’utilise un predicat delete/3 que j’ai écrit aussi, voici le code des deux

delete([],_,[]).

delete([A|X],E,Z) :- A==E, delete(X,E,Z).

delete([A|X],E,[A|Z]) :- A \== E, delete(X,E,Z).

filter(M,[],M).

filter([K|M],[E|N],Z) :- delete([K|M],E,Z), filter(Z,N,B).

Delete fonctionne bien, mais filtre pas vraiment, sans renvoyer d’érreur, il ne renvoie pas ce que j’veux, avec cet exemple

filtre([1,1,3,7,7],[1,7],Z).

les 4 dernières lignes de la trace

N-3 Call: (10) filtre([3], [], _18304470) ? creep

N-2 Exit: (10) filtre([3], [], [3]) ? creep

N-1 Exit: (9) filtre([3, 7, 7], [7], [3]) ? creep

N Exit: (8) filtre([1, 1, 3, 7, 7], [1, 7], [3, 7, 7]) ? creep

On voit bien que la ligne n-2 contient le resultat que je veux, [3], et c’est cette unification que j’attend qu’il renvoie, mais il remonte dans les appel récursif et renvoie la première unification (juste privé des '1’) et je comprends pas comment régler ça

sentez vous libre de critiquer mes raisonnement et ma manière de coder, j’avoue que prolog me déstabilise pas mal, j’ai du mal a comprendre la logique derrière.

+0 -0

On peut coder plus simple (et probablement plus idiomatique).

Par exemple delete([A|X],E,Z) :- A==E, delete(X,E,Z). peut s’écrire comme suit :

delete([A|X],A,Z) :- 
    delete(X,A,Z).

Ici l’unification est directe et n’a pas besoin d’être explicitée.

Pour le troisième cas delete([A|X],E,Z) :- A\==E, delete(X,E,[A|Z])., on peut éviter l’usage de \= en utilisant une coupure sur le cas précédent (si tu as déjà vu les coupures).

Quant a ce code : filter([K|M],[E|N],Z) :- delete([K|M],E,Z), filter(Z,N,B)., non seulement [K|M] ne sert a rien sous cette forme, mais surtout tu as un souci avec B qui n’est lié a rien.

Enfin, une question: qu’est ce qui est attendu pour filter([a,c,a,b,c,d,d,b],[a,d],L) ? Tu dois supprimer les doublons aussi ?

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte