2016-06-04 1 views
2

Je veux supprimer toutes les apparences d'un élément dans une liste, similaire à this, mais dans mon cas, la liste peut avoir des variables non-instanciées. Par exemple:Prolog: supprime un membre de la liste avec des valeurs non-instanciées

delMember(z, [A,B,A,z], L). 
L = [A, B, A]; 
false. 

et

delMember(A, [A, B, A, z], L). 
L = [B,z]; 
false. 

J'ai essayé de définir delMember comme suit:

delMember(_, [], []). 
delMember(X, [X|Xs], Y) :- delMember(X, Xs, Y). 
delMember(X, [T|Xs], [T|Y]) :- X \== T, delMember(X, Xs, Y). 

Avec cette définition, le dernier résultat que je reçois est correct mais il essaie encore pour instancier les variables avant cela.

?- delMember(A, [A,B,A,z], R). 
A = B, B = z, 
R = [] ; 
A = B, 
R = [z] ; 
A = z, 
R = [B] ; 
R = [B, z] ; 

des idées ???

+2

L'unification se produit dans votre deuxième alinéa: 'delMember (X, [X | X], Y): - delMember (X, Xs, Y). », qui va unifier le premier argument avec la tête de la liste dans le second argument s'ils sont unifiables. Puisque vous essayez d'éviter cela, vous devez utiliser '==' là aussi: 'delMember (X, [Y | Xs], R): - X == Y, delMember (X, Xs, R). – lurker

+0

Merci @lurker! C'était exactement ce dont j'avais besoin. Si vous voulez mettre une réponse à cela, je serai heureux de l'accepter. – lithiium

Répondre

1

Si vous regardez votre deuxième clause sous-jacente:

delMember(X, [X|Xs], Y) :- delMember(X, Xs, Y). 

Unification se produit avec le X dans les premier et deuxième arguments. Cela conduit aux résultats que vous observez lorsque vous faites votre requête. Vous devez appliquer le même opérateur que vous avez fait dans votre troisième clause. Donc, votre prédicat complet (avec quelques noms de variables légèrement modifié pour être plus conventionnel) ressemblerait à ceci:

delMember(_, [], []). 
delMember(X, [X1|Xs], Ys) :- X == X1, delMember(X, Xs, Ys). 
delMember(X, [X1|Xs], [X1|Ys]) :- X \== X1, delMember(X, Xs, Ys).