Listen in neuer Liste im Prolog ohne Verwendung von flatten / 2 [Duplikat]

Nov 20 2020

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

3 DuDa Nov 20 2020 at 02:58

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/2nicht 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 stepfür ein Gericht zu verwenden.

Zum Abflachen empfehle ich die Implementierung flatten2/2aus 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/2wenn 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/3gibt die Zutaten als einzelnes Element für jedes Gericht und Schrittnummer an. So sind für jeden Dishund Stepmehrere 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.

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.

?-