Listen in neuer Liste im Prolog ohne Verwendung von flatten / 2 [Duplikat]
Ich rufe mehrere Listen aus Listen ab und füge sie in eine neue Liste ein. Aber ich möchte die neue Liste der einzelnen Elemente erstellen und keine Liste mit Listen. Angenommen, ich habe die Liste [[a, b], c, [d, e]], die ich erhalten möchte [a, b, c, d, e]. Wie gehe ich vor?
Antworten
So verwenden Sie heute einen Beispielcode, der aus einer zufälligen Frage stammt: Nehmen Sie an, Sie haben eine Wissensbasis wie folgt:
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], []).
Und Sie interessieren sich für alle Zutaten für ein Gericht. Erste Idee wäre
?- Dish='pancakes', findall(X,step(Dish,_,_,X,_),I).
Dish = pancakes,
I = [[butter, sugar], [eggs], [flour, bakingpowder]] ;
false.
Das Problem hierbei ist jedoch, dass die Zutatenliste nestet ist. Da dies flatten/2
nicht zulässig ist, haben Sie jetzt zwei Möglichkeiten: entweder das Ergebnis zu reduzieren oder findall für alle Zutaten aus der Zutatenliste der einzelnen Zutaten step
für ein Gericht zu verwenden.
Zum Abflachen empfehle ich die Implementierung flatten2/2
aus diesem Beitrag. Die daraus resultierende Frage könnte ungefähr so lauten:
?- Dish='pancakes', findall(X,step(Dish,_,_,X,_),I), flatten2(I,J).
Fügen Sie ein hinzu, sort/2
wenn Sie Duplikate als Statet in diesem Beitrag entfernen möchten .
Wenn Sie die zweite Methode verwenden möchten, müssen Sie ein Hilfsprädikat erstellen, das die Zutaten für alle Gerichte anzeigt. ingredients/3
gibt die Zutaten als einzelnes Element für jedes Gericht und Schrittnummer an. So sind für jeden Dish
und Step
mehrere Einträge unterschiedliche Zutaten möglich.
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.
Um die Duplikate loszuwerden, verwenden Sie sort/2
.
PS: Ich weiß immer noch nicht, ob du es benutzen darfst findall/3
.
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.
?-