2010-10-24 17 views
1

J'ai un problème où j'ai une liste comme ceci:Motif liste correspondant à des listes

[[el1, el2, el3], 
[el4, el5, el6], 
[[el7, el8, el9], [el10, el11, el12], ..... , [elxx, elyy, elzz]], 
[el, el, el]...]] 

Je veux motif correspondre à la liste intérieure des listes, la

[el7, el8, el9], [el10, el11, el12], ..... , [elxx, elyy, elzz] 

Comment cela peut-il être terminé?

A partir de maintenant je patternmatch les autres éléments avec

my_method([[El1, El2, El3] | Rest]). 

MISE À JOUR

Je veux match de modèle si l'élément suivant de la liste est une liste de listes - je vais Enumérer les cette liste, en supprimant article après article. Il peut y avoir un nombre quelconque de listes de listes, et elles peuvent contenir n'importe quel nombre d'éléments. Ils peuvent également contenir des listes de listes. En fait, j'appellerai récursivement la même méthode de traitement chaque fois que je tomberai sur une liste de listes.

Toutes les listes de niveau inférieur auront trois éléments, mais ces éléments peuvent être différents:

[1, p, neg (5,6)] [5, neg (7,6), hypothèse]

+0

Pouvez-vous clarifier la question un peu? Voulez-vous simplement obtenir le troisième élément de la liste (qui dans ce cas est la liste des listes) ou voulez-vous trouver l'élément qui est une liste de listes (sans savoir à quelle position ce sera)? – sepp2k

+0

@ sepp2k Question mise à jour avec un peu plus d'informations. Merci :) – Max

+0

Est-ce que toutes vos listes, qui ne sont pas des listes de listes, ont exactement trois éléments? – sepp2k

Répondre

1

Vous avez dit: « Je vais itérer sur cette liste, Suppression de l'élément après élément », est donc ici le code qui fait exactement cela, en supposant un « élément » est une liste à trois éléments de non-listes.

nested_member(X,X) :- 
    X = [A,_,_], 
    \+ is_list(A). 
nested_member(X,[L|_]) :- 
    nested_member(X,L). 
nested_member(X,[_|L]) :- 
    nested_member(X,L). 

Cela peut être utilisé pour revenir en arrière sur les « éléments »:

?- nested_member(X,[[el1, el2, el3], [el4, el5, el6], 
        [[el7, el8, el9], [el10, el11, el12],[elxx, elyy, elzz]]]). 
X = [el1, el2, el3] ; 
X = [el4, el5, el6] ; 
X = [el7, el8, el9] ; 
X = [el10, el11, el12] ; 
X = [elxx, elyy, elzz] ; 
false. 

Je te veux, vous pouvez même trouver la profondeur dans la liste des articles ont été trouvés:

nested_member(X,L,D) :- 
    nested_member(X,L,0,D). 
nested_member(X,X,D,D) :- 
    X = [A,_,_], 
    \+ is_list(A). 
nested_member(X,[L|_],D0,D) :- 
    D1 is D0+1, 
    nested_member(X,L,D1,D). 
nested_member(X,[_|L],D0,D) :- 
    nested_member(X,L,D0,D). 
+0

Je n'ai pas beaucoup de connaissances sur Prolog ... Pourriez-vous expliquer dans un peu plus de détails, comme ce que signifie \ + is_list (A)? Pourquoi mettez-vous X = [A, _, _]? Le premier X correspond seulement au second X s'ils sont égaux, non? – Max

+0

'\ +' est la négation, donc 'A' n'est peut-être pas une liste. 'X = [A, _, _]' correspond 'X' avec une liste de trois éléments, nommant le premier membre de la liste' A'. Et oui, si deux arguments ont le même nom, ils doivent être égaux. Dans le cas d'utilisation prévu, cela signifie que le premier argument (une variable) est défini sur la valeur du deuxième argument. –

1

Vous pouvez utiliser des prédicats similaires aux suivants.

qualify([], []). 
qualify([H|T], [HN|TN]) :- qualify_one(H, HN), qualify(T, TN). 

qualify_one([H|_], N) :- qualify_one(H, N1), N is N1 + 1, !. 
qualify_one(_, 0). 

Qu'est-ce que qualify fait est pour chaque membre de la liste pour savoir à quel niveau de l'échelle « pas une liste », « liste simple », « liste des listes », ... il est, sur la base premier article.

Exemple:

?- qualify([1,[2,3,3],[[4,5,6], [7,8,9]]], NS). 
NS = [0, 1, 2].