Terminazione Programmi terminanti esempio decrescenza

Transcript

Terminazione Programmi terminanti esempio decrescenza
Programmi terminanti
Terminazione
„
esempio
member(X, [X| _ ]).
member(X, [ _ |L]) :- member(X,L).
append([], L, L).
append([X|L1], L2, [X|L]) :- append(L1,L2,L).
?- member(t1,t2). ha SLD finito per ogni coppia
di termini t1,t2 ground.
?- append(t1,t2,t3). ha SLD finito per ogni terna
di termini t1,t2,t3 ground.
Un programma logico si dice terminante se,
fissata una qualsiasi regola di selezione, ogni
albero SLD per un goal ground è finito
(ovvero ogni SLD-derivazione di un goal
ground è finita).
decrescenza
„
„
Osserviamo che se t2 in member(t1,t2) è
ground ed unifica con [_|L] allora anche L
rimane associata ad un termine ground che è
più "semplice" di t2.
Analoga proprietà vale per t1 in
append(t1,t2,t3) quando unifica con [X|L1].
Terminazione "a sinistra"
„
„
„
esempio
Un programma logico P si dice terminante-asinistra se, fissata la regola di selezione
leftmost, ogni albero SLD per P che ha alla
radice un goal ground è finito.
quicksort([],[]).
quicksort([X|L], L2) :- partition(L,X,Small, Bigs),
quicksort(Small,Sord), quicksort(Bigs, Bord),
append(Sord,[X|Bord],L2).
Notazione. Chiamiamo LD-derivazione una
derivazione SLD con regola di selezione leftmost.
Nota: è una terminazione "universale" nel senso che
tutte le LD-derivazioni di goal ground sono finite.
?- quicksort(t1,t2). ha SLD finito per ogni coppia di
termini t1,t2 ground.
„ E' vero? Perché? E' terminante?
„ Che dire di partition? (non è chiamata con termini
ground).
partition
partition([],Y,[],[]).
partition([X|L],Y,[X|L1],L2):- X≤Y, partition(L,Y,L1,L2).
partition([X|L],Y,L1,[X|L2]):- X>Y, partition(L,Y,L1,L2).
Notiamo che se [X|L] viene legato ad un termine
ground allora L è un termine ground più semplice.
Se t1 è ground allora tutte le derivazioni (leftmost)
per la query partition(t1,t2,t3,t4) sono finite (anche
se t3 e t4 non sono ground).
decrescenza e terminazione
quicksort([X|L], L2) :- partition(L,X,Small, Bigs),
quicksort(Small,Sord), quicksort(Bigs, Bord),
append(Sord,[X|Bord],L2).
Possiamo convincerci che se [X|L] viene legata ad un
termine ground [t0|t1] allora tutte le derivazioni
(leftmost) per quicksort([X|L],L2) sono finite. Infatti:
- la chiamata a partition ha i primi due argomenti
ground e quindi partition(L,X,Small, Bigs) con L legata a
t1 termina, e se ha successo le variabili Small e Bigs
vengono legate a termini ground più semplici di t1.
cont. %
decrescenza di quicksort
- le due chiamate ricorsive a quicksort si applicano a
termini più semplici di t1 e pertanto terminano;
- inoltre la loro esecuzione lega Sord e Bord a termini
ground;
- pertanto l'append viene chiamata con il primo
argomento ground e questo è sufficiente a garantirne
la terminazione.
Mappe di livello
„
„
Chiamiamo mappa di livello una funzione |.| che
associa ad ogni elemento della base di Herbrand
(atomo ground) un naturale.
|.| : HB --> N
Nel definire una mappa di livello utilizziamo delle norme
definite sui termini che compaiono negli atomi.
Esempi
| append(t1,t2,t3) | = list_lenght(t1)
| pre-order(t1,t2) | = size(t1)
Norme
Chiamiamo norma una funzione weight che associa
ad ogni termine un valore (su di un insieme ben
fondato).
weight : Term --> N
Esempi:
„ list_lenght: conta il numero di elementi in una
lista, è 0 su termini che non sono liste.
list_lenght([1,X,[[2]|Y]]) = 3
„ size: conta il numero di funtori in un termine
size([1,X,[2|Y]]) = size([1|[X|[[2|[]]|Y]]]) = 5
„
Accettabilità
Definizione
Sia P un programma, |.| una mappa di livello e I un
modello per P. P si dice accettabile rispetto a |.| ed I se
- per ogni clausola c di P e
per ogni istanza ground H :- A,B,C di c
se I |= A allora |H| > |B|
Accettabilità e terminazione-a-sinistra
Teorema 1
Ogni programma accettabile è terminante-asinistra.
Esempio.
Il programma quicksort è accettabile e quindi è
terminante-a-sinistra.
esempio
Sia |append(t1,t2,t3)| = list_lenght(t1)
„ Consideriamo la query
Q = append([1,2], [X,3], Z), append(Z,Y,W).
Q è limitata rispetto a |.| ed il minimo modello di
Herbrand di append:
„ Siano t1 e t2 due termini ground
M |= append([1,2], [t1,3], t2)
solo se t2 è una
lista di lunghezza 4.
| append([1,2], [t1,3], t2)| ≤ 4
| append(t2, t3, t4)| ≤ 4
Interrogazioni (query) limitate
Definizione
Sia |.| una mappa di livello, I una interpretazione
e Q una query (anche non ground).
Diciamo che Q è limitata rispetto a |.| ed I se
esiste un naturale k tale che
- per ogni istanza ground A,B,C di Q
se I|= A allora |B| ≤ k
Accettabilità e query limitate
„
Teorema 2
Sia P un programma accettabile rispetto ad una
mappa di livello |.| ed un modello I, e sia Q una
query bounded rispetto a |.| ed I.
Allora ogni LD-derivazione di Q è finita.
esempi
„
„
„
Ogni LD-derivazione di
?- append([1,2], [X,3], Z), append(Z,Y,W).
è finita.
Ogni LD-derivazione di
?- append([2,X,5],Y,W).
è finita.
Ogni LD-derivazione di
?- quicksort([2,4,5,1], L).
è finita.
quicksort_dl
Versione 1
quicksort_dl([],L-L).
quicksort_dl([X|L], S - D ) :- partition(L,X,Small, Bigs),
quicksort_dl(Small,S-[X|B]),
quicksort_dl(Bigs, B-D).
Versione 2
quicksort_dl([],L-L).
quicksort_dl([X|L], S - D ) :- partition(L,X,Small, Bigs),
quicksort_dl(Bigs, B-D),
quicksort_dl(Small,S-[X|B]).
esercizi
„
„
„
Dimostrare che ogni LD-derivazione di
append(X,Y,[2,4,6]) è finita.
Dire se ogni LD-derivazione di
quicksort(L,[2,4,6]) è finita.
Dire se ogni LD-derivazione di
quicksort_dl(L,[2,4,6]-[]) è finita in entrambi i
programmi riportati nella diapositiva successiva.