190 likes | 299 Views
Controllare lo spazio di ricerca. Fabio Massimo Zanzotto ( slides di Andrea Turbati). Esercizio. Realizziamo il predicato: /* not_member (X,L) */ vero se X è un elemento, L è una lista e X non appartiene a L. Backtracking.
E N D
Controllare lo spazio di ricerca Fabio Massimo Zanzotto (slides di Andrea Turbati)
Esercizio Realizziamo il predicato: /* not_member(X,L) */ vero se X è un elemento, L è una lista e X non appartiene a L.
Backtracking • Il backtracking è una delle caratteristiche principali del Prolog • Tramite il backtracking vengono esplorate tutte le possibili soluzioni • Se l’utente non è soddisfatto di una data soluzione, può chiedere al programma di cercarne un’altra, “forzando” il backtracking
Backtracking • In certi casi, se l’utente chiede una seconda soluzione, questa potrebbe essere errata, o comunque non prevista da chi ha scritto il programma • Questo può essere evitato ponendo ulteriori controlli nelle regole, a scapito delle prestazioni
Esempio • Creiamo una regola per l’identificazione del minimo: min(X, Y, X):- X =< Y. min(X,Y,Y). • Se la prima regola fallisce, cioè X è maggiore di Y allora il minimo è Y e quindi si usa la seconda versione della regola min
Esempio • Questa scrittura, anche se in un primo momento sembra corretta ha un comportamento errato se l’utente chiede un’altra soluzione • ?- min(3, 8, Min). • Min = 3 • ; • Min = 8
Algoritmo di Risoluzione ?- path(a,d). … by examples edge(a,b). edge(b,c). edge(a,e). edge(c,d). edge(d,e). edge(f,e). path(X,Y):- edge(X,Y). path(X,Y):- path(X,Z),path(Z,Y). edge(a,d). path(a,Z),path(Z,d). edge(a,Z),path(Z,d). fail edge(a,b),path(b,d). edge(a,b),path(b,Z),path(Z,d). edge(a,b),edge(b,c),path(c,d). edge(a,b),edge(b,c),edge(c,d). Success! X=a,Y=d X=a,Y=d
Cut • Per impedire il backtracking in un determinato punto bisogna usare ! • Il ! pone, nell’esecuzione del programma, un punto oltre il quale il backtracking non può tornare
Esempio Cut min2(X, Y, X):- X =< Y, !. min2(X,Y,Y). • ?- min(3,8,Min). • Min = 3
Esempio 2 Cut • Come possiamo aggiungere un elemento ad una lista solo se tale elemento non è già presente? add(X, L, L):- member(X, L). add(X, L, [X|L]). • La soluzione sembra semplice e corretta
Esempio 2 Cut • ?- add(5, [1,2], L). • L=[5, 1,2] • ?- add(5,[1,2,5],L). • L=[1,5,2] • ; • L=[5, 1,2,5]
Esempio 2 Cut • Soluzione a prova di backtracking add2(X, L, L):- member(X,L), !. add2(X, L, [X|L]). • ?- add2(5,[1,2,5],L). • L=[1,2,5]
Negationasfailure • Come possiamo rappresentare in Prolog la frase “Mary ama tutti gli animali, ma non i serpenti”? • La parte complicata è il “ma non i serpenti” • L’idea è formularla nel seguente modo: se X è un serpente, allora a Mary non piace, altrimenti se è un animale si.
Negationasfailure likes(mary, X):- snake(X), !, fail. likes(mary, X):- animal(X). • fail, usato insieme al !, permette di esprimere il concetto di non riuscita di una regola, impedendo il backtracking e quindi l’utilizzo della regola successiva
Different • Ragionamento analogo per la regola different, che verifica se due termini sono differenti o meno different(X,X):- !, fail. different(_,_).
Not • Il concetto di Not, cioè di una regola che ha successo solo se il predicato che gli viene passato fallisce può essere espresso mediante: not(P):- P, !, fail; true. • Dove true ha sempre successo
Different • Sfruttando la regola per il not, è possibile riscrivere il different in modo più semplice different2(X,Y):- not(X=Y).
Problemi con la cut e la negazione • La cut va usata solo se realmente necessaria, perché può portare a dei problemi: • Usando la cut l’ordine delle regole diventa immutabile • Con la cut si può avere una interpretazione diversa delle regole • p:- a,b. p:-c => (a & b) V c • p:- a,!,b. p:-c => (a & b) V (~a & c) • Con la not si può avere risposta positiva non solo quando qualcosa è falso, ma anche quando non si hanno abbastanza informazioni per dimostrare che è vero
Esercizi • Trasformare il not, in un operatore. Che operatore diventerà? Infisso, prefisso o postfisso? • Riscrivere l’esempio di Mary e dei serpenti con questo nuovo operatore