listy na nowej liście w prologu bez używania spłaszczenia / 2 [duplicate]

Nov 20 2020

Pobieram wiele list z list i umieszczam je na nowej liście. Ale chcę utworzyć nową listę pojedynczych pozycji, a nie listę z listami. Powiedzmy, że mam listę [[a, b], c, [d, e]], którą chciałbym uzyskać [a, b, c, d, e]. Jak mam się do tego zabrać?

Odpowiedzi

3 DuDa Nov 20 2020 at 02:58

Aby skorzystać dzisiaj z przykładowego wycinania kodu z losowego pytania: załóżmy, że masz następującą bazę wiedzy:

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], []). 

Interesują Cię wszystkie składniki dania. Pierwszy pomysł byłby

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

Ale problem polega na tym, że lista składników jest zagnieżdżona. Ponieważ flatten/2nie jest to dozwolone, masz teraz dwie możliwości: albo spłaszczenie wyniku, albo użycie wszystkich składników z listy składników każdego stepdania.

Do spłaszczenia zalecam użycie implementacji flatten2/2z tego postu. Wynikowe pytanie może wyglądać mniej więcej tak:

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

Dodaj, sort/2jeśli chcesz pozbyć się duplikatów jako statystyka w tym poście.

Jeśli chcesz skorzystać z drugiej metody, musisz utworzyć predykat pomocniczy, który pokazuje składniki wszystkich potraw. ingredients/3podaje składniki jako pojedynczy element dla każdego dania i numer kroku. Tak więc dla każdego Dishi Stepwielu wpisów z różnymi składnikami jest możliwe.

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.

Aby pozbyć się duplikatów, użyj sort/2.

PS: Nadal nie wiem, czy możesz używać 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.

?-