2010-03-31 15 views
1

Je suis nouveau dans Prolog et j'essaie de créer une fonction qui supprimera simplement toutes les instances d'un élément d'une liste. Le code suivant est ce que j'ai jusqu'à présent:Création d'une fonction 'remove member' dans prolog

remove([H|T], E, L2) :- (\+ ([H|T] == []) -> 
    (H == E 
     -> remove(T, E, L2) 
     ; append(L2, H, L2), remove(T, E, L2) 
    ) 
    ; append(L2, []) 
). 

Quand je lance ce code sur:

remove([1,2,3,4,5], 3, L2). 

je reçois une erreur:

ERROR: Out of global stack 

Quelqu'un pourrait-il me rappeler pourquoi je je reçois ce problème?

Répondre

3

Cette déclaration

[H|T] == [] 

ne peut jamais être vrai parce qu'une liste vide ne peut jamais être identique à une liste qui contient au moins un élément.

+0

Vous avez raison. Cependant, à chaque itération, je passe un élément de moins (la queue), ce qui signifie que finalement, la liste n'aura aucun élément et la récursivité devrait s'arrêter. Au moins que l'idée ... – screenshot345

+0

Vous semblez provenir d'un contexte différent (programmation impérative?) Et donc avoir une incompréhension fondamentale de la façon dont fonctionne Prolog. Je vous recommande de regarder le code source des prédicats de traitement de liste comme membre/2, append/3, etc. L'idée de base est que les listes sont immuables, et supprimer signifie copier tous les éléments voulus d'une liste à l'autre et ignorer les indésirables. [H | T] = [] peut _never_ être vrai, même si T = [], alors vous avez juste [H] = [] qui ne tient pas. – Kaarel

1

Ce que vous avez besoin est un de SWI Soustraire prédicat:

?- subtract([1,1,2,3,1],[1,2],R). 
R = [3]. 

?- listing(subtract). 
lists:subtract([], _, []) :- !. 
lists:subtract([A|C], B, D) :- 
     memberchk(A, B), !, 
     subtract(C, B, D). 
lists:subtract([A|B], C, [A|D]) :- 
     subtract(B, C, D). 

true.