In Prolog spesso risolvo un problema fornendo un modello (una struttura contenente variabili) e quindi soddisfacendo una serie di vincoli su di esso. Un esempio semplice potrebbe essere:Soddisfare una serie di obiettivi in Prolog
go(T) :-
T = [_, _, _],
member(cat, T),
member(dog, T),
member(mouse, T).
E in pratica l'insieme di vincoli viene generato un altro modo piuttosto che essendo fissato, e devo scrivere un predicato ricorsivo per soddisfare ogni vincolo a sua volta:
go(T) :-
T = [_, _, _],
findall(A, animal(A), As),
% satisy member(A, T) for each A in As
fill_in_animals(T, As)
fill_in_animals(T, []).
fill_in_animals(T, [A|Rest]) :-
member(A, T),
fill_in_animals(T, Rest).
Si noti che la mia domanda non riguarda i vincoli relativi alle liste, e anche i parametri del vincolo non possono sempre essere generati facilmente come elenco da passare a un predicato di helper relativamente semplice come usato sopra. In pratica ho trovato l'helper è un predicato piuttosto sgraziato che scrivo ogni volta, che:
- accetta un template, diversi parametri da utilizzare per il vincolo (e quindi per il legame variabili del modello di valori utili), e una variabile per indicare quale vincolo sta a.
- Genera un vincolo per soddisfare in questa iterazione, applicandolo al modello.
- Richiama automaticamente se stesso in modo che i restanti vincoli possano essere soddisfatti.
Quello che sto cercando è un predicato sulla falsariga di findall
, ecc., Che soddisferà una serie di obiettivi, uno dopo l'altro. Qualcosa del tipo:
% satisfyall(:Goal)
% backtracks on Goal but keeps all bindings from each fully satisfied goal.
satisfyall((animal(A), member(A, T)))
La risposta che sto cercando non deve essere in questa forma. In effetti, potrebbe esserci una contraddizione tra il backtracking su un obiettivo e il mantenimento di ogni set di binding da esso derivante.
Spero di aver spiegato il mio problema in modo che sia ragionevolmente chiaro cosa potrebbe essere d'aiuto. (Se non me lo faccia sapere.) Scuse in anticipo per la domanda prolissa!
Update (2 anni più tardi)
ci proverò più tardi oggi e aggiornare la mia domanda!
Nota che non ho mai detto che avrei aggiornato la domanda lo stesso giorno del tentativo. ;-)
@CapelliC mi ha guidato nella giusta direzione, e ho trovato un modello che sembra funzionare abbastanza bene:
?- Gs = [member(red),member(blue)], T = [_,_], foreach(member(G, Gs), call(G, T)).
T = [red, blue] ;
T = [blue, red] ;
[lambda.pl] (http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl) potrebbe aiutare, ma penso che si dovrebbe andare con findall/3 – CapelliC
C'è qualche ragione particolare che lambda non è distribuito con SWI? Mi piacerebbe poter usare 'use_module (library (lambda))'! –
@DanielLyons: Ho avuto qualche downvote quando ho provato a rispondere a questa stessa domanda :) – CapelliC