Documente Academic
Documente Profesional
Documente Cultură
Backtracking: Ruxandra Stoean Ruxandra - Stoean@inf - Ucv
Backtracking: Ruxandra Stoean Ruxandra - Stoean@inf - Ucv
2/32
Backtracking - exemplu
Sa consideram programul: natural(0). natural(N) :- natural(N1), N is N1 + 1. Ce va genera Prolog-ul in urma unui apel de forma: ? natural(N), write(N), nl, sleep(1), fail.
3/32
Backtracking - exemplu
Se va genera un ciclu infinit:
numerele succesive backtracking. sunt generate prin
Primul numr natural este generat i afiat. Apoi fail foreaza backtracking-ul s acioneze. A doua clauz este apelat, genernd numere naturale succesive.
4/32
5/32
6/32
7/32
Backtracking
Backtracking-ul n Prolog este asadar foarte uor de utilizat. Predicatul fail/0 este cel care duce la forarea backtrackingului:
el ntoarce ntotdeauna un rezultat negativ i duce la reapelarea predicatelor care se afl naintea sa, ori de cte ori este posibil.
8/32
Permutari
Sa generam permutrile muimii {a, b, c, d} folosind backtracking-ul in acest scop. Mai intai definim cele 4 litere: litera(a). litera(b). litera(c). litera(d).
9/32
Permutari
permutare(X, Y, Z, T) :- litera(X), litera(Y), litera(Z), litera(T), X \= Y, X \=Z, Y \= Z, X \=T, Y\=T,Z \=T. permutari :- permutare(X, Y, Z, T), write(X), tab(1), write(Y), tab(1), write(Z), tab(1), write(T), nl, fail. permutari. Apelm simplu, predicatul permutari: ? permutari.
10/32
Permutari
Iata permutarile rezultate:
11/32
Taietura (Cut)
Uneori ns, din cauza backtracking-ului, sunt ntoarse rezultate nedorite. Pentru evitarea acestora, Prologul ne vine n ajutor, prin ceea ce se numete taietura. Cu ajutorul acestui procedeu, Prologul ofer posibilitatea opririi backtrackingului. Procedeul se mai numete cut i se noteaz cu semnul exclamrii (!).
12/32
Taietura (Cut)
Tietura face ca Prologul s blocheze toate deciziile fcute pn la momentul apariiei sale (adic a semnului exclamrii). Asta nseamn c, dac backtracking-ul era n desfurare, el va fi oprit i nu se vor mai cuta alte alternative pentru ce se gsete nainte de tietur (!).
13/32
Exemplu
locul(1, simion). locul(2, maria). locul(3, sorin). locul(3, cristian). ? locul(3, Nume), write(Nume), nl, fail. sorin cristian ? locul(3, Nume), !, write(Nume), nl, fail. sorin
14/32
Mai adaugam:
despre(1, ' este castigatorul concursului.'). despre(1, ' primeste 100$.'). despre(2, ' a ctigat locul II.'). despre(2, ' primeste 50$.'). despre(3, ' a castigat locul III'). despre(3, ' primeste 25$.'). spune(Loc) :- locul(Loc, Cine), write(Cine), nl, despre(Loc, Despre), tab(3), write(Despre), nl, fail. ? spune(3). sorin a castigat locul III primeste 25$. cristian a castigat locul III primeste 25$.
15/32
Cut
Dac vrem ns s tim care este primul dintre cei care au luat locul trei i cteva lucruri despre el, avem nevoie de tietur - adugm la predicatul spune/1 semnul exclamrii astfel: spune(Loc) :- locul(Loc, Cine), write(Cine), nl, !, despre(Loc, Despre), tab(3), write(Despre), nl, fail. Acum, dup adugarea fcut, backtrackingul se va aplica numai asupra predicatelor aflate dupa semnul exclamrii.
16/32
Taietura
Tietura se folosete de obicei n interiorul unui predicat unde Prolog-ul a gsit primul rspuns posibil despre care se doresc mai multe detalii. Sau pentru a fora un predicat s ntoarc un rspuns negativ (adic fail) ntr-o anumit situaie i nu vrem s caute alte soluii. Tietura ns, n general, mrete complexitatea codului dect s o simplifice, iar utili utilizarea zarea ei este bine s fie evitat pe ct posibil:
se spune chiar c ea reprezint goto-ul programrii logice.
1 2 4 5 6 3 7
Arbori si grafuri
1 2 3 4
5 6 7
9 8
18/32
Arbori
2
1 3
19/32
Arbori
% tata(X,Y) - X este tatal lui Y tata(0,1). tata(1,2). tata(1,3). tata(2,4). tata(2,5). tata(2,6). tata(3,7).
4 2
1 3
20/32
Parcurgere in adancime
2
1 3
21/32
Parcurgere in adancime
Gaseste toti X care au o anumita relatie cu un Y dat; acestia se pun in lista L 2
1 3
findall(X, relatie(X,Y), L)
parcurgere:-tata(0, Rad), p([Rad]). p([]). p([Nod|Rest]) :- write(Nod), tab(2), findall(D, tata(Nod, D), LC), append(LC, Rest, Stiva), p(Stiva).
22/32
Parcurgere in adancime
?-parcurgere.
4 2
1 3
23/32
Parcurgere in latime
2
1 3
24/32
Parcurgere in latime
2
1 3
parcurgere_latime:-tata(0, Rad), c([Rad]). c([]). c([P|Rest]) :- write(P), tab(2), findall(D, tata(P, D), LC), append(Rest, LC, Coada), c(Coada).
25/32
Parcurgere in latime
?-parcurgere_latime.
4 2
1 3
26/32
Grafuri orientate
1 5 9 2 3 4 7 6 8
27/32
Grafuri orientate
marc(1, 2). marc(1, 4). marc(1, 5). marc(3, 2). marc(3, 7). marc(4, 3). marc(5, 6). marc(6, 8). marc(7, 6). marc(9, 8).
1 5 9 2 3 4 7 6 8
28/32
Grafuri orientate
1 5 9 2 3 4 7 6 8
29/32
Grafuri orientate
1 5 9 2 3 4 7 6 8
drum :- write('Introduceti nodul de start: '), read(X), write('Introduceti nodul destinatie: '), read(Y), drum(X, Y, L), write_ln(L), fail. drum.
30/32
Grafuri orientate
1 5 9 2 3 4 7 6 8
drum(X, Y, L) :- drum(X, Y, [X], L). drum(X, X, L, L). drum(X, Y, L, Lista) :- marc(X, Z), not(member(Z, L)), append(L, [Z], L1), drum(Z, Y, L1, Lista).
31/32
Grafuri orientate
?- drum.
2 3 1 5 9 4 7 6 8
32/32
Pe saptamana viitoare!