listes dans une nouvelle liste dans prologue sans utiliser flatten / 2 [duplicate]

Nov 20 2020

Je récupère plusieurs listes à partir de listes et les mets dans une nouvelle liste. Mais je veux faire la nouvelle liste d'éléments individuels et non une liste avec des listes. Alors disons que j'ai la liste [[a, b], c, [d, e]] que je voudrais obtenir [a, b, c, d, e]. Comment dois-je procéder?

Réponses

3 DuDa Nov 20 2020 at 02:58

Pour utiliser un exemple de code extrait d'une question aléatoire aujourd'hui: supposons que vous disposez d'une base de connaissances comme suit:

step('pancakes', 1, 'mix butter and sugar in a bowl', [butter, sugar], [bowl]). 
step('pancakes', 2, 'add eggs', [eggs], []). 
step('pancakes', 3, 'mix flour and bakingpowder', [flour, bakingpowder], []). 

Et vous êtes intéressé par tous les ingrédients d'un plat. La première idée serait

?- Dish='pancakes', findall(X,step(Dish,_,_,X,_),I).
Dish = pancakes,
I = [[butter, sugar], [eggs], [flour, bakingpowder]] ;
false.

Mais le problème ici est que la liste des ingrédients est imbriquée. Puisque ce flatten/2n'est pas autorisé, vous avez maintenant 2 choix: soit aplatir votre résultat, soit utiliser findall sur tous les ingrédients de la liste des ingrédients de chacun steppour un plat.

Pour aplatir, je recommande d'utiliser l'implémentation flatten2/2de ce post. La question résultante pourrait être quelque chose comme ceci:

?- Dish='pancakes', findall(X,step(Dish,_,_,X,_),I), flatten2(I,J).

Ajoutez un sort/2si vous souhaitez vous débarrasser des doublons comme état dans cet article.

Si vous souhaitez utiliser la deuxième méthode, vous devez créer un prédicat d'aide qui montre les ingrédients de tous les plats. ingredients/3donne les ingrédients comme élément unique pour chaque plat et numéro d'étape. Donc, pour chaque Dishet Stepplusieurs entrées avec différents ingrédients sont possibles.

ingredients(Dish,Step,Ingred):-
    step(Dish,Step,_,L,_),
    member(Ingred,L).

?- Dish='pancakes', findall(X,ingredients(Dish,_,X),I).
Dish = pancakes,
I = [butter, sugar, eggs, flour, bakingpowder] ;
false.

Pour se débarrasser des doublons, utilisez sort/2.

PS: Je ne sais toujours pas si vous êtes autorisé à utiliser findall/3.

1 Kintalken Nov 20 2020 at 04:27
flatten(SOURCEs,TARGETs)
:-
phrase(flatten(SOURCEs),TARGETs)
.

flatten([HEAD|TAILs]) --> { is_list(HEAD) } , HEAD , flatten(TAILs) .
flatten([HEAD|TAILs]) --> { \+ is_list(HEAD) } , [HEAD] , flatten(TAILs) .
flatten([]) --> [] .
/**
?- flatten([[a,b],c,[d,e]],TARGETs) .
TARGETs = [a, b, c, d, e] ;
false.

?-