2009-09-23 17 views
13

devo P1 predicato che restituisce i valori uno dopo l'altro in questo modo:Come trovo tutte le soluzioni per un obiettivo in Prolog?

-? P1(ARGUMENTS, RETURN). 
-? RETURN = 1; 
-? RETURN = 2; 
-? RETURN = 3; 
-? fail. 

Ho anche un'altra predicato chiamato P2:

P2(ARGUMENTS, LIST) :- P1(ARGUMENTS, RETURN),... % SOMEHOW HERE I NEED TO INSERT ALL VALUES OF RETURN TO LIST. 

Come non trovare tutti i valori di RETURN ed assegnarli a LIST?

+0

È questo il relativo ?: http://stackoverflow.com/questions/1445490/expand-a-query-into-a-list-in-prolog –

+0

grazie, che aiuta! – Asterisk

risposta

16

Usa findall per ottenere questo risultato:

P2(ARGUMENTS, LIST) :- findall(X, P1(ARGUMENTS, X), LIST). 

Questo è legato al bagof function mentioned in the question collegato a da Anders Lindahl. C'è una buona spiegazione sul rapporto tra le due funzioni (e una terza funzione setof) here:

per illustrare le differenze considerano un piccolo esempio:

listing(p). 

p(1,3,5). 
p(2,4,1). 
p(3,5,2). 
p(4,3,1). 
p(5,2,4). 

provare i seguenti obiettivi. (La risposta schermi sono stati modificati per risparmiare spazio .)

?- bagof(Z,p(X,Y,Z),Bag). 
Z = _G182 X = 1 Y = 3 Bag = [5] ; 
Z = _G182 X = 2 Y = 4 Bag = [1] ; 
Z = _G182 X = 3 Y = 5 Bag = [2] ; 
Z = _G182 X = 4 Y = 3 Bag = [1] ; 
Z = _G182 X = 5 Y = 2 Bag = [4] ; 
No 

?- findall(Z,p(X,Y,Z),Bag). 
Z = _G182 X = _G180 Y = _G181 Bag = [5, 1, 2, 1, 4] ; 
No 

?- bagof(Z,X^Y^p(X,Y,Z),Bag). 
Z = _G182 X = _G180 Y = _G181 Bag = [5, 1, 2, 1, 4] ; 
No 

?- setof(Z,X^Y^p(X,Y,Z),Bag). 
Z = _G182 X = _G180 Y = _G181 Bag = [1, 2, 4, 5] ; 
No 

I predicati bagof e setof rendimento collezioni per i singoli attacchi di le variabili libere nella meta. setof produce una versione ordinata della raccolta senza duplicati. Per evitare le variabili di binding, utilizzare un'espressione quantificatore . Ad esempio porta bagof(Z,X^Y^p(X,Y,Z),Bag) chiede "sacchetto di Z 's tale che esiste un X ed esiste un Y tale che p(X,Y,Z)". findall si comporta come bagof con tutte le variabili libere automaticamente quantificate in modo esistenziale. Inoltre findall restituisce una lista vuota [] lì non ha alcun obiettivo soddisfazione, mentre bagof non riesce.

Problemi correlati