This shows you the differences between two versions of the page.
pp:21:laboratoare:prolog:legare-executie [2021/05/09 19:56] bot.pp |
pp:21:laboratoare:prolog:legare-executie [2021/05/10 03:09] (current) bot.pp |
||
---|---|---|---|
Line 19: | Line 19: | ||
<code> | <code> | ||
- | % lungime(+Lista,-Lungime) | + | % lungime(+Lista,-Lungime) |
lungime([],0). | lungime([],0). | ||
lungime([_ | R], N) :- lungime(R, N1), N is N1 + 1. | lungime([_ | R], N) :- lungime(R, N1), N is N1 + 1. | ||
Line 25: | Line 25: | ||
</code> | </code> | ||
<code> | <code> | ||
- | ?- lungime([1,2,3],N).` | + | ?- lungime([1,2,3],N). |
N = 3. | N = 3. | ||
Line 61: | Line 61: | ||
<code> | <code> | ||
- | % remove(+Elem, +Lista, -ListaNoua) | + | % remove(+Elem, +Lista, -ListaNoua) |
- | remove(E, [E | R], R). | + | remove(E, [E | R], R). |
remove(E, [F | R], [F | L]) :- remove(E, R, L). | remove(E, [F | R], [F | L]) :- remove(E, R, L). | ||
</code> | </code> | ||
<code> | <code> | ||
- | % perm(+Lista, -Permutare) | + | % perm(+Lista, -Permutare) |
- | perm([], []). | + | perm([], []). |
perm([F | R], P) :- perm(R, P1), remove(F, P, P1). | perm([F | R], P) :- perm(R, P1), remove(F, P, P1). | ||
Line 105: | Line 105: | ||
<code> | <code> | ||
- | % predicat care verifică că toate elementele din prima listă sunt prezente în a doua | + | % predicat care verifică că toate elementele din prima listă sunt prezente în a doua |
all_members([], _). | all_members([], _). | ||
- | all_members([X | Rest], In) :- member(X, In), all_members(Rest, In). | + | all_members([X | Rest], In) :- member(X, In), all_members(Rest, In). |
% predicat care verifică faptul că țările nu au culori identice cu niciun vecin | % predicat care verifică faptul că țările nu au culori identice cu niciun vecin | ||
Line 129: | Line 129: | ||
template([1/_, 2/_, 3/_, 4/_, 5/_, 6/_, 7/_]). | template([1/_, 2/_, 3/_, 4/_, 5/_, 6/_, 7/_]). | ||
- | correct([]) :- !. correct([X/Y | Others]):- | + | correct([]) :- !. |
- | correct(Others),` | + | correct([X/Y | Others]):- |
- | member(Y, ["r", "g", "b"]),` | + | correct(Others), |
- | safe(X/Y, Others).` | + | member(Y, ["r", "g", "b"]), |
+ | safe(X/Y, Others). | ||
solve_maps(S):-template(S), correct(S). | solve_maps(S):-template(S), correct(S). | ||
Line 156: | Line 157: | ||
</code> | </code> | ||
- | Acest lucru se întâmplă pentru că, în ''%%p2%%'', Prolog nu poate să derive, pe baza negației, legări pentru ''%%X%%''. În prolog putem folosi negația doar pentru a //verifică// variabile deja legate, sau pentru a exprima faptul că //nu se poate demonstra că predicatul este adevărat//. În ''%%p1%%'', ''%%X%%'' este legat și negația are rolul de a verifica că ''%%lazy%%'' nu este adevărat pentru ''%%X%%''. În ''%%p2%%'', ''%%X%%'' este nelegat, deci putem interpreta rezultatele folosind a doua modalitate: Prolog va încerca să demonstreze că nu există ''%%X%%'' pentru care ''%%lazy%%'' să fie adevărat, ceea ce nu este corect. | + | Acest lucru se întâmplă pentru că, în ''%%p2%%'', Prolog nu poate să derive, pe baza negației, legări pentru ''%%X%%''. În Prolog putem folosi negația doar pentru a //verifica// variabile deja legate, sau pentru a exprima faptul că //nu se poate demonstra că predicatul este adevărat//. În ''%%p1%%'', ''%%X%%'' este legat și negația are rolul de a verifica că ''%%lazy%%'' nu este adevărat pentru ''%%X%%''. În ''%%p2%%'', ''%%X%%'' este nelegat, deci putem interpreta rezultatele folosind a doua modalitate: Prolog va încerca să demonstreze că nu există ''%%X%%'' pentru care ''%%lazy%%'' să fie adevărat, ceea ce nu este corect. |
==== Predicatul false ==== | ==== Predicatul false ==== | ||
Line 173: | Line 174: | ||
?- my_reverse([1,2,3,4],[],Rev). | ?- my_reverse([1,2,3,4],[],Rev). | ||
List:[1,2,3,4], Acc:[] | List:[1,2,3,4], Acc:[] | ||
- | List:[2,3,4], Acc:[1] | + | List:[2,3,4], Acc:[1] |
List:[3,4], Acc:[2,1] | List:[3,4], Acc:[2,1] | ||
List:[4], Acc:[3,2,1] | List:[4], Acc:[3,2,1] | ||
Line 184: | Line 185: | ||
În Prolog, predicatul cut (''%%!%%'') are rolul de a elimina toate punctele de bifurcație create în predicatul curent. La evaluarea predicatului cut într-un predicat ''%%p%%'', se vor realiza două tipuri de efecte: | În Prolog, predicatul cut (''%%!%%'') are rolul de a elimina toate punctele de bifurcație create în predicatul curent. La evaluarea predicatului cut într-un predicat ''%%p%%'', se vor realiza două tipuri de efecte: | ||
- | * nu se vor mai genera soluții (dacă este nevoie, sau dacă soluția curent eșuează) pentru alte reguli ale predicatului ''%%p%%'' | + | * nu se vor mai genera soluții (dacă este nevoie, sau dacă soluția curentă eșuează) pentru alte reguli ale predicatului ''%%p%%'' |
- | * nu se vor mai genera soluții (dacă este nevoie, sau dacă soluția curent eșuează), pentru alte soluții ale condițiilor care apar **în aceeași regulă cu cut**, și înainte de cut. | + | * nu se vor mai genera soluții (dacă este nevoie, sau dacă soluția curentă eșuează), pentru alte soluții ale condițiilor care apar **în aceeași regulă cu cut**, și înainte de cut. |
De exemplu, în programul: | De exemplu, în programul: | ||
<code> | <code> | ||
- | p(a). | + | p(a). |
- | p(b). | + | p(b). |
- | p(A/B) :- q(A), !, t(A/B). p(d). | + | p(A/B) :- q(A), !, t(A/B). |
+ | p(d). | ||
- | q(a). | + | q(a). |
- | q(b). | + | q(b). |
q(c). | q(c). | ||
- | t(a/a). | + | t(a/a). |
- | t(a/b). | + | t(a/b). |
- | t(b/c). | + | t(b/c). |
- | t(b/d). | + | t(b/d). |
</code> | </code> | ||
Line 222: | Line 224: | ||
Putem utiliza predicatul cut în două moduri: | Putem utiliza predicatul cut în două moduri: | ||
- | * atunci când știm că am ajuns la soluția care ne interesează, și știm că nu mai avem nevoie de o altă soluție pentru predicat, putem utiliza cut pentru a nu mai explora alte soluții (cut verde / //green cut//). | + | * atunci când știm că am ajuns la soluția care ne interesează, și știm că nu mai avem nevoie de o altă soluție pentru predicat, putem utiliza cut pentru a nu mai explora alte soluții (cut verde / //green cut//). |
- | * atunci când dorim în mod explicit ca Prolog să nu mai exploreze alte posibilități pentru același predicat, pentru că acestea nu ar genera soluții corecte, dacă se aplică regula curentă (cut roșu / //red cut//). | + | * atunci când dorim în mod explicit ca Prolog să nu mai exploreze alte posibilități pentru același predicat, pentru că acestea nu ar genera soluții corecte, dacă se aplică regula curentă (cut roșu / //red cut//). |
- | Exemplu: implementarea predicatului ''%%min%%''. | + | **Exemplu:** implementarea predicatului ''%%min%%''. |
- | Varianta 1 -- fără cut: | + | **Varianta 1** -- fără cut: |
<code> | <code> | ||
Line 243: | Line 245: | ||
Pentru interogarea ''%%minB(2, 3, Min)%%'' se obțin două soluții: ''%%Min=2%%'' și ''%%Min=3%%''. | Pentru interogarea ''%%minB(2, 3, Min)%%'' se obțin două soluții: ''%%Min=2%%'' și ''%%Min=3%%''. | ||
- | Putem integra predicatul cut ca un cut verde astfel: | + | **Varianta 2** Putem integra predicatul cut ca un cut verde astfel: |
<code> | <code> | ||
Line 261: | Line 263: | ||
Pentru ''%%min2B(3, 2 ,M)%%'', se va evalua predicatul cut (care anulează alternativa pentru min2B), inegalitatea eșuează, și interogarea va eșua, pentru că din cauza lui cut Prolog nu mai intră și pe a doua regulă. | Pentru ''%%min2B(3, 2 ,M)%%'', se va evalua predicatul cut (care anulează alternativa pentru min2B), inegalitatea eșuează, și interogarea va eșua, pentru că din cauza lui cut Prolog nu mai intră și pe a doua regulă. | ||
- | Putem integra predicatul cut ca un cut roșu astfel: | + | **Varianta 3** Putem integra predicatul cut ca un cut roșu astfel: |
<code> | <code> | ||
- | min3(X, Y, Min) :- X < Y, !, X = Min. | + | min3(X, Y, Min) :- X < Y, !, X = Min. |
min3(_, Y, Min) :- Y = Min. | min3(_, Y, Min) :- Y = Min. | ||