p(1). % predicatul p/1 este adevărat pentru valoarea 1 p(2). p(a). p([1,2,3]). % în prolog avem pattern-matching q(X, X) :- p(X). % predicatul q este adevărat dacă ambele argumente ale lui sunt același lucru și dacă p(argument al lui q) este adevărat t(X) :- \+ p(X). % Prolog trebuie să aibă de unde să ia legări pentru X s(X) :- member(X, [1, 2, 3, 4, 5, a, b, c, d, e, [1], [1, 2], [1, 2, 3]]), \+ p(X). same(X, X). % Alice came across a lion and a unicorn in a forest of forgetfulness. % Those two are strange beings. % The lion lies every Monday, Tuesday and Wednesday % and the other days he speaks the truth. % The unicorn lies on Thursdays, Fridays and Saturdays, % however the other days of the week he speaks the truth. % Lion: Yesterday I was lying. % Unicorn: So was I. % Which day did they say that? % concepte: zilele săptămânii, zilele în care mint unicornul și leul, % unicornul și leu % relații: % când minte fiecare animal % ce zice fiecare acum % ieri % relația de "ieri" yesterday(mon, sun). yesterday(tue, mon). yesterday(wed, tue). yesterday(thu, wed). yesterday(fri, thu). yesterday(sat, fri). yesterday(sun, sat). % relația "când minte fiecare animal" lies(lion, [mon, tue, wed]). lies(unicorn, [thu, fri, sat]). % relația "Animal (poate) spune azi (Today) că ieri a mințit" saysTodayItLiedYesterday(Animal, Today) :- yesterday(Today, Yesterday), lies(Animal, DaysLies), % obtine DaysLies \+ member(Today, DaysLies), % azi minte member(Yesterday, DaysLies). saysTodayItLiedYesterday(Animal, Today) :- yesterday(Today, Yesterday), lies(Animal, DaysLies), member(Today, DaysLies), \+ member(Yesterday, DaysLies). % relația "Today este soluție" sol(Today) :- saysTodayItLiedYesterday(lion, Today), saysTodayItLiedYesterday(unicorn, Today). % myMember/2 % myMember(+Elem, +Lista) myMember(_, []) :- false. myMember(E, List) :- List = [H|_], E = H. myMember(E, List) :- List = [_|T], myMember(E, T). % nu am nevoie să exprim ce lucruri sunt false % Prolog nu va găsi o afirmație pentru cazul în care lista este % vidă -> în acest caz, myMember este fals. myMember2(E, [E|_]). % E este membru într-o listă în care E este primul element. myMember2(E, [_|T]) :- myMember2(E, T). % E este membru într-o listă în care E este membru în tail % sumEvens/2 % sumEvens(+L, -Suma) sumEvens([], 0). % suma pentru o listă vidă este 0 sumEvens([H|T], Sum) :- H mod 2 =:= 0, % dacă primul element este par sumEvens(T, SumTail), % fac suma pentru Tail Sum is H + SumTail. % adun pe H la suma pentru Tail sumEvens([H|T], Sum) :- H mod 2 =:= 1, % dacă primul element este impar sumEvens(T, Sum). % fac suma pentru Tail, este chiar rezultatul. % vreau un predicat echivalent cu map (+1) % incList/2 % incList(+ListIn, -ListOut) incList([], []). incList([H|T], LOut) :- H1 is H + 1, % incrementez pe H, la un H1 incList(T, T1), % incrementez restul listei la un T1 LOut = [H1|T1].% construiesc pe LOut ca listă formată din H1 și T1 incList2([], []). incList2([H|T], [H1|T1]) :- H1 is H + 1, incList2(T, T1). % incList2 este adevărat pentru două liste nevide, unde % primul element din a doua listă este primul element din prima listă % plus 1 % iar incList2 este adevărat pentru restul din prima listă și restul din % a doua listă % myReverse(?List, ?RevList) myReverse([], []). myReverse([E], [E]). % nu este necesară myReverse([First|Rest], RevList) :- % vreau ca myReverse să fie adevărat pentru Rest și RevRest myReverse(Rest, RevRest), % vreau ca RevList să fie o listă care începe cu RevRest % și are First ca ultimul element % RevList este concatenarea lui RevRest cu lista formată din First append(RevRest, [First], RevList). % e.g. vreau să fac myReverseAcc([1,2,3,4,5], [], RevList) % în cazul de bază, lista s-a terminat, în al 2lea argument am deja % lista inversată % -> leg al 3lea parametru (rezultatul final) la același lucru cu % acumulatorul %myReverseAcc([], RezultatulFinal, RezultatulFinal). myReverseAcc([], Acc, RezFinal) :- Acc = RezFinal. myReverseAcc([First|Rest], Acc, RevList) :- % în Acc am inversul părții din listă pe care l-am văzut înainte % e.g. la un moment dat am: % [First|Rest] = [4,5] % Acc = [3,2,1] % inversez restul liste (Rest) % construiesc acumulatorul pentru apelul recursiv % construiesc în parametrul acumulatorului o listă cu First % ca prim element și acumulatorul primit ca restul elementelor % rezultatul final este același în al 3lea argument de la acest apel % și de la apelul recursiv myReverseAcc(Rest, [First | Acc], RevList). % Vreau să generez numerele naturale până la un anumit număr strict % pozitiv (îl numim Limita) maiMicDecat(0, _). maiMicDecat(N, Limita) :- maiMicDecat(NMinus1, Limita), % mă bazez că a fost legat NMinus1 la o valoare % pe baza unei soluții existente construiesc altă soluție N is NMinus1 + 1, N =< Limita. % în loc să caut o valoare pentru care este predicatul deja aeevărat % pot să merg în recursivitate arătând unde am ajuns cu căutarea % soluției maiMicDecat2H(0, _, _). maiMicDecat2H(N, Limita, Adancime) :- % verific că nu am ajuns prea adânc în recursivitate Adancime < Limita, AdancimePlus1 is Adancime + 1, % restul codului este la fel maiMicDecat2H(NMinus1, Limita, AdancimePlus1), N is NMinus1 + 1, N =< Limita. % opțional, oricum verific adâncimea maiMicDecat2(N, Limita) :- maiMicDecat2H(N, Limita, 0).