% 1. exemplul din primul laborator % ========================================== parinte(ioana, radu). parinte(ioana, miruna). parinte(alin, radu). parinte(alin, miruna). parinte(ana, mihai). parinte(ana, wendy). parinte(radu, mihai). parinte(radu, wendy). stramos(A, B):- parinte(A, B). stramos(A, B):- parinte(A,X), stramos(X,B). soti(A, B):- parinte(A, X), !, parinte(B, X), A \= B. % try: ?- trace, stramos(A, B), notrace, nodebug. % in general, end tracing with: ?- notrace, nodebug. % 2. variabile neinstantiate % ========================================== % any(X). any(X) :- display(X). % sau: any(X) :- format("X este: ~w~n", [X]). any(X, X). % try ?- any(X, Y). % any(X, Y) :- X = Y. % identic cu any(X, X). % any(X, Y) :- X is Y. % la consola vad 'ce legari s-au fortat ca sa fie adevarat?'. % 3. generarea numerelor % ========================================== % interval(X) :- X < 10. interval(0). interval(X) :- interval(Y), Y < 10, X is Y + 1. % runs infinitely after X = 10 interval2H(I, _, I). interval2H(I, L, X):- I < L, I1 is I + 1, interval2H(I1, L, X). interval2(X) :- interval2H(0, 10, X). % third argument left un-instantiated is bound to values % between the first and the second argument count(A, B, A) :- A =< B. count(A, B, C) :- A < B, A2 is A + 1, count(A2, B, C). factorial2a(1, 1). factorial2a(N, F) :- factorial2a(N2, F2), N is N2 + 1, F is F2 * N. factorial2bH(N, F, ND, F) :- ND == N. factorial2bH(N, F, N, FD) :- FD == F. factorial2bH(N, F, NO, FO) :- ( integer(NO), NI < NO ; integer(FO), FI < FO ), N1 is N + 1, F1 is F * N1, factorial2bH(N1, F1, NO, FO). factorial2a(N, F) :- factorial2bH(1, 1, N, F). % 4. directia construirii solutiilor % ========================================== inc(X, Y) :- Y is X + 1. % Simplu - recursivitate pe stiva (se mai face o unificare la % intoarcere, in argumentul de iesire). incListB([], []). incListB([H | T],[H1 | T1]) :- inc(H, H1), incListB(T, T1). % echivalent cu % incListB([H|T], LOut) :- inc(H,H1), incListB(T,T1), LOut = [H1 | T1]. % Cu acumulator si constructia rezultatului la capatul recursivitatii % Recursivitate pe coada incListF(L,LR) :- incListFH(L,[],LR). incListFH([], L, LOut) :- reverse(L, LOut). incListFH([H|T], LA, LR) :- inc(H,H1), incListFH(T, [H1 | LA], LR). % 5. backtracking % ========================================== % stateG(S) :- member(S, [a,b,c,d,e,f,g]). nextG(a, b). nextG(a, e). nextG(b, c). nextG(b, d). nextG(d, a). % recursive nextG(e, f). nextG(e, g). initialG(a). finalG(f). finalG(g). problemG(problem(initialG, nextG, finalG)). % problem(initial, next, final) extractInitialPred(P, problem(P, _, _)). extractNextPred(P, problem(_, P, _)). extractFinalPred(P, problem(_, _, P)). initial(Pb, S) :- extractInitialPred(Init, Pb), call(Init, S). next(Pb, S, SNext) :- extractNextPred(P, Pb), call(P, S, SNext). final(Pb, S) :- extractFinalPred(P, Pb), call(P, S). % a declarative perspective: % a node on the path to solution is either the solution, % or has a neighbor that is on the path to the solution onPath(Pb, Current, [Current]) :- final(Pb, Current). onPath(Pb, Current, [Current | Path]) :- next(Pb, Current, Next), onPath(Pb, Next, Path). path(Pb, Path) :- initial(Pb, S), onPath(Pb, S, Path). % an algorithmic perspective: (identical, in implementation, to above) % search for the solution ends with the final state % otherwise, search the solution starting from a next state search(Pb, Current, [Current]) :- final(Pb, Current). search(Pb, Current, [Current | Sol]) :- next(Pb, Current, Next), search(Pb, Next, Sol). search(Pb, Sol) :- initial(Pb, S), search(Pb, S, Sol). % supporting recursion: add a history of visited states searchR(Pb, Current, H, [Current]) :- final(Pb, Current), print(H), nl. searchR(Pb, Current, H, [Current | Sol]) :- next(Pb, Current, Next), not(member(Next, H)), searchR(Pb, Next, [Next | H], Sol). searchR(Pb, Sol) :- initial(Pb, S), searchR(Pb, S, [S], Sol). % 7. printing: format % ============================================== % print(_). prettyPrintList(L) :- ppListH(L, 1). ppListH([], N) :- format("completed, ~w elements printed.~n", [N]). ppListH([H|T], I) :- format("element no. ~w: ~w~n", [I, H]), I1 is I + 1, ppListH(T, I1). % 8. debugging: % ============================================== % try predicates trace, notrace (maybe debug and nodebug also): % for 1 argument predicates dotracing(P, X) :- trace, call(P, X), notrace, nodebug. % 9. cut si fail % ============================================== min(X, Y, M) :- X =< Y, M is X. min(X, Y, M) :- X > Y, M is Y. min2(X, Y, M) :- X =< Y, M = X. min2(X, Y, M) :- X > Y, M = Y. % Echivalent cu min2. min3(X, Y, X) :- X =< Y. min3(X, Y, Y) :- X > Y. % Gresit! min4(X, Y, X) :- X =< Y. min4(_, Y, Y). min5(X, Y, X) :- X =< Y, !. min5(_, Y, Y). este(lili, liliac). este(fifi, papagal). zboara(liliac). zboara(papagal). pasare(X) :- este(X, liliac), !, fail. pasare(X) :- este(X, Y), zboara(Y), !. pasare(X) :- zboara(X).